blob: 93ecb2bbb43d95261f7050613f3a7a6a2ab3eec5 [file] [log] [blame]
/*
* Copyright 2017, Data61
* Commonwealth Scientific and Industrial Research Organisation (CSIRO)
* ABN 41 687 119 230.
*
* This software may be distributed and modified according to the terms of
* the BSD 2-Clause license. Note that NO WARRANTY is provided.
* See "LICENSE_BSD2.txt" for details.
*
* @TAG(DATA61_BSD)
*/
#pragma once
#include <stdint.h>
#include <sel4/sel4.h>
#include <simple/simple.h>
#include <sel4utils/thread.h>
#include <vka/vka.h>
#include <vka/object.h>
#include <vspace/vspace.h>
/** @file APIs for managing and interacting with the serial server thread.
*
* Defines the constants for the protocol, messages, and server-side state, as
* well as the entry point and back-end routines for the server's API.
*
* All vka_t, vspace_t and simple_t instances that are supplied to this library
* by the developer must persist and be functional for the lifetime of the
* server thread.
*/
#define SERSERVS "Serserv Server: "
#define SERSERVC "Serserv Client: "
#define SERSERVP "Serserv Parent: "
#define SERIAL_SERVER_BADGE_VALUE_EMPTY (0)
#define SERIAL_SERVER_SHMEM_MAX_SIZE (BIT(seL4_PageBits))
/* IPC values returned in the "label" message header. */
enum serial_server_errors {
SERIAL_SERVER_NOERROR = 0,
/* No future collisions with seL4_Error.*/
SERIAL_SERVER_ERROR_SHMEM_TOO_LARGE = seL4_NumErrors,
SERIAL_SERVER_ERROR_SERIAL_BIND_FAILED,
SERIAL_SERVER_ERROR_UNKNOWN
};
/* IPC Message register values for SSMSGREG_FUNC */
enum serial_server_funcs {
FUNC_CONNECT_REQ = 0,
FUNC_CONNECT_ACK,
FUNC_SERVER_SPAWN_SYNC_REQ,
FUNC_SERVER_SPAWN_SYNC_ACK,
FUNC_PRINTF_REQ,
FUNC_PRINTF_ACK,
FUNC_WRITE_REQ,
FUNC_WRITE_ACK,
FUNC_DISCONNECT_REQ,
FUNC_DISCONNECT_ACK,
FUNC_KILL_REQ,
FUNC_KILL_ACK,
};
/* Designated purposes of each message register in the mini-protocol. */
enum serial_server_msgregs {
/* These four are fixed headers in every serserv message. */
SSMSGREG_FUNC = 0,
/* This is a convenience label for IPC MessageInfo length. */
SSMSGREG_LABEL0,
SSMSGREG_CONNECT_REQ_SHMEM_SIZE = SSMSGREG_LABEL0,
SSMSGREG_CONNECT_REQ_END,
SSMSGREG_CONNECT_ACK_MAX_SHMEM_SIZE = SSMSGREG_LABEL0,
SSMSGREG_CONNECT_ACK_END,
SSMSGREG_SPAWN_SYNC_REQ_END = SSMSGREG_LABEL0,
SSMSGREG_SPAWN_SYNC_ACK_END = SSMSGREG_LABEL0,
SSMSGREG_PRINTF_REQ_FMT_STRLEN = SSMSGREG_LABEL0,
SSMSGREG_PRINTF_REQ_END,
SSMSGREG_PRINTF_ACK_PRINTF_RET = SSMSGREG_LABEL0,
SSMSGREG_PRINTF_ACK_END,
SSMSGREG_WRITE_REQ_BUFF_LEN = SSMSGREG_LABEL0,
SSMSGREG_WRITE_REQ_END,
SSMSGREG_WRITE_ACK_N_BYTES_WRITTEN = SSMSGREG_LABEL0,
SSMSGREG_WRITE_ACK_END,
SSMSGREG_DISCONNECT_REQ_END = SSMSGREG_LABEL0,
SSMSGREG_DISCONNECT_ACK_END = SSMSGREG_LABEL0,
SSMSGREG_KILL_REQ_END = SSMSGREG_LABEL0,
SSMSGREG_KILL_ACK_END = SSMSGREG_LABEL0
};
/* Per-client context maintained by the server. */
typedef struct _serial_server_registry_entry {
seL4_Word badge_value;
volatile char *shmem;
seL4_CPtr *shmem_frame_caps;
size_t shmem_size;
} serial_server_registry_entry_t;
/* State maintained by the server. */
typedef struct _serial_server_context {
simple_t *server_simple;
vka_t *server_vka;
seL4_CPtr server_cspace;
cspacepath_t *frame_cap_recv_cspaths;
vspace_t *server_vspace;
sel4utils_thread_t server_thread;
vka_object_t server_ep_obj;
size_t shmem_max_size, shmem_max_n_pages;
int registry_n_entries;
serial_server_registry_entry_t *registry;
seL4_Word parent_badge_value;
cspacepath_t _badged_server_ep_cspath;
} serial_server_context_t;
/* Global server instance accessor functions. */
serial_server_context_t *get_serial_server(void);
/** Internal library function: acts as the main() for the server thread.
*/
void serial_server_main(void);
serial_server_registry_entry_t *serial_server_registry_get_entry_by_badge(seL4_Word badge_value);
/** Determines whether or not a badge value has been reserved and given out.
* @param badge_value The badge value in question.
* @return True only if the badge value has been given out.
* False if the badge value is invalid, or hasn't been given out.
*/
bool serial_server_badge_is_allocated(seL4_Word badge_value);
/** Returns an unused, unique badge value to the caller, and will NOT attempt
* to resize the pool of available badge values to fulfill the request.
*
* The server maintains a list of badge values, so it can also be used to
* allocate and ration out badge values.
*
* @return Returns a positive integer GREATER THAN 0 if successful.
* Returns 0 if unsuccessful.
*/
seL4_Word serial_server_badge_value_get_unused(void);
/** Returns a new, unique badge value to the caller, and WILL allocate new
* badge values to satisfy the request.
*
* @return Returns a positive integer GREATER THAN 0 if successful.
* Returns 0 if unsuccessful.
*/
seL4_Word serial_server_badge_value_alloc(void);
/** Returns a badge value to the pool of available badge values.
* @param badge_value The badge value to free.
*/
void serial_server_badge_value_free(seL4_Word badge_value);