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 <sys/types.h> 15#include <stdint.h> 16 17#include <sel4/sel4.h> 18 19#include <simple/simple.h> 20#include <sel4utils/thread.h> 21#include <vka/vka.h> 22#include <vka/object.h> 23#include <vspace/vspace.h> 24 25/** @file API for making requests to a serial server multiplexing thread. 26 * 27 * If CONFIG_SERIAL_SERVER_COLOURED_OUTPUT is set, the output will also 28 * be wrapped in ansi escape codes which allow client code to be identified 29 * in a terminal. 30 * 31 * By default, the new thread which is created by this API will share the 32 * CSpace and VSpace of its creator. Each client of the server thread is required 33 * to have a badged cap to the Endpoint that the Server is listening on. The 34 * badge on this Endpoint cap must have been allocated by the library's 35 * serial_server_badge_value_alloc() or serial_server_badge_value_get_unused() 36 * function. 37 * 38 * Establishing a connection to the server is as simple as calling: 39 * serial_client_context_t conn; 40 * error = serial_server_client_connect(..., &conn). 41 * Then check the error value returned: 42 * if (error != SERIAL_SERVER_NOERROR) { ... } 43 * 44 * If the connect() call was successful, make sure you save the 45 * serial_client_context_t object. Then use the serial server's printf from 46 * that point on, by passing the serial_client_context_t object: 47 * serial_server_printf(&conn, "Hello world from %s!", "john"); 48 * 49 * You can easily abstract away the long function name using preprocessor 50 * defines or wrapper functions such as: 51 * #define printf(fmt, ...) serial_server_printf(&global_client_conn, ## __VA_ARGS__) 52 * 53 * CAUTION: 54 * All vka_t, vpsace_t, and simple_t instances passed to this library by 55 * reference must remain functional throughout the lifetime of the server. 56 */ 57 58/* Context given to each client to preserve state. 59 * 60 * This is an opaque handle data type, and clients are not to assume the 61 * layout or purpose of its members. 62 */ 63typedef struct _serial_client_context { 64 seL4_Word badge_value; 65 cspacepath_t badged_server_ep_cspath; 66 volatile char *shmem; 67 size_t shmem_size; 68} serial_client_context_t; 69 70/** Establishes a connection to the server thread and returns a connection 71 * handle. It is expected that this will be called by the client thread itself. 72 * 73 * CAUTION: 74 * All vka_t, vpsace_t, and simple_t instances passed to this library by 75 * reference must remain functional throughout the lifetime of the server. 76 * 77 * Can be called by any thread which has an endpoint to the thread/process 78 * that spawned the server thread. 79 * @param server_ep_cap CPtr to an endpoint between the client and the SERVER 80 * thread. 81 * @param client_vka Initialized vka_t for the client thread. 82 * @param client_vspace Initialized vspace_t for the client thread. 83 * @param client_badge_value Unique badge value for the connection between this 84 * client and the server thread. Each client of the 85 * server must have a unique badge value. Two clients 86 * connecting with the same badge value will cause the 87 * server to overwrite the former with the latter. 88 * @param conn [out] Connection token returned by the library. Use this to make calls 89 * to the server thread. 90 * @return Error value: 0 on success, non-zero on failure. 91 */ 92int serial_server_client_connect(seL4_CPtr server_ep_cap, 93 vka_t *client_vka, 94 vspace_t *client_vspace, 95 serial_client_context_t *conn); 96 97/** Sends a request to the server to print a message to the serial. 98 * 99 * @param ctxt Valid connection token returned by serial_server_client_connect(). 100 * @param fmt Valid printf format specifier string. 101 * @param ... Variadic argument list for printf. 102 * @return The number of characters printed. If the call had to be aborted due 103 * to an error condition, a negative error code is returned. 104 */ 105ssize_t serial_server_printf(serial_client_context_t *ctxt, const char *fmt, ...); 106 107 108/** Sends the server a request to print the current contents of the shared memory buffer. 109 * For use when the client uses the shared memory buffer directly. 110 * 111 * @param ctxt Valid connection token returned by serial_server_client_connect(). 112 * @param len the size of the buffer data. 113 * @return The number of bytes written (positive integer), or a negative integer 114 * for error condition. 115 * 116 */ 117ssize_t serial_server_flush(serial_client_context_t *ctxt, ssize_t len); 118 119/** Sends a request to the server to write a fixed-length buffer to the serial. 120 * 121 * @param ctxt Valid connection token returned by serial_server_client_connect(). 122 * @param in_buff Input buffer of data. 123 * @param len the size of the buffer data. 124 * @return The number of bytes written (positive integer), or a negative integer 125 * for error condition. 126 */ 127ssize_t serial_server_write(serial_client_context_t *ctxt, const char *in_buff, ssize_t len); 128 129/** Sends a request to the server to disconnect the calling client. 130 * 131 * Causes the server to release the connection metadata it holds about the 132 * client in question and teardown the shared memory mapping between the server 133 * and that client. 134 * @param ctxt Initialized connection token returned from 135 * serial_server_client_connect(). 136 */ 137void serial_server_disconnect(serial_client_context_t *ctxt); 138 139/** Sends a request to the server to "kill" itself. 140 * 141 * In practice, right now that means that the server exits its message loop and 142 * stops listening for IPC from clients, and then seL4_TCB_Suspend()s itself. 143 * @param conn Connection handle to the server, returned by 144 * serial_server_client_connect(). 145 * @return Integer value: 0 on successfull "kill", non-zero if the server was 146 * unable to shutdown for some reason. 147 */ 148int serial_server_kill(serial_client_context_t *conn); 149