rendered paste body#include <misc.h>
#include <sha1.h>
#define NOR ((unsigned char *) 0xA0000000)
#define NORWORD ((unsigned short int *) 0xA0000000)
#define SECZONE_OFFSET 0x3FA000
#define SECZONE_SIZE 0x1000
#define CHIPID_LOC ((unsigned char *) 0xF440006C)
void eraseblock(int addr);
void writeblock(int block, int length);
unsigned char virgin[] = {
0x00, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x01, 0x01, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00,
0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
unsigned char NOR_ID[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
unsigned char CHIP_ID[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
};
unsigned char payload[SECZONE_SIZE];
int fredtool_main() __attribute__ ((section (".fredtool_entry")));
int
fredtool_entry()
{
sha1_context ctx;
memcpy(CHIP_ID, CHIPID_LOC, sizeof(CHIP_ID));
sha1_starts(&ctx);
sha1_update(&ctx, NOR_ID, sizeof(NOR_ID));
sha1_update(&ctx, CHIP_ID, sizeof(CHIP_ID));
sha1_finish(&ctx, (void *)payload);
eraseblock(SECZONE_OFFSET);
writeblock(SECZONE_OFFSET, SECZONE_SIZE);
while(1);
}
void
eraseblock(int addr)
{
NOR[addr] = 0xFF;
NOR[addr] = 0x60;
NOR[addr] = 0xD0; /* Unlock */
NOR[addr] = 0x20;
NOR[addr] = 0xD0; /* Erase */
NOR[addr] = 0x50;
while(NOR[addr] != 0x80); /* Wait for it to be ready */
}
void
writeblock(int addr, int length)
{
extern unsigned char *payload;
unsigned int i;
short int j;
/* First unlock the blocks */
for(i = 0; i < length; i+= 0x4000) {
NOR[addr + i] = 0xFF;
NOR[addr + i] = 0x60;
/* Unlock */
NOR[addr + i] = 0xD0;
NOR[addr + i] = 0xFF;
}
NOR[0] = 0xFF;
for(i = 0; i < length; i += 4) {
j = *(payload++); //0
j += 256 * (*(payload++)); //1
NOR[addr + i] = 0x40;
NORWORD[(addr + i) / 2] = j; //0x1100
NOR[addr] = 0x70;
/* Wait for it to be ready */
while(NOR[addr] != 0x80);
NOR[addr]=0xFF;
j = *(payload++); //2
j += 256 * (*(payload++)); //3
NOR[addr + i] = 0x40;
NORWORD[((addr + i) / 2) + 1] = j; //0x3322
NOR[addr] = 0x70;
/* Wait for it to be ready */
while(NOR[addr] != 0x80);
NOR[addr] = 0xFF;
}
}