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 <stdbool.h> 26 #include <stdint.h> 27 #include <stdarg.h> 28 #include <stddef.h> 29 #include <eventQ.h> 30 #include <plat/app.h> 31 #include <eventnums.h> 32 #include <variant/variant.h> 33 #include "toolchain.h" 34 35 #include <nanohub/nanohub.h> 36 37 //#define SEGMENT_CRC_SUPPORT 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 typedef void (*OsDeferCbkF)(void *); 130 131 typedef void (*EventFreeF)(void* event); 132 133 SET_PACKED_STRUCT_MODE_ON 134 struct SeosEedataEncrKeyData { 135 uint64_t keyID; 136 uint8_t key[32]; 137 } ATTRIBUTE_PACKED; 138 SET_PACKED_STRUCT_MODE_OFF 139 140 /* ==== ABOUT THE "urgent" FLAG ==== 141 * 142 * Do not set "urgent" unless you understand all the repercussions! What repercussions you might ask? 143 * Setting this flag will place your defer request at the front of the queue. This is useful for enqueueing work 144 * from interrupt context that needs to be done "very very soon"(tm). Doing this will delay all other work requests 145 * that have heretofore been peacefully queueing in full faith and with complete belief in fairness of our "FIFO"-ness. 146 * Please be appreciative of this fact and do not abuse this! Example: if you are setting "urgent" flag outside of interrupt 147 * context, you're very very likely wrong. That is not to say that being in interrupt context is a free pass to set this! 148 */ 149 150 // osMainInit is exposed for testing only, it must never be called for any reason at all by anyone 151 void osMainInit(void); 152 // osMainDequeueLoop is exposed for testing only, it must never be called for any reason at all by anyone 153 void osMainDequeueLoop(void); 154 void osMain(void); 155 156 bool osEventSubscribe(uint32_t tid, uint32_t evtType); /* async */ 157 bool osEventUnsubscribe(uint32_t tid, uint32_t evtType); /* async */ 158 bool osEventsSubscribe(uint32_t numEvts, ...); /* async */ 159 bool osEventsUnsubscribe(uint32_t numEvts, ...); /* async */ 160 161 bool osEnqueuePrivateEvt(uint32_t evtType, void *evtData, EventFreeF evtFreeF, uint32_t toTid); 162 bool osEnqueuePrivateEvtAsApp(uint32_t evtType, void *evtData, uint32_t toTid); 163 bool osEnqueuePrivateEvtNew(uint16_t evtType, void *evtData, 164 void (*evtFreeCallback)(uint16_t eventType, void *eventData), 165 uint32_t toTid); 166 167 bool osEnqueueEvt(uint32_t evtType, void *evtData, EventFreeF evtFreeF); 168 bool osEnqueueEvtOrFree(uint32_t evtType, void *evtData, EventFreeF evtFreeF); 169 bool osEnqueueEvtAsApp(uint32_t evtType, void *evtData, bool freeData); 170 void osRemovePendingEvents(bool (*match)(uint32_t evtType, const void *evtData, void *context), void *context); 171 172 bool osDefer(OsDeferCbkF callback, void *cookie, bool urgent); 173 174 bool osTidById(uint64_t *appId, uint32_t *tid); 175 bool osAppInfoById(uint64_t appId, uint32_t *appIdx, uint32_t *appVer, uint32_t *appSize); 176 bool osAppInfoByIndex(uint32_t appIdx, uint64_t *appId, uint32_t *appVer, uint32_t *appSize); 177 bool osExtAppInfoByIndex(uint32_t appIdx, uint64_t *appId, uint32_t *appVer, uint32_t *appSize); 178 uint32_t osGetCurrentTid(); 179 uint32_t osSetCurrentTid(uint32_t); 180 181 struct AppHdr *osAppSegmentCreate(uint32_t size); 182 bool osAppSegmentClose(struct AppHdr *app, uint32_t segSize, uint32_t segState); 183 bool osAppSegmentSetState(const struct AppHdr *app, uint32_t segState); 184 bool osSegmentSetSize(struct Segment *seg, uint32_t size); 185 bool osAppWipeData(struct AppHdr *app); 186 struct Segment *osGetSegment(const struct AppHdr *app); 187 struct Segment *osSegmentGetEnd(); 188 189 static inline int32_t osSegmentGetSize(const struct Segment *seg) 190 { 191 return seg ? seg->size[0] | (seg->size[1] << 8) | (seg->size[2] << 16) : SEG_SIZE_INVALID; 192 } 193 194 static inline uint32_t osSegmentGetState(const struct Segment *seg) 195 { 196 return seg ? seg->state : SEG_STATE_INVALID; 197 } 198 199 static inline struct AppHdr *osSegmentGetData(const struct Segment *seg) 200 { 201 return (struct AppHdr*)(&seg[1]); 202 } 203 204 #ifdef SEGMENT_CRC_SUPPORT 205 206 struct SegmentFooter 207 { 208 uint32_t crc; 209 }; 210 211 #define FOOTER_SIZE sizeof(struct SegmentFooter) 212 #else 213 #define FOOTER_SIZE 0 214 #endif 215 216 static inline uint32_t osSegmentSizeAlignedWithFooter(uint32_t size) 217 { 218 return ((size + 3) & ~3) + FOOTER_SIZE; 219 } 220 221 static inline const struct Segment *osSegmentSizeGetNext(const struct Segment *seg, uint32_t size) 222 { 223 struct Segment *next = (struct Segment *)(((uint8_t*)seg) + 224 osSegmentSizeAlignedWithFooter(size) + 225 sizeof(*seg) 226 ); 227 return seg ? next : NULL; 228 } 229 230 static inline const struct Segment *osSegmentGetNext(const struct Segment *seg) 231 { 232 return osSegmentSizeGetNext(seg, osSegmentGetSize(seg)); 233 } 234 235 static inline uint32_t osAppSegmentGetState(const struct AppHdr *app) 236 { 237 return osSegmentGetState(osGetSegment(app)); 238 } 239 240 struct SegmentIterator { 241 const struct Segment *shared; 242 const struct Segment *sharedEnd; 243 const struct Segment *seg; 244 }; 245 246 void osSegmentIteratorInit(struct SegmentIterator *it); 247 248 static inline bool osSegmentIteratorNext(struct SegmentIterator *it) 249 { 250 const struct Segment *seg = it->shared; 251 const struct Segment *next = seg < it->sharedEnd ? osSegmentGetNext(seg) : it->sharedEnd; 252 253 it->shared = next; 254 it->seg = seg; 255 256 return seg < it->sharedEnd; 257 } 258 259 bool osWriteShared(void *dest, const void *src, uint32_t len); 260 bool osEraseShared(); 261 262 //event retaining support 263 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 264 void osFreeRetainedEvent(uint32_t evtType, void *evtData, TaggedPtr *evtFreeingInfoP); 265 266 uint32_t osExtAppStopApps(uint64_t appId); 267 uint32_t osExtAppEraseApps(uint64_t appId); 268 uint32_t osExtAppStartApps(uint64_t appId); 269 270 bool osAppIsChre(uint16_t tid); 271 272 /* Logging */ 273 enum LogLevel { 274 LOG_ERROR = 'E', 275 LOG_WARN = 'W', 276 LOG_INFO = 'I', 277 LOG_DEBUG = 'D', 278 LOG_VERBOSE = 'V', 279 }; 280 281 void osLogv(char clevel, uint32_t flags, const char *str, va_list vl); 282 void osLog(enum LogLevel level, const char *str, ...) PRINTF_ATTRIBUTE(2, 3); 283 284 #ifndef INTERNAL_APP_INIT 285 #define INTERNAL_APP_INIT(_id, _ver, _init, _end, _event) \ 286 SET_INTERNAL_LOCATION(location, ".internal_app_init")static const struct AppHdr \ 287 SET_INTERNAL_LOCATION_ATTRIBUTES(used, section (".internal_app_init")) mAppHdr = { \ 288 .hdr.magic = APP_HDR_MAGIC, \ 289 .hdr.fwVer = APP_HDR_VER_CUR, \ 290 .hdr.fwFlags = FL_APP_HDR_INTERNAL | FL_APP_HDR_APPLICATION, \ 291 .hdr.appId = (_id), \ 292 .hdr.appVer = (_ver), \ 293 .hdr.payInfoType = LAYOUT_APP, \ 294 .vec.init = (uint32_t)(_init), \ 295 .vec.end = (uint32_t)(_end), \ 296 .vec.handle = (uint32_t)(_event) \ 297 } 298 #endif 299 300 #ifndef APP_INIT 301 #define APP_INIT(_ver, _init, _end, _event) \ 302 extern const struct AppFuncs _mAppFuncs; \ 303 const struct AppFuncs SET_EXTERNAL_APP_ATTRIBUTES(used, section (".app_init"), \ 304 visibility("default")) _mAppFuncs = { \ 305 .init = (_init), \ 306 .end = (_end), \ 307 .handle = (_event) \ 308 }; \ 309 const uint32_t SET_EXTERNAL_APP_VERSION(used, section (".app_version"), \ 310 visibility("default")) _mAppVer = _ver 311 #endif 312 313 314 #ifdef __cplusplus 315 } 316 #endif 317 318 #endif 319