mirror of
https://github.com/m-labs/artiq.git
synced 2024-12-25 19:28:26 +08:00
runtime: support RPC and log on AMP
This commit is contained in:
parent
f26c53cb35
commit
45bb9d8840
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user