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 <inttypes.h> 18 #include <stdarg.h> 19 #include <stdlib.h> 20 #include <string.h> 21 22 #include <plat/eeData.h> 23 #include <plat/plat.h> 24 #include <plat/wdt.h> 25 26 #include <apInt.h> 27 #include <atomic.h> 28 #include <bl.h> 29 #include <cpu.h> 30 #include <crc.h> 31 #include <eventQ.h> 32 #include <heap.h> 33 #include <hostIntf.h> 34 #include <mpu.h> 35 #include <nanohubPacket.h> 36 #include <osApi.h> 37 #include <platform.h> 38 #include <printf.h> 39 #include <sensors.h> 40 #include <seos.h> 41 #include <seos_priv.h> 42 #include <slab.h> 43 #include <syscall.h> 44 #include <timer.h> 45 #include <util.h> 46 47 #include <nanohub/nanohub.h> 48 49 #include <chreApi.h> 50 51 struct TaskPool { 52 struct Task data[MAX_TASKS]; 53 }; 54 55 static struct TaskPool mTaskPool; 56 static struct EvtQueue *mEvtsInternal; 57 static struct SlabAllocator* mMiscInternalThingsSlab; 58 static struct TaskList mFreeTasks; 59 static struct TaskList mTasks; 60 static struct Task *mCurrentTask; 61 static struct Task *mSystemTask; 62 static TaggedPtr *mCurEvtEventFreeingInfo = NULL; //used as flag for retaining. NULL when none or already retained 63 64 static inline void list_init(struct TaskList *l) 65 { 66 l->prev = l->next = NO_NODE; 67 } 68 69 struct Task *osGetCurrentTask() 70 { 71 return mCurrentTask; 72 } 73 74 struct Task *osSetCurrentTask(struct Task *task) 75 { 76 struct Task *old = mCurrentTask; 77 while (true) { 78 old = mCurrentTask; 79 if (atomicCmpXchgPtr((uintptr_t*)&mCurrentTask, (uintptr_t)old, (uintptr_t)task)) { 80 break; 81 } 82 } 83 return old; 84 } 85 86 // beyond this point, noone shall access mCurrentTask directly 87 88 static inline bool osTaskTestFlags(struct Task *task, uint32_t mask) 89 { 90 return (atomicReadByte(&task->flags) & mask) != 0; 91 } 92 93 bool osAppIsChre(uint16_t tid) 94 { 95 struct Task *task = osTaskFindByTid(tid); 96 97 return task && osTaskIsChre(task); 98 } 99 100 uint32_t osAppChreVersion(uint16_t tid) 101 { 102 struct Task *task = osTaskFindByTid(tid); 103 104 if (task) 105 return osTaskChreVersion(task); 106 else 107 return 0; 108 } 109 110 static inline uint32_t osTaskClrSetFlags(struct Task *task, uint32_t clrMask, uint32_t setMask) 111 { 112 while (true) { 113 uint8_t flags = atomicReadByte(&task->flags); 114 uint8_t newFlags = (flags & ~clrMask) | setMask; 115 if (atomicCmpXchgByte(&task->flags, flags, newFlags)) 116 return newFlags; 117 } 118 } 119 120 static inline uint32_t osTaskAddIoCount(struct Task *task, int32_t delta) 121 { 122 uint8_t count = atomicAddByte(&task->ioCount, delta); 123 124 count += delta; // old value is returned, so we add it again 125 126 return count; 127 } 128 129 static inline uint32_t osTaskGetIoCount(struct Task *task) 130 { 131 return atomicReadByte(&task->ioCount); 132 } 133 134 uint8_t osTaskIndex(struct Task *task) 135 { 136 // we don't need signed diff here: this way we simplify boundary check 137 size_t idx = task - &mTaskPool.data[0]; 138 return idx >= MAX_TASKS || &mTaskPool.data[idx] != task ? NO_NODE : idx; 139 } 140 141 static inline struct Task *osTaskByIdx(size_t idx) 142 { 143 return idx >= MAX_TASKS ? NULL : &mTaskPool.data[idx]; 144 } 145 146 uint32_t osGetCurrentTid() 147 { 148 struct Task *task = osGetCurrentTask(); 149 if (task == NULL) { 150 return UINT32_MAX; 151 } 152 return task->tid; 153 } 154 155 uint32_t osSetCurrentTid(uint32_t tid) 156 { 157 struct Task *task = osTaskByIdx(TID_TO_TASK_IDX(tid)); 158 159 if (task && task->tid == tid) { 160 struct Task *preempted = osSetCurrentTask(task); 161 return preempted->tid; 162 } 163 164 return osGetCurrentTid(); 165 } 166 167 static inline struct Task *osTaskListPeekHead(struct TaskList *listHead) 168 { 169 TaskIndex idx = listHead->next; 170 return idx == NO_NODE ? NULL : &mTaskPool.data[idx]; 171 } 172 173 #ifdef DEBUG 174 static void dumpListItems(const char *p, struct TaskList *listHead) 175 { 176 int i = 0; 177 struct Task *task; 178 179 osLog(LOG_ERROR, "List: %s (%p) [%u;%u]\n", 180 p, 181 listHead, 182 listHead ? listHead->prev : NO_NODE, 183 listHead ? listHead->next : NO_NODE 184 ); 185 if (!listHead) 186 return; 187 188 for_each_task(listHead, task) { 189 osLog(LOG_ERROR, " item %d: task=%p TID=%04X [%u;%u;%u]\n", 190 i, 191 task, 192 task->tid, 193 task->list.prev, 194 osTaskIndex(task), 195 task->list.next 196 ); 197 ++i; 198 } 199 } 200 201 static void dumpTaskList(const char *f, struct Task *task, struct TaskList *listHead) 202 { 203 osLog(LOG_ERROR, "%s: pool: %p; task=%p [%u;%u;%u]; listHead=%p [%u;%u]\n", 204 f, 205 &mTaskPool, 206 task, 207 task ? task->list.prev : NO_NODE, 208 osTaskIndex(task), 209 task ? task->list.next : NO_NODE, 210 listHead, 211 listHead ? listHead->prev : NO_NODE, 212 listHead ? listHead->next : NO_NODE 213 ); 214 dumpListItems("Tasks", &mTasks); 215 dumpListItems("Free Tasks", &mFreeTasks); 216 } 217 #else 218 #define dumpTaskList(a,b,c) 219 #endif 220 221 static inline void osTaskListRemoveTask(struct TaskList *listHead, struct Task *task) 222 { 223 if (task && listHead) { 224 struct TaskList *cur = &task->list; 225 TaskIndex left_idx = cur->prev; 226 TaskIndex right_idx = cur->next; 227 struct TaskList *left = left_idx == NO_NODE ? listHead : &mTaskPool.data[left_idx].list; 228 struct TaskList *right = right_idx == NO_NODE ? listHead : &mTaskPool.data[right_idx].list; 229 cur->prev = cur->next = NO_NODE; 230 left->next = right_idx; 231 right->prev = left_idx; 232 } else { 233 dumpTaskList(__func__, task, listHead); 234 } 235 } 236 237 static inline void osTaskListAddTail(struct TaskList *listHead, struct Task *task) 238 { 239 if (task && listHead) { 240 struct TaskList *cur = &task->list; 241 TaskIndex last_idx = listHead->prev; 242 TaskIndex new_idx = osTaskIndex(task); 243 struct TaskList *last = last_idx == NO_NODE ? listHead : &mTaskPool.data[last_idx].list; 244 cur->prev = last_idx; 245 cur->next = NO_NODE; 246 last->next = new_idx; 247 listHead->prev = new_idx; 248 } else { 249 dumpTaskList(__func__, task, listHead); 250 } 251 } 252 253 static struct Task *osAllocTask() 254 { 255 struct Task *task = osTaskListPeekHead(&mFreeTasks); 256 257 if (task) { 258 osTaskListRemoveTask(&mFreeTasks, task); 259 uint16_t tid = task->tid; 260 memset(task, 0, sizeof(*task)); 261 task->tid = tid; 262 } 263 264 return task; 265 } 266 267 static void osFreeTask(struct Task *task) 268 { 269 if (task) { 270 task->flags = 0; 271 task->ioCount = 0; 272 osTaskListAddTail(&mFreeTasks, task); 273 } 274 } 275 276 static void osRemoveTask(struct Task *task) 277 { 278 osTaskListRemoveTask(&mTasks, task); 279 } 280 281 static void osAddTask(struct Task *task) 282 { 283 osTaskListAddTail(&mTasks, task); 284 } 285 286 struct Task* osTaskFindByTid(uint32_t tid) 287 { 288 TaskIndex idx = TID_TO_TASK_IDX(tid); 289 290 return idx < MAX_TASKS ? &mTaskPool.data[idx] : NULL; 291 } 292 293 static inline bool osTaskInit(struct Task *task) 294 { 295 struct Task *preempted = osSetCurrentTask(task); 296 bool done = cpuAppInit(task->app, &task->platInfo, task->tid); 297 osSetCurrentTask(preempted); 298 return done; 299 } 300 301 static void osTaskRelease(struct Task *task) 302 { 303 uint32_t taskTid = task->tid; 304 uint32_t platErr, sensorErr; 305 int timErr, heapErr; 306 uint64_t appId; 307 308 if (task->app) 309 appId = task->app->hdr.appId; 310 else 311 appId = 0; 312 313 platErr = platFreeResources(taskTid); // HW resources cleanup (IRQ, DMA etc) 314 sensorErr = sensorFreeAll(taskTid); 315 timErr = timTimerCancelAll(taskTid); 316 heapErr = heapFreeAll(taskTid); 317 318 if (platErr || sensorErr || timErr || heapErr) 319 osLog(LOG_WARN, "released app ID 0x%" PRIx64 "; plat:%08" PRIx32 " sensor:%08" PRIx32 " tim:%d heap:%d; TID %04" PRIX32 "\n", appId, platErr, sensorErr, timErr, heapErr, taskTid); 320 else 321 osLog(LOG_INFO, "released app ID 0x%" PRIx64 "; TID %04" PRIX32 "\n", appId, taskTid); 322 } 323 324 static inline void osTaskEnd(struct Task *task) 325 { 326 if (!osTaskTestFlags(task, FL_TASK_ABORTED)) { 327 struct Task *preempted = osSetCurrentTask(task); 328 cpuAppEnd(task->app, &task->platInfo); 329 osSetCurrentTask(preempted); 330 } 331 332 // task was supposed to release it's resources, 333 // but we do our cleanup anyway 334 // NOTE: we don't need to unsubscribe from events 335 osTaskRelease(task); 336 } 337 338 static inline void osTaskHandle(struct Task *task, uint16_t evtType, uint16_t fromTid, const void* evtData) 339 { 340 struct Task *preempted = osSetCurrentTask(task); 341 cpuAppHandle(task->app, &task->platInfo, 342 EVENT_WITH_ORIGIN(evtType, osTaskIsChre(task) ? fromTid : 0), 343 evtData); 344 osSetCurrentTask(preempted); 345 } 346 347 void osTaskInvokeMessageFreeCallback(struct Task *task, void (*freeCallback)(void *, size_t), void *message, uint32_t messageSize) 348 { 349 if (!task || !freeCallback) 350 return; 351 cpuAppInvoke(task->app, &task->platInfo, (void (*)(uintptr_t,uintptr_t))freeCallback, (uintptr_t)message, (uintptr_t)messageSize); 352 } 353 354 void osTaskInvokeEventFreeCallback(struct Task *task, void (*freeCallback)(uint16_t, void *), uint16_t event, void *data) 355 { 356 if (!task || !freeCallback) 357 return; 358 cpuAppInvoke(task->app, &task->platInfo, 359 (void (*)(uintptr_t,uintptr_t))freeCallback, 360 (uintptr_t)event, (uintptr_t)data); 361 } 362 363 static void osPrivateEvtFreeF(void *event) 364 { 365 union SeosInternalSlabData *act = event; 366 uint16_t fromTid = act->privateEvt.fromTid; 367 struct Task *srcTask = osTaskFindByTid(fromTid); 368 TaggedPtr evtFreeInfo = act->privateEvt.evtFreeInfo; 369 uint32_t evtType = act->privateEvt.evtType; 370 void *evtData = act->privateEvt.evtData; 371 372 slabAllocatorFree(mMiscInternalThingsSlab, event); 373 374 if (!srcTask) { 375 osLog(LOG_ERROR, "ERROR: Failed to find task to free event: evtType=%08" PRIX32 "\n", evtType); 376 return; 377 } 378 379 if (taggedPtrIsPtr(evtFreeInfo) && taggedPtrToPtr(evtFreeInfo)) { 380 if (osTaskIsChre(srcTask) && (evtType >> 16) == EVT_PRIVATE_CLASS_CHRE) { 381 osChreFreeEvent(fromTid, 382 (void (*)(uint16_t, void *))taggedPtrToPtr(evtFreeInfo), 383 evtType & EVT_MASK, evtData); 384 } else { 385 // this is for internal non-CHRE tasks, and CHRE tasks 386 // System may schedule non-CHRE events on behalf of CHRE app; 387 // this is the place we release them 388 struct Task *preempted = osSetCurrentTask(srcTask); 389 ((EventFreeF)taggedPtrToPtr(evtFreeInfo))(evtData); 390 osSetCurrentTask(preempted); 391 } 392 } else if (taggedPtrIsUint(evtFreeInfo)) { 393 // this is for external non-CHRE tasks 394 struct AppEventFreeData fd = {.evtType = evtType, .evtData = evtData}; 395 osTaskHandle(srcTask, EVT_APP_FREE_EVT_DATA, OS_SYSTEM_TID, &fd); 396 } 397 398 osTaskAddIoCount(srcTask, -1); 399 } 400 401 static void handleEventFreeing(uint32_t evtType, void *evtData, TaggedPtr evtFreeData) // watch out, this is synchronous 402 { 403 struct Task *srcTask = osTaskFindByTid(EVENT_GET_ORIGIN(evtType)); 404 405 if (!srcTask) { 406 osLog(LOG_ERROR, "ERROR: Failed to find task to free event: evtType=%08" PRIX32 "\n", evtType); 407 return; 408 } 409 410 // release non-CHRE event; we can't determine if this is CHRE or non-CHRE event, but 411 // this method is only called to release non-CHRE events, so we make use of that fact 412 413 if (taggedPtrIsPtr(evtFreeData) && taggedPtrToPtr(evtFreeData)) { 414 // this is for internal non-CHRE tasks, and CHRE tasks 415 // System may schedule non-CHRE events on behalf of CHRE app; 416 // this is the place we release them 417 struct Task *preempted = osSetCurrentTask(srcTask); 418 ((EventFreeF)taggedPtrToPtr(evtFreeData))(evtData); 419 osSetCurrentTask(preempted); 420 } else if (taggedPtrIsUint(evtFreeData)) { 421 // this is for external non-CHRE tasks 422 struct AppEventFreeData fd = {.evtType = EVENT_GET_EVENT(evtType), .evtData = evtData}; 423 osTaskHandle(srcTask, EVT_APP_FREE_EVT_DATA, OS_SYSTEM_TID, &fd); 424 } 425 426 osTaskAddIoCount(srcTask, -1); 427 } 428 429 static void osInit(void) 430 { 431 heapInit(); 432 platInitialize(); 433 434 osLog(LOG_INFO, "SEOS Initializing\n"); 435 cpuInitLate(); 436 437 /* create the queues */ 438 if (!(mEvtsInternal = evtQueueAlloc(512, handleEventFreeing))) { 439 osLog(LOG_INFO, "events failed to init\n"); 440 return; 441 } 442 443 mMiscInternalThingsSlab = slabAllocatorNew(sizeof(union SeosInternalSlabData), alignof(union SeosInternalSlabData), 64 /* for now? */); 444 if (!mMiscInternalThingsSlab) { 445 osLog(LOG_INFO, "deferred actions list failed to init\n"); 446 return; 447 } 448 } 449 450 static struct Task* osTaskFindByAppID(uint64_t appID) 451 { 452 struct Task *task; 453 454 for_each_task(&mTasks, task) { 455 if (task->app && task->app->hdr.appId == appID) 456 return task; 457 } 458 459 return NULL; 460 } 461 462 void osSegmentIteratorInit(struct SegmentIterator *it) 463 { 464 uint32_t sz; 465 uint8_t *start = platGetSharedAreaInfo(&sz); 466 467 it->shared = (const struct Segment *)(start); 468 it->sharedEnd = (const struct Segment *)(start + sz); 469 it->seg = NULL; 470 } 471 472 bool osAppSegmentSetState(const struct AppHdr *app, uint32_t segState) 473 { 474 bool done; 475 struct Segment *seg = osGetSegment(app); 476 uint8_t state = segState; 477 478 if (!seg) 479 return false; 480 481 mpuAllowRamExecution(true); 482 mpuAllowRomWrite(true); 483 done = BL.blProgramShared(&seg->state, &state, sizeof(state), BL_FLASH_KEY1, BL_FLASH_KEY2); 484 mpuAllowRomWrite(false); 485 mpuAllowRamExecution(false); 486 487 return done; 488 } 489 490 bool osSegmentSetSize(struct Segment *seg, uint32_t size) 491 { 492 bool ret = true; 493 494 if (!seg) 495 return false; 496 497 if (size > SEG_SIZE_MAX) { 498 seg->state = SEG_ST_ERASED; 499 size = SEG_SIZE_MAX; 500 ret = false; 501 } 502 seg->size[0] = size; 503 seg->size[1] = size >> 8; 504 seg->size[2] = size >> 16; 505 506 return ret; 507 } 508 509 struct Segment *osSegmentGetEnd() 510 { 511 uint32_t size; 512 uint8_t *start = platGetSharedAreaInfo(&size); 513 return (struct Segment *)(start + size); 514 } 515 516 uint32_t osSegmentGetFree() 517 { 518 struct SegmentIterator it; 519 const struct Segment *storageSeg = NULL; 520 521 osSegmentIteratorInit(&it); 522 while (osSegmentIteratorNext(&it)) { 523 if (osSegmentGetState(it.seg) == SEG_ST_EMPTY) { 524 storageSeg = it.seg; 525 break; 526 } 527 } 528 if (!storageSeg || storageSeg > it.sharedEnd) 529 return 0; 530 531 return (uint8_t *)it.sharedEnd - (uint8_t *)storageSeg; 532 } 533 534 struct Segment *osGetSegment(const struct AppHdr *app) 535 { 536 uint32_t size; 537 uint8_t *start = platGetSharedAreaInfo(&size); 538 539 return (struct Segment *)((uint8_t*)app && 540 (uint8_t*)app >= start && 541 (uint8_t*)app < (start + size) ? 542 (uint8_t*)app - sizeof(struct Segment) : NULL); 543 } 544 545 bool osEraseShared() 546 { 547 wdtDisableClk(); 548 mpuAllowRamExecution(true); 549 mpuAllowRomWrite(true); 550 (void)BL.blEraseShared(BL_FLASH_KEY1, BL_FLASH_KEY2); 551 mpuAllowRomWrite(false); 552 mpuAllowRamExecution(false); 553 wdtEnableClk(); 554 return true; 555 } 556 557 bool osWriteShared(void *dest, const void *src, uint32_t len) 558 { 559 bool ret; 560 561 mpuAllowRamExecution(true); 562 mpuAllowRomWrite(true); 563 ret = BL.blProgramShared(dest, src, len, BL_FLASH_KEY1, BL_FLASH_KEY2); 564 mpuAllowRomWrite(false); 565 mpuAllowRamExecution(false); 566 567 if (!ret) 568 osLog(LOG_ERROR, "osWriteShared: blProgramShared return false\n"); 569 570 return ret; 571 } 572 573 struct AppHdr *osAppSegmentCreate(uint32_t size) 574 { 575 struct SegmentIterator it; 576 const struct Segment *storageSeg = NULL; 577 struct AppHdr *app; 578 579 osSegmentIteratorInit(&it); 580 while (osSegmentIteratorNext(&it)) { 581 if (osSegmentGetState(it.seg) == SEG_ST_EMPTY) { 582 storageSeg = it.seg; 583 break; 584 } 585 } 586 if (!storageSeg || osSegmentSizeGetNext(storageSeg, size) > it.sharedEnd) 587 return NULL; 588 589 app = osSegmentGetData(storageSeg); 590 osAppSegmentSetState(app, SEG_ST_RESERVED); 591 592 return app; 593 } 594 595 bool osAppSegmentClose(struct AppHdr *app, uint32_t segDataSize, uint32_t segState) 596 { 597 struct Segment seg; 598 599 // this is enough for holding padding to uint32_t and the footer 600 uint8_t footer[sizeof(uint32_t) + FOOTER_SIZE]; 601 int footerLen; 602 bool ret; 603 uint32_t totalSize; 604 uint8_t *start = platGetSharedAreaInfo(&totalSize); 605 uint8_t *end = start + totalSize; 606 int32_t fullSize = segDataSize + sizeof(seg); // without footer or padding 607 struct Segment *storageSeg = osGetSegment(app); 608 609 // sanity check 610 if (segDataSize >= SEG_SIZE_MAX) 611 return false; 612 613 // physical limits check 614 if (osSegmentSizeAlignedWithFooter(segDataSize) + sizeof(struct Segment) > totalSize) 615 return false; 616 617 // available space check: we could truncate size, instead of disallowing it, 618 // but we know that we performed validation on the size before, in *Create call, 619 // and it was fine, so this must be a programming error, and so we fail. 620 // on a side note: size may grow or shrink compared to original estimate. 621 // typically it shrinks, since we skip some header info and padding, as well 622 // as signature blocks, but it is possible that at some point we may produce 623 // more data for some reason. At that time the logic here may need to change 624 if (osSegmentSizeGetNext(storageSeg, segDataSize) > (struct Segment*)end) 625 return false; 626 627 seg.state = segState; 628 osSegmentSetSize(&seg, segDataSize); 629 630 ret = osWriteShared((uint8_t*)storageSeg, (uint8_t*)&seg, sizeof(seg)); 631 632 footerLen = (-fullSize) & 3; 633 memset(footer, 0x00, footerLen); 634 635 wdtDisableClk(); 636 struct SegmentFooter segFooter = { 637 .crc = ~soft_crc32(storageSeg, fullSize, ~0), 638 }; 639 wdtEnableClk(); 640 memcpy(&footer[footerLen], &segFooter, sizeof(segFooter)); 641 footerLen += sizeof(segFooter); 642 643 if (ret && footerLen) 644 ret = osWriteShared((uint8_t*)storageSeg + fullSize, footer, footerLen); 645 646 return ret; 647 } 648 649 bool osAppWipeData(struct AppHdr *app) 650 { 651 struct Segment *seg = osGetSegment(app); 652 int32_t size = osSegmentGetSize(seg); 653 uint8_t *p = (uint8_t*)app; 654 uint32_t state = osSegmentGetState(seg); 655 uint8_t buf[256]; 656 bool done = true; 657 658 if (!seg || size == SEG_SIZE_INVALID || state == SEG_ST_EMPTY) { 659 osLog(LOG_ERROR, "%s: can't erase segment: app=%p; seg=%p" 660 "; size=%" PRIu32 661 "; state=%" PRIu32 662 "\n", 663 __func__, app, seg, size, state); 664 return false; 665 } 666 667 size = osSegmentSizeAlignedWithFooter(size); 668 669 memset(buf, 0, sizeof(buf)); 670 while (size > 0) { 671 uint32_t flashSz = size > sizeof(buf) ? sizeof(buf) : size; 672 // keep trying to zero-out stuff even in case of intermittent failures. 673 // flash write may occasionally fail on some byte, but it is not good enough 674 // reason to not rewrite other bytes 675 bool res = osWriteShared(p, buf, flashSz); 676 done = done && res; 677 size -= flashSz; 678 p += flashSz; 679 } 680 681 return done; 682 } 683 684 static inline bool osAppIsValid(const struct AppHdr *app) 685 { 686 return app->hdr.magic == APP_HDR_MAGIC && 687 app->hdr.fwVer == APP_HDR_VER_CUR && 688 (app->hdr.fwFlags & FL_APP_HDR_APPLICATION) != 0 && 689 app->hdr.payInfoType == LAYOUT_APP; 690 } 691 692 static bool osExtAppIsValid(const struct AppHdr *app, uint32_t len) 693 { 694 return osAppIsValid(app) && 695 len >= sizeof(*app) && 696 osAppSegmentGetState(app) == SEG_ST_VALID && 697 osAppSegmentCalcCrcResidue(app) == CRC_RESIDUE && 698 !(app->hdr.fwFlags & FL_APP_HDR_INTERNAL); 699 } 700 701 static bool osIntAppIsValid(const struct AppHdr *app) 702 { 703 return osAppIsValid(app) && 704 osAppSegmentGetState(app) == SEG_STATE_INVALID && 705 (app->hdr.fwFlags & FL_APP_HDR_INTERNAL) != 0; 706 } 707 708 static inline bool osExtAppErase(const struct AppHdr *app) 709 { 710 return osAppSegmentSetState(app, SEG_ST_ERASED); 711 } 712 713 static struct Task *osLoadApp(const struct AppHdr *app) { 714 struct Task *task; 715 716 task = osAllocTask(); 717 if (!task) { 718 osLog(LOG_WARN, "External app id %016" PRIX64 " @ %p cannot be used as too many apps already exist.\n", app->hdr.appId, app); 719 return NULL; 720 } 721 task->app = app; 722 bool done = (app->hdr.fwFlags & FL_APP_HDR_INTERNAL) ? 723 cpuInternalAppLoad(task->app, &task->platInfo) : 724 cpuAppLoad(task->app, &task->platInfo); 725 726 if (!done) { 727 osLog(LOG_WARN, "App @ %p ID %016" PRIX64 " failed to load\n", app, app->hdr.appId); 728 osFreeTask(task); 729 task = NULL; 730 } 731 732 return task; 733 } 734 735 static void osUnloadApp(struct Task *task) 736 { 737 // this is called on task that has stopped running, or had never run 738 cpuAppUnload(task->app, &task->platInfo); 739 osFreeTask(task); 740 } 741 742 static bool osStartApp(const struct AppHdr *app) 743 { 744 bool done = false; 745 struct Task *task; 746 747 if ((task = osLoadApp(app)) != NULL) { 748 task->subbedEvtListSz = MAX_EMBEDDED_EVT_SUBS; 749 task->subbedEvents = task->subbedEventsInt; 750 osTaskMakeNewTid(task); 751 752 // print external NanoApp info to facilitate NanoApp debugging 753 if (!(task->app->hdr.fwFlags & FL_APP_HDR_INTERNAL)) 754 osLog(LOG_INFO, 755 "loaded app ID 0x%" PRIx64 " at flash base 0x%" PRIxPTR " ram base 0x%" PRIxPTR "; TID %04" PRIX16 "\n", 756 task->app->hdr.appId, (uintptr_t) task->app, (uintptr_t) task->platInfo.data, task->tid); 757 758 done = osTaskInit(task); 759 760 if (!done) { 761 osLog(LOG_WARN, "App @ %p ID %016" PRIX64 " failed to init\n", task->app, task->app->hdr.appId); 762 osUnloadApp(task); 763 } else { 764 osAddTask(task); 765 (void)osEnqueueEvt(EVT_APP_BEGIN, task, NULL); 766 } 767 } 768 769 return done; 770 } 771 772 static bool osStopTask(struct Task *task, bool abort) 773 { 774 struct Task *preempted; 775 776 if (!task) 777 return false; 778 779 if (osTaskTestFlags(task, FL_TASK_STOPPED)) 780 return true; 781 782 preempted = osSetCurrentTask(mSystemTask); 783 osRemoveTask(task); 784 osTaskClrSetFlags(task, 0, FL_TASK_STOPPED); 785 786 if (abort) 787 osTaskClrSetFlags(task, 0, FL_TASK_ABORTED); 788 else if (osTaskGetIoCount(task)) 789 osTaskHandle(task, EVT_APP_STOP, OS_SYSTEM_TID, NULL); 790 osEnqueueEvt(EVT_APP_END, task, NULL); 791 792 osSetCurrentTask(preempted); 793 794 return true; 795 } 796 797 void osTaskAbort(struct Task *task) 798 { 799 osStopTask(task, true); 800 } 801 802 static bool matchAutoStart(const void *cookie, const struct AppHdr *app) 803 { 804 bool match = (bool)cookie; 805 806 if (app->hdr.fwFlags & FL_APP_HDR_CHRE) { 807 if (app->hdr.chreApiMajor == 0xFF && app->hdr.chreApiMinor == 0xFF) 808 return match; 809 else if ((app->hdr.chreApiMajor < 0x01) || 810 (app->hdr.chreApiMajor == 0x01 && app->hdr.chreApiMinor < 0x01)) 811 return match; 812 else 813 return !match; 814 } else { 815 return match; 816 } 817 } 818 819 static bool matchAppId(const void *data, const struct AppHdr *app) 820 { 821 uint64_t appId, vendor, seqId, curAppId; 822 823 memcpy(&appId, data, sizeof(appId)); 824 vendor = APP_ID_GET_VENDOR(appId); 825 seqId = APP_ID_GET_SEQ_ID(appId); 826 curAppId = app->hdr.appId; 827 828 if ((vendor == APP_VENDOR_ANY || vendor == APP_ID_GET_VENDOR(curAppId)) && 829 (seqId == APP_SEQ_ID_ANY || seqId == APP_ID_GET_SEQ_ID(curAppId))) { 830 return true; 831 } else { 832 return false; 833 } 834 } 835 836 static bool osExtAppFind(struct SegmentIterator *it, appMatchFunc func, const void *data) 837 { 838 const struct AppHdr *app; 839 const struct Segment *seg; 840 841 while (osSegmentIteratorNext(it)) { 842 seg = it->seg; 843 if (!seg) 844 break; 845 if (seg->state == SEG_ST_EMPTY) 846 break; 847 if (seg->state != SEG_ST_VALID) 848 continue; 849 app = osSegmentGetData(seg); 850 if (func(data, app)) 851 return true; 852 } 853 854 return false; 855 } 856 857 static uint32_t osExtAppStopEraseApps(appMatchFunc func, const void *data, bool doErase) 858 { 859 const struct AppHdr *app; 860 int32_t len; 861 struct SegmentIterator it; 862 uint32_t stopCount = 0; 863 uint32_t eraseCount = 0; 864 uint32_t appCount = 0; 865 uint32_t taskCount = 0; 866 struct MgmtStatus stat = { .value = 0 }; 867 struct Task *task; 868 869 osSegmentIteratorInit(&it); 870 while (osExtAppFind(&it, func, data)) { 871 app = osSegmentGetData(it.seg); 872 len = osSegmentGetSize(it.seg); 873 if (!osExtAppIsValid(app, len)) 874 continue; 875 appCount++; 876 /* it is safe to erase a running app; 877 * erase merely sets a flag in the header, 878 * and app keeps running until it is stopped */ 879 if (doErase && osExtAppErase(app)) 880 eraseCount++; 881 task = osTaskFindByAppID(app->hdr.appId); 882 if (task) { 883 taskCount++; 884 if (osStopTask(task, false)) 885 stopCount++; 886 } 887 } 888 SET_COUNTER(stat.app, appCount); 889 SET_COUNTER(stat.task, taskCount); 890 SET_COUNTER(stat.op, stopCount); 891 SET_COUNTER(stat.erase, eraseCount); 892 893 return stat.value; 894 } 895 896 uint32_t osExtAppStopAppsByAppId(uint64_t appId) 897 { 898 return osExtAppStopEraseApps(matchAppId, &appId, false); 899 } 900 901 uint32_t osExtAppEraseAppsByAppId(uint64_t appId) 902 { 903 return osExtAppStopEraseApps(matchAppId, &appId, true); 904 } 905 906 static void osScanExternal() 907 { 908 struct SegmentIterator it; 909 osSegmentIteratorInit(&it); 910 while (osSegmentIteratorNext(&it)) { 911 switch (osSegmentGetState(it.seg)) { 912 case SEG_ST_EMPTY: 913 // everything looks good 914 osLog(LOG_INFO, "External area is good\n"); 915 return; 916 case SEG_ST_ERASED: 917 case SEG_ST_VALID: 918 // this is valid stuff, ignore 919 break; 920 case SEG_ST_RESERVED: 921 default: 922 // something is wrong: erase everything 923 osLog(LOG_ERROR, "External area is damaged. Erasing\n"); 924 osEraseShared(); 925 return; 926 } 927 } 928 } 929 930 static uint32_t osExtAppStartApps(appMatchFunc func, void *data) 931 { 932 const struct AppHdr *app; 933 int32_t len; 934 struct SegmentIterator it; 935 struct SegmentIterator checkIt; 936 uint32_t startCount = 0; 937 uint32_t eraseCount = 0; 938 uint32_t appCount = 0; 939 uint32_t taskCount = 0; 940 struct MgmtStatus stat = { .value = 0 }; 941 942 osScanExternal(); 943 944 osSegmentIteratorInit(&it); 945 while (osExtAppFind(&it, func, data)) { 946 app = osSegmentGetData(it.seg); 947 len = osSegmentGetSize(it.seg); 948 949 // skip erased or malformed apps 950 if (!osExtAppIsValid(app, len)) 951 continue; 952 953 appCount++; 954 checkIt = it; 955 // find the most recent copy 956 while (osExtAppFind(&checkIt, matchAppId, &app->hdr.appId)) { 957 if (osExtAppErase(app)) // erase the old one, so we skip it next time 958 eraseCount++; 959 app = osSegmentGetData(checkIt.seg); 960 } 961 962 if (osTaskFindByAppID(app->hdr.appId)) { 963 // this either the most recent external app with the same ID, 964 // or internal app with the same id; in both cases we do nothing 965 taskCount++; 966 continue; 967 } 968 969 if (osStartApp(app)) 970 startCount++; 971 } 972 SET_COUNTER(stat.app, appCount); 973 SET_COUNTER(stat.task, taskCount); 974 SET_COUNTER(stat.op, startCount); 975 SET_COUNTER(stat.erase, eraseCount); 976 977 return stat.value; 978 } 979 980 uint32_t osExtAppStartAppsByAppId(uint64_t appId) 981 { 982 return osExtAppStartApps(matchAppId, &appId); 983 } 984 985 static void osStartTasks(void) 986 { 987 const struct AppHdr *app; 988 uint32_t i, nApps; 989 struct Task* task; 990 uint32_t status = 0; 991 uint32_t taskCnt = 0; 992 993 osLog(LOG_DEBUG, "Initializing task pool...\n"); 994 list_init(&mTasks); 995 list_init(&mFreeTasks); 996 for (i = 0; i < MAX_TASKS; ++i) { 997 task = &mTaskPool.data[i]; 998 list_init(&task->list); 999 osFreeTask(task); 1000 } 1001 1002 mSystemTask = osAllocTask(); // this is a dummy task; holder of TID 0; all system code will run with TID 0 1003 osSetCurrentTask(mSystemTask); 1004 osLog(LOG_DEBUG, "System task is: %p\n", mSystemTask); 1005 1006 /* first enum all internal apps, making sure to check for dupes */ 1007 osLog(LOG_DEBUG, "Starting internal apps...\n"); 1008 for (i = 0, app = platGetInternalAppList(&nApps); i < nApps; i++, app++) { 1009 if (!osIntAppIsValid(app)) { 1010 osLog(LOG_WARN, "Invalid internal app @ %p ID %016" PRIX64 1011 "header version: %" PRIu16 1012 "\n", 1013 app, app->hdr.appId, app->hdr.fwVer); 1014 continue; 1015 } 1016 1017 if (!(app->hdr.fwFlags & FL_APP_HDR_INTERNAL)) { 1018 osLog(LOG_WARN, "Internal app is not marked: [%p]: flags: 0x%04" PRIX16 1019 "; ID: %016" PRIX64 1020 "; ignored\n", 1021 app, app->hdr.fwFlags, app->hdr.appId); 1022 continue; 1023 } 1024 if ((task = osTaskFindByAppID(app->hdr.appId))) { 1025 osLog(LOG_WARN, "Internal app ID %016" PRIX64 1026 "@ %p attempting to update internal app @ %p; app @%p ignored.\n", 1027 app->hdr.appId, app, task->app, app); 1028 continue; 1029 } 1030 if (osStartApp(app)) 1031 taskCnt++; 1032 } 1033 1034 osLog(LOG_DEBUG, "Starting external apps...\n"); 1035 status = osExtAppStartApps(matchAutoStart, (void *)true); 1036 osLog(LOG_DEBUG, "Started %" PRIu32 " internal apps; EXT status: %08" PRIX32 "\n", taskCnt, status); 1037 } 1038 1039 static void osInternalEvtHandle(uint32_t evtType, void *evtData) 1040 { 1041 union SeosInternalSlabData *da = (union SeosInternalSlabData*)evtData; 1042 struct Task *task, *ssTask; 1043 uint32_t i, j; 1044 uint16_t tid = EVENT_GET_ORIGIN(evtType); 1045 uint16_t evt = EVENT_GET_EVENT(evtType), newEvt; 1046 struct Task *srcTask = osTaskFindByTid(tid); 1047 struct Task *preempted = osSetCurrentTask(srcTask); 1048 struct AppEventStartStop ssMsg; 1049 1050 switch (evt) { 1051 case EVT_SUBSCRIBE_TO_EVT: 1052 case EVT_UNSUBSCRIBE_TO_EVT: 1053 /* get task */ 1054 task = osTaskFindByTid(da->evtSub.tid); 1055 if (!task) 1056 break; 1057 1058 for (j = 0; j < da->evtSub.numEvts; j++) { 1059 /* find if subscribed to this evt */ 1060 for (i = 0; i < task->subbedEvtCount && task->subbedEvents[i] != da->evtSub.evts[j]; i++); 1061 1062 /* if unsub & found -> unsub */ 1063 if (evt == EVT_UNSUBSCRIBE_TO_EVT && i != task->subbedEvtCount) 1064 task->subbedEvents[i] = task->subbedEvents[--task->subbedEvtCount]; 1065 /* if sub & not found -> sub */ 1066 else if (evt == EVT_SUBSCRIBE_TO_EVT && i == task->subbedEvtCount) { 1067 if (task->subbedEvtListSz == task->subbedEvtCount) { /* enlarge the list */ 1068 uint32_t newSz = (task->subbedEvtListSz * 3 + 1) / 2; 1069 uint32_t *newList = heapAlloc(sizeof(uint32_t[newSz])); /* grow by 50% */ 1070 if (newList) { 1071 memcpy(newList, task->subbedEvents, sizeof(uint32_t[task->subbedEvtListSz])); 1072 if (task->subbedEvents != task->subbedEventsInt) 1073 heapFree(task->subbedEvents); 1074 task->subbedEvents = newList; 1075 task->subbedEvtListSz = newSz; 1076 } 1077 } 1078 if (task->subbedEvtListSz > task->subbedEvtCount) { /* have space ? */ 1079 task->subbedEvents[task->subbedEvtCount++] = da->evtSub.evts[j]; 1080 } 1081 } 1082 } 1083 break; 1084 1085 case EVT_APP_BEGIN: 1086 case EVT_APP_END: 1087 ssTask = evtData; 1088 ssMsg.appId = ssTask->app->hdr.appId; 1089 ssMsg.version = ssTask->app->hdr.appVer; 1090 ssMsg.tid = ssTask->tid; 1091 if (evt == EVT_APP_BEGIN) { 1092 newEvt = EVT_APP_STARTED; 1093 } else { 1094 newEvt = EVT_APP_STOPPED; 1095 osTaskEnd(ssTask); 1096 osUnloadApp(ssTask); 1097 } 1098 1099 /* send this event to all tasks who want it */ 1100 for_each_task(&mTasks, task) { 1101 if (task != ssTask) { 1102 for (i = 0; i < task->subbedEvtCount; i++) { 1103 if (task->subbedEvents[i] == newEvt) { 1104 osTaskHandle(task, newEvt, OS_SYSTEM_TID, &ssMsg); 1105 break; 1106 } 1107 } 1108 } 1109 } 1110 break; 1111 1112 case EVT_DEFERRED_CALLBACK: 1113 da->deferred.callback(da->deferred.cookie); 1114 break; 1115 1116 case EVT_PRIVATE_EVT: 1117 task = osTaskFindByTid(da->privateEvt.toTid); 1118 evtType = da->privateEvt.evtType & EVT_MASK; 1119 evtData = da->privateEvt.evtData; 1120 if (task) { 1121 //private events cannot be retained 1122 TaggedPtr *tmp = mCurEvtEventFreeingInfo; 1123 mCurEvtEventFreeingInfo = NULL; 1124 osTaskHandle(task, evtType, da->privateEvt.fromTid, da->privateEvt.evtData); 1125 mCurEvtEventFreeingInfo = tmp; 1126 } 1127 break; 1128 } 1129 osSetCurrentTask(preempted); 1130 } 1131 1132 void abort(void) 1133 { 1134 /* this is necessary for va_* funcs... */ 1135 osLog(LOG_ERROR, "Abort called"); 1136 while(1); 1137 } 1138 1139 bool osRetainCurrentEvent(TaggedPtr *evtFreeingInfoP) 1140 { 1141 if (!mCurEvtEventFreeingInfo) 1142 return false; 1143 1144 *evtFreeingInfoP = *mCurEvtEventFreeingInfo; 1145 mCurEvtEventFreeingInfo = NULL; 1146 return true; 1147 } 1148 1149 void osFreeRetainedEvent(uint32_t evtType, void *evtData, TaggedPtr *evtFreeingInfoP) 1150 { 1151 //TODO: figure the way to calculate src tid here to pass to handleEventFreeing 1152 handleEventFreeing(evtType, evtData, *evtFreeingInfoP); 1153 } 1154 1155 void osMainInit(void) 1156 { 1157 cpuInit(); 1158 cpuIntsOff(); 1159 osInit(); 1160 timInit(); 1161 sensorsInit(); 1162 syscallInit(); 1163 osApiExport(mMiscInternalThingsSlab); 1164 osChreApiExport(); 1165 apIntInit(); 1166 cpuIntsOn(); 1167 wdtInit(); 1168 osStartTasks(); 1169 1170 //broadcast app start to all already-loaded apps 1171 (void)osEnqueueEvt(EVT_APP_START, NULL, NULL); 1172 } 1173 1174 void osMainDequeueLoop(void) 1175 { 1176 TaggedPtr evtFreeingInfo; 1177 uint32_t evtType, j; 1178 void *evtData; 1179 struct Task *task; 1180 uint16_t tid, evt; 1181 1182 /* get an event */ 1183 if (!evtQueueDequeue(mEvtsInternal, &evtType, &evtData, &evtFreeingInfo, true)) 1184 return; 1185 1186 /* by default we free them when we're done with them */ 1187 mCurEvtEventFreeingInfo = &evtFreeingInfo; 1188 tid = EVENT_GET_ORIGIN(evtType); 1189 evt = EVENT_GET_EVENT(evtType); 1190 1191 if (evt < EVT_NO_FIRST_USER_EVENT) { 1192 /* handle deferred actions and other reserved events here */ 1193 osInternalEvtHandle(evtType, evtData); 1194 } else { 1195 /* send this event to all tasks who want it */ 1196 for_each_task(&mTasks, task) { 1197 for (j = 0; j < task->subbedEvtCount; j++) { 1198 if (task->subbedEvents[j] == evt) { 1199 osTaskHandle(task, evt, tid, evtData); 1200 break; 1201 } 1202 } 1203 } 1204 } 1205 1206 /* free it */ 1207 if (mCurEvtEventFreeingInfo) 1208 handleEventFreeing(evtType, evtData, evtFreeingInfo); 1209 1210 /* avoid some possible errors */ 1211 mCurEvtEventFreeingInfo = NULL; 1212 } 1213 1214 void __attribute__((noreturn)) osMain(void) 1215 { 1216 osMainInit(); 1217 1218 while (true) 1219 { 1220 osMainDequeueLoop(); 1221 platPeriodic(); 1222 } 1223 } 1224 1225 static void osDeferredActionFreeF(void* event) 1226 { 1227 slabAllocatorFree(mMiscInternalThingsSlab, event); 1228 } 1229 1230 static bool osEventsSubscribeUnsubscribeV(bool sub, uint32_t numEvts, va_list ap) 1231 { 1232 struct Task *task = osGetCurrentTask(); 1233 union SeosInternalSlabData *act; 1234 int i; 1235 1236 if (!sub && osTaskTestFlags(task, FL_TASK_STOPPED)) // stopping, so this is a no-op 1237 return true; 1238 1239 if (numEvts > MAX_EVT_SUB_CNT) 1240 return false; 1241 1242 act = slabAllocatorAlloc(mMiscInternalThingsSlab); 1243 1244 if (!act) 1245 return false; 1246 1247 act->evtSub.tid = task->tid; 1248 act->evtSub.numEvts = numEvts; 1249 for (i = 0; i < numEvts; i++) 1250 act->evtSub.evts[i] = va_arg(ap, uint32_t); 1251 1252 return osEnqueueEvtOrFree(sub ? EVT_SUBSCRIBE_TO_EVT : EVT_UNSUBSCRIBE_TO_EVT, act, osDeferredActionFreeF); 1253 } 1254 1255 static bool osEventsSubscribeUnsubscribe(bool sub, uint32_t numEvts, ...) 1256 { 1257 bool ret; 1258 va_list ap; 1259 1260 va_start(ap, numEvts); 1261 ret = osEventsSubscribeUnsubscribeV(sub, numEvts, ap); 1262 va_end(ap); 1263 1264 return ret; 1265 } 1266 1267 bool osEventSubscribe(uint32_t tid, uint32_t evtType) 1268 { 1269 (void)tid; 1270 return osEventsSubscribeUnsubscribe(true, 1, evtType); 1271 } 1272 1273 bool osEventUnsubscribe(uint32_t tid, uint32_t evtType) 1274 { 1275 (void)tid; 1276 return osEventsSubscribeUnsubscribe(false, 1, evtType); 1277 } 1278 1279 bool osEventsSubscribe(uint32_t numEvts, ...) 1280 { 1281 bool ret; 1282 va_list ap; 1283 1284 va_start(ap, numEvts); 1285 ret = osEventsSubscribeUnsubscribeV(true, numEvts, ap); 1286 va_end(ap); 1287 1288 return ret; 1289 } 1290 1291 bool osEventsUnsubscribe(uint32_t numEvts, ...) 1292 { 1293 bool ret; 1294 va_list ap; 1295 1296 va_start(ap, numEvts); 1297 ret = osEventsSubscribeUnsubscribeV(false, numEvts, ap); 1298 va_end(ap); 1299 1300 return ret; 1301 } 1302 1303 static bool osEnqueueEvtCommon(uint32_t evt, void *evtData, TaggedPtr evtFreeInfo, bool urgent) 1304 { 1305 struct Task *task = osGetCurrentTask(); 1306 uint32_t evtType = EVENT_WITH_ORIGIN(evt, osGetCurrentTid()); 1307 1308 osTaskAddIoCount(task, 1); 1309 1310 if (osTaskTestFlags(task, FL_TASK_STOPPED) || 1311 !evtQueueEnqueue(mEvtsInternal, evtType, evtData, evtFreeInfo, urgent)) { 1312 osTaskAddIoCount(task, -1); 1313 return false; 1314 } 1315 1316 return true; 1317 } 1318 1319 void osRemovePendingEvents(bool (*match)(uint32_t evtType, const void *evtData, void *context), void *context) 1320 { 1321 evtQueueRemoveAllMatching(mEvtsInternal, match, context); 1322 } 1323 1324 bool osEnqueueEvt(uint32_t evtType, void *evtData, EventFreeF evtFreeF) 1325 { 1326 return osEnqueueEvtCommon(evtType, evtData, taggedPtrMakeFromPtr(evtFreeF), false); 1327 } 1328 1329 bool osEnqueueEvtOrFree(uint32_t evtType, void *evtData, EventFreeF evtFreeF) 1330 { 1331 bool success = osEnqueueEvt(evtType, evtData, evtFreeF); 1332 1333 if (!success && evtFreeF) 1334 evtFreeF(evtData); 1335 1336 return success; 1337 } 1338 1339 bool osEnqueueEvtAsApp(uint32_t evtType, void *evtData, bool freeData) 1340 { 1341 // compatibility with existing external apps 1342 if (evtType & EVENT_TYPE_BIT_DISCARDABLE_COMPAT) 1343 evtType |= EVENT_TYPE_BIT_DISCARDABLE; 1344 1345 return osEnqueueEvtCommon(evtType, evtData, freeData ? taggedPtrMakeFromUint(osGetCurrentTid()) : taggedPtrMakeFromPtr(NULL), false); 1346 } 1347 1348 bool osDefer(OsDeferCbkF callback, void *cookie, bool urgent) 1349 { 1350 union SeosInternalSlabData *act = slabAllocatorAlloc(mMiscInternalThingsSlab); 1351 if (!act) 1352 return false; 1353 1354 act->deferred.callback = callback; 1355 act->deferred.cookie = cookie; 1356 1357 if (osEnqueueEvtCommon(EVT_DEFERRED_CALLBACK, act, taggedPtrMakeFromPtr(osDeferredActionFreeF), urgent)) 1358 return true; 1359 1360 slabAllocatorFree(mMiscInternalThingsSlab, act); 1361 return false; 1362 } 1363 1364 static bool osEnqueuePrivateEvtEx(uint32_t evtType, void *evtData, TaggedPtr evtFreeInfo, uint32_t toTid) 1365 { 1366 union SeosInternalSlabData *act = slabAllocatorAlloc(mMiscInternalThingsSlab); 1367 bool result; 1368 1369 if (!act) { 1370 osLog(LOG_ERROR, "[seos] ERROR: osEnqueuePrivateEvtEx: call to slabAllocatorAlloc() failed\n"); 1371 return false; 1372 } 1373 struct Task *task = osGetCurrentTask(); 1374 osTaskAddIoCount(task, 1); 1375 1376 act->privateEvt.evtType = evtType; 1377 act->privateEvt.evtData = evtData; 1378 act->privateEvt.evtFreeInfo = evtFreeInfo; 1379 act->privateEvt.fromTid = task->tid; 1380 act->privateEvt.toTid = toTid; 1381 1382 osSetCurrentTask(mSystemTask); 1383 result = osEnqueueEvtOrFree(EVT_PRIVATE_EVT, act, osPrivateEvtFreeF); 1384 osSetCurrentTask(task); 1385 return result; 1386 } 1387 1388 // only called to send events for CHRE apps 1389 bool osEnqueuePrivateEvtNew(uint16_t evtType, void *evtData, 1390 void (*evtFreeCallback)(uint16_t evtType, void *evtData), 1391 uint32_t toTid) 1392 { 1393 if (!osEnqueuePrivateEvtEx(evtType | (EVT_PRIVATE_CLASS_CHRE << 16), evtData, 1394 taggedPtrMakeFromPtr(evtFreeCallback), toTid)) { 1395 osChreFreeEvent(osGetCurrentTid(), evtFreeCallback, evtType, evtData); 1396 return false; 1397 } 1398 return true; 1399 } 1400 1401 bool osEnqueuePrivateEvt(uint32_t evtType, void *evtData, EventFreeF evtFreeF, uint32_t toTid) 1402 { 1403 return osEnqueuePrivateEvtEx(evtType & EVT_MASK, evtData, taggedPtrMakeFromPtr(evtFreeF), toTid); 1404 } 1405 1406 bool osEnqueuePrivateEvtAsApp(uint32_t evtType, void *evtData, uint32_t toTid) 1407 { 1408 return osEnqueuePrivateEvtEx(evtType & EVT_MASK, evtData, taggedPtrMakeFromUint(osGetCurrentTid()), toTid); 1409 } 1410 1411 bool osTidById(const uint64_t *appId, uint32_t *tid) 1412 { 1413 struct Task *task; 1414 1415 for_each_task(&mTasks, task) { 1416 if (task->app && !memcmp(&task->app->hdr.appId, appId, sizeof(*appId))) { 1417 *tid = task->tid; 1418 return true; 1419 } 1420 } 1421 1422 return false; 1423 } 1424 1425 bool osAppInfoById(uint64_t appId, uint32_t *appIdx, uint32_t *appVer, uint32_t *appSize) 1426 { 1427 uint32_t i = 0; 1428 struct Task *task; 1429 1430 for_each_task(&mTasks, task) { 1431 const struct AppHdr *app = task->app; 1432 if (app && app->hdr.appId == appId) { 1433 *appIdx = i; 1434 *appVer = app->hdr.appVer; 1435 *appSize = app->sect.rel_end; 1436 return true; 1437 } 1438 i++; 1439 } 1440 1441 return false; 1442 } 1443 1444 bool osAppInfoByIndex(uint32_t appIdx, uint64_t *appId, uint32_t *appVer, uint32_t *appSize) 1445 { 1446 struct Task *task; 1447 int i = 0; 1448 1449 for_each_task(&mTasks, task) { 1450 if (i != appIdx) { 1451 ++i; 1452 } else { 1453 const struct AppHdr *app = task->app; 1454 *appId = app->hdr.appId; 1455 *appVer = app->hdr.appVer; 1456 *appSize = app->sect.rel_end; 1457 return true; 1458 } 1459 } 1460 1461 return false; 1462 } 1463 1464 bool osExtAppInfoByIndex(uint32_t appIdx, uint64_t *appId, uint32_t *appVer, uint32_t *appSize) 1465 { 1466 struct Task *task; 1467 int i = 0; 1468 1469 for_each_task(&mTasks, task) { 1470 const struct AppHdr *app = task->app; 1471 if (!(app->hdr.fwFlags & FL_APP_HDR_INTERNAL)) { 1472 if (i != appIdx) { 1473 ++i; 1474 } else { 1475 *appId = app->hdr.appId; 1476 *appVer = app->hdr.appVer; 1477 *appSize = app->sect.rel_end; 1478 return true; 1479 } 1480 } 1481 } 1482 1483 return false; 1484 } 1485 1486 void osLogv(char clevel, uint32_t flags, const char *str, va_list vl) 1487 { 1488 void *userData = platLogAllocUserData(); 1489 1490 platLogPutcharF(userData, clevel); 1491 cvprintf(platLogPutcharF, flags, userData, str, vl); 1492 1493 platLogFlush(userData); 1494 } 1495 1496 void osLog(enum LogLevel level, const char *str, ...) 1497 { 1498 va_list vl; 1499 1500 va_start(vl, str); 1501 osLogv((char)level, 0, str, vl); 1502 va_end(vl); 1503 } 1504 1505 1506 1507 1508 //Google's public key for Google's apps' signing 1509 const uint8_t __attribute__ ((section (".pubkeys"))) _RSA_KEY_GOOGLE[] = { 1510 0xd9, 0xcd, 0x83, 0xae, 0xb5, 0x9e, 0xe4, 0x63, 0xf1, 0x4c, 0x26, 0x6a, 0x1c, 0xeb, 0x4c, 0x12, 1511 0x5b, 0xa6, 0x71, 0x7f, 0xa2, 0x4e, 0x7b, 0xa2, 0xee, 0x02, 0x86, 0xfc, 0x0d, 0x31, 0x26, 0x74, 1512 0x1e, 0x9c, 0x41, 0x43, 0xba, 0x16, 0xe9, 0x23, 0x4d, 0xfc, 0xc4, 0xca, 0xcc, 0xd5, 0x27, 0x2f, 1513 0x16, 0x4c, 0xe2, 0x85, 0x39, 0xb3, 0x0b, 0xcb, 0x73, 0xb6, 0x56, 0xc2, 0x98, 0x83, 0xf6, 0xfa, 1514 0x7a, 0x6e, 0xa0, 0x9a, 0xcc, 0x83, 0x97, 0x9d, 0xde, 0x89, 0xb2, 0xa3, 0x05, 0x46, 0x0c, 0x12, 1515 0xae, 0x01, 0xf8, 0x0c, 0xf5, 0x39, 0x32, 0xe5, 0x94, 0xb9, 0xa0, 0x8f, 0x19, 0xe4, 0x39, 0x54, 1516 0xad, 0xdb, 0x81, 0x60, 0x74, 0x63, 0xd5, 0x80, 0x3b, 0xd2, 0x88, 0xf4, 0xcb, 0x6b, 0x47, 0x28, 1517 0x80, 0xb0, 0xd1, 0x89, 0x6d, 0xd9, 0x62, 0x88, 0x81, 0xd6, 0xc0, 0x13, 0x88, 0x91, 0xfb, 0x7d, 1518 0xa3, 0x7f, 0xa5, 0x40, 0x12, 0xfb, 0x77, 0x77, 0x4c, 0x98, 0xe4, 0xd3, 0x62, 0x39, 0xcc, 0x63, 1519 0x34, 0x76, 0xb9, 0x12, 0x67, 0xfe, 0x83, 0x23, 0x5d, 0x40, 0x6b, 0x77, 0x93, 0xd6, 0xc0, 0x86, 1520 0x6c, 0x03, 0x14, 0xdf, 0x78, 0x2d, 0xe0, 0x9b, 0x5e, 0x05, 0xf0, 0x93, 0xbd, 0x03, 0x1d, 0x17, 1521 0x56, 0x88, 0x58, 0x25, 0xa6, 0xae, 0x63, 0xd2, 0x01, 0x43, 0xbb, 0x7e, 0x7a, 0xa5, 0x62, 0xdf, 1522 0x8a, 0x31, 0xbd, 0x24, 0x1b, 0x1b, 0xeb, 0xfe, 0xdf, 0xd1, 0x31, 0x61, 0x4a, 0xfa, 0xdd, 0x6e, 1523 0x62, 0x0c, 0xa9, 0xcd, 0x08, 0x0c, 0xa1, 0x1b, 0xe7, 0xf2, 0xed, 0x36, 0x22, 0xd0, 0x5d, 0x80, 1524 0x78, 0xeb, 0x6f, 0x5a, 0x58, 0x18, 0xb5, 0xaf, 0x82, 0x77, 0x4c, 0x95, 0xce, 0xc6, 0x4d, 0xda, 1525 0xca, 0xef, 0x68, 0xa6, 0x6d, 0x71, 0x4d, 0xf1, 0x14, 0xaf, 0x68, 0x25, 0xb8, 0xf3, 0xff, 0xbe, 1526 }; 1527 1528 1529 #ifdef DEBUG 1530 1531 //debug key whose privatekey is checked in as misc/debug.privkey 1532 const uint8_t __attribute__ ((section (".pubkeys"))) _RSA_KEY_GOOGLE_DEBUG[] = { 1533 0x2d, 0xff, 0xa6, 0xb5, 0x65, 0x87, 0xbe, 0x61, 0xd1, 0xe1, 0x67, 0x10, 0xa1, 0x9b, 0xc6, 0xca, 1534 0xc8, 0xb1, 0xf0, 0xaa, 0x88, 0x60, 0x9f, 0xa1, 0x00, 0xa1, 0x41, 0x9a, 0xd8, 0xb4, 0xd1, 0x74, 1535 0x9f, 0x23, 0x28, 0x0d, 0xc2, 0xc4, 0x37, 0x15, 0xb1, 0x4a, 0x80, 0xca, 0xab, 0xb9, 0xba, 0x09, 1536 0x7d, 0xf8, 0x44, 0xd6, 0xa2, 0x72, 0x28, 0x12, 0x91, 0xf6, 0xa5, 0xea, 0xbd, 0xf8, 0x81, 0x6b, 1537 0xd2, 0x3c, 0x50, 0xa2, 0xc6, 0x19, 0x54, 0x48, 0x45, 0x8d, 0x92, 0xac, 0x01, 0xda, 0x14, 0x32, 1538 0xdb, 0x05, 0x82, 0x06, 0x30, 0x25, 0x09, 0x7f, 0x5a, 0xbb, 0x86, 0x64, 0x70, 0x98, 0x64, 0x1e, 1539 0xe6, 0xca, 0x1d, 0xc1, 0xcb, 0xb6, 0x23, 0xd2, 0x62, 0x00, 0x46, 0x97, 0xd5, 0xcc, 0xe6, 0x36, 1540 0x72, 0xec, 0x2e, 0x43, 0x1f, 0x0a, 0xaf, 0xf2, 0x51, 0xe1, 0xcd, 0xd2, 0x98, 0x5d, 0x7b, 0x64, 1541 0xeb, 0xd1, 0x35, 0x4d, 0x59, 0x13, 0x82, 0x6c, 0xbd, 0xc4, 0xa2, 0xfc, 0xad, 0x64, 0x73, 0xe2, 1542 0x71, 0xb5, 0xf4, 0x45, 0x53, 0x6b, 0xc3, 0x56, 0xb9, 0x8b, 0x3d, 0xeb, 0x00, 0x48, 0x6e, 0x29, 1543 0xb1, 0xb4, 0x8e, 0x2e, 0x43, 0x39, 0xef, 0x45, 0xa0, 0xb8, 0x8b, 0x5f, 0x80, 0xb5, 0x0c, 0xc3, 1544 0x03, 0xe3, 0xda, 0x51, 0xdc, 0xec, 0x80, 0x2c, 0x0c, 0xdc, 0xe2, 0x71, 0x0a, 0x14, 0x4f, 0x2c, 1545 0x22, 0x2b, 0x0e, 0xd1, 0x8b, 0x8f, 0x93, 0xd2, 0xf3, 0xec, 0x3a, 0x5a, 0x1c, 0xba, 0x80, 0x54, 1546 0x23, 0x7f, 0xb0, 0x54, 0x8b, 0xe3, 0x98, 0x22, 0xbb, 0x4b, 0xd0, 0x29, 0x5f, 0xce, 0xf2, 0xaa, 1547 0x99, 0x89, 0xf2, 0xb7, 0x5d, 0x8d, 0xb2, 0x72, 0x0b, 0x52, 0x02, 0xb8, 0xa4, 0x37, 0xa0, 0x3b, 1548 0xfe, 0x0a, 0xbc, 0xb3, 0xb3, 0xed, 0x8f, 0x8c, 0x42, 0x59, 0xbe, 0x4e, 0x31, 0xed, 0x11, 0x9b, 1549 }; 1550 1551 #endif 1552