forked from M-Labs/artiq
runtime: startup kernel support
This commit is contained in:
parent
592663a649
commit
d0b5c3ba7f
|
@ -66,10 +66,6 @@ void bridge_main(void)
|
|||
mailbox_acknowledge();
|
||||
break;
|
||||
}
|
||||
case MESSAGE_TYPE_BRG_DDS_INITALL:
|
||||
dds_init_all();
|
||||
mailbox_acknowledge();
|
||||
break;
|
||||
case MESSAGE_TYPE_BRG_DDS_SEL: {
|
||||
struct msg_brg_dds_sel *msg;
|
||||
|
||||
|
|
|
@ -23,11 +23,6 @@ void brg_start(void)
|
|||
}
|
||||
}
|
||||
|
||||
void brg_stop(void)
|
||||
{
|
||||
kloader_stop();
|
||||
}
|
||||
|
||||
void brg_ttloe(int n, int value)
|
||||
{
|
||||
struct msg_brg_ttl_out msg;
|
||||
|
@ -48,14 +43,6 @@ void brg_ttlo(int n, int value)
|
|||
mailbox_send_and_wait(&msg);
|
||||
}
|
||||
|
||||
void brg_ddsinitall(void)
|
||||
{
|
||||
struct msg_base msg;
|
||||
|
||||
msg.type = MESSAGE_TYPE_BRG_DDS_INITALL;
|
||||
mailbox_send_and_wait(&msg);
|
||||
}
|
||||
|
||||
void brg_ddssel(int channel)
|
||||
{
|
||||
struct msg_brg_dds_sel msg;
|
||||
|
|
|
@ -2,12 +2,10 @@
|
|||
#define __BRIDGE_CTL_H
|
||||
|
||||
void brg_start(void);
|
||||
void brg_stop(void);
|
||||
|
||||
void brg_ttloe(int n, int value);
|
||||
void brg_ttlo(int n, int value);
|
||||
|
||||
void brg_ddsinitall(void);
|
||||
void brg_ddssel(int channel);
|
||||
void brg_ddsreset(void);
|
||||
unsigned int brg_ddsread(unsigned int address);
|
||||
|
|
|
@ -62,7 +62,7 @@ int watchdog_set(int ms)
|
|||
break;
|
||||
}
|
||||
if(id < 0) {
|
||||
log("Failed to add watchdog");
|
||||
log("WARNING: Failed to add watchdog");
|
||||
return id;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,19 +33,6 @@
|
|||
now += DURATION_WRITE; \
|
||||
} while(0)
|
||||
|
||||
void dds_init_all(void)
|
||||
{
|
||||
int i;
|
||||
long long int now;
|
||||
|
||||
now = rtio_get_counter() + 10000;
|
||||
for(i=0;i<DDS_CHANNEL_COUNT;i++) {
|
||||
dds_init(now, i);
|
||||
now += DURATION_INIT + DURATION_WRITE; /* + FUD time */
|
||||
}
|
||||
while(rtio_get_counter() < now);
|
||||
}
|
||||
|
||||
void dds_init(long long int timestamp, int channel)
|
||||
{
|
||||
long long int now;
|
||||
|
|
|
@ -54,7 +54,6 @@ enum {
|
|||
PHASE_MODE_TRACKING = 2
|
||||
};
|
||||
|
||||
void dds_init_all(void);
|
||||
void dds_init(long long int timestamp, int channel);
|
||||
void dds_batch_enter(long long int timestamp);
|
||||
void dds_batch_exit(void);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <generated/csr.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "clock.h"
|
||||
#include "flash_storage.h"
|
||||
#include "mailbox.h"
|
||||
#include "messages.h"
|
||||
|
@ -91,33 +92,50 @@ void kloader_start_user_kernel(kernel_function k)
|
|||
start_kernel_cpu((void *)k);
|
||||
}
|
||||
|
||||
void kloader_start_idle_kernel(void)
|
||||
static int kloader_start_flash_kernel(char *key)
|
||||
{
|
||||
char buffer[32*1024];
|
||||
int len;
|
||||
unsigned int len, remain;
|
||||
kernel_function k;
|
||||
|
||||
if(!kernel_cpu_reset_read()) {
|
||||
log("BUG: attempted to start kernel CPU while already running (idle kernel)");
|
||||
return;
|
||||
log("BUG: attempted to start kernel CPU while already running (%s)", key);
|
||||
return 0;
|
||||
}
|
||||
#if (defined CSR_SPIFLASH_BASE && defined SPIFLASH_PAGE_SIZE)
|
||||
len = fs_read("idle_kernel", buffer, sizeof(buffer), NULL);
|
||||
len = fs_read(key, buffer, sizeof(buffer), &remain);
|
||||
if(len <= 0)
|
||||
return;
|
||||
return 0;
|
||||
if(remain) {
|
||||
log("ERROR: %s too long", key);
|
||||
return 0;
|
||||
}
|
||||
if(!kloader_load(buffer, len)) {
|
||||
log("Failed to load ELF binary for idle kernel");
|
||||
return;
|
||||
log("ERROR: failed to load ELF binary (%s)", key);
|
||||
return 0;
|
||||
}
|
||||
k = kloader_find("run");
|
||||
if(!k) {
|
||||
log("Failed to find entry point for ELF kernel");
|
||||
return;
|
||||
log("ERROR: failed to find entry point for ELF kernel (%s)", key);
|
||||
return 0;
|
||||
}
|
||||
start_kernel_cpu((void *)k);
|
||||
return 1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int kloader_start_startup_kernel(void)
|
||||
{
|
||||
return kloader_start_flash_kernel("startup_kernel");
|
||||
}
|
||||
|
||||
int kloader_start_idle_kernel(void)
|
||||
{
|
||||
return kloader_start_flash_kernel("idle_kernel");
|
||||
}
|
||||
|
||||
void kloader_stop(void)
|
||||
{
|
||||
kernel_cpu_reset_write(1);
|
||||
|
@ -140,6 +158,8 @@ int kloader_is_essential_kmsg(int msgtype)
|
|||
case MESSAGE_TYPE_NOW_INIT_REQUEST:
|
||||
case MESSAGE_TYPE_NOW_SAVE:
|
||||
case MESSAGE_TYPE_LOG:
|
||||
case MESSAGE_TYPE_WATCHDOG_SET_REQUEST:
|
||||
case MESSAGE_TYPE_WATCHDOG_CLEAR:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
|
@ -179,6 +199,22 @@ void kloader_service_essential_kmsg(void)
|
|||
mailbox_acknowledge();
|
||||
break;
|
||||
}
|
||||
case MESSAGE_TYPE_WATCHDOG_SET_REQUEST: {
|
||||
struct msg_watchdog_set_request *msg = (struct msg_watchdog_set_request *)umsg;
|
||||
struct msg_watchdog_set_reply reply;
|
||||
|
||||
reply.type = MESSAGE_TYPE_WATCHDOG_SET_REPLY;
|
||||
reply.id = watchdog_set(msg->ms);
|
||||
mailbox_send_and_wait(&reply);
|
||||
break;
|
||||
}
|
||||
case MESSAGE_TYPE_WATCHDOG_CLEAR: {
|
||||
struct msg_watchdog_clear *msg = (struct msg_watchdog_clear *)umsg;
|
||||
|
||||
watchdog_clear(msg->id);
|
||||
mailbox_acknowledge();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
/* handled elsewhere */
|
||||
break;
|
||||
|
|
|
@ -12,7 +12,8 @@ int kloader_load(void *buffer, int length);
|
|||
kernel_function kloader_find(const char *name);
|
||||
|
||||
void kloader_start_bridge(void);
|
||||
void kloader_start_idle_kernel(void);
|
||||
int kloader_start_startup_kernel(void);
|
||||
int kloader_start_idle_kernel(void);
|
||||
void kloader_start_user_kernel(kernel_function k);
|
||||
void kloader_stop(void);
|
||||
|
||||
|
|
|
@ -30,13 +30,6 @@
|
|||
#include "session.h"
|
||||
#include "moninj.h"
|
||||
|
||||
static void common_init(void)
|
||||
{
|
||||
brg_start();
|
||||
brg_ddsinitall();
|
||||
kloader_stop();
|
||||
}
|
||||
|
||||
#ifdef CSR_ETHMAC_BASE
|
||||
|
||||
u32_t sys_now(void)
|
||||
|
@ -260,7 +253,7 @@ int main(void)
|
|||
test_main();
|
||||
} else {
|
||||
puts("Entering regular mode.");
|
||||
common_init();
|
||||
session_startup_kernel();
|
||||
regular_main();
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -19,7 +19,6 @@ enum {
|
|||
MESSAGE_TYPE_BRG_READY,
|
||||
MESSAGE_TYPE_BRG_TTL_O,
|
||||
MESSAGE_TYPE_BRG_TTL_OE,
|
||||
MESSAGE_TYPE_BRG_DDS_INITALL,
|
||||
MESSAGE_TYPE_BRG_DDS_SEL,
|
||||
MESSAGE_TYPE_BRG_DDS_RESET,
|
||||
MESSAGE_TYPE_BRG_DDS_READ_REQUEST,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include <stdio.h>
|
||||
#include <generated/csr.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "clock.h"
|
||||
#include "flash_storage.h"
|
||||
#include "rtiocrg.h"
|
||||
|
@ -17,17 +17,17 @@ void rtiocrg_init(void)
|
|||
clk = 0;
|
||||
fs_read("startup_clock", &b, 1, NULL);
|
||||
if(b == 'i')
|
||||
printf("Startup RTIO clock: internal\n");
|
||||
log("Startup RTIO clock: internal");
|
||||
else if(b == 'e') {
|
||||
printf("Startup RTIO clock: external\n");
|
||||
log("Startup RTIO clock: external");
|
||||
clk = 1;
|
||||
} else
|
||||
printf("WARNING: unknown startup_clock entry in flash storage\n");
|
||||
log("ERROR: unrecognized startup_clock entry in flash storage");
|
||||
|
||||
if(!rtiocrg_switch_clock(clk)) {
|
||||
printf("WARNING: startup RTIO clock failed\n");
|
||||
printf("WARNING: this may cause the system initialization to fail\n");
|
||||
printf("WARNING: fix clocking and reset the device\n");
|
||||
log("ERROR: startup RTIO clock failed");
|
||||
log("WARNING: this may cause the system initialization to fail");
|
||||
log("WARNING: fix clocking and reset the device");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -64,6 +64,44 @@ enum {
|
|||
USER_KERNEL_WAIT_RPC /* < must come after _RUNNING */
|
||||
};
|
||||
|
||||
void session_startup_kernel(void)
|
||||
{
|
||||
struct msg_base *umsg;
|
||||
|
||||
now = -1;
|
||||
watchdog_init();
|
||||
if(!kloader_start_startup_kernel())
|
||||
return;
|
||||
|
||||
while(1) {
|
||||
kloader_service_essential_kmsg();
|
||||
|
||||
umsg = mailbox_receive();
|
||||
if(umsg) {
|
||||
if(!kloader_validate_kpointer(umsg))
|
||||
break;
|
||||
if(kloader_is_essential_kmsg(umsg->type))
|
||||
continue;
|
||||
if(umsg->type == MESSAGE_TYPE_FINISHED)
|
||||
break;
|
||||
else if(umsg->type == MESSAGE_TYPE_EXCEPTION) {
|
||||
log("WARNING: startup kernel ended with exception");
|
||||
break;
|
||||
} else {
|
||||
log("ERROR: received invalid message type from kernel CPU");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(watchdog_expired()) {
|
||||
log("WARNING: watchdog expired in startup kernel");
|
||||
break;
|
||||
}
|
||||
}
|
||||
kloader_stop();
|
||||
log("Startup kernel terminated");
|
||||
}
|
||||
|
||||
void session_start(void)
|
||||
{
|
||||
buffer_in_index = 0;
|
||||
|
@ -77,6 +115,7 @@ void session_end(void)
|
|||
{
|
||||
kloader_stop();
|
||||
now = -1;
|
||||
watchdog_init();
|
||||
kloader_start_idle_kernel();
|
||||
}
|
||||
|
||||
|
@ -490,22 +529,6 @@ static int process_kmsg(struct msg_base *umsg)
|
|||
mailbox_acknowledge();
|
||||
break;
|
||||
}
|
||||
case MESSAGE_TYPE_WATCHDOG_SET_REQUEST: {
|
||||
struct msg_watchdog_set_request *msg = (struct msg_watchdog_set_request *)umsg;
|
||||
struct msg_watchdog_set_reply reply;
|
||||
|
||||
reply.type = MESSAGE_TYPE_WATCHDOG_SET_REPLY;
|
||||
reply.id = watchdog_set(msg->ms);
|
||||
mailbox_send_and_wait(&reply);
|
||||
break;
|
||||
}
|
||||
case MESSAGE_TYPE_WATCHDOG_CLEAR: {
|
||||
struct msg_watchdog_clear *msg = (struct msg_watchdog_clear *)umsg;
|
||||
|
||||
watchdog_clear(msg->id);
|
||||
mailbox_acknowledge();
|
||||
break;
|
||||
}
|
||||
case MESSAGE_TYPE_RPC_REQUEST: {
|
||||
struct msg_rpc_request *msg = (struct msg_rpc_request *)umsg;
|
||||
|
||||
|
@ -516,7 +539,7 @@ static int process_kmsg(struct msg_base *umsg)
|
|||
break;
|
||||
}
|
||||
default: {
|
||||
log("Received invalid message type from kernel CPU");
|
||||
log("ERROR: received invalid message type from kernel CPU");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef __SESSION_H
|
||||
#define __SESSION_H
|
||||
|
||||
void session_startup_kernel(void);
|
||||
void session_start(void);
|
||||
void session_end(void);
|
||||
|
||||
|
|
Loading…
Reference in New Issue