runtime: startup kernel support

This commit is contained in:
Sebastien Bourdeauducq 2015-10-31 23:26:09 +08:00
parent 592663a649
commit d0b5c3ba7f
13 changed files with 98 additions and 78 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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