mirror of
https://github.com/m-labs/artiq.git
synced 2024-12-29 05:03:34 +08:00
runtime: eliminate struct dyld_info from kernel interface.
This commit is contained in:
parent
c6a57d2043
commit
7cfa667d98
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user