corecom: exception support

This commit is contained in:
Sebastien Bourdeauducq 2014-09-21 23:36:10 +08:00
parent 0c9f05dc80
commit 3de24619b2
6 changed files with 59 additions and 18 deletions

View File

@ -70,4 +70,4 @@ class Core:
binary = get_runtime_binary(self.runtime_env, func_def)
self.core_com.load(binary)
self.core_com.run(func_def.name)
self.core_com.serve(rpc_map)
self.core_com.serve(rpc_map, exception_map)

View File

@ -25,9 +25,14 @@ class CoreCom:
def run(self, kname):
print("RUN: "+kname)
def serve(self, rpc_map):
def serve(self, rpc_map, exception_map):
print("================")
print(" RPC map")
print("================")
for k, v in sorted(rpc_map.items(), key=itemgetter(0)):
print(str(k)+" -> "+str(v))
print("================")
print(" Exception map")
print("================")
for k, v in sorted(exception_map.items(), key=itemgetter(0)):
print(str(k)+" -> "+str(v))

View File

@ -31,8 +31,9 @@ class _D2HMsgType(Enum):
CRC_FAILED = 6
OBJECT_UNRECOGNIZED = 7
KERNEL_FINISHED = 8
KERNEL_STARTUP_FAILED = 9
RPC_REQUEST = 10
KERNEL_EXCEPTION = 9
KERNEL_STARTUP_FAILED = 10
RPC_REQUEST = 11
def _write_exactly(f, data):
@ -141,12 +142,10 @@ class CoreCom:
_write_exactly(self.port, struct.pack("b", ord(c)))
logger.debug("running kernel: {}".format(kname))
def serve(self, rpc_map):
def serve(self, rpc_map, exception_map):
while True:
msg = self._get_device_msg()
if msg == _D2HMsgType.KERNEL_FINISHED:
return
elif msg == _D2HMsgType.RPC_REQUEST:
if msg == _D2HMsgType.RPC_REQUEST:
rpc_num, n_args = struct.unpack(">hb",
_read_exactly(self.port, 3))
args = []
@ -160,5 +159,11 @@ class CoreCom:
_write_exactly(self.port, struct.pack(">l", r))
logger.debug("rpc service: {} ({}) == {}".format(
rpc_num, args, r))
elif msg == _D2HMsgType.KERNEL_EXCEPTION:
(exception_num, ) = struct.unpack(">l",
_read_exactly(self.port, 4))
raise exception_map[exception_num]
elif msg == _D2HMsgType.KERNEL_FINISHED:
return
else:
raise IOError("Incorrect request from device: "+str(msg))

View File

@ -1,8 +1,14 @@
#ifndef __CORECOM_H
#define __CORECOM_H
enum {
KERNEL_RUN_FINISHED,
KERNEL_RUN_EXCEPTION,
KERNEL_RUN_STARTUP_FAILED
};
typedef int (*object_loader)(void *, int);
typedef int (*kernel_runner)(const char *);
typedef int (*kernel_runner)(const char *, int *);
void corecom_serve(object_loader load_object, kernel_runner run_kernel);
int corecom_rpc(int rpc_num, int n_args, ...);

View File

@ -25,6 +25,7 @@ enum {
MSGTYPE_OBJECT_UNRECOGNIZED,
MSGTYPE_KERNEL_FINISHED,
MSGTYPE_KERNEL_EXCEPTION,
MSGTYPE_KERNEL_STARTUP_FAILED,
MSGTYPE_RPC_REQUEST,
@ -114,7 +115,7 @@ static void receive_and_run_kernel(kernel_runner run_kernel)
int length;
int i;
char kernel_name[256];
int r;
int r, eid;
length = receive_int();
if(length > (sizeof(kernel_name)-1)) {
@ -125,8 +126,22 @@ static void receive_and_run_kernel(kernel_runner run_kernel)
kernel_name[i] = receive_char();
kernel_name[length] = 0;
r = run_kernel(kernel_name);
send_char(r ? MSGTYPE_KERNEL_FINISHED : MSGTYPE_KERNEL_STARTUP_FAILED);
r = run_kernel(kernel_name, &eid);
switch(r) {
case KERNEL_RUN_FINISHED:
send_char(MSGTYPE_KERNEL_FINISHED);
break;
case KERNEL_RUN_EXCEPTION:
send_char(MSGTYPE_KERNEL_EXCEPTION);
send_int(eid);
break;
case KERNEL_RUN_STARTUP_FAILED:
send_char(MSGTYPE_KERNEL_STARTUP_FAILED);
break;
default:
corecom_log("BUG: run_kernel returned unexpected value '%d'", r);
break;
}
}
void corecom_serve(object_loader load_object, kernel_runner run_kernel)

View File

@ -8,6 +8,7 @@
#include "corecom.h"
#include "elf_loader.h"
#include "exceptions.h"
#include "services.h"
#include "rtio.h"
#include "dds.h"
@ -64,19 +65,28 @@ static int load_object(void *buffer, int length)
typedef void (*kernel_function)(void);
static int run_kernel(const char *kernel_name)
static int run_kernel(const char *kernel_name, int *eid)
{
kernel_function k;
struct exception_env ee;
int exception_occured;
k = find_symbol(symtab, kernel_name);
if(k == NULL) {
corecom_log("Failed to find kernel entry point '%s' in object", kernel_name);
return 0;
return KERNEL_RUN_STARTUP_FAILED;
}
exception_occured = exception_catch(&ee, eid);
if(exception_occured)
return KERNEL_RUN_EXCEPTION;
else {
rtio_init();
flush_cpu_icache();
k();
exception_pop();
return KERNEL_RUN_FINISHED;
}
rtio_init();
flush_cpu_icache();
k();
return 1;
}
static void blink_led(void)