Home | History | Annotate | Download | only in nandwrite
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  *  * Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  *  * Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in
     12  *    the documentation and/or other materials provided with the
     13  *    distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     18  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     19  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
     22  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     25  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  * SUCH DAMAGE.
     27  */
     28 
     29 #include <boot/boot.h>
     30 #include <boot/board.h>
     31 #include <boot/flash.h>
     32 
     33 #define FLASH_PAGE_SIZE 2048
     34 #define FLASH_PAGE_BITS 11
     35 
     36 int startswith(const char *str, const char *prefix)
     37 {
     38     while(*prefix){
     39         if(*prefix++ != *str++) return 0;
     40     }
     41     return 1;
     42 }
     43 
     44 void verify_flash(ptentry *p, void *addr, unsigned len, int extra)
     45 {
     46 	int offset = 0;
     47 	void *buf = alloc(FLASH_PAGE_SIZE + extra);
     48 	int verify_extra = extra;
     49 	if(verify_extra > 4)
     50 		verify_extra = 16;
     51 	while(len > 0) {
     52 		flash_read_ext(p, extra, offset, buf, FLASH_PAGE_SIZE);
     53 		if(memcmp(addr, buf, FLASH_PAGE_SIZE + verify_extra)) {
     54 			dprintf("verify failed at %x\n", offset);
     55 	        jtag_fail("verify failed");
     56 			return;
     57 		}
     58 		offset += FLASH_PAGE_SIZE;
     59 		addr += FLASH_PAGE_SIZE;
     60 		len -= FLASH_PAGE_SIZE;
     61 		if(extra) {
     62 			addr += extra;
     63 			len -= extra;
     64 		}
     65 	}
     66 	dprintf("verify done %d extra bytes\n", verify_extra);
     67 	jtag_okay("verify done");
     68 }
     69 
     70 void handle_flash(const char *name, unsigned addr, unsigned len)
     71 {
     72     int r;
     73     ptentry *p;
     74 
     75     dprintf("image @ %x (%d bytes)\n", addr, len);
     76     dprintf("write to '%s' partition\n", name);
     77 
     78     p = flash_find_ptn(name);
     79 
     80     if(p == 0) {
     81         jtag_fail("partition not found");
     82         return;
     83     } else {
     84         if(flash_init()) {
     85             jtag_fail("flash_init() failed");
     86             return;
     87         }
     88 
     89         dprintf("erasing flash @ %d (len=%d)\n", p->start, p->length);
     90         flash_erase(p);
     91 
     92         if(len) {
     93             dprintf("writing flash at @ %d\n", p->start);
     94 
     95             if(!strcmp(name, "system") || !strcmp(name, "userdata")) {
     96                 r = flash_write(p, 64, (void*) addr, len);
     97             } else {
     98                 len = (len + FLASH_PAGE_SIZE - 1) & (~(FLASH_PAGE_SIZE-1));
     99                 r = flash_write(p, 0, (void*) addr, len);
    100             }
    101 			//verify_flash(p, addr, len, (!strcmp(name, "system") || !strcmp(name, "userdata")) ? 64 : 0);
    102             if(r) {
    103                 jtag_fail("partition write failed");
    104             } else {
    105                 jtag_okay("partition written");
    106             }
    107             return;
    108         } else {
    109             jtag_okay("partition erased");
    110             return;
    111         }
    112     }
    113 }
    114 
    115 void hexdump(void *ptr, unsigned len)
    116 {
    117     unsigned char *b = ptr;
    118     int count = 0;
    119 
    120     dprintf("%x: ", (unsigned) b);
    121     while(len-- > 0) {
    122         dprintf("%b ", *b++);
    123         if(++count == 16) {
    124             dprintf("\n%x: ", (unsigned) b);
    125             count = 0;
    126         }
    127     }
    128     if(count != 0) dprintf("\n");
    129 }
    130 
    131 static unsigned char *tmpbuf = 0;
    132 
    133 void handle_dump(const char *name, unsigned offset)
    134 {
    135     ptentry *p;
    136 
    137     if(tmpbuf == 0) {
    138         tmpbuf = alloc(4096);
    139     }
    140 
    141     dprintf("dump '%s' partition\n", name);
    142     p = flash_find_ptn(name);
    143 
    144     if(p == 0) {
    145         jtag_fail("partition not found");
    146         return;
    147     }
    148 
    149     if(flash_init()) {
    150         jtag_fail("flash_init() failed");
    151         return;
    152     }
    153 
    154 #if 0
    155         /* XXX reimpl */
    156     if(flash_read_page(p->start * 64, tmpbuf, tmpbuf + 2048)){
    157         jtag_fail("flash_read() failed");
    158         return;
    159     }
    160 #endif
    161 
    162     dprintf("page %d data:\n", p->start * 64);
    163     hexdump(tmpbuf, 256);
    164     dprintf("page %d extra:\n", p->start * 64);
    165     hexdump(tmpbuf, 16);
    166     jtag_okay("done");
    167 }
    168 
    169 void handle_command(const char *cmd, unsigned a0, unsigned a1, unsigned a2)
    170 {
    171     if(startswith(cmd,"flash:")){
    172         handle_flash(cmd + 6, a0, a1);
    173         return;
    174     }
    175 
    176     if(startswith(cmd,"dump:")){
    177         handle_dump(cmd + 5, a0);
    178         return;
    179     }
    180 
    181     jtag_fail("unknown command");
    182 }
    183 
    184 int _main(void)
    185 {
    186     arm11_clock_init();
    187 
    188     dprintf_set_putc(jtag_dputc);
    189 
    190     board_init();
    191 
    192     jtag_cmd_loop(handle_command);
    193 
    194     return 0;
    195 }
    196