blob: 20491c6e37f94266f322bd79e83b580c679ade55 [file] [log] [blame]
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _SEOS_H_
#define _SEOS_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <plat/inc/taggedPtr.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdarg.h>
#include <eventQ.h>
#include <plat/inc/app.h>
#include <eventnums.h>
#include "toolchain.h"
#define MAX_TASKS 16
#define MAX_EMBEDDED_EVT_SUBS 6 /* tradeoff, no wrong answer */
#define TASK_IDX_BITS 8 /* should be big enough to hold MAX_TASKS, but still fit in TaskIndex */
typedef uint8_t TaskIndex;
/* NOTE: [TASK ID]
* TID is designed to be 16-bit; there is no reason for TID to become bigger than that on a system
* with typical RAM size of 64kB. However, in NO CASE TID values should overlap with TaggedPtr TAG mask,
* which is currently defined as 0x80000000.
*/
#define TASK_TID_BITS 16
#define TASK_TID_MASK ((1 << TASK_TID_BITS) - 1)
#define TASK_TID_INCREMENT (1 << TASK_IDX_BITS)
#define TASK_TID_IDX_MASK ((1 << TASK_IDX_BITS) - 1)
#define TASK_TID_COUNTER_MASK ((1 << TASK_TID_BITS) - TASK_TID_INCREMENT)
#if MAX_TASKS > TASK_TID_IDX_MASK
#error MAX_TASKS does not fit in TASK_TID_BITS
#endif
#define OS_SYSTEM_TID 0
#define OS_VER 0x0000
#define ENCR_KEY_GOOGLE_PREPOPULATED 1 // our key ID is 1
struct AppFuncs { /* do not rearrange */
/* lifescycle */
bool (*init)(uint32_t yourTid); //simple init only - no ints on at this time
void (*end)(void); //die quickly please
/* events */
void (*handle)(uint32_t evtType, const void* evtData);
};
#define APP_HDR_MAGIC "GoogleNanoApp"
#define APP_HDR_VER_CUR 0
#define APP_HDR_MARKER_UPLOADING 0xFFFF
#define APP_HDR_MARKER_VERIFYING 0xFFFE
#define APP_HDR_MARKER_VALID 0xFF00
#define APP_HDR_MARKER_INTERNAL 0xFF01 //no external app should at any point have this marker value!
#define APP_HDR_MARKER_DELETED 0x0000
/* 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 */
#define APP_ID_FIRST_USABLE 0x0100000000000000ULL //all app ids lower than this are reserved for google's internal use
#define APP_ID_GET_VENDOR(appid) ((appid) >> 24)
#define APP_ID_GET_SEQ_ID(appid) ((appid) & 0xFFFFFF)
#define APP_ID_MAKE(vendor, app) ((((uint64_t)(vendor)) << 24) | ((app) & APP_SEQ_ID_ANY))
#define APP_ID_VENDOR_GOOGLE UINT64_C(0x476F6F676C) // "Googl"
#define APP_VENDOR_ANY UINT64_C(0xFFFFFFFFFF)
#define APP_SEQ_ID_ANY UINT64_C(0xFFFFFF)
#define APP_ID_ANY UINT64_C(0xFFFFFFFFFFFFFFFF)
struct AppHdr {
char magic[13];
uint8_t fmtVer; //app header format version
uint16_t marker;
uint64_t appId;
uint32_t data_start;
uint32_t data_end;
uint32_t data_data;
uint32_t bss_start;
uint32_t bss_end;
uint32_t got_start;
uint32_t got_end;
uint32_t rel_start;
uint32_t rel_end;
uint32_t appVer; //version of actual app
uint32_t rfu;
struct AppFuncs funcs;
};
struct AppEventFreeData { //goes with EVT_APP_FREE_EVT_DATA
uint32_t evtType;
void* evtData;
};
typedef void (*OsDeferCbkF)(void *);
typedef void (*EventFreeF)(void* event);
SET_PACKED_STRUCT_MODE_ON
struct SeosEedataEncrKeyData {
uint64_t keyID;
uint8_t key[32];
} ATTRIBUTE_PACKED;
SET_PACKED_STRUCT_MODE_OFF
/* ==== ABOUT THE "urgent" FLAG ====
*
* Do not set "urgent" unless you understand all the repercussions! What repercussions you might ask?
* Setting this flag will place your defer request at the front of the queue. This is useful for enqueueing work
* from interrupt context that needs to be done "very very soon"(tm). Doing this will delay all other work requests
* that have heretofore been peacefully queueing in full faith and with complete belief in fairness of our "FIFO"-ness.
* Please be appreciative of this fact and do not abuse this! Example: if you are setting "urgent" flag outside of interrupt
* context, you're very very likely wrong. That is not to say that being in interrupt context is a free pass to set this!
*/
// osMainInit is exposed for testing only, it must never be called for any reason at all by anyone
void osMainInit(void);
// osMainDequeueLoop is exposed for testing only, it must never be called for any reason at all by anyone
void osMainDequeueLoop(void);
void osMain(void);
bool osEventSubscribe(uint32_t tid, uint32_t evtType); /* async */
bool osEventUnsubscribe(uint32_t tid, uint32_t evtType); /* async */
bool osEnqueuePrivateEvt(uint32_t evtType, void *evtData, EventFreeF evtFreeF, uint32_t toTid);
bool osEnqueuePrivateEvtAsApp(uint32_t evtType, void *evtData, uint32_t fromApp, uint32_t toTid);
bool osEnqueueEvt(uint32_t evtType, void *evtData, EventFreeF evtFreeF);
bool osEnqueueEvtOrFree(uint32_t evtType, void *evtData, EventFreeF evtFreeF);
bool osEnqueueEvtAsApp(uint32_t evtType, void *evtData, uint32_t fromApp);
bool osDefer(OsDeferCbkF callback, void *cookie, bool urgent);
bool osTidById(uint64_t appId, uint32_t *tid);
bool osAppInfoById(uint64_t appId, uint32_t *appIdx, uint32_t *appVer, uint32_t *appSize);
bool osAppInfoByIndex(uint32_t appIdx, uint64_t *appId, uint32_t *appVer, uint32_t *appSize);
uint32_t osGetCurrentTid();
uint32_t osSetCurrentTid(uint32_t);
//event retaining support
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
void osFreeRetainedEvent(uint32_t evtType, void *evtData, TaggedPtr *evtFreeingInfoP);
uint32_t osExtAppStopApps(uint64_t appId);
uint32_t osExtAppEraseApps(uint64_t appId);
uint32_t osExtAppStartApps(uint64_t appId);
/* Logging */
enum LogLevel {
LOG_ERROR = 'E',
LOG_WARN = 'W',
LOG_INFO = 'I',
LOG_DEBUG = 'D',
};
void osLogv(enum LogLevel level, const char *str, va_list vl);
void osLog(enum LogLevel level, const char *str, ...) PRINTF_ATTRIBUTE;
#ifndef INTERNAL_APP_INIT
#define INTERNAL_APP_INIT(_id, _ver, _init, _end, _event) \
SET_INTERNAL_LOCATION(location, ".internal_app_init")static const struct AppHdr SET_INTERNAL_LOCATION_ATTRIBUTES(used, section (".internal_app_init")) mAppHdr = { \
.magic = APP_HDR_MAGIC, \
.fmtVer = APP_HDR_VER_CUR, \
.marker = APP_HDR_MARKER_INTERNAL, \
.appId = (_id), \
.appVer = (_ver), \
.funcs.init = (_init), \
.funcs.end = (_end), \
.funcs.handle = (_event) \
}
#endif
#ifndef APP_INIT
#define APP_INIT(_ver, _init, _end, _event) \
extern const struct AppFuncs _mAppFuncs; \
const struct AppFuncs SET_EXTERNAL_APP_ATTRIBUTES(used, section (".app_init"), visibility("default")) _mAppFuncs = { \
.init = (_init), \
.end = (_end), \
.handle = (_event) \
}; \
const uint32_t SET_EXTERNAL_APP_VERSION(used, section (".app_version"), visibility("default")) _mAppVer = _ver
#endif
#ifdef __cplusplus
}
#endif
#endif