Implement RPC
This commit is contained in:
parent
f2fb4d5d01
commit
14063e60be
@ -1323,7 +1323,7 @@ errors sfn NIC_ERR_{
|
|||||||
failure IO "Error during card IO",
|
failure IO "Error during card IO",
|
||||||
failure INTR "Interrupted system call",
|
failure INTR "Interrupted system call",
|
||||||
failure NOSYS "Not implemented",
|
failure NOSYS "Not implemented",
|
||||||
failure UNKNOWN "Uknown error",
|
failure UNKNOWN "Unknown error",
|
||||||
failure TX_PKT "Error sending packet",
|
failure TX_PKT "Error sending packet",
|
||||||
failure RX_PKT "Error receiving packet",
|
failure RX_PKT "Error receiving packet",
|
||||||
failure RX_DISCARD "Error, packet needs to be discared",
|
failure RX_DISCARD "Error, packet needs to be discared",
|
||||||
@ -1376,6 +1376,10 @@ errors vas VAS_ERR_ {
|
|||||||
errors aos AOS_ERR_ {
|
errors aos AOS_ERR_ {
|
||||||
failure LMP_SEND_FAILURE "Failure while sending AOS LMP message",
|
failure LMP_SEND_FAILURE "Failure while sending AOS LMP message",
|
||||||
failure LMP_MSGTYPE_UNKNOWN "Unknown message type for AOS LMP implementation",
|
failure LMP_MSGTYPE_UNKNOWN "Unknown message type for AOS LMP implementation",
|
||||||
|
failure RPC_UNEXPECTED_MSGTYPE "Received RPC message of unexpected type",
|
||||||
|
failure RPC_ARG_TOO_BIG "RPC argument is too big",
|
||||||
|
failure RPC_RET_TOO_BIG "RPC return value is too big",
|
||||||
|
failure RPC_UNKNOWN_MSG_TYPE "RPC with unknown message type",
|
||||||
};
|
};
|
||||||
|
|
||||||
// errors NIC driver
|
// errors NIC driver
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
bootdriver /armv8/sbin/boot_armv8_generic
|
bootdriver /armv8/sbin/boot_armv8_generic
|
||||||
cpudriver /armv8/sbin/cpu_a57_qemu loglevel=3 serial=0x9000000 logmask=128
|
cpudriver /armv8/sbin/cpu_a57_qemu loglevel=3 serial=0x9000000 logmask=128
|
||||||
module /armv8/sbin/init
|
module /armv8/sbin/init
|
||||||
module /armv8/sbin/hello catch Aurel Jan Sandro
|
module /armv8/sbin/hello Aurel Jan Sandro
|
||||||
module /armv8/sbin/memeater
|
module /armv8/sbin/memeater
|
||||||
|
|
||||||
# End of file, this needs to have a certain length...
|
# End of file, this needs to have a certain length...
|
||||||
|
|||||||
@ -5,5 +5,5 @@
|
|||||||
bootdriver /armv8/sbin/boot_armv8_generic
|
bootdriver /armv8/sbin/boot_armv8_generic
|
||||||
cpudriver /armv8/sbin/cpu_imx8x
|
cpudriver /armv8/sbin/cpu_imx8x
|
||||||
module /armv8/sbin/init
|
module /armv8/sbin/init
|
||||||
module /armv8/sbin/hello catch Aurel Jan Sandro
|
module /armv8/sbin/hello Aurel Jan Sandro
|
||||||
module /armv8/sbin/memeater
|
module /armv8/sbin/memeater
|
||||||
@ -17,23 +17,34 @@
|
|||||||
|
|
||||||
#include <aos/aos.h>
|
#include <aos/aos.h>
|
||||||
|
|
||||||
|
#define RPC_SHARED_SIZE PAGE_SIZE
|
||||||
|
|
||||||
// define some message types
|
// define some message types
|
||||||
#define RPC_MTYPE_CHILD_ENDPOINT 1UL
|
enum rpc_mtype {
|
||||||
#define RPC_MTYPE_CHILD_ENDPOINT_OK 2UL
|
RPC_MTYPE_CHILD_ENDPOINT,
|
||||||
#define RPC_MTYPE_GET_RAM_CAP 3UL
|
RPC_MTYPE_SEND_NUMBER,
|
||||||
#define RPC_MTYPE_GET_RAM_CAP_OK 4UL
|
RPC_MTYPE_SEND_STRING,
|
||||||
|
RPC_MTYPE_GET_RAM_CAP,
|
||||||
|
RPC_MTYPE_SERIAL_GETCHAR,
|
||||||
|
RPC_MTYPE_SERIAL_PUTCHAR,
|
||||||
|
RPC_MTYPE_PROCESS_SPAWN,
|
||||||
|
RPC_MTYPE_PROCESS_GET_NAME,
|
||||||
|
RPC_MTYPE_PROCESS_GET_ALL_PIDS,
|
||||||
|
RPC_MTYPE_COUNT // How many message types exist
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/* An RPC binding, which may be transported over LMP or UMP. */
|
/* An RPC binding, which may be transported over LMP or UMP. */
|
||||||
struct aos_rpc {
|
struct aos_rpc {
|
||||||
// TODO(M3): Add state
|
|
||||||
struct lmp_chan *chan;
|
struct lmp_chan *chan;
|
||||||
|
struct waitset ws;
|
||||||
|
void *shared_mem;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Initialize an aos_rpc struct.
|
* \brief Initialize an aos_rpc struct.
|
||||||
*/
|
*/
|
||||||
errval_t aos_rpc_init(struct aos_rpc *rpc);
|
errval_t aos_rpc_init(struct aos_rpc *rpc, struct lmp_chan *chan, void *shared_mem);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -25,6 +25,7 @@ struct spawn_domain_params {
|
|||||||
char *envp[MAX_ENVIRON_VARS + 1]; ///< Environment strings; +1 for NULL terminator
|
char *envp[MAX_ENVIRON_VARS + 1]; ///< Environment strings; +1 for NULL terminator
|
||||||
void *vspace_buf; ///< Serialised vspace data
|
void *vspace_buf; ///< Serialised vspace data
|
||||||
size_t vspace_buf_len; ///< Length of serialised vspace data
|
size_t vspace_buf_len; ///< Length of serialised vspace data
|
||||||
|
void *rpc_shared_memory;
|
||||||
void *tls_init_base; ///< Address of initialised TLS data block
|
void *tls_init_base; ///< Address of initialised TLS data block
|
||||||
size_t tls_init_len; ///< Length of initialised TLS data block
|
size_t tls_init_len; ///< Length of initialised TLS data block
|
||||||
size_t tls_total_len; ///< Total (initialised + BSS) TLS data length
|
size_t tls_total_len; ///< Total (initialised + BSS) TLS data length
|
||||||
|
|||||||
28
include/spawn/rpc_server.h
Normal file
28
include/spawn/rpc_server.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#ifndef _RPC_SERVER_H_
|
||||||
|
#define _RPC_SERVER_H_
|
||||||
|
|
||||||
|
#include <aos/aos.h>
|
||||||
|
|
||||||
|
struct aos_rpc_server {
|
||||||
|
struct lmp_chan *chan;
|
||||||
|
struct waitset ws;
|
||||||
|
void *shared_mem;
|
||||||
|
|
||||||
|
struct capref ret_cap;
|
||||||
|
errval_t ret_err;
|
||||||
|
size_t ret_size;
|
||||||
|
uintptr_t ret0;
|
||||||
|
uintptr_t ret1;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize an aos_rpc_server struct.
|
||||||
|
*/
|
||||||
|
void rpc_server_init(struct aos_rpc_server *rpc, struct lmp_chan *chan, void *shared_mem);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start listening for RPCs.
|
||||||
|
*/
|
||||||
|
void rpc_server_register_recv(struct aos_rpc_server *rpc);
|
||||||
|
|
||||||
|
#endif /* _RPC_SERVER_H_ */
|
||||||
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include "aos/slot_alloc.h"
|
#include "aos/slot_alloc.h"
|
||||||
#include "aos/paging.h"
|
#include "aos/paging.h"
|
||||||
|
#include <spawn/rpc_server.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -34,7 +35,7 @@ struct spawninfo {
|
|||||||
// when spawning a new dispatcher,
|
// when spawning a new dispatcher,
|
||||||
// e.g. references to the child's
|
// e.g. references to the child's
|
||||||
// capabilities or paging state
|
// capabilities or paging state
|
||||||
|
|
||||||
//afeer: see script page 84/85
|
//afeer: see script page 84/85
|
||||||
struct cnoderef cspace_l1_cnode_info;
|
struct cnoderef cspace_l1_cnode_info;
|
||||||
struct capref cspace_l1_cnode_cap;
|
struct capref cspace_l1_cnode_cap;
|
||||||
@ -58,6 +59,8 @@ struct spawninfo {
|
|||||||
struct capref vspace_cap_l0_pagetable;
|
struct capref vspace_cap_l0_pagetable;
|
||||||
|
|
||||||
struct lmp_chan init_chan;
|
struct lmp_chan init_chan;
|
||||||
|
struct capref rpc_shared_frame;
|
||||||
|
struct aos_rpc_server rpc_server;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Start a child process using the multiboot command line. Fills in si.
|
// Start a child process using the multiboot command line. Fills in si.
|
||||||
|
|||||||
@ -17,74 +17,171 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void noop_callback(void *arg) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static errval_t do_aos_rpc(
|
||||||
|
struct aos_rpc *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
|
||||||
|
) {
|
||||||
|
errval_t err;
|
||||||
|
|
||||||
|
// Send call
|
||||||
|
while (true) {
|
||||||
|
err = lmp_chan_send4(rpc->chan, LMP_FLAG_YIELD | LMP_FLAG_SYNC, arg_cap, msg_type, arg_size, arg0, arg1);
|
||||||
|
if (!err_is_fail(err)) break;
|
||||||
|
if (!lmp_err_is_transient(err)) {
|
||||||
|
return err_push(err, AOS_ERR_LMP_SEND_FAILURE);
|
||||||
|
}
|
||||||
|
err = lmp_chan_register_send(rpc->chan, &rpc->ws, MKCLOSURE(noop_callback, NULL));
|
||||||
|
if (err_is_fail(err)) return err;
|
||||||
|
err = event_dispatch(&rpc->ws);
|
||||||
|
if (err_is_fail(err)) return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Receive return value
|
||||||
|
struct lmp_recv_msg recv = LMP_RECV_MSG_INIT;
|
||||||
|
while (!lmp_endpoint_can_recv(rpc->chan->endpoint)) {
|
||||||
|
err = lmp_chan_register_recv(rpc->chan, &rpc->ws, MKCLOSURE(noop_callback, NULL));
|
||||||
|
if (err_is_fail(err)) return err;
|
||||||
|
err = event_dispatch(&rpc->ws);
|
||||||
|
if (err_is_fail(err)) return err;
|
||||||
|
}
|
||||||
|
err = lmp_chan_recv(rpc->chan, &recv, ret_cap);
|
||||||
|
assert(err_is_ok(err));
|
||||||
|
|
||||||
|
if (ret_size != NULL) *ret_size = recv.words[1];
|
||||||
|
if (ret0 != NULL) *ret0 = recv.words[2];
|
||||||
|
if (ret1 != NULL) *ret1 = recv.words[3];
|
||||||
|
return recv.words[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
errval_t
|
errval_t
|
||||||
aos_rpc_send_number(struct aos_rpc *rpc, uintptr_t num) {
|
aos_rpc_send_number(struct aos_rpc *rpc, uintptr_t num) {
|
||||||
// TODO: implement functionality to send a number over the channel
|
// Implement functionality to send a number over the channel
|
||||||
// given channel and wait until the ack gets returned.
|
// given channel and wait until the ack gets returned.
|
||||||
return SYS_ERR_OK;
|
return do_aos_rpc(
|
||||||
|
rpc, RPC_MTYPE_SEND_NUMBER,
|
||||||
|
NULL_CAP, 0, num, 0,
|
||||||
|
NULL, NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
errval_t
|
errval_t
|
||||||
aos_rpc_send_string(struct aos_rpc *rpc, const char *string) {
|
aos_rpc_send_string(struct aos_rpc *rpc, const char *string) {
|
||||||
// TODO: implement functionality to send a string over the given channel
|
// Implement functionality to send a string over the given channel
|
||||||
// and wait for a response.
|
// and wait for a response.
|
||||||
return SYS_ERR_OK;
|
size_t string_size = strlen(string) + 1;
|
||||||
|
if (string_size > RPC_SHARED_SIZE) return AOS_ERR_RPC_ARG_TOO_BIG;
|
||||||
|
memcpy(rpc->shared_mem, string, string_size);
|
||||||
|
|
||||||
|
return do_aos_rpc(
|
||||||
|
rpc, RPC_MTYPE_SEND_STRING,
|
||||||
|
NULL_CAP, string_size, 0, 0,
|
||||||
|
NULL, NULL, NULL, NULL
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
errval_t
|
errval_t
|
||||||
aos_rpc_get_ram_cap(struct aos_rpc *rpc, size_t bytes, size_t alignment,
|
aos_rpc_get_ram_cap(struct aos_rpc *rpc, size_t bytes, size_t alignment,
|
||||||
struct capref *ret_cap, size_t *ret_bytes) {
|
struct capref *ret_cap, size_t *ret_bytes) {
|
||||||
// TODO: implement functionality to request a RAM capability over the
|
// Implement functionality to request a RAM capability over the
|
||||||
// given channel and wait until it is delivered.
|
// given channel and wait until it is delivered.
|
||||||
return SYS_ERR_OK;
|
return do_aos_rpc(
|
||||||
|
rpc, RPC_MTYPE_GET_RAM_CAP,
|
||||||
|
NULL_CAP, 0, bytes, alignment,
|
||||||
|
ret_cap, NULL, ret_bytes, NULL
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
errval_t
|
errval_t
|
||||||
aos_rpc_serial_getchar(struct aos_rpc *rpc, char *retc) {
|
aos_rpc_serial_getchar(struct aos_rpc *rpc, char *retc) {
|
||||||
// TODO implement functionality to request a character from
|
// Implement functionality to request a character from
|
||||||
// the serial driver.
|
// the serial driver.
|
||||||
return SYS_ERR_OK;
|
uintptr_t retval;
|
||||||
|
errval_t err = do_aos_rpc(
|
||||||
|
rpc, RPC_MTYPE_SERIAL_GETCHAR,
|
||||||
|
NULL_CAP, 0, 0, 0,
|
||||||
|
NULL, NULL, &retval, NULL);
|
||||||
|
*retc = retval;
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
errval_t
|
errval_t
|
||||||
aos_rpc_serial_putchar(struct aos_rpc *rpc, char c) {
|
aos_rpc_serial_putchar(struct aos_rpc *rpc, char c) {
|
||||||
// TODO implement functionality to send a character to the
|
// Implement functionality to send a character to the
|
||||||
// serial port.
|
// serial port.
|
||||||
return SYS_ERR_OK;
|
return do_aos_rpc(
|
||||||
|
rpc, RPC_MTYPE_SERIAL_PUTCHAR,
|
||||||
|
NULL_CAP, 0, c, 0,
|
||||||
|
NULL, NULL, NULL, NULL
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
errval_t
|
errval_t
|
||||||
aos_rpc_process_spawn(struct aos_rpc *rpc, char *cmdline,
|
aos_rpc_process_spawn(struct aos_rpc *rpc, char *cmdline,
|
||||||
coreid_t core, domainid_t *newpid) {
|
coreid_t core, domainid_t *newpid) {
|
||||||
// TODO (M5): implement spawn new process rpc
|
// (M5): implement spawn new process rpc
|
||||||
return SYS_ERR_OK;
|
size_t cmdline_size = strlen(cmdline) + 1;
|
||||||
|
if (cmdline_size > RPC_SHARED_SIZE) return AOS_ERR_RPC_ARG_TOO_BIG;
|
||||||
|
memcpy(rpc->shared_mem, cmdline, cmdline_size);
|
||||||
|
|
||||||
|
uintptr_t retval;
|
||||||
|
errval_t err = do_aos_rpc(
|
||||||
|
rpc, RPC_MTYPE_PROCESS_SPAWN,
|
||||||
|
NULL_CAP, cmdline_size, core, 0,
|
||||||
|
NULL, NULL, &retval, NULL
|
||||||
|
);
|
||||||
|
*newpid = retval;
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
errval_t
|
errval_t
|
||||||
aos_rpc_process_get_name(struct aos_rpc *rpc, domainid_t pid, char **name) {
|
aos_rpc_process_get_name(struct aos_rpc *rpc, domainid_t pid, char **name) {
|
||||||
// TODO (M5): implement name lookup for process given a process id
|
// (M5): implement name lookup for process given a process id
|
||||||
return SYS_ERR_OK;
|
size_t name_len;
|
||||||
|
errval_t err = do_aos_rpc(
|
||||||
|
rpc, RPC_MTYPE_PROCESS_GET_NAME,
|
||||||
|
NULL_CAP, 0, pid, 0,
|
||||||
|
NULL, &name_len, NULL, NULL
|
||||||
|
);
|
||||||
|
if (err_is_fail(err)) return err;
|
||||||
|
*name = malloc(name_len);
|
||||||
|
if (*name == NULL) return LIB_ERR_MALLOC_FAIL;
|
||||||
|
memcpy(name, rpc->shared_mem, name_len);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
errval_t
|
errval_t
|
||||||
aos_rpc_process_get_all_pids(struct aos_rpc *rpc, domainid_t **pids,
|
aos_rpc_process_get_all_pids(struct aos_rpc *rpc, domainid_t **pids,
|
||||||
size_t *pid_count) {
|
size_t *pid_count) {
|
||||||
// TODO (M5): implement process id discovery
|
// (M5): implement process id discovery
|
||||||
return SYS_ERR_OK;
|
size_t ret_len;
|
||||||
|
errval_t err = do_aos_rpc(
|
||||||
|
rpc, RPC_MTYPE_PROCESS_GET_NAME,
|
||||||
|
NULL_CAP, 0, 0, 0,
|
||||||
|
NULL, &ret_len, NULL, NULL
|
||||||
|
);
|
||||||
|
if (err_is_fail(err)) return err;
|
||||||
|
*pid_count = ret_len / sizeof(**pids);
|
||||||
|
*pids = malloc(ret_len);
|
||||||
|
if (*pids == NULL) return LIB_ERR_MALLOC_FAIL;
|
||||||
|
memcpy(pids, rpc->shared_mem, ret_len);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We are allowed to change the signature for this one
|
// We are allowed to change the signature for this one
|
||||||
errval_t aos_rpc_init(struct aos_rpc *rpc)
|
errval_t aos_rpc_init(struct aos_rpc *rpc, struct lmp_chan *chan, void *shared_mem)
|
||||||
{
|
{
|
||||||
// TODO!
|
rpc->chan = chan;
|
||||||
|
rpc->shared_mem = shared_mem;
|
||||||
|
waitset_init(&rpc->ws);
|
||||||
return SYS_ERR_OK;
|
return SYS_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,9 +190,8 @@ errval_t aos_rpc_init(struct aos_rpc *rpc)
|
|||||||
*/
|
*/
|
||||||
struct aos_rpc *aos_rpc_get_init_channel(void)
|
struct aos_rpc *aos_rpc_get_init_channel(void)
|
||||||
{
|
{
|
||||||
//TODO: Return channel to talk to init process
|
// Return channel to talk to init process
|
||||||
debug_printf("aos_rpc_get_init_channel NYI\n");
|
return get_init_rpc();
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -103,10 +199,9 @@ struct aos_rpc *aos_rpc_get_init_channel(void)
|
|||||||
*/
|
*/
|
||||||
struct aos_rpc *aos_rpc_get_memory_channel(void)
|
struct aos_rpc *aos_rpc_get_memory_channel(void)
|
||||||
{
|
{
|
||||||
//TODO: Return channel to talk to memory server process (or whoever
|
// Return channel to talk to memory server process (or whoever
|
||||||
//implements memory server functionality)
|
// implements memory server functionality)
|
||||||
debug_printf("aos_rpc_get_memory_channel NYI\n");
|
return get_init_rpc();
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -114,10 +209,9 @@ struct aos_rpc *aos_rpc_get_memory_channel(void)
|
|||||||
*/
|
*/
|
||||||
struct aos_rpc *aos_rpc_get_process_channel(void)
|
struct aos_rpc *aos_rpc_get_process_channel(void)
|
||||||
{
|
{
|
||||||
//TODO: Return channel to talk to process server process (or whoever
|
// Return channel to talk to process server process (or whoever
|
||||||
//implements process server functionality)
|
// implements process server functionality)
|
||||||
debug_printf("aos_rpc_get_process_channel NYI\n");
|
return get_init_rpc();
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -125,9 +219,7 @@ struct aos_rpc *aos_rpc_get_process_channel(void)
|
|||||||
*/
|
*/
|
||||||
struct aos_rpc *aos_rpc_get_serial_channel(void)
|
struct aos_rpc *aos_rpc_get_serial_channel(void)
|
||||||
{
|
{
|
||||||
//TODO: Return channel to talk to serial driver/terminal process (whoever
|
// Return channel to talk to serial driver/terminal process (whoever
|
||||||
//implements print/read functionality)
|
// implements print/read functionality)
|
||||||
debug_printf("aos_rpc_get_serial_channel NYI\n");
|
return get_init_rpc();
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -83,7 +83,6 @@ static size_t dummy_terminal_read(char *buf, size_t len)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO rueegges: putting it here for now. Not sure how to do rcp abstraction yet
|
|
||||||
static int event_init_dispatch_thread(void *arg)
|
static int event_init_dispatch_thread(void *arg)
|
||||||
{
|
{
|
||||||
errval_t err;
|
errval_t err;
|
||||||
@ -95,8 +94,6 @@ static int event_init_dispatch_thread(void *arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO rueegges: putting it here for now. Not sure how to do rcp abstraction yet
|
|
||||||
// receive messages sent by the init
|
|
||||||
static void handle_init_recv(void *arg)
|
static void handle_init_recv(void *arg)
|
||||||
{
|
{
|
||||||
errval_t err;
|
errval_t err;
|
||||||
@ -106,31 +103,13 @@ static void handle_init_recv(void *arg)
|
|||||||
struct capref cap;
|
struct capref cap;
|
||||||
|
|
||||||
err = lmp_chan_recv(init_chan, &msg, &cap);
|
err = lmp_chan_recv(init_chan, &msg, &cap);
|
||||||
if (err_is_fail(err)) {
|
assert(err_is_ok(err));
|
||||||
if (lmp_err_is_transient(err)) {
|
|
||||||
err = lmp_endpoint_register(init_chan->endpoint, get_default_waitset(), MKCLOSURE(handle_init_recv, init_chan));
|
|
||||||
if (err_is_fail(err)) {
|
|
||||||
USER_PANIC_ERR(err, "Could not reregister after failed init_chan cap receive");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
USER_PANIC_ERR(err, "Failure in child channel");
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(msg.words[0]){
|
if (msg.words[0] == SYS_ERR_OK) {
|
||||||
case RPC_MTYPE_CHILD_ENDPOINT_OK:
|
debug_printf("Received child init OK\n");
|
||||||
debug_printf("Received child init OK\n");
|
init_chan_initialized = true;
|
||||||
init_chan_initialized = true;
|
} else {
|
||||||
break;
|
USER_PANIC("Child LMP initialization failed.");
|
||||||
default:
|
|
||||||
USER_PANIC("Unknown rpc message type.");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = lmp_endpoint_register(init_chan->endpoint, get_default_waitset(), MKCLOSURE(handle_init_recv, init_chan));
|
|
||||||
if (err_is_fail(err)) {
|
|
||||||
USER_PANIC_ERR(err, "[handle_init_recv]: Could not register endpoint after receiving message");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,6 +186,7 @@ errval_t barrelfish_init_onthread(struct spawn_domain_params *params)
|
|||||||
// TODO MILESTONE 3: register ourselves with init
|
// TODO MILESTONE 3: register ourselves with init
|
||||||
/* allocate lmp channel structure */
|
/* allocate lmp channel structure */
|
||||||
struct lmp_chan *init_chan = malloc(sizeof(struct lmp_chan));
|
struct lmp_chan *init_chan = malloc(sizeof(struct lmp_chan));
|
||||||
|
lmp_chan_init(init_chan);
|
||||||
/* create local endpoint */
|
/* create local endpoint */
|
||||||
err = endpoint_create(DEFAULT_LMP_BUF_WORDS, &init_chan->local_cap, &init_chan->endpoint);
|
err = endpoint_create(DEFAULT_LMP_BUF_WORDS, &init_chan->local_cap, &init_chan->endpoint);
|
||||||
if (err_is_fail(err)) {
|
if (err_is_fail(err)) {
|
||||||
@ -232,7 +212,7 @@ errval_t barrelfish_init_onthread(struct spawn_domain_params *params)
|
|||||||
}
|
}
|
||||||
/* initialize init RPC client with lmp channel */
|
/* initialize init RPC client with lmp channel */
|
||||||
struct aos_rpc *init_rpc = malloc(sizeof(struct aos_rpc));
|
struct aos_rpc *init_rpc = malloc(sizeof(struct aos_rpc));
|
||||||
err = aos_rpc_init(init_rpc);
|
err = aos_rpc_init(init_rpc, init_chan, params->rpc_shared_memory);
|
||||||
if (err_is_fail(err)){
|
if (err_is_fail(err)){
|
||||||
return err_push(err, ERR_NOTIMP);
|
return err_push(err, ERR_NOTIMP);
|
||||||
}
|
}
|
||||||
@ -261,7 +241,7 @@ errval_t barrelfish_init_onthread(struct spawn_domain_params *params)
|
|||||||
void barrelfish_init_disabled(dispatcher_handle_t handle, bool init_dom_arg);
|
void barrelfish_init_disabled(dispatcher_handle_t handle, bool init_dom_arg);
|
||||||
void barrelfish_init_disabled(dispatcher_handle_t handle, bool init_dom_arg)
|
void barrelfish_init_disabled(dispatcher_handle_t handle, bool init_dom_arg)
|
||||||
{
|
{
|
||||||
; init_domain = init_dom_arg;
|
init_domain = init_dom_arg;
|
||||||
disp_init_disabled(handle);
|
disp_init_disabled(handle);
|
||||||
thread_init_disabled(handle, init_dom_arg);
|
thread_init_disabled(handle, init_dom_arg);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,34 +6,42 @@
|
|||||||
#include <grading.h>
|
#include <grading.h>
|
||||||
|
|
||||||
|
|
||||||
void grading_rpc_handle_number(uintptr_t val)
|
void grading_rpc_handle_number(uintptr_t val)
|
||||||
{
|
{
|
||||||
|
debug_printf("grading_rpc_handle_number(%"PRIuPTR")\n", val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void grading_rpc_handler_string(const char* string)
|
void grading_rpc_handler_string(const char* string)
|
||||||
{
|
{
|
||||||
|
debug_printf("grading_rpc_handler_string(\"%s\")\n", string);
|
||||||
}
|
}
|
||||||
|
|
||||||
void grading_rpc_handler_serial_getchar(void)
|
void grading_rpc_handler_serial_getchar(void)
|
||||||
{
|
{
|
||||||
|
debug_printf("grading_rpc_handler_serial_getchar()\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void grading_rpc_handler_serial_putchar(char c)
|
void grading_rpc_handler_serial_putchar(char c)
|
||||||
{
|
{
|
||||||
|
debug_printf("grading_rpc_handler_serial_putchar(0x%"PRIx8")\n", c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void grading_rpc_handler_ram_cap(size_t bytes, size_t alignment)
|
void grading_rpc_handler_ram_cap(size_t bytes, size_t alignment)
|
||||||
{
|
{
|
||||||
|
debug_printf("grading_rpc_handler_ram_cap(0x%"PRIxPTR", 0x%"PRIxPTR")\n", bytes, alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
void grading_rpc_handler_process_spawn(char* cmdline, coreid_t core)
|
void grading_rpc_handler_process_spawn(char* cmdline, coreid_t core)
|
||||||
{
|
{
|
||||||
|
debug_printf("grading_rpc_handler_process_spawn(\"%s\", %"PRIuCOREID")\n", cmdline, core);
|
||||||
}
|
}
|
||||||
|
|
||||||
void grading_rpc_handler_process_get_name(domainid_t pid)
|
void grading_rpc_handler_process_get_name(domainid_t pid)
|
||||||
{
|
{
|
||||||
|
debug_printf("grading_rpc_handler_process_get_name(%"PRIuDOMAINID")\n", pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void grading_rpc_handler_process_get_all_pids(void)
|
void grading_rpc_handler_process_get_all_pids(void)
|
||||||
{
|
{
|
||||||
|
debug_printf("grading_rpc_handler_process_get_all_pids()\n");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
#include <spawn/spawn.h>
|
#include <spawn/spawn.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#define PROCESS_COUNT 5
|
#define PROCESS_COUNT 1
|
||||||
|
|
||||||
void do_test_spawn(void) {
|
void do_test_spawn(void) {
|
||||||
// spawn multiple processes
|
// spawn multiple processes
|
||||||
|
|||||||
@ -7,13 +7,13 @@
|
|||||||
-- ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
|
-- ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
|
||||||
--
|
--
|
||||||
-- Hakefile for lib/spawn
|
-- Hakefile for lib/spawn
|
||||||
--
|
--
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
[
|
[
|
||||||
build library {
|
build library {
|
||||||
target = "spawn",
|
target = "spawn",
|
||||||
cFiles = [ "spawn.c" ],
|
cFiles = [ "spawn.c", "rpc_server.c" ],
|
||||||
addLibraries = [ "elf", "argv", "multiboot" ]
|
addLibraries = [ "elf", "argv", "multiboot" ]
|
||||||
},
|
},
|
||||||
build library {
|
build library {
|
||||||
|
|||||||
219
lib/spawn/rpc_server.c
Normal file
219
lib/spawn/rpc_server.c
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
#include <aos/aos.h>
|
||||||
|
#include <aos/aos_rpc.h>
|
||||||
|
#include <spawn/rpc_server.h>
|
||||||
|
#include <grading.h>
|
||||||
|
|
||||||
|
typedef errval_t (*rpc_handler_t)(
|
||||||
|
struct aos_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
|
||||||
|
);
|
||||||
|
|
||||||
|
static rpc_handler_t rpc_handlers[RPC_MTYPE_COUNT];
|
||||||
|
|
||||||
|
static void rpc_server_handle_recv(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) {
|
||||||
|
rpc->chan = chan;
|
||||||
|
rpc->shared_mem = shared_mem;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rpc_server_register_recv(struct aos_rpc_server *rpc) {
|
||||||
|
errval_t err = lmp_chan_register_recv(rpc->chan, get_default_waitset(), MKCLOSURE(rpc_server_handle_recv, rpc));
|
||||||
|
if (err_is_fail(err)) {
|
||||||
|
DEBUG_ERR(err, "Could not register receive handler");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rpc_server_handle_recv(void *arg) {
|
||||||
|
errval_t err;
|
||||||
|
struct aos_rpc_server *rpc = (struct aos_rpc_server *)arg;
|
||||||
|
|
||||||
|
struct lmp_recv_msg msg = LMP_RECV_MSG_INIT;
|
||||||
|
struct capref arg_cap;
|
||||||
|
|
||||||
|
err = lmp_chan_recv(rpc->chan, &msg, &arg_cap);
|
||||||
|
assert(err_is_ok(err));
|
||||||
|
|
||||||
|
rpc->ret_cap = NULL_CAP;
|
||||||
|
rpc->ret_size = 0;
|
||||||
|
rpc->ret0 = 0;
|
||||||
|
rpc->ret1 = 0;
|
||||||
|
if (msg.words[0] >= RPC_MTYPE_COUNT) {
|
||||||
|
err = AOS_ERR_RPC_UNKNOWN_MSG_TYPE;
|
||||||
|
} else if (msg.words[1] > RPC_SHARED_SIZE) {
|
||||||
|
err = AOS_ERR_RPC_ARG_TOO_BIG;
|
||||||
|
} else {
|
||||||
|
rpc_handler_t handler = rpc_handlers[msg.words[0]];
|
||||||
|
if (handler == NULL) {
|
||||||
|
err = AOS_ERR_RPC_UNKNOWN_MSG_TYPE;
|
||||||
|
} else {
|
||||||
|
err = handler(
|
||||||
|
rpc,
|
||||||
|
arg_cap, msg.words[1], msg.words[2], msg.words[3],
|
||||||
|
&rpc->ret_cap, &rpc->ret_size, &rpc->ret0, &rpc->ret1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rpc->ret_err = err;
|
||||||
|
|
||||||
|
rpc_server_send_reply(rpc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rpc_server_send_reply(void *arg) {
|
||||||
|
struct aos_rpc_server *rpc = (struct aos_rpc_server *)arg;
|
||||||
|
errval_t err;
|
||||||
|
|
||||||
|
err = lmp_chan_send4(
|
||||||
|
rpc->chan, LMP_FLAG_YIELD | LMP_FLAG_SYNC,
|
||||||
|
rpc->ret_cap, rpc->ret_err, rpc->ret_size, rpc->ret0, rpc->ret1
|
||||||
|
);
|
||||||
|
if (err_is_fail(err)) {
|
||||||
|
if (!lmp_err_is_transient(err)) {
|
||||||
|
DEBUG_ERR(err, "Could not send RPC reply");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Cannot send right now, try again later
|
||||||
|
err = lmp_chan_register_send(rpc->chan, &rpc->ws, MKCLOSURE(rpc_server_send_reply, arg));
|
||||||
|
if (err_is_fail(err)) {
|
||||||
|
DEBUG_ERR(err, "Could not register send handler");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sent reply, wait for next RPC call
|
||||||
|
rpc_server_register_recv(rpc);
|
||||||
|
}
|
||||||
|
|
||||||
|
// RPC handlers
|
||||||
|
|
||||||
|
static errval_t handle_rpc_send_number(
|
||||||
|
struct aos_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
|
||||||
|
) {
|
||||||
|
uintptr_t num = arg0;
|
||||||
|
|
||||||
|
grading_rpc_handle_number(num);
|
||||||
|
|
||||||
|
return SYS_ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static errval_t handle_rpc_send_string(
|
||||||
|
struct aos_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
|
||||||
|
) {
|
||||||
|
const char* string = rpc->shared_mem;
|
||||||
|
if (arg_size == 0 || string[arg_size - 1] != '\0') {
|
||||||
|
return ERR_INVALID_ARGS;
|
||||||
|
}
|
||||||
|
|
||||||
|
grading_rpc_handler_string(string);
|
||||||
|
|
||||||
|
return SYS_ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static errval_t handle_rpc_get_ram_cap(
|
||||||
|
struct aos_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
|
||||||
|
) {
|
||||||
|
size_t bytes = arg0;
|
||||||
|
size_t alignment = arg1;
|
||||||
|
|
||||||
|
grading_rpc_handler_ram_cap(bytes, alignment);
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
*ret0 = bytes;
|
||||||
|
|
||||||
|
return LIB_ERR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static errval_t handle_rpc_serial_getchar(
|
||||||
|
struct aos_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
|
||||||
|
) {
|
||||||
|
|
||||||
|
grading_rpc_handler_serial_getchar();
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
*ret0 = 'A';
|
||||||
|
|
||||||
|
return LIB_ERR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static errval_t handle_rpc_serial_putchar(
|
||||||
|
struct aos_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
|
||||||
|
) {
|
||||||
|
char c = arg0;
|
||||||
|
|
||||||
|
grading_rpc_handler_serial_putchar(c);
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
|
||||||
|
return LIB_ERR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static errval_t handle_rpc_process_spawn(
|
||||||
|
struct aos_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
|
||||||
|
) {
|
||||||
|
char *cmdline = rpc->shared_mem;
|
||||||
|
coreid_t core = arg0;
|
||||||
|
if (arg_size == 0 || cmdline[arg_size - 1] != '\0') {
|
||||||
|
return ERR_INVALID_ARGS;
|
||||||
|
}
|
||||||
|
|
||||||
|
grading_rpc_handler_process_spawn(cmdline, core);
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
*ret0 = 0;
|
||||||
|
|
||||||
|
return LIB_ERR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static errval_t handle_rpc_process_get_name(
|
||||||
|
struct aos_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
|
||||||
|
) {
|
||||||
|
domainid_t pid = arg0;
|
||||||
|
|
||||||
|
grading_rpc_handler_process_get_name(pid);
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
memcpy(rpc->shared_mem, "name", 5);
|
||||||
|
*ret_size = 5;
|
||||||
|
|
||||||
|
return LIB_ERR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static errval_t handle_rpc_process_get_all_pids(
|
||||||
|
struct aos_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
|
||||||
|
) {
|
||||||
|
grading_rpc_handler_process_get_all_pids();
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
|
||||||
|
return LIB_ERR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static rpc_handler_t rpc_handlers[RPC_MTYPE_COUNT] = {
|
||||||
|
[RPC_MTYPE_SEND_NUMBER] = handle_rpc_send_number,
|
||||||
|
[RPC_MTYPE_SEND_STRING] = handle_rpc_send_string,
|
||||||
|
[RPC_MTYPE_GET_RAM_CAP] = handle_rpc_get_ram_cap,
|
||||||
|
[RPC_MTYPE_SERIAL_GETCHAR] = handle_rpc_serial_getchar,
|
||||||
|
[RPC_MTYPE_SERIAL_PUTCHAR] = handle_rpc_serial_putchar,
|
||||||
|
[RPC_MTYPE_PROCESS_SPAWN] = handle_rpc_process_spawn,
|
||||||
|
[RPC_MTYPE_PROCESS_GET_NAME] = handle_rpc_process_get_name,
|
||||||
|
[RPC_MTYPE_PROCESS_GET_ALL_PIDS] = handle_rpc_process_get_all_pids,
|
||||||
|
};
|
||||||
@ -47,46 +47,23 @@ static void armv8_set_registers(void *arch_load_info,
|
|||||||
disabled_area->regs[REG_OFFSET(PIC_REGISTER)] = got_base;
|
disabled_area->regs[REG_OFFSET(PIC_REGISTER)] = got_base;
|
||||||
}
|
}
|
||||||
|
|
||||||
// receive messages sent by the child
|
|
||||||
static void handle_child_recv(void *arg) {
|
static void handle_child_recv(void *arg) {
|
||||||
errval_t err;
|
errval_t err;
|
||||||
struct lmp_chan *init_chan = (struct lmp_chan *)arg;
|
struct spawninfo *si = (struct spawninfo *)arg;
|
||||||
|
|
||||||
struct lmp_recv_msg msg = LMP_RECV_MSG_INIT;
|
struct lmp_recv_msg msg = LMP_RECV_MSG_INIT;
|
||||||
struct capref cap;
|
struct capref cap;
|
||||||
|
|
||||||
err = lmp_chan_recv(init_chan, &msg, &cap);
|
err = lmp_chan_recv(&si->init_chan, &msg, &cap);
|
||||||
if (err_is_fail(err)) {
|
assert(err_is_ok(err));
|
||||||
if (lmp_err_is_transient(err)) {
|
|
||||||
err = lmp_endpoint_register(init_chan->endpoint, get_default_waitset(), MKCLOSURE(handle_child_recv, init_chan));
|
|
||||||
if (err_is_fail(err)) {
|
|
||||||
USER_PANIC_ERR(err, "Could not reregister after failed init_chan cap receive");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
USER_PANIC_ERR(err, "Failure in child channel");
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(msg.words[0]){
|
switch(msg.words[0]){
|
||||||
case RPC_MTYPE_CHILD_ENDPOINT:
|
case RPC_MTYPE_CHILD_ENDPOINT:
|
||||||
debug_printf("SPAWN: Received child init_chan endpoint\n");
|
debug_printf("SPAWN: Received child init_chan endpoint\n");
|
||||||
init_chan->remote_cap = cap;
|
si->init_chan.remote_cap = cap;
|
||||||
err = lmp_chan_send1(init_chan, LMP_FLAG_YIELD | LMP_FLAG_SYNC, NULL_CAP, RPC_MTYPE_CHILD_ENDPOINT_OK);
|
err = lmp_chan_send1(&si->init_chan, LMP_FLAG_YIELD | LMP_FLAG_SYNC, NULL_CAP, SYS_ERR_OK);
|
||||||
if (err_is_fail(err)) {
|
if (err_is_fail(err)) {
|
||||||
USER_PANIC_ERR(err, "Failed to send RPC_MTYPE_CHILD_ENDPOINT_OK");
|
USER_PANIC_ERR(err, "Failed to send reply");
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RPC_MTYPE_GET_RAM_CAP:
|
|
||||||
debug_printf("[handle_init_recv]: RPC_MTYPE_GET_RAM_CAP\n");
|
|
||||||
|
|
||||||
size_t requested_size = msg.words[1];
|
|
||||||
struct capref new_ram_cap;
|
|
||||||
frame_alloc(&new_ram_cap, requested_size, NULL);
|
|
||||||
|
|
||||||
err = lmp_chan_send1(init_chan, LMP_FLAG_YIELD | LMP_FLAG_SYNC, NULL_CAP, RPC_MTYPE_GET_RAM_CAP_OK);
|
|
||||||
if (err_is_fail(err)) {
|
|
||||||
USER_PANIC_ERR(err, "Failed to send RPC_MTYPE_GET_RAM_CAP_OK");
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -94,10 +71,7 @@ static void handle_child_recv(void *arg) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = lmp_endpoint_register(init_chan->endpoint, get_default_waitset(), MKCLOSURE(handle_child_recv, init_chan));
|
rpc_server_register_recv(&si->rpc_server);
|
||||||
if (err_is_fail(err)) {
|
|
||||||
USER_PANIC_ERR(err, "Could not reregister after failed init_chan cap receive");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct temp_mapping {
|
struct temp_mapping {
|
||||||
@ -594,6 +568,22 @@ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si,
|
|||||||
return err_push(err, SPAWN_ERR_SERIALISE_VSPACE);
|
return err_push(err, SPAWN_ERR_SERIALISE_VSPACE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create shared memory for RPC
|
||||||
|
err = frame_alloc(&si->rpc_shared_frame, RPC_SHARED_SIZE, NULL);
|
||||||
|
if (err_is_fail(err)) return err_push(err, LIB_ERR_FRAME_ALLOC);
|
||||||
|
|
||||||
|
void *rpc_shared_memory;
|
||||||
|
err = paging_map_frame_attr(
|
||||||
|
get_current_paging_state(), &rpc_shared_memory,
|
||||||
|
RPC_SHARED_SIZE, si->rpc_shared_frame, VREGION_FLAGS_READ_WRITE);
|
||||||
|
if (err_is_fail(err)) return err;
|
||||||
|
|
||||||
|
err = paging_map_frame_attr(
|
||||||
|
&child_paging_state, &domain_params->rpc_shared_memory,
|
||||||
|
RPC_SHARED_SIZE, si->rpc_shared_frame, VREGION_FLAGS_READ_WRITE);
|
||||||
|
if (err_is_fail(err)) return err;
|
||||||
|
|
||||||
|
|
||||||
// afeer: TODO: what do i put here? do we need to set these fields to some value?
|
// afeer: TODO: what do i put here? do we need to set these fields to some value?
|
||||||
// domain_params->tls_init_base = NULL;
|
// domain_params->tls_init_base = NULL;
|
||||||
// domain_params->tls_init_len = 0;
|
// domain_params->tls_init_len = 0;
|
||||||
@ -624,9 +614,11 @@ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si,
|
|||||||
err = paging_unmap(get_current_paging_state(), arguments_page_in_self);
|
err = paging_unmap(get_current_paging_state(), arguments_page_in_self);
|
||||||
if (err_is_fail(err)) return err_push(err, LIB_ERR_PMAP_UNMAP);
|
if (err_is_fail(err)) return err_push(err, LIB_ERR_PMAP_UNMAP);
|
||||||
|
|
||||||
|
rpc_server_init(&si->rpc_server, &si->init_chan, rpc_shared_memory);
|
||||||
|
|
||||||
// Receive the child's endpoint for the init channel
|
// Receive the child's endpoint for the init channel
|
||||||
lmp_chan_alloc_recv_slot(&si->init_chan);
|
lmp_chan_alloc_recv_slot(&si->init_chan);
|
||||||
err = lmp_endpoint_register(si->init_chan.endpoint, get_default_waitset(), MKCLOSURE(handle_child_recv, &si->init_chan));
|
err = lmp_chan_register_recv(&si->init_chan, get_default_waitset(), MKCLOSURE(handle_child_recv, si));
|
||||||
if (err_is_fail(err)) return err;
|
if (err_is_fail(err)) return err;
|
||||||
|
|
||||||
// - Make the new dispatcher runnable
|
// - Make the new dispatcher runnable
|
||||||
|
|||||||
@ -18,19 +18,28 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <aos/aos.h>
|
#include <aos/aos.h>
|
||||||
|
#include <aos/aos_rpc.h>
|
||||||
#include <aos/deferred.h>
|
#include <aos/deferred.h>
|
||||||
|
|
||||||
#define HELLO_CATCH_COMMAND "catch"
|
#define HELLO_CATCH_COMMAND "catch"
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
errval_t err;
|
||||||
printf("Hello, world!\n");
|
printf("Hello, world!\n");
|
||||||
|
|
||||||
printf("argv:\n");
|
printf("argv:\n");
|
||||||
for(int i = 0; i < argc; ++i) {
|
for(int i = 0; i < argc; ++i) {
|
||||||
printf(" %d -> %s\n", i, argv[i]);
|
printf(" %d -> %s\n", i, argv[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct aos_rpc *rpc = aos_rpc_get_init_channel();
|
||||||
|
err = aos_rpc_send_number(rpc, 1234);
|
||||||
|
if (err_is_fail(err)) USER_PANIC_ERR(err, "Failed to send RPC");
|
||||||
|
|
||||||
|
err = aos_rpc_send_string(rpc, "Hello World via RPC!");
|
||||||
|
if (err_is_fail(err)) USER_PANIC_ERR(err, "Failed to send RPC");
|
||||||
|
|
||||||
// if we receive the catch command, RUN!
|
// if we receive the catch command, RUN!
|
||||||
if (argc > 1 && !strncmp(argv[1], HELLO_CATCH_COMMAND, sizeof(HELLO_CATCH_COMMAND))) {
|
if (argc > 1 && !strncmp(argv[1], HELLO_CATCH_COMMAND, sizeof(HELLO_CATCH_COMMAND))) {
|
||||||
int iter = 0;
|
int iter = 0;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user