| /* | |
| * 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); |