diff options
27 files changed, 625 insertions, 59 deletions
diff --git a/Documentation/devicetree/bindings/interrupt-controller/riscv,cpu-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/riscv,cpu-intc.txt new file mode 100644 index 000000000000..b0a8af51c388 --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/riscv,cpu-intc.txt | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | RISC-V Hart-Level Interrupt Controller (HLIC) | ||
| 2 | --------------------------------------------- | ||
| 3 | |||
| 4 | RISC-V cores include Control Status Registers (CSRs) which are local to each | ||
| 5 | CPU core (HART in RISC-V terminology) and can be read or written by software. | ||
| 6 | Some of these CSRs are used to control local interrupts connected to the core. | ||
| 7 | Every interrupt is ultimately routed through a hart's HLIC before it | ||
| 8 | interrupts that hart. | ||
| 9 | |||
| 10 | The RISC-V supervisor ISA manual specifies three interrupt sources that are | ||
| 11 | attached to every HLIC: software interrupts, the timer interrupt, and external | ||
| 12 | interrupts. Software interrupts are used to send IPIs between cores. The | ||
| 13 | timer interrupt comes from an architecturally mandated real-time timer that is | ||
| 14 | controller via Supervisor Binary Interface (SBI) calls and CSR reads. External | ||
| 15 | interrupts connect all other device interrupts to the HLIC, which are routed | ||
| 16 | via the platform-level interrupt controller (PLIC). | ||
| 17 | |||
| 18 | All RISC-V systems that conform to the supervisor ISA specification are | ||
| 19 | required to have a HLIC with these three interrupt sources present. Since the | ||
| 20 | interrupt map is defined by the ISA it's not listed in the HLIC's device tree | ||
| 21 | entry, though external interrupt controllers (like the PLIC, for example) will | ||
| 22 | need to define how their interrupts map to the relevant HLICs. This means | ||
| 23 | a PLIC interrupt property will typically list the HLICs for all present HARTs | ||
| 24 | in the system. | ||
| 25 | |||
| 26 | Required properties: | ||
| 27 | - compatible : "riscv,cpu-intc" | ||
| 28 | - #interrupt-cells : should be <1> | ||
| 29 | - interrupt-controller : Identifies the node as an interrupt controller | ||
| 30 | |||
| 31 | Furthermore, this interrupt-controller MUST be embedded inside the cpu | ||
| 32 | definition of the hart whose CSRs control these local interrupts. | ||
| 33 | |||
| 34 | An example device tree entry for a HLIC is show below. | ||
| 35 | |||
| 36 | cpu1: cpu@1 { | ||
| 37 | compatible = "riscv"; | ||
| 38 | ... | ||
| 39 | cpu1-intc: interrupt-controller { | ||
| 40 | #interrupt-cells = <1>; | ||
| 41 | compatible = "riscv,cpu-intc", "sifive,fu540-c000-cpu-intc"; | ||
| 42 | interrupt-controller; | ||
| 43 | }; | ||
| 44 | }; | ||
diff --git a/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.txt b/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.txt new file mode 100644 index 000000000000..6adf7a6e8825 --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.txt | |||
| @@ -0,0 +1,58 @@ | |||
| 1 | SiFive Platform-Level Interrupt Controller (PLIC) | ||
| 2 | ------------------------------------------------- | ||
| 3 | |||
| 4 | SiFive SOCs include an implementation of the Platform-Level Interrupt Controller | ||
| 5 | (PLIC) high-level specification in the RISC-V Privileged Architecture | ||
| 6 | specification. The PLIC connects all external interrupts in the system to all | ||
| 7 | hart contexts in the system, via the external interrupt source in each hart. | ||
| 8 | |||
| 9 | A hart context is a privilege mode in a hardware execution thread. For example, | ||
| 10 | in an 4 core system with 2-way SMT, you have 8 harts and probably at least two | ||
| 11 | privilege modes per hart; machine mode and supervisor mode. | ||
| 12 | |||
| 13 | Each interrupt can be enabled on per-context basis. Any context can claim | ||
| 14 | a pending enabled interrupt and then release it once it has been handled. | ||
| 15 | |||
| 16 | Each interrupt has a configurable priority. Higher priority interrupts are | ||
| 17 | serviced first. Each context can specify a priority threshold. Interrupts | ||
| 18 | with priority below this threshold will not cause the PLIC to raise its | ||
| 19 | interrupt line leading to the context. | ||
| 20 | |||
| 21 | While the PLIC supports both edge-triggered and level-triggered interrupts, | ||
| 22 | interrupt handlers are oblivious to this distinction and therefore it is not | ||
| 23 | specified in the PLIC device-tree binding. | ||
| 24 | |||
| 25 | While the RISC-V ISA doesn't specify a memory layout for the PLIC, the | ||
| 26 | "sifive,plic-1.0.0" device is a concrete implementation of the PLIC that | ||
| 27 | contains a specific memory layout, which is documented in chapter 8 of the | ||
| 28 | SiFive U5 Coreplex Series Manual <https://static.dev.sifive.com/U54-MC-RVCoreIP.pdf>. | ||
| 29 | |||
| 30 | Required properties: | ||
| 31 | - compatible : "sifive,plic-1.0.0" and a string identifying the actual | ||
| 32 | detailed implementation in case that specific bugs need to be worked around. | ||
| 33 | - #address-cells : should be <0> or more. | ||
| 34 | - #interrupt-cells : should be <1> or more. | ||
| 35 | - interrupt-controller : Identifies the node as an interrupt controller. | ||
| 36 | - reg : Should contain 1 register range (address and length). | ||
| 37 | - interrupts-extended : Specifies which contexts are connected to the PLIC, | ||
| 38 | with "-1" specifying that a context is not present. Each node pointed | ||
| 39 | to should be a riscv,cpu-intc node, which has a riscv node as parent. | ||
| 40 | - riscv,ndev: Specifies how many external interrupts are supported by | ||
| 41 | this controller. | ||
| 42 | |||
| 43 | Example: | ||
| 44 | |||
| 45 | plic: interrupt-controller@c000000 { | ||
| 46 | #address-cells = <0>; | ||
| 47 | #interrupt-cells = <1>; | ||
| 48 | compatible = "sifive,plic-1.0.0", "sifive,fu540-c000-plic"; | ||
| 49 | interrupt-controller; | ||
| 50 | interrupts-extended = < | ||
| 51 | &cpu0-intc 11 | ||
| 52 | &cpu1-intc 11 &cpu1-intc 9 | ||
| 53 | &cpu2-intc 11 &cpu2-intc 9 | ||
| 54 | &cpu3-intc 11 &cpu3-intc 9 | ||
| 55 | &cpu4-intc 11 &cpu4-intc 9>; | ||
| 56 | reg = <0xc000000 0x4000000>; | ||
| 57 | riscv,ndev = <10>; | ||
| 58 | }; | ||
diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile index 2627e4813edf..9ddd88bb30b7 100644 --- a/arch/riscv/Makefile +++ b/arch/riscv/Makefile | |||
| @@ -25,6 +25,9 @@ ifeq ($(CONFIG_ARCH_RV64I),y) | |||
| 25 | 25 | ||
| 26 | KBUILD_CFLAGS += -mabi=lp64 | 26 | KBUILD_CFLAGS += -mabi=lp64 |
| 27 | KBUILD_AFLAGS += -mabi=lp64 | 27 | KBUILD_AFLAGS += -mabi=lp64 |
| 28 | |||
| 29 | KBUILD_CFLAGS += $(call cc-ifversion, -ge, 0500, -DCONFIG_ARCH_SUPPORTS_INT128) | ||
| 30 | |||
| 28 | KBUILD_MARCH = rv64im | 31 | KBUILD_MARCH = rv64im |
| 29 | LDFLAGS += -melf64lriscv | 32 | LDFLAGS += -melf64lriscv |
| 30 | else | 33 | else |
diff --git a/arch/riscv/configs/defconfig b/arch/riscv/configs/defconfig index 07326466871b..36473d7dbaac 100644 --- a/arch/riscv/configs/defconfig +++ b/arch/riscv/configs/defconfig | |||
| @@ -76,3 +76,4 @@ CONFIG_ROOT_NFS=y | |||
| 76 | CONFIG_CRYPTO_USER_API_HASH=y | 76 | CONFIG_CRYPTO_USER_API_HASH=y |
| 77 | CONFIG_MODULES=y | 77 | CONFIG_MODULES=y |
| 78 | CONFIG_MODULE_UNLOAD=y | 78 | CONFIG_MODULE_UNLOAD=y |
| 79 | CONFIG_SIFIVE_PLIC=y | ||
diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h index 421fa3585798..28a0d1cb374c 100644 --- a/arch/riscv/include/asm/csr.h +++ b/arch/riscv/include/asm/csr.h | |||
| @@ -54,6 +54,7 @@ | |||
| 54 | /* Interrupt Enable and Interrupt Pending flags */ | 54 | /* Interrupt Enable and Interrupt Pending flags */ |
| 55 | #define SIE_SSIE _AC(0x00000002, UL) /* Software Interrupt Enable */ | 55 | #define SIE_SSIE _AC(0x00000002, UL) /* Software Interrupt Enable */ |
| 56 | #define SIE_STIE _AC(0x00000020, UL) /* Timer Interrupt Enable */ | 56 | #define SIE_STIE _AC(0x00000020, UL) /* Timer Interrupt Enable */ |
| 57 | #define SIE_SEIE _AC(0x00000200, UL) /* External Interrupt Enable */ | ||
| 57 | 58 | ||
| 58 | #define EXC_INST_MISALIGNED 0 | 59 | #define EXC_INST_MISALIGNED 0 |
| 59 | #define EXC_INST_ACCESS 1 | 60 | #define EXC_INST_ACCESS 1 |
diff --git a/arch/riscv/include/asm/irq.h b/arch/riscv/include/asm/irq.h index 4dee9d4c13c0..996b6fbe17a6 100644 --- a/arch/riscv/include/asm/irq.h +++ b/arch/riscv/include/asm/irq.h | |||
| @@ -17,11 +17,8 @@ | |||
| 17 | 17 | ||
| 18 | #define NR_IRQS 0 | 18 | #define NR_IRQS 0 |
| 19 | 19 | ||
| 20 | #define INTERRUPT_CAUSE_SOFTWARE 1 | ||
| 21 | #define INTERRUPT_CAUSE_TIMER 5 | ||
| 22 | #define INTERRUPT_CAUSE_EXTERNAL 9 | ||
| 23 | |||
