Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions sw-sysemu/memory/erbium/main_memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,17 @@ void MainMemory::reset()
{
regions[erbreg_idx].reset(new SysregsEr<region_bases[erbreg_idx]>());
regions[mram_bridge_idx].reset(new DenseRegion<region_bases[mram_bridge_idx], region_sizes[mram_bridge_idx]>());
regions[i2c_idx].reset(new DenseRegion<region_bases[i2c_idx], region_sizes[i2c_idx]>());
regions[qspi_idx].reset(new DenseRegion<region_bases[qspi_idx], region_sizes[qspi_idx]>());
regions[uart_idx].reset(new ShaktiUart<region_bases[uart_idx], region_sizes[uart_idx], ER_PLIC_UART0_INTR_ID>());
regions[bootrom_idx].reset(new DenseRegion<region_bases[bootrom_idx], region_sizes[bootrom_idx], false>());
regions[sram_idx].reset(new DenseRegion<region_bases[sram_idx], region_sizes[sram_idx]>());
regions[xspi_idx].reset(new DenseRegion<region_bases[xspi_idx], region_sizes[xspi_idx]>());
regions[dram_idx].reset(new DenseRegion<region_bases[dram_idx], region_sizes[dram_idx]>());
regions[otp_idx].reset(new DenseRegion<region_bases[otp_idx], region_sizes[otp_idx], false>());
regions[sysreg_idx].reset(new SysregRegion<region_bases[sysreg_idx], region_sizes[sysreg_idx]>());
regions[plic_idx].reset(new ER_PLIC<region_bases[plic_idx], region_sizes[plic_idx]>());
regions[nic_idx].reset(new DenseRegion<region_bases[nic_idx], region_sizes[nic_idx]>());
}

void MainMemory::wdt_clock_tick(const Agent& agent, uint64_t cycle)
Expand Down
19 changes: 18 additions & 1 deletion sw-sysemu/memory/erbium/main_memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,18 @@ namespace bemu {
// | From | To | Size | Maps to |
// +----------------+----------------+----------+-------------------+
// | 0x00_0200_0000 | 0x00_0200_0FFF | 4KiB | SystemRegisters |
// | 0x00_0200_1000 | 0x00_0200_1FFF | 4KiB | MRAM Bridge |
// | 0x00_0200_2000 | 0x00_0200_2FFF | 4KiB | I2C |
// | 0x00_0200_3000 | 0x00_0200_3FFF | 4KiB | QSPI |
// | 0x00_0200_4000 | 0x00_0200_4FFF | 4KiB | UART |
// | 0x00_0200_A000 | 0x00_0200_BFFF | 8KiB | Boot ROM |
// | 0x00_0200_8000 | 0x00_0200_9FFF | 8KiB | Boot ROM |
// | 0x00_0200_C000 | 0x00_0200_CFFF | 4KiB | Scratch SRAM |
// | 0x00_0200_F000 | 0x00_0200_FFFF | 4KiB | xSPI |
// | 0x00_4000_0000 | 0x00_40FF_FFFF | 16MiB | MRAM |
// | 0x00_7FFF_D000 | 0x00_7FFF_FFFF | 12KiB | OTP (read-only) |
// | 0x00_8000_0000 | 0x00_80FF_FFFF | 16MiB | ESR Registers |
// | 0x00_A000_0000 | 0x00_A3FF_FFFF | 64MiB | PLIC |
// | 0x00_FE00_0000 | 0x00_FE01_5FFF | 88KiB | NIC config |
// +----------------+----------------+----------+-------------------+
//

Expand All @@ -48,39 +53,51 @@ struct MainMemory {
enum : unsigned {
erbreg_idx,
mram_bridge_idx,
i2c_idx,
qspi_idx,
uart_idx,
bootrom_idx,
sram_idx,
xspi_idx,
dram_idx,
otp_idx,
sysreg_idx,
plic_idx,
nic_idx,

REGION_COUNT
};

constexpr static uint64_t region_bases[REGION_COUNT] = {
/* erbreg */ ERBIUM_TOP_SYSTEM_REGISTERS_BASE,
/* mram_bridge */ ERBIUM_TOP_MRAM_REGISTERS_BASE,
/* i2c */ ERBIUM_TOP_I2C_REGISTERS_BASE,
/* qspi */ ERBIUM_TOP_QSPI_REGISTERS_BASE,
/* uart */ ERBIUM_TOP_UART_REGISTERS_BASE,
/* bootrom */ ERBIUM_TOP_BOOTROM_BASE,
/* sram */ ERBIUM_TOP_SRAM_BASE,
/* xspi */ ERBIUM_TOP_XSPI_REGISTERS_BASE,
/* dram */ ERBIUM_TOP_MRAM_BASE,
/* otp */ 0x007FFFD000ull,
/* sysreg */ ERBIUM_TOP_CPU_REGISTERS_BASE,
/* plic */ ERBIUM_TOP_PLIC_BASE,
/* nic */ ERBIUM_TOP_NIC_CONFIG_BASE,
};

constexpr static size_t region_sizes[REGION_COUNT] = {
/* erbreg */ ERBIUM_TOP_MRAM_REGISTERS_BASE - ERBIUM_TOP_SYSTEM_REGISTERS_BASE,
/* mram_bridge */ ERBIUM_TOP_I2C_REGISTERS_BASE - ERBIUM_TOP_MRAM_REGISTERS_BASE,
/* i2c */ ERBIUM_TOP_QSPI_REGISTERS_BASE - ERBIUM_TOP_I2C_REGISTERS_BASE,
/* qspi */ ERBIUM_TOP_UART_REGISTERS_BASE - ERBIUM_TOP_QSPI_REGISTERS_BASE,
/* uart */ 4_KiB,
/* bootrom */ ERBIUM_TOP_BOOTROM_SIZE,
/* sram */ ERBIUM_TOP_SRAM_SIZE,
/* xspi */ 4_KiB,
/* dram */ ERBIUM_TOP_MRAM_SIZE,
/* otp */ 12_KiB,
/* sysreg */ 16_MiB,
/* plic */ 64_MiB,
/* nic */ ERBIUM_TOP_NIC_CONFIG_SIZE,
};

public:
Expand Down
48 changes: 43 additions & 5 deletions sw-sysemu/pma_er.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ namespace bemu {
//
// 0x0200_0000 - 0x0200_0FFF: System registers (4K)
// 0x0200_1000 - 0x0200_1FFF: MRAM registers (4K)
// 0x0200_2000 - 0x0200_2FFF: Periph registers (4K)
// 0x0200_2000 - 0x0200_2FFF: I2C registers (4K)
// 0x0200_3000 - 0x0200_3FFF: QSPI registers (4K)
// 0x0200_F000 - 0x0200_FFFF: xSPI registers (4K)
// 0x0200_4000 - 0x0200_4FFF: UART registers (4K)
// 0x0200_8000 - 0x0200_9FFF: Bootrom (8K)
Expand All @@ -28,6 +29,7 @@ namespace bemu {
// 0x7FFF_D000 - 0x7FFF_FFFF: OTP (12K, read-only)
// 0x8000_0000 - 0x9FFF_FFFF: ESR/CPU registers (512M)
// 0xA000_0000 - 0xA3FF_FFFF: PLIC (64M)
// 0xFE00_0000 - 0xFE01_5FFF: NIC config (88K)
//
// Bases come from hwinc/top.h (regenerated from the top-level RDL);
// upper bounds either come from the next region's base or, where the
Expand All @@ -39,11 +41,14 @@ static inline bool paddr_is_sysreg(uint64_t addr)
static inline bool paddr_is_mramreg(uint64_t addr)
{ return (addr >= ERBIUM_TOP_MRAM_REGISTERS_BASE) && (addr < ERBIUM_TOP_I2C_REGISTERS_BASE); }

static inline bool paddr_is_periph(uint64_t addr)
static inline bool paddr_is_i2c(uint64_t addr)
{ return (addr >= ERBIUM_TOP_I2C_REGISTERS_BASE) && (addr < ERBIUM_TOP_QSPI_REGISTERS_BASE); }

static inline bool paddr_is_qspi(uint64_t addr)
{ return (addr >= ERBIUM_TOP_QSPI_REGISTERS_BASE) && (addr < ERBIUM_TOP_UART_REGISTERS_BASE); }

static inline bool paddr_is_xspi(uint64_t addr)
{ return (addr >= ERBIUM_TOP_XSPI_REGISTERS_BASE) && (addr < ERBIUM_TOP_XSPI_REGISTERS_END); }
{ return (addr >= ERBIUM_TOP_XSPI_REGISTERS_BASE) && (addr < ERBIUM_TOP_XSPI_REGISTERS_BASE + 0x1000ull); }

static inline bool paddr_is_uart(uint64_t addr)
{ return (addr >= ERBIUM_TOP_UART_REGISTERS_BASE) && (addr < ERBIUM_TOP_UART_REGISTERS_END); }
Expand All @@ -68,6 +73,9 @@ static inline bool paddr_is_mram(uint64_t addr)
static inline bool paddr_is_esr(uint64_t addr)
{ return (addr >= ERBIUM_TOP_CPU_REGISTERS_BASE) && (addr < ERBIUM_TOP_PLIC_BASE); }

static inline bool paddr_is_nic(uint64_t addr)
{ return (addr >= ERBIUM_TOP_NIC_CONFIG_BASE) && (addr < ERBIUM_TOP_NIC_CONFIG_END); }

static inline bool paddr_is_plic(uint64_t addr)
{ return (addr >= ERBIUM_TOP_PLIC_BASE) && (addr < ERBIUM_TOP_PLIC_END); }

Expand Down Expand Up @@ -275,8 +283,8 @@ uint64_t pma_check_data_access(const Hart& cpu, uint64_t vaddr,
return addr;
}

if (paddr_is_periph(addr)) {
// Periph registers: 32-bit aligned, 32-bit access, M/S privilege,
if (paddr_is_i2c(addr)) {
// I2C registers: 32-bit aligned, 32-bit access, M/S privilege,
// no AMO/TensorOp/CacheOp
Privilege mode = effective_execution_mode(cpu, macc);
if (amo
Expand Down Expand Up @@ -305,6 +313,21 @@ uint64_t pma_check_data_access(const Hart& cpu, uint64_t vaddr,
return addr;
}

if (paddr_is_qspi(addr)) {
// QSPI registers: 64-bit aligned, 32-bit access, M/S privilege,
// no AMO/TensorOp/CacheOp
Privilege mode = effective_execution_mode(cpu, macc);
if (amo
|| ts_tl_co
|| (size != 4)
|| !addr_is_size_aligned(addr, 8)
|| (mode == Privilege::U))
{
throw_access_fault(vaddr, macc);
}
return addr;
}

if (paddr_is_uart(addr)) {
// UART registers: 64-bit aligned, 32-bit access, M/S privilege,
// no AMO/TensorOp/CacheOp
Expand All @@ -320,6 +343,21 @@ uint64_t pma_check_data_access(const Hart& cpu, uint64_t vaddr,
return addr;
}

if (paddr_is_nic(addr)) {
// NIC config: 64-bit aligned, 32-bit access, M-mode only,
// no AMO/TensorOp/CacheOp
Privilege mode = effective_execution_mode(cpu, macc);
if (amo
|| ts_tl_co
|| (size != 4)
|| !addr_is_size_aligned(addr, 8)
|| (mode != Privilege::M))
{
throw_access_fault(vaddr, macc);
}
return addr;
}

// Unknown/reserved region - access fault
throw_access_fault(vaddr, macc);
}
Expand Down
Loading