From d0b5c3ba7fb6d428b8c8d42cb024942a0815d203 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Sat, 31 Oct 2015 23:26:09 +0800 Subject: [PATCH] runtime: startup kernel support --- soc/runtime/bridge.c | 4 --- soc/runtime/bridge_ctl.c | 13 --------- soc/runtime/bridge_ctl.h | 2 -- soc/runtime/clock.c | 2 +- soc/runtime/dds.c | 13 --------- soc/runtime/dds.h | 1 - soc/runtime/kloader.c | 56 ++++++++++++++++++++++++++++++++------- soc/runtime/kloader.h | 3 ++- soc/runtime/main.c | 9 +------ soc/runtime/messages.h | 1 - soc/runtime/rtiocrg.c | 14 +++++----- soc/runtime/session.c | 57 ++++++++++++++++++++++++++++------------ soc/runtime/session.h | 1 + 13 files changed, 98 insertions(+), 78 deletions(-) diff --git a/soc/runtime/bridge.c b/soc/runtime/bridge.c index 3c4097c39..8ae83c1cc 100644 --- a/soc/runtime/bridge.c +++ b/soc/runtime/bridge.c @@ -66,10 +66,6 @@ void bridge_main(void) mailbox_acknowledge(); break; } - case MESSAGE_TYPE_BRG_DDS_INITALL: - dds_init_all(); - mailbox_acknowledge(); - break; case MESSAGE_TYPE_BRG_DDS_SEL: { struct msg_brg_dds_sel *msg; diff --git a/soc/runtime/bridge_ctl.c b/soc/runtime/bridge_ctl.c index 14a042a0d..11182efb9 100644 --- a/soc/runtime/bridge_ctl.c +++ b/soc/runtime/bridge_ctl.c @@ -23,11 +23,6 @@ void brg_start(void) } } -void brg_stop(void) -{ - kloader_stop(); -} - void brg_ttloe(int n, int value) { struct msg_brg_ttl_out msg; @@ -48,14 +43,6 @@ void brg_ttlo(int n, int value) mailbox_send_and_wait(&msg); } -void brg_ddsinitall(void) -{ - struct msg_base msg; - - msg.type = MESSAGE_TYPE_BRG_DDS_INITALL; - mailbox_send_and_wait(&msg); -} - void brg_ddssel(int channel) { struct msg_brg_dds_sel msg; diff --git a/soc/runtime/bridge_ctl.h b/soc/runtime/bridge_ctl.h index d87f83812..e6d2b7306 100644 --- a/soc/runtime/bridge_ctl.h +++ b/soc/runtime/bridge_ctl.h @@ -2,12 +2,10 @@ #define __BRIDGE_CTL_H void brg_start(void); -void brg_stop(void); void brg_ttloe(int n, int value); void brg_ttlo(int n, int value); -void brg_ddsinitall(void); void brg_ddssel(int channel); void brg_ddsreset(void); unsigned int brg_ddsread(unsigned int address); diff --git a/soc/runtime/clock.c b/soc/runtime/clock.c index 171fb6f30..0d0d3f4c3 100644 --- a/soc/runtime/clock.c +++ b/soc/runtime/clock.c @@ -62,7 +62,7 @@ int watchdog_set(int ms) break; } if(id < 0) { - log("Failed to add watchdog"); + log("WARNING: Failed to add watchdog"); return id; } diff --git a/soc/runtime/dds.c b/soc/runtime/dds.c index f07684265..7d120a0cd 100644 --- a/soc/runtime/dds.c +++ b/soc/runtime/dds.c @@ -33,19 +33,6 @@ now += DURATION_WRITE; \ } while(0) -void dds_init_all(void) -{ - int i; - long long int now; - - now = rtio_get_counter() + 10000; - for(i=0;i #include "log.h" +#include "clock.h" #include "flash_storage.h" #include "mailbox.h" #include "messages.h" @@ -91,33 +92,50 @@ void kloader_start_user_kernel(kernel_function k) start_kernel_cpu((void *)k); } -void kloader_start_idle_kernel(void) +static int kloader_start_flash_kernel(char *key) { char buffer[32*1024]; - int len; + unsigned int len, remain; kernel_function k; if(!kernel_cpu_reset_read()) { - log("BUG: attempted to start kernel CPU while already running (idle kernel)"); - return; + log("BUG: attempted to start kernel CPU while already running (%s)", key); + return 0; } #if (defined CSR_SPIFLASH_BASE && defined SPIFLASH_PAGE_SIZE) - len = fs_read("idle_kernel", buffer, sizeof(buffer), NULL); + len = fs_read(key, buffer, sizeof(buffer), &remain); if(len <= 0) - return; + return 0; + if(remain) { + log("ERROR: %s too long", key); + return 0; + } if(!kloader_load(buffer, len)) { - log("Failed to load ELF binary for idle kernel"); - return; + log("ERROR: failed to load ELF binary (%s)", key); + return 0; } k = kloader_find("run"); if(!k) { - log("Failed to find entry point for ELF kernel"); - return; + log("ERROR: failed to find entry point for ELF kernel (%s)", key); + return 0; } start_kernel_cpu((void *)k); + return 1; +#else + return 0; #endif } +int kloader_start_startup_kernel(void) +{ + return kloader_start_flash_kernel("startup_kernel"); +} + +int kloader_start_idle_kernel(void) +{ + return kloader_start_flash_kernel("idle_kernel"); +} + void kloader_stop(void) { kernel_cpu_reset_write(1); @@ -140,6 +158,8 @@ int kloader_is_essential_kmsg(int msgtype) case MESSAGE_TYPE_NOW_INIT_REQUEST: case MESSAGE_TYPE_NOW_SAVE: case MESSAGE_TYPE_LOG: + case MESSAGE_TYPE_WATCHDOG_SET_REQUEST: + case MESSAGE_TYPE_WATCHDOG_CLEAR: return 1; default: return 0; @@ -179,6 +199,22 @@ void kloader_service_essential_kmsg(void) mailbox_acknowledge(); break; } + case MESSAGE_TYPE_WATCHDOG_SET_REQUEST: { + struct msg_watchdog_set_request *msg = (struct msg_watchdog_set_request *)umsg; + struct msg_watchdog_set_reply reply; + + reply.type = MESSAGE_TYPE_WATCHDOG_SET_REPLY; + reply.id = watchdog_set(msg->ms); + mailbox_send_and_wait(&reply); + break; + } + case MESSAGE_TYPE_WATCHDOG_CLEAR: { + struct msg_watchdog_clear *msg = (struct msg_watchdog_clear *)umsg; + + watchdog_clear(msg->id); + mailbox_acknowledge(); + break; + } default: /* handled elsewhere */ break; diff --git a/soc/runtime/kloader.h b/soc/runtime/kloader.h index ceefbc89d..8f6091d28 100644 --- a/soc/runtime/kloader.h +++ b/soc/runtime/kloader.h @@ -12,7 +12,8 @@ int kloader_load(void *buffer, int length); kernel_function kloader_find(const char *name); void kloader_start_bridge(void); -void kloader_start_idle_kernel(void); +int kloader_start_startup_kernel(void); +int kloader_start_idle_kernel(void); void kloader_start_user_kernel(kernel_function k); void kloader_stop(void); diff --git a/soc/runtime/main.c b/soc/runtime/main.c index bdd9d4b8c..f020b74ea 100644 --- a/soc/runtime/main.c +++ b/soc/runtime/main.c @@ -30,13 +30,6 @@ #include "session.h" #include "moninj.h" -static void common_init(void) -{ - brg_start(); - brg_ddsinitall(); - kloader_stop(); -} - #ifdef CSR_ETHMAC_BASE u32_t sys_now(void) @@ -260,7 +253,7 @@ int main(void) test_main(); } else { puts("Entering regular mode."); - common_init(); + session_startup_kernel(); regular_main(); } return 0; diff --git a/soc/runtime/messages.h b/soc/runtime/messages.h index 221b394a3..4a4e10737 100644 --- a/soc/runtime/messages.h +++ b/soc/runtime/messages.h @@ -19,7 +19,6 @@ enum { MESSAGE_TYPE_BRG_READY, MESSAGE_TYPE_BRG_TTL_O, MESSAGE_TYPE_BRG_TTL_OE, - MESSAGE_TYPE_BRG_DDS_INITALL, MESSAGE_TYPE_BRG_DDS_SEL, MESSAGE_TYPE_BRG_DDS_RESET, MESSAGE_TYPE_BRG_DDS_READ_REQUEST, diff --git a/soc/runtime/rtiocrg.c b/soc/runtime/rtiocrg.c index 255f2a308..de56fde0d 100644 --- a/soc/runtime/rtiocrg.c +++ b/soc/runtime/rtiocrg.c @@ -1,6 +1,6 @@ -#include #include +#include "log.h" #include "clock.h" #include "flash_storage.h" #include "rtiocrg.h" @@ -17,17 +17,17 @@ void rtiocrg_init(void) clk = 0; fs_read("startup_clock", &b, 1, NULL); if(b == 'i') - printf("Startup RTIO clock: internal\n"); + log("Startup RTIO clock: internal"); else if(b == 'e') { - printf("Startup RTIO clock: external\n"); + log("Startup RTIO clock: external"); clk = 1; } else - printf("WARNING: unknown startup_clock entry in flash storage\n"); + log("ERROR: unrecognized startup_clock entry in flash storage"); if(!rtiocrg_switch_clock(clk)) { - printf("WARNING: startup RTIO clock failed\n"); - printf("WARNING: this may cause the system initialization to fail\n"); - printf("WARNING: fix clocking and reset the device\n"); + log("ERROR: startup RTIO clock failed"); + log("WARNING: this may cause the system initialization to fail"); + log("WARNING: fix clocking and reset the device"); } } diff --git a/soc/runtime/session.c b/soc/runtime/session.c index c0908639c..a76a51687 100644 --- a/soc/runtime/session.c +++ b/soc/runtime/session.c @@ -64,6 +64,44 @@ enum { USER_KERNEL_WAIT_RPC /* < must come after _RUNNING */ }; +void session_startup_kernel(void) +{ + struct msg_base *umsg; + + now = -1; + watchdog_init(); + if(!kloader_start_startup_kernel()) + return; + + while(1) { + kloader_service_essential_kmsg(); + + umsg = mailbox_receive(); + if(umsg) { + if(!kloader_validate_kpointer(umsg)) + break; + if(kloader_is_essential_kmsg(umsg->type)) + continue; + if(umsg->type == MESSAGE_TYPE_FINISHED) + break; + else if(umsg->type == MESSAGE_TYPE_EXCEPTION) { + log("WARNING: startup kernel ended with exception"); + break; + } else { + log("ERROR: received invalid message type from kernel CPU"); + break; + } + } + + if(watchdog_expired()) { + log("WARNING: watchdog expired in startup kernel"); + break; + } + } + kloader_stop(); + log("Startup kernel terminated"); +} + void session_start(void) { buffer_in_index = 0; @@ -77,6 +115,7 @@ void session_end(void) { kloader_stop(); now = -1; + watchdog_init(); kloader_start_idle_kernel(); } @@ -490,22 +529,6 @@ static int process_kmsg(struct msg_base *umsg) mailbox_acknowledge(); break; } - case MESSAGE_TYPE_WATCHDOG_SET_REQUEST: { - struct msg_watchdog_set_request *msg = (struct msg_watchdog_set_request *)umsg; - struct msg_watchdog_set_reply reply; - - reply.type = MESSAGE_TYPE_WATCHDOG_SET_REPLY; - reply.id = watchdog_set(msg->ms); - mailbox_send_and_wait(&reply); - break; - } - case MESSAGE_TYPE_WATCHDOG_CLEAR: { - struct msg_watchdog_clear *msg = (struct msg_watchdog_clear *)umsg; - - watchdog_clear(msg->id); - mailbox_acknowledge(); - break; - } case MESSAGE_TYPE_RPC_REQUEST: { struct msg_rpc_request *msg = (struct msg_rpc_request *)umsg; @@ -516,7 +539,7 @@ static int process_kmsg(struct msg_base *umsg) break; } default: { - log("Received invalid message type from kernel CPU"); + log("ERROR: received invalid message type from kernel CPU"); return 0; } } diff --git a/soc/runtime/session.h b/soc/runtime/session.h index 988d0f6b0..5728103ae 100644 --- a/soc/runtime/session.h +++ b/soc/runtime/session.h @@ -1,6 +1,7 @@ #ifndef __SESSION_H #define __SESSION_H +void session_startup_kernel(void); void session_start(void); void session_end(void);