1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef _SYSCALL_DO_H_ 18 #define _SYSCALL_DO_H_ 19 20 21 #ifdef __cplusplus 22 extern "C" { 23 #endif 24 25 #ifdef _OS_BUILD_ 26 #error "Syscalls should not be called from OS code" 27 #endif 28 29 #include <cpu/inc/syscallDo.h> 30 #include <sensors.h> 31 #include <syscall.h> 32 #include <stdarg.h> 33 #include <gpio.h> 34 #include <osApi.h> 35 #include <seos.h> 36 #include <util.h> 37 38 39 /* it is always safe to use this, but using syscallDo0P .. syscallDo4P macros may produce faster code for free */ 40 static inline uintptr_t syscallDoGeneric(uint32_t syscallNo, ...) 41 { 42 uintptr_t ret; 43 va_list vl; 44 45 va_start(vl, syscallNo); 46 #ifdef SYSCALL_PARAMS_PASSED_AS_PTRS 47 ret = cpuSyscallDo(syscallNo, &vl); 48 #else 49 ret = cpuSyscallDo(syscallNo, *(uint32_t*)&vl); 50 #endif 51 va_end(vl); 52 53 return ret; 54 } 55 56 #ifdef cpuSyscallDo0P 57 #define syscallDo0P(syscallNo) cpuSyscallDo0P(syscallNo) 58 #else 59 #define syscallDo0P(syscallNo) syscallDoGeneric(syscallNo) 60 #endif 61 62 #ifdef cpuSyscallDo1P 63 #define syscallDo1P(syscallNo,p1) cpuSyscallDo1P(syscallNo,p1) 64 #else 65 #define syscallDo1P(syscallNo,p1) syscallDoGeneric(syscallNo,p1) 66 #endif 67 68 #ifdef cpuSyscallDo2P 69 #define syscallDo2P(syscallNo,p1,p2) cpuSyscallDo2P(syscallNo,p1,p2) 70 #else 71 #define syscallDo2P(syscallNo,p1,p2) syscallDoGeneric(syscallNo,p1,p2) 72 #endif 73 74 #ifdef cpuSyscallDo3P 75 #define syscallDo3P(syscallNo,p1,p2,p3) cpuSyscallDo3P(syscallNo,p1,p2,p3) 76 #else 77 #define syscallDo3P(syscallNo,p1,p2,p3) syscallDoGeneric(syscallNo,p1,p2,p3) 78 #endif 79 80 #ifdef cpuSyscallDo4P 81 #define syscallDo4P(syscallNo,p1,p2,p3,p4) cpuSyscallDo4P(syscallNo,p1,p2,p3,p4) 82 #else 83 #define syscallDo4P(syscallNo,p1,p2,p3,p4) syscallDoGeneric(syscallNo,p1,p2,p3,p4) 84 #endif 85 86 #ifdef cpuSyscallDo5P 87 #define syscallDo5P(syscallNo,p1,p2,p3,p4,p5) cpuSyscallDo5P(syscallNo,p1,p2,p3,p4,p5) 88 #else 89 #define syscallDo5P(syscallNo,p1,p2,p3,p4,p5) syscallDoGeneric(syscallNo,p1,p2,p3,p4,p5) 90 #endif 91 92 93 94 //system syscalls live here 95 static inline bool eOsEventSubscribe(uint32_t tid, uint32_t evtType) 96 { 97 return syscallDo2P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_MAIN, SYSCALL_OS_MAIN_EVENTQ, SYSCALL_OS_MAIN_EVTQ_SUBCRIBE), tid, evtType); 98 } 99 100 static inline bool eOsEventUnsubscribe(uint32_t tid, uint32_t evtType) 101 { 102 return syscallDo2P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_MAIN, SYSCALL_OS_MAIN_EVENTQ, SYSCALL_OS_MAIN_EVTQ_UNSUBCRIBE), tid, evtType); 103 } 104 105 static inline bool eOsEnqueueEvt(uint32_t evtType, void *evtData, uint32_t tidOfWhoWillFreeThisEvent) // tidOfWhoWillFreeThisEvent is likely your TID 106 { 107 return syscallDo3P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_MAIN, SYSCALL_OS_MAIN_EVENTQ, SYSCALL_OS_MAIN_EVTQ_ENQUEUE), evtType, evtData, tidOfWhoWillFreeThisEvent); 108 } 109 110 static inline bool eOsEnqueueEvtOrFree(uint32_t evtType, void *evtData, EventFreeF evtFreeF, uint32_t tidOfWhoWillFreeThisEvent) // tidOfWhoWillFreeThisEvent is likely your TID 111 { 112 bool success = eOsEnqueueEvt(evtType, evtData, tidOfWhoWillFreeThisEvent); 113 if (!success && evtFreeF) 114 evtFreeF(evtData); 115 return success; 116 } 117 118 static inline bool eOsEnqueuePrivateEvt(uint32_t evtType, void *evtData, uint32_t tidOfWhoWillFreeThisEvent, uint32_t toTid) 119 { 120 return syscallDo4P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_MAIN, SYSCALL_OS_MAIN_EVENTQ, SYSCALL_OS_MAIN_EVTQ_ENQUEUE_PRIVATE), evtType, evtData, tidOfWhoWillFreeThisEvent, toTid); 121 } 122 123 static inline bool eOsRetainCurrentEvent(TaggedPtr *evtFreeingInfoP) 124 { 125 return syscallDo1P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_MAIN, SYSCALL_OS_MAIN_EVENTQ, SYSCALL_OS_MAIN_EVTQ_RETAIN_EVT), evtFreeingInfoP); 126 } 127 128 static inline bool eOsFreeRetainedEvent(uint32_t evtType, void *evtData, TaggedPtr *evtFreeingInfoP) 129 { 130 return syscallDo3P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_MAIN, SYSCALL_OS_MAIN_EVENTQ, SYSCALL_OS_MAIN_EVTQ_FREE_RETAINED), evtType, evtData, evtFreeingInfoP); 131 } 132 133 static inline void eOsLogvInternal(enum LogLevel level, const char *str, uintptr_t args_list) 134 { 135 (void)syscallDo3P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_MAIN, SYSCALL_OS_MAIN_LOGGING, SYSCALL_OS_MAIN_LOG_LOGV), level, str, args_list); 136 } 137 138 static inline void eOsLogv(enum LogLevel level, const char *str, va_list vl) 139 { 140 eOsLogvInternal(level, str, VA_LIST_TO_INTEGER(vl)); 141 } 142 143 static inline void eOsLog(enum LogLevel level, const char *str, ...) 144 { 145 va_list vl; 146 147 va_start(vl, str); 148 eOsLogvInternal(level, str, VA_LIST_TO_INTEGER(vl)); 149 va_end(vl); 150 } 151 152 static inline const struct SensorInfo* eOsSensorSignalInternalEvt(uint32_t handle, uint32_t intEvtNum, uint32_t value1, uint64_t value2) 153 { 154 uint32_t value2_lo = value2; 155 uint32_t value2_hi = value2 >> 32; 156 157 return (const struct SensorInfo*)syscallDo5P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_MAIN, SYSCALL_OS_MAIN_SENSOR, SYSCALL_OS_MAIN_SENSOR_SIGNAL), handle, intEvtNum, value1, value2_lo, value2_hi); 158 } 159 160 static inline uint32_t eOsSensorRegister(const struct SensorInfo *si, uint32_t tid, void *cookie, bool initComplete) 161 { 162 return syscallDo4P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_MAIN, SYSCALL_OS_MAIN_SENSOR, SYSCALL_OS_MAIN_SENSOR_REG), si, tid, cookie, (int)initComplete); 163 } 164 165 static inline bool eOsSensorUnregister(uint32_t handle) 166 { 167 return syscallDo1P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_MAIN, SYSCALL_OS_MAIN_SENSOR, SYSCALL_OS_MAIN_SENSOR_UNREG), handle); 168 } 169 170 static inline bool eOsSensorRegisterInitComplete(uint32_t handle) 171 { 172 return syscallDo1P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_MAIN, SYSCALL_OS_MAIN_SENSOR, SYSCALL_OS_MAIN_SENSOR_REG_INIT_COMP), handle); 173 } 174 175 static inline const struct SensorInfo* eOsSensorFind(uint32_t sensorType, uint32_t idx, uint32_t *handleP) 176 { 177 return (const struct SensorInfo*)syscallDo3P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_MAIN, SYSCALL_OS_MAIN_SENSOR, SYSCALL_OS_MAIN_SENSOR_FIND), sensorType, idx, handleP); 178 } 179 180 static inline bool eOsSensorRequest(uint32_t clientId, uint32_t sensorHandle, uint32_t rate, uint64_t latency) 181 { 182 uint32_t latency_lo = latency; 183 uint32_t latency_hi = latency >> 32; 184 185 return syscallDo5P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_MAIN, SYSCALL_OS_MAIN_SENSOR, SYSCALL_OS_MAIN_SENSOR_REQUEST), clientId, sensorHandle, rate, latency_lo, latency_hi); 186 } 187 188 static inline bool eOsSensorRequestRateChange(uint32_t clientId, uint32_t sensorHandle, uint32_t newRate, uint64_t newLatency) 189 { 190 uint32_t newLatency_lo = newLatency; 191 uint32_t newLatency_hi = newLatency >> 32; 192 193 return syscallDo5P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_MAIN, SYSCALL_OS_MAIN_SENSOR, SYSCALL_OS_MAIN_SENSOR_RATE_CHG), clientId, sensorHandle, newRate, newLatency_lo, newLatency_hi); 194 } 195 196 static inline bool eOsSensorRelease(uint32_t clientId, uint32_t sensorHandle) 197 { 198 return syscallDo2P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_MAIN, SYSCALL_OS_MAIN_SENSOR, SYSCALL_OS_MAIN_SENSOR_RELEASE), clientId, sensorHandle); 199 } 200 201 static inline bool eOsSensorTriggerOndemand(uint32_t clientId, uint32_t sensorHandle) 202 { 203 return syscallDo2P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_MAIN, SYSCALL_OS_MAIN_SENSOR, SYSCALL_OS_MAIN_SENSOR_TRIGGER), clientId, sensorHandle); 204 } 205 206 static inline uint32_t eOsSensorGetCurRate(uint32_t sensorHandle) 207 { 208 return syscallDo1P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_MAIN, SYSCALL_OS_MAIN_SENSOR, SYSCALL_OS_MAIN_SENSOR_GET_RATE), sensorHandle); 209 } 210 211 static inline uint64_t eOsSensorGetTime(void) 212 { 213 uint64_t timeNanos; 214 syscallDo1P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_MAIN, SYSCALL_OS_MAIN_SENSOR, SYSCALL_OS_MAIN_SENSOR_GET_TIME), &timeNanos); 215 return timeNanos; 216 } 217 218 static inline uint64_t eOsTimGetTime(void) 219 { 220 uint64_t timeNanos; 221 syscallDo1P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_MAIN, SYSCALL_OS_MAIN_TIME, SYSCALL_OS_MAIN_TIME_GET_TIME), &timeNanos); 222 return timeNanos; 223 } 224 225 static inline uint32_t eOsTimTimerSet(uint64_t length, uint32_t jitterPpm, uint32_t driftPpm, uint32_t tid, void* cookie, bool oneShot) 226 { 227 uint32_t lengthLo = length; 228 uint32_t lengthHi = length >> 32; 229 230 return syscallDoGeneric(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_MAIN, SYSCALL_OS_MAIN_TIME, SYSCALL_OS_MAIN_TIME_SET_TIMER), lengthLo, lengthHi, jitterPpm, driftPpm, tid, cookie, (int)oneShot); 231 } 232 233 static inline bool eOsTimTimerCancel(uint32_t timerId) 234 { 235 return syscallDo1P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_MAIN, SYSCALL_OS_MAIN_TIME, SYSCALL_OS_MAIN_TIME_CANCEL_TIMER), timerId); 236 } 237 238 static inline void* eOsHeapAlloc(uint32_t sz) 239 { 240 return (void*)syscallDo1P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_MAIN, SYSCALL_OS_MAIN_HEAP, SYSCALL_OS_MAIN_HEAP_ALLOC), sz); 241 } 242 243 static inline void eOsHeapFree(void* ptr) 244 { 245 (void)syscallDo1P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_MAIN, SYSCALL_OS_MAIN_HEAP, SYSCALL_OS_MAIN_HEAP_FREE), ptr); 246 } 247 248 static inline struct SlabAllocator* eOsSlabAllocatorNew(uint32_t itemSz, uint32_t itemAlign, uint32_t numItems) 249 { 250 return (struct SlabAllocator*)syscallDo3P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_MAIN, SYSCALL_OS_MAIN_SLAB, SYSCALL_OS_MAIN_SLAB_NEW), itemSz, itemAlign, numItems); 251 } 252 253 static inline void eOsSlabAllocatorDestroy(struct SlabAllocator* allocator) 254 { 255 (void)syscallDo1P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_MAIN, SYSCALL_OS_MAIN_SLAB, SYSCALL_OS_MAIN_SLAB_DESTROY), allocator); 256 } 257 258 static inline void* eOsSlabAllocatorAlloc(struct SlabAllocator* allocator) 259 { 260 return (void *)syscallDo1P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_MAIN, SYSCALL_OS_MAIN_SLAB, SYSCALL_OS_MAIN_SLAB_ALLOC), allocator); 261 } 262 263 static inline void eOsSlabAllocatorFree(struct SlabAllocator* allocator, void* ptrP) 264 { 265 (void)syscallDo2P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_MAIN, SYSCALL_OS_MAIN_SLAB, SYSCALL_OS_MAIN_SLAB_FREE), allocator, ptrP); 266 } 267 268 static inline uint64_t eOsHostGetTime(void) 269 { 270 uint64_t timeNanos; 271 syscallDo1P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_MAIN, SYSCALL_OS_MAIN_HOST, SYSCALL_OS_MAIN_HOST_GET_TIME), &timeNanos); 272 return timeNanos; 273 } 274 275 static inline uint64_t eOsRtcGetTime(void) 276 { 277 uint64_t timeNanos; 278 syscallDo1P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_MAIN, SYSCALL_OS_MAIN_RTC, SYSCALL_OS_MAIN_RTC_GET_TIME), &timeNanos); 279 return timeNanos; 280 } 281 282 static inline struct Gpio* eOsGpioRequest(uint32_t gpioNum) 283 { 284 return (struct Gpio*)syscallDo1P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_DRIVERS, SYSCALL_OS_DRV_GPIO, SYSCALL_OS_DRV_GPIO_REQ), gpioNum); 285 } 286 287 static inline void eOsGpioRelease(struct Gpio* __restrict gpio) 288 { 289 syscallDo1P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_DRIVERS, SYSCALL_OS_DRV_GPIO, SYSCALL_OS_DRV_GPIO_REL), gpio); 290 } 291 292 static inline void eOsGpioConfigInput(const struct Gpio* __restrict gpio, int32_t gpioSpeed, enum GpioPullMode pull) 293 { 294 syscallDo3P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_DRIVERS, SYSCALL_OS_DRV_GPIO, SYSCALL_OS_DRV_GPIO_CFG_IN), gpio, gpioSpeed, pull); 295 } 296 297 static inline void eOsGpioConfigOutput(const struct Gpio* __restrict gpio, int32_t gpioSpeed, enum GpioPullMode pull, enum GpioOpenDrainMode odrMode, bool value) 298 { 299 syscallDo5P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_DRIVERS, SYSCALL_OS_DRV_GPIO, SYSCALL_OS_DRV_GPIO_CFG_OUT), gpio, gpioSpeed, pull, odrMode, value); 300 } 301 302 static inline void eOsGpioConfigAlt(const struct Gpio* __restrict gpio, int32_t gpioSpeed, enum GpioPullMode pull, enum GpioOpenDrainMode odrMode, uint32_t altFunc) 303 { 304 syscallDo5P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_DRIVERS, SYSCALL_OS_DRV_GPIO, SYSCALL_OS_DRV_GPIO_CFG_ALT), gpio, gpioSpeed, pull, odrMode, altFunc); 305 } 306 307 static inline bool eOsGpioGet(const struct Gpio* __restrict gpio) 308 { 309 return !!syscallDo1P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_DRIVERS, SYSCALL_OS_DRV_GPIO, SYSCALL_OS_DRV_GPIO_GET), gpio); 310 } 311 312 static inline void eOsGpioSet(const struct Gpio* __restrict gpio, bool value) 313 { 314 syscallDo2P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_DRIVERS, SYSCALL_OS_DRV_GPIO, SYSCALL_OS_DRV_GPIO_SET), gpio, value); 315 } 316 317 static inline int eOsI2cMasterRequest(uint32_t busId, uint32_t speedInHz) 318 { 319 return syscallDo2P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_DRIVERS, SYSCALL_OS_DRV_I2C_MASTER, SYSCALL_OS_DRV_I2CM_REQ), busId, speedInHz); 320 } 321 322 static inline int eOsI2cMasterRelease(uint32_t busId) 323 { 324 return syscallDo1P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_DRIVERS, SYSCALL_OS_DRV_I2C_MASTER, SYSCALL_OS_DRV_I2CM_REL), busId); 325 } 326 327 static inline int eOsI2cMasterTxRx(uint32_t busId, uint32_t addr, const void *txBuf, size_t txSize, void *rxBuf, size_t rxSize, uint32_t cbkTid, void *cookie) 328 { 329 return syscallDoGeneric(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_DRIVERS, SYSCALL_OS_DRV_I2C_MASTER, SYSCALL_OS_DRV_I2CM_TXRX), busId, addr, txBuf, txSize, rxBuf, rxSize, cbkTid, cookie); 330 } 331 332 static inline int eOsI2cSlaveRequest(uint32_t busId, uint32_t addr) 333 { 334 return syscallDo2P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_DRIVERS, SYSCALL_OS_DRV_I2C_SLAVE, SYSCALL_OS_DRV_I2CS_REQ), busId, addr); 335 } 336 337 static inline int eOsI2cSlaveRelease(uint32_t busId) 338 { 339 return syscallDo1P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_DRIVERS, SYSCALL_OS_DRV_I2C_SLAVE, SYSCALL_OS_DRV_I2CS_REL), busId); 340 } 341 342 static inline void eOsI2cSlaveEnableRx(uint32_t busId, void *rxBuf, size_t rxSize, uint32_t cbkTid, void *cookie) 343 { 344 syscallDo5P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_DRIVERS, SYSCALL_OS_DRV_I2C_SLAVE, SYSCALL_OS_DRV_I2CS_RX_EN), busId, rxBuf, rxSize, cbkTid, cookie); 345 } 346 347 static inline int eOsI2cSlaveTxPreamble(uint32_t busId, uint8_t byte, uint32_t cbkTid, void *cookie) 348 { 349 return syscallDo4P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_DRIVERS, SYSCALL_OS_DRV_I2C_SLAVE, SYSCALL_OS_DRV_I2CS_TX_PRE), busId, byte, cbkTid, cookie); 350 } 351 352 static inline int eOsI2cSlaveTxPacket(uint32_t busId, const void *txBuf, size_t txSize, uint32_t cbkTid, void *cookie) 353 { 354 return syscallDo5P(SYSCALL_NO(SYSCALL_DOMAIN_OS, SYSCALL_OS_DRIVERS, SYSCALL_OS_DRV_I2C_SLAVE, SYSCALL_OS_DRV_I2CS_TX_PKT), busId, txBuf, txSize, cbkTid, cookie); 355 } 356 357 #ifdef __cplusplus 358 } 359 #endif 360 361 #endif 362 363