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) binary = get_runtime_binary(self.runtime_env, func_def)
self.core_com.load(binary) self.core_com.load(binary)
self.core_com.run(func_def.name) 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): def run(self, kname):
print("RUN: "+kname) print("RUN: "+kname)
def serve(self, rpc_map): def serve(self, rpc_map, exception_map):
print("================") print("================")
print(" RPC map") print(" RPC map")
print("================") print("================")
for k, v in sorted(rpc_map.items(), key=itemgetter(0)): for k, v in sorted(rpc_map.items(), key=itemgetter(0)):
print(str(k)+" -> "+str(v)) 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 CRC_FAILED = 6
OBJECT_UNRECOGNIZED = 7 OBJECT_UNRECOGNIZED = 7
KERNEL_FINISHED = 8 KERNEL_FINISHED = 8
KERNEL_STARTUP_FAILED = 9 KERNEL_EXCEPTION = 9
RPC_REQUEST = 10 KERNEL_STARTUP_FAILED = 10
RPC_REQUEST = 11
def _write_exactly(f, data): def _write_exactly(f, data):
@ -141,12 +142,10 @@ class CoreCom:
_write_exactly(self.port, struct.pack("b", ord(c))) _write_exactly(self.port, struct.pack("b", ord(c)))
logger.debug("running kernel: {}".format(kname)) logger.debug("running kernel: {}".format(kname))
def serve(self, rpc_map): def serve(self, rpc_map, exception_map):
while True: while True:
msg = self._get_device_msg() msg = self._get_device_msg()
if msg == _D2HMsgType.KERNEL_FINISHED: if msg == _D2HMsgType.RPC_REQUEST:
return
elif msg == _D2HMsgType.RPC_REQUEST:
rpc_num, n_args = struct.unpack(">hb", rpc_num, n_args = struct.unpack(">hb",
_read_exactly(self.port, 3)) _read_exactly(self.port, 3))
args = [] args = []
@ -160,5 +159,11 @@ class CoreCom:
_write_exactly(self.port, struct.pack(">l", r)) _write_exactly(self.port, struct.pack(">l", r))
logger.debug("rpc service: {} ({}) == {}".format( logger.debug("rpc service: {} ({}) == {}".format(
rpc_num, args, r)) 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: else:
raise IOError("Incorrect request from device: "+str(msg)) raise IOError("Incorrect request from device: "+str(msg))

View File

@ -1,8 +1,14 @@
#ifndef __CORECOM_H #ifndef __CORECOM_H
#define __CORECOM_H #define __CORECOM_H
enum {
KERNEL_RUN_FINISHED,
KERNEL_RUN_EXCEPTION,
KERNEL_RUN_STARTUP_FAILED
};
typedef int (*object_loader)(void *, int); 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); void corecom_serve(object_loader load_object, kernel_runner run_kernel);
int corecom_rpc(int rpc_num, int n_args, ...); int corecom_rpc(int rpc_num, int n_args, ...);

View File

@ -25,6 +25,7 @@ enum {
MSGTYPE_OBJECT_UNRECOGNIZED, MSGTYPE_OBJECT_UNRECOGNIZED,
MSGTYPE_KERNEL_FINISHED, MSGTYPE_KERNEL_FINISHED,
MSGTYPE_KERNEL_EXCEPTION,
MSGTYPE_KERNEL_STARTUP_FAILED, MSGTYPE_KERNEL_STARTUP_FAILED,
MSGTYPE_RPC_REQUEST, MSGTYPE_RPC_REQUEST,
@ -114,7 +115,7 @@ static void receive_and_run_kernel(kernel_runner run_kernel)
int length; int length;
int i; int i;
char kernel_name[256]; char kernel_name[256];
int r; int r, eid;
length = receive_int(); length = receive_int();
if(length > (sizeof(kernel_name)-1)) { 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[i] = receive_char();
kernel_name[length] = 0; kernel_name[length] = 0;
r = run_kernel(kernel_name); r = run_kernel(kernel_name, &eid);
send_char(r ? MSGTYPE_KERNEL_FINISHED : MSGTYPE_KERNEL_STARTUP_FAILED); 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) void corecom_serve(object_loader load_object, kernel_runner run_kernel)

View File

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