diff --git a/artiq/runtime/kloader.c b/artiq/runtime/kloader.c index cf8c9610c..06cf737c5 100644 --- a/artiq/runtime/kloader.c +++ b/artiq/runtime/kloader.c @@ -1,8 +1,6 @@ #include #include -#include - #include "kloader.h" #include "log.h" #include "clock.h" @@ -10,8 +8,13 @@ #include "mailbox.h" #include "messages.h" -static void start_kernel_cpu(struct msg_load_request *msg) +int kloader_load_library(const void *library) { + if(!kernel_cpu_reset_read()) { + core_log("BUG: attempted to load kernel library while kernel CPU is running\n"); + return 0; + } + // Stop kernel CPU before messing with its code. kernel_cpu_reset_write(1); @@ -22,22 +25,15 @@ static void start_kernel_cpu(struct msg_load_request *msg) &_binary_ksupport_elf_end - &_binary_ksupport_elf_start); // Start kernel CPU. - mailbox_send(msg); kernel_cpu_reset_write(0); -} -static int load_or_start_kernel(const void *library, int run_kernel) -{ - static struct dyld_info library_info; struct msg_load_request request = { - .library = library, - .library_info = &library_info, - .run_kernel = run_kernel, + .type = MESSAGE_TYPE_LOAD_REQUEST, + .library = library, }; - start_kernel_cpu(&request); + mailbox_send(&request); struct msg_load_reply *reply = mailbox_wait_and_receive(); - mailbox_acknowledge(); if(reply->type != MESSAGE_TYPE_LOAD_REPLY) { core_log("BUG: unexpected reply to load/run request\n"); @@ -52,14 +48,14 @@ static int load_or_start_kernel(const void *library, int run_kernel) return 1; } -int kloader_load_library(const void *library) +void kloader_start_kernel() { - if(!kernel_cpu_reset_read()) { - core_log("BUG: attempted to load kernel library while kernel CPU is running\n"); - return 0; + if(kernel_cpu_reset_read()) { + core_log("BUG: attempted to load kernel library while kernel CPU is stopped\n"); + return; } - return load_or_start_kernel(library, 0); + mailbox_acknowledge(); } void kloader_filter_backtrace(struct artiq_backtrace_item *backtrace, @@ -78,11 +74,6 @@ void kloader_filter_backtrace(struct artiq_backtrace_item *backtrace, *backtrace_size = cursor - backtrace; } -void kloader_start_kernel() -{ - load_or_start_kernel(NULL, 1); -} - static int kloader_start_flash_kernel(char *key) { #if (defined CSR_SPIFLASH_BASE && defined CONFIG_SPIFLASH_PAGE_SIZE) @@ -98,7 +89,10 @@ static int kloader_start_flash_kernel(char *key) return 0; } - return load_or_start_kernel(buffer, 1); + if(!kloader_load_library(buffer)) + return 0; + kloader_start_kernel(); + return 1; #else return 0; #endif diff --git a/artiq/runtime/ksupport.c b/artiq/runtime/ksupport.c index 5bf530cbe..00066cda3 100644 --- a/artiq/runtime/ksupport.c +++ b/artiq/runtime/ksupport.c @@ -370,44 +370,40 @@ static void now_save(void) int main(void); int main(void) { - struct msg_load_request *request = mailbox_receive(); + static struct dyld_info library_info; + + struct msg_load_request *request = mailbox_wait_and_receive(); struct msg_load_reply load_reply = { .type = MESSAGE_TYPE_LOAD_REPLY, .error = NULL }; - if(request->library != NULL) { - if(!dyld_load(request->library, KERNELCPU_PAYLOAD_ADDRESS, - resolve_runtime_export, request->library_info, - &load_reply.error)) { - mailbox_send(&load_reply); - while(1); - } - - void *__bss_start = dyld_lookup("__bss_start", request->library_info); - void *_end = dyld_lookup("_end", request->library_info); - memset(__bss_start, 0, _end - __bss_start); - } - - if(request->run_kernel) { - void (*kernel_run)() = request->library_info->init; - void *typeinfo = dyld_lookup("typeinfo", request->library_info); - - mailbox_send_and_wait(&load_reply); - - now_init(); - kernel_run(); - now_save(); - - attribute_writeback(typeinfo); - - struct msg_base finished_reply; - finished_reply.type = MESSAGE_TYPE_FINISHED; - mailbox_send_and_wait(&finished_reply); - } else { + if(!dyld_load(request->library, KERNELCPU_PAYLOAD_ADDRESS, + resolve_runtime_export, &library_info, + &load_reply.error)) { mailbox_send(&load_reply); + while(1); } + void *__bss_start = dyld_lookup("__bss_start", &library_info); + void *_end = dyld_lookup("_end", &library_info); + memset(__bss_start, 0, _end - __bss_start); + + void (*kernel_run)() = library_info.init; + void *typeinfo = dyld_lookup("typeinfo", &library_info); + + mailbox_send_and_wait(&load_reply); + + now_init(); + kernel_run(); + now_save(); + + attribute_writeback(typeinfo); + + struct msg_base finished_reply; + finished_reply.type = MESSAGE_TYPE_FINISHED; + mailbox_send_and_wait(&finished_reply); + while(1); } diff --git a/artiq/runtime/messages.h b/artiq/runtime/messages.h index f16b4a1c3..6b72e0c4b 100644 --- a/artiq/runtime/messages.h +++ b/artiq/runtime/messages.h @@ -6,6 +6,7 @@ #include enum { + MESSAGE_TYPE_LOAD_REQUEST, MESSAGE_TYPE_LOAD_REPLY, MESSAGE_TYPE_NOW_INIT_REQUEST, MESSAGE_TYPE_NOW_INIT_REPLY, @@ -33,9 +34,8 @@ struct msg_base { /* kernel messages */ struct msg_load_request { + int type; const void *library; - struct dyld_info *library_info; - int run_kernel; }; struct msg_load_reply { diff --git a/artiq/runtime/session.c b/artiq/runtime/session.c index bbe89cb47..7e8236e86 100644 --- a/artiq/runtime/session.c +++ b/artiq/runtime/session.c @@ -929,6 +929,11 @@ static int process_kmsg(struct msg_base *umsg) return 0; if(kloader_is_essential_kmsg(umsg->type)) return 1; /* handled elsewhere */ + if(user_kernel_state == USER_KERNEL_LOADED && + umsg->type == MESSAGE_TYPE_LOAD_REPLY) { + // Kernel standing by. + return 1; + } if(user_kernel_state == USER_KERNEL_WAIT_RPC && umsg->type == MESSAGE_TYPE_RPC_RECV_REQUEST) { // Handled and acknowledged when we receive