mbed-os/platform/CThunkBase.cpp

146 lines
4.4 KiB
C++

/* mbed Microcontroller Library
* Copyright (c) 2018-2018 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.
* 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.
*/
#include "platform/platform.h"
#include "platform/mbed_critical.h"
#include "platform/mbed_assert.h"
#include "platform/mbed_error.h"
#include "CThunkBase.h"
MBED_STATIC_ASSERT(MBED_CONF_PLATFORM_CTHUNK_COUNT_MAX < 256, "MBED_CONF_PLATFORM_CTHUNK_COUNT_MAX must be less than 256");
MBED_STATIC_ASSERT(MBED_CONF_PLATFORM_CTHUNK_COUNT_MAX > 0, "MBED_CONF_PLATFORM_CTHUNK_COUNT_MAX must be greater than 0");
#define ENABLE_N(N) ((MBED_CONF_PLATFORM_CTHUNK_COUNT_MAX & N) ? 1 : 0)
#define START_128 0
#define START_64 (START_128 + ENABLE_N(128) * 128)
#define START_32 (START_64 + ENABLE_N(64) * 64)
#define START_16 (START_32 + ENABLE_N(32) * 32)
#define START_8 (START_16 + ENABLE_N(16) * 16)
#define START_4 (START_8 + ENABLE_N(8) * 8)
#define START_2 (START_4 + ENABLE_N(4) * 4)
#define START_1 (START_2 + ENABLE_N(2) * 2)
#define DECLARE_THUNK128(start) \
DECLARE_THUNK64(start), \
DECLARE_THUNK64(start + 64)
#define DECLARE_THUNK64(start) \
DECLARE_THUNK32(start), \
DECLARE_THUNK32(start + 32)
#define DECLARE_THUNK32(start) \
DECLARE_THUNK16(start), \
DECLARE_THUNK16(start + 16)
#define DECLARE_THUNK16(start) \
DECLARE_THUNK8(start), \
DECLARE_THUNK8(start + 8)
#define DECLARE_THUNK8(start) \
DECLARE_THUNK4(start), \
DECLARE_THUNK4(start + 4)
#define DECLARE_THUNK4(start) \
DECLARE_THUNK2(start), \
DECLARE_THUNK2(start + 2)
#define DECLARE_THUNK2(start) \
DECLARE_THUNK1(start), \
DECLARE_THUNK1(start + 1)
#define DECLARE_THUNK1(index) &CThunkBase::thunk_entry<index>
const CThunkEntry CThunkBase::_thunk_table[MBED_CONF_PLATFORM_CTHUNK_COUNT_MAX] = {
#if ENABLE_N(128)
DECLARE_THUNK128(START_128),
#endif
#if ENABLE_N(64)
DECLARE_THUNK64(START_64),
#endif
#if ENABLE_N(32)
DECLARE_THUNK32(START_32),
#endif
#if ENABLE_N(16)
DECLARE_THUNK16(START_16),
#endif
#if ENABLE_N(8)
DECLARE_THUNK8(START_8),
#endif
#if ENABLE_N(4)
DECLARE_THUNK4(START_4),
#endif
#if ENABLE_N(2)
DECLARE_THUNK2(START_2),
#endif
#if ENABLE_N(1)
DECLARE_THUNK1(START_1)
#endif
};
CThunkBase *CThunkBase::_thunk_storage[MBED_CONF_PLATFORM_CTHUNK_COUNT_MAX];
CThunkBase::CthunkFree CThunkBase::_cthunk_free_real = NULL;
CThunkEntry CThunkBase::cthunk_alloc(CThunkBase *cthunk)
{
// Atomically allocate one entry
core_util_critical_section_enter();
CThunkEntry entry = NULL;
for (int i = 0; i < MBED_CONF_PLATFORM_CTHUNK_COUNT_MAX; i++) {
if (_thunk_storage[i] == NULL) {
_thunk_storage[i] = cthunk;
entry = _thunk_table[i];
break;
}
}
core_util_critical_section_exit();
if (entry == NULL) {
MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_OUT_OF_RESOURCES), "Ran out of CThunk entries. Increase MBED_CONF_PLATFORM_CTHUNK_COUNT_MAX to fix this error");
}
// Set function pointer on first use. This allows _thunk_table
// and _thunk_storage to get removed by the linker if
// cthunk_alloc is never used.
_cthunk_free_real = &cthunk_free_real;
return entry;
}
void CThunkBase::cthunk_free(CThunkEntry item)
{
if (_cthunk_free_real) {
_cthunk_free_real(item);
}
}
void CThunkBase::cthunk_free_real(CThunkEntry item)
{
bool found = false;
core_util_critical_section_enter();
for (int i = 0; i < MBED_CONF_PLATFORM_CTHUNK_COUNT_MAX; i++) {
if (_thunk_table[i] == item) {
_thunk_storage[i] = NULL;
found = true;
break;
}
}
core_util_critical_section_exit();
if (!found) {
MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_INVALID_ARGUMENT), "Tried to free invalid CThunkEntry");
}
}