runtime: eliminate struct dyld_info from kernel interface.

This commit is contained in:
whitequark 2016-09-30 01:25:46 +00:00
parent c6a57d2043
commit 7cfa667d98
4 changed files with 51 additions and 56 deletions

View File

@ -1,8 +1,6 @@
#include <string.h>
#include <generated/csr.h>
#include <dyld.h>
#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

View File

@ -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);
}

View File

@ -6,6 +6,7 @@
#include <stdint.h>
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 {

View File

@ -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