From b6818c205e2de4d810909eeb20b926af686074ba Mon Sep 17 00:00:00 2001 From: Gabriel Somlo Date: Sat, 21 Dec 2019 12:59:19 -0500 Subject: [PATCH 1/2] cpu/rocket: access PLIC registers via pointer dereference Since the PLIC is internal to Rocket, access its registers directly via pointer dereference, rather than through the LiteX CSR Bus accessors (which assume subregister slicing, and are therefore inappropriate for registers NOT accessed over the LiteX CSR Bus). Signed-off-by: Gabriel Somlo --- litex/soc/software/bios/isr.c | 10 +++++----- litex/soc/software/include/base/irq.h | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/litex/soc/software/bios/isr.c b/litex/soc/software/bios/isr.c index 68944072d..93c231bb1 100644 --- a/litex/soc/software/bios/isr.c +++ b/litex/soc/software/bios/isr.c @@ -16,11 +16,11 @@ void plic_init(void) // priorities for interrupt pins 1..4 for (i = 1; i <= 4; i++) - csr_writel(1, PLIC_BASE + 4*i); + *((unsigned int *)PLIC_BASE + i) = 1; // enable interrupt pins 1..4 - csr_writel(0xf << 1, PLIC_ENABLED); + *((unsigned int *)PLIC_ENABLED) = 0xf << 1; // set priority threshold to 0 (any priority > 0 triggers interrupt) - csr_writel(0, PLIC_THRSHLD); + *((unsigned int *)PLIC_THRSHLD) = 0; } void isr(void); @@ -28,7 +28,7 @@ void isr(void) { unsigned int claim; - while ((claim = csr_readl(PLIC_CLAIM))) { + while ((claim = *((unsigned int *)PLIC_CLAIM))) { switch (claim - 1) { case UART_INTERRUPT: uart_isr(); @@ -45,7 +45,7 @@ void isr(void) printf("###########################\n\n"); break; } - csr_writel(claim, PLIC_CLAIM); + *((unsigned int *)PLIC_CLAIM) = claim; } } #else diff --git a/litex/soc/software/include/base/irq.h b/litex/soc/software/include/base/irq.h index a9d1fecbe..babc5424f 100644 --- a/litex/soc/software/include/base/irq.h +++ b/litex/soc/software/include/base/irq.h @@ -111,7 +111,7 @@ static inline unsigned int irq_getmask(void) asm volatile ("csrr %0, %1" : "=r"(mask) : "i"(CSR_IRQ_MASK)); return mask; #elif defined (__rocket__) - return csr_readl(PLIC_ENABLED) >> 1; + return *((unsigned int *)PLIC_ENABLED) >> 1; #elif defined (__microwatt__) return 0; // FIXME #else @@ -134,7 +134,7 @@ static inline void irq_setmask(unsigned int mask) #elif defined (__minerva__) asm volatile ("csrw %0, %1" :: "i"(CSR_IRQ_MASK), "r"(mask)); #elif defined (__rocket__) - csr_writel(mask << 1, PLIC_ENABLED); + *((unsigned int *)PLIC_ENABLED) = mask << 1; #elif defined (__microwatt__) // FIXME #else @@ -161,7 +161,7 @@ static inline unsigned int irq_pending(void) asm volatile ("csrr %0, %1" : "=r"(pending) : "i"(CSR_IRQ_PENDING)); return pending; #elif defined (__rocket__) - return csr_readl(PLIC_PENDING) >> 1; + return *((unsigned int *)PLIC_PENDING) >> 1; #elif defined (__microwatt__) return 0; // FIXME #else From 585b50b2922c45722a0954848080d161a4122725 Mon Sep 17 00:00:00 2001 From: Gabriel Somlo Date: Wed, 18 Dec 2019 11:24:11 -0500 Subject: [PATCH 2/2] soc_core: csr_alignment assertions Enforce the condition that csr_alignment be either 32 or 64 when requested explicitly when initializing SoCCore(). Additionally, if a CPU is specified, enforce that csr_alignment be equal to the native CPU word size (currently either 32 or 64), and warn the caller if an alignment value *higher* than the CPU native word size was explicitly requested. In conclusion, if a CPU is specified, then csr_alignment should be assumed to equal 8*sizeof(unsigned long). Signed-off-by: Gabriel Somlo --- litex/soc/integration/soc_core.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/litex/soc/integration/soc_core.py b/litex/soc/integration/soc_core.py index 6bafe6f1f..61281f02f 100644 --- a/litex/soc/integration/soc_core.py +++ b/litex/soc/integration/soc_core.py @@ -141,6 +141,8 @@ class SoCCore(Module): self.csr_data_width = csr_data_width self.csr_address_width = csr_address_width + assert csr_alignment in [32, 64] + self.with_ctrl = with_ctrl self.with_uart = with_uart @@ -200,6 +202,9 @@ class SoCCore(Module): # Allow SoCController to reset the CPU if with_ctrl: self.comb += self.cpu.reset.eq(self.ctrl.reset) + + assert csr_alignment <= self.cpu.data_width + csr_alignment = self.cpu.data_width else: self.submodules.cpu = cpu.CPUNone() self.soc_io_regions.update(self.cpu.io_regions) @@ -256,7 +261,6 @@ class SoCCore(Module): self.add_interrupt("timer0", allow_user_defined=True) # Add Wishbone to CSR bridge - csr_alignment = max(csr_alignment, self.cpu.data_width) self.config["CSR_DATA_WIDTH"] = csr_data_width self.config["CSR_ALIGNMENT"] = csr_alignment assert csr_data_width <= csr_alignment