Home | History | Annotate | Download | only in inc
      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 #ifndef _SEOS_H_
     18 #define _SEOS_H_
     19 
     20 #ifdef __cplusplus
     21 extern "C" {
     22 #endif
     23 
     24 #include <plat/taggedPtr.h>
     25 #include <plat/wdt.h>
     26 #include <stdbool.h>
     27 #include <stdint.h>
     28 #include <stdarg.h>
     29 #include <stddef.h>
     30 #include <eventQ.h>
     31 #include <plat/app.h>
     32 #include <eventnums.h>
     33 #include <variant/variant.h>
     34 #include <crc.h>
     35 #include "toolchain.h"
     36 
     37 #include <nanohub/nanohub.h>
     38 
     39 #ifndef MAX_TASKS
     40 /* Default to 16 tasks, override may come from variant.h */
     41 #define MAX_TASKS                        16
     42 #endif
     43 
     44 #define MAX_EMBEDDED_EVT_SUBS             6 /* tradeoff, no wrong answer */
     45 #define TASK_IDX_BITS                     8 /* should be big enough to hold MAX_TASKS, but still fit in TaskIndex */
     46 
     47 typedef uint8_t TaskIndex;
     48 
     49 struct AppFuncs { /* do not rearrange */
     50     /* lifescycle */
     51     bool (*init)(uint32_t yourTid);   //simple init only - no ints on at this time
     52     void (*end)(void);                //die quickly please
     53     /* events */
     54     void (*handle)(uint32_t evtType, const void* evtData);
     55 };
     56 
     57 /* NOTE: [TASK ID]
     58  * TID is designed to be 16-bit; there is no reason for TID to become bigger than that on a system
     59  * with typical RAM size of 64kB. However, in NO CASE TID values should overlap with TaggedPtr TAG mask,
     60  * which is currently defined as 0x80000000.
     61  */
     62 
     63 #define TASK_TID_BITS 16
     64 
     65 #define TASK_TID_MASK ((1 << TASK_TID_BITS) - 1)
     66 #define TASK_TID_INCREMENT (1 << TASK_IDX_BITS)
     67 #define TASK_TID_IDX_MASK ((1 << TASK_IDX_BITS) - 1)
     68 #define TASK_TID_COUNTER_MASK ((1 << TASK_TID_BITS) - TASK_TID_INCREMENT)
     69 
     70 #if MAX_TASKS > TASK_TID_IDX_MASK
     71 #error MAX_TASKS does not fit in TASK_TID_BITS
     72 #endif
     73 
     74 #define OS_SYSTEM_TID                    0
     75 #define OS_VER                           0x0000
     76 
     77 // FIXME: compatibility: keep key ID 1 until key update is functional
     78 //#define ENCR_KEY_GOOGLE_PREPOPULATED     0x041F010000000001
     79 #define ENCR_KEY_GOOGLE_PREPOPULATED     1 // our key ID is 1
     80 
     81 #define APP_HDR_MAGIC              NANOAPP_FW_MAGIC
     82 #define APP_HDR_VER_CUR            1
     83 
     84 #define FL_APP_HDR_INTERNAL        0x0001 // to be able to fork behavior at run time for internal apps
     85 #define FL_APP_HDR_APPLICATION     0x0002 // image has AppHdr; otherwise is has AppInfo header
     86 #define FL_APP_HDR_SECURE          0x0004 // secure content, needs to be zero-filled when discarded
     87 #define FL_APP_HDR_VOLATILE        0x0008 // volatile content, segment shall be deleted after operation is complete
     88 #define FL_APP_HDR_CHRE            0x0010 // app is CHRE API compatible
     89 #define FL_KEY_HDR_DELETE          0x8000 // key-specific flag: if set key id refers to existing key which has to be deleted
     90 
     91 /* app ids are split into vendor and app parts. vendor parts are assigned by google. App parts are free for each vendor to assign at will */
     92 #define KEY_ID_MAKE(vendor, key)   ((((uint64_t)(vendor)) << 24) | ((key) & KEY_SEQ_ID_ANY))
     93 #define HW_ID_MAKE(vendor, ver)    ((((uint64_t)(vendor)) << 24) | (PLATFORM_ID(ver) & HW_ID_ANY))
     94 #define KEY_SEQ_ID_ANY             UINT64_C(0xFFFFFF)
     95 #define HW_ID_ANY                  UINT64_C(0xFFFFFF)
     96 #define PLATFORM_ID(ver)           ((((PLATFORM_HW_TYPE) & 0xFFFF) << 8) | (ver & 0xFF))
     97 
     98 #define APP_INFO_CMD_ADD_KEY 1
     99 #define APP_INFO_CMD_REMOVE_KEY 2
    100 #define APP_INFO_CMD_OS_UPDATE 3
    101 
    102 #define SEG_STATE_INVALID UINT32_C(0xFFFFFFFF)
    103 #define SEG_SIZE_MAX      UINT32_C(0x00FFFFFF)
    104 #define SEG_SIZE_INVALID  (-1)
    105 #define SEG_ST(arg) (((arg) << 4) | (arg))
    106 
    107 #define SEG_ID_EMPTY    0xF
    108 #define SEG_ID_RESERVED 0x7 // upload in progress
    109 #define SEG_ID_VALID    0x3 // CRC-32 valid
    110 #define SEG_ID_ERASED   0x0 // segment erased
    111 
    112 #define SEG_ST_EMPTY    SEG_ST(SEG_ID_EMPTY)
    113 #define SEG_ST_RESERVED SEG_ST(SEG_ID_RESERVED)
    114 #define SEG_ST_VALID    SEG_ST(SEG_ID_VALID)
    115 #define SEG_ST_ERASED   SEG_ST(SEG_ID_ERASED)
    116 
    117 struct Segment {
    118     uint8_t  state;   // 0xFF: empty; bit7=0: segment present; bit6=0: size valid; bit5=0: CRC-32 valid; bit4=0:segment erased;
    119                       // bits 3-0 replicate bits7-4;
    120     uint8_t  size[3]; // actual stored size in flash, initially filled with 0xFF
    121                       // updated after flash operation is completed (successfully or not)
    122 };
    123 
    124 struct AppEventFreeData { //goes with EVT_APP_FREE_EVT_DATA
    125     uint32_t evtType;
    126     void* evtData;
    127 };
    128 
    129 struct AppEventStartStop {
    130     uint64_t appId;
    131     uint32_t version;
    132     uint16_t tid;
    133 };
    134 
    135 typedef void (*OsDeferCbkF)(void *);
    136 
    137 typedef void (*EventFreeF)(void* event);
    138 
    139 SET_PACKED_STRUCT_MODE_ON
    140 struct SeosEedataEncrKeyData {
    141     uint64_t keyID;
    142     uint8_t key[32];
    143 } ATTRIBUTE_PACKED;
    144 SET_PACKED_STRUCT_MODE_OFF
    145 
    146 /* ==== ABOUT THE "urgent" FLAG ====
    147  *
    148  * Do not set "urgent" unless you understand all the repercussions! What repercussions you might ask?
    149  * Setting this flag will place your defer request at the front of the queue. This is useful for enqueueing work
    150  * from interrupt context that needs to be done "very very soon"(tm). Doing this will delay all other work requests
    151  * that have heretofore been peacefully queueing in full faith and with complete belief in fairness of our "FIFO"-ness.
    152  * Please be appreciative of this fact and do not abuse this! Example: if you are setting "urgent" flag outside of interrupt
    153  * context, you're very very likely wrong. That is not to say that being in interrupt context is a free pass to set this!
    154  */
    155 
    156 // osMainInit is exposed for testing only, it must never be called for any reason at all by anyone
    157 void osMainInit(void);
    158 // osMainDequeueLoop is exposed for testing only, it must never be called for any reason at all by anyone
    159 void osMainDequeueLoop(void);
    160 void osMain(void);
    161 
    162 bool osEventSubscribe(uint32_t tid, uint32_t evtType); /* async */
    163 bool osEventUnsubscribe(uint32_t tid, uint32_t evtType);  /* async */
    164 bool osEventsSubscribe(uint32_t numEvts, ...); /* async */
    165 bool osEventsUnsubscribe(uint32_t numEvts, ...); /* async */
    166 
    167 bool osEnqueuePrivateEvt(uint32_t evtType, void *evtData, EventFreeF evtFreeF, uint32_t toTid);
    168 bool osEnqueuePrivateEvtAsApp(uint32_t evtType, void *evtData, uint32_t toTid);
    169 bool osEnqueuePrivateEvtNew(uint16_t evtType, void *evtData,
    170                                    void (*evtFreeCallback)(uint16_t eventType, void *eventData),
    171                                    uint32_t toTid);
    172 
    173 bool osEnqueueEvt(uint32_t evtType, void *evtData, EventFreeF evtFreeF);
    174 bool osEnqueueEvtOrFree(uint32_t evtType, void *evtData, EventFreeF evtFreeF);
    175 bool osEnqueueEvtAsApp(uint32_t evtType, void *evtData, bool freeData);
    176 void osRemovePendingEvents(bool (*match)(uint32_t evtType, const void *evtData, void *context), void *context);
    177 
    178 bool osDefer(OsDeferCbkF callback, void *cookie, bool urgent);
    179 
    180 bool osTidById(const uint64_t *appId, uint32_t *tid);
    181 bool osAppInfoById(uint64_t appId, uint32_t *appIdx, uint32_t *appVer, uint32_t *appSize);
    182 bool osAppInfoByIndex(uint32_t appIdx, uint64_t *appId, uint32_t *appVer, uint32_t *appSize);
    183 bool osExtAppInfoByIndex(uint32_t appIdx, uint64_t *appId, uint32_t *appVer, uint32_t *appSize);
    184 uint32_t osGetCurrentTid();
    185 uint32_t osSetCurrentTid(uint32_t);
    186 
    187 struct AppHdr *osAppSegmentCreate(uint32_t size);
    188 bool osAppSegmentClose(struct AppHdr *app, uint32_t segSize, uint32_t segState);
    189 bool osAppSegmentSetState(const struct AppHdr *app, uint32_t segState);
    190 bool osSegmentSetSize(struct Segment *seg, uint32_t size);
    191 bool osAppWipeData(struct AppHdr *app);
    192 struct Segment *osSegmentGetEnd();
    193 uint32_t osSegmentGetFree();
    194 struct Segment *osGetSegment(const struct AppHdr *app);
    195 
    196 static inline int32_t osSegmentGetSize(const struct Segment *seg)
    197 {
    198     return seg ? seg->size[0] | (seg->size[1] << 8) | (seg->size[2] << 16) : SEG_SIZE_INVALID;
    199 }
    200 
    201 static inline uint32_t osSegmentGetState(const struct Segment *seg)
    202 {
    203     return seg ? seg->state : SEG_STATE_INVALID;
    204 }
    205 
    206 static inline struct AppHdr *osSegmentGetData(const struct Segment *seg)
    207 {
    208     return (struct AppHdr*)(&seg[1]);
    209 }
    210 
    211 struct SegmentFooter
    212 {
    213     uint32_t crc;
    214 };
    215 
    216 #define FOOTER_SIZE sizeof(struct SegmentFooter)
    217 
    218 static inline uint32_t osSegmentGetCrc(const struct Segment *seg)
    219 {
    220     struct SegmentFooter *footer = (struct SegmentFooter *)(((uint8_t*)seg) +
    221         ((osSegmentGetSize(seg) + 3) & ~3) + sizeof(*seg));
    222     return footer ? footer->crc : 0xFFFFFFFF;
    223 }
    224 
    225 static inline uint32_t osSegmentSizeAlignedWithFooter(uint32_t size)
    226 {
    227     return ((size + 3) & ~3) + FOOTER_SIZE;
    228 }
    229 
    230 static inline const struct Segment *osSegmentSizeGetNext(const struct Segment *seg, uint32_t size)
    231 {
    232     struct Segment *next = (struct Segment *)(((uint8_t*)seg) +
    233                                               osSegmentSizeAlignedWithFooter(size) +
    234                                               sizeof(*seg)
    235                                               );
    236     return seg ? next : NULL;
    237 }
    238 
    239 static inline const struct Segment *osSegmentGetNext(const struct Segment *seg)
    240 {
    241     return osSegmentSizeGetNext(seg, osSegmentGetSize(seg));
    242 }
    243 
    244 static inline uint32_t osAppSegmentGetState(const struct AppHdr *app)
    245 {
    246     return osSegmentGetState(osGetSegment(app));
    247 }
    248 
    249 static inline uint32_t osAppSegmentGetCrc(const struct AppHdr *app)
    250 {
    251     return osSegmentGetCrc(osGetSegment(app));
    252 }
    253 
    254 static inline uint32_t osAppSegmentCalcCrcResidue(const struct AppHdr *app)
    255 {
    256     struct Segment *seg = osGetSegment(app);
    257     uint32_t size = osSegmentSizeAlignedWithFooter(osSegmentGetSize(seg));
    258     uint32_t crc;
    259 
    260     wdtDisableClk();
    261     crc = soft_crc32((uint8_t*)seg, size + sizeof(*seg), ~0);
    262     wdtEnableClk();
    263 
    264     return crc;
    265 }
    266 
    267 struct SegmentIterator {
    268     const struct Segment *shared;
    269     const struct Segment *sharedEnd;
    270     const struct Segment *seg;
    271 };
    272 
    273 void osSegmentIteratorInit(struct SegmentIterator *it);
    274 
    275 static inline bool osSegmentIteratorNext(struct SegmentIterator *it)
    276 {
    277     const struct Segment *seg = it->shared;
    278     const struct Segment *next = seg < it->sharedEnd ? osSegmentGetNext(seg) : it->sharedEnd;
    279 
    280     it->shared = next;
    281     it->seg = seg;
    282 
    283     return seg < it->sharedEnd;
    284 }
    285 
    286 bool osWriteShared(void *dest, const void *src, uint32_t len);
    287 bool osEraseShared();
    288 
    289 //event retaining support
    290 bool osRetainCurrentEvent(TaggedPtr *evtFreeingInfoP); //called from any apps' event handling to retain current event. Only valid for first app that tries. evtFreeingInfoP filled by call and used to free evt later
    291 void osFreeRetainedEvent(uint32_t evtType, void *evtData, TaggedPtr *evtFreeingInfoP);
    292 
    293 uint32_t osExtAppStopAppsByAppId(uint64_t appId);
    294 uint32_t osExtAppEraseAppsByAppId(uint64_t appId);
    295 uint32_t osExtAppStartAppsByAppId(uint64_t appId);
    296 
    297 bool osAppIsChre(uint16_t tid);
    298 uint32_t osAppChreVersion(uint16_t tid);
    299 
    300 /* Logging */
    301 enum LogLevel {
    302     LOG_ERROR   = 'E',
    303     LOG_WARN    = 'W',
    304     LOG_INFO    = 'I',
    305     LOG_DEBUG   = 'D',
    306     LOG_VERBOSE = 'V',
    307 };
    308 
    309 void osLogv(char clevel, uint32_t flags, const char *str, va_list vl);
    310 void osLog(enum LogLevel level, const char *str, ...) PRINTF_ATTRIBUTE(2, 3);
    311 
    312 #ifndef INTERNAL_APP_INIT
    313 #define INTERNAL_APP_INIT(_id, _ver, _init, _end, _event)                               \
    314 SET_INTERNAL_LOCATION(location, ".internal_app_init")static const struct AppHdr         \
    315 SET_INTERNAL_LOCATION_ATTRIBUTES(used, section (".internal_app_init")) mAppHdr = {      \
    316     .hdr.magic       = APP_HDR_MAGIC,                                                   \
    317     .hdr.fwVer       = APP_HDR_VER_CUR,                                                 \
    318     .hdr.fwFlags     = FL_APP_HDR_INTERNAL | FL_APP_HDR_APPLICATION,                    \
    319     .hdr.appId       = (_id),                                                           \
    320     .hdr.appVer      = (_ver),                                                          \
    321     .hdr.payInfoType = LAYOUT_APP,                                                      \
    322     .vec.init        = (uint32_t)(_init),                                               \
    323     .vec.end         = (uint32_t)(_end),                                                \
    324     .vec.handle      = (uint32_t)(_event)                                               \
    325 }
    326 #endif
    327 
    328 #ifndef INTERNAL_CHRE_APP_INIT
    329 #define INTERNAL_CHRE_APP_INIT(_id, _ver, _init, _end, _event)                          \
    330 SET_INTERNAL_LOCATION(location, ".internal_app_init")static const struct AppHdr         \
    331 SET_INTERNAL_LOCATION_ATTRIBUTES(used, section (".internal_app_init")) mAppHdr = {      \
    332     .hdr.magic        = APP_HDR_MAGIC,                                                  \
    333     .hdr.fwVer        = APP_HDR_VER_CUR,                                                \
    334     .hdr.fwFlags      = FL_APP_HDR_INTERNAL | FL_APP_HDR_APPLICATION | FL_APP_HDR_CHRE, \
    335     .hdr.chreApiMajor = 0x01,                                                           \
    336     .hdr.chreApiMinor = 0x02,                                                           \
    337     .hdr.appId        = (_id),                                                          \
    338     .hdr.appVer       = (_ver),                                                         \
    339     .hdr.payInfoType  = LAYOUT_APP,                                                     \
    340     .vec.init         = (uint32_t)(_init),                                              \
    341     .vec.end          = (uint32_t)(_end),                                               \
    342     .vec.handle       = (uint32_t)(_event)                                              \
    343 }
    344 #endif
    345 
    346 #ifndef APP_INIT
    347 #define APP_INIT(_ver, _init, _end, _event)                                             \
    348 extern const struct AppFuncs _mAppFuncs;                                                \
    349 const struct AppFuncs SET_EXTERNAL_APP_ATTRIBUTES(used, section (".app_init"),          \
    350 visibility("default")) _mAppFuncs = {                                                   \
    351     .init   = (_init),                                                                  \
    352     .end    = (_end),                                                                   \
    353     .handle = (_event)                                                                  \
    354 };                                                                                      \
    355 const uint32_t SET_EXTERNAL_APP_VERSION(used, section (".app_version"),                 \
    356 visibility("default")) _mAppVer = _ver
    357 #endif
    358 
    359 
    360 #ifdef __cplusplus
    361 }
    362 #endif
    363 
    364 #endif
    365