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