safety checkin of fwflash tool (hacking counterpart (lpcload) atm)
authorhackbard <hackbard@staubsauger.localdomain>
Fri, 31 Aug 2007 13:00:12 +0000 (15:00 +0200)
committerhackbard <hackbard@staubsauger.localdomain>
Fri, 31 Aug 2007 13:00:12 +0000 (15:00 +0200)
betty/fwflash.c

index 508b09c..8b89941 100644 (file)
  * defines
  */
 
-/* bank 0/2 addr */
+/* bank 0/2 and boootloader addr/size */
 #define BANK0                  0x80000000
 #define BANK2                  0x82000000
+#define BANK_SIZE              0x00100000
+#define BOOTLOADER             0x7fffe000
+#define BL_SIZE                        0x00000800
 
 /* flash cmd addresses - flash[0-18] <--> arm[1-19]*/
 #define B0F555 (*((volatile unsigned long *)(BANK0|0xaaa)))    // 0x555
@@ -30,6 +33,7 @@
 /* commands */
 #define CMD_READ               'R'
 #define CMD_CHIP_ERASE         'E'
+#define CMD_CHIP_ID            'I'
 
 #define BUFSIZE                        16
 
@@ -42,33 +46,102 @@ typedef unsigned short u16;
 typedef unsigned int u32;
 
 /*
- * define macros
+ * functions
  */
 
-#define TX_BYTE(x)             while(!(UART0_LSR&(1<<5))) continue; \
-                               UART0_THR=x
+void mmap_init(u8 memtype) {
 
-#define TX_NL                  TX_BYTE('\n'); TX_BYTE('\r')
+       MEMMAP=memtype;
+}
 
-#define TX_STRING(x,len)       for(scnt=0;scnt<len;scnt++) {   \
-                                       TX_BYTE(x[scnt]);       \
-                               }                               \
-                               TX_NL
+void uart0_init(void) {
 
-/*
- * function prototypes
- */
+       PINSEL0=0x05;                   // pin select -> tx, rx
+       UART0_FCR=0x07;                 // enable fifo
+       UART0_LCR=0x83;                 // set dlab + word length
+       UART0_DLL=0x10;                 // br: 9600 @ 10/4 mhz
+       UART0_DLM=0x00;
+       UART0_LCR=0x03;                 // unset dlab
+}
 
-void mmap_init(u8 memtype);
-void uart0_init(void);
-void uart0_send_string(char *txbuf);
-void uart0_send_char(char send);
+void uart0_send_string(char *txbuf) {
 
-/*
- * global variables
- */
+       int i;
+
+       i=0;
+
+       while(txbuf[i]) {
+               UART0_THR=txbuf[i++];
+               /* flush if tx buffer maximum reached */
+               if(!(i%16))
+                       while(!(UART0_LSR&(1<<6)))
+                               continue;
+       }
+       
+       /* flush if \n and \r do not fit in the tx buffer */
+       if(i>14)
+               while(!(UART0_LSR&(1<<6)))
+                       continue;
 
-int scnt;
+       UART0_THR='\n';
+       UART0_THR='\r';
+
+       /* flush uart0 anyways */
+       while(!(UART0_LSR&(1<<6)))
+               continue;
+}
+
+void uart0_send_buf16(u16 *buf,int len) {
+
+       int i;
+
+       i=0;
+
+       for(i=0;i<len;i++) {
+               if(!(i%8))
+                       while(!(UART0_LSR&(1<<6)))
+                               continue;
+               UART0_THR=buf[i]&0xff;
+               UART0_THR=(buf[i]>>8)&0xff;
+       }
+}
+
+void uart0_send_buf32(u32 *buf,int len) {
+
+       int i;
+
+       i=0;
+
+       for(i=0;i<len;i++) {
+               if(!(i%4))
+                       while(!(UART0_LSR&(1<<6)))
+                               continue;
+               UART0_THR=buf[i]&0xff;
+               UART0_THR=(buf[i]>>8)&0xff;
+               UART0_THR=(buf[i]>>16)&0xff;
+               UART0_THR=(buf[i]>>24)&0xff;
+       }
+}
+
+void uart0_send_byte(u8 send) {
+
+       while(!(UART0_LSR&(1<<5)))
+               continue;
+
+       UART0_THR=send;
+}
+
+u8 uart0_get_byte(void) {
+
+       u8 rx;
+
+       while(!(UART0_LSR&(1<<0)))
+               continue;
+
+       rx=UART0_RBR;
+
+       return rx;
+}
 
 /*
  * main function
@@ -78,10 +151,9 @@ int main(void) {
 
        /* variables */
 
-       u32 i,addrlen,datalen;
+       u32 i,addrlen,datalen,addr;
        u8 buf[BUFSIZE];
-       u32 addr;
-       u16 *dptr;
+       u16 data;
        u8 cmd;
        u8 txrx;
 
@@ -90,18 +162,9 @@ int main(void) {
        //mmap_init(MMAP_RAM);
 
        /* uart initialization */
-
-       //uart0_init();
-
-       PINSEL0=0x05;                   // pin select -> tx, rx
-       UART0_FCR=0x07;                 // enable fifo
-       UART0_LCR=0x83;                 // set dlab + word length
-       UART0_DLL=0x10;                 // br: 9600 @ 10/4 mhz
-       UART0_DLM=0x00;
-       UART0_LCR=0x03;                 // unset dlab
+       uart0_init();
 
        /* external memory init */
-
        BCFG0=0x1000FBEF;               // BCFG2 should be fine as is
 
        /* begin the main loop */
@@ -110,52 +173,57 @@ int main(void) {
        /* receive cmd */
        while(1) {
 
-               while(!(UART0_LSR&(1<<0)))
-                       continue;
-               cmd=UART0_RBR;
-
-               if(cmd==CMD_CHIP_ERASE) {
-                       addrlen=0;
-                       datalen=1;
-                       break;
+               cmd=uart0_get_byte();
+               txrx=1;
+               switch(cmd) {
+                       case CMD_CHIP_ERASE:
+                               addrlen=0;
+                               datalen=1;
+                               break;
+                       case CMD_READ:
+                               addrlen=4;
+                               datalen=4;
+                               break;
+                       case CMD_CHIP_ID:
+                               addrlen=0;
+                               datalen=1;
+                               break;
+                       default:
+                               uart0_send_byte('f');
+                               txrx=0;
+                               break;
                }
 
-               if(cmd==CMD_READ) {
-                       addrlen=4;
-                       datalen=1;
+               if(txrx) {
+                       /* send an ack */
+                       uart0_send_byte(cmd);
                        break;
                }
        }
 
        /* receive (only if there is) more data from uart0 */
-
        addr=0;
        for(i=0;i<addrlen;i++) {
-               //TX_STRING("got addr",8);
-               while(!(UART0_LSR&(1<<0)))
-                       continue;
-               txrx=UART0_RBR;
-               //addr|=(txrx<<((addrlen-i-1)*4));
-               addr=0x80000000;
+               txrx=uart0_get_byte();
+               addr|=(txrx<<((addrlen-i-1)*8));
        }
 
-       for(i=0;i<datalen;i++) {
-               //TX_STRING("got data",8);
-               while(!(UART0_LSR&(1<<0)))
-                       continue;
-               buf[i]=UART0_RBR;
-       }
+       for(i=0;i<datalen;i++)
+               buf[i]=uart0_get_byte();
 
        /* process the cmd */
-
        switch(cmd) {
                case CMD_READ:
-                       dptr=(u16 *)addr;
-                       for(i=0;i<buf[0];i++) {
-                               TX_BYTE(*dptr);
-                               dptr++;
-                       }
-                       break;  
+                       /* data length to read */
+                       datalen=buf[0]<<24|buf[1]<<16|buf[2]<<8|buf[3];
+                       /* check addr and datalen */
+                       if((addr>=BANK0)&(addr+datalen<BANK0+BANK_SIZE))
+                               uart0_send_buf16((u16 *)addr,datalen);
+                       if((addr>=BANK2)&(addr+datalen<BANK2+BANK_SIZE))
+                               uart0_send_buf16((u16 *)addr,datalen);
+                       if((addr>=BOOTLOADER)&(addr+datalen<BOOTLOADER+BL_SIZE))
+                               uart0_send_buf32((u32 *)addr,datalen);
+                       break;
                case CMD_CHIP_ERASE:
                        if(buf[0]=='0') {
                                B0F555=0xaa;
@@ -173,57 +241,31 @@ int main(void) {
                                B2F2AA=0x55;
                                B2F555=0x10;
                        }
+                       uart0_send_byte(buf[0]);
+                       break;
+               case CMD_CHIP_ID:
+                       if(buf[0]=='0') {
+                               B0F555=0xaa;
+                               B0F2AA=0x55;
+                               B0F555=0x90;
+                               data=*((u16 *)BANK0);
+                               data=*((u16 *)(BANK0|0x200));
+                       }
+                       else if(buf[0]=='2') {
+                               B2F555=0xaa;
+                               B2F2AA=0x55;
+                               B2F555=0x90;
+                               data=*((u16 *)BANK2);
+                               data=*((u16 *)(BANK2|0x200));
+                       }
+                       uart0_send_buf16(&data,2);
                        break;
                default:
                        break;
        }
-
-       /* send an ack, the cmd! */
-       TX_BYTE(cmd);
                
        }
 
        return 0;
 }
 
-/*
- * functions
- */
-
-void mmap_init(u8 memtype) {
-
-       MEMMAP=memtype;
-}
-
-void uart0_init(void) {
-
-       PINSEL0=0x05;                   // pin select -> tx, rx
-       UART0_FCR=0x07;                 // enable fifo
-       UART0_LCR=0x83;                 // set dlab + word length
-       UART0_DLL=0x10;                 // br: 9600 @ 10/4 mhz
-       UART0_DLM=0x00;
-       UART0_LCR=0x03;                 // unset dlab
-}
-
-void uart0_send_string(char *txbuf) {
-
-       int i;
-
-       i=0;
-
-       while(txbuf[i])
-               UART0_THR=txbuf[i++];
-       UART0_THR='\n';
-       UART0_THR='\r';
-
-       while(!(UART0_LSR&(1<<6))) {}
-}
-
-void uart0_send_char(char send) {
-
-       while(!(UART0_LSR&(1<<5)))
-               continue;
-
-       UART0_THR=send;
-}
-