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 <stdarg.h> 18 #include <stdbool.h> 19 #include <stdint.h> 20 #include <stdlib.h> 21 #include <string.h> 22 23 #include <cpu.h> 24 #include <cpu/cpuMath.h> 25 #include <heap.h> 26 #include <sensors.h> 27 #include <sensors_priv.h> 28 #include <seos.h> 29 #include <seos_priv.h> 30 #include <syscall.h> 31 #include <timer.h> 32 #include <util.h> 33 #include <printf.h> 34 35 #include <chre.h> 36 #include <chreApi.h> 37 38 #define MINIMUM_INTERVAL_DEFAULT_HZ SENSOR_HZ(1.0f) 39 40 /* 41 * This is to ensure that message size and some extra headers will stay representable with 1 byte 42 * Code relies on that in many places. 43 */ 44 C_STATIC_ASSERT(max_chre_msg_size, CHRE_MESSAGE_TO_HOST_MAX_SIZE <= 240); 45 46 /* 47 * Many syscalls rely on the property that uintptr_t can hold uint32_t without data loss 48 * This is enforced by static assertion in chreApi.h 49 * None of the methods returning uint32_t are cast to uintptr_t 50 * This is done in order to let compiler warn us if our assumption is not safe for some reason 51 */ 52 53 static inline uint64_t osChreGetAppId(void) 54 { 55 struct Task *task = osGetCurrentTask(); 56 const struct AppHdr *app = task ? task->app : NULL; 57 58 return app ? app->hdr.appId : 0; 59 } 60 61 static void osChreApiGetAppId(uintptr_t *retValP, va_list args) 62 { 63 uint64_t *appId = va_arg(args, uint64_t *); 64 if (appId) 65 *appId = osChreGetAppId(); 66 } 67 68 static void osChreApiGetInstanceId(uintptr_t *retValP, va_list args) 69 { 70 *retValP = osGetCurrentTid(); 71 } 72 73 static void osChreApiLogLogv(uintptr_t *retValP, va_list args) 74 { 75 va_list innerArgs; 76 enum chreLogLevel level = va_arg(args, int /* enums promoted to ints in va_args in C */); 77 const static char levels[] = "EWIDV"; 78 char clevel = (level > CHRE_LOG_DEBUG || level < 0) ? 'V' : levels[level]; 79 const char *str = va_arg(args, const char*); 80 uintptr_t inner = va_arg(args, uintptr_t); 81 82 va_copy(innerArgs, INTEGER_TO_VA_LIST(inner)); 83 osLogv(clevel, PRINTF_FLAG_CHRE, str, innerArgs); 84 va_end(innerArgs); 85 } 86 87 static void osChreApiLogLogvOld(uintptr_t *retValP, va_list args) 88 { 89 va_list innerArgs; 90 enum chreLogLevel level = va_arg(args, int /* enums promoted to ints in va_args in C */); 91 const static char levels[] = "EWIDV"; 92 char clevel = (level > CHRE_LOG_DEBUG || level < 0) ? 'V' : levels[level]; 93 const char *str = va_arg(args, const char*); 94 uintptr_t inner = va_arg(args, uintptr_t); 95 96 va_copy(innerArgs, INTEGER_TO_VA_LIST(inner)); 97 osLogv(clevel, PRINTF_FLAG_CHRE | PRINTF_FLAG_SHORT_DOUBLE, str, innerArgs); 98 va_end(innerArgs); 99 } 100 101 static void osChreApiGetTime(uintptr_t *retValP, va_list args) 102 { 103 uint64_t *timeNanos = va_arg(args, uint64_t *); 104 if (timeNanos) 105 *timeNanos = sensorGetTime(); 106 } 107 108 static inline uint32_t osChreTimerSet(uint64_t duration, const void* cookie, bool oneShot) 109 { 110 uint32_t timId = timTimerSetNew(duration, cookie, oneShot); 111 112 return timId == 0 ? CHRE_TIMER_INVALID : timId; 113 } 114 115 static void osChreApiTimerSet(uintptr_t *retValP, va_list args) 116 { 117 uint32_t length_lo = va_arg(args, uint32_t); 118 uint32_t length_hi = va_arg(args, uint32_t); 119 void *cookie = va_arg(args, void *); 120 bool oneshot = va_arg(args, int); 121 uint64_t length = (((uint64_t)length_hi) << 32) | length_lo; 122 123 *retValP = osChreTimerSet(length, cookie, oneshot); 124 } 125 126 static void osChreApiTimerCancel(uintptr_t *retValP, va_list args) 127 { 128 uint32_t timerId = va_arg(args, uint32_t); 129 *retValP = timTimerCancelEx(timerId, true); 130 } 131 132 static inline void osChreAbort(uint32_t abortCode) 133 { 134 struct Task *task = osGetCurrentTask(); 135 osLog(LOG_ERROR, "APP ID=0x%" PRIX64 " TID=0x%" PRIX16 " aborted [code 0x%" PRIX32 "]", 136 task->app->hdr.appId, task->tid, abortCode); 137 osTaskAbort(task); 138 } 139 140 static void osChreApiAbort(uintptr_t *retValP, va_list args) 141 { 142 uint32_t code = va_arg(args, uint32_t); 143 osChreAbort(code); 144 } 145 146 static void osChreApiHeapAlloc(uintptr_t *retValP, va_list args) 147 { 148 uint32_t size = va_arg(args, uint32_t); 149 *retValP = (uintptr_t)heapAlloc(size); 150 } 151 152 static void osChreApiHeapFree(uintptr_t *retValP, va_list args) 153 { 154 void *ptr = va_arg(args, void *); 155 heapFree(ptr); 156 } 157 158 /* 159 * we have no way to verify if this is a CHRE event; just trust the caller to do the right thing 160 */ 161 void osChreFreeEvent(uint32_t tid, chreEventCompleteFunction *cbFreeEvt, uint32_t evtType, void * evtData) 162 { 163 struct Task *chreTask = osTaskFindByTid(tid); 164 struct Task *preempted = osSetCurrentTask(chreTask); 165 if (chreTask && osTaskIsChre(chreTask)) 166 osTaskInvokeEventFreeCallback(chreTask, cbFreeEvt, evtType, evtData); 167 osSetCurrentTask(preempted); 168 } 169 170 static bool osChreSendEvent(uint16_t evtType, void *evtData, 171 chreEventCompleteFunction *evtFreeCallback, 172 uint32_t toTid) 173 { 174 /* 175 * this primitive may only be used for USER CHRE events; 176 * system events come from the OS itself through different path, 177 * and are interpreted by the CHRE app compatibility library. 178 * therefore, we have to enforce the evtType >= CHRE_EVENT_FIRST_USER_VALUE. 179 */ 180 if (evtType < CHRE_EVENT_FIRST_USER_VALUE) { 181 osChreFreeEvent(osGetCurrentTid(), evtFreeCallback, evtType, evtData); 182 return false; 183 } 184 return osEnqueuePrivateEvtNew(evtType, evtData, evtFreeCallback, toTid); 185 } 186 187 static void osChreApiSendEvent(uintptr_t *retValP, va_list args) 188 { 189 uint16_t evtType = va_arg(args, uint32_t); // stored as 32-bit 190 void *evtData = va_arg(args, void *); 191 chreEventCompleteFunction *freeCallback = va_arg(args, chreEventCompleteFunction *); 192 uint32_t toTid = va_arg(args, uint32_t); 193 *retValP = osChreSendEvent(evtType, evtData, freeCallback, toTid); 194 } 195 196 static bool osChreSendMessageToHost(void *message, uint32_t messageSize, 197 uint32_t reservedMessageType, 198 chreMessageFreeFunction *freeCallback) 199 { 200 bool result = false; 201 struct HostHubRawPacket *hostMsg = NULL; 202 203 if (messageSize > CHRE_MESSAGE_TO_HOST_MAX_SIZE || (messageSize && !message)) 204 goto out; 205 206 hostMsg = heapAlloc(sizeof(*hostMsg) + messageSize); 207 if (!hostMsg) 208 goto out; 209 210 if (messageSize) 211 memcpy(hostMsg+1, message, messageSize); 212 213 hostMsg->appId = osChreGetAppId(); 214 hostMsg->dataLen = messageSize; 215 result = osEnqueueEvtOrFree(EVT_APP_TO_HOST, hostMsg, heapFree); 216 217 out: 218 if (freeCallback) 219 osTaskInvokeMessageFreeCallback(osGetCurrentTask(), freeCallback, message, messageSize); 220 return result; 221 } 222 223 static void osChreApiSendMessageToHost(uintptr_t *retValP, va_list args) 224 { 225 void *message = va_arg(args, void *); 226 uint32_t messageSize = va_arg(args, uint32_t); 227 uint32_t reservedMessageType = va_arg(args, uint32_t); 228 chreMessageFreeFunction *freeCallback = va_arg(args, chreMessageFreeFunction *); 229 230 *retValP = osChreSendMessageToHost(message, messageSize, reservedMessageType, freeCallback); 231 } 232 233 static bool osChreSensorFindDefault(uint8_t sensorType, uint32_t *pHandle) 234 { 235 if (!pHandle) 236 return false; 237 238 const struct SensorInfo *info = sensorFind(sensorType, 0, pHandle); 239 240 return info != NULL; 241 } 242 243 static void osChreApiSensorFindDefault(uintptr_t *retValP, va_list args) 244 { 245 uint8_t sensorType = va_arg(args, uint32_t); 246 uint32_t *pHandle = va_arg(args, uint32_t *); 247 *retValP = osChreSensorFindDefault(sensorType, pHandle); 248 } 249 250 static bool osChreSensorGetInfo(uint32_t sensorHandle, struct chreSensorInfo *info) 251 { 252 struct Sensor *s = sensorFindByHandle(sensorHandle); 253 if (!s || !info) 254 return false; 255 const struct SensorInfo *si = s->si; 256 info->sensorName = si->sensorName; 257 info->sensorType = si->sensorType; 258 info->unusedFlags = 0; 259 260 if (si->sensorType == CHRE_SENSOR_TYPE_INSTANT_MOTION_DETECT 261 || si->sensorType == CHRE_SENSOR_TYPE_STATIONARY_DETECT) 262 info->isOneShot = true; 263 else 264 info->isOneShot = false; 265 info->isOnChange = s->hasOnchange; 266 267 return true; 268 } 269 270 static void osChreApiSensorGetInfo(uintptr_t *retValP, va_list args) 271 { 272 uint32_t sensorHandle = va_arg(args, uint32_t); 273 struct chreSensorInfo *info = va_arg(args, struct chreSensorInfo *); 274 *retValP = osChreSensorGetInfo(sensorHandle, info); 275 } 276 277 static bool osChreSensorGetSamplingStatus(uint32_t sensorHandle, 278 struct chreSensorSamplingStatus *status) 279 { 280 struct Sensor *s = sensorFindByHandle(sensorHandle); 281 if (!s || !status) 282 return false; 283 284 if (s->currentRate == SENSOR_RATE_OFF 285 || s->currentRate >= SENSOR_RATE_POWERING_ON) { 286 status->enabled = 0; 287 status->interval = 0; 288 status->latency = 0; 289 } else { 290 status->enabled = true; 291 if (s->currentRate == SENSOR_RATE_ONDEMAND 292 || s->currentRate == SENSOR_RATE_ONCHANGE 293 || s->currentRate == SENSOR_RATE_ONESHOT) 294 status->interval = CHRE_SENSOR_INTERVAL_DEFAULT; 295 else 296 status->interval = (UINT32_C(1024000000) / s->currentRate) * UINT64_C(1000); 297 298 if (s->currentLatency == SENSOR_LATENCY_NODATA) 299 status->latency = CHRE_SENSOR_INTERVAL_DEFAULT; 300 else 301 status->latency = s->currentLatency; 302 } 303 304 return true; 305 } 306 307 static void osChreApiSensorGetStatus(uintptr_t *retValP, va_list args) 308 { 309 uint32_t sensorHandle = va_arg(args, uint32_t); 310 struct chreSensorSamplingStatus *status = va_arg(args, struct chreSensorSamplingStatus *); 311 *retValP = osChreSensorGetSamplingStatus(sensorHandle, status); 312 } 313 314 static bool osChreSensorConfigure(uint32_t sensorHandle, 315 enum chreSensorConfigureMode mode, 316 uint64_t interval, uint64_t latency) 317 { 318 uint32_t rate, interval_us; 319 bool ret; 320 struct Sensor *s = sensorFindByHandle(sensorHandle); 321 int i; 322 if (!s) 323 return false; 324 325 if (mode & CHRE_SENSOR_CONFIGURE_RAW_POWER_ON) { 326 if (interval == CHRE_SENSOR_INTERVAL_DEFAULT) { 327 // use first rate in supported rates list > minimum (if avaliable) 328 const struct SensorInfo *si = s->si; 329 if (!si) 330 return false; 331 332 if (!si->supportedRates || si->supportedRates[0] == 0) 333 rate = SENSOR_RATE_ONCHANGE; 334 else { 335 for (i = 0; si->supportedRates[i] != 0; i++) { 336 rate = si->supportedRates[i]; 337 if (rate >= MINIMUM_INTERVAL_DEFAULT_HZ) 338 break; 339 } 340 } 341 } else { 342 interval_us = U64_DIV_BY_CONST_U16(interval, 1000); 343 rate = UINT32_C(1024000000) / interval_us; 344 } 345 if (!rate) // 0 is a reserved value. minimum is 1 346 rate = 1; 347 if (latency == CHRE_SENSOR_LATENCY_DEFAULT) 348 latency = 0ULL; 349 if (sensorGetReqRate(sensorHandle) == SENSOR_RATE_OFF) { 350 if ((ret = sensorRequest(0, sensorHandle, rate, latency))) { 351 if (!(ret = osEventsSubscribe(2, sensorGetMyEventType(s->si->sensorType), sensorGetMyCfgEventType(s->si->sensorType)))) 352 sensorRelease(0, sensorHandle); 353 } 354 } else { 355 ret = sensorRequestRateChange(0, sensorHandle, rate, latency); 356 } 357 } else if (mode & (CHRE_SENSOR_CONFIGURE_RAW_REPORT_CONTINUOUS|CHRE_SENSOR_CONFIGURE_RAW_REPORT_ONE_SHOT)) { 358 if (interval != CHRE_SENSOR_INTERVAL_DEFAULT 359 || latency != CHRE_SENSOR_LATENCY_DEFAULT) 360 ret = false; 361 else if (sensorGetReqRate(sensorHandle) == SENSOR_RATE_OFF) 362 ret = osEventsSubscribe(2, sensorGetMyEventType(s->si->sensorType), sensorGetMyCfgEventType(s->si->sensorType)); 363 else 364 ret = true; 365 } else { 366 if (sensorGetReqRate(sensorHandle) != SENSOR_RATE_OFF) { 367 if ((ret = sensorRelease(0, sensorHandle))) 368 ret = osEventsUnsubscribe(2, sensorGetMyEventType(s->si->sensorType), sensorGetMyCfgEventType(s->si->sensorType)); 369 } else { 370 ret = osEventsUnsubscribe(2, sensorGetMyEventType(s->si->sensorType), sensorGetMyCfgEventType(s->si->sensorType)); 371 } 372 } 373 374 return ret; 375 } 376 377 static void osChreApiSensorConfig(uintptr_t *retValP, va_list args) 378 { 379 uint32_t sensorHandle = va_arg(args, uint32_t); 380 enum chreSensorConfigureMode mode = va_arg(args, int); 381 uint64_t interval = va_arg(args, uint32_t); 382 uint32_t interval_hi = va_arg(args, uint32_t); 383 uint64_t latency = va_arg(args, uint32_t); 384 uint32_t latency_hi = va_arg(args, uint32_t); 385 386 interval |= ((uint64_t)interval_hi) << 32; 387 latency |= ((uint64_t)latency_hi) << 32; 388 389 *retValP = osChreSensorConfigure(sensorHandle, mode, interval, latency); 390 } 391 392 static uint32_t osChreGetApiVersion(void) 393 { 394 return CHRE_API_VERSION; 395 } 396 397 static void osChreApiChreApiVersion(uintptr_t *retValP, va_list args) 398 { 399 *retValP = osChreGetApiVersion(); 400 } 401 402 static uint32_t osChreGetVersion(void) 403 { 404 return CHRE_API_VERSION | NANOHUB_OS_PATCH_LEVEL; 405 } 406 407 static void osChreApiChreOsVersion(uintptr_t *retValP, va_list args) 408 { 409 *retValP = (uintptr_t)osChreGetVersion(); 410 } 411 412 static uint64_t osChreGetPlatformId(void) 413 { 414 return HW_ID_MAKE(NANOHUB_VENDOR_GOOGLE, 0); 415 } 416 417 static void osChreApiPlatformId(uintptr_t *retValP, va_list args) 418 { 419 uint64_t *pHwId = va_arg(args, uint64_t*); 420 if (pHwId) 421 *pHwId = osChreGetPlatformId(); 422 } 423 424 static const struct SyscallTable chreMainApiTable = { 425 .numEntries = SYSCALL_CHRE_MAIN_API_LAST, 426 .entry = { 427 [SYSCALL_CHRE_MAIN_API_LOG_OLD] = { .func = osChreApiLogLogvOld }, 428 [SYSCALL_CHRE_MAIN_API_LOG] = { .func = osChreApiLogLogv }, 429 [SYSCALL_CHRE_MAIN_API_GET_APP_ID] = { .func = osChreApiGetAppId }, 430 [SYSCALL_CHRE_MAIN_API_GET_INST_ID] = { .func = osChreApiGetInstanceId }, 431 [SYSCALL_CHRE_MAIN_API_GET_TIME] = { .func = osChreApiGetTime }, 432 [SYSCALL_CHRE_MAIN_API_TIMER_SET] = { .func = osChreApiTimerSet }, 433 [SYSCALL_CHRE_MAIN_API_TIMER_CANCEL] = { .func = osChreApiTimerCancel }, 434 [SYSCALL_CHRE_MAIN_API_ABORT] = { .func = osChreApiAbort }, 435 [SYSCALL_CHRE_MAIN_API_HEAP_ALLOC] = { .func = osChreApiHeapAlloc }, 436 [SYSCALL_CHRE_MAIN_API_HEAP_FREE] = { .func = osChreApiHeapFree }, 437 [SYSCALL_CHRE_MAIN_API_SEND_EVENT] = { .func = osChreApiSendEvent }, 438 [SYSCALL_CHRE_MAIN_API_SEND_MSG] = { .func = osChreApiSendMessageToHost }, 439 [SYSCALL_CHRE_MAIN_API_SENSOR_FIND_DEFAULT] = { .func = osChreApiSensorFindDefault }, 440 [SYSCALL_CHRE_MAIN_API_SENSOR_GET_INFO] = { .func = osChreApiSensorGetInfo }, 441 [SYSCALL_CHRE_MAIN_API_SENSOR_GET_STATUS] = { .func = osChreApiSensorGetStatus }, 442 [SYSCALL_CHRE_MAIN_API_SENSOR_CONFIG] = { .func = osChreApiSensorConfig }, 443 [SYSCALL_CHRE_MAIN_API_GET_OS_API_VERSION] = { .func = osChreApiChreApiVersion }, 444 [SYSCALL_CHRE_MAIN_API_GET_OS_VERSION] = { .func = osChreApiChreOsVersion }, 445 [SYSCALL_CHRE_MAIN_API_GET_PLATFORM_ID] = { .func = osChreApiPlatformId }, 446 }, 447 }; 448 449 static const struct SyscallTable chreMainTable = { 450 .numEntries = SYSCALL_CHRE_MAIN_LAST, 451 .entry = { 452 [SYSCALL_CHRE_MAIN_API] = { .subtable = (struct SyscallTable*)&chreMainApiTable, }, 453 }, 454 }; 455 456 static const struct SyscallTable chreTable = { 457 .numEntries = SYSCALL_CHRE_LAST, 458 .entry = { 459 [SYSCALL_CHRE_MAIN] = { .subtable = (struct SyscallTable*)&chreMainTable, }, 460 }, 461 }; 462 463 void osChreApiExport() 464 { 465 if (!syscallAddTable(SYSCALL_NO(SYSCALL_DOMAIN_CHRE,0,0,0), 1, (struct SyscallTable*)&chreTable)) 466 osLog(LOG_ERROR, "Failed to export CHRE OS API"); 467 } 468