runtime: support RPC and log on AMP

This commit is contained in:
Sebastien Bourdeauducq 2015-04-06 19:40:12 +08:00
parent f26c53cb35
commit 45bb9d8840
8 changed files with 105 additions and 30 deletions

View File

@ -1,6 +1,8 @@
#ifndef __COMM_H
#define __COMM_H
#include <stdarg.h>
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 */

View File

@ -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<len;i++)
send_char(outbuf[i]);
}
void comm_log(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
comm_log_va(fmt, args);
va_end(args);
}

View File

@ -1,13 +1,7 @@
#include <generated/csr.h>
#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);
}
}

View File

@ -1,9 +1,14 @@
#include <stdarg.h>
#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);
}

View File

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

View File

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

View File

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

View File

@ -1,9 +1,14 @@
#ifndef __MESSAGES_H
#define __MESSAGES_H
#include <stdarg.h>
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 */