mirror of https://github.com/m-labs/artiq.git
runtime: support RPC and log on AMP
This commit is contained in:
parent
f26c53cb35
commit
45bb9d8840
|
@ -1,6 +1,8 @@
|
||||||
#ifndef __COMM_H
|
#ifndef __COMM_H
|
||||||
#define __COMM_H
|
#define __COMM_H
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
KERNEL_RUN_INVALID_STATUS,
|
KERNEL_RUN_INVALID_STATUS,
|
||||||
|
|
||||||
|
@ -13,7 +15,9 @@ typedef int (*object_loader)(void *, int);
|
||||||
typedef int (*kernel_runner)(const char *, int *, long long int *);
|
typedef int (*kernel_runner)(const char *, int *, long long int *);
|
||||||
|
|
||||||
void comm_serve(object_loader load_object, kernel_runner run_kernel);
|
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, ...);
|
int comm_rpc(int rpc_num, ...);
|
||||||
|
void comm_log_va(const char *fmt, va_list args);
|
||||||
void comm_log(const char *fmt, ...);
|
void comm_log(const char *fmt, ...);
|
||||||
|
|
||||||
#endif /* __COMM_H */
|
#endif /* __COMM_H */
|
||||||
|
|
|
@ -242,7 +242,7 @@ static int send_value(int type_tag, void *value)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int comm_rpc(int rpc_num, ...)
|
int comm_rpc_va(int rpc_num, va_list args)
|
||||||
{
|
{
|
||||||
int type_tag;
|
int type_tag;
|
||||||
int eid;
|
int eid;
|
||||||
|
@ -251,11 +251,8 @@ int comm_rpc(int rpc_num, ...)
|
||||||
send_char(MSGTYPE_RPC_REQUEST);
|
send_char(MSGTYPE_RPC_REQUEST);
|
||||||
send_sint(rpc_num);
|
send_sint(rpc_num);
|
||||||
|
|
||||||
va_list args;
|
|
||||||
va_start(args, rpc_num);
|
|
||||||
while((type_tag = va_arg(args, int)))
|
while((type_tag = va_arg(args, int)))
|
||||||
send_value(type_tag, type_tag == 'n' ? NULL : va_arg(args, void *));
|
send_value(type_tag, type_tag == 'n' ? NULL : va_arg(args, void *));
|
||||||
va_end(args);
|
|
||||||
send_char(0);
|
send_char(0);
|
||||||
|
|
||||||
eid = receive_int();
|
eid = receive_int();
|
||||||
|
@ -271,19 +268,36 @@ int comm_rpc(int rpc_num, ...)
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
void comm_log(const char *fmt, ...)
|
int comm_rpc(int rpc_num, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
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;
|
int len;
|
||||||
char outbuf[256];
|
char outbuf[256];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
va_start(args, fmt);
|
|
||||||
len = vscnprintf(outbuf, sizeof(outbuf), fmt, args);
|
len = vscnprintf(outbuf, sizeof(outbuf), fmt, args);
|
||||||
va_end(args);
|
|
||||||
|
|
||||||
send_char(MSGTYPE_LOG);
|
send_char(MSGTYPE_LOG);
|
||||||
send_sint(len);
|
send_sint(len);
|
||||||
for(i=0;i<len;i++)
|
for(i=0;i<len;i++)
|
||||||
send_char(outbuf[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 <generated/csr.h>
|
||||||
|
|
||||||
#include "exceptions.h"
|
|
||||||
|
|
||||||
#ifdef ARTIQ_AMP
|
|
||||||
#include "mailbox.h"
|
|
||||||
#include "messages.h"
|
|
||||||
#else
|
|
||||||
#include "comm.h"
|
#include "comm.h"
|
||||||
#endif
|
#include "exceptions.h"
|
||||||
|
|
||||||
#define MAX_EXCEPTION_CONTEXTS 64
|
#define MAX_EXCEPTION_CONTEXTS 64
|
||||||
|
|
||||||
|
@ -58,18 +52,7 @@ void exception_raise_params(int id,
|
||||||
stored_params[2] = p2;
|
stored_params[2] = p2;
|
||||||
exception_longjmp(exception_contexts[--ec_top].jb);
|
exception_longjmp(exception_contexts[--ec_top].jb);
|
||||||
} else {
|
} 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);
|
comm_log("ERROR: uncaught exception, ID=%d\n", id);
|
||||||
#endif
|
|
||||||
while(1);
|
while(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
#include "exceptions.h"
|
#include "exceptions.h"
|
||||||
#include "mailbox.h"
|
#include "mailbox.h"
|
||||||
#include "messages.h"
|
#include "messages.h"
|
||||||
#include "rtio.h"
|
#include "rtio.h"
|
||||||
#include "dds.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);
|
||||||
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);
|
while(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int comm_rpc(int rpc_num, ...);
|
|
||||||
int comm_rpc(int rpc_num, ...)
|
int comm_rpc(int rpc_num, ...)
|
||||||
{
|
{
|
||||||
/* TODO */
|
struct msg_rpc_request request;
|
||||||
return 0;
|
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)
|
void mailbox_acknowledge(void)
|
||||||
{
|
{
|
||||||
KERNELCPU_MAILBOX = 0;
|
KERNELCPU_MAILBOX = 0;
|
||||||
|
|
|
@ -6,6 +6,7 @@ int mailbox_acknowledged(void);
|
||||||
void mailbox_send_and_wait(void *ptr);
|
void mailbox_send_and_wait(void *ptr);
|
||||||
|
|
||||||
void *mailbox_receive(void);
|
void *mailbox_receive(void);
|
||||||
|
void *mailbox_wait_and_receive(void);
|
||||||
void mailbox_acknowledge(void);
|
void mailbox_acknowledge(void);
|
||||||
|
|
||||||
#endif /* __MAILBOX_H */
|
#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];
|
eparams[i] = msg->eparams[i];
|
||||||
return KERNEL_RUN_EXCEPTION;
|
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:
|
default:
|
||||||
*eid = EID_INTERNAL_ERROR;
|
*eid = EID_INTERNAL_ERROR;
|
||||||
for(i=0;i<3;i++)
|
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;
|
void *jb;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
k = find_symbol(symtab, kernel_name);
|
k = find_symbol(symtab, kernel_name);
|
||||||
if(k == NULL) {
|
if(k == NULL) {
|
||||||
comm_log("Failed to find kernel entry point '%s' in object", kernel_name);
|
comm_log("Failed to find kernel entry point '%s' in object", kernel_name);
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
#ifndef __MESSAGES_H
|
#ifndef __MESSAGES_H
|
||||||
#define __MESSAGES_H
|
#define __MESSAGES_H
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
MESSAGE_TYPE_FINISHED,
|
MESSAGE_TYPE_FINISHED,
|
||||||
MESSAGE_TYPE_EXCEPTION
|
MESSAGE_TYPE_EXCEPTION,
|
||||||
|
MESSAGE_TYPE_RPC_REQUEST,
|
||||||
|
MESSAGE_TYPE_RPC_REPLY,
|
||||||
|
MESSAGE_TYPE_LOG
|
||||||
};
|
};
|
||||||
|
|
||||||
struct msg_unknown {
|
struct msg_unknown {
|
||||||
|
@ -20,4 +25,21 @@ struct msg_exception {
|
||||||
long long int eparams[3];
|
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 */
|
#endif /* __MESSAGES_H */
|
||||||
|
|
Loading…
Reference in New Issue