rendered paste body//coded by geohot, anonymous, and gray
//thanks to anonymous for the baseband "toolchain"
//just download arm-elf and run the bat file
typedef volatile unsigned int vu32;
typedef volatile unsigned short vu16;
typedef volatile unsigned char vu8;
//UART0
#define USART0_TXB *(vu32*)0xF1000020
#define USART0_RXB *(vu32*)0xF1000024
#define USART0_FCSTAT *(vu32*)0xF1000068
#define USART0_ICR *(vu32*)0xF1000070
#define WDT_CON0 *(vu32*)0xF4400024
#define WDT_CON1 *(vu32*)0xF4400028
#define WDT_STAT *(vu32*)0xF440002C //the top 4 bytes are the current wdt
#define STM_CLC *(vu32*)0xf4b00000
#define STM_TIM4 *(vu32*)0xf4b00020
//EBU
#define SDRMREF0 *(vu32*)0xF0000040
#define SDRMCON0 *(vu32*)0xF0000050
#define SDRMOD0 *(vu32*)0xF0000060
#define ADDRSEL0 *(vu32*)0xF0000080
#define ADDRSEL1 *(vu32*)0xF0000088
#define ADDRSEL4 *(vu32*)0xF00000A8
#define BUSCON0 *(vu32*)0xF00000C0
#define BUSCON1 *(vu32*)0xF00000C8
#define BUSCON4 *(vu32*)0xF00000E0
#define NOR ((unsigned char*)0xA0000000)
#define NORWORD ((unsigned short int*)0xA0000000)
#define MEM ((unsigned char*)0xA8000000)
unsigned char uart_rx_byte(void);
void uart_tx_byte(unsigned char byte);
void disablewdt();
void initflash();
void sendflashreset();
void halt();
void sendflashcmd(unsigned char cmd);
//void writeblock(int block, short int bytestowrite);
void readblock(int block, int length);
void writeblock(int block, int length);
void eraseblock(int addr);
int main()
{
unsigned int i=0;
unsigned short int j=0;
disablewdt();
initflash();
uart_tx_byte('U');
unsigned char waitbyte;
do
{
waitbyte = uart_rx_byte();
} while(waitbyte!=0xCC);
uart_tx_byte('T');
if(NOR[0]!=0x7E) //Make sure tp removed
{
uart_tx_byte('F');
halt();
}
/*for(i=0x3F0000;i<0x400000;i+=0x1000)
{
eraseblock(i);
}
sendflashreset();
uart_tx_byte('E');
writeblock(0x3F0000,0x10000);*/
//WRITE NOR
writeblock(0x20000,0x2E4000);
uart_tx_byte('D');
halt();
return 0;
}
/*
void writeblock(int addr, short int bytestowrite)
{
unsigned int i;
//first unlock the block
NOR[addr]=0xFF;
NOR[addr]=0x60;
NOR[addr]=0xD0; //Unlock
NOR[addr]=0xFF;
NOR[addr]=0xE9;
// NOR[addr]=0xE8;
while(NOR[addr]&0x80!=0x80); //wait for it to be ready
uart_tx_byte(NOR[addr]);
NORWORD[addr/2]=bytestowrite-1; //send size
for(i=0;i<bytestowrite;i+=2)
{
NORWORD[(addr+i)/2]=0x55AA; //0x1100
}
NOR[addr]=0xD0;
NOR[addr]=0x70;
while(NOR[addr]&0x80!=0x80); //wait for it to be ready
uart_tx_byte(NOR[addr]);
NOR[addr]=0xFF;
}
*/
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 readblock(int addr, int length)
{
unsigned int i;
for(i=0;i<length;i++)
{
uart_tx_byte(NOR[addr+i]);
}
}
void writeblock(int addr, int length)
{
unsigned int i;
//first unlock the blocks
for(i=0;i<length;i+=0x4000)
{
NOR[addr+i]=0xFF;
NOR[addr+i]=0x60;
NOR[addr+i]=0xD0; //Unlock
NOR[addr+i]=0xFF;
}
short int j;
//uart_tx_byte('E');
sendflashreset();
for(i=0;i<length;i+=4)
{
j=uart_rx_byte(); //0
j+=256*uart_rx_byte(); //1
NOR[addr+i]=0x40;
NORWORD[(addr+i)/2]=j; //0x1100
NOR[addr]=0x70;
while(NOR[addr]!=0x80); //wait for it to be ready
NOR[addr]=0xFF;
j=uart_rx_byte(); //2
j+=256*uart_rx_byte(); //3
NOR[addr+i]=0x40;
NORWORD[((addr+i)/2)+1]=j; //0x3322
NOR[addr]=0x70;
while(NOR[addr]!=0x80); //wait for it to be ready
NOR[addr]=0xFF;
}
}
void disablewdt()
{
WDT_CON0=0xED6800F1; //first(password)
WDT_CON0=0xAAAA00F2; //unlock endinit(modify)
WDT_CON1=8; //this is the disable request
WDT_CON0=0xAAAA00F8; //relock endinit(pw)
WDT_CON0=0xAAAA00F3; //relock endinit(modify)
}
void sendflashcmd(unsigned char cmd)
{
NOR[0xAAA]=0xAA;
NOR[0x554]=0x54;
NOR[0xAAA]=cmd;
}
void sendflashreset()
{
NOR[0]=0xFF;
}
void initflash()
{
ADDRSEL1=0xA8000041;
BUSCON1=0x30720200;
SDRMREF0=6;
SDRMCON0=0x891C70;
SDRMOD0=0x23;
ADDRSEL0=0xA0000011;
ADDRSEL4=0xA0000011;
BUSCON0=0x00522600;
BUSCON4=0x00522600;
}
void halt()
{
halt();
}
// waits until something received
unsigned char uart_rx_byte(void)
{
while( (USART0_FCSTAT & 4) == 0 );
USART0_ICR |= 4;
return USART0_RXB&255;
}
void uart_tx_byte(unsigned char byte)
{
unsigned int data = USART0_TXB;
data &= ~0xFF;
data |= byte;
USART0_TXB = data;
while( (USART0_FCSTAT&2) == 0 );
USART0_ICR |= 2;
}