Partially implement urpc
Allocating memory on core 1 now works, but spawning on core 1 not yet.
This commit is contained in:
parent
d90add66da
commit
0148df04a0
@ -2,31 +2,45 @@
|
|||||||
#define _LIB_BARRELFISH_AOS_URPC_H
|
#define _LIB_BARRELFISH_AOS_URPC_H
|
||||||
|
|
||||||
#include <aos/aos.h>
|
#include <aos/aos.h>
|
||||||
|
#include <spawn/rpc_server.h>
|
||||||
#define RPC_URPC_FRAME_SIZE (ROUND_UP(sizeof(struct aos_urpc_meta), PAGE_SIZE) + PAGE_SIZE)
|
|
||||||
|
|
||||||
struct aos_urpc_meta {
|
struct aos_urpc_meta {
|
||||||
volatile bool call_in_progress;
|
volatile uint8_t call_in_progress;
|
||||||
|
|
||||||
|
|
||||||
uintptr_t msg_type;
|
|
||||||
size_t arg_size;
|
|
||||||
uintptr_t arg0;
|
|
||||||
uintptr_t arg1;
|
|
||||||
struct capability arg_cap;
|
|
||||||
|
|
||||||
errval_t ret_errval;
|
|
||||||
size_t ret_size;
|
|
||||||
uintptr_t ret0;
|
|
||||||
uintptr_t ret1;
|
|
||||||
uint8_t has_ret_cap;
|
|
||||||
struct capability ret_cap;
|
|
||||||
|
|
||||||
|
uintptr_t a0;
|
||||||
|
uintptr_t a1;
|
||||||
|
uintptr_t a2;
|
||||||
|
uintptr_t a3;
|
||||||
|
struct capability cap;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct aos_urpc_frame {
|
||||||
|
struct aos_urpc_meta meta_to_app;
|
||||||
|
struct aos_urpc_meta meta_to_bsp;
|
||||||
|
uint8_t padding[PAGE_SIZE - 2 * sizeof(struct aos_urpc_meta)];
|
||||||
|
uint8_t shared_mem_to_app[PAGE_SIZE];
|
||||||
|
uint8_t shared_mem_to_bsp[PAGE_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
STATIC_ASSERT_SIZEOF(struct aos_urpc_frame, MON_URPC_SIZE);
|
||||||
|
|
||||||
struct aos_urpc {
|
struct aos_urpc {
|
||||||
struct aos_urpc_meta *urpc;
|
struct aos_urpc_meta *meta;
|
||||||
void *shared_mem;
|
void *shared_mem;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct aos_urpc_server {
|
||||||
|
struct generic_rpc_server g;
|
||||||
|
struct aos_urpc_meta *meta;
|
||||||
|
struct thread_sem sem;
|
||||||
|
};
|
||||||
|
|
||||||
|
int urpc_server(void *arg);
|
||||||
|
|
||||||
|
errval_t do_aos_urpc(
|
||||||
|
struct aos_urpc *rpc, uintptr_t msg_type,
|
||||||
|
struct capref arg_cap, size_t arg_size, uintptr_t arg0, uintptr_t arg1,
|
||||||
|
struct capref *ret_cap, size_t *ret_size, uintptr_t *ret0, uintptr_t *ret1
|
||||||
|
);
|
||||||
|
|
||||||
#endif // _LIB_BARRELFISH_AOS_URPC_H
|
#endif // _LIB_BARRELFISH_AOS_URPC_H
|
||||||
|
|||||||
@ -54,7 +54,7 @@
|
|||||||
*/
|
*/
|
||||||
// Supports at least #MON_URPC_CHANNEL_LEN
|
// Supports at least #MON_URPC_CHANNEL_LEN
|
||||||
// Change #MON_URPC_CHANNEL_LEN if changing this
|
// Change #MON_URPC_CHANNEL_LEN if changing this
|
||||||
#define MON_URPC_SIZE (2 * BASE_PAGE_SIZE)
|
#define MON_URPC_SIZE (3 * BASE_PAGE_SIZE)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
||||||
|
|||||||
@ -3,9 +3,13 @@
|
|||||||
|
|
||||||
#include <aos/aos.h>
|
#include <aos/aos.h>
|
||||||
|
|
||||||
struct aos_rpc_server {
|
struct generic_rpc_server {
|
||||||
struct lmp_chan *chan;
|
|
||||||
void *shared_mem;
|
void *shared_mem;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct aos_rpc_server {
|
||||||
|
struct generic_rpc_server g;
|
||||||
|
struct lmp_chan *chan;
|
||||||
|
|
||||||
struct capref ret_cap;
|
struct capref ret_cap;
|
||||||
errval_t ret_err;
|
errval_t ret_err;
|
||||||
@ -14,6 +18,12 @@ struct aos_rpc_server {
|
|||||||
uintptr_t ret1;
|
uintptr_t ret1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef errval_t (*rpc_handler_t)(
|
||||||
|
struct generic_rpc_server *rpc,
|
||||||
|
struct capref arg_cap, size_t arg_size, uintptr_t arg0, uintptr_t arg1,
|
||||||
|
struct capref *ret_cap, size_t *ret_size, uintptr_t *ret0, uintptr_t *ret1
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize an aos_rpc_server struct.
|
* Initialize an aos_rpc_server struct.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -14,38 +14,39 @@
|
|||||||
|
|
||||||
#include <aos/aos_urpc.h>
|
#include <aos/aos_urpc.h>
|
||||||
#include <aos/kernel_cap_invocations.h>
|
#include <aos/kernel_cap_invocations.h>
|
||||||
|
#include <aos/waitset_chan.h>
|
||||||
|
#include <aos/aos_rpc.h>
|
||||||
|
#include <spawn/rpc_server.h>
|
||||||
|
|
||||||
__attribute__((__used__))
|
extern coreid_t my_core_id;
|
||||||
static errval_t do_aos_urpc(
|
extern rpc_handler_t rpc_handlers[RPC_MTYPE_COUNT];
|
||||||
|
|
||||||
|
errval_t do_aos_urpc(
|
||||||
struct aos_urpc *rpc, uintptr_t msg_type,
|
struct aos_urpc *rpc, uintptr_t msg_type,
|
||||||
struct capref arg_cap, size_t arg_size, uintptr_t arg0, uintptr_t arg1,
|
struct capref arg_cap, size_t arg_size, uintptr_t arg0, uintptr_t arg1,
|
||||||
struct capref *ret_cap, size_t *ret_size, uintptr_t *ret0, uintptr_t *ret1
|
struct capref *ret_cap, size_t *ret_size, uintptr_t *ret0, uintptr_t *ret1
|
||||||
) {
|
) {
|
||||||
errval_t err;
|
errval_t err;
|
||||||
|
|
||||||
rpc->urpc->msg_type = msg_type;
|
assert(rpc->meta->call_in_progress == 0);
|
||||||
|
|
||||||
struct capability arg_cap_info;
|
assert(capref_is_null(arg_cap));
|
||||||
err = cap_direct_identify(arg_cap, &arg_cap_info);
|
rpc->meta->cap.type = ObjType_Null;
|
||||||
if (err_is_fail(err)) return err_push(err, LIB_ERR_CAP_IDENTIFY);
|
|
||||||
// only allow ram capabilities or frame capabilities to be sent to other cores
|
|
||||||
assert(arg_cap_info.type == ObjType_RAM || arg_cap_info.type == ObjType_Frame);
|
|
||||||
|
|
||||||
rpc->urpc->arg_cap = arg_cap_info;
|
rpc->meta->a0 = msg_type;
|
||||||
|
rpc->meta->a1 = arg_size;
|
||||||
rpc->urpc->arg_size = arg_size;
|
rpc->meta->a2 = arg0;
|
||||||
rpc->urpc->arg0 = arg0;
|
rpc->meta->a3 = arg1;
|
||||||
rpc->urpc->arg1 = arg1;
|
|
||||||
|
|
||||||
// memory barrier
|
// memory barrier
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
"dmb sy\n"
|
"dmb sy\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
rpc->urpc->call_in_progress = 1;
|
rpc->meta->call_in_progress = 1;
|
||||||
|
|
||||||
// wait until the rpc call completes
|
// wait until the rpc call completes
|
||||||
while(rpc->urpc->call_in_progress) {
|
while(rpc->meta->call_in_progress) {
|
||||||
// yield the thread because there might be useful stuff to do...
|
// yield the thread because there might be useful stuff to do...
|
||||||
thread_yield();
|
thread_yield();
|
||||||
}
|
}
|
||||||
@ -56,15 +57,97 @@ static errval_t do_aos_urpc(
|
|||||||
);
|
);
|
||||||
|
|
||||||
// read the response
|
// read the response
|
||||||
if (ret_size != NULL) *ret_size = rpc->urpc->ret_size;
|
if (ret_size != NULL) *ret_size = rpc->meta->a1;
|
||||||
if (ret0 != NULL) *ret0 = rpc->urpc->ret0;
|
if (ret0 != NULL) *ret0 = rpc->meta->a2;
|
||||||
if (ret1 != NULL) *ret1 = rpc->urpc->ret1;
|
if (ret1 != NULL) *ret1 = rpc->meta->a3;
|
||||||
|
|
||||||
if(ret_cap != NULL && rpc->urpc->has_ret_cap) {
|
if(ret_cap != NULL && rpc->meta->cap.type == ObjType_RAM) {
|
||||||
err = slot_alloc(ret_cap);
|
err = slot_alloc(ret_cap);
|
||||||
ram_forge(*ret_cap, rpc->urpc->ret_cap.u.ram.base, rpc->urpc->ret_cap.u.ram.bytes, );
|
if (err_is_fail(err)) return err_push(err, LIB_ERR_SLOT_ALLOC);
|
||||||
|
err = ram_forge(*ret_cap, rpc->meta->cap.u.ram.base, rpc->meta->cap.u.ram.bytes, my_core_id);
|
||||||
|
if (err_is_fail(err)) return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rpc->urpc->ret_errval;
|
return rpc->meta->a0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void urpc_server_handler(void *arg) {
|
||||||
|
struct aos_urpc_server *urpc = arg;
|
||||||
|
errval_t err;
|
||||||
|
|
||||||
|
uintptr_t msg_type = urpc->meta->a0;
|
||||||
|
uintptr_t arg_size = urpc->meta->a1;
|
||||||
|
uintptr_t arg0 = urpc->meta->a2;
|
||||||
|
uintptr_t arg1 = urpc->meta->a3;
|
||||||
|
|
||||||
|
struct capref ret_cap = NULL_CAP;
|
||||||
|
urpc->meta->a1 = 0;
|
||||||
|
urpc->meta->a2 = 0;
|
||||||
|
urpc->meta->a3 = 0;
|
||||||
|
if (msg_type >= RPC_MTYPE_COUNT) {
|
||||||
|
err = AOS_ERR_RPC_UNKNOWN_MSG_TYPE;
|
||||||
|
} else if (arg_size > RPC_SHARED_SIZE) {
|
||||||
|
err = AOS_ERR_RPC_ARG_TOO_BIG;
|
||||||
|
} else {
|
||||||
|
rpc_handler_t handler = rpc_handlers[msg_type];
|
||||||
|
if (handler == NULL) {
|
||||||
|
err = AOS_ERR_RPC_UNKNOWN_MSG_TYPE;
|
||||||
|
} else {
|
||||||
|
err = handler(
|
||||||
|
&urpc->g,
|
||||||
|
NULL_CAP, arg_size, arg0, arg1,
|
||||||
|
&ret_cap, &urpc->meta->a1, &urpc->meta->a2, &urpc->meta->a3
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
urpc->meta->a0 = err;
|
||||||
|
if (!capref_is_null(ret_cap)) {
|
||||||
|
err = cap_direct_identify(ret_cap, &urpc->meta->cap);
|
||||||
|
if (err_is_fail(err)) {
|
||||||
|
DEBUG_ERR(err, "in cap_direct_identify while handling URPC");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
// only allow ram capabilities or frame capabilities to be sent to other cores
|
||||||
|
assert(urpc->meta->cap.type == ObjType_RAM || urpc->meta->cap.type == ObjType_Frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
// memory barrier
|
||||||
|
__asm volatile (
|
||||||
|
"dmb sy\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
// tell the other side that we are done
|
||||||
|
urpc->meta->call_in_progress = false;
|
||||||
|
|
||||||
|
// Unblock the URPC thread
|
||||||
|
thread_sem_post(&urpc->sem);
|
||||||
|
}
|
||||||
|
|
||||||
|
int urpc_server(void *arg) {
|
||||||
|
struct aos_urpc_server *urpc = arg;
|
||||||
|
struct waitset *default_ws = get_default_waitset();
|
||||||
|
struct waitset_chanstate chan;
|
||||||
|
waitset_chanstate_init(&chan, CHANTYPE_OTHER);
|
||||||
|
|
||||||
|
thread_sem_init(&urpc->sem, 0);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
// wait until an rpc call arrives
|
||||||
|
while(urpc->meta->call_in_progress == false) {
|
||||||
|
// yield the thread because there might be useful stuff to do...
|
||||||
|
thread_yield();
|
||||||
|
}
|
||||||
|
|
||||||
|
// memory barrier
|
||||||
|
__asm volatile (
|
||||||
|
"dmb sy\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
// handle the URPC on the same thread that handles regular RPCs, to avoid concurrency for the handlers
|
||||||
|
waitset_chan_trigger_closure(default_ws, &chan, MKCLOSURE(urpc_server_handler, urpc));
|
||||||
|
|
||||||
|
// wait until the rpc is handled
|
||||||
|
thread_sem_wait(&urpc->sem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4,20 +4,15 @@
|
|||||||
#include <grading.h>
|
#include <grading.h>
|
||||||
#include <spawn/spawn.h>
|
#include <spawn/spawn.h>
|
||||||
|
|
||||||
typedef errval_t (*rpc_handler_t)(
|
extern coreid_t my_core_id;
|
||||||
struct aos_rpc_server *rpc,
|
rpc_handler_t rpc_handlers[RPC_MTYPE_COUNT];
|
||||||
struct capref arg_cap, size_t arg_size, uintptr_t arg0, uintptr_t arg1,
|
|
||||||
struct capref *ret_cap, size_t *ret_size, uintptr_t *ret0, uintptr_t *ret1
|
|
||||||
);
|
|
||||||
|
|
||||||
static rpc_handler_t rpc_handlers[RPC_MTYPE_COUNT];
|
|
||||||
|
|
||||||
static void rpc_server_handle_recv(void *arg);
|
static void rpc_server_handle_recv(void *arg);
|
||||||
static void rpc_server_send_reply(void *arg);
|
static void rpc_server_send_reply(void *arg);
|
||||||
|
|
||||||
void rpc_server_init(struct aos_rpc_server *rpc, struct lmp_chan *chan, void *shared_mem) {
|
void rpc_server_init(struct aos_rpc_server *rpc, struct lmp_chan *chan, void *shared_mem) {
|
||||||
rpc->chan = chan;
|
rpc->chan = chan;
|
||||||
rpc->shared_mem = shared_mem;
|
rpc->g.shared_mem = shared_mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rpc_server_register_recv(struct aos_rpc_server *rpc) {
|
void rpc_server_register_recv(struct aos_rpc_server *rpc) {
|
||||||
@ -51,7 +46,7 @@ static void rpc_server_handle_recv(void *arg) {
|
|||||||
err = AOS_ERR_RPC_UNKNOWN_MSG_TYPE;
|
err = AOS_ERR_RPC_UNKNOWN_MSG_TYPE;
|
||||||
} else {
|
} else {
|
||||||
err = handler(
|
err = handler(
|
||||||
rpc,
|
&rpc->g,
|
||||||
arg_cap, msg.words[1], msg.words[2], msg.words[3],
|
arg_cap, msg.words[1], msg.words[2], msg.words[3],
|
||||||
&rpc->ret_cap, &rpc->ret_size, &rpc->ret0, &rpc->ret1
|
&rpc->ret_cap, &rpc->ret_size, &rpc->ret0, &rpc->ret1
|
||||||
);
|
);
|
||||||
@ -90,7 +85,7 @@ static void rpc_server_send_reply(void *arg) {
|
|||||||
// RPC handlers
|
// RPC handlers
|
||||||
|
|
||||||
static errval_t handle_rpc_send_number(
|
static errval_t handle_rpc_send_number(
|
||||||
struct aos_rpc_server *rpc,
|
struct generic_rpc_server *rpc,
|
||||||
struct capref arg_cap, size_t arg_size, uintptr_t arg0, uintptr_t arg1,
|
struct capref arg_cap, size_t arg_size, uintptr_t arg0, uintptr_t arg1,
|
||||||
struct capref *ret_cap, size_t *ret_size, uintptr_t *ret0, uintptr_t *ret1
|
struct capref *ret_cap, size_t *ret_size, uintptr_t *ret0, uintptr_t *ret1
|
||||||
) {
|
) {
|
||||||
@ -102,7 +97,7 @@ static errval_t handle_rpc_send_number(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static errval_t handle_rpc_send_string(
|
static errval_t handle_rpc_send_string(
|
||||||
struct aos_rpc_server *rpc,
|
struct generic_rpc_server *rpc,
|
||||||
struct capref arg_cap, size_t arg_size, uintptr_t arg0, uintptr_t arg1,
|
struct capref arg_cap, size_t arg_size, uintptr_t arg0, uintptr_t arg1,
|
||||||
struct capref *ret_cap, size_t *ret_size, uintptr_t *ret0, uintptr_t *ret1
|
struct capref *ret_cap, size_t *ret_size, uintptr_t *ret0, uintptr_t *ret1
|
||||||
) {
|
) {
|
||||||
@ -117,7 +112,7 @@ static errval_t handle_rpc_send_string(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static errval_t handle_rpc_get_ram_cap(
|
static errval_t handle_rpc_get_ram_cap(
|
||||||
struct aos_rpc_server *rpc,
|
struct generic_rpc_server *rpc,
|
||||||
struct capref arg_cap, size_t arg_size, uintptr_t arg0, uintptr_t arg1,
|
struct capref arg_cap, size_t arg_size, uintptr_t arg0, uintptr_t arg1,
|
||||||
struct capref *ret_cap, size_t *ret_size, uintptr_t *ret0, uintptr_t *ret1
|
struct capref *ret_cap, size_t *ret_size, uintptr_t *ret0, uintptr_t *ret1
|
||||||
) {
|
) {
|
||||||
@ -136,7 +131,7 @@ static errval_t handle_rpc_get_ram_cap(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static errval_t handle_rpc_serial_getchar(
|
static errval_t handle_rpc_serial_getchar(
|
||||||
struct aos_rpc_server *rpc,
|
struct generic_rpc_server *rpc,
|
||||||
struct capref arg_cap, size_t arg_size, uintptr_t arg0, uintptr_t arg1,
|
struct capref arg_cap, size_t arg_size, uintptr_t arg0, uintptr_t arg1,
|
||||||
struct capref *ret_cap, size_t *ret_size, uintptr_t *ret0, uintptr_t *ret1
|
struct capref *ret_cap, size_t *ret_size, uintptr_t *ret0, uintptr_t *ret1
|
||||||
) {
|
) {
|
||||||
@ -150,7 +145,7 @@ static errval_t handle_rpc_serial_getchar(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static errval_t handle_rpc_serial_putchar(
|
static errval_t handle_rpc_serial_putchar(
|
||||||
struct aos_rpc_server *rpc,
|
struct generic_rpc_server *rpc,
|
||||||
struct capref arg_cap, size_t arg_size, uintptr_t arg0, uintptr_t arg1,
|
struct capref arg_cap, size_t arg_size, uintptr_t arg0, uintptr_t arg1,
|
||||||
struct capref *ret_cap, size_t *ret_size, uintptr_t *ret0, uintptr_t *ret1
|
struct capref *ret_cap, size_t *ret_size, uintptr_t *ret0, uintptr_t *ret1
|
||||||
) {
|
) {
|
||||||
@ -165,7 +160,7 @@ static errval_t handle_rpc_serial_putchar(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static errval_t handle_rpc_serial_write(
|
static errval_t handle_rpc_serial_write(
|
||||||
struct aos_rpc_server *rpc,
|
struct generic_rpc_server *rpc,
|
||||||
struct capref arg_cap, size_t arg_size, uintptr_t arg0, uintptr_t arg1,
|
struct capref arg_cap, size_t arg_size, uintptr_t arg0, uintptr_t arg1,
|
||||||
struct capref *ret_cap, size_t *ret_size, uintptr_t *ret0, uintptr_t *ret1
|
struct capref *ret_cap, size_t *ret_size, uintptr_t *ret0, uintptr_t *ret1
|
||||||
) {
|
) {
|
||||||
@ -177,7 +172,7 @@ static errval_t handle_rpc_serial_write(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static errval_t handle_rpc_serial_read(
|
static errval_t handle_rpc_serial_read(
|
||||||
struct aos_rpc_server *rpc,
|
struct generic_rpc_server *rpc,
|
||||||
struct capref arg_cap, size_t arg_size, uintptr_t arg0, uintptr_t arg1,
|
struct capref arg_cap, size_t arg_size, uintptr_t arg0, uintptr_t arg1,
|
||||||
struct capref *ret_cap, size_t *ret_size, uintptr_t *ret0, uintptr_t *ret1
|
struct capref *ret_cap, size_t *ret_size, uintptr_t *ret0, uintptr_t *ret1
|
||||||
) {
|
) {
|
||||||
@ -189,7 +184,7 @@ static errval_t handle_rpc_serial_read(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static errval_t handle_rpc_process_spawn(
|
static errval_t handle_rpc_process_spawn(
|
||||||
struct aos_rpc_server *rpc,
|
struct generic_rpc_server *rpc,
|
||||||
struct capref arg_cap, size_t arg_size, uintptr_t arg0, uintptr_t arg1,
|
struct capref arg_cap, size_t arg_size, uintptr_t arg0, uintptr_t arg1,
|
||||||
struct capref *ret_cap, size_t *ret_size, uintptr_t *ret0, uintptr_t *ret1
|
struct capref *ret_cap, size_t *ret_size, uintptr_t *ret0, uintptr_t *ret1
|
||||||
) {
|
) {
|
||||||
@ -201,17 +196,21 @@ static errval_t handle_rpc_process_spawn(
|
|||||||
|
|
||||||
grading_rpc_handler_process_spawn(cmdline, core);
|
grading_rpc_handler_process_spawn(cmdline, core);
|
||||||
|
|
||||||
struct spawninfo *si = malloc(sizeof(struct spawninfo));
|
if (core != my_core_id) {
|
||||||
|
struct spawninfo *si = malloc(sizeof(struct spawninfo));
|
||||||
|
|
||||||
char *argv[MAX_CMDLINE_ARGS];
|
char *argv[MAX_CMDLINE_ARGS];
|
||||||
int argc;
|
int argc;
|
||||||
spawn_parse_cmd(cmdline, &argc, argv);
|
spawn_parse_cmd(cmdline, &argc, argv);
|
||||||
|
|
||||||
return spawn_load_argv(argc, argv, si, (domainid_t *)ret0);
|
return spawn_load_argv(argc, argv, si, (domainid_t *)ret0);
|
||||||
|
}
|
||||||
|
assert(core == 0); // Spawning from core 1 on core 0 is not supported.
|
||||||
|
abort(); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
static errval_t handle_rpc_process_get_name(
|
static errval_t handle_rpc_process_get_name(
|
||||||
struct aos_rpc_server *rpc,
|
struct generic_rpc_server *rpc,
|
||||||
struct capref arg_cap, size_t arg_size, uintptr_t arg0, uintptr_t arg1,
|
struct capref arg_cap, size_t arg_size, uintptr_t arg0, uintptr_t arg1,
|
||||||
struct capref *ret_cap, size_t *ret_size, uintptr_t *ret0, uintptr_t *ret1
|
struct capref *ret_cap, size_t *ret_size, uintptr_t *ret0, uintptr_t *ret1
|
||||||
) {
|
) {
|
||||||
@ -244,7 +243,7 @@ static errval_t handle_rpc_process_get_name(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static errval_t handle_rpc_process_get_all_pids(
|
static errval_t handle_rpc_process_get_all_pids(
|
||||||
struct aos_rpc_server *rpc,
|
struct generic_rpc_server *rpc,
|
||||||
struct capref arg_cap, size_t arg_size, uintptr_t arg0, uintptr_t arg1,
|
struct capref arg_cap, size_t arg_size, uintptr_t arg0, uintptr_t arg1,
|
||||||
struct capref *ret_cap, size_t *ret_size, uintptr_t *ret0, uintptr_t *ret1
|
struct capref *ret_cap, size_t *ret_size, uintptr_t *ret0, uintptr_t *ret1
|
||||||
) {
|
) {
|
||||||
@ -271,7 +270,7 @@ static errval_t handle_rpc_process_get_all_pids(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static rpc_handler_t rpc_handlers[RPC_MTYPE_COUNT] = {
|
rpc_handler_t rpc_handlers[RPC_MTYPE_COUNT] = {
|
||||||
[RPC_MTYPE_SEND_NUMBER] = handle_rpc_send_number,
|
[RPC_MTYPE_SEND_NUMBER] = handle_rpc_send_number,
|
||||||
[RPC_MTYPE_SEND_STRING] = handle_rpc_send_string,
|
[RPC_MTYPE_SEND_STRING] = handle_rpc_send_string,
|
||||||
[RPC_MTYPE_GET_RAM_CAP] = handle_rpc_get_ram_cap,
|
[RPC_MTYPE_GET_RAM_CAP] = handle_rpc_get_ram_cap,
|
||||||
|
|||||||
@ -28,6 +28,7 @@
|
|||||||
#include <aos/coreboot.h>
|
#include <aos/coreboot.h>
|
||||||
#include <aos/cache.h>
|
#include <aos/cache.h>
|
||||||
|
|
||||||
|
#include <barrelfish_kpi/startup_arm.h>
|
||||||
|
|
||||||
|
|
||||||
struct bootinfo *bi;
|
struct bootinfo *bi;
|
||||||
@ -35,6 +36,30 @@ struct bootinfo *bi;
|
|||||||
coreid_t my_core_id;
|
coreid_t my_core_id;
|
||||||
struct platform_info platform_info;
|
struct platform_info platform_info;
|
||||||
|
|
||||||
|
// only valid on app core
|
||||||
|
static struct aos_urpc urpc_to_bsp;
|
||||||
|
|
||||||
|
// only valid on app core
|
||||||
|
static struct aos_urpc_server urpc_to_app_server;
|
||||||
|
|
||||||
|
// only valid on bsp core
|
||||||
|
struct aos_urpc urpc_to_app;
|
||||||
|
|
||||||
|
|
||||||
|
static errval_t ram_alloc_remote_core(struct capref *ret, size_t size, size_t alignment)
|
||||||
|
{
|
||||||
|
errval_t err;
|
||||||
|
|
||||||
|
err = do_aos_urpc(
|
||||||
|
&urpc_to_bsp, RPC_MTYPE_GET_RAM_CAP,
|
||||||
|
NULL_CAP, 0, size, alignment,
|
||||||
|
ret, NULL, NULL, NULL
|
||||||
|
);
|
||||||
|
if (err_is_fail(err)) return err_push(err, LIB_ERR_RAM_ALLOC);
|
||||||
|
|
||||||
|
return SYS_ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
bsp_main(int argc, char *argv[]) {
|
bsp_main(int argc, char *argv[]) {
|
||||||
errval_t err;
|
errval_t err;
|
||||||
@ -61,11 +86,11 @@ bsp_main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
|
|
||||||
// TODO: Spawn system processes, boot second core etc. here
|
// TODO: Spawn system processes, boot second core etc. here
|
||||||
|
|
||||||
// A URPC frame, to hold the cross-core communication channels that you
|
// A URPC frame, to hold the cross-core communication channels that you
|
||||||
// will implement in Section 7.16.
|
// will implement in Section 7.16.
|
||||||
struct capref urpc_frame;
|
struct capref urpc_frame;
|
||||||
err = frame_alloc(&urpc_frame, RPC_URPC_FRAME_SIZE, NULL);
|
err = frame_alloc(&urpc_frame, MON_URPC_SIZE, NULL);
|
||||||
if(err_is_fail(err)) return err_push(err, LIB_ERR_FRAME_ALLOC);
|
if(err_is_fail(err)) return err_push(err, LIB_ERR_FRAME_ALLOC);
|
||||||
|
|
||||||
struct frame_identity urpc_frame_id;
|
struct frame_identity urpc_frame_id;
|
||||||
@ -85,20 +110,17 @@ bsp_main(int argc, char *argv[]) {
|
|||||||
USER_PANIC("Platform not implemented");
|
USER_PANIC("Platform not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
void *addr;
|
void *urpc_addr;
|
||||||
paging_map_frame(get_current_paging_state(), &addr, PAGE_SIZE, urpc_frame);
|
err = paging_map_frame(get_current_paging_state(), &urpc_addr, MON_URPC_SIZE, urpc_frame);
|
||||||
assert(err_is_ok(err));
|
if (err_is_fail(err)) return err;
|
||||||
*(uint8_t *)addr = 123;
|
memset(urpc_addr, 0, MON_URPC_SIZE);
|
||||||
|
|
||||||
// memory barrier
|
// memory barrier
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
"dmb sy\n"
|
"dmb sy\n"
|
||||||
);
|
);
|
||||||
cpu_idcache_wbinv_range((uintptr_t)addr, 64);
|
cpu_idcache_wbinv_range((uintptr_t)urpc_addr, MON_URPC_SIZE);
|
||||||
// memory barrier
|
|
||||||
__asm volatile (
|
|
||||||
"dmb sy\n"
|
|
||||||
);
|
|
||||||
// TODO rueegges: can we get the mpid in a better way?
|
// TODO rueegges: can we get the mpid in a better way?
|
||||||
err = coreboot(1, "boot_armv8_generic", cpu_driver_name, "init", urpc_frame_id);
|
err = coreboot(1, "boot_armv8_generic", cpu_driver_name, "init", urpc_frame_id);
|
||||||
if (err_is_fail(err)) return err_push(err, MON_ERR_SPAWN_CORE);
|
if (err_is_fail(err)) return err_push(err, MON_ERR_SPAWN_CORE);
|
||||||
@ -107,20 +129,16 @@ bsp_main(int argc, char *argv[]) {
|
|||||||
// err = coreboot(3, "boot_armv8_generic", cpu_driver_name, "init", urpc_frame_id);
|
// err = coreboot(3, "boot_armv8_generic", cpu_driver_name, "init", urpc_frame_id);
|
||||||
// if (err_is_fail(err)) return err_push(err, MON_ERR_SPAWN_CORE);
|
// if (err_is_fail(err)) return err_push(err, MON_ERR_SPAWN_CORE);
|
||||||
|
|
||||||
while(*(volatile uint8_t *)addr == 123){
|
struct aos_urpc_frame *urpc = urpc_addr;
|
||||||
cpu_idcache_wbinv_range((uintptr_t)addr, 64);
|
|
||||||
// memory barrier
|
|
||||||
__asm volatile (
|
|
||||||
"dmb sy\n"
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
// memory barrier
|
struct aos_urpc_server *urpc_to_bsp_server = malloc(sizeof(struct aos_urpc_server));
|
||||||
__asm volatile (
|
urpc_to_bsp_server->g.shared_mem = &urpc->shared_mem_to_bsp;
|
||||||
"dmb sy\n"
|
urpc_to_bsp_server->meta = &urpc->meta_to_bsp;
|
||||||
);
|
thread_create(urpc_server, urpc_to_bsp_server);
|
||||||
|
|
||||||
|
urpc_to_app.shared_mem = &urpc->shared_mem_to_app;
|
||||||
|
urpc_to_app.meta = &urpc->meta_to_app;
|
||||||
|
|
||||||
debug_printf("Got response\n");
|
|
||||||
|
|
||||||
// Grading
|
// Grading
|
||||||
grading_test_late();
|
grading_test_late();
|
||||||
@ -164,23 +182,17 @@ app_main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
// TODO: Spawn system processes etc. here
|
// TODO: Spawn system processes etc. here
|
||||||
|
|
||||||
// test communication
|
struct aos_urpc_frame *urpc = (void*)MON_URPC_VBASE;
|
||||||
struct capref cap_urpc = {
|
|
||||||
.cnode = { .croot = CPTR_ROOTCN, .cnode = CPTR_TASKCN_BASE, .level = CNODE_TYPE_OTHER, },
|
urpc_to_bsp.shared_mem = &urpc->shared_mem_to_bsp;
|
||||||
.slot = TASKCN_SLOT_MON_URPC
|
urpc_to_bsp.meta = &urpc->meta_to_bsp;
|
||||||
};
|
|
||||||
void *addr;
|
urpc_to_app_server.g.shared_mem = &urpc->shared_mem_to_app;
|
||||||
err = paging_map_frame(get_current_paging_state(), &addr, PAGE_SIZE, cap_urpc);
|
urpc_to_app_server.meta = &urpc->meta_to_app;
|
||||||
if(err_is_fail(err)) {
|
|
||||||
USER_PANIC_ERR(err, "failed to map urpc frame");
|
ram_alloc_set(ram_alloc_remote_core);
|
||||||
}
|
|
||||||
assert(*(uint8_t *)addr == 123);
|
thread_create(urpc_server, &urpc_to_app_server);
|
||||||
*(uint8_t *)addr = 21;
|
|
||||||
cpu_idcache_wbinv_range((uintptr_t)addr, 64);
|
|
||||||
// memory barrier
|
|
||||||
__asm volatile (
|
|
||||||
"dmb sy\n"
|
|
||||||
);
|
|
||||||
|
|
||||||
// Grading
|
// Grading
|
||||||
grading_test_late();
|
grading_test_late();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user