From c92e4cb3ca122349c27019f3715c9a2e41bf3c04 Mon Sep 17 00:00:00 2001 From: Evan Lojewski Date: Wed, 10 Mar 2021 07:32:24 -0700 Subject: [PATCH 1/2] xics: Ass missing static keywords to irq header. --- litex/soc/cores/cpu/microwatt/irq.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/litex/soc/cores/cpu/microwatt/irq.h b/litex/soc/cores/cpu/microwatt/irq.h index a6332d08c..f20bc3f04 100644 --- a/litex/soc/cores/cpu/microwatt/irq.h +++ b/litex/soc/cores/cpu/microwatt/irq.h @@ -33,54 +33,54 @@ void isr(uint64_t vec); // Default external interrupt priority set by software during IRQ enable #define PPC_EXT_INTERRUPT_PRIO 0x08 -uint8_t inline xics_icp_readb(int reg) +static inline uint8_t xics_icp_readb(int reg) { return *((uint8_t*)(XICSICP_BASE + reg)); } -void inline xics_icp_writeb(int reg, uint8_t value) +static inline void xics_icp_writeb(int reg, uint8_t value) { *((uint8_t*)(XICSICP_BASE + reg)) = value; } -uint32_t inline xics_icp_readw(int reg) +static inline uint32_t xics_icp_readw(int reg) { return *((uint32_t*)(XICSICP_BASE + reg)); } -void inline xics_icp_writew(int reg, uint32_t value) +static inline void xics_icp_writew(int reg, uint32_t value) { *((uint32_t*)(XICSICP_BASE + reg)) = value; } -uint32_t inline xics_ics_read_xive(int irq_number) +static inline uint32_t xics_ics_read_xive(int irq_number) { return *((uint32_t*)(XICSICS_BASE + 0x800 + (irq_number << 2))); } -void inline xics_ics_write_xive(int irq_number, uint32_t priority) +static inline void xics_ics_write_xive(int irq_number, uint32_t priority) { *((uint32_t*)(XICSICS_BASE + 0x800 + (irq_number << 2))) = priority; } -void inline mtmsrd(uint64_t val) +static inline void mtmsrd(uint64_t val) { __asm__ volatile("mtmsrd %0" : : "r" (val) : "memory"); } -uint64_t inline mfmsr(void) +static inline uint64_t mfmsr(void) { uint64_t rval; __asm__ volatile("mfmsr %0" : "=r" (rval) : : "memory"); return rval; } -void inline mtdec(uint64_t val) +static inline void mtdec(uint64_t val) { __asm__ volatile("mtdec %0" : : "r" (val) : "memory"); } -uint64_t inline mfdec(void) +static inline uint64_t mfdec(void) { uint64_t rval; __asm__ volatile("mfdec %0" : "=r" (rval) : : "memory"); From 08072eb872aea79c81f54181b71e26d5f8aa5688 Mon Sep 17 00:00:00 2001 From: Evan Lojewski Date: Wed, 10 Mar 2021 07:36:11 -0700 Subject: [PATCH 2/2] xics: Disable endianness swapping The endianess swapping code caused the core to diverge from microwatt resulting in: - The xics tests not working as-is: https://github.com/antonblanchard/microwatt/blob/master/tests/xics/xics.h - byte writes writing to the incorrect byte This removes endianswapping and minimizes the delta from upstream for the xics irq.h header. --- litex/soc/cores/cpu/microwatt/core.py | 21 +++++---------------- litex/soc/cores/cpu/microwatt/irq.h | 10 ++++++---- 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/litex/soc/cores/cpu/microwatt/core.py b/litex/soc/cores/cpu/microwatt/core.py index 7efea0d8e..4acef6289 100644 --- a/litex/soc/cores/cpu/microwatt/core.py +++ b/litex/soc/cores/cpu/microwatt/core.py @@ -123,7 +123,6 @@ class Microwatt(CPU): variant = self.variant, core_irq_out = self.core_ext_irq, int_level_in = self.interrupt, - endianness = self.endianness ) xicsicp_region = soc_region_cls(origin=soc.mem_map.get("xicsicp"), size=4096, cached=False) xicsics_region = soc_region_cls(origin=soc.mem_map.get("xicsics"), size=4096, cached=False) @@ -212,22 +211,12 @@ class Microwatt(CPU): class XICSSlave(Module, AutoCSR): - def __init__(self, platform, core_irq_out=Signal(), int_level_in=Signal(16), endianness="big", variant="standard"): + def __init__(self, platform, core_irq_out=Signal(), int_level_in=Signal(16), variant="standard"): self.variant = variant self.icp_bus = icp_bus = wishbone.Interface(data_width=32, adr_width=12) self.ics_bus = ics_bus = wishbone.Interface(data_width=32, adr_width=12) - # Bus endianness handlers - self.icp_dat_w = Signal(32) - self.icp_dat_r = Signal(32) - self.comb += self.icp_dat_w.eq(icp_bus.dat_w if endianness == "big" else reverse_bytes(icp_bus.dat_w)) - self.comb += icp_bus.dat_r.eq(self.icp_dat_r if endianness == "big" else reverse_bytes(self.icp_dat_r)) - self.ics_dat_w = Signal(32) - self.ics_dat_r = Signal(32) - self.comb += self.ics_dat_w.eq(ics_bus.dat_w if endianness == "big" else reverse_bytes(ics_bus.dat_w)) - self.comb += ics_bus.dat_r.eq(self.ics_dat_r if endianness == "big" else reverse_bytes(self.ics_dat_r)) - # XICS signals self.ics_icp_xfer_src = Signal(4) self.ics_icp_xfer_pri = Signal(8) @@ -238,11 +227,11 @@ class XICSSlave(Module, AutoCSR): i_rst = ResetSignal(), # Wishbone bus - o_wishbone_dat_r = self.icp_dat_r, + o_wishbone_dat_r = icp_bus.dat_r, o_wishbone_ack = icp_bus.ack, i_wishbone_adr = icp_bus.adr, - i_wishbone_dat_w = self.icp_dat_w, + i_wishbone_dat_w = icp_bus.dat_w, i_wishbone_cyc = icp_bus.cyc, i_wishbone_stb = icp_bus.stb, i_wishbone_sel = icp_bus.sel, @@ -260,11 +249,11 @@ class XICSSlave(Module, AutoCSR): i_rst = ResetSignal(), # Wishbone bus - o_wishbone_dat_r = self.ics_dat_r, + o_wishbone_dat_r = ics_bus.dat_r, o_wishbone_ack = ics_bus.ack, i_wishbone_adr = ics_bus.adr, - i_wishbone_dat_w = self.ics_dat_w, + i_wishbone_dat_w = ics_bus.dat_w, i_wishbone_cyc = ics_bus.cyc, i_wishbone_stb = ics_bus.stb, i_wishbone_sel = ics_bus.sel, diff --git a/litex/soc/cores/cpu/microwatt/irq.h b/litex/soc/cores/cpu/microwatt/irq.h index f20bc3f04..a4b20b66d 100644 --- a/litex/soc/cores/cpu/microwatt/irq.h +++ b/litex/soc/cores/cpu/microwatt/irq.h @@ -33,6 +33,8 @@ void isr(uint64_t vec); // Default external interrupt priority set by software during IRQ enable #define PPC_EXT_INTERRUPT_PRIO 0x08 +#define bswap32(x) (uint32_t)__builtin_bswap32((uint32_t)(x)) + static inline uint8_t xics_icp_readb(int reg) { return *((uint8_t*)(XICSICP_BASE + reg)); @@ -45,22 +47,22 @@ static inline void xics_icp_writeb(int reg, uint8_t value) static inline uint32_t xics_icp_readw(int reg) { - return *((uint32_t*)(XICSICP_BASE + reg)); + return bswap32(*((uint32_t*)(XICSICP_BASE + reg))); } static inline void xics_icp_writew(int reg, uint32_t value) { - *((uint32_t*)(XICSICP_BASE + reg)) = value; + *((uint32_t*)(XICSICP_BASE + reg)) = bswap32(value); } static inline uint32_t xics_ics_read_xive(int irq_number) { - return *((uint32_t*)(XICSICS_BASE + 0x800 + (irq_number << 2))); + return bswap32(*((uint32_t*)(XICSICS_BASE + 0x800 + (irq_number << 2)))); } static inline void xics_ics_write_xive(int irq_number, uint32_t priority) { - *((uint32_t*)(XICSICS_BASE + 0x800 + (irq_number << 2))) = priority; + *((uint32_t*)(XICSICS_BASE + 0x800 + (irq_number << 2))) = bswap32(priority); } static inline void mtmsrd(uint64_t val)