mbed library sources. Supersedes mbed-src.
Dependents: Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more
Diff: platform/CThunk.h
- Revision:
- 189:f392fc9709a3
- Parent:
- 187:0387e8f68319
--- a/platform/CThunk.h Thu Nov 08 11:46:34 2018 +0000 +++ b/platform/CThunk.h Wed Feb 20 22:31:08 2019 +0000 @@ -13,6 +13,7 @@ * - ideally suited for class object receiving interrupts (NVIC_SetVector) * * Copyright (c) 2014-2015 ARM Limited + * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,45 +39,7 @@ #ifndef __CTHUNK_H__ #define __CTHUNK_H__ -#define CTHUNK_ADDRESS 1 -#define CTHUNK_VARIABLES volatile uint32_t code[2] - -#if (defined(__CORTEX_M3) || defined(__CORTEX_M4) || defined(__CORTEX_M7) || defined(__CORTEX_A9) \ - || defined(__CORTEX_M33)) -/** -* CTHUNK disassembly for Cortex-M3/M4/M7/A9 (thumb2): -* * adr r0, #4 -* * ldm r0, {r0, r1, r2, pc} -* -* This instruction loads the arguments for the static thunking function to r0-r2, and -* branches to that function by loading its address into PC. -* -* This is safe for both regular calling and interrupt calling, since it only touches scratch registers -* which should be saved by the caller, and are automatically saved as part of the IRQ context switch. -*/ -#define CTHUNK_ASSIGMENT do { \ - m_thunk.code[0] = 0xE890A001; \ - m_thunk.code[1] = 0x00008007; \ - } while (0) - -#elif (defined(__CORTEX_M0PLUS) || defined(__CORTEX_M0) || defined(__CORTEX_M23)) -/* -* CTHUNK disassembly for Cortex M0/M0+ (thumb): -* * adr r0, #4 -* * ldm r0, {r0, r1, r2, r3} -* * bx r3 -*/ -#define CTHUNK_ASSIGMENT do { \ - m_thunk.code[0] = 0xC80FA001; \ - m_thunk.code[1] = 0x00004718; \ - } while (0) - -#else -#error "Target is not currently suported." -#endif - -/* IRQ/Exception compatible thunk entry function */ -typedef void (*CThunkEntry)(void); +#include "CThunkBase.h" /** * Class for created a pointer with data bound to it @@ -84,7 +47,7 @@ * @note Synchronization level: Not protected */ template<class T> -class CThunk { +class CThunk: public CThunkBase { public: typedef void (T::*CCallbackSimple)(void); typedef void (T::*CCallback)(void *context); @@ -101,7 +64,8 @@ ~CThunk() { - + cthunk_free(_entry); + _entry = NULL; } inline CThunk(T *instance, CCallbackSimple callback) @@ -126,27 +90,30 @@ inline void callback(CCallback callback) { - m_callback = callback; + _callback = callback; } inline void callback(CCallbackSimple callback) { - m_callback = (CCallback)callback; + _callback_simple = callback; } inline void context(void *context) { - m_thunk.context = (uint32_t)context; + _context = context; } inline void context(uint32_t context) { - m_thunk.context = context; + _context = (void *)context; } inline uint32_t entry(void) { - return (((uint32_t)&m_thunk) | CTHUNK_ADDRESS); + if (_entry == NULL) { + _entry = cthunk_alloc(this); + } + return (uint32_t)_entry; } /* get thunk entry point for connecting rhunk to an IRQ table */ @@ -168,78 +135,34 @@ } private: - T *m_instance; - volatile CCallback m_callback; + T *_instance; + void *_context; + union { + CCallbackSimple _callback_simple; + CCallback _callback; + }; + + CThunkEntry _entry; -// TODO: this needs proper fix, to refactor toolchain header file and all its use -// PACKED there is not defined properly for IAR -#if defined (__ICCARM__) - typedef __packed struct { - CTHUNK_VARIABLES; - volatile uint32_t instance; - volatile uint32_t context; - volatile uint32_t callback; - volatile uint32_t trampoline; - } CThunkTrampoline; -#else - typedef struct { - CTHUNK_VARIABLES; - volatile uint32_t instance; - volatile uint32_t context; - volatile uint32_t callback; - volatile uint32_t trampoline; - } __attribute__((__packed__)) CThunkTrampoline; -#endif + static void trampoline(CThunkBase *base) + { + CThunk<T> *self = static_cast<CThunk<T>*>(base); + T *instance = self->_instance; + void *context = self->_context; + CCallback callback = self->_callback; - static void trampoline(T *instance, void *context, CCallback *callback) - { - if (instance && *callback) { - (static_cast<T *>(instance)->**callback)(context); + if (instance && callback) { + (instance->*callback)(context); } } - volatile CThunkTrampoline m_thunk; - inline void init(T *instance, CCallback callback, void *context) { - /* remember callback - need to add this level of redirection - as pointer size for member functions differs between platforms */ - m_callback = callback; - - /* populate thunking trampoline */ - CTHUNK_ASSIGMENT; - m_thunk.context = (uint32_t)context; - m_thunk.instance = (uint32_t)instance; - m_thunk.callback = (uint32_t)&m_callback; - m_thunk.trampoline = (uint32_t)&trampoline; - -#if defined(__CORTEX_A9) - /* Data cache clean */ - /* Cache control */ - { - uint32_t start_addr = (uint32_t)&m_thunk & 0xFFFFFFE0; - uint32_t end_addr = (uint32_t)&m_thunk + sizeof(m_thunk); - uint32_t addr; - - /* Data cache clean and invalid */ - for (addr = start_addr; addr < end_addr; addr += 0x20) { - L1C_CleanInvalidateDCacheMVA((void *)addr); - } - /* Instruction cache invalid */ - L1C_InvalidateICacheAll(); - MMU_InvalidateTLB(); - L1C_InvalidateBTAC(); - } -#endif -#if defined(__CORTEX_M7) - /* Data cache clean and invalid */ - SCB_CleanInvalidateDCache(); - - /* Instruction cache invalid */ - SCB_InvalidateICache(); -#endif - __ISB(); - __DSB(); + _instance = instance; + _context = context; + _callback = callback; + _trampoline = &trampoline; + _entry = 0; } };