Home | History | Annotate | Download | only in src
      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