diff options
Diffstat (limited to 'riscv/mmu.h')
-rw-r--r-- | riscv/mmu.h | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/riscv/mmu.h b/riscv/mmu.h index 1f8d34b..105908e 100644 --- a/riscv/mmu.h +++ b/riscv/mmu.h @@ -105,12 +105,32 @@ public: store_slow_path(addr, sizeof(type##_t), (const uint8_t*)&val); \ } + // template for functions that perform an atomic memory operation + #define amo_func(type) \ + template<typename op> \ + type##_t amo_##type(reg_t addr, op f) { \ + if (addr & (sizeof(type##_t)-1)) \ + throw trap_store_address_misaligned(addr); \ + try { \ + auto lhs = load_##type(addr); \ + store_##type(addr, f(lhs)); \ + return lhs; \ + } catch (trap_load_access_fault& t) { \ + /* AMO faults should be reported as store faults */ \ + throw trap_store_access_fault(t.get_badaddr()); \ + } \ + } + // store value to memory at aligned address store_func(uint8) store_func(uint16) store_func(uint32) store_func(uint64) + // perform an atomic memory operation at an aligned address + amo_func(uint32) + amo_func(uint64) + static const reg_t ICACHE_ENTRIES = 1024; inline size_t icache_index(reg_t addr) |