30 template<
typename WordT, ptraddr_t TCMBaseAddr>
37 static constexpr size_t ShadowWordSizeBits =
38 utils::bytes2bits(
sizeof(*shadowCap));
42 static constexpr size_t ShadowWordShift =
43 utils::log2<ShadowWordSizeBits>();
47 static constexpr size_t ShadowWordMask = (1U << ShadowWordShift) - 1;
56 static constexpr size_t shadow_offset_bits(ptraddr_t addr)
58 return (addr - TCMBaseAddr) >> utils::log2<sizeof(void *)>();
61 static constexpr size_t shadow_word_index(
size_t offsetBits)
63 return offsetBits >> ShadowWordShift;
66 static constexpr WordT shadow_mask_bits_below_address(ptraddr_t addr)
68 size_t capoffset = shadow_offset_bits(addr);
69 return (WordT(1) << (capoffset & ShadowWordMask)) - 1;
72 static constexpr WordT shadow_mask_bits_above_address(ptraddr_t addr)
74 return ~shadow_mask_bits_below_address(addr);
81 static_assert((shadow_mask_bits_above_address(0) ^
82 shadow_mask_bits_below_address(0)) == WordT(-1));
83 static_assert((shadow_mask_bits_above_address(7) ^
84 shadow_mask_bits_below_address(7)) == WordT(-1));
85 static_assert((shadow_mask_bits_above_address(ShadowWordSizeBits - 1) ^
86 shadow_mask_bits_below_address(ShadowWordSizeBits -
96#if !defined(CLANG_TIDY)
97 Debug::Assert(address > TCMBaseAddr,
98 "Address {} is below the TCM base {}",
102 size_t capoffset = shadow_offset_bits(address);
103 WordT shadowWord = shadowCap[shadow_word_index(capoffset)];
104 WordT mask = (WordT(1) << (capoffset & ShadowWordMask));
114 shadowCap[shadow_word_index(capoffset)] = shadowWord;
124 __always_inline
void mark_range(ptraddr_t base, ptraddr_t top)
126 size_t baseCapOffset = shadow_offset_bits(base);
127 size_t topCapOffset = shadow_offset_bits(top);
128 size_t baseWordIx = shadow_word_index(baseCapOffset);
129 size_t topWordIx = shadow_word_index(topCapOffset);
131 WordT maskHi = shadow_mask_bits_below_address(top);
132 WordT maskLo = shadow_mask_bits_above_address(base);
134 if (baseWordIx == topWordIx)
142 WordT mask = maskHi & maskLo;
145 shadowCap[baseWordIx] |= mask;
149 shadowCap[baseWordIx] &= ~mask;
174 shadowCap[topWordIx] |= maskHi;
179 shadowCap[topWordIx] &= ~maskHi;
187 for (
size_t shadowWordIx = topWordIx - 1; baseWordIx < shadowWordIx;
190 shadowCap[shadowWordIx] = midWord;
195 shadowCap[baseWordIx] |= maskLo;
199 shadowCap[baseWordIx] &= ~maskLo;
243 bool mark_get(
size_t addr)
245 size_t capoffset = shadow_offset_bits(addr);
246 WordT shadowWord = shadowCap[shadow_word_index(capoffset)];
247 WordT mask = (WordT(1) << (capoffset & ShadowWordMask));
249 return (shadowWord & mask) != 0;
C++ helpers for operating on capabilities.
Helper class for accessing capability properties on pointers.
ptraddr_t top() const
Returns the address of the top of this capability.
AddressProxy address()
Access the address of the capability.
ptraddr_t base() const
Returns the base address of this capability.
Class for interacting with the shadow bitmap.
void mark_set_range(CHERI::Capability< void > cap)
Set a range of shadow bits, from cap's base to its top.
void init()
Initialise this class with a capability to the shadow bitmap.
void mark_range(ptraddr_t base, ptraddr_t top)
Set or clear the shadow bits for all addresses within [base, top).
void mark_one(ptraddr_t address, bool fill)
Set or clear the single shadow bit for an address.
void mark_clear_one(ptraddr_t address)
Clear a single shadow bit for an address.
void mark_clear_range(ptraddr_t base, ptraddr_t top)
Clear a range of shadow bits, from base to top.
void mark_set_one(CHERI::Capability< void > cap)
Set a single shadow bit for an address.
#define MMIO_CAPABILITY(type, name)
Provide a capability of the type volatile type * referring to the MMIO region exported in the linker ...
C++ APIs for assertions, invariants, and writing formatted debug messages to a UART.
Miscellaneous utility functions and classes.