From aba2d3f112ffbd0bfea1657ed535a95c05fc57a7 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Sat, 25 Jul 2015 16:26:04 +0800 Subject: [PATCH] runtime: process essential kernel CPU messages at all time --- soc/runtime/kloader.c | 63 +++++++++++++++++++++++++++++++++++++++++++ soc/runtime/kloader.h | 6 +++++ soc/runtime/main.c | 5 +++- soc/runtime/session.c | 47 +++++--------------------------- 4 files changed, 80 insertions(+), 41 deletions(-) diff --git a/soc/runtime/kloader.c b/soc/runtime/kloader.c index f73723981..0cdf56634 100644 --- a/soc/runtime/kloader.c +++ b/soc/runtime/kloader.c @@ -4,6 +4,7 @@ #include "log.h" #include "flash_storage.h" #include "mailbox.h" +#include "messages.h" #include "elf_loader.h" #include "services.h" #include "kloader.h" @@ -122,3 +123,65 @@ void kloader_stop(void) kernel_cpu_reset_write(1); mailbox_acknowledge(); } + +int kloader_validate_kpointer(void *p) +{ + unsigned int v = (unsigned int)p; + if((v < 0x40400000) || (v > (0x4fffffff - 1024*1024))) { + log("Received invalid pointer from kernel CPU: 0x%08x", v); + return 0; + } + return 1; +} + +int kloader_is_essential_kmsg(int msgtype) +{ + switch(msgtype) { + case MESSAGE_TYPE_NOW_INIT_REQUEST: + case MESSAGE_TYPE_NOW_SAVE: + case MESSAGE_TYPE_LOG: + return 1; + default: + return 0; + } +} + +long long int now; + +void kloader_service_essential_kmsg(void) +{ + struct msg_base *umsg; + + umsg = mailbox_receive(); + if(umsg) { + if(!kloader_validate_kpointer(umsg)) + return; + switch(umsg->type) { + case MESSAGE_TYPE_NOW_INIT_REQUEST: { + struct msg_now_init_reply reply; + + reply.type = MESSAGE_TYPE_NOW_INIT_REPLY; + reply.now = now; + mailbox_send_and_wait(&reply); + break; + } + case MESSAGE_TYPE_NOW_SAVE: { + struct msg_now_save *msg = (struct msg_now_save *)umsg; + + now = msg->now; + mailbox_acknowledge(); + break; + } + case MESSAGE_TYPE_LOG: { + struct msg_log *msg = (struct msg_log *)umsg; + + log_va(msg->fmt, msg->args); + mailbox_acknowledge(); + break; + } + default: + /* handled elsewhere */ + break; + } + } +} diff --git a/soc/runtime/kloader.h b/soc/runtime/kloader.h index bf484b4e1..098a740b7 100644 --- a/soc/runtime/kloader.h +++ b/soc/runtime/kloader.h @@ -4,6 +4,8 @@ #define KERNELCPU_EXEC_ADDRESS 0x40400000 #define KERNELCPU_PAYLOAD_ADDRESS 0x40404000 +extern long long int now; + typedef void (*kernel_function)(void); int kloader_load(void *buffer, int length); @@ -14,4 +16,8 @@ void kloader_start_idle_kernel(void); void kloader_start_user_kernel(kernel_function k); void kloader_stop(void); +int kloader_validate_kpointer(void *p); +int kloader_is_essential_kmsg(int msgtype); +void kloader_service_essential_kmsg(void); + #endif /* __KLOADER_H */ diff --git a/soc/runtime/main.c b/soc/runtime/main.c index 4feb8c9a0..306f26b20 100644 --- a/soc/runtime/main.c +++ b/soc/runtime/main.c @@ -143,6 +143,7 @@ static void regular_main(void) session_end(); while(1) { lwip_service(); + kloader_service_essential_kmsg(); kserver_service(); } } @@ -201,8 +202,10 @@ static void regular_main(void) /* Open the session for the serial control. */ session_start(); - while(1) + while(1) { + kloader_service_essential_kmsg(); serial_service(); + } } #endif diff --git a/soc/runtime/session.c b/soc/runtime/session.c index 1a7f5d879..9b3591e30 100644 --- a/soc/runtime/session.c +++ b/soc/runtime/session.c @@ -11,8 +11,8 @@ #include "log.h" #include "kloader.h" #include "exceptions.h" -#include "session.h" #include "flash_storage.h" +#include "session.h" #define BUFFER_IN_SIZE (1024*1024) #define BUFFER_OUT_SIZE (1024*1024) @@ -55,7 +55,6 @@ static void submit_output(int len) } static int user_kernel_state; -static long long int now; enum { USER_KERNEL_NONE = 0, @@ -153,7 +152,7 @@ static int process_input(void) log("Attempted to switch RTIO clock while kernel running"); buffer_out[8] = REMOTEMSG_TYPE_CLOCK_SWITCH_FAILED; submit_output(9); - break; + break; } rtio_crg_clock_sel_write(buffer_in[9]); buffer_out[8] = REMOTEMSG_TYPE_CLOCK_SWITCH_COMPLETED; @@ -421,16 +420,6 @@ static int add_rpc_value(int bi, int type_tag, void *value) return bi - obi; } -static int validate_kpointer(void *p) -{ - unsigned int v = (unsigned int)p; - if((v < 0x40400000) || (v > (0x4fffffff - 1024*1024))) { - log("Received invalid pointer from kernel CPU: 0x%08x", v); - return 0; - } - return 1; -} - static int send_rpc_request(int rpc_num, va_list args) { int r; @@ -448,7 +437,7 @@ static int send_rpc_request(int rpc_num, va_list args) v = NULL; else { v = va_arg(args, void *); - if(!validate_kpointer(v)) + if(!kloader_validate_kpointer(v)) return 0; } r = add_rpc_value(bi, type_tag, v); @@ -467,31 +456,16 @@ static int send_rpc_request(int rpc_num, va_list args) /* assumes output buffer is empty when called */ static int process_kmsg(struct msg_base *umsg) { - if(!validate_kpointer(umsg)) + if(!kloader_validate_kpointer(umsg)) return 0; - if((user_kernel_state != USER_KERNEL_RUNNING) - && (umsg->type != MESSAGE_TYPE_NOW_INIT_REQUEST) - && (umsg->type != MESSAGE_TYPE_NOW_SAVE)) { + if(kloader_is_essential_kmsg(umsg->type)) + return 1; /* handled elsewhere */ + if(user_kernel_state != USER_KERNEL_RUNNING) { log("Received unexpected message from kernel CPU while not in running state"); return 0; } switch(umsg->type) { - case MESSAGE_TYPE_NOW_INIT_REQUEST: { - struct msg_now_init_reply reply; - - reply.type = MESSAGE_TYPE_NOW_INIT_REPLY; - reply.now = now; - mailbox_send_and_wait(&reply); - break; - } - case MESSAGE_TYPE_NOW_SAVE: { - struct msg_now_save *msg = (struct msg_now_save *)umsg; - - now = msg->now; - mailbox_acknowledge(); - break; - } case MESSAGE_TYPE_FINISHED: buffer_out[8] = REMOTEMSG_TYPE_KERNEL_FINISHED; submit_output(9); @@ -538,13 +512,6 @@ static int process_kmsg(struct msg_base *umsg) mailbox_acknowledge(); break; } - case MESSAGE_TYPE_LOG: { - struct msg_log *msg = (struct msg_log *)umsg; - - log_va(msg->fmt, msg->args); - mailbox_acknowledge(); - break; - } default: { log("Received invalid message type from kernel CPU"); return 0;