summaryrefslogtreecommitdiffstats
path: root/src/target/firmware/apps
diff options
context:
space:
mode:
authorIngo Albrecht <prom@berlin.ccc.de>2010-04-11 07:26:42 +0200
committerIngo Albrecht <prom@berlin.ccc.de>2010-07-20 14:41:19 +0200
commit3936c397a7918fa8625355b5af39a371da6adc3a (patch)
treee3bbd8b7e44aad22531098f856516ed360da126b /src/target/firmware/apps
parentd602dcaafb8d1d2018ca9a6ee2f7472480a4f972 (diff)
loader: flash locking commands, various flash rework
Diffstat (limited to 'src/target/firmware/apps')
-rw-r--r--src/target/firmware/apps/loader/main.c160
-rw-r--r--src/target/firmware/apps/loader/protocol.h27
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,
};