runtime: implement RPC syscall

This commit is contained in:
Sebastien Bourdeauducq 2014-07-07 19:13:43 +02:00
parent 09e78a1f5e
commit bb4a992907
1 changed files with 67 additions and 26 deletions

View File

@ -11,24 +11,12 @@
#include "elf_loader.h" #include "elf_loader.h"
static void receive_sync(void) enum {
{ MSGTYPE_KERNEL_FINISHED = 0x01,
char c; MSGTYPE_RPC_REQUEST = 0x02,
int recognized; };
recognized = 0; static int receive_int(void)
while(1) {
c = readchar();
if(c == 0x5a) {
recognized++;
if(recognized == 4)
return;
} else
recognized = 0;
}
}
static int receive_length(void)
{ {
unsigned int r; unsigned int r;
int i; int i;
@ -36,11 +24,57 @@ static int receive_length(void)
r = 0; r = 0;
for(i=0;i<4;i++) { for(i=0;i<4;i++) {
r <<= 8; r <<= 8;
r |= (unsigned char)readchar(); r |= (unsigned char)uart_read();
} }
return r; 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) static int download_kernel(void *buffer, int maxlength)
{ {
int length; int length;
@ -48,25 +82,29 @@ static int download_kernel(void *buffer, int maxlength)
unsigned char *_buffer = buffer; unsigned char *_buffer = buffer;
receive_sync(); receive_sync();
length = receive_length(); length = receive_int();
if(length > maxlength) if(length > maxlength)
return -1; return -1;
for(i=0;i<length;i++) for(i=0;i<length;i++)
_buffer[i] = readchar(); _buffer[i] = receive_char();
send_char(0x4f);
return length; return length;
} }
static int rpc(int rpc_num, int n_args, ...) 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_list args;
va_start(args, n_args); va_start(args, n_args);
while(n_args--) while(n_args--)
printf("%d\n", va_arg(args, int)); send_int(va_arg(args, int));
va_end(args); va_end(args);
return 1; return receive_int();
} }
static void gpio_set(int channel, int level) static void gpio_set(int channel, int level)
@ -98,9 +136,12 @@ int main(void)
while(1) { while(1) {
length = download_kernel(kbuf, sizeof(kbuf)); length = download_kernel(kbuf, sizeof(kbuf));
if(length > 0) { if(length > 0) {
load_elf(syscalls, kbuf, length, kcode, sizeof(kcode)); if(load_elf(syscalls, kbuf, length, kcode, sizeof(kcode))) {
flush_cpu_icache(); flush_cpu_icache();
k(); k();
send_sync();
send_char(MSGTYPE_KERNEL_FINISHED);
}
} }
} }