forked from M-Labs/artiq
runtime: implement RPC syscall
This commit is contained in:
parent
09e78a1f5e
commit
bb4a992907
|
@ -11,24 +11,12 @@
|
|||
|
||||
#include "elf_loader.h"
|
||||
|
||||
static void receive_sync(void)
|
||||
{
|
||||
char c;
|
||||
int recognized;
|
||||
enum {
|
||||
MSGTYPE_KERNEL_FINISHED = 0x01,
|
||||
MSGTYPE_RPC_REQUEST = 0x02,
|
||||
};
|
||||
|
||||
recognized = 0;
|
||||
while(1) {
|
||||
c = readchar();
|
||||
if(c == 0x5a) {
|
||||
recognized++;
|
||||
if(recognized == 4)
|
||||
return;
|
||||
} else
|
||||
recognized = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int receive_length(void)
|
||||
static int receive_int(void)
|
||||
{
|
||||
unsigned int r;
|
||||
int i;
|
||||
|
@ -36,11 +24,57 @@ static int receive_length(void)
|
|||
r = 0;
|
||||
for(i=0;i<4;i++) {
|
||||
r <<= 8;
|
||||
r |= (unsigned char)readchar();
|
||||
r |= (unsigned char)uart_read();
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
static char receive_char(void)
|
||||
{
|
||||
return uart_read();
|
||||
}
|
||||
|
||||
static void send_int(int x)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0;i<4;i++) {
|
||||
uart_write((x & 0xff000000) >> 24);
|
||||
x <<= 8;
|
||||
}
|
||||
}
|
||||
|
||||
static void send_sint(short int i)
|
||||
{
|
||||
uart_write((i >> 8) & 0xff);
|
||||
uart_write(i & 0xff);
|
||||
}
|
||||
|
||||
static void send_char(char c)
|
||||
{
|
||||
uart_write(c);
|
||||
}
|
||||
|
||||
static void receive_sync(void)
|
||||
{
|
||||
char c;
|
||||
int recognized;
|
||||
|
||||
recognized = 0;
|
||||
while(recognized < 4) {
|
||||
c = uart_read();
|
||||
if(c == 0x5a)
|
||||
recognized++;
|
||||
else
|
||||
recognized = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void send_sync(void)
|
||||
{
|
||||
send_int(0x5a5a5a5a);
|
||||
}
|
||||
|
||||
static int download_kernel(void *buffer, int maxlength)
|
||||
{
|
||||
int length;
|
||||
|
@ -48,25 +82,29 @@ static int download_kernel(void *buffer, int maxlength)
|
|||
unsigned char *_buffer = buffer;
|
||||
|
||||
receive_sync();
|
||||
length = receive_length();
|
||||
length = receive_int();
|
||||
if(length > maxlength)
|
||||
return -1;
|
||||
for(i=0;i<length;i++)
|
||||
_buffer[i] = readchar();
|
||||
_buffer[i] = receive_char();
|
||||
send_char(0x4f);
|
||||
return length;
|
||||
}
|
||||
|
||||
static int rpc(int rpc_num, int n_args, ...)
|
||||
{
|
||||
printf("rpc_num=%d n_args=%d\n", rpc_num, n_args);
|
||||
send_sync();
|
||||
send_char(MSGTYPE_RPC_REQUEST);
|
||||
send_sint(rpc_num);
|
||||
send_char(n_args);
|
||||
|
||||
va_list args;
|
||||
va_start(args, n_args);
|
||||
while(n_args--)
|
||||
printf("%d\n", va_arg(args, int));
|
||||
send_int(va_arg(args, int));
|
||||
va_end(args);
|
||||
|
||||
return 1;
|
||||
return receive_int();
|
||||
}
|
||||
|
||||
static void gpio_set(int channel, int level)
|
||||
|
@ -98,9 +136,12 @@ int main(void)
|
|||
while(1) {
|
||||
length = download_kernel(kbuf, sizeof(kbuf));
|
||||
if(length > 0) {
|
||||
load_elf(syscalls, kbuf, length, kcode, sizeof(kcode));
|
||||
flush_cpu_icache();
|
||||
k();
|
||||
if(load_elf(syscalls, kbuf, length, kcode, sizeof(kcode))) {
|
||||
flush_cpu_icache();
|
||||
k();
|
||||
send_sync();
|
||||
send_char(MSGTYPE_KERNEL_FINISHED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue