diff --git a/soc/runtime/comm.h b/soc/runtime/comm.h index 0adf69973..f30431448 100644 --- a/soc/runtime/comm.h +++ b/soc/runtime/comm.h @@ -1,6 +1,8 @@ #ifndef __COMM_H #define __COMM_H +#include + enum { KERNEL_RUN_INVALID_STATUS, @@ -13,7 +15,9 @@ typedef int (*object_loader)(void *, int); typedef int (*kernel_runner)(const char *, int *, long long int *); void comm_serve(object_loader load_object, kernel_runner run_kernel); +int comm_rpc_va(int rpc_num, va_list args); int comm_rpc(int rpc_num, ...); +void comm_log_va(const char *fmt, va_list args); void comm_log(const char *fmt, ...); #endif /* __COMM_H */ diff --git a/soc/runtime/comm_serial.c b/soc/runtime/comm_serial.c index e55c2bc7b..546010e44 100644 --- a/soc/runtime/comm_serial.c +++ b/soc/runtime/comm_serial.c @@ -242,7 +242,7 @@ static int send_value(int type_tag, void *value) return 0; } -int comm_rpc(int rpc_num, ...) +int comm_rpc_va(int rpc_num, va_list args) { int type_tag; int eid; @@ -251,11 +251,8 @@ int comm_rpc(int rpc_num, ...) send_char(MSGTYPE_RPC_REQUEST); send_sint(rpc_num); - va_list args; - va_start(args, rpc_num); while((type_tag = va_arg(args, int))) send_value(type_tag, type_tag == 'n' ? NULL : va_arg(args, void *)); - va_end(args); send_char(0); eid = receive_int(); @@ -271,19 +268,36 @@ int comm_rpc(int rpc_num, ...) return retval; } -void comm_log(const char *fmt, ...) +int comm_rpc(int rpc_num, ...) { va_list args; + int r; + + va_start(args, rpc_num); + r = comm_rpc_va(rpc_num, args); + va_end(args); + return r; +} + +void comm_log_va(const char *fmt, va_list args) +{ int len; char outbuf[256]; int i; - va_start(args, fmt); len = vscnprintf(outbuf, sizeof(outbuf), fmt, args); - va_end(args); send_char(MSGTYPE_LOG); send_sint(len); for(i=0;i -#include "exceptions.h" - -#ifdef ARTIQ_AMP -#include "mailbox.h" -#include "messages.h" -#else #include "comm.h" -#endif +#include "exceptions.h" #define MAX_EXCEPTION_CONTEXTS 64 @@ -58,18 +52,7 @@ void exception_raise_params(int id, stored_params[2] = p2; exception_longjmp(exception_contexts[--ec_top].jb); } else { -#ifdef ARTIQ_AMP - struct msg_exception msg; - int i; - - msg.type = MESSAGE_TYPE_EXCEPTION; - msg.eid = EID_INTERNAL_ERROR; - for(i=0;i<3;i++) - msg.eparams[i] = 0; - mailbox_send_and_wait(&msg); -#else comm_log("ERROR: uncaught exception, ID=%d\n", id); -#endif while(1); } } diff --git a/soc/runtime/ksupport.c b/soc/runtime/ksupport.c index 5d27bf847..a9828592c 100644 --- a/soc/runtime/ksupport.c +++ b/soc/runtime/ksupport.c @@ -1,9 +1,14 @@ +#include + #include "exceptions.h" #include "mailbox.h" #include "messages.h" #include "rtio.h" #include "dds.h" +/* for the prototypes for comm_rpc and comm_log */ +#include "comm.h" + void exception_handler(unsigned long vect, unsigned long *sp); void exception_handler(unsigned long vect, unsigned long *sp) { @@ -50,9 +55,33 @@ int main(void) while(1); } -int comm_rpc(int rpc_num, ...); int comm_rpc(int rpc_num, ...) { - /* TODO */ - return 0; + struct msg_rpc_request request; + struct msg_rpc_reply *reply; + int r; + + request.type = MESSAGE_TYPE_RPC_REQUEST; + request.rpc_num = rpc_num; + va_start(request.args, rpc_num); + mailbox_send_and_wait(&request); + va_end(request.args); + + reply = mailbox_wait_and_receive(); + if(reply->type != MESSAGE_TYPE_RPC_REPLY) + exception_raise(EID_INTERNAL_ERROR); + r = reply->ret_val; + mailbox_acknowledge(); + return r; +} + +void comm_log(const char *fmt, ...) +{ + struct msg_log request; + + request.type = MESSAGE_TYPE_LOG; + request.fmt = fmt; + va_start(request.args, fmt); + mailbox_send_and_wait(&request); + va_end(request.args); } diff --git a/soc/runtime/mailbox.c b/soc/runtime/mailbox.c index 6a24abdd4..00d87a62f 100644 --- a/soc/runtime/mailbox.c +++ b/soc/runtime/mailbox.c @@ -75,6 +75,14 @@ void *mailbox_receive(void) } } +void *mailbox_wait_and_receive(void) +{ + void *r; + + while(!(r = mailbox_receive())); + return r; +} + void mailbox_acknowledge(void) { KERNELCPU_MAILBOX = 0; diff --git a/soc/runtime/mailbox.h b/soc/runtime/mailbox.h index e4316c197..f1d40c973 100644 --- a/soc/runtime/mailbox.h +++ b/soc/runtime/mailbox.h @@ -6,6 +6,7 @@ int mailbox_acknowledged(void); void mailbox_send_and_wait(void *ptr); void *mailbox_receive(void); +void *mailbox_wait_and_receive(void); void mailbox_acknowledge(void); #endif /* __MAILBOX_H */ diff --git a/soc/runtime/main.c b/soc/runtime/main.c index f512dd294..36291c55b 100644 --- a/soc/runtime/main.c +++ b/soc/runtime/main.c @@ -85,6 +85,21 @@ static int process_msg(struct msg_unknown *umsg, int *eid, long long int *eparam eparams[i] = msg->eparams[i]; return KERNEL_RUN_EXCEPTION; } + case MESSAGE_TYPE_RPC_REQUEST: { + struct msg_rpc_request *msg = (struct msg_rpc_request *)umsg; + struct msg_rpc_reply reply; + + reply.type = MESSAGE_TYPE_RPC_REPLY; + reply.ret_val = comm_rpc_va(msg->rpc_num, msg->args); + mailbox_send_and_wait(&reply); + return KERNEL_RUN_INVALID_STATUS; + } + case MESSAGE_TYPE_LOG: { + struct msg_log *msg = (struct msg_log *)umsg; + + comm_log(msg->fmt, msg->args); + return KERNEL_RUN_INVALID_STATUS; + } default: *eid = EID_INTERNAL_ERROR; for(i=0;i<3;i++) @@ -105,7 +120,6 @@ static int run_kernel(const char *kernel_name, int *eid, long long int *eparams) void *jb; #endif - k = find_symbol(symtab, kernel_name); if(k == NULL) { comm_log("Failed to find kernel entry point '%s' in object", kernel_name); diff --git a/soc/runtime/messages.h b/soc/runtime/messages.h index 4bc37add9..d79d8e354 100644 --- a/soc/runtime/messages.h +++ b/soc/runtime/messages.h @@ -1,9 +1,14 @@ #ifndef __MESSAGES_H #define __MESSAGES_H +#include + enum { MESSAGE_TYPE_FINISHED, - MESSAGE_TYPE_EXCEPTION + MESSAGE_TYPE_EXCEPTION, + MESSAGE_TYPE_RPC_REQUEST, + MESSAGE_TYPE_RPC_REPLY, + MESSAGE_TYPE_LOG }; struct msg_unknown { @@ -20,4 +25,21 @@ struct msg_exception { long long int eparams[3]; }; +struct msg_rpc_request { + int type; + int rpc_num; + va_list args; +}; + +struct msg_rpc_reply { + int type; + int ret_val; +}; + +struct msg_log { + int type; + const char *fmt; + va_list args; +}; + #endif /* __MESSAGES_H */