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 
osExpApiEvtqSubscribe(uintptr_t * retValP,va_list args)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 
osExpApiEvtqUnsubscribe(uintptr_t * retValP,va_list args)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 
osExpApiEvtqEnqueue(uintptr_t * retValP,va_list args)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 
osExpApiEvtqEnqueuePrivate(uintptr_t * retValP,va_list args)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 
osExpApiEvtqRetainEvt(uintptr_t * retValP,va_list args)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 
osExpApiEvtqFreeRetained(uintptr_t * retValP,va_list args)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 
osExpApiLogLogv(uintptr_t * retValP,va_list args)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, str, innerArgs);
93     va_end(innerArgs);
94 }
95 
osExpApiSensorSignal(uintptr_t * retValP,va_list args)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 
osExpApiSensorReg(uintptr_t * retValP,va_list args)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 
osExpApiSensorUnreg(uintptr_t * retValP,va_list args)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 
osExpApiSensorRegInitComp(uintptr_t * retValP,va_list args)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 
osExpApiSensorFind(uintptr_t * retValP,va_list args)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 
osExpApiSensorReq(uintptr_t * retValP,va_list args)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 
osExpApiSensorRateChg(uintptr_t * retValP,va_list args)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 
osExpApiSensorRel(uintptr_t * retValP,va_list args)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 
osExpApiSensorTrigger(uintptr_t * retValP,va_list args)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 
osExpApiSensorGetRate(uintptr_t * retValP,va_list args)181 static void osExpApiSensorGetRate(uintptr_t *retValP, va_list args)
182 {
183     uint32_t sensorHandle = va_arg(args, uint32_t);
184 
185     *retValP = sensorGetCurRate(sensorHandle);
186 }
187 
osExpApiSensorGetTime(uintptr_t * retValP,va_list args)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 
osExpApiTimGetTime(uintptr_t * retValP,va_list args)194 static void osExpApiTimGetTime(uintptr_t *retValP, va_list args)
195 {
196     uint64_t *timeNanos = va_arg(args, uint64_t *);
197     *timeNanos = timGetTime();
198 }
199 
osExpApiTimSetTimer(uintptr_t * retValP,va_list args)200 static void osExpApiTimSetTimer(uintptr_t *retValP, va_list args)
201 {
202     uint32_t length_lo = va_arg(args, uint32_t);
203     uint32_t length_hi = va_arg(args, uint32_t);
204     uint32_t jitterPpm = va_arg(args, uint32_t);
205     uint32_t driftPpm = va_arg(args, uint32_t);
206     (void)va_arg(args, uint32_t); // tid
207     void *cookie = va_arg(args, void *);
208     bool oneshot = va_arg(args, int);
209     uint64_t length = (((uint64_t)length_hi) << 32) + length_lo;
210 
211     *retValP = timTimerSetAsApp(length, jitterPpm, driftPpm, 0, cookie, oneshot);
212 }
213 
osExpApiTimCancelTimer(uintptr_t * retValP,va_list args)214 static void osExpApiTimCancelTimer(uintptr_t *retValP, va_list args)
215 {
216     uint32_t timerId = va_arg(args, uint32_t);
217 
218     *retValP = timTimerCancel(timerId);
219 }
220 
osExpApiHeapAlloc(uintptr_t * retValP,va_list args)221 static void osExpApiHeapAlloc(uintptr_t *retValP, va_list args)
222 {
223     uint32_t sz = va_arg(args, uint32_t);
224 
225     *retValP = (uintptr_t)heapAlloc(sz);
226 }
227 
osExpApiHeapFree(uintptr_t * retValP,va_list args)228 static void osExpApiHeapFree(uintptr_t *retValP, va_list args)
229 {
230     void *mem = va_arg(args, void *);
231 
232     heapFree(mem);
233 }
234 
osExpApiSlabNew(uintptr_t * retValP,va_list args)235 static void osExpApiSlabNew(uintptr_t *retValP, va_list args)
236 {
237     uint32_t itemSz = va_arg(args, uint32_t);
238     uint32_t itemAlign = va_arg(args, uint32_t);
239     uint32_t numItems = va_arg(args, uint32_t);
240 
241     *retValP = (uintptr_t)slabAllocatorNew(itemSz, itemAlign, numItems);
242 }
243 
osExpApiSlabDestroy(uintptr_t * retValP,va_list args)244 static void osExpApiSlabDestroy(uintptr_t *retValP, va_list args)
245 {
246     struct SlabAllocator *allocator = va_arg(args, struct SlabAllocator *);
247 
248     slabAllocatorDestroy(allocator);
249 }
250 
osExpApiSlabAlloc(uintptr_t * retValP,va_list args)251 static void osExpApiSlabAlloc(uintptr_t *retValP, va_list args)
252 {
253     struct SlabAllocator *allocator = va_arg(args, struct SlabAllocator *);
254 
255     *retValP = (uintptr_t)slabAllocatorAlloc(allocator);
256 }
257 
osExpApiSlabFree(uintptr_t * retValP,va_list args)258 static void osExpApiSlabFree(uintptr_t *retValP, va_list args)
259 {
260     struct SlabAllocator *allocator = va_arg(args, struct SlabAllocator *);
261     void *mem = va_arg(args, void *);
262 
263     slabAllocatorFree(allocator, mem);
264 }
265 
osExpApiHostGetTime(uintptr_t * retValP,va_list args)266 static void osExpApiHostGetTime(uintptr_t *retValP, va_list args)
267 {
268     uint64_t *timeNanos = va_arg(args, uint64_t *);
269     *timeNanos = hostGetTime();
270 }
271 
osExpApiRtcGetTime(uintptr_t * retValP,va_list args)272 static void osExpApiRtcGetTime(uintptr_t *retValP, va_list args)
273 {
274     uint64_t *timeNanos = va_arg(args, uint64_t *);
275     *timeNanos = rtcGetTime();
276 }
277 
osExpApiI2cCbkInfoAlloc(void * cookie)278 static union OsApiSlabItem* osExpApiI2cCbkInfoAlloc(void *cookie)
279 {
280     union OsApiSlabItem *thing = slabAllocatorAlloc(mSlabAllocator);
281 
282     if (thing) {
283         thing->i2cAppCbkInfo.toTid = osGetCurrentTid();
284         thing->i2cAppCbkInfo.cookie = cookie;
285     }
286 
287     return thing;
288 }
289 
osExpApiI2cInternalEvtFreeF(void * evt)290 static void osExpApiI2cInternalEvtFreeF(void *evt)
291 {
292     slabAllocatorFree(mSlabAllocator, evt);
293 }
294 
osExpApiI2cInternalCbk(void * cookie,size_t tx,size_t rx,int err)295 static void osExpApiI2cInternalCbk(void *cookie, size_t tx, size_t rx, int err)
296 {
297     union OsApiSlabItem *thing = (union OsApiSlabItem*)cookie;
298     uint32_t tid;
299 
300     tid = thing->i2cAppCbkInfo.toTid;
301     cookie = thing->i2cAppCbkInfo.cookie;
302 
303     //we reuse the same slab element to send the event now
304     thing->i2cAppCbkEvt.cookie = cookie;
305     thing->i2cAppCbkEvt.tx = tx;
306     thing->i2cAppCbkEvt.rx = rx;
307     thing->i2cAppCbkEvt.err = err;
308 
309     if (!osEnqueuePrivateEvt(EVT_APP_I2C_CBK, &thing->i2cAppCbkEvt, osExpApiI2cInternalEvtFreeF, tid)) {
310         osLog(LOG_WARN, "Failed to send I2C evt to app. This might end badly for the app...");
311         osExpApiI2cInternalEvtFreeF(thing);
312         // TODO: terminate app here: memory pressure is severe
313     }
314 }
315 
osExpApiGpioReq(uintptr_t * retValP,va_list args)316 static void osExpApiGpioReq(uintptr_t *retValP, va_list args)
317 {
318     uint32_t gpioNum = va_arg(args, uint32_t);
319 
320     *retValP = (uintptr_t)gpioRequest(gpioNum);
321 }
322 
osExpApiGpioRel(uintptr_t * retValP,va_list args)323 static void osExpApiGpioRel(uintptr_t *retValP, va_list args)
324 {
325     struct Gpio* gpio = va_arg(args, struct Gpio*);
326 
327     gpioRelease(gpio);
328 }
329 
osExpApiGpioCfgIn(uintptr_t * retValP,va_list args)330 static void osExpApiGpioCfgIn(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 
336     gpioConfigInput(gpio, speed, pullMode);
337 }
338 
osExpApiGpioCfgOut(uintptr_t * retValP,va_list args)339 static void osExpApiGpioCfgOut(uintptr_t *retValP, va_list args)
340 {
341     struct Gpio* gpio = va_arg(args, struct Gpio*);
342     int32_t speed = va_arg(args, int32_t);
343     enum GpioPullMode pullMode = va_arg(args, int);
344     enum GpioOpenDrainMode odrMode = va_arg(args, int);
345     bool value = !!va_arg(args, int);
346 
347     gpioConfigOutput(gpio, speed, pullMode, odrMode, value);
348 }
349 
osExpApiGpioCfgAlt(uintptr_t * retValP,va_list args)350 static void osExpApiGpioCfgAlt(uintptr_t *retValP, va_list args)
351 {
352     struct Gpio* gpio = va_arg(args, struct Gpio*);
353     int32_t speed = va_arg(args, int32_t);
354     enum GpioPullMode pullMode = va_arg(args, int);
355     enum GpioOpenDrainMode odrMode = va_arg(args, int);
356     uint32_t altFunc = va_arg(args, uint32_t);
357 
358     gpioConfigAlt(gpio, speed, pullMode, odrMode, altFunc);
359 }
360 
osExpApiGpioGet(uintptr_t * retValP,va_list args)361 static void osExpApiGpioGet(uintptr_t *retValP, va_list args)
362 {
363     struct Gpio* gpio = va_arg(args, struct Gpio*);
364 
365     *retValP = gpioGet(gpio);
366 }
367 
osExpApiGpioSet(uintptr_t * retValP,va_list args)368 static void osExpApiGpioSet(uintptr_t *retValP, va_list args)
369 {
370     struct Gpio* gpio = va_arg(args, struct Gpio*);
371     bool value = !!va_arg(args, int);
372 
373     gpioSet(gpio, value);
374 }
375 
osExpApiI2cMstReq(uintptr_t * retValP,va_list args)376 static void osExpApiI2cMstReq(uintptr_t *retValP, va_list args)
377 {
378     uint32_t busId = va_arg(args, uint32_t);
379     uint32_t speed = va_arg(args, uint32_t);
380 
381     *retValP = i2cMasterRequest(busId, speed);
382 }
383 
osExpApiI2cMstRel(uintptr_t * retValP,va_list args)384 static void osExpApiI2cMstRel(uintptr_t *retValP, va_list args)
385 {
386     uint32_t busId = va_arg(args, uint32_t);
387 
388     *retValP = i2cMasterRelease(busId);
389 }
390 
osExpApiI2cMstTxRx(uintptr_t * retValP,va_list args)391 static void osExpApiI2cMstTxRx(uintptr_t *retValP, va_list args)
392 {
393     uint32_t busId = va_arg(args, uint32_t);
394     uint32_t addr = va_arg(args, uint32_t);
395     const void *txBuf = va_arg(args, const void*);
396     size_t txSize = va_arg(args, size_t);
397     void *rxBuf = va_arg(args, void*);
398     size_t rxSize = va_arg(args, size_t);
399     (void)va_arg(args, uint32_t); // tid
400     void *cookie = va_arg(args, void *);
401     union OsApiSlabItem *cbkInfo = osExpApiI2cCbkInfoAlloc(cookie);
402 
403     if (!cbkInfo)
404         *retValP =  -ENOMEM;
405 
406     *retValP = i2cMasterTxRx(busId, addr, txBuf, txSize, rxBuf, rxSize, osExpApiI2cInternalCbk, cbkInfo);
407 
408     if (*retValP)
409         slabAllocatorFree(mSlabAllocator, cbkInfo);
410 }
411 
osExpApiI2cSlvReq(uintptr_t * retValP,va_list args)412 static void osExpApiI2cSlvReq(uintptr_t *retValP, va_list args)
413 {
414     uint32_t busId = va_arg(args, uint32_t);
415     uint32_t addr = va_arg(args, uint32_t);
416 
417     *retValP = i2cSlaveRequest(busId, addr);
418 }
419 
osExpApiI2cSlvRel(uintptr_t * retValP,va_list args)420 static void osExpApiI2cSlvRel(uintptr_t *retValP, va_list args)
421 {
422     uint32_t busId = va_arg(args, uint32_t);
423 
424     *retValP = i2cSlaveRelease(busId);
425 }
426 
osExpApiI2cSlvRxEn(uintptr_t * retValP,va_list args)427 static void osExpApiI2cSlvRxEn(uintptr_t *retValP, va_list args)
428 {
429     uint32_t busId = va_arg(args, uint32_t);
430     void *rxBuf = va_arg(args, void*);
431     size_t rxSize = va_arg(args, size_t);
432     (void)va_arg(args, uint32_t); // tid
433     void *cookie = va_arg(args, void *);
434     union OsApiSlabItem *cbkInfo = osExpApiI2cCbkInfoAlloc(cookie);
435 
436     if (!cbkInfo)
437         *retValP =  -ENOMEM;
438 
439     i2cSlaveEnableRx(busId, rxBuf, rxSize, osExpApiI2cInternalCbk, cbkInfo);
440 
441     if (*retValP)
442         slabAllocatorFree(mSlabAllocator, cbkInfo);
443 }
444 
osExpApiI2cSlvTxPre(uintptr_t * retValP,va_list args)445 static void osExpApiI2cSlvTxPre(uintptr_t *retValP, va_list args)
446 {
447     uint32_t busId = va_arg(args, uint32_t);
448     uint8_t byte = va_arg(args, int);
449     (void)va_arg(args, uint32_t); // tid
450     void *cookie = va_arg(args, void *);
451     union OsApiSlabItem *cbkInfo = osExpApiI2cCbkInfoAlloc(cookie);
452 
453     if (!cbkInfo)
454         *retValP =  -ENOMEM;
455 
456     *retValP = i2cSlaveTxPreamble(busId, byte, osExpApiI2cInternalCbk, cbkInfo);
457 
458     if (*retValP)
459         slabAllocatorFree(mSlabAllocator, cbkInfo);
460 }
461 
osExpApiI2cSlvTxPkt(uintptr_t * retValP,va_list args)462 static void osExpApiI2cSlvTxPkt(uintptr_t *retValP, va_list args)
463 {
464     uint32_t busId = va_arg(args, uint32_t);
465     const void *txBuf = va_arg(args, const void*);
466     size_t txSize = va_arg(args, size_t);
467     (void)va_arg(args, uint32_t); // tid
468     void *cookie = va_arg(args, void *);
469     union OsApiSlabItem *cbkInfo = osExpApiI2cCbkInfoAlloc(cookie);
470 
471     if (!cbkInfo)
472         *retValP =  -ENOMEM;
473 
474     *retValP = i2cSlaveTxPacket(busId, txBuf, txSize, osExpApiI2cInternalCbk, cbkInfo);
475 
476     if (*retValP)
477         slabAllocatorFree(mSlabAllocator, cbkInfo);
478 }
479 
osApiExport(struct SlabAllocator * mainSlubAllocator)480 void osApiExport(struct SlabAllocator *mainSlubAllocator)
481 {
482     static const struct SyscallTable osMainEvtqTable = {
483         .numEntries = SYSCALL_OS_MAIN_EVTQ_LAST,
484         .entry = {
485             [SYSCALL_OS_MAIN_EVTQ_SUBCRIBE]        = { .func = osExpApiEvtqSubscribe,   },
486             [SYSCALL_OS_MAIN_EVTQ_UNSUBCRIBE]      = { .func = osExpApiEvtqUnsubscribe, },
487             [SYSCALL_OS_MAIN_EVTQ_ENQUEUE]         = { .func = osExpApiEvtqEnqueue,     },
488             [SYSCALL_OS_MAIN_EVTQ_ENQUEUE_PRIVATE] = { .func = osExpApiEvtqEnqueuePrivate, },
489             [SYSCALL_OS_MAIN_EVTQ_RETAIN_EVT]      = { .func = osExpApiEvtqRetainEvt,      },
490             [SYSCALL_OS_MAIN_EVTQ_FREE_RETAINED]   = { .func = osExpApiEvtqFreeRetained,   },
491         },
492     };
493 
494     static const struct SyscallTable osMainLogTable = {
495         .numEntries = SYSCALL_OS_MAIN_LOG_LAST,
496         .entry = {
497             [SYSCALL_OS_MAIN_LOG_LOGV]   = { .func = osExpApiLogLogv,   },
498         },
499     };
500 
501     static const struct SyscallTable osMainSensorsTable = {
502         .numEntries = SYSCALL_OS_MAIN_SENSOR_LAST,
503         .entry = {
504             [SYSCALL_OS_MAIN_SENSOR_SIGNAL]        = { .func = osExpApiSensorSignal,  },
505             [SYSCALL_OS_MAIN_SENSOR_REG]           = { .func = osExpApiSensorReg,     },
506             [SYSCALL_OS_MAIN_SENSOR_UNREG]         = { .func = osExpApiSensorUnreg,   },
507             [SYSCALL_OS_MAIN_SENSOR_REG_INIT_COMP] = { .func = osExpApiSensorRegInitComp },
508             [SYSCALL_OS_MAIN_SENSOR_FIND]          = { .func = osExpApiSensorFind,    },
509             [SYSCALL_OS_MAIN_SENSOR_REQUEST]       = { .func = osExpApiSensorReq,     },
510             [SYSCALL_OS_MAIN_SENSOR_RATE_CHG]      = { .func = osExpApiSensorRateChg, },
511             [SYSCALL_OS_MAIN_SENSOR_RELEASE]       = { .func = osExpApiSensorRel,     },
512             [SYSCALL_OS_MAIN_SENSOR_TRIGGER]       = { .func = osExpApiSensorTrigger, },
513             [SYSCALL_OS_MAIN_SENSOR_GET_RATE]      = { .func = osExpApiSensorGetRate, },
514             [SYSCALL_OS_MAIN_SENSOR_GET_TIME]      = { .func = osExpApiSensorGetTime, },
515 
516         },
517     };
518 
519     static const struct SyscallTable osMainTimerTable = {
520         .numEntries = SYSCALL_OS_MAIN_TIME_LAST,
521         .entry = {
522             [SYSCALL_OS_MAIN_TIME_GET_TIME]     = { .func = osExpApiTimGetTime,  },
523             [SYSCALL_OS_MAIN_TIME_SET_TIMER]    = { .func = osExpApiTimSetTimer,     },
524             [SYSCALL_OS_MAIN_TIME_CANCEL_TIMER] = { .func = osExpApiTimCancelTimer,   },
525         },
526     };
527 
528     static const struct SyscallTable osMainHeapTable = {
529         .numEntries = SYSCALL_OS_MAIN_HEAP_LAST,
530         .entry = {
531             [SYSCALL_OS_MAIN_HEAP_ALLOC] = { .func = osExpApiHeapAlloc },
532             [SYSCALL_OS_MAIN_HEAP_FREE]  = { .func = osExpApiHeapFree },
533         },
534     };
535 
536     static const struct SyscallTable osMainSlabTable = {
537         .numEntries = SYSCALL_OS_MAIN_SLAB_LAST,
538         .entry = {
539             [SYSCALL_OS_MAIN_SLAB_NEW]     = { .func = osExpApiSlabNew },
540             [SYSCALL_OS_MAIN_SLAB_DESTROY] = { .func = osExpApiSlabDestroy },
541             [SYSCALL_OS_MAIN_SLAB_ALLOC]   = { .func = osExpApiSlabAlloc },
542             [SYSCALL_OS_MAIN_SLAB_FREE]    = { .func = osExpApiSlabFree },
543         },
544     };
545 
546     static const struct SyscallTable osMainHostTable = {
547         .numEntries = SYSCALL_OS_MAIN_HOST_LAST,
548         .entry = {
549             [SYSCALL_OS_MAIN_HOST_GET_TIME] = { .func = osExpApiHostGetTime },
550         },
551     };
552 
553     static const struct SyscallTable osMainRtcTable = {
554         .numEntries = SYSCALL_OS_MAIN_RTC_LAST,
555         .entry = {
556             [SYSCALL_OS_MAIN_RTC_GET_TIME] = { .func = osExpApiRtcGetTime },
557         },
558     };
559 
560     static const struct SyscallTable osMainTable = {
561         .numEntries = SYSCALL_OS_MAIN_LAST,
562         .entry = {
563             [SYSCALL_OS_MAIN_EVENTQ]  = { .subtable = (struct SyscallTable*)&osMainEvtqTable,    },
564             [SYSCALL_OS_MAIN_LOGGING] = { .subtable = (struct SyscallTable*)&osMainLogTable,     },
565             [SYSCALL_OS_MAIN_SENSOR]  = { .subtable = (struct SyscallTable*)&osMainSensorsTable, },
566             [SYSCALL_OS_MAIN_TIME]    = { .subtable = (struct SyscallTable*)&osMainTimerTable,   },
567             [SYSCALL_OS_MAIN_HEAP]    = { .subtable = (struct SyscallTable*)&osMainHeapTable,    },
568             [SYSCALL_OS_MAIN_SLAB]    = { .subtable = (struct SyscallTable*)&osMainSlabTable,    },
569             [SYSCALL_OS_MAIN_HOST]    = { .subtable = (struct SyscallTable*)&osMainHostTable,    },
570             [SYSCALL_OS_MAIN_RTC]     = { .subtable = (struct SyscallTable*)&osMainRtcTable,     },
571         },
572     };
573 
574     static const struct SyscallTable osDrvGpioTable = {
575         .numEntries = SYSCALL_OS_DRV_GPIO_LAST,
576         .entry = {
577             [SYSCALL_OS_DRV_GPIO_REQ]     = { .func = osExpApiGpioReq,    },
578             [SYSCALL_OS_DRV_GPIO_REL]     = { .func = osExpApiGpioRel,    },
579             [SYSCALL_OS_DRV_GPIO_CFG_IN]  = { .func = osExpApiGpioCfgIn,  },
580             [SYSCALL_OS_DRV_GPIO_CFG_OUT] = { .func = osExpApiGpioCfgOut, },
581             [SYSCALL_OS_DRV_GPIO_CFG_ALT] = { .func = osExpApiGpioCfgAlt, },
582             [SYSCALL_OS_DRV_GPIO_GET]     = { .func = osExpApiGpioGet,    },
583             [SYSCALL_OS_DRV_GPIO_SET]     = { .func = osExpApiGpioSet,    },
584         },
585     };
586 
587     static const struct SyscallTable osGrvI2cMstTable = {
588         .numEntries = SYSCALL_OS_DRV_I2CM_LAST,
589         .entry = {
590             [SYSCALL_OS_DRV_I2CM_REQ]  = { .func = osExpApiI2cMstReq,  },
591             [SYSCALL_OS_DRV_I2CM_REL]  = { .func = osExpApiI2cMstRel,  },
592             [SYSCALL_OS_DRV_I2CM_TXRX] = { .func = osExpApiI2cMstTxRx, },
593         },
594     };
595 
596     static const struct SyscallTable osGrvI2cSlvTable = {
597         .numEntries = SYSCALL_OS_DRV_I2CS_LAST,
598         .entry = {
599             [ SYSCALL_OS_DRV_I2CS_REQ]    = { .func = osExpApiI2cSlvReq,   },
600             [ SYSCALL_OS_DRV_I2CS_REL]    = { .func = osExpApiI2cSlvRel,   },
601             [ SYSCALL_OS_DRV_I2CS_RX_EN]  = { .func = osExpApiI2cSlvRxEn,  },
602             [ SYSCALL_OS_DRV_I2CS_TX_PRE] = { .func = osExpApiI2cSlvTxPre, },
603             [ SYSCALL_OS_DRV_I2CS_TX_PKT] = { .func = osExpApiI2cSlvTxPkt, },
604         },
605     };
606 
607     static const struct SyscallTable osDriversTable = {
608         .numEntries = SYSCALL_OS_DRV_LAST,
609         .entry = {
610             [SYSCALL_OS_DRV_GPIO]       = { .subtable = (struct SyscallTable*)&osDrvGpioTable,   },
611             [SYSCALL_OS_DRV_I2C_MASTER] = { .subtable = (struct SyscallTable*)&osGrvI2cMstTable, },
612             [SYSCALL_OS_DRV_I2C_SLAVE]  = { .subtable = (struct SyscallTable*)&osGrvI2cSlvTable, },
613         },
614     };
615 
616     static const struct SyscallTable osTable = {
617         .numEntries = SYSCALL_OS_LAST,
618         .entry = {
619             [SYSCALL_OS_MAIN]    = { .subtable = (struct SyscallTable*)&osMainTable,    },
620             [SYSCALL_OS_DRIVERS] = { .subtable = (struct SyscallTable*)&osDriversTable, },
621         },
622     };
623 
624     if (!syscallAddTable(SYSCALL_NO(SYSCALL_DOMAIN_OS,0,0,0), 1, (struct SyscallTable*)&osTable))
625         osLog(LOG_ERROR, "Failed to export OS base API");
626 }
627