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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,7 @@
#ifndef __SESSION_H
#define __SESSION_H
void session_startup_kernel(void);
void session_start(void);
void session_end(void);