7static const char*
TAG =
"SlotMap";
19#define BUILD_ECC_ENTRY(name, id, start, end) \
20 { TropicSlotMap::SlotType::ECC, name, static_cast<uint8_t>(id), \
21 static_cast<uint16_t>(start), static_cast<uint16_t>(end) },
22#define BUILD_RMEM_ENTRY(name, id, start, end) \
23 { TropicSlotMap::SlotType::RMEM, name, static_cast<uint8_t>(id), \
24 static_cast<uint16_t>(start), static_cast<uint16_t>(end) },
38 static TropicSlotMap inst;
45TropicSlotMap::TropicSlotMap() {
53void TropicSlotMap::setError(
const char* message) {
56 errorMessage_ = message;
57 LOG_E(
TAG,
"%s", message ? message :
"slot map error");
63void TropicSlotMap::validateOnce() {
65 errorMessage_ =
nullptr;
69 if (!a.moduleName || a.moduleName[0] ==
'\0') {
70 setError(
"slot map entry with empty module name");
74 setError(
"slot map entry with unknown module id");
77 if (a.start > a.end) {
78 setError(
"slot map range has start > end");
81 if (a.start == 0 || a.end == 0) {
82 setError(
"slot map range uses reserved slot 0");
88 setError(
"slot map ECC range out of bounds");
92 setError(
"slot map ECC range includes reserved slot");
98 setError(
"slot map RMEM range out of bounds");
103 setError(
"slot map RMEM range below minimum allowed");
110 if (!b.moduleName)
continue;
112 if (a.type == b.type) {
113 bool overlap = !(a.end < b.start || b.end < a.start);
115 setError(
"slot map overlap detected");
120 if (strcmp(a.moduleName, b.moduleName) == 0 && a.type == b.type) {
121 setError(
"slot map duplicate module/type entry");
125 if (a.moduleId == b.moduleId &&
126 strcmp(a.moduleName, b.moduleName) != 0) {
127 setError(
"slot map module id used by multiple names");
142 if (!moduleName || !out)
return false;
145 if (entry.type != type)
continue;
146 if (strcmp(entry.moduleName, moduleName) != 0)
continue;
148 out->
type = entry.type;
151 out->
start = entry.start;
152 out->
end = entry.end;
166 if (!out)
return false;
169 if (entry.type != type)
continue;
170 if (entry.moduleId !=
moduleId)
continue;
172 out->
type = entry.type;
175 out->
start = entry.start;
176 out->
end = entry.end;
189 if (entry.type != type)
continue;
195 r.
start = entry.start;
212 return slot >= range.
start && slot <= range.
end;
229 auto mix = [&
hash](uint32_t v) {
243 mix(
static_cast<uint32_t
>(entry.type));
Centralized non-cryptographic hash utilities.
#define BUILD_ECC_ENTRY(name, id, start, end)
#define BUILD_RMEM_ENTRY(name, id, start, end)
CDC Log: logging over TinyUSB CDC and UART.
#define LOG_E(tag, fmt,...)
void(*)(const SlotRange &range, void *user) RangeCallback
static TropicSlotMap & instance()
Returns singleton Tropic slot-map instance.
uint16_t rmemMax() const
Returns maximum RMEM slot index.
void forEachRange(SlotType type, RangeCallback cb, void *user) const
Iterates configured slot ranges of the given type in declaration order.
bool isRmemAllowedForModuleId(uint16_t slot, uint8_t moduleId) const
Checks whether RMEM slot is allowed for given module id.
bool getRangeByModuleId(uint8_t moduleId, SlotType type, SlotRange *out) const
Retrieves slot range by module id and slot type.
uint32_t computeMapSignature() const
Computes deterministic signature over static map constants and ranges.
bool getRangeByName(const char *moduleName, SlotType type, SlotRange *out) const
Retrieves slot range by module name and slot type.
static constexpr uint32_t FNV1A_32_OFFSET_BASIS
FNV-1a 32-bit constants (Fowler/Noll/Vo).
void fnv1a_mix_u32(uint32_t &hash, uint32_t value)
Mixes a 32-bit word into a running FNV-1a 32-bit hash.
static constexpr size_t kSlotMapCount
static const SlotMapEntry kSlotMap[]
static constexpr uint16_t RMEM_SLOT_MAX
static constexpr uint8_t ECC_SLOT_MAX
static constexpr uint16_t RMEM_SLOT_MIN
static constexpr uint16_t RMEM_SLOT_RESERVED
static constexpr uint8_t ECC_SLOT_RESERVED
static constexpr uint8_t ECC_SLOT_MIN
static constexpr uint16_t RMEM_SLOT_MIN_ALLOC
TropicSlotMap::SlotType type
#define TROPIC_ECC_SLOT_MAP(X)
#define TROPIC_RMEM_SLOT_MAP(X)
#define MODULE_ID_UNKNOWN