mirror of https://github.com/m-labs/artiq.git
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 <string.h>
|
||||||
#include <generated/csr.h>
|
#include <generated/csr.h>
|
||||||
|
|
||||||
#include <dyld.h>
|
|
||||||
|
|
||||||
#include "kloader.h"
|
#include "kloader.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "clock.h"
|
#include "clock.h"
|
||||||
|
@ -10,8 +8,13 @@
|
||||||
#include "mailbox.h"
|
#include "mailbox.h"
|
||||||
#include "messages.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.
|
// Stop kernel CPU before messing with its code.
|
||||||
kernel_cpu_reset_write(1);
|
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);
|
&_binary_ksupport_elf_end - &_binary_ksupport_elf_start);
|
||||||
|
|
||||||
// Start kernel CPU.
|
// Start kernel CPU.
|
||||||
mailbox_send(msg);
|
|
||||||
kernel_cpu_reset_write(0);
|
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 = {
|
struct msg_load_request request = {
|
||||||
.library = library,
|
.type = MESSAGE_TYPE_LOAD_REQUEST,
|
||||||
.library_info = &library_info,
|
.library = library,
|
||||||
.run_kernel = run_kernel,
|
|
||||||
};
|
};
|
||||||
start_kernel_cpu(&request);
|
mailbox_send(&request);
|
||||||
|
|
||||||
struct msg_load_reply *reply = mailbox_wait_and_receive();
|
struct msg_load_reply *reply = mailbox_wait_and_receive();
|
||||||
mailbox_acknowledge();
|
|
||||||
|
|
||||||
if(reply->type != MESSAGE_TYPE_LOAD_REPLY) {
|
if(reply->type != MESSAGE_TYPE_LOAD_REPLY) {
|
||||||
core_log("BUG: unexpected reply to load/run request\n");
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int kloader_load_library(const void *library)
|
void kloader_start_kernel()
|
||||||
{
|
{
|
||||||
if(!kernel_cpu_reset_read()) {
|
if(kernel_cpu_reset_read()) {
|
||||||
core_log("BUG: attempted to load kernel library while kernel CPU is running\n");
|
core_log("BUG: attempted to load kernel library while kernel CPU is stopped\n");
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return load_or_start_kernel(library, 0);
|
mailbox_acknowledge();
|
||||||
}
|
}
|
||||||
|
|
||||||
void kloader_filter_backtrace(struct artiq_backtrace_item *backtrace,
|
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;
|
*backtrace_size = cursor - backtrace;
|
||||||
}
|
}
|
||||||
|
|
||||||
void kloader_start_kernel()
|
|
||||||
{
|
|
||||||
load_or_start_kernel(NULL, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int kloader_start_flash_kernel(char *key)
|
static int kloader_start_flash_kernel(char *key)
|
||||||
{
|
{
|
||||||
#if (defined CSR_SPIFLASH_BASE && defined CONFIG_SPIFLASH_PAGE_SIZE)
|
#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 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return load_or_start_kernel(buffer, 1);
|
if(!kloader_load_library(buffer))
|
||||||
|
return 0;
|
||||||
|
kloader_start_kernel();
|
||||||
|
return 1;
|
||||||
#else
|
#else
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -370,44 +370,40 @@ static void now_save(void)
|
||||||
int main(void);
|
int main(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 = {
|
struct msg_load_reply load_reply = {
|
||||||
.type = MESSAGE_TYPE_LOAD_REPLY,
|
.type = MESSAGE_TYPE_LOAD_REPLY,
|
||||||
.error = NULL
|
.error = NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
if(request->library != NULL) {
|
if(!dyld_load(request->library, KERNELCPU_PAYLOAD_ADDRESS,
|
||||||
if(!dyld_load(request->library, KERNELCPU_PAYLOAD_ADDRESS,
|
resolve_runtime_export, &library_info,
|
||||||
resolve_runtime_export, request->library_info,
|
&load_reply.error)) {
|
||||||
&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 {
|
|
||||||
mailbox_send(&load_reply);
|
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);
|
while(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
MESSAGE_TYPE_LOAD_REQUEST,
|
||||||
MESSAGE_TYPE_LOAD_REPLY,
|
MESSAGE_TYPE_LOAD_REPLY,
|
||||||
MESSAGE_TYPE_NOW_INIT_REQUEST,
|
MESSAGE_TYPE_NOW_INIT_REQUEST,
|
||||||
MESSAGE_TYPE_NOW_INIT_REPLY,
|
MESSAGE_TYPE_NOW_INIT_REPLY,
|
||||||
|
@ -33,9 +34,8 @@ struct msg_base {
|
||||||
/* kernel messages */
|
/* kernel messages */
|
||||||
|
|
||||||
struct msg_load_request {
|
struct msg_load_request {
|
||||||
|
int type;
|
||||||
const void *library;
|
const void *library;
|
||||||
struct dyld_info *library_info;
|
|
||||||
int run_kernel;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct msg_load_reply {
|
struct msg_load_reply {
|
||||||
|
|
|
@ -929,6 +929,11 @@ static int process_kmsg(struct msg_base *umsg)
|
||||||
return 0;
|
return 0;
|
||||||
if(kloader_is_essential_kmsg(umsg->type))
|
if(kloader_is_essential_kmsg(umsg->type))
|
||||||
return 1; /* handled elsewhere */
|
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 &&
|
if(user_kernel_state == USER_KERNEL_WAIT_RPC &&
|
||||||
umsg->type == MESSAGE_TYPE_RPC_RECV_REQUEST) {
|
umsg->type == MESSAGE_TYPE_RPC_RECV_REQUEST) {
|
||||||
// Handled and acknowledged when we receive
|
// Handled and acknowledged when we receive
|
||||||
|
|
Loading…
Reference in New Issue