Added arbitrary length terminal write and read with early return

This commit is contained in:
Sparchatus 2022-03-31 13:12:33 +00:00
parent f22a6fa5a0
commit 12ee3bb5b6
4 changed files with 95 additions and 40 deletions

View File

@ -28,6 +28,7 @@ enum rpc_mtype {
RPC_MTYPE_SERIAL_GETCHAR,
RPC_MTYPE_SERIAL_PUTCHAR,
RPC_MTYPE_SERIAL_WRITE,
RPC_MTYPE_SERIAL_READ,
RPC_MTYPE_PROCESS_SPAWN,
RPC_MTYPE_PROCESS_GET_NAME,
RPC_MTYPE_PROCESS_GET_ALL_PIDS,
@ -82,9 +83,16 @@ errval_t aos_rpc_serial_putchar(struct aos_rpc *chan, char c);
/**
* \brief Send a list of characters to the serial port
*/
errval_t aos_rpc_serial_write(struct aos_rpc *chan, const char *buf,
size_t aos_rpc_serial_write(struct aos_rpc *chan, const char *buf,
size_t buf_len);
/**
* \brief Read a list of characters from the serial port
*/
size_t aos_rpc_serial_read(struct aos_rpc *rpc, char *buf,
size_t buf_len);
/**
* \brief Request that the process manager start a new process
* \arg cmdline the name of the process that needs to be spawned (without a

View File

@ -126,34 +126,77 @@ aos_rpc_serial_putchar(struct aos_rpc *rpc, char c) {
);
}
// putchar for terminal printing is too slow so we send buffers instead
errval_t
// putchar for terminal printing is too slow so we write buffers instead
// the corresponding interface does not know about errors, just partial writes
size_t
aos_rpc_serial_write(struct aos_rpc *rpc, const char *buf, size_t buf_len) {
errval_t err;
// split the buffer into chunks for sending
size_t total_bytes = 0;
while(buf_len > 0) {
size_t chunk_len = buf_len;
if (chunk_len > RPC_SHARED_SIZE) {
chunk_len = RPC_SHARED_SIZE;
}
size_t chunk_len = MIN(buf_len, RPC_SHARED_SIZE);
memcpy(rpc->shared_mem, buf, chunk_len);
size_t written_bytes;
err = do_aos_rpc(
rpc, RPC_MTYPE_SERIAL_WRITE,
NULL_CAP, chunk_len, 0, 0,
NULL, NULL, NULL, NULL
NULL, NULL, &written_bytes, NULL
);
if (err_is_fail(err)) {
return err;
return total_bytes;
}
total_bytes += written_bytes;
// if the receiver was not able to write all we have given, return for now
if (written_bytes < chunk_len) {
return total_bytes;
}
buf += chunk_len;
buf_len -= chunk_len;
}
return SYS_ERR_OK;
return total_bytes;
}
// getchar for terminal reading is too slow so we read buffers instead
// the corresponding interface does not know about errors, just partial reads
size_t
aos_rpc_serial_read(struct aos_rpc *rpc, char *buf, size_t buf_len) {
errval_t err;
// split the buffer into chunks for reading
size_t total_bytes = 0;
while(buf_len > 0) {
size_t chunk_len = MIN(buf_len, RPC_SHARED_SIZE);
size_t read_bytes;
err = do_aos_rpc(
rpc, RPC_MTYPE_SERIAL_WRITE,
NULL_CAP, 0, chunk_len, 0,
NULL, NULL, &read_bytes, NULL
);
if (err_is_fail(err)) {
return total_bytes;
}
memcpy(buf, rpc->shared_mem, read_bytes);
total_bytes += read_bytes;
// if the receiver was not able to write all we have given, return for now
if (read_bytes < chunk_len) {
return total_bytes;
}
buf += chunk_len;
buf_len -= chunk_len;
}
return total_bytes;
}
errval_t

View File

@ -83,17 +83,6 @@ static size_t dummy_terminal_read(char *buf, size_t len)
return 0;
}
static int event_init_dispatch_thread(void *arg)
{
errval_t err;
while(true) {
err = event_dispatch(get_default_waitset());
if (err_is_fail(err)) {
USER_PANIC_ERR(err_push(err, LIB_ERR_EVENT_DISPATCH), "Failed to dispatch events");
}
}
}
static void handle_init_recv(void *arg)
{
errval_t err;
@ -115,27 +104,29 @@ static void handle_init_recv(void *arg)
// TODO rueegges: allow partial write
static size_t aos_terminal_write(const char *buf, size_t len)
{
errval_t err;
if(len == 0) return 0;
struct aos_rpc *rpc = aos_rpc_get_serial_channel();
if (rpc == NULL) {
debug_printf("Attempted to printf before initializing rpc: %.*s\n", len, buf);
USER_PANIC("Make sure to initialize rpc before function barrelfish_libc_glue_init is called.");
return len;
debug_printf("[aos_terminal_write] RPC NOT YET INITIALIZED: %.*s\n", len, buf);
USER_PANIC("Make sure to initialize aos_rpc before barrelfish_libc_glue_init is called.");
}
err = aos_rpc_serial_write(rpc, buf, len);
assert(err_is_ok(err));
return len;
return aos_rpc_serial_write(rpc, buf, len);
}
// TODO rueegges: make more efficient?
static size_t aos_terminal_read(char *buf, size_t len)
{
errval_t err;
if(len == 0) return 0;
struct aos_rpc *rpc = aos_rpc_get_serial_channel();
err = aos_rpc_serial_getchar(rpc, buf);
assert(err_is_ok(err));
return 1;
if (rpc == NULL) {
debug_printf("[aos_terminal_read] RPC NOT YET INITIALIZED: %.*s\n", len, buf);
USER_PANIC("Make sure to initialize aos_rpc before barrelfish_libc_glue_init is called.");
}
return aos_rpc_serial_read(rpc, buf, len);
}
/* Set libc function pointers */
@ -250,9 +241,6 @@ errval_t barrelfish_init_onthread(struct spawn_domain_params *params)
/* set init RPC client in our program state */
set_init_rpc(init_rpc);
// create thread to dispatch events
thread_create(event_init_dispatch_thread, NULL);
/* TODO MILESTONE 3: now we should have a channel with init set up and can
* use it for the ram allocator */

View File

@ -166,15 +166,30 @@ static errval_t handle_rpc_serial_write(
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
) {
if (arg_size == 0 ) {
return ERR_INVALID_ARGS;
}
// MARKER SHELL: Replace with UART call
for (size_t i = 0; i < arg_size; ++i){
putchar(((char *)rpc->shared_mem)[i]);
}
// return the number of characters written. Important for UART for early return when the buffer is full
*ret0 = arg_size;
return SYS_ERR_OK;
}
static errval_t handle_rpc_serial_read(
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
) {
// MARKER SHELL: Replace with UART call
for (size_t i = 0; i < arg_size; ++i){
((char *)rpc->shared_mem)[i] = getchar();
}
// return the number of characters read. Important for UART for early return when the buffer is empty
*ret0 = arg_size;
return SYS_ERR_OK;
}
@ -268,6 +283,7 @@ static rpc_handler_t rpc_handlers[RPC_MTYPE_COUNT] = {
[RPC_MTYPE_SERIAL_GETCHAR] = handle_rpc_serial_getchar,
[RPC_MTYPE_SERIAL_PUTCHAR] = handle_rpc_serial_putchar,
[RPC_MTYPE_SERIAL_WRITE] = handle_rpc_serial_write,
[RPC_MTYPE_SERIAL_READ] = handle_rpc_serial_read,
[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,