init

Dependencies:   mbed

Committer:
Nathan Yonkee
Date:
Fri Mar 02 07:16:49 2018 -0700
Revision:
10:46a4cf51ee38
Parent:
9:d58e77ebd769
remove mbed-os

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Nathan Yonkee 9:d58e77ebd769 1
Nathan Yonkee 9:d58e77ebd769 2 /** \addtogroup platform */
Nathan Yonkee 9:d58e77ebd769 3 /** @{*/
Nathan Yonkee 9:d58e77ebd769 4 /**
Nathan Yonkee 9:d58e77ebd769 5 * \defgroup platform_CThunk CThunk class
Nathan Yonkee 9:d58e77ebd769 6 * @{
Nathan Yonkee 9:d58e77ebd769 7 */
Nathan Yonkee 9:d58e77ebd769 8 /* General C++ Object Thunking class
Nathan Yonkee 9:d58e77ebd769 9 *
Nathan Yonkee 9:d58e77ebd769 10 * - allows direct callbacks to non-static C++ class functions
Nathan Yonkee 9:d58e77ebd769 11 * - keeps track for the corresponding class instance
Nathan Yonkee 9:d58e77ebd769 12 * - supports an optional context parameter for the called function
Nathan Yonkee 9:d58e77ebd769 13 * - ideally suited for class object receiving interrupts (NVIC_SetVector)
Nathan Yonkee 9:d58e77ebd769 14 *
Nathan Yonkee 9:d58e77ebd769 15 * Copyright (c) 2014-2015 ARM Limited
Nathan Yonkee 9:d58e77ebd769 16 *
Nathan Yonkee 9:d58e77ebd769 17 * Licensed under the Apache License, Version 2.0 (the "License");
Nathan Yonkee 9:d58e77ebd769 18 * you may not use this file except in compliance with the License.
Nathan Yonkee 9:d58e77ebd769 19 * You may obtain a copy of the License at
Nathan Yonkee 9:d58e77ebd769 20 *
Nathan Yonkee 9:d58e77ebd769 21 * http://www.apache.org/licenses/LICENSE-2.0
Nathan Yonkee 9:d58e77ebd769 22 *
Nathan Yonkee 9:d58e77ebd769 23 * Unless required by applicable law or agreed to in writing, software
Nathan Yonkee 9:d58e77ebd769 24 * distributed under the License is distributed on an "AS IS" BASIS,
Nathan Yonkee 9:d58e77ebd769 25 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Nathan Yonkee 9:d58e77ebd769 26 * See the License for the specific language governing permissions and
Nathan Yonkee 9:d58e77ebd769 27 * limitations under the License.
Nathan Yonkee 9:d58e77ebd769 28 */
Nathan Yonkee 9:d58e77ebd769 29
Nathan Yonkee 9:d58e77ebd769 30 /* General C++ Object Thunking class
Nathan Yonkee 9:d58e77ebd769 31 *
Nathan Yonkee 9:d58e77ebd769 32 * - allows direct callbacks to non-static C++ class functions
Nathan Yonkee 9:d58e77ebd769 33 * - keeps track for the corresponding class instance
Nathan Yonkee 9:d58e77ebd769 34 * - supports an optional context parameter for the called function
Nathan Yonkee 9:d58e77ebd769 35 * - ideally suited for class object receiving interrupts (NVIC_SetVector)
Nathan Yonkee 9:d58e77ebd769 36 */
Nathan Yonkee 9:d58e77ebd769 37
Nathan Yonkee 9:d58e77ebd769 38 #ifndef __CTHUNK_H__
Nathan Yonkee 9:d58e77ebd769 39 #define __CTHUNK_H__
Nathan Yonkee 9:d58e77ebd769 40
Nathan Yonkee 9:d58e77ebd769 41 #define CTHUNK_ADDRESS 1
Nathan Yonkee 9:d58e77ebd769 42 #define CTHUNK_VARIABLES volatile uint32_t code[2]
Nathan Yonkee 9:d58e77ebd769 43
Nathan Yonkee 9:d58e77ebd769 44 #if (defined(__CORTEX_M3) || defined(__CORTEX_M4) || defined(__CORTEX_M7) || defined(__CORTEX_A9) \
Nathan Yonkee 9:d58e77ebd769 45 || defined(__CORTEX_M33))
Nathan Yonkee 9:d58e77ebd769 46 /**
Nathan Yonkee 9:d58e77ebd769 47 * CTHUNK disassembly for Cortex-M3/M4/M7/A9 (thumb2):
Nathan Yonkee 9:d58e77ebd769 48 * * adr r0, #4
Nathan Yonkee 9:d58e77ebd769 49 * * ldm r0, {r0, r1, r2, pc}
Nathan Yonkee 9:d58e77ebd769 50 *
Nathan Yonkee 9:d58e77ebd769 51 * This instruction loads the arguments for the static thunking function to r0-r2, and
Nathan Yonkee 9:d58e77ebd769 52 * branches to that function by loading its address into PC.
Nathan Yonkee 9:d58e77ebd769 53 *
Nathan Yonkee 9:d58e77ebd769 54 * This is safe for both regular calling and interrupt calling, since it only touches scratch registers
Nathan Yonkee 9:d58e77ebd769 55 * which should be saved by the caller, and are automatically saved as part of the IRQ context switch.
Nathan Yonkee 9:d58e77ebd769 56 */
Nathan Yonkee 9:d58e77ebd769 57 #define CTHUNK_ASSIGMENT do { \
Nathan Yonkee 9:d58e77ebd769 58 m_thunk.code[0] = 0xE890A001; \
Nathan Yonkee 9:d58e77ebd769 59 m_thunk.code[1] = 0x00008007; \
Nathan Yonkee 9:d58e77ebd769 60 } while (0)
Nathan Yonkee 9:d58e77ebd769 61
Nathan Yonkee 9:d58e77ebd769 62 #elif (defined(__CORTEX_M0PLUS) || defined(__CORTEX_M0) || defined(__CORTEX_M23))
Nathan Yonkee 9:d58e77ebd769 63 /*
Nathan Yonkee 9:d58e77ebd769 64 * CTHUNK disassembly for Cortex M0/M0+ (thumb):
Nathan Yonkee 9:d58e77ebd769 65 * * adr r0, #4
Nathan Yonkee 9:d58e77ebd769 66 * * ldm r0, {r0, r1, r2, r3}
Nathan Yonkee 9:d58e77ebd769 67 * * bx r3
Nathan Yonkee 9:d58e77ebd769 68 */
Nathan Yonkee 9:d58e77ebd769 69 #define CTHUNK_ASSIGMENT do { \
Nathan Yonkee 9:d58e77ebd769 70 m_thunk.code[0] = 0xC80FA001; \
Nathan Yonkee 9:d58e77ebd769 71 m_thunk.code[1] = 0x00004718; \
Nathan Yonkee 9:d58e77ebd769 72 } while (0)
Nathan Yonkee 9:d58e77ebd769 73
Nathan Yonkee 9:d58e77ebd769 74 #else
Nathan Yonkee 9:d58e77ebd769 75 #error "Target is not currently suported."
Nathan Yonkee 9:d58e77ebd769 76 #endif
Nathan Yonkee 9:d58e77ebd769 77
Nathan Yonkee 9:d58e77ebd769 78 /* IRQ/Exception compatible thunk entry function */
Nathan Yonkee 9:d58e77ebd769 79 typedef void (*CThunkEntry)(void);
Nathan Yonkee 9:d58e77ebd769 80
Nathan Yonkee 9:d58e77ebd769 81 /**
Nathan Yonkee 9:d58e77ebd769 82 * Class for created a pointer with data bound to it
Nathan Yonkee 9:d58e77ebd769 83 *
Nathan Yonkee 9:d58e77ebd769 84 * @note Synchronization level: Not protected
Nathan Yonkee 9:d58e77ebd769 85 */
Nathan Yonkee 9:d58e77ebd769 86 template<class T>
Nathan Yonkee 9:d58e77ebd769 87 class CThunk
Nathan Yonkee 9:d58e77ebd769 88 {
Nathan Yonkee 9:d58e77ebd769 89 public:
Nathan Yonkee 9:d58e77ebd769 90 typedef void (T::*CCallbackSimple)(void);
Nathan Yonkee 9:d58e77ebd769 91 typedef void (T::*CCallback)(void* context);
Nathan Yonkee 9:d58e77ebd769 92
Nathan Yonkee 9:d58e77ebd769 93 inline CThunk(T *instance)
Nathan Yonkee 9:d58e77ebd769 94 {
Nathan Yonkee 9:d58e77ebd769 95 init(instance, NULL, NULL);
Nathan Yonkee 9:d58e77ebd769 96 }
Nathan Yonkee 9:d58e77ebd769 97
Nathan Yonkee 9:d58e77ebd769 98 inline CThunk(T *instance, CCallback callback)
Nathan Yonkee 9:d58e77ebd769 99 {
Nathan Yonkee 9:d58e77ebd769 100 init(instance, callback, NULL);
Nathan Yonkee 9:d58e77ebd769 101 }
Nathan Yonkee 9:d58e77ebd769 102
Nathan Yonkee 9:d58e77ebd769 103 ~CThunk() {
Nathan Yonkee 9:d58e77ebd769 104
Nathan Yonkee 9:d58e77ebd769 105 }
Nathan Yonkee 9:d58e77ebd769 106
Nathan Yonkee 9:d58e77ebd769 107 inline CThunk(T *instance, CCallbackSimple callback)
Nathan Yonkee 9:d58e77ebd769 108 {
Nathan Yonkee 9:d58e77ebd769 109 init(instance, (CCallback)callback, NULL);
Nathan Yonkee 9:d58e77ebd769 110 }
Nathan Yonkee 9:d58e77ebd769 111
Nathan Yonkee 9:d58e77ebd769 112 inline CThunk(T &instance, CCallback callback)
Nathan Yonkee 9:d58e77ebd769 113 {
Nathan Yonkee 9:d58e77ebd769 114 init(instance, callback, NULL);
Nathan Yonkee 9:d58e77ebd769 115 }
Nathan Yonkee 9:d58e77ebd769 116
Nathan Yonkee 9:d58e77ebd769 117 inline CThunk(T &instance, CCallbackSimple callback)
Nathan Yonkee 9:d58e77ebd769 118 {
Nathan Yonkee 9:d58e77ebd769 119 init(instance, (CCallback)callback, NULL);
Nathan Yonkee 9:d58e77ebd769 120 }
Nathan Yonkee 9:d58e77ebd769 121
Nathan Yonkee 9:d58e77ebd769 122 inline CThunk(T &instance, CCallback callback, void* context)
Nathan Yonkee 9:d58e77ebd769 123 {
Nathan Yonkee 9:d58e77ebd769 124 init(instance, callback, context);
Nathan Yonkee 9:d58e77ebd769 125 }
Nathan Yonkee 9:d58e77ebd769 126
Nathan Yonkee 9:d58e77ebd769 127 inline void callback(CCallback callback)
Nathan Yonkee 9:d58e77ebd769 128 {
Nathan Yonkee 9:d58e77ebd769 129 m_callback = callback;
Nathan Yonkee 9:d58e77ebd769 130 }
Nathan Yonkee 9:d58e77ebd769 131
Nathan Yonkee 9:d58e77ebd769 132 inline void callback(CCallbackSimple callback)
Nathan Yonkee 9:d58e77ebd769 133 {
Nathan Yonkee 9:d58e77ebd769 134 m_callback = (CCallback)callback;
Nathan Yonkee 9:d58e77ebd769 135 }
Nathan Yonkee 9:d58e77ebd769 136
Nathan Yonkee 9:d58e77ebd769 137 inline void context(void* context)
Nathan Yonkee 9:d58e77ebd769 138 {
Nathan Yonkee 9:d58e77ebd769 139 m_thunk.context = (uint32_t)context;
Nathan Yonkee 9:d58e77ebd769 140 }
Nathan Yonkee 9:d58e77ebd769 141
Nathan Yonkee 9:d58e77ebd769 142 inline void context(uint32_t context)
Nathan Yonkee 9:d58e77ebd769 143 {
Nathan Yonkee 9:d58e77ebd769 144 m_thunk.context = context;
Nathan Yonkee 9:d58e77ebd769 145 }
Nathan Yonkee 9:d58e77ebd769 146
Nathan Yonkee 9:d58e77ebd769 147 inline uint32_t entry(void)
Nathan Yonkee 9:d58e77ebd769 148 {
Nathan Yonkee 9:d58e77ebd769 149 return (((uint32_t)&m_thunk)|CTHUNK_ADDRESS);
Nathan Yonkee 9:d58e77ebd769 150 }
Nathan Yonkee 9:d58e77ebd769 151
Nathan Yonkee 9:d58e77ebd769 152 /* get thunk entry point for connecting rhunk to an IRQ table */
Nathan Yonkee 9:d58e77ebd769 153 inline operator CThunkEntry(void)
Nathan Yonkee 9:d58e77ebd769 154 {
Nathan Yonkee 9:d58e77ebd769 155 return (CThunkEntry)entry();
Nathan Yonkee 9:d58e77ebd769 156 }
Nathan Yonkee 9:d58e77ebd769 157
Nathan Yonkee 9:d58e77ebd769 158 /* get thunk entry point for connecting rhunk to an IRQ table */
Nathan Yonkee 9:d58e77ebd769 159 inline operator uint32_t(void)
Nathan Yonkee 9:d58e77ebd769 160 {
Nathan Yonkee 9:d58e77ebd769 161 return entry();
Nathan Yonkee 9:d58e77ebd769 162 }
Nathan Yonkee 9:d58e77ebd769 163
Nathan Yonkee 9:d58e77ebd769 164 /* simple test function */
Nathan Yonkee 9:d58e77ebd769 165 inline void call(void)
Nathan Yonkee 9:d58e77ebd769 166 {
Nathan Yonkee 9:d58e77ebd769 167 (((CThunkEntry)(entry()))());
Nathan Yonkee 9:d58e77ebd769 168 }
Nathan Yonkee 9:d58e77ebd769 169
Nathan Yonkee 9:d58e77ebd769 170 private:
Nathan Yonkee 9:d58e77ebd769 171 T* m_instance;
Nathan Yonkee 9:d58e77ebd769 172 volatile CCallback m_callback;
Nathan Yonkee 9:d58e77ebd769 173
Nathan Yonkee 9:d58e77ebd769 174 // TODO: this needs proper fix, to refactor toolchain header file and all its use
Nathan Yonkee 9:d58e77ebd769 175 // PACKED there is not defined properly for IAR
Nathan Yonkee 9:d58e77ebd769 176 #if defined (__ICCARM__)
Nathan Yonkee 9:d58e77ebd769 177 typedef __packed struct
Nathan Yonkee 9:d58e77ebd769 178 {
Nathan Yonkee 9:d58e77ebd769 179 CTHUNK_VARIABLES;
Nathan Yonkee 9:d58e77ebd769 180 volatile uint32_t instance;
Nathan Yonkee 9:d58e77ebd769 181 volatile uint32_t context;
Nathan Yonkee 9:d58e77ebd769 182 volatile uint32_t callback;
Nathan Yonkee 9:d58e77ebd769 183 volatile uint32_t trampoline;
Nathan Yonkee 9:d58e77ebd769 184 } CThunkTrampoline;
Nathan Yonkee 9:d58e77ebd769 185 #else
Nathan Yonkee 9:d58e77ebd769 186 typedef struct
Nathan Yonkee 9:d58e77ebd769 187 {
Nathan Yonkee 9:d58e77ebd769 188 CTHUNK_VARIABLES;
Nathan Yonkee 9:d58e77ebd769 189 volatile uint32_t instance;
Nathan Yonkee 9:d58e77ebd769 190 volatile uint32_t context;
Nathan Yonkee 9:d58e77ebd769 191 volatile uint32_t callback;
Nathan Yonkee 9:d58e77ebd769 192 volatile uint32_t trampoline;
Nathan Yonkee 9:d58e77ebd769 193 } __attribute__((__packed__)) CThunkTrampoline;
Nathan Yonkee 9:d58e77ebd769 194 #endif
Nathan Yonkee 9:d58e77ebd769 195
Nathan Yonkee 9:d58e77ebd769 196 static void trampoline(T* instance, void* context, CCallback* callback)
Nathan Yonkee 9:d58e77ebd769 197 {
Nathan Yonkee 9:d58e77ebd769 198 if(instance && *callback) {
Nathan Yonkee 9:d58e77ebd769 199 (static_cast<T*>(instance)->**callback)(context);
Nathan Yonkee 9:d58e77ebd769 200 }
Nathan Yonkee 9:d58e77ebd769 201 }
Nathan Yonkee 9:d58e77ebd769 202
Nathan Yonkee 9:d58e77ebd769 203 volatile CThunkTrampoline m_thunk;
Nathan Yonkee 9:d58e77ebd769 204
Nathan Yonkee 9:d58e77ebd769 205 inline void init(T *instance, CCallback callback, void* context)
Nathan Yonkee 9:d58e77ebd769 206 {
Nathan Yonkee 9:d58e77ebd769 207 /* remember callback - need to add this level of redirection
Nathan Yonkee 9:d58e77ebd769 208 as pointer size for member functions differs between platforms */
Nathan Yonkee 9:d58e77ebd769 209 m_callback = callback;
Nathan Yonkee 9:d58e77ebd769 210
Nathan Yonkee 9:d58e77ebd769 211 /* populate thunking trampoline */
Nathan Yonkee 9:d58e77ebd769 212 CTHUNK_ASSIGMENT;
Nathan Yonkee 9:d58e77ebd769 213 m_thunk.context = (uint32_t)context;
Nathan Yonkee 9:d58e77ebd769 214 m_thunk.instance = (uint32_t)instance;
Nathan Yonkee 9:d58e77ebd769 215 m_thunk.callback = (uint32_t)&m_callback;
Nathan Yonkee 9:d58e77ebd769 216 m_thunk.trampoline = (uint32_t)&trampoline;
Nathan Yonkee 9:d58e77ebd769 217
Nathan Yonkee 9:d58e77ebd769 218 #if defined(__CORTEX_A9)
Nathan Yonkee 9:d58e77ebd769 219 /* Data cache clean */
Nathan Yonkee 9:d58e77ebd769 220 /* Cache control */
Nathan Yonkee 9:d58e77ebd769 221 {
Nathan Yonkee 9:d58e77ebd769 222 uint32_t start_addr = (uint32_t)&m_thunk & 0xFFFFFFE0;
Nathan Yonkee 9:d58e77ebd769 223 uint32_t end_addr = (uint32_t)&m_thunk + sizeof(m_thunk);
Nathan Yonkee 9:d58e77ebd769 224 uint32_t addr;
Nathan Yonkee 9:d58e77ebd769 225
Nathan Yonkee 9:d58e77ebd769 226 /* Data cache clean and invalid */
Nathan Yonkee 9:d58e77ebd769 227 for (addr = start_addr; addr < end_addr; addr += 0x20) {
Nathan Yonkee 9:d58e77ebd769 228 L1C_CleanInvalidateDCacheMVA((void *)addr);
Nathan Yonkee 9:d58e77ebd769 229 }
Nathan Yonkee 9:d58e77ebd769 230 /* Instruction cache invalid */
Nathan Yonkee 9:d58e77ebd769 231 L1C_InvalidateICacheAll();
Nathan Yonkee 9:d58e77ebd769 232 MMU_InvalidateTLB();
Nathan Yonkee 9:d58e77ebd769 233 L1C_InvalidateBTAC();
Nathan Yonkee 9:d58e77ebd769 234 }
Nathan Yonkee 9:d58e77ebd769 235 #endif
Nathan Yonkee 9:d58e77ebd769 236 #if defined(__CORTEX_M7)
Nathan Yonkee 9:d58e77ebd769 237 /* Data cache clean and invalid */
Nathan Yonkee 9:d58e77ebd769 238 SCB_CleanInvalidateDCache();
Nathan Yonkee 9:d58e77ebd769 239
Nathan Yonkee 9:d58e77ebd769 240 /* Instruction cache invalid */
Nathan Yonkee 9:d58e77ebd769 241 SCB_InvalidateICache();
Nathan Yonkee 9:d58e77ebd769 242 #endif
Nathan Yonkee 9:d58e77ebd769 243 __ISB();
Nathan Yonkee 9:d58e77ebd769 244 __DSB();
Nathan Yonkee 9:d58e77ebd769 245 }
Nathan Yonkee 9:d58e77ebd769 246 };
Nathan Yonkee 9:d58e77ebd769 247
Nathan Yonkee 9:d58e77ebd769 248 /**@}*/
Nathan Yonkee 9:d58e77ebd769 249
Nathan Yonkee 9:d58e77ebd769 250 /**@}*/
Nathan Yonkee 9:d58e77ebd769 251
Nathan Yonkee 9:d58e77ebd769 252 #endif/*__CTHUNK_H__*/
Nathan Yonkee 9:d58e77ebd769 253