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