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#include "../../state.h" 14#include "../../device_timer.h" 15#include "../dispatch.h" 16#include "timer_dspace.h" 17#include <refos/refos.h> 18 19/*! @file 20 @brief Timer dataspace interface functions. 21 22 This module implements a subset of the dataspace interface (<refos-rpc/data_server.h>), 23 for timer devices. The common dataspace dispatcher module delegates calls to us if it has 24 decided that the recieved message is a timer dataspace call. 25 26 This is a thin layer basically wrapping the device_timer module, which has the concrete 27 implementations. 28*/ 29 30seL4_CPtr 31timer_open_handler(void *rpc_userptr , char* rpc_name , int rpc_flags , int rpc_mode , 32 int rpc_size , int* rpc_errno) 33{ 34 /* Return the timer dataspace badged EP. */ 35 assert(timeServ.timerBadgeEP); 36 SET_ERRNO_PTR(rpc_errno, ESUCCESS); 37 return timeServ.timerBadgeEP; 38} 39 40int 41timer_write_handler(void *rpc_userptr , seL4_CPtr rpc_dspace_fd , uint32_t rpc_offset , 42 rpc_buffer_t rpc_buf , uint32_t rpc_count) 43{ 44 struct srv_client *c = (struct srv_client *) rpc_userptr; 45 assert(c && c->magic == TIMESERV_CLIENT_MAGIC); 46 assert(rpc_dspace_fd == TIMESERV_DSPACE_BADGE_TIMER); 47 48 if (rpc_buf.count < sizeof(uint64_t)) { 49 return -EINVALIDPARAM; 50 } 51 52 /* Writing to the timer dataspace results in a sleep call. */ 53 uint64_t timeWait = *( (uint64_t*) (rpc_buf.data) ); 54 dvprintf("timer_write_handler client waiting for %llu nanoseconds.\n", timeWait); 55 56 int error = device_timer_save_caller_as_waiter(&timeServ.devTimer, c, timeWait); 57 if (error == ESUCCESS) { 58 c->rpcClient.skip_reply = true; 59 } 60 return -error; 61} 62 63int 64timer_read_handler(void *rpc_userptr , seL4_CPtr rpc_dspace_fd , uint32_t rpc_offset , 65 rpc_buffer_t rpc_buf , uint32_t rpc_count) 66{ 67 if (!rpc_buf.count) { 68 return -EINVALIDPARAM; 69 } 70 if (rpc_buf.count < sizeof(uint64_t)) { 71 ROS_WARNING("Buffer not large enough: need %d only got %d.", sizeof(uint64_t), 72 rpc_buf.count); 73 return 0; 74 } 75 76 assert(rpc_dspace_fd == TIMESERV_DSPACE_BADGE_TIMER); 77 78 /* Reading from the timer dataspace results in a sys_get_time call. */ 79 uint64_t time = device_timer_get_time(&timeServ.devTimer); 80 memcpy(rpc_buf.data, &time, sizeof(uint64_t)); 81 return sizeof(uint64_t); 82}