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