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