mirror of https://github.com/m-labs/artiq.git
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 "flash_storage.h"
|
||||
#include "mailbox.h"
|
||||
#include "messages.h"
|
||||
#include "elf_loader.h"
|
||||
#include "services.h"
|
||||
#include "kloader.h"
|
||||
|
@ -122,3 +123,65 @@ void kloader_stop(void)
|
|||
kernel_cpu_reset_write(1);
|
||||
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_PAYLOAD_ADDRESS 0x40404000
|
||||
|
||||
extern long long int now;
|
||||
|
||||
typedef void (*kernel_function)(void);
|
||||
|
||||
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_stop(void);
|
||||
|
||||
int kloader_validate_kpointer(void *p);
|
||||
int kloader_is_essential_kmsg(int msgtype);
|
||||
void kloader_service_essential_kmsg(void);
|
||||
|
||||
#endif /* __KLOADER_H */
|
||||
|
|
|
@ -143,6 +143,7 @@ static void regular_main(void)
|
|||
session_end();
|
||||
while(1) {
|
||||
lwip_service();
|
||||
kloader_service_essential_kmsg();
|
||||
kserver_service();
|
||||
}
|
||||
}
|
||||
|
@ -201,8 +202,10 @@ static void regular_main(void)
|
|||
|
||||
/* Open the session for the serial control. */
|
||||
session_start();
|
||||
while(1)
|
||||
while(1) {
|
||||
kloader_service_essential_kmsg();
|
||||
serial_service();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
#include "log.h"
|
||||
#include "kloader.h"
|
||||
#include "exceptions.h"
|
||||
#include "session.h"
|
||||
#include "flash_storage.h"
|
||||
#include "session.h"
|
||||
|
||||
#define BUFFER_IN_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 long long int now;
|
||||
|
||||
enum {
|
||||
USER_KERNEL_NONE = 0,
|
||||
|
@ -153,7 +152,7 @@ static int process_input(void)
|
|||
log("Attempted to switch RTIO clock while kernel running");
|
||||
buffer_out[8] = REMOTEMSG_TYPE_CLOCK_SWITCH_FAILED;
|
||||
submit_output(9);
|
||||
break;
|
||||
break;
|
||||
}
|
||||
rtio_crg_clock_sel_write(buffer_in[9]);
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
int r;
|
||||
|
@ -448,7 +437,7 @@ static int send_rpc_request(int rpc_num, va_list args)
|
|||
v = NULL;
|
||||
else {
|
||||
v = va_arg(args, void *);
|
||||
if(!validate_kpointer(v))
|
||||
if(!kloader_validate_kpointer(v))
|
||||
return 0;
|
||||
}
|
||||
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 */
|
||||
static int process_kmsg(struct msg_base *umsg)
|
||||
{
|
||||
if(!validate_kpointer(umsg))
|
||||
if(!kloader_validate_kpointer(umsg))
|
||||
return 0;
|
||||
if((user_kernel_state != USER_KERNEL_RUNNING)
|
||||
&& (umsg->type != MESSAGE_TYPE_NOW_INIT_REQUEST)
|
||||
&& (umsg->type != MESSAGE_TYPE_NOW_SAVE)) {
|
||||
if(kloader_is_essential_kmsg(umsg->type))
|
||||
return 1; /* handled elsewhere */
|
||||
if(user_kernel_state != USER_KERNEL_RUNNING) {
|
||||
log("Received unexpected message from kernel CPU while not in running state");
|
||||
return 0;
|
||||
}
|
||||
|
||||
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:
|
||||
buffer_out[8] = REMOTEMSG_TYPE_KERNEL_FINISHED;
|
||||
submit_output(9);
|
||||
|
@ -538,13 +512,6 @@ static int process_kmsg(struct msg_base *umsg)
|
|||
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: {
|
||||
log("Received invalid message type from kernel CPU");
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue