From cd96ee330ffb9c2929aa28be4bec0293fec1a41f Mon Sep 17 00:00:00 2001 From: Nils Wistoff Date: Fri, 13 Dec 2019 20:00:53 +0100 Subject: [PATCH] ariane: update PLIC and dts add PLIC driver for Ariane and update dts Signed-off-by: Nils Wistoff Reviewed-by: Siwei Zhuang --- include/drivers/irq/ariane.h | 177 +++++++++++++++++++++++++++++ src/plat/ariane/config.cmake | 5 +- src/plat/ariane/overlay-ariane.dts | 18 +++ tools/dts/ariane.dts | 10 +- 4 files changed, 206 insertions(+), 4 deletions(-) create mode 100644 include/drivers/irq/ariane.h create mode 100644 src/plat/ariane/overlay-ariane.dts diff --git a/include/drivers/irq/ariane.h b/include/drivers/irq/ariane.h new file mode 100644 index 000000000..68e8b36b8 --- /dev/null +++ b/include/drivers/irq/ariane.h @@ -0,0 +1,177 @@ +/* + * Copyright 2019, Data61 + * Commonwealth Scientific and Industrial Research Organisation (CSIRO) + * ABN 41 687 119 230. + * + * This software may be distributed and modified according to the terms of + * the GNU General Public License version 2. Note that NO WARRANTY is provided. + * See "LICENSE_GPLv2.txt" for details. + * + * @TAG(DATA61_GPL) + */ + +#ifndef __DRIVER_IRQ_ARIANE_H +#define __DRIVER_IRQ_ARIANE_H + +#include +#include + +/* The memory map is based on the PLIC section in + * https://static.dev.sifive.com/U54-MC-RVCoreIP.pdf + */ + +#define PLIC_PPTR_BASE (PLIC_PPTR + 0x0C000000) + + +#define PLIC_HART_ID (CONFIG_FIRST_HART_ID) + +#define PLIC_PRIO 0x0 +#define PLIC_PRIO_PER_ID 0x4 + +#define PLIC_PENDING 0x1000 +#define PLIC_EN 0x2000 +#define PLIC_EN_PER_HART 0x100 +#define PLIC_EN_PER_CONTEXT 0x80 + + +#define PLIC_THRES 0x200000 +#define PLIC_SVC_CONTEXT 1 +#define PLIC_THRES_PER_HART 0x2000 +#define PLIC_THRES_PER_CONTEXT 0x1000 +#define PLIC_THRES_CLAIM 0x4 + +#define PLIC_NUM_INTERRUPTS 30 +#define PLAT_PLIC_THRES_ADJUST(x) (x) +#define PLAT_PLIC_EN_ADJUST(x) (x) + +typedef uint32_t interrupt_t; + +static inline void write_sie(word_t value) +{ + asm volatile("csrw sie, %0" :: "r"(value)); +} + +static inline word_t read_sie(void) +{ + word_t temp; + asm volatile("csrr %0, sie" : "=r"(temp)); + return temp; +} + +static inline uint32_t readl(const volatile uint64_t addr) +{ + uint32_t val; + asm volatile("lw %0, 0(%1)" : "=r"(val) : "r"(addr)); + return val; +} + +static inline void writel(uint32_t val, volatile uint64_t addr) +{ + asm volatile("sw %0, 0(%1)" : : "r"(val), "r"(addr)); +} + +static inline word_t plic_enable_offset(word_t hart_id, word_t context_id) +{ + word_t addr = PLAT_PLIC_EN_ADJUST(PLIC_EN + hart_id * PLIC_EN_PER_HART + context_id * PLIC_EN_PER_CONTEXT); + return addr; +} + + +static inline word_t plic_thres_offset(word_t hart_id, word_t context_id) +{ + word_t addr = PLAT_PLIC_THRES_ADJUST(PLIC_THRES + hart_id * PLIC_THRES_PER_HART + context_id * PLIC_THRES_PER_CONTEXT); + return addr; +} + +static inline word_t plic_claim_offset(word_t hart_id, word_t context_id) +{ + word_t addr = plic_thres_offset(hart_id, context_id) + PLIC_THRES_CLAIM; + return addr; +} + +static inline bool_t plic_pending_interrupt(word_t interrupt) +{ + word_t addr = PLIC_PPTR_BASE + PLIC_PENDING + (interrupt / 32) * 4; + word_t bit = interrupt % 32; + if (readl(addr) & BIT(bit)) { + return true; + } else { + return false; + } +} + +static inline word_t get_hart_id(void) +{ +#ifdef ENABLE_SMP_SUPPORT + return cpuIndexToID(getCurrentCPUIndex()); +#else + return CONFIG_FIRST_HART_ID; +#endif +} + +static inline interrupt_t plic_get_claim(void) +{ + /* Read the claim register for our HART interrupt context */ + word_t hart_id = get_hart_id(); + return readl(PLIC_PPTR_BASE + plic_claim_offset(hart_id, PLIC_SVC_CONTEXT)); +} + +static inline void plic_complete_claim(interrupt_t irq) +{ + /* Complete the IRQ claim by writing back to the claim register. */ + word_t hart_id = get_hart_id(); + writel(irq, PLIC_PPTR_BASE + plic_claim_offset(hart_id, PLIC_SVC_CONTEXT)); +} + +static inline void plic_mask_irq(bool_t disable, interrupt_t irq) +{ + uint64_t addr = 0; + uint32_t val = 0; + uint32_t bit = 0; + + word_t hart_id = get_hart_id(); + addr = PLIC_PPTR_BASE + plic_enable_offset(hart_id, PLIC_SVC_CONTEXT) + (irq / 32) * 4; + bit = irq % 32; + + val = readl(addr); + if (disable) { + val &= ~BIT(bit); + } else { + val |= BIT(bit); + } + writel(val, addr); +} + +static inline void plic_init_hart(void) +{ + + word_t hart_id = get_hart_id(); + + for (int i = 1; i <= PLIC_NUM_INTERRUPTS; i++) { + /* Disable interrupts */ + plic_mask_irq(true, i); + } + + /* Set threshold to zero */ + writel(0, (PLIC_PPTR_BASE + plic_thres_offset(hart_id, PLIC_SVC_CONTEXT))); +} + +static inline void plic_init_controller(void) +{ + + for (int i = 1; i <= PLIC_NUM_INTERRUPTS; i++) { + /* Clear all pending bits */ + if (plic_pending_interrupt(i)) { + readl(PLIC_PPTR_BASE + plic_claim_offset(PLIC_HART_ID, PLIC_SVC_CONTEXT)); + writel(i, PLIC_PPTR_BASE + plic_claim_offset(PLIC_HART_ID, PLIC_SVC_CONTEXT)); + } + } + + /* Set the priorities of all interrupts to 1 */ + for (int i = 1; i <= PLIC_MAX_IRQ + 1; i++) { + writel(2, PLIC_PPTR_BASE + PLIC_PRIO + PLIC_PRIO_PER_ID * i); + } + +} + +#endif /* __DRIVER_IRQ_ARIANE_H */ diff --git a/src/plat/ariane/config.cmake b/src/plat/ariane/config.cmake index 160203b8d..d5f7c4b6f 100644 --- a/src/plat/ariane/config.cmake +++ b/src/plat/ariane/config.cmake @@ -13,9 +13,10 @@ if(KernelPlatformAriane) config_set(KernelRiscVPlatform RISCV_PLAT "ariane") config_set(KernelPlatformFirstHartID FIRST_HART_ID 0) list(APPEND KernelDTSList "tools/dts/ariane.dts") + list(APPEND KernelDTSList "src/plat/ariane/overlay-ariane.dts") declare_default_headers( - TIMER_FREQUENCY 10000000llu PLIC_MAX_NUM_INT 0 - INTERRUPT_CONTROLLER arch/machine/plic.h + TIMER_FREQUENCY 10000000llu PLIC_MAX_NUM_INT 30 + INTERRUPT_CONTROLLER drivers/irq/ariane.h ) else() unset(KernelPlatformFirstHartID CACHE) diff --git a/src/plat/ariane/overlay-ariane.dts b/src/plat/ariane/overlay-ariane.dts new file mode 100644 index 000000000..13d425a5a --- /dev/null +++ b/src/plat/ariane/overlay-ariane.dts @@ -0,0 +1,18 @@ +/* + * Copyright 2019, Data61 + * Commonwealth Scientific and Industrial Research Organisation (CSIRO) + * ABN 41 687 119 230. + * + * This software may be distributed and modified according to the terms of + * the GNU General Public License version 2. Note that NO WARRANTY is provided. + * See "LICENSE_GPLv2.txt" for details. + * + * @TAG(DATA61_GPL) + */ + +/ { + chosen { + seL4,kernel-devices = + &{/soc/interrupt-controller@c000000}; + }; +}; diff --git a/tools/dts/ariane.dts b/tools/dts/ariane.dts index a0cda58f5..0e4681b09 100644 --- a/tools/dts/ariane.dts +++ b/tools/dts/ariane.dts @@ -19,7 +19,6 @@ compatible = "eth,ariane-bare-dev"; model = "eth,ariane-bare"; chosen { - stdout-path = "/soc/uart@10000000:115200"; }; cpus { #address-cells = <1>; @@ -73,7 +72,7 @@ interrupts-extended = <&CPU0_intc 11 &CPU0_intc 9>; reg = <0x0 0xc000000 0x0 0x4000000>; riscv,max-priority = <7>; - riscv,ndev = <3>; + riscv,ndev = <30>; }; debug-controller@0 { compatible = "riscv,debug-013"; @@ -91,6 +90,13 @@ reg-shift = <2>; // regs are spaced on 32 bit boundary reg-io-width = <4>; // only 32-bit access are supported }; + timer@18000000 { + compatible = "pulp,apb_timer"; + interrupts = <0x00000004 0x00000005 0x00000006 0x00000007>; + reg = <0x00000000 0x18000000 0x00000000 0x00001000>; + interrupt-parent = <&PLIC0>; + reg-names = "control"; + }; xps-spi@20000000 { compatible = "xlnx,xps-spi-2.00.b", "xlnx,xps-spi-2.00.a"; #address-cells = <1>;