runtime: process essential kernel CPU messages at all time

This commit is contained in:
Sebastien Bourdeauducq 2015-07-25 16:26:04 +08:00
parent d14a31f443
commit aba2d3f112
4 changed files with 80 additions and 41 deletions

View File

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

View File

@ -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 */

View File

@ -143,6 +143,7 @@ static void regular_main(void)
session_end();
while(1) {
lwip_service();
kloader_service_essential_kmsg();
kserver_service();
}
}
@ -201,9 +202,11 @@ 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

View File

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