1/* 2 * Copyright 2017, Data61 3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 * ABN 41 687 119 230. 5 * 6 * This software may be distributed and modified according to the terms of 7 * the BSD 2-Clause license. Note that NO WARRANTY is provided. 8 * See "LICENSE_BSD2.txt" for details. 9 * 10 * @TAG(DATA61_BSD) 11 */ 12#pragma once 13 14#include <stdint.h> 15 16#include <sel4/sel4.h> 17 18#include <simple/simple.h> 19#include <sel4utils/thread.h> 20#include <vka/vka.h> 21#include <vka/object.h> 22#include <vspace/vspace.h> 23 24/** @file APIs for managing and interacting with the serial server thread. 25 * 26 * Defines the constants for the protocol, messages, and server-side state, as 27 * well as the entry point and back-end routines for the server's API. 28 * 29 * All vka_t, vspace_t and simple_t instances that are supplied to this library 30 * by the developer must persist and be functional for the lifetime of the 31 * server thread. 32 */ 33 34#define SERSERVS "Serserv Server: " 35#define SERSERVC "Serserv Client: " 36#define SERSERVP "Serserv Parent: " 37 38#define SERIAL_SERVER_BADGE_VALUE_EMPTY (0) 39 40#define SERIAL_SERVER_SHMEM_MAX_SIZE (BIT(seL4_PageBits)) 41 42/* IPC values returned in the "label" message header. */ 43enum serial_server_errors { 44 SERIAL_SERVER_NOERROR = 0, 45 /* No future collisions with seL4_Error.*/ 46 SERIAL_SERVER_ERROR_SHMEM_TOO_LARGE = seL4_NumErrors, 47 SERIAL_SERVER_ERROR_SERIAL_BIND_FAILED, 48 SERIAL_SERVER_ERROR_UNKNOWN 49}; 50 51/* IPC Message register values for SSMSGREG_FUNC */ 52enum serial_server_funcs { 53 FUNC_CONNECT_REQ = 0, 54 FUNC_CONNECT_ACK, 55 56 FUNC_SERVER_SPAWN_SYNC_REQ, 57 FUNC_SERVER_SPAWN_SYNC_ACK, 58 59 FUNC_PRINTF_REQ, 60 FUNC_PRINTF_ACK, 61 62 FUNC_WRITE_REQ, 63 FUNC_WRITE_ACK, 64 65 FUNC_DISCONNECT_REQ, 66 FUNC_DISCONNECT_ACK, 67 68 FUNC_KILL_REQ, 69 FUNC_KILL_ACK, 70}; 71 72/* Designated purposes of each message register in the mini-protocol. */ 73enum serial_server_msgregs { 74 /* These four are fixed headers in every serserv message. */ 75 SSMSGREG_FUNC = 0, 76 /* This is a convenience label for IPC MessageInfo length. */ 77 SSMSGREG_LABEL0, 78 79 SSMSGREG_CONNECT_REQ_SHMEM_SIZE = SSMSGREG_LABEL0, 80 SSMSGREG_CONNECT_REQ_END, 81 82 SSMSGREG_CONNECT_ACK_MAX_SHMEM_SIZE = SSMSGREG_LABEL0, 83 SSMSGREG_CONNECT_ACK_END, 84 85 SSMSGREG_SPAWN_SYNC_REQ_END = SSMSGREG_LABEL0, 86 87 SSMSGREG_SPAWN_SYNC_ACK_END = SSMSGREG_LABEL0, 88 89 SSMSGREG_PRINTF_REQ_FMT_STRLEN = SSMSGREG_LABEL0, 90 SSMSGREG_PRINTF_REQ_END, 91 92 SSMSGREG_PRINTF_ACK_PRINTF_RET = SSMSGREG_LABEL0, 93 SSMSGREG_PRINTF_ACK_END, 94 95 SSMSGREG_WRITE_REQ_BUFF_LEN = SSMSGREG_LABEL0, 96 SSMSGREG_WRITE_REQ_END, 97 98 SSMSGREG_WRITE_ACK_N_BYTES_WRITTEN = SSMSGREG_LABEL0, 99 SSMSGREG_WRITE_ACK_END, 100 101 SSMSGREG_DISCONNECT_REQ_END = SSMSGREG_LABEL0, 102 103 SSMSGREG_DISCONNECT_ACK_END = SSMSGREG_LABEL0, 104 105 SSMSGREG_KILL_REQ_END = SSMSGREG_LABEL0, 106 107 SSMSGREG_KILL_ACK_END = SSMSGREG_LABEL0 108}; 109 110/* Per-client context maintained by the server. */ 111typedef struct _serial_server_registry_entry { 112 seL4_Word badge_value; 113 volatile char *shmem; 114 seL4_CPtr *shmem_frame_caps; 115 size_t shmem_size; 116} serial_server_registry_entry_t; 117 118/* State maintained by the server. */ 119typedef struct _serial_server_context { 120 simple_t *server_simple; 121 vka_t *server_vka; 122 seL4_CPtr server_cspace; 123 cspacepath_t *frame_cap_recv_cspaths; 124 vspace_t *server_vspace; 125 sel4utils_thread_t server_thread; 126 vka_object_t server_ep_obj; 127 size_t shmem_max_size, shmem_max_n_pages; 128 129 int registry_n_entries; 130 serial_server_registry_entry_t *registry; 131 132 seL4_Word parent_badge_value; 133 cspacepath_t _badged_server_ep_cspath; 134} serial_server_context_t; 135 136/* Global server instance accessor functions. */ 137serial_server_context_t *get_serial_server(void); 138 139/** Internal library function: acts as the main() for the server thread. 140 */ 141void serial_server_main(void); 142 143serial_server_registry_entry_t *serial_server_registry_get_entry_by_badge(seL4_Word badge_value); 144 145/** Determines whether or not a badge value has been reserved and given out. 146 * @param badge_value The badge value in question. 147 * @return True only if the badge value has been given out. 148 * False if the badge value is invalid, or hasn't been given out. 149 */ 150bool serial_server_badge_is_allocated(seL4_Word badge_value); 151 152/** Returns an unused, unique badge value to the caller, and will NOT attempt 153 * to resize the pool of available badge values to fulfill the request. 154 * 155 * The server maintains a list of badge values, so it can also be used to 156 * allocate and ration out badge values. 157 * 158 * @return Returns a positive integer GREATER THAN 0 if successful. 159 * Returns 0 if unsuccessful. 160 */ 161seL4_Word serial_server_badge_value_get_unused(void); 162 163/** Returns a new, unique badge value to the caller, and WILL allocate new 164 * badge values to satisfy the request. 165 * 166 * @return Returns a positive integer GREATER THAN 0 if successful. 167 * Returns 0 if unsuccessful. 168 */ 169seL4_Word serial_server_badge_value_alloc(void); 170 171/** Returns a badge value to the pool of available badge values. 172 * @param badge_value The badge value to free. 173 */ 174void serial_server_badge_value_free(seL4_Word badge_value); 175