forked from M-Labs/artiq
runtime: process essential kernel CPU messages at all time
This commit is contained in:
parent
d14a31f443
commit
aba2d3f112
|
@ -4,6 +4,7 @@
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "flash_storage.h"
|
#include "flash_storage.h"
|
||||||
#include "mailbox.h"
|
#include "mailbox.h"
|
||||||
|
#include "messages.h"
|
||||||
#include "elf_loader.h"
|
#include "elf_loader.h"
|
||||||
#include "services.h"
|
#include "services.h"
|
||||||
#include "kloader.h"
|
#include "kloader.h"
|
||||||
|
@ -122,3 +123,65 @@ void kloader_stop(void)
|
||||||
kernel_cpu_reset_write(1);
|
kernel_cpu_reset_write(1);
|
||||||
mailbox_acknowledge();
|
mailbox_acknowledge();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int kloader_validate_kpointer(void *p)
|
||||||
|
{
|
||||||
|
unsigned int v = (unsigned int)p;
|
||||||
|
if((v < 0x40400000) || (v > (0x4fffffff - 1024*1024))) {
|
||||||
|
log("Received invalid pointer from kernel CPU: 0x%08x", v);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int kloader_is_essential_kmsg(int msgtype)
|
||||||
|
{
|
||||||
|
switch(msgtype) {
|
||||||
|
case MESSAGE_TYPE_NOW_INIT_REQUEST:
|
||||||
|
case MESSAGE_TYPE_NOW_SAVE:
|
||||||
|
case MESSAGE_TYPE_LOG:
|
||||||
|
return 1;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long long int now;
|
||||||
|
|
||||||
|
void kloader_service_essential_kmsg(void)
|
||||||
|
{
|
||||||
|
struct msg_base *umsg;
|
||||||
|
|
||||||
|
umsg = mailbox_receive();
|
||||||
|
if(umsg) {
|
||||||
|
if(!kloader_validate_kpointer(umsg))
|
||||||
|
return;
|
||||||
|
switch(umsg->type) {
|
||||||
|
case MESSAGE_TYPE_NOW_INIT_REQUEST: {
|
||||||
|
struct msg_now_init_reply reply;
|
||||||
|
|
||||||
|
reply.type = MESSAGE_TYPE_NOW_INIT_REPLY;
|
||||||
|
reply.now = now;
|
||||||
|
mailbox_send_and_wait(&reply);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MESSAGE_TYPE_NOW_SAVE: {
|
||||||
|
struct msg_now_save *msg = (struct msg_now_save *)umsg;
|
||||||
|
|
||||||
|
now = msg->now;
|
||||||
|
mailbox_acknowledge();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MESSAGE_TYPE_LOG: {
|
||||||
|
struct msg_log *msg = (struct msg_log *)umsg;
|
||||||
|
|
||||||
|
log_va(msg->fmt, msg->args);
|
||||||
|
mailbox_acknowledge();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
/* handled elsewhere */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
#define KERNELCPU_EXEC_ADDRESS 0x40400000
|
#define KERNELCPU_EXEC_ADDRESS 0x40400000
|
||||||
#define KERNELCPU_PAYLOAD_ADDRESS 0x40404000
|
#define KERNELCPU_PAYLOAD_ADDRESS 0x40404000
|
||||||
|
|
||||||
|
extern long long int now;
|
||||||
|
|
||||||
typedef void (*kernel_function)(void);
|
typedef void (*kernel_function)(void);
|
||||||
|
|
||||||
int kloader_load(void *buffer, int length);
|
int kloader_load(void *buffer, int length);
|
||||||
|
@ -14,4 +16,8 @@ void 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);
|
||||||
|
|
||||||
|
int kloader_validate_kpointer(void *p);
|
||||||
|
int kloader_is_essential_kmsg(int msgtype);
|
||||||
|
void kloader_service_essential_kmsg(void);
|
||||||
|
|
||||||
#endif /* __KLOADER_H */
|
#endif /* __KLOADER_H */
|
||||||
|
|
|
@ -143,6 +143,7 @@ static void regular_main(void)
|
||||||
session_end();
|
session_end();
|
||||||
while(1) {
|
while(1) {
|
||||||
lwip_service();
|
lwip_service();
|
||||||
|
kloader_service_essential_kmsg();
|
||||||
kserver_service();
|
kserver_service();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -201,8 +202,10 @@ static void regular_main(void)
|
||||||
|
|
||||||
/* Open the session for the serial control. */
|
/* Open the session for the serial control. */
|
||||||
session_start();
|
session_start();
|
||||||
while(1)
|
while(1) {
|
||||||
|
kloader_service_essential_kmsg();
|
||||||
serial_service();
|
serial_service();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -11,8 +11,8 @@
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "kloader.h"
|
#include "kloader.h"
|
||||||
#include "exceptions.h"
|
#include "exceptions.h"
|
||||||
#include "session.h"
|
|
||||||
#include "flash_storage.h"
|
#include "flash_storage.h"
|
||||||
|
#include "session.h"
|
||||||
|
|
||||||
#define BUFFER_IN_SIZE (1024*1024)
|
#define BUFFER_IN_SIZE (1024*1024)
|
||||||
#define BUFFER_OUT_SIZE (1024*1024)
|
#define BUFFER_OUT_SIZE (1024*1024)
|
||||||
|
@ -55,7 +55,6 @@ static void submit_output(int len)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int user_kernel_state;
|
static int user_kernel_state;
|
||||||
static long long int now;
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
USER_KERNEL_NONE = 0,
|
USER_KERNEL_NONE = 0,
|
||||||
|
@ -153,7 +152,7 @@ static int process_input(void)
|
||||||
log("Attempted to switch RTIO clock while kernel running");
|
log("Attempted to switch RTIO clock while kernel running");
|
||||||
buffer_out[8] = REMOTEMSG_TYPE_CLOCK_SWITCH_FAILED;
|
buffer_out[8] = REMOTEMSG_TYPE_CLOCK_SWITCH_FAILED;
|
||||||
submit_output(9);
|
submit_output(9);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
rtio_crg_clock_sel_write(buffer_in[9]);
|
rtio_crg_clock_sel_write(buffer_in[9]);
|
||||||
buffer_out[8] = REMOTEMSG_TYPE_CLOCK_SWITCH_COMPLETED;
|
buffer_out[8] = REMOTEMSG_TYPE_CLOCK_SWITCH_COMPLETED;
|
||||||
|
@ -421,16 +420,6 @@ static int add_rpc_value(int bi, int type_tag, void *value)
|
||||||
return bi - obi;
|
return bi - obi;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int validate_kpointer(void *p)
|
|
||||||
{
|
|
||||||
unsigned int v = (unsigned int)p;
|
|
||||||
if((v < 0x40400000) || (v > (0x4fffffff - 1024*1024))) {
|
|
||||||
log("Received invalid pointer from kernel CPU: 0x%08x", v);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int send_rpc_request(int rpc_num, va_list args)
|
static int send_rpc_request(int rpc_num, va_list args)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
@ -448,7 +437,7 @@ static int send_rpc_request(int rpc_num, va_list args)
|
||||||
v = NULL;
|
v = NULL;
|
||||||
else {
|
else {
|
||||||
v = va_arg(args, void *);
|
v = va_arg(args, void *);
|
||||||
if(!validate_kpointer(v))
|
if(!kloader_validate_kpointer(v))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
r = add_rpc_value(bi, type_tag, v);
|
r = add_rpc_value(bi, type_tag, v);
|
||||||
|
@ -467,31 +456,16 @@ static int send_rpc_request(int rpc_num, va_list args)
|
||||||
/* assumes output buffer is empty when called */
|
/* assumes output buffer is empty when called */
|
||||||
static int process_kmsg(struct msg_base *umsg)
|
static int process_kmsg(struct msg_base *umsg)
|
||||||
{
|
{
|
||||||
if(!validate_kpointer(umsg))
|
if(!kloader_validate_kpointer(umsg))
|
||||||
return 0;
|
return 0;
|
||||||
if((user_kernel_state != USER_KERNEL_RUNNING)
|
if(kloader_is_essential_kmsg(umsg->type))
|
||||||
&& (umsg->type != MESSAGE_TYPE_NOW_INIT_REQUEST)
|
return 1; /* handled elsewhere */
|
||||||
&& (umsg->type != MESSAGE_TYPE_NOW_SAVE)) {
|
if(user_kernel_state != USER_KERNEL_RUNNING) {
|
||||||
log("Received unexpected message from kernel CPU while not in running state");
|
log("Received unexpected message from kernel CPU while not in running state");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(umsg->type) {
|
switch(umsg->type) {
|
||||||
case MESSAGE_TYPE_NOW_INIT_REQUEST: {
|
|
||||||
struct msg_now_init_reply reply;
|
|
||||||
|
|
||||||
reply.type = MESSAGE_TYPE_NOW_INIT_REPLY;
|
|
||||||
reply.now = now;
|
|
||||||
mailbox_send_and_wait(&reply);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MESSAGE_TYPE_NOW_SAVE: {
|
|
||||||
struct msg_now_save *msg = (struct msg_now_save *)umsg;
|
|
||||||
|
|
||||||
now = msg->now;
|
|
||||||
mailbox_acknowledge();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MESSAGE_TYPE_FINISHED:
|
case MESSAGE_TYPE_FINISHED:
|
||||||
buffer_out[8] = REMOTEMSG_TYPE_KERNEL_FINISHED;
|
buffer_out[8] = REMOTEMSG_TYPE_KERNEL_FINISHED;
|
||||||
submit_output(9);
|
submit_output(9);
|
||||||
|
@ -538,13 +512,6 @@ static int process_kmsg(struct msg_base *umsg)
|
||||||
mailbox_acknowledge();
|
mailbox_acknowledge();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MESSAGE_TYPE_LOG: {
|
|
||||||
struct msg_log *msg = (struct msg_log *)umsg;
|
|
||||||
|
|
||||||
log_va(msg->fmt, msg->args);
|
|
||||||
mailbox_acknowledge();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
default: {
|
||||||
log("Received invalid message type from kernel CPU");
|
log("Received invalid message type from kernel CPU");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue