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 #include <plat/inc/taggedPtr.h> 18 #include <syscall.h> 19 #include <sensors.h> 20 #include <errno.h> 21 #include <osApi.h> 22 #include <timer.h> 23 #include <gpio.h> 24 #include <util.h> 25 #include <seos.h> 26 #include <slab.h> 27 #include <heap.h> 28 #include <i2c.h> 29 30 static struct SlabAllocator *mSlabAllocator; 31 32 33 static void osExpApiEvtqSubscribe(uintptr_t *retValP, va_list args) 34 { 35 (void)va_arg(args, uint32_t); // tid 36 uint32_t evtType = va_arg(args, uint32_t); 37 38 *retValP = osEventSubscribe(0, evtType); 39 } 40 41 static void osExpApiEvtqUnsubscribe(uintptr_t *retValP, va_list args) 42 { 43 (void)va_arg(args, uint32_t); // tid 44 uint32_t evtType = va_arg(args, uint32_t); 45 46 *retValP = osEventUnsubscribe(0, evtType); 47 } 48 49 static void osExpApiEvtqEnqueue(uintptr_t *retValP, va_list args) 50 { 51 uint32_t evtType = va_arg(args, uint32_t); 52 void *evtData = va_arg(args, void*); 53 (void)va_arg(args, uint32_t); // tid 54 55 *retValP = osEnqueueEvtAsApp(evtType, evtData, 0); 56 } 57 58 static void osExpApiEvtqEnqueuePrivate(uintptr_t *retValP, va_list args) 59 { 60 uint32_t evtType = va_arg(args, uint32_t); 61 void *evtData = va_arg(args, void*); 62 (void)va_arg(args, uint32_t); // tid 63 uint32_t toTid = va_arg(args, uint32_t); 64 65 *retValP = osEnqueuePrivateEvtAsApp(evtType, evtData, 0, toTid); 66 } 67 68 static void osExpApiEvtqRetainEvt(uintptr_t *retValP, va_list args) 69 { 70 TaggedPtr *evtFreeingInfoP = va_arg(args, TaggedPtr*); 71 72 *retValP = osRetainCurrentEvent(evtFreeingInfoP); 73 } 74 75 static void osExpApiEvtqFreeRetained(uintptr_t *retValP, va_list args) 76 { 77 uint32_t evtType = va_arg(args, uint32_t); 78 void *evtData = va_arg(args, void*); 79 TaggedPtr *evtFreeingInfoP = va_arg(args, TaggedPtr*); 80 81 osFreeRetainedEvent(evtType, evtData, evtFreeingInfoP); 82 } 83 84 static void osExpApiLogLogv(uintptr_t *retValP, va_list args) 85 { 86 enum LogLevel level = va_arg(args, int /* enums promoted to ints in va_args in C */); 87 const char *str = va_arg(args, const char*); 88 va_list innerArgs; 89 va_copy(innerArgs, INTEGER_TO_VA_LIST(va_arg(args, uintptr_t))); 90 osLogv(level, str, innerArgs); 91 va_end(innerArgs); 92 } 93 94 static void osExpApiSensorSignal(uintptr_t *retValP, va_list args) 95 { 96 uint32_t handle = va_arg(args, uint32_t); 97 uint32_t intEvtNum = va_arg(args, uint32_t); 98 uint32_t value1 = va_arg(args, uint32_t); 99 uint32_t value2_lo = va_arg(args, uint32_t); 100 uint32_t value2_hi = va_arg(args, uint32_t); 101 uint64_t value2 = (((uint64_t)value2_hi) << 32) + value2_lo; 102 103 *retValP = (uintptr_t)sensorSignalInternalEvt(handle, intEvtNum, value1, value2); 104 } 105 106 static void osExpApiSensorReg(uintptr_t *retValP, va_list args) 107 { 108 const struct SensorInfo *si = va_arg(args, const struct SensorInfo*); 109 (void)va_arg(args, uint32_t); // tid 110 void *cookie = va_arg(args, void *); 111 bool initComplete = va_arg(args, int); 112 113 *retValP = (uintptr_t)sensorRegisterAsApp(si, 0, cookie, initComplete); 114 } 115 116 static void osExpApiSensorUnreg(uintptr_t *retValP, va_list args) 117 { 118 uint32_t handle = va_arg(args, uint32_t); 119 120 *retValP = (uintptr_t)sensorUnregister(handle); 121 } 122 123 static void osExpApiSensorRegInitComp(uintptr_t *retValP, va_list args) 124 { 125 uint32_t handle = va_arg(args, uint32_t); 126 127 *retValP = (uintptr_t)sensorRegisterInitComplete(handle); 128 } 129 130 static void osExpApiSensorFind(uintptr_t *retValP, va_list args) 131 { 132 uint32_t sensorType = va_arg(args, uint32_t); 133 uint32_t idx = va_arg(args, uint32_t); 134 uint32_t *handleP = va_arg(args, uint32_t*); 135 136 *retValP = (uintptr_t)sensorFind(sensorType, idx, handleP); 137 } 138 139 static void osExpApiSensorReq(uintptr_t *retValP, va_list args) 140 { 141 (void)va_arg(args, uint32_t); // clientId == tid 142 uint32_t sensorHandle = va_arg(args, uint32_t); 143 uint32_t rate = va_arg(args, uint32_t); 144 uint32_t latency_lo = va_arg(args, uint32_t); 145 uint32_t latency_hi = va_arg(args, uint32_t); 146 uint64_t latency = (((uint64_t)latency_hi) << 32) + latency_lo; 147 148 *retValP = sensorRequest(0, sensorHandle, rate, latency); 149 } 150 151 static void osExpApiSensorRateChg(uintptr_t *retValP, va_list args) 152 { 153 (void)va_arg(args, uint32_t); // clientId == tid 154 uint32_t sensorHandle = va_arg(args, uint32_t); 155 uint32_t newRate = va_arg(args, uint32_t); 156 uint32_t newLatency_lo = va_arg(args, uint32_t); 157 uint32_t newLatency_hi = va_arg(args, uint32_t); 158 uint64_t newLatency = (((uint64_t)newLatency_hi) << 32) + newLatency_lo; 159 160 *retValP = sensorRequestRateChange(0, sensorHandle, newRate, newLatency); 161 } 162 163 static void osExpApiSensorRel(uintptr_t *retValP, va_list args) 164 { 165 (void)va_arg(args, uint32_t); // clientId == tid 166 uint32_t sensorHandle = va_arg(args, uint32_t); 167 168 *retValP = sensorRelease(0, sensorHandle); 169 } 170 171 static void osExpApiSensorTrigger(uintptr_t *retValP, va_list args) 172 { 173 (void)va_arg(args, uint32_t); // clientId == tid 174 uint32_t sensorHandle = va_arg(args, uint32_t); 175 176 *retValP = sensorTriggerOndemand(0, sensorHandle); 177 } 178 179 static void osExpApiSensorGetRate(uintptr_t *retValP, va_list args) 180 { 181 uint32_t sensorHandle = va_arg(args, uint32_t); 182 183 *retValP = sensorGetCurRate(sensorHandle); 184 } 185 186 static void osExpApiTimGetTime(uintptr_t *retValP, va_list args) 187 { 188 uint64_t *timeNanos = va_arg(args, uint64_t *); 189 *timeNanos = timGetTime(); 190 } 191 192 static void osExpApiTimSetTimer(uintptr_t *retValP, va_list args) 193 { 194 uint32_t length_lo = va_arg(args, uint32_t); 195 uint32_t length_hi = va_arg(args, uint32_t); 196 uint32_t jitterPpm = va_arg(args, uint32_t); 197 uint32_t driftPpm = va_arg(args, uint32_t); 198 (void)va_arg(args, uint32_t); // tid 199 void *cookie = va_arg(args, void *); 200 bool oneshot = va_arg(args, int); 201 uint64_t length = (((uint64_t)length_hi) << 32) + length_lo; 202 203 *retValP = timTimerSetAsApp(length, jitterPpm, driftPpm, 0, cookie, oneshot); 204 } 205 206 static void osExpApiTimCancelTimer(uintptr_t *retValP, va_list args) 207 { 208 uint32_t timerId = va_arg(args, uint32_t); 209 210 *retValP = timTimerCancel(timerId); 211 } 212 213 static void osExpApiHeapAlloc(uintptr_t *retValP, va_list args) 214 { 215 uint32_t sz = va_arg(args, uint32_t); 216 217 *retValP = (uintptr_t)heapAlloc(sz); 218 } 219 220 static void osExpApiHeapFree(uintptr_t *retValP, va_list args) 221 { 222 void *mem = va_arg(args, void *); 223 224 heapFree(mem); 225 } 226 227 static void osExpApiSlabNew(uintptr_t *retValP, va_list args) 228 { 229 uint32_t itemSz = va_arg(args, uint32_t); 230 uint32_t itemAlign = va_arg(args, uint32_t); 231 uint32_t numItems = va_arg(args, uint32_t); 232 233 *retValP = (uintptr_t)slabAllocatorNew(itemSz, itemAlign, numItems); 234 } 235 236 static void osExpApiSlabDestroy(uintptr_t *retValP, va_list args) 237 { 238 struct SlabAllocator *allocator = va_arg(args, struct SlabAllocator *); 239 240 slabAllocatorDestroy(allocator); 241 } 242 243 static void osExpApiSlabAlloc(uintptr_t *retValP, va_list args) 244 { 245 struct SlabAllocator *allocator = va_arg(args, struct SlabAllocator *); 246 247 *retValP = (uintptr_t)slabAllocatorAlloc(allocator); 248 } 249 250 static void osExpApiSlabFree(uintptr_t *retValP, va_list args) 251 { 252 struct SlabAllocator *allocator = va_arg(args, struct SlabAllocator *); 253 void *mem = va_arg(args, void *); 254 255 slabAllocatorFree(allocator, mem); 256 } 257 258 static union OsApiSlabItem* osExpApiI2cCbkInfoAlloc(void *cookie) 259 { 260 union OsApiSlabItem *thing = slabAllocatorAlloc(mSlabAllocator); 261 262 if (thing) { 263 thing->i2cAppCbkInfo.toTid = osGetCurrentTid(); 264 thing->i2cAppCbkInfo.cookie = cookie; 265 } 266 267 return thing; 268 } 269 270 static void osExpApiI2cInternalEvtFreeF(void *evt) 271 { 272 slabAllocatorFree(mSlabAllocator, evt); 273 } 274 275 static void osExpApiI2cInternalCbk(void *cookie, size_t tx, size_t rx, int err) 276 { 277 union OsApiSlabItem *thing = (union OsApiSlabItem*)cookie; 278 uint32_t tid; 279 280 tid = thing->i2cAppCbkInfo.toTid; 281 cookie = thing->i2cAppCbkInfo.cookie; 282 283 //we reuse the same slab element to send the event now 284 thing->i2cAppCbkEvt.cookie = cookie; 285 thing->i2cAppCbkEvt.tx = tx; 286 thing->i2cAppCbkEvt.rx = rx; 287 thing->i2cAppCbkEvt.err = err; 288 289 if (!osEnqueuePrivateEvt(EVT_APP_I2C_CBK, &thing->i2cAppCbkEvt, osExpApiI2cInternalEvtFreeF, tid)) { 290 osLog(LOG_WARN, "Failed to send I2C evt to app. This might end badly for the app..."); 291 osExpApiI2cInternalEvtFreeF(thing); 292 // TODO: terminate app here: memory pressure is severe 293 } 294 } 295 296 static void osExpApiGpioReq(uintptr_t *retValP, va_list args) 297 { 298 uint32_t gpioNum = va_arg(args, uint32_t); 299 300 *retValP = (uintptr_t)gpioRequest(gpioNum); 301 } 302 303 static void osExpApiGpioRel(uintptr_t *retValP, va_list args) 304 { 305 struct Gpio* gpio = va_arg(args, struct Gpio*); 306 307 gpioRelease(gpio); 308 } 309 310 static void osExpApiGpioCfgIn(uintptr_t *retValP, va_list args) 311 { 312 struct Gpio* gpio = va_arg(args, struct Gpio*); 313 int32_t speed = va_arg(args, int32_t); 314 enum GpioPullMode pullMode = va_arg(args, int); 315 316 gpioConfigInput(gpio, speed, pullMode); 317 } 318 319 static void osExpApiGpioCfgOut(uintptr_t *retValP, va_list args) 320 { 321 struct Gpio* gpio = va_arg(args, struct Gpio*); 322 int32_t speed = va_arg(args, int32_t); 323 enum GpioPullMode pullMode = va_arg(args, int); 324 enum GpioOpenDrainMode odrMode = va_arg(args, int); 325 bool value = !!va_arg(args, int); 326 327 gpioConfigOutput(gpio, speed, pullMode, odrMode, value); 328 } 329 330 static void osExpApiGpioCfgAlt(uintptr_t *retValP, va_list args) 331 { 332 struct Gpio* gpio = va_arg(args, struct Gpio*); 333 int32_t speed = va_arg(args, int32_t); 334 enum GpioPullMode pullMode = va_arg(args, int); 335 enum GpioOpenDrainMode odrMode = va_arg(args, int); 336 uint32_t altFunc = va_arg(args, uint32_t); 337 338 gpioConfigAlt(gpio, speed, pullMode, odrMode, altFunc); 339 } 340 341 static void osExpApiGpioGet(uintptr_t *retValP, va_list args) 342 { 343 struct Gpio* gpio = va_arg(args, struct Gpio*); 344 345 *retValP = gpioGet(gpio); 346 } 347 348 static void osExpApiGpioSet(uintptr_t *retValP, va_list args) 349 { 350 struct Gpio* gpio = va_arg(args, struct Gpio*); 351 bool value = !!va_arg(args, int); 352 353 gpioSet(gpio, value); 354 } 355 356 static void osExpApiI2cMstReq(uintptr_t *retValP, va_list args) 357 { 358 uint32_t busId = va_arg(args, uint32_t); 359 uint32_t speed = va_arg(args, uint32_t); 360 361 *retValP = i2cMasterRequest(busId, speed); 362 } 363 364 static void osExpApiI2cMstRel(uintptr_t *retValP, va_list args) 365 { 366 uint32_t busId = va_arg(args, uint32_t); 367 368 *retValP = i2cMasterRelease(busId); 369 } 370 371 static void osExpApiI2cMstTxRx(uintptr_t *retValP, va_list args) 372 { 373 uint32_t busId = va_arg(args, uint32_t); 374 uint32_t addr = va_arg(args, uint32_t); 375 const void *txBuf = va_arg(args, const void*); 376 size_t txSize = va_arg(args, size_t); 377 void *rxBuf = va_arg(args, void*); 378 size_t rxSize = va_arg(args, size_t); 379 (void)va_arg(args, uint32_t); // tid 380 void *cookie = va_arg(args, void *); 381 union OsApiSlabItem *cbkInfo = osExpApiI2cCbkInfoAlloc(cookie); 382 383 if (!cbkInfo) 384 *retValP = -ENOMEM; 385 386 *retValP = i2cMasterTxRx(busId, addr, txBuf, txSize, rxBuf, rxSize, osExpApiI2cInternalCbk, cbkInfo); 387 388 if (*retValP) 389 slabAllocatorFree(mSlabAllocator, cbkInfo); 390 } 391 392 static void osExpApiI2cSlvReq(uintptr_t *retValP, va_list args) 393 { 394 uint32_t busId = va_arg(args, uint32_t); 395 uint32_t addr = va_arg(args, uint32_t); 396 397 *retValP = i2cSlaveRequest(busId, addr); 398 } 399 400 static void osExpApiI2cSlvRel(uintptr_t *retValP, va_list args) 401 { 402 uint32_t busId = va_arg(args, uint32_t); 403 404 *retValP = i2cSlaveRelease(busId); 405 } 406 407 static void osExpApiI2cSlvRxEn(uintptr_t *retValP, va_list args) 408 { 409 uint32_t busId = va_arg(args, uint32_t); 410 void *rxBuf = va_arg(args, void*); 411 size_t rxSize = va_arg(args, size_t); 412 (void)va_arg(args, uint32_t); // tid 413 void *cookie = va_arg(args, void *); 414 union OsApiSlabItem *cbkInfo = osExpApiI2cCbkInfoAlloc(cookie); 415 416 if (!cbkInfo) 417 *retValP = -ENOMEM; 418 419 i2cSlaveEnableRx(busId, rxBuf, rxSize, osExpApiI2cInternalCbk, cbkInfo); 420 421 if (*retValP) 422 slabAllocatorFree(mSlabAllocator, cbkInfo); 423 } 424 425 static void osExpApiI2cSlvTxPre(uintptr_t *retValP, va_list args) 426 { 427 uint32_t busId = va_arg(args, uint32_t); 428 uint8_t byte = va_arg(args, int); 429 (void)va_arg(args, uint32_t); // tid 430 void *cookie = va_arg(args, void *); 431 union OsApiSlabItem *cbkInfo = osExpApiI2cCbkInfoAlloc(cookie); 432 433 if (!cbkInfo) 434 *retValP = -ENOMEM; 435 436 *retValP = i2cSlaveTxPreamble(busId, byte, osExpApiI2cInternalCbk, cbkInfo); 437 438 if (*retValP) 439 slabAllocatorFree(mSlabAllocator, cbkInfo); 440 } 441 442 static void osExpApiI2cSlvTxPkt(uintptr_t *retValP, va_list args) 443 { 444 uint32_t busId = va_arg(args, uint32_t); 445 const void *txBuf = va_arg(args, const void*); 446 size_t txSize = va_arg(args, size_t); 447 (void)va_arg(args, uint32_t); // tid 448 void *cookie = va_arg(args, void *); 449 union OsApiSlabItem *cbkInfo = osExpApiI2cCbkInfoAlloc(cookie); 450 451 if (!cbkInfo) 452 *retValP = -ENOMEM; 453 454 *retValP = i2cSlaveTxPacket(busId, txBuf, txSize, osExpApiI2cInternalCbk, cbkInfo); 455 456 if (*retValP) 457 slabAllocatorFree(mSlabAllocator, cbkInfo); 458 } 459 460 void osApiExport(struct SlabAllocator *mainSlubAllocator) 461 { 462 static const struct SyscallTable osMainEvtqTable = { 463 .numEntries = SYSCALL_OS_MAIN_EVTQ_LAST, 464 .entry = { 465 [SYSCALL_OS_MAIN_EVTQ_SUBCRIBE] = { .func = osExpApiEvtqSubscribe, }, 466 [SYSCALL_OS_MAIN_EVTQ_UNSUBCRIBE] = { .func = osExpApiEvtqUnsubscribe, }, 467 [SYSCALL_OS_MAIN_EVTQ_ENQUEUE] = { .func = osExpApiEvtqEnqueue, }, 468 [SYSCALL_OS_MAIN_EVTQ_ENQUEUE_PRIVATE] = { .func = osExpApiEvtqEnqueuePrivate, }, 469 [SYSCALL_OS_MAIN_EVTQ_RETAIN_EVT] = { .func = osExpApiEvtqRetainEvt, }, 470 [SYSCALL_OS_MAIN_EVTQ_FREE_RETAINED] = { .func = osExpApiEvtqFreeRetained, }, 471 }, 472 }; 473 474 static const struct SyscallTable osMainLogTable = { 475 .numEntries = SYSCALL_OS_MAIN_LOG_LAST, 476 .entry = { 477 [SYSCALL_OS_MAIN_LOG_LOGV] = { .func = osExpApiLogLogv, }, 478 }, 479 }; 480 481 static const struct SyscallTable osMainSensorsTable = { 482 .numEntries = SYSCALL_OS_MAIN_SENSOR_LAST, 483 .entry = { 484 [SYSCALL_OS_MAIN_SENSOR_SIGNAL] = { .func = osExpApiSensorSignal, }, 485 [SYSCALL_OS_MAIN_SENSOR_REG] = { .func = osExpApiSensorReg, }, 486 [SYSCALL_OS_MAIN_SENSOR_UNREG] = { .func = osExpApiSensorUnreg, }, 487 [SYSCALL_OS_MAIN_SENSOR_REG_INIT_COMP] = { .func = osExpApiSensorRegInitComp }, 488 [SYSCALL_OS_MAIN_SENSOR_FIND] = { .func = osExpApiSensorFind, }, 489 [SYSCALL_OS_MAIN_SENSOR_REQUEST] = { .func = osExpApiSensorReq, }, 490 [SYSCALL_OS_MAIN_SENSOR_RATE_CHG] = { .func = osExpApiSensorRateChg, }, 491 [SYSCALL_OS_MAIN_SENSOR_RELEASE] = { .func = osExpApiSensorRel, }, 492 [SYSCALL_OS_MAIN_SENSOR_TRIGGER] = { .func = osExpApiSensorTrigger, }, 493 [SYSCALL_OS_MAIN_SENSOR_GET_RATE] = { .func = osExpApiSensorGetRate, }, 494 495 }, 496 }; 497 498 static const struct SyscallTable osMainTimerTable = { 499 .numEntries = SYSCALL_OS_MAIN_TIME_LAST, 500 .entry = { 501 [SYSCALL_OS_MAIN_TIME_GET_TIME] = { .func = osExpApiTimGetTime, }, 502 [SYSCALL_OS_MAIN_TIME_SET_TIMER] = { .func = osExpApiTimSetTimer, }, 503 [SYSCALL_OS_MAIN_TIME_CANCEL_TIMER] = { .func = osExpApiTimCancelTimer, }, 504 }, 505 }; 506 507 static const struct SyscallTable osMainHeapTable = { 508 .numEntries = SYSCALL_OS_MAIN_HEAP_LAST, 509 .entry = { 510 [SYSCALL_OS_MAIN_HEAP_ALLOC] = { .func = osExpApiHeapAlloc }, 511 [SYSCALL_OS_MAIN_HEAP_FREE] = { .func = osExpApiHeapFree }, 512 }, 513 }; 514 515 static const struct SyscallTable osMainSlabTable = { 516 .numEntries = SYSCALL_OS_MAIN_SLAB_LAST, 517 .entry = { 518 [SYSCALL_OS_MAIN_SLAB_NEW] = { .func = osExpApiSlabNew }, 519 [SYSCALL_OS_MAIN_SLAB_DESTROY] = { .func = osExpApiSlabDestroy }, 520 [SYSCALL_OS_MAIN_SLAB_ALLOC] = { .func = osExpApiSlabAlloc }, 521 [SYSCALL_OS_MAIN_SLAB_FREE] = { .func = osExpApiSlabFree }, 522 }, 523 }; 524 525 static const struct SyscallTable osMainTable = { 526 .numEntries = SYSCALL_OS_MAIN_LAST, 527 .entry = { 528 [SYSCALL_OS_MAIN_EVENTQ] = { .subtable = (struct SyscallTable*)&osMainEvtqTable, }, 529 [SYSCALL_OS_MAIN_LOGGING] = { .subtable = (struct SyscallTable*)&osMainLogTable, }, 530 [SYSCALL_OS_MAIN_SENSOR] = { .subtable = (struct SyscallTable*)&osMainSensorsTable, }, 531 [SYSCALL_OS_MAIN_TIME] = { .subtable = (struct SyscallTable*)&osMainTimerTable, }, 532 [SYSCALL_OS_MAIN_HEAP] = { .subtable = (struct SyscallTable*)&osMainHeapTable, }, 533 [SYSCALL_OS_MAIN_SLAB] = { .subtable = (struct SyscallTable*)&osMainSlabTable, }, 534 }, 535 }; 536 537 static const struct SyscallTable osDrvGpioTable = { 538 .numEntries = SYSCALL_OS_DRV_GPIO_LAST, 539 .entry = { 540 [SYSCALL_OS_DRV_GPIO_REQ] = { .func = osExpApiGpioReq, }, 541 [SYSCALL_OS_DRV_GPIO_REL] = { .func = osExpApiGpioRel, }, 542 [SYSCALL_OS_DRV_GPIO_CFG_IN] = { .func = osExpApiGpioCfgIn, }, 543 [SYSCALL_OS_DRV_GPIO_CFG_OUT] = { .func = osExpApiGpioCfgOut, }, 544 [SYSCALL_OS_DRV_GPIO_CFG_ALT] = { .func = osExpApiGpioCfgAlt, }, 545 [SYSCALL_OS_DRV_GPIO_GET] = { .func = osExpApiGpioGet, }, 546 [SYSCALL_OS_DRV_GPIO_SET] = { .func = osExpApiGpioSet, }, 547 }, 548 }; 549 550 static const struct SyscallTable osGrvI2cMstTable = { 551 .numEntries = SYSCALL_OS_DRV_I2CM_LAST, 552 .entry = { 553 [SYSCALL_OS_DRV_I2CM_REQ] = { .func = osExpApiI2cMstReq, }, 554 [SYSCALL_OS_DRV_I2CM_REL] = { .func = osExpApiI2cMstRel, }, 555 [SYSCALL_OS_DRV_I2CM_TXRX] = { .func = osExpApiI2cMstTxRx, }, 556 }, 557 }; 558 559 static const struct SyscallTable osGrvI2cSlvTable = { 560 .numEntries = SYSCALL_OS_DRV_I2CS_LAST, 561 .entry = { 562 [ SYSCALL_OS_DRV_I2CS_REQ] = { .func = osExpApiI2cSlvReq, }, 563 [ SYSCALL_OS_DRV_I2CS_REL] = { .func = osExpApiI2cSlvRel, }, 564 [ SYSCALL_OS_DRV_I2CS_RX_EN] = { .func = osExpApiI2cSlvRxEn, }, 565 [ SYSCALL_OS_DRV_I2CS_TX_PRE] = { .func = osExpApiI2cSlvTxPre, }, 566 [ SYSCALL_OS_DRV_I2CS_TX_PKT] = { .func = osExpApiI2cSlvTxPkt, }, 567 }, 568 }; 569 570 static const struct SyscallTable osDriversTable = { 571 .numEntries = SYSCALL_OS_DRV_LAST, 572 .entry = { 573 [SYSCALL_OS_DRV_GPIO] = { .subtable = (struct SyscallTable*)&osDrvGpioTable, }, 574 [SYSCALL_OS_DRV_I2C_MASTER] = { .subtable = (struct SyscallTable*)&osGrvI2cMstTable, }, 575 [SYSCALL_OS_DRV_I2C_SLAVE] = { .subtable = (struct SyscallTable*)&osGrvI2cSlvTable, }, 576 }, 577 }; 578 579 static const struct SyscallTable osTable = { 580 .numEntries = SYSCALL_OS_LAST, 581 .entry = { 582 [SYSCALL_OS_MAIN] = { .subtable = (struct SyscallTable*)&osMainTable, }, 583 [SYSCALL_OS_DRIVERS] = { .subtable = (struct SyscallTable*)&osDriversTable, }, 584 }, 585 }; 586 587 if (!syscallAddTable(SYSCALL_DOMAIN_OS, 1, (struct SyscallTable*)&osTable)) 588 osLog(LOG_ERROR, "Failed to export OS base API"); 589 } 590 591