diff options
author | Ingo Albrecht <prom@berlin.ccc.de> | 2010-04-11 07:26:42 +0200 |
---|---|---|
committer | Ingo Albrecht <prom@berlin.ccc.de> | 2010-07-20 14:41:19 +0200 |
commit | 3936c397a7918fa8625355b5af39a371da6adc3a (patch) | |
tree | e3bbd8b7e44aad22531098f856516ed360da126b /src/target/firmware/apps | |
parent | d602dcaafb8d1d2018ca9a6ee2f7472480a4f972 (diff) |
loader: flash locking commands, various flash rework
Diffstat (limited to 'src/target/firmware/apps')
-rw-r--r-- | src/target/firmware/apps/loader/main.c | 160 | ||||
-rw-r--r-- | src/target/firmware/apps/loader/protocol.h | 27 |
2 files changed, 136 insertions, 51 deletions
diff --git a/src/target/firmware/apps/loader/main.c b/src/target/firmware/apps/loader/main.c index a3aefa8e..d1fdb317 100644 --- a/src/target/firmware/apps/loader/main.c +++ b/src/target/firmware/apps/loader/main.c @@ -48,8 +48,7 @@ #include <calypso/uart.h> #include <calypso/timer.h> -#include <layer1/sync.h> -#include <layer1/tpu_window.h> +#include <cfi_flash.h> #include "protocol.h" @@ -95,11 +94,7 @@ static void device_jump(void *entry) { } static void -loader_send_simple(uint8_t dlci, uint8_t command) { - struct msgb *msg = sercomm_alloc_msgb(1); - if(!msg) { - puts("Failed to allocate message buffer!\n"); - } +loader_send_simple(struct msgb *msg, uint8_t dlci, uint8_t command) { msgb_put_u8(msg, command); sercomm_sendmsg(dlci, msg); } @@ -108,16 +103,15 @@ extern unsigned char _start; static void loader_send_init(uint8_t dlci) { - struct msgb *msg = sercomm_alloc_msgb(1); - if(!msg) { - puts("Failed to allocate message buffer!\n"); - } + struct msgb *msg = sercomm_alloc_msgb(9); msgb_put_u8(msg, LOADER_INIT); msgb_put_u32(msg, 0); msgb_put_u32(msg, &_start); sercomm_sendmsg(dlci, msg); } +flash_t the_flash; + int main(void) { /* Always disable wdt (some platforms enable it on boot) */ @@ -137,6 +131,11 @@ int main(void) puts("\n\nOSMOCOM Calypso loader (revision " GIT_REVISION ")\n"); puts(hr); + /* Initialize flash driver */ + if(flash_init(&the_flash, 0)) { + puts("Failed to initialize flash!\n"); + } + /* Identify environment */ printf("Running on %s in environment %s\n", manifest_board, manifest_environment); @@ -167,42 +166,45 @@ static void cmd_handler(uint8_t dlci, struct msgb *msg) { uint8_t command = msgb_get_u8(msg); - printf("command %u: ", command); + int res; + + flash_lock_t lock; + uint8_t chip; uint8_t nbytes; uint16_t crc; uint32_t address; - struct msgb *reply; + struct msgb *reply = sercomm_alloc_msgb(256); // XXX + + if(!reply) { + printf("Failed to allocate reply buffer!\n"); + goto out; + } switch(command) { case LOADER_PING: - puts("ping\n"); - loader_send_simple(dlci, LOADER_PING); + loader_send_simple(reply, dlci, LOADER_PING); break; case LOADER_RESET: - puts("reset\n"); - loader_send_simple(dlci, LOADER_RESET); + loader_send_simple(reply, dlci, LOADER_RESET); device_reset(); break; case LOADER_POWEROFF: - puts("poweroff\n"); - loader_send_simple(dlci, LOADER_POWEROFF); + loader_send_simple(reply, dlci, LOADER_POWEROFF); device_poweroff(); break; case LOADER_ENTER_ROM_LOADER: - puts("jump to rom loader\n"); - loader_send_simple(dlci, LOADER_ENTER_ROM_LOADER); + loader_send_simple(reply, dlci, LOADER_ENTER_ROM_LOADER); device_enter_loader(1); break; case LOADER_ENTER_FLASH_LOADER: - puts("jump to flash loader\n"); - loader_send_simple(dlci, LOADER_ENTER_FLASH_LOADER); + loader_send_simple(reply, dlci, LOADER_ENTER_FLASH_LOADER); device_enter_loader(0); break; @@ -211,16 +213,11 @@ static void cmd_handler(uint8_t dlci, struct msgb *msg) { nbytes = msgb_get_u8(msg); address = msgb_get_u32(msg); - printf("mem read %u @ %p\n", nbytes, (void*)address); - - reply = sercomm_alloc_msgb(6 + nbytes); - - if(!reply) { - printf("Failed to allocate reply buffer!\n"); - } + crc = crc16(0, (void*)address, nbytes); msgb_put_u8(reply, LOADER_MEM_READ); msgb_put_u8(reply, nbytes); + msgb_put_u16(reply, crc); msgb_put_u32(reply, address); memcpy(msgb_put(reply, nbytes), (void*)address, nbytes); @@ -235,27 +232,14 @@ static void cmd_handler(uint8_t dlci, struct msgb *msg) { crc = msgb_get_u16(msg); address = msgb_get_u32(msg); - printf("mem write %u @ %p\n", nbytes, (void*)address); - void *data = msgb_get(msg, nbytes); uint16_t mycrc = crc16(0, data, nbytes); -#if 0 - printf("crc %x got %x\n", mycrc, crc); - hexdump(data, nbytes); -#endif - if(mycrc == crc) { memcpy((void*)address, data, nbytes); } - reply = sercomm_alloc_msgb(8); - - if(!reply) { - printf("Failed to allocate reply buffer!\n"); - } - msgb_put_u8(reply, LOADER_MEM_WRITE); msgb_put_u8(reply, nbytes); msgb_put_u16(reply, mycrc); @@ -269,29 +253,105 @@ static void cmd_handler(uint8_t dlci, struct msgb *msg) { address = msgb_get_u32(msg); - printf("jump to 0x%x\n", address); + msgb_put_u8(reply, LOADER_JUMP); + msgb_put_u32(reply, address); + + sercomm_sendmsg(dlci, reply); + + device_jump((void*)address); + + break; + + case LOADER_FLASH_INFO: - reply = sercomm_alloc_msgb(5); + msgb_put_u8(reply, LOADER_FLASH_INFO); + msgb_put_u8(reply, 1); // nchips - if(!reply) { - printf("Failed to allocate reply buffer!\n"); + // chip 1 + msgb_put_u32(reply, the_flash.f_base); + msgb_put_u32(reply, the_flash.f_size); + msgb_put_u8(reply, the_flash.f_nregions); + + int i; + for(i = 0; i < the_flash.f_nregions; i++) { + msgb_put_u32(reply, the_flash.f_regions[i].fr_bnum); + msgb_put_u32(reply, the_flash.f_regions[i].fr_bsize); } - msgb_put_u8(reply, LOADER_JUMP); + sercomm_sendmsg(dlci, reply); + + break; + + case LOADER_FLASH_ERASE: + case LOADER_FLASH_UNLOCK: + case LOADER_FLASH_LOCK: + case LOADER_FLASH_LOCKDOWN: + + chip = msgb_get_u8(msg); + address = msgb_get_u32(msg); + + if(command == LOADER_FLASH_ERASE) { + res = flash_block_erase(&the_flash, address); + } + if(command == LOADER_FLASH_UNLOCK) { + res = flash_block_unlock(&the_flash, address); + } + if(command == LOADER_FLASH_LOCK) { + res = flash_block_lock(&the_flash, address); + } + if(command == LOADER_FLASH_LOCKDOWN) { + res = flash_block_lockdown(&the_flash, address); + } + + msgb_put_u8(reply, command); + msgb_put_u8(reply, chip); msgb_put_u32(reply, address); + msgb_put_u32(reply, (res != 0)); sercomm_sendmsg(dlci, reply); - device_jump((void*)address); + break; + + case LOADER_FLASH_GETLOCK: + + chip = msgb_get_u8(msg); + address = msgb_get_u32(msg); + + lock = flash_block_getlock(&the_flash, address); + + msgb_put_u8(reply, command); + msgb_put_u8(reply, chip); + msgb_put_u32(reply, address); + + switch(lock) { + case FLASH_UNLOCKED: + msgb_put_u32(reply, LOADER_FLASH_UNLOCKED); + break; + case FLASH_LOCKED: + msgb_put_u32(reply, LOADER_FLASH_LOCKED); + break; + case FLASH_LOCKED_DOWN: + msgb_put_u32(reply, LOADER_FLASH_LOCKED_DOWN); + break; + default: + msgb_put_u32(reply, 0xFFFFFFFF); + break; + } + + sercomm_sendmsg(dlci, reply); break; default: printf("unknown command %d\n", command); - break; + msgb_free(reply); + + break; } + out: + msgb_free(msg); } diff --git a/src/target/firmware/apps/loader/protocol.h b/src/target/firmware/apps/loader/protocol.h index c2ea25ca..0a61c89e 100644 --- a/src/target/firmware/apps/loader/protocol.h +++ b/src/target/firmware/apps/loader/protocol.h @@ -1,12 +1,37 @@ enum loader_command { + /* init message from loader */ LOADER_INIT, + + /* ping / pong */ LOADER_PING, + + /* lifecycle requests */ LOADER_RESET, LOADER_POWEROFF, + + /* jumps */ + LOADER_JUMP, LOADER_ENTER_ROM_LOADER, LOADER_ENTER_FLASH_LOADER, + + /* generic memory ops */ LOADER_MEM_READ, LOADER_MEM_WRITE, - LOADER_JUMP, + + /* flash operations */ + LOADER_FLASH_INFO, + LOADER_FLASH_ERASE, + LOADER_FLASH_UNLOCK, + LOADER_FLASH_LOCK, + LOADER_FLASH_LOCKDOWN, + LOADER_FLASH_GETLOCK, + LOADER_FLASH_PROGRAM, + +}; + +enum loader_flash_lock { + LOADER_FLASH_UNLOCKED = 0, + LOADER_FLASH_LOCKED, + LOADER_FLASH_LOCKED_DOWN, }; |