1 /* 2 * Copyright (C) 2017 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 /******************************************************************************* 18 * ~ ~ ~ W A R N I N G ~ ~ ~ 19 * 20 * The following code is used to load a nanoapp into a Qualcomm implementation 21 * of the CHRE API that is based on Nanohub. This is not intended as a reference 22 * for future platforms and is provided for backwards compatibility with this 23 * implementation. 24 * 25 * You may find more suitable examples of app support libraries under the 26 * build/app_support directory for other variants. These files are typically 27 * designed to perform early initialization of the CHRE nanoapp and may be 28 * required by some platforms but not all. 29 * 30 ******************************************************************************/ 31 32 #include <chre.h> 33 #include <stdbool.h> 34 #include <stdint.h> 35 36 #ifdef __cplusplus 37 extern "C" { 38 #endif 39 40 #define LEGACY_APP_HDR_MAGIC_ARRAY \ 41 {'G', 'o', 'o', 'g', 'l', 'e', 'N', 'a', 'n', 'o', 'A', 'p', 'p'} 42 43 #define APP_HDR_VER_CUR 0 44 #define APP_HDR_MARKER_INTERNAL 0xFF01 45 46 #define EVT_APP_FROM_HOST 0x000000F8 47 #define EVT_APP_TIMER 0x000000DF 48 49 struct AppFuncs { 50 bool (*init)(uint32_t yourTid); 51 void (*end)(void); 52 void (*handle)(uint32_t evtType, const void *evtData); 53 }; 54 55 // This was the old "struct AppHdr" before the binary format was refactored as 56 // part of b/28265099. It's what Qualcomm's implementation currently expects as 57 // input when registering an app. 58 struct LegacyAppHdr { 59 char magic[13]; 60 uint8_t fmtVer; //app header format version 61 uint16_t marker; 62 63 uint64_t appId; 64 65 uint32_t data_start; 66 uint32_t data_end; 67 uint32_t data_data; 68 69 uint32_t bss_start; 70 uint32_t bss_end; 71 72 uint32_t got_start; 73 uint32_t got_end; 74 uint32_t rel_start; 75 uint32_t rel_end; 76 77 uint32_t appVer; 78 uint32_t rfu; 79 80 struct AppFuncs funcs; 81 }; 82 83 struct TimerEvent { 84 uint32_t timerId; 85 void *data; 86 }; 87 88 // These two functions are specific to Qualcomm's Nanohub platform 89 // implementation 90 extern void platSlpiAddInternalApp(const struct LegacyAppHdr *, bool); 91 extern void platSlpiRemoveInternalApp(const struct LegacyAppHdr *); 92 93 static void __appInit(void) __attribute__((constructor)); 94 static void __appEnd(void) __attribute__((destructor)); 95 96 static bool chreappStart(uint32_t tid); 97 static void chreappHandle(uint32_t eventTypeAndTid, const void *eventData); 98 99 #if !defined(NANOAPP_ID) || !defined(NANOAPP_VERSION) 100 #error NANOAPP_ID and NANOAPP_VERSION must be defined in the build environment 101 #endif 102 103 static const struct LegacyAppHdr mAppHdr = { 104 .magic = LEGACY_APP_HDR_MAGIC_ARRAY, 105 .fmtVer = APP_HDR_VER_CUR, 106 .marker = APP_HDR_MARKER_INTERNAL, 107 .appId = NANOAPP_ID, 108 .appVer = NANOAPP_VERSION, 109 .funcs.init = chreappStart, 110 .funcs.end = nanoappEnd, 111 .funcs.handle = chreappHandle, 112 }; 113 114 // Note: this runs when CHRE first loads the Nanoapp. We use it to register the 115 // app's entry points with the runtime environment. 116 static void __appInit(void) 117 { 118 platSlpiAddInternalApp(&mAppHdr, false); 119 } 120 121 static void __appEnd(void) 122 { 123 platSlpiRemoveInternalApp(&mAppHdr); 124 } 125 126 static bool chreappStart(uint32_t tid) 127 { 128 return nanoappStart(); 129 } 130 131 static void chreappHandle(uint32_t eventTypeAndTid, const void *eventData) 132 { 133 uint16_t evt = eventTypeAndTid; 134 uint16_t srcTid = eventTypeAndTid >> 16; 135 const void *data = eventData; 136 137 union EventLocalData { 138 struct chreMessageFromHostData msg; 139 } u; 140 141 switch(evt) { 142 case EVT_APP_TIMER: 143 evt = CHRE_EVENT_TIMER; 144 data = ((struct TimerEvent *)eventData)->data; 145 break; 146 case EVT_APP_FROM_HOST: 147 evt = CHRE_EVENT_MESSAGE_FROM_HOST; 148 data = &u.msg; 149 u.msg.message = (uint8_t*)eventData + 1; 150 // TODO: fill messageType with the correct value once available. 151 u.msg.messageType = 0; 152 u.msg.messageSize = *(uint8_t*)eventData; 153 break; 154 } 155 nanoappHandleEvent(srcTid, evt, data); 156 } 157 158 #ifdef __cplusplus 159 } 160 #endif 161