1/* 2 * Copyright 2016, 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(D61_BSD) 11 */ 12 13#ifndef _RPC_INTERFACE_DATA_CLIENT_HELPER_H_ 14#define _RPC_INTERFACE_DATA_CLIENT_HELPER_H_ 15 16#include <stdint.h> 17#include <stdlib.h> 18#include <refos/refos.h> 19#include <refos/error.h> 20#include <refos-rpc/rpc.h> 21#include <refos-rpc/data_client.h> 22#include <refos-rpc/proc_client_helper.h> 23#include <refos-util/walloc.h> 24#include <refos/sync.h> 25#include <refos-util/cspace.h> 26 27/*! @file 28 @brief Helper functions for the data interface. 29 30 This file contains a simple layer of helper functions that make using the dataspace interface 31 much easier, but are too complex to have been generated by the stub generator. 32*/ 33 34/*! @brief Set the data_open() to paddr mode, for dataservers which support opening a dataspace at a 35 specific physical address. Mainly used for device MMIO. 36*/ 37#define DSPACE_FLAG_DEVICE_PADDR 0x10000000 38#define DSPACE_FLAG_UNCACHED 0x20000000 39 40/*! @brief Structure containing state for a mapped dataspace. */ 41typedef struct data_mapping { 42 seL4_CPtr session; /* No ownership. */ 43 seL4_CPtr dataspace; /* Has ownership. */ 44 seL4_CPtr window; /* Has ownership. */ 45 46 char* vaddr; 47 48 int size; 49 int sizeNPages; 50 int dspaceSize; 51 52 refos_err_t err; 53} data_mapping_t; 54 55/*! @brief Helper function to open a dataspace, allocate a window to map into, then map it there. 56 @param session The client connection session to the dataspace server. (No ownership) 57 @param name The name of the dataspace server. 58 @param flags The read / write / create flags. 59 @param mode The mode to create new file with, in the case that a new one is created. 60 @param size The size of mapping window. 61 @param dspaceSize The size of dataspace to open. Note that some data servers may ignore this. 62 @return A data_mapping_t structure containing the result mapping. Look in the err member of the 63 structure to check for any errors that have occured. (Gives ownership) 64*/ 65static inline data_mapping_t 66data_open_map(seL4_CPtr session, char* name, int flags, int mode, int size, int dspaceSize) 67{ 68 int errnoRetVal = EINVALID; 69 data_mapping_t d; 70 memset(&d, 0, sizeof(data_mapping_t)); 71 d.session = session; 72 73 /* Allocate window. */ 74 d.size = size; 75 d.sizeNPages = (size / REFOS_PAGE_SIZE) + ((size % REFOS_PAGE_SIZE) ? 1 : 0); 76 seL4_Word vaddr = 0; 77 if (flags & DSPACE_FLAG_UNCACHED) { 78 vaddr = walloc_ext(d.sizeNPages, &d.window, PROC_WINDOW_PERMISSION_READWRITE, 79 PROC_WINDOW_FLAGS_UNCACHED); 80 } else { 81 vaddr = walloc(d.sizeNPages, &d.window); 82 } 83 if (!vaddr || !d.window) { 84 errnoRetVal = ENOMEM; 85 goto exit0; 86 } 87 d.vaddr = (char*) vaddr; 88 89 /* Open the dataspace. */ 90 if (dspaceSize < 0) { 91 /* Default dataspace size to same size as the window. */ 92 dspaceSize = size; 93 } 94 d.dspaceSize = dspaceSize; 95 d.dataspace = data_open(session, name, flags, mode, dspaceSize, &errnoRetVal); 96 if (errnoRetVal != ESUCCESS || d.dataspace == 0) { 97 REFOS_SET_ERRNO(errnoRetVal); 98 goto exit1; 99 } 100 101 /* Map the dataspace. */ 102 errnoRetVal = data_datamap(session, d.dataspace, d.window, 0); 103 if (errnoRetVal != ESUCCESS) { 104 REFOS_SET_ERRNO(errnoRetVal); 105 goto exit2; 106 } 107 108 REFOS_SET_ERRNO(ESUCCESS); 109 d.err = ESUCCESS; 110 return d; 111 112 /* Exit stack. */ 113exit2: 114 data_close(session, d.dataspace); 115 seL4_CNode_Delete(REFOS_CSPACE, d.dataspace, REFOS_CDEPTH); 116 csfree(d.dataspace); 117 118exit1: 119 walloc_free(vaddr, d.sizeNPages); 120 121exit0: 122 REFOS_SET_ERRNO(errnoRetVal); 123 memset(&d, 0, sizeof(data_mapping_t)); 124 d.err = errnoRetVal; 125 return d; 126} 127 128/*! @brief Release a data mapping previous initialised by @ref data_open_map. 129 @param d The previously mapped dataspace. (Takes ownership) 130 @return ESUCCESS on success, refos_err_t error otherwise. 131*/ 132static inline refos_err_t 133data_mapping_release(data_mapping_t d) 134{ 135 if (d.err != ESUCCESS) { 136 return ESUCCESS; 137 } 138 139 if (d.window) { 140 refos_err_t error = data_dataunmap(d.session, d.window); 141 if (error != ESUCCESS) { 142 return error; 143 } 144 assert(d.vaddr); 145 walloc_free((uint32_t) d.vaddr, d.sizeNPages); 146 } 147 148 refos_err_t error = data_close(d.session, d.dataspace); 149 if (error != ESUCCESS) { 150 return error; 151 } 152 csfree_delete(d.dataspace); 153 154 memset(&d, 0, sizeof(data_mapping_t)); 155 return ESUCCESS; 156} 157 158/*! @brief Helper function for data_provide_data_from_parambuffer(). 159 160 Helper function for data_provide_data_from_parambuffer(), that basically copies the given 161 content into the given parameter buffer before calling data_provide_data_from_parambuffer(). 162 163 @param session The client connection session to the dataspace server. (No ownership) 164 @param dspace_fd The cap to the remote dataspace to provide the content for. 165 @param offset The offset into the remote dataspace to provide content for. 166 @param content The content buffer. (No ownership) 167 @param contentSize The size of the content. (May have maximum content size.) 168 @param paramBuffer The parameter buffer that has been set up. 169 @return ESUCCESS if success, refos_error error code otherwise. 170*/ 171static inline refos_err_t 172data_provide_data(seL4_CPtr session, seL4_CPtr dspace_fd, uint32_t offset, char *content, 173 uint32_t contentSize, data_mapping_t* paramBuffer) 174{ 175 if (!content) { 176 return EINVALIDPARAM; 177 } 178 if (!paramBuffer || paramBuffer->err != ESUCCESS) { 179 return ENOPARAMBUFFER; 180 } 181 if (contentSize >= paramBuffer->size) { 182 return ENOMEM; 183 } 184 memcpy(paramBuffer->vaddr, content, contentSize); 185 return data_provide_data_from_parambuffer(session, dspace_fd, offset, contentSize); 186} 187 188#endif /* _RPC_INTERFACE_DATA_CLIENT_HELPER_H_ */ 189