/* * 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_PRIV_H__ #define __SEOS_PRIV_H__ #include #include #include #define NO_NODE (TaskIndex)(-1) #define for_each_task(listHead, task) for (task = osTaskByIdx((listHead)->next); task; task = osTaskByIdx(task->list.next)) #define TID_TO_TASK_IDX(tid) (tid & TASK_TID_IDX_MASK) #define FL_TASK_STOPPED 1 #define FL_TASK_ABORTED 2 #define EVT_SUBSCRIBE_TO_EVT 0x00000000 #define EVT_UNSUBSCRIBE_TO_EVT 0x00000001 #define EVT_DEFERRED_CALLBACK 0x00000002 #define EVT_PRIVATE_EVT 0x00000003 #define EVT_PRIVATE_CLASS_CHRE 0x00000001 #define EVENT_WITH_ORIGIN(evt, origin) (((evt) & EVT_MASK) | ((origin) << (32 - TASK_TID_BITS))) #define EVENT_GET_ORIGIN(evt) ((evt) >> (32 - TASK_TID_BITS)) #define EVENT_GET_EVENT(evt) ((evt) & (EVT_MASK & ~EVENT_TYPE_BIT_DISCARDABLE)) #define MAX_EVT_SUB_CNT 6 SET_PACKED_STRUCT_MODE_ON struct TaskList { TaskIndex prev; TaskIndex next; } ATTRIBUTE_PACKED; SET_PACKED_STRUCT_MODE_OFF struct Task { /* App entry points */ const struct AppHdr *app; /* per-platform app info */ struct PlatAppInfo platInfo; /* for some basic number of subbed events, the array is stored directly here. after that, a heap chunk is used */ uint32_t subbedEventsInt[MAX_EMBEDDED_EVT_SUBS]; uint32_t *subbedEvents; /* NULL for invalid tasks */ struct TaskList list; /* task pointer will not change throughout task lifetime, * however same task pointer may be reused for a new task; to eliminate the ambiguity, * TID is maintained for each task such that new tasks will be guaranteed to receive different TID */ uint16_t tid; uint8_t subbedEvtCount; uint8_t subbedEvtListSz; uint8_t flags; uint8_t ioCount; }; struct I2cEventData { void *cookie; uint32_t tx; uint32_t rx; int err; }; union OsApiSlabItem { struct I2cEventData i2cAppCbkEvt; struct { uint32_t toTid; void *cookie; } i2cAppCbkInfo; }; /* this is a system slab allocator internal data type */ union SeosInternalSlabData { struct { uint16_t tid; uint8_t numEvts; uint16_t evts[MAX_EVT_SUB_CNT]; } evtSub; struct { OsDeferCbkF callback; void *cookie; } deferred; struct { uint32_t evtType; void *evtData; TaggedPtr evtFreeInfo; uint16_t fromTid; uint16_t toTid; } privateEvt; union OsApiSlabItem osApiItem; }; typedef bool (*appMatchFunc)(const void *cookie, const struct AppHdr *); uint8_t osTaskIndex(struct Task *task); struct Task *osGetCurrentTask(); struct Task *osSetCurrentTask(struct Task *task); struct Task *osTaskFindByTid(uint32_t tid); void osTaskAbort(struct Task *task); void osTaskInvokeMessageFreeCallback(struct Task *task, void (*freeCallback)(void *, size_t), void *message, uint32_t messageSize); void osTaskInvokeEventFreeCallback(struct Task *task, void (*freeCallback)(uint16_t, void *), uint16_t event, void *data); void osChreTaskHandle(struct Task *task, uint32_t evtType, const void *evtData); static inline bool osTaskIsChre(const struct Task *task) { return task->app && (task->app->hdr.fwFlags & FL_APP_HDR_CHRE) != 0; } static inline uint32_t osTaskChreVersion(const struct Task *task) { if (osTaskIsChre(task)) { // Apps loaded on 1.0 stored 0xFF in both rfu bytes if (task->app->hdr.chreApiMajor == 0xFF && task->app->hdr.chreApiMinor == 0xFF) return CHRE_API_VERSION_1_0; else return task->app->hdr.chreApiMajor << 24 | task->app->hdr.chreApiMinor << 16; } else { return 0; } } static inline void osTaskMakeNewTid(struct Task *task) { task->tid = ((task->tid + TASK_TID_INCREMENT) & TASK_TID_COUNTER_MASK) | (osTaskIndex(task) & TASK_TID_IDX_MASK); } #endif // __SEOS_PRIV_H__