static struct bsc_fd connection;
+static struct {
+ unsigned char quit;
+} osmoload;
+
static int usage(const char *name)
{
printf("\nUsage: %s [ -v | -h ] [ -m {c123,c155} ] [ -l /tmp/osmocom_loader ] COMMAND\n", name);
static void
loader_handle_reply(struct msgb *msg) {
- printf("Received ");
- hexdump(msg->data, msg->len);
+ uint8_t cmd = msgb_get_u8(msg);
+
+ uint8_t length;
+ uint32_t address;
+
+ switch(cmd) {
+ case LOADER_PING:
+ printf("Received pong.\n");
+ osmoload.quit = 1;
+ break;
+ case LOADER_RESET:
+ printf("Reset confirmed.\n");
+ osmoload.quit = 1;
+ break;
+ case LOADER_POWEROFF:
+ printf("Poweroff confirmed.\n");
+ osmoload.quit = 1;
+ break;
+ case LOADER_ENTER_ROM_LOADER:
+ printf("Jump to ROM loader confirmed.\n");
+ osmoload.quit = 1;
+ break;
+ case LOADER_ENTER_FLASH_LOADER:
+ printf("Jump to flash loader confirmed.\n");
+ osmoload.quit = 1;
+ break;
+ case LOADER_MEM_READ:
+ length = msgb_get_u8(msg);
+ address = msgb_get_u32(msg);
+ printf("Received memory dump of %d bytes at 0x%x:\n", length, address);
+ hexdump(msgb_get(msg, length), length);
+ osmoload.quit = 1;
+ break;
+ case LOADER_MEM_WRITE:
+ length = msgb_get_u8(msg);
+ address = msgb_get_u32(msg);
+ printf("Confirmed memory write of %d bytes at 0x%x.\n", length, address);
+ osmoload.quit = 1;
+ break;
+ default:
+ printf("Received unknown reply for command %d:\n");
+ hexdump(msg->data, msg->len);
+ osmoload.quit = 1;
+ break;
+ }
}
static int
}
}
+static void
+loader_send_simple(uint8_t command) {
+ struct msgb *msg = msgb_alloc(MSGB_MAX, "loader");
+ msgb_put_u8(msg, command);
+ loader_send_request(msg);
+ msgb_free(msg);
+}
+
+static void
+loader_send_memread(uint8_t length, uint32_t address) {
+ struct msgb *msg = msgb_alloc(MSGB_MAX, "loader");
+ msgb_put_u8(msg, LOADER_MEM_READ);
+ msgb_put_u8(msg, 128);
+ msgb_put_u32(msg, 0x00810000);
+ loader_send_request(msg);
+ msgb_free(msg);
+}
+
+static void
+loader_send_memwrite(uint8_t length, uint32_t address, void *data) {
+ struct msgb *msg = msgb_alloc(MSGB_MAX, "loader");
+ msgb_put_u8(msg, LOADER_MEM_WRITE);
+ msgb_put_u8(msg, length);
+ msgb_put_u32(msg, address);
+ memcpy(msgb_put(msg, 128), data, length);
+ loader_send_request(msg);
+ msgb_free(msg);
+}
+
static void
loader_command(char *name, int cmdc, char **cmdv) {
if(!cmdc) {
usage(name);
}
+ struct msgb *msg;
char *cmd = cmdv[0];
+ char buf[256];
+ memset(buf, 23, sizeof(buf));
+
printf("Command %s\n", cmd);
if(!strcmp(cmd, "ping")) {
- struct msgb *msg = msgb_alloc(MSGB_MAX, "loader");
- msgb_put_u8(msg, LOADER_PING);
- msgb_put_u8(msg, 0);
- loader_send_request(msg);
- msgb_free(msg);
+ loader_send_simple(LOADER_PING);
+ } else if(!strcmp(cmd, "memread")) {
+ loader_send_memread(128, 0x810000);
+ } else if(!strcmp(cmd, "memwrite")) {
+ loader_send_memwrite(128, 0x810000, buf);
+ } else if(!strcmp(cmd, "off")) {
+ loader_send_simple(LOADER_POWEROFF);
+ } else if(!strcmp(cmd, "reset")) {
+ loader_send_simple(LOADER_RESET);
+ } else if(!strcmp(cmd, "romload")) {
+ loader_send_simple(LOADER_ENTER_ROM_LOADER);
+ } else if(!strcmp(cmd, "flashload")) {
+ loader_send_simple(LOADER_ENTER_FLASH_LOADER);
} else {
printf("Unknown command '%s'\n", cmd);
usage(name);
}
}
+ osmoload.quit = 0;
+
loader_connect(loader_un_path);
loader_command(argv[0], argc - optind, argv + optind);
+ while(!osmoload.quit) {
+ bsc_select_main(0);
+ }
+
return 0;
}
uint8_t data[0];
} __attribute__((__packed__));
-uint32_t htonl(uint32_t hostlong) {
-#if BYTE_ORDER==LITTLE_ENDIAN
- return (hostlong>>24) | ((hostlong&0xff0000)>>8) |
- ((hostlong&0xff00)<<8) | (hostlong<<24);
-#else
- return hostlong;
-#endif
-}
-
-uint32_t ntohl(uint32_t hostlong) __attribute__((weak,alias("htonl")));
-
-uint16_t htons(uint16_t hostshort) {
-#if BYTE_ORDER==LITTLE_ENDIAN
- return ((hostshort>>8)&0xff) | (hostshort<<8);
-#else
- return hostshort;
-#endif
-}
-
-uint16_t ntohs(uint16_t hostshort) __attribute__((weak,alias("htons")));
-
-#define SCAN
-
-#ifdef SCAN
-/* if scanning is enabled, scan from 0 ... 124 */
-#define BASE_ARFCN 0
-#else
-/* fixed ARFCN in GSM1800 at which Harald has his GSM test license */
-#define BASE_ARFCN 871
-#endif
-
/* Main Program */
const char *hr = "======================================================================\n";
int flag = 0;
-void poweroff(void) {
+static void flush_uart(void) {
unsigned i;
- for(i = 0; i < 10; i++) {
+ for(i = 0; i < 500; i++) {
uart_poll(SERCOMM_UART_NR);
- delay_ms(10);
+ delay_ms(1);
}
+}
+
+static void device_poweroff(void) {
+ flush_uart();
twl3025_power_off();
}
+static void device_reset(void) {
+ flush_uart();
+ wdog_reset();
+}
+
+static void device_enter_loader(unsigned char bootrom) {
+ flush_uart();
+ puts("XXX: loader entry is broken\n");
+ return;
+
+ /* XXX: this is not working (with or without bootrom) */
+ calypso_bootrom(bootrom);
+ void (*entry)( void ) = (void (*)(void))0;
+ 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");
+ }
+ msgb_put_u8(msg, command);
+ sercomm_sendmsg(dlci, msg);
+}
+
int main(void)
{
/* Always disable wdt (some platforms enable it on boot) */
sercomm_init();
/* Say hi */
- puts("\n\nOSMOCOM Calypso loader\n");
+ puts("\n\nOSMOCOM Calypso loader (revision " GIT_REVISION ")\n");
puts(hr);
/* Set up a key handler for powering off */
/* Set up loader communications */
sercomm_register_rx_cb(SC_DLCI_LOADER, &cmd_handler);
+ /* Notify any running osmoload about our startup */
+ loader_send_simple(SC_DLCI_LOADER, LOADER_INIT);
+
/* Wait for events */
while (1) {
keypad_poll();
return;
}
- uint8_t command = 0; //= msgb_get_u8(msg);
-
- printf("command %u\n", command);
+ uint8_t command = msgb_get_u8(msg);
- msgb_free(msg);
-
- return;
+ printf("command %u: ", command);
uint8_t nbytes;
uint32_t address;
switch(command) {
case LOADER_PING:
+ puts("ping\n");
+ loader_send_simple(dlci, LOADER_PING);
+ break;
+
+ case LOADER_RESET:
+ puts("reset\n");
+ loader_send_simple(dlci, LOADER_RESET);
+ device_reset();
+ break;
- printf("ping\n");
+ case LOADER_POWEROFF:
+ puts("poweroff\n");
+ loader_send_simple(dlci, LOADER_POWEROFF);
+ device_poweroff();
+ break;
- //sercomm_sendmsg(dlci, msg);
- //msg = NULL;
+ case LOADER_ENTER_ROM_LOADER:
+ puts("jump to rom loader\n");
+ loader_send_simple(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);
+ device_enter_loader(0);
break;
case LOADER_MEM_READ:
reply = sercomm_alloc_msgb(6 + nbytes);
+ if(!reply) {
+ printf("Failed to allocate reply buffer!\n");
+ }
+
msgb_put_u8(reply, LOADER_MEM_READ);
msgb_put_u8(reply, nbytes);
msgb_put_u32(reply, address);
break;
- }
+ case LOADER_MEM_WRITE:
+
+ nbytes = msgb_get_u8(msg);
+ address = msgb_get_u32(msg);
+
+ printf("mem write %u @ %p\n", nbytes, (void*)address);
+
+ memcpy((void*)address, msgb_get(msg, nbytes), nbytes);
+
+ reply = sercomm_alloc_msgb(6);
+
+ if(!reply) {
+ printf("Failed to allocate reply buffer!\n");
+ }
+
+ msgb_put_u8(reply, LOADER_MEM_WRITE);
+ msgb_put_u8(reply, nbytes);
+ msgb_put_u32(reply, address);
+
+ sercomm_sendmsg(dlci, reply);
+
+ break;
- if(msg) {
- msgb_free(msg);
}
+
+ msgb_free(msg);
}
static void key_handler(enum key_codes code, enum key_states state)
switch (code) {
case KEY_POWER:
- poweroff();
+ puts("Powering off due to keypress.\n");
+ device_poweroff();
+ break;
+ case KEY_OK:
+ puts("Resetting due to keypress.\n");
+ device_reset();
break;
default:
break;