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 
osExpApiEvtqSubscribe(uintptr_t * retValP,va_list args)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 
osExpApiEvtqUnsubscribe(uintptr_t * retValP,va_list args)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 
osExpApiEvtqEnqueue(uintptr_t * retValP,va_list args)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 
osExpApiEvtqEnqueuePrivate(uintptr_t * retValP,va_list args)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 
osExpApiEvtqRetainEvt(uintptr_t * retValP,va_list args)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 
osExpApiEvtqFreeRetained(uintptr_t * retValP,va_list args)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 
osExpApiLogLogv(uintptr_t * retValP,va_list args)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 
osExpApiSensorSignal(uintptr_t * retValP,va_list args)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 
osExpApiSensorReg(uintptr_t * retValP,va_list args)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 
osExpApiSensorUnreg(uintptr_t * retValP,va_list args)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 
osExpApiSensorRegInitComp(uintptr_t * retValP,va_list args)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 
osExpApiSensorFind(uintptr_t * retValP,va_list args)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 
osExpApiSensorReq(uintptr_t * retValP,va_list args)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 
osExpApiSensorRateChg(uintptr_t * retValP,va_list args)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 
osExpApiSensorRel(uintptr_t * retValP,va_list args)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 
osExpApiSensorTrigger(uintptr_t * retValP,va_list args)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 
osExpApiSensorGetCurRate(uintptr_t * retValP,va_list args)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 
osExpApiSensorGetTime(uintptr_t * retValP,va_list args)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 
osExpApiSensorGetReqRate(uintptr_t * retValP,va_list args)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 
osExpApiTimGetTime(uintptr_t * retValP,va_list args)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 
osExpApiTimSetTimer(uintptr_t * retValP,va_list args)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 
osExpApiTimCancelTimer(uintptr_t * retValP,va_list args)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 
osExpApiHeapAlloc(uintptr_t * retValP,va_list args)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 
osExpApiHeapFree(uintptr_t * retValP,va_list args)236 static void osExpApiHeapFree(uintptr_t *retValP, va_list args)
237 {
238     void *mem = va_arg(args, void *);
239 
240     heapFree(mem);
241 }
242 
osExpApiSlabNew(uintptr_t * retValP,va_list args)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 
osExpApiSlabDestroy(uintptr_t * retValP,va_list args)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 
osExpApiSlabAlloc(uintptr_t * retValP,va_list args)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 
osExpApiSlabFree(uintptr_t * retValP,va_list args)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 
osExpApiHostGetTime(uintptr_t * retValP,va_list args)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 
osExpApiRtcGetTime(uintptr_t * retValP,va_list args)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 
osExpApiI2cCbkInfoAlloc(void * cookie)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 
osExpApiI2cInternalEvtFreeF(void * evt)298 static void osExpApiI2cInternalEvtFreeF(void *evt)
299 {
300     slabAllocatorFree(mSlabAllocator, evt);
301 }
302 
osExpApiI2cInternalCbk(void * cookie,size_t tx,size_t rx,int err)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 
osExpApiGpioReq(uintptr_t * retValP,va_list args)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 
osExpApiGpioRel(uintptr_t * retValP,va_list args)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 
osExpApiGpioCfgIn(uintptr_t * retValP,va_list args)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 
osExpApiGpioCfgOut(uintptr_t * retValP,va_list args)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 
osExpApiGpioCfgAlt(uintptr_t * retValP,va_list args)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 
osExpApiGpioGet(uintptr_t * retValP,va_list args)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 
osExpApiGpioSet(uintptr_t * retValP,va_list args)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 
osExpApiI2cMstReq(uintptr_t * retValP,va_list args)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 
osExpApiI2cMstRel(uintptr_t * retValP,va_list args)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 
osExpApiI2cMstTxRx(uintptr_t * retValP,va_list args)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 
osExpApiI2cSlvReq(uintptr_t * retValP,va_list args)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 
osExpApiI2cSlvRel(uintptr_t * retValP,va_list args)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 
osExpApiI2cSlvRxEn(uintptr_t * retValP,va_list args)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 
osExpApiI2cSlvTxPre(uintptr_t * retValP,va_list args)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 
osExpApiI2cSlvTxPkt(uintptr_t * retValP,va_list args)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 
osApiExport(struct SlabAllocator * mainSlubAllocator)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