[PATCH 1/1] Initial commit of PLIC


Abner Chang
 

From: Abner Chang <abner.chang@...>

This is the commit for creating the patches for
widely review in Platform Spec HSC task group

Signed-off-by: Abner Chang <abner.chang@...>
---
riscv-plic.adoc | 306 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 306 insertions(+)
create mode 100644 riscv-plic.adoc

diff --git a/riscv-plic.adoc b/riscv-plic.adoc
new file mode 100644
index 0000000..b770e0e
--- /dev/null
+++ b/riscv-plic.adoc
@@ -0,0 +1,306 @@
+= *RISC-V Platform-Level Interrupt Controller Specification*
+
+== Copyright and license information
+
+This RISC-V PLIC specification is
+
+[%hardbreaks]
+(C) 2017 Drew Barbier <drew@...>
+(C) 2018-2019 Palmer Dabbelt <palmer@...>
+(C) 2019 Abner Chang, Hewlett Packard Enterprise <abner.chang@...>
+
+It is licensed under the Creative Commons Attribution 4.0 International
+License (CC-BY 4.0). The full license text is available at
+https://creativecommons.org/licenses/by/4.0/.
+
+== Introduction
+
+This document contains the RISC-V platform-level interrupt controller (PLIC)
+specification, which defines an interrupt controller specifically designed to
+work in the context of RISC-V systems. The PLIC multiplexes various device
+interrupts onto the external interrupt lines of Hart contexts, with
+hardware support for interrupt priorities. +
+This specification defines the general PLIC architecture and operation parameters.
+The PLIC which claimed as PLIC-Compliant standard PLIC should follow the
+implementations mentioned in sections below.
+
+.Figure 1 RISC-V PLIC Interrupt Architecture Block Diagram
+image::Images/PLIC.jpg[GitHub,1000,643, link=https://github.com/riscv/riscv-plic-spec/blob/master/Images/PLIC.jpg]
+
+== RISC-V PLIC Operation Parameters
+
+General PLIC operation parameter register blocks are defined in this spec, those are: +
+
+- *Interrupt Priorities registers:* +
+ The interrupt priority for each interrupt source. +
+
+- *Interrupt Pending Bits registers:* +
+ The interrupt pending status of each interrupt source. +
+
+- *Interrupt Enables registers:* +
+ The enablement of interrupt source of each context. +
+
+- *Priority Thresholds registers:* +
+ The interrupt priority threshold of each context. +
+
+- *Interrupt Claim registers:* +
+ The register to acquire interrupt source ID of each context. +
+
+- *Interrupt Completion registers:* +
+ The register to send interrupt completion message to the associated gateway. +
+
++
+
+Below is the figure of PLIC Operation Parameter Block Diagram,
+
+.Figure 2 PLIC Operation Parameter Block Diagram
+image::Images/PLICArch.jpg[GitHub, link=https://github.com/riscv/riscv-plic-spec/blob/master/Images/PLICArch.jpg]
+
+== Memory Map
+
+The `base address of PLIC Memory Map` is platform implementation-specific.
+
+*PLIC Memory Map*
+
+ base + 0x000000: Reserved (interrupt source 0 does not exist)
+ base + 0x000004: Interrupt source 1 priority
+ base + 0x000008: Interrupt source 2 priority
+ ...
+ base + 0x000FFC: Interrupt source 1023 priority
+ base + 0x001000: Interrupt Pending bit 0-31
+ base + 0x00107C: Interrupt Pending bit 992-1023
+ ...
+ base + 0x002000: Enable bits for sources 0-31 on context 0
+ base + 0x002004: Enable bits for sources 32-63 on context 0
+ ...
+ base + 0x00207F: Enable bits for sources 992-1023 on context 0
+ base + 0x002080: Enable bits for sources 0-31 on context 1
+ base + 0x002084: Enable bits for sources 32-63 on context 1
+ ...
+ base + 0x0020FF: Enable bits for sources 992-1023 on context 1
+ base + 0x002100: Enable bits for sources 0-31 on context 2
+ base + 0x002104: Enable bits for sources 32-63 on context 2
+ ...
+ base + 0x00217F: Enable bits for sources 992-1023 on context 2
+ ...
+ base + 0x1F1F80: Enable bits for sources 0-31 on context 15871
+ base + 0x1F1F84: Enable bits for sources 32-63 on context 15871
+ base + 0x1F1FFF: Enable bits for sources 992-1023 on context 15871
+ ...
+ base + 0x1FFFFC: Reserved
+ base + 0x200000: Priority threshold for context 0
+ base + 0x200004: Claim/complete for context 0
+ base + 0x200008: Reserved
+ ...
+ base + 0x200FFC: Reserved
+ base + 0x201000: Priority threshold for context 1
+ base + 0x201004: Claim/complete for context 1
+ ...
+ base + 0x3FFE000: Priority threshold for context 15871
+ base + 0x3FFE004: Claim/complete for context 15871
+ base + 0x3FFE008: Reserved
+ ...
+ base + 0x3FFFFFC: Reserved
+
+Sections below describe the control register blocks of PLIC operation parameters.
+
+== Register Width
+
+The memory map register width is in 32-bit.
+
+== Interrupt Priorities
+
+If PLIC supports Interrupt Priorities, then each PLIC interrupt source can be assigned a priority by writing to its 32-bit
+memory-mapped `priority` register. A priority value of 0 is reserved to mean ''never interrupt'' and effectively
+disables the interrupt. Priority 1 is the lowest active priority while the maximum level of priority depends on
+PLIC implementation. Ties between global interrupts of the same priority are broken by the Interrupt ID; interrupts
+with the lowest ID have the highest
+effective priority. +
+ +
+The base address of Interrupt Source Priority block within PLIC Memory Map region is fixed at 0x000000.
+
+[cols="15%,20%,20%,45%"]
+|===
+| *PLIC Register Block Name*| *Function*|*Register Block Size in Byte*| *Description*
+|Interrupt Source Priority
+|Interrupt Source Priority #0 to #1023
+|1024 * 4 = 4096(0x1000) bytes
+|This is a continuously memory block which contains PLIC Interrupt Source Priority. Total 1024 Interrupt Source Priority
+in this memory block. Interrupt Source Priority #0 is reserved which indicates it does not exist.
+|===
+
+*PLIC Interrupt Source Priority Memory Map* +
+
+ 0x000000: Reserved (interrupt source 0 does not exist)
+ 0x000004: Interrupt source 1 priority
+ 0x000008: Interrupt source 2 priority
+ ...
+ 0x000FFC: Interrupt source 1023 priority
+
+== Interrupt Pending Bits
+
+The current status of the interrupt source pending bits in the PLIC core can be
+read from the pending array, organized as 32-bit register. The pending bit
+for interrupt ID N is stored in bit (N mod 32) of word (N/32). Bit 0
+of word 0, which represents the non-existent interrupt source 0, is hardwired
+to zero.
+
+A pending bit in the PLIC core can be cleared by setting the associated enable
+bit then performing a claim. +
+ +
+The base address of Interrupt Pending Bits block within PLIC Memory Map region is fixed at 0x001000.
+
+[cols="15%,20%,20%,45%"]
+|===
+| *PLIC Register Block Name* | *Function*|*Register Block Size in Byte*| *Description*
+|Interrupt Pending Bits
+|Interrupt Pending Bit of Interrupt Source #0 to #N
+|1024 / 8 = 128(0x80) bytes
+|This is a continuously memory block contains PLIC Interrupt Pending Bits. Each Interrupt Pending Bit occupies 1-bit from this register block.
+|===
+
+*PLIC Interrupt Pending Bits Memory Map* +
+
+ 0x001000: Interrupt Source #0 to #31 Pending Bits
+ ...
+ 0x00107C: Interrupt Source #992 to #1023 Pending Bits
+
+
+== Interrupt Enables
+
+Each global interrupt can be enabled by setting the corresponding bit in the
+`enables` register. The `enables` registers are accessed as a contiguous array
+of 32-bit registers, packed the same way as the `pending` bits. Bit 0 of enable
+register 0 represents the non-existent interrupt ID 0 and is hardwired to 0.
+PLIC has 15872 Interrupt Enable blocks for the contexts. The `context` is referred
+to the specific privilege mode in the specific Hart of specific RISC-V processor
+instance. How PLIC organizes interrupts for the contexts (Hart and privilege mode)
+is out of RISC-V PLIC specification scope, however it must be spec-out in vendor's
+PLIC specification. +
+ +
+The base address of Interrupt Enable Bits block within PLIC Memory Map region is fixed at 0x002000. +
+ +
+[cols="15%,20%,20%,45%"]
+|===
+| *PLIC Register Block Name* | *Function*|*Register Block Size in Byte*| *Description*
+|Interrupt Enable Bits
+|Interrupt Enable Bit of Interrupt Source #0 to #1023 for 15872 contexts
+|(1024 / 8) * 15872 = 2031616(0x1f0000) bytes
+|This is a continuously memory block contains PLIC Interrupt Enable Bits of 15872 contexts.
+Each Interrupt Enable Bit occupies 1-bit from this register block and total 15872 Interrupt
+Enable Bit blocks
+|===
+
+*PLIC Interrupt Enable Bits Memory Map* +
+
+ 0x002000: Interrupt Source #0 to #31 Enable Bits on context 0
+ ...
+ 0x00207F: Interrupt Source #992 to #1023 Enable Bits on context 0
+ 0x002080: Interrupt Source #0 to #31 Enable Bits on context 1
+ ...
+ 0x0020FF: Interrupt Source #992 to #1023 Enable Bits on context 1
+ 0x002100: Interrupt Source #0 to #31 Enable Bits on context 2
+ ...
+ 0x00217F: Interrupt Source #992 to #1023 Enable Bits on context 2
+ 0x002180: Interrupt Source #0 to #31 Enable Bits on context 3
+ ...
+ 0x0021FF: Interrupt Source #992 to #1023 Enable Bits on context 3
+ ...
+ ...
+ ...
+ 0x1F1F80: Interrupt Source #0 to #31 on context 15871
+ ...
+ 0x1F1F80: Interrupt Source #992 to #1023 on context 15871
+
+== Priority Thresholds
+
+PLIC provides context based `threshold register` for the settings of a interrupt priority
+threshold of each context. The `threshold register` is a WARL field. The PLIC will mask all
+PLIC interrupts of a priority less than or equal to `threshold`. For example,
+a`threshold` value of zero permits all interrupts with non-zero priority. +
+ +
+The base address of Priority Thresholds register block is located at 4K alignement starts
+from offset 0x200000.
+
+[cols="15%,20%,20%,45%"]
+|===
+| *PLIC Register Block Name* | *Function*|*Register Block Size in Byte*| *Description*
+|Priority Threshold
+|Priority Threshold for 15872 contexts
+|4096 * 15872 = 65011712(0x3e00000) bytes
+|This is the register of Priority Thresholds setting for each conetxt
+|===
+
+*PLIC Interrupt Priority Thresholds Memory Map* +
+
+ 0x200000: Priority threshold for context 0
+ 0x201000: Priority threshold for context 1
+ 0x202000: Priority threshold for context 2
+ 0x203000: Priority threshold for context 3
+ ...
+ ...
+ ...
+ 0x3FFF000: Priority threshold for context 15871
+
+== Interrupt Claim Process
+
+The PLIC can perform an interrupt claim by reading the `claim/complete`
+register, which returns the ID of the highest priority pending interrupt or
+zero if there is no pending interrupt. A successful claim will also atomically
+clear the corresponding pending bit on the interrupt source. +
+The PLIC can perform a claim at any time and the claim operation is not affected
+by the setting of the priority threshold register. +
+The Interrupt Claim Process register is context based and is located at
+(4K alignement + 4) starts from offset 0x200000.
+
+[cols="15%,20%,20%,45%"]
+|===
+| *PLIC Register Block Name* | *Function*|*Register Block Size in Byte*| *Description*
+|Interrupt Claim Register
+|Interrupt Claim Process for 15872 contexts
+|4096 * 15872 = 65011712(0x3e00000) bytes
+|This is the register used to acquire interrupt ID for each conetxt
+|===
+
+*PLIC Interrupt Claim Process Memory Map* +
+
+ 0x200004: Interrupt Claim Process for context 0
+ 0x201004: Interrupt Claim Process for context 1
+ 0x202004: Interrupt Claim Process for context 2
+ 0x203004: Interrupt Claim Process for context 3
+ ...
+ ...
+ ...
+ 0x3FFF004: Interrupt Claim Process for context 15871
+
+## Interrupt Completion
+
+The PLIC signals it has completed executing an interrupt handler by writing the
+interrupt ID it received from the claim to the `claim/complete` register. The
+PLIC does not check whether the completion ID is the same as the last claim ID
+for that target. If the completion ID does not match an interrupt source that
+is currently enabled for the target, the completion is silently ignored. +
+The Interrupt Completion registers are context based and located at the same address
+with Interrupt Claim Process register, which is at (4K alignement + 4) starts from
+offset 0x200000.
+ +
+[cols="15%,20%,20%,45%"]
+|===
+| *PLIC Register Block Name* | *Registers*|*Register Block Size in Byte*| *Description*
+|Interrupt Completion Register
+|Interrupt Completion for 15872 contexts
+|4096 * 15872 = 65011712(0x3e00000) bytes
+|This is register to write to complete Interrupt process
+|===
+
+*PLIC Interrupt Completion Memory Map* +
+
+ 0x200004: Interrupt Completion for context 0
+ 0x201004: Interrupt Completion for context 1
+ 0x202004: Interrupt Completion for context 2
+ 0x203004: Interrupt Completion for context 3
+ ...
+ ...
+ ...
+ 0x3FFF004: Interrupt Completion for context 15871
+
--
2.19.0.windows.1


@guoren
 

On Sun, Jun 20, 2021 at 9:36 PM Abner Chang <renba.chang@...> wrote:

From: Abner Chang <abner.chang@...>

This is the commit for creating the patches for
widely review in Platform Spec HSC task group

Signed-off-by: Abner Chang <abner.chang@...>
---
riscv-plic.adoc | 306 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 306 insertions(+)
create mode 100644 riscv-plic.adoc

diff --git a/riscv-plic.adoc b/riscv-plic.adoc
new file mode 100644
index 0000000..b770e0e
--- /dev/null
+++ b/riscv-plic.adoc
@@ -0,0 +1,306 @@
+= *RISC-V Platform-Level Interrupt Controller Specification*
+
+== Copyright and license information
+
+This RISC-V PLIC specification is
+
+[%hardbreaks]
+(C) 2017 Drew Barbier <drew@...>
+(C) 2018-2019 Palmer Dabbelt <palmer@...>
+(C) 2019 Abner Chang, Hewlett Packard Enterprise <abner.chang@...>
+
+It is licensed under the Creative Commons Attribution 4.0 International
+License (CC-BY 4.0). The full license text is available at
+https://creativecommons.org/licenses/by/4.0/.
+
+== Introduction
+
+This document contains the RISC-V platform-level interrupt controller (PLIC)
+specification, which defines an interrupt controller specifically designed to
+work in the context of RISC-V systems. The PLIC multiplexes various device
+interrupts onto the external interrupt lines of Hart contexts, with
+hardware support for interrupt priorities. +
+This specification defines the general PLIC architecture and operation parameters.
+The PLIC which claimed as PLIC-Compliant standard PLIC should follow the
+implementations mentioned in sections below.
+
+.Figure 1 RISC-V PLIC Interrupt Architecture Block Diagram
+image::Images/PLIC.jpg[GitHub,1000,643, link=https://github.com/riscv/riscv-plic-spec/blob/master/Images/PLIC.jpg]
+
+== RISC-V PLIC Operation Parameters
+
+General PLIC operation parameter register blocks are defined in this spec, those are: +
+
+- *Interrupt Priorities registers:* +
+ The interrupt priority for each interrupt source. +
+
+- *Interrupt Pending Bits registers:* +
+ The interrupt pending status of each interrupt source. +
+
+- *Interrupt Enables registers:* +
+ The enablement of interrupt source of each context. +
+
+- *Priority Thresholds registers:* +
+ The interrupt priority threshold of each context. +
+
+- *Interrupt Claim registers:* +
+ The register to acquire interrupt source ID of each context. +
+
+- *Interrupt Completion registers:* +
+ The register to send interrupt completion message to the associated gateway. +
+
++
+
+Below is the figure of PLIC Operation Parameter Block Diagram,
+
+.Figure 2 PLIC Operation Parameter Block Diagram
+image::Images/PLICArch.jpg[GitHub, link=https://github.com/riscv/riscv-plic-spec/blob/master/Images/PLICArch.jpg]
+
+== Memory Map
+
+The `base address of PLIC Memory Map` is platform implementation-specific.
+
+*PLIC Memory Map*
+
+ base + 0x000000: Reserved (interrupt source 0 does not exist)
+ base + 0x000004: Interrupt source 1 priority
+ base + 0x000008: Interrupt source 2 priority
+ ...
+ base + 0x000FFC: Interrupt source 1023 priority
+ base + 0x001000: Interrupt Pending bit 0-31
+ base + 0x00107C: Interrupt Pending bit 992-1023
+ ...
+ base + 0x002000: Enable bits for sources 0-31 on context 0
+ base + 0x002004: Enable bits for sources 32-63 on context 0
+ ...
+ base + 0x00207F: Enable bits for sources 992-1023 on context 0
+ base + 0x002080: Enable bits for sources 0-31 on context 1
+ base + 0x002084: Enable bits for sources 32-63 on context 1
+ ...
+ base + 0x0020FF: Enable bits for sources 992-1023 on context 1
+ base + 0x002100: Enable bits for sources 0-31 on context 2
+ base + 0x002104: Enable bits for sources 32-63 on context 2
+ ...
+ base + 0x00217F: Enable bits for sources 992-1023 on context 2
+ ...
+ base + 0x1F1F80: Enable bits for sources 0-31 on context 15871
+ base + 0x1F1F84: Enable bits for sources 32-63 on context 15871
+ base + 0x1F1FFF: Enable bits for sources 992-1023 on context 15871
+ ...
+ base + 0x1FFFFC: Reserved
+ base + 0x200000: Priority threshold for context 0
+ base + 0x200004: Claim/complete for context 0
+ base + 0x200008: Reserved
+ ...
+ base + 0x200FFC: Reserved
+ base + 0x201000: Priority threshold for context 1
+ base + 0x201004: Claim/complete for context 1
+ ...
+ base + 0x3FFE000: Priority threshold for context 15871
+ base + 0x3FFE004: Claim/complete for context 15871
+ base + 0x3FFE008: Reserved
+ ...
+ base + 0x3FFFFFC: Reserved
+
+Sections below describe the control register blocks of PLIC operation parameters.
+
+== Register Width
+
+The memory map register width is in 32-bit.
+
+== Interrupt Priorities
+
+If PLIC supports Interrupt Priorities, then each PLIC interrupt source can be assigned a priority by writing to its 32-bit
+memory-mapped `priority` register. A priority value of 0 is reserved to mean ''never interrupt'' and effectively
+disables the interrupt. Priority 1 is the lowest active priority while the maximum level of priority depends on
+PLIC implementation. Ties between global interrupts of the same priority are broken by the Interrupt ID; interrupts
+with the lowest ID have the highest
+effective priority. +
+ +
+The base address of Interrupt Source Priority block within PLIC Memory Map region is fixed at 0x000000.
+
+[cols="15%,20%,20%,45%"]
+|===
+| *PLIC Register Block Name*| *Function*|*Register Block Size in Byte*| *Description*
+|Interrupt Source Priority
+|Interrupt Source Priority #0 to #1023
+|1024 * 4 = 4096(0x1000) bytes
+|This is a continuously memory block which contains PLIC Interrupt Source Priority. Total 1024 Interrupt Source Priority
+in this memory block. Interrupt Source Priority #0 is reserved which indicates it does not exist.
+|===
+
+*PLIC Interrupt Source Priority Memory Map* +
+
+ 0x000000: Reserved (interrupt source 0 does not exist)
+ 0x000004: Interrupt source 1 priority
+ 0x000008: Interrupt source 2 priority
+ ...
+ 0x000FFC: Interrupt source 1023 priority
+
+== Interrupt Pending Bits
+
+The current status of the interrupt source pending bits in the PLIC core can be
+read from the pending array, organized as 32-bit register. The pending bit
+for interrupt ID N is stored in bit (N mod 32) of word (N/32). Bit 0
+of word 0, which represents the non-existent interrupt source 0, is hardwired
+to zero.
+
+A pending bit in the PLIC core can be cleared by setting the associated enable
+bit then performing a claim. +
I suggest adding PENDING SET and PENDING CLR registers to implement a
soft plic irq mechanism, here.

PENDING SET: only '1' bits of the value would be set into reg and '0'
bits of the value would be ignored.
PENDING CLR: only '0' bits of the value would be set into reg and '1'
bits of the value would be ignored.

How?

+ +
+The base address of Interrupt Pending Bits block within PLIC Memory Map region is fixed at 0x001000.
+
+[cols="15%,20%,20%,45%"]
+|===
+| *PLIC Register Block Name* | *Function*|*Register Block Size in Byte*| *Description*
+|Interrupt Pending Bits
+|Interrupt Pending Bit of Interrupt Source #0 to #N
+|1024 / 8 = 128(0x80) bytes
+|This is a continuously memory block contains PLIC Interrupt Pending Bits. Each Interrupt Pending Bit occupies 1-bit from this register block.
+|===
+
+*PLIC Interrupt Pending Bits Memory Map* +
+
+ 0x001000: Interrupt Source #0 to #31 Pending Bits
+ ...
+ 0x00107C: Interrupt Source #992 to #1023 Pending Bits
+
+
+== Interrupt Enables
+
+Each global interrupt can be enabled by setting the corresponding bit in the
+`enables` register. The `enables` registers are accessed as a contiguous array
+of 32-bit registers, packed the same way as the `pending` bits. Bit 0 of enable
+register 0 represents the non-existent interrupt ID 0 and is hardwired to 0.
+PLIC has 15872 Interrupt Enable blocks for the contexts. The `context` is referred
+to the specific privilege mode in the specific Hart of specific RISC-V processor
+instance. How PLIC organizes interrupts for the contexts (Hart and privilege mode)
+is out of RISC-V PLIC specification scope, however it must be spec-out in vendor's
+PLIC specification. +
+ +
+The base address of Interrupt Enable Bits block within PLIC Memory Map region is fixed at 0x002000. +
+ +
+[cols="15%,20%,20%,45%"]
+|===
+| *PLIC Register Block Name* | *Function*|*Register Block Size in Byte*| *Description*
+|Interrupt Enable Bits
+|Interrupt Enable Bit of Interrupt Source #0 to #1023 for 15872 contexts
+|(1024 / 8) * 15872 = 2031616(0x1f0000) bytes
+|This is a continuously memory block contains PLIC Interrupt Enable Bits of 15872 contexts.
+Each Interrupt Enable Bit occupies 1-bit from this register block and total 15872 Interrupt
+Enable Bit blocks
+|===
+
+*PLIC Interrupt Enable Bits Memory Map* +
+
+ 0x002000: Interrupt Source #0 to #31 Enable Bits on context 0
+ ...
+ 0x00207F: Interrupt Source #992 to #1023 Enable Bits on context 0
+ 0x002080: Interrupt Source #0 to #31 Enable Bits on context 1
+ ...
+ 0x0020FF: Interrupt Source #992 to #1023 Enable Bits on context 1
+ 0x002100: Interrupt Source #0 to #31 Enable Bits on context 2
+ ...
+ 0x00217F: Interrupt Source #992 to #1023 Enable Bits on context 2
+ 0x002180: Interrupt Source #0 to #31 Enable Bits on context 3
+ ...
+ 0x0021FF: Interrupt Source #992 to #1023 Enable Bits on context 3
+ ...
+ ...
+ ...
+ 0x1F1F80: Interrupt Source #0 to #31 on context 15871
+ ...
+ 0x1F1F80: Interrupt Source #992 to #1023 on context 15871
+
+== Priority Thresholds
+
+PLIC provides context based `threshold register` for the settings of a interrupt priority
+threshold of each context. The `threshold register` is a WARL field. The PLIC will mask all
+PLIC interrupts of a priority less than or equal to `threshold`. For example,
+a`threshold` value of zero permits all interrupts with non-zero priority. +
+ +
+The base address of Priority Thresholds register block is located at 4K alignement starts
+from offset 0x200000.
+
+[cols="15%,20%,20%,45%"]
+|===
+| *PLIC Register Block Name* | *Function*|*Register Block Size in Byte*| *Description*
+|Priority Threshold
+|Priority Threshold for 15872 contexts
+|4096 * 15872 = 65011712(0x3e00000) bytes
+|This is the register of Priority Thresholds setting for each conetxt
+|===
+
+*PLIC Interrupt Priority Thresholds Memory Map* +
+
+ 0x200000: Priority threshold for context 0
+ 0x201000: Priority threshold for context 1
+ 0x202000: Priority threshold for context 2
+ 0x203000: Priority threshold for context 3
+ ...
+ ...
+ ...
+ 0x3FFF000: Priority threshold for context 15871
+
+== Interrupt Claim Process
+
+The PLIC can perform an interrupt claim by reading the `claim/complete`
+register, which returns the ID of the highest priority pending interrupt or
+zero if there is no pending interrupt. A successful claim will also atomically
+clear the corresponding pending bit on the interrupt source. +
+The PLIC can perform a claim at any time and the claim operation is not affected
+by the setting of the priority threshold register. +
+The Interrupt Claim Process register is context based and is located at
+(4K alignement + 4) starts from offset 0x200000.
+
+[cols="15%,20%,20%,45%"]
+|===
+| *PLIC Register Block Name* | *Function*|*Register Block Size in Byte*| *Description*
+|Interrupt Claim Register
+|Interrupt Claim Process for 15872 contexts
+|4096 * 15872 = 65011712(0x3e00000) bytes
+|This is the register used to acquire interrupt ID for each conetxt
+|===
+
+*PLIC Interrupt Claim Process Memory Map* +
+
+ 0x200004: Interrupt Claim Process for context 0
+ 0x201004: Interrupt Claim Process for context 1
+ 0x202004: Interrupt Claim Process for context 2
+ 0x203004: Interrupt Claim Process for context 3
+ ...
+ ...
+ ...
+ 0x3FFF004: Interrupt Claim Process for context 15871
+
+## Interrupt Completion
+
+The PLIC signals it has completed executing an interrupt handler by writing the
+interrupt ID it received from the claim to the `claim/complete` register. The
+PLIC does not check whether the completion ID is the same as the last claim ID
+for that target. If the completion ID does not match an interrupt source that
+is currently enabled for the target, the completion is silently ignored. +
+The Interrupt Completion registers are context based and located at the same address
+with Interrupt Claim Process register, which is at (4K alignement + 4) starts from
+offset 0x200000.
+ +
+[cols="15%,20%,20%,45%"]
+|===
+| *PLIC Register Block Name* | *Registers*|*Register Block Size in Byte*| *Description*
+|Interrupt Completion Register
+|Interrupt Completion for 15872 contexts
+|4096 * 15872 = 65011712(0x3e00000) bytes
+|This is register to write to complete Interrupt process
+|===
+
+*PLIC Interrupt Completion Memory Map* +
+
+ 0x200004: Interrupt Completion for context 0
+ 0x201004: Interrupt Completion for context 1
+ 0x202004: Interrupt Completion for context 2
+ 0x203004: Interrupt Completion for context 3
+ ...
+ ...
+ ...
+ 0x3FFF004: Interrupt Completion for context 15871
+
--
2.19.0.windows.1






--
Best Regards
Guo Ren

ML: https://lore.kernel.org/linux-csky/


Alistair Francis
 

On Sun, 2021-06-20 at 21:32 +0800, Abner Chang wrote:
From: Abner Chang <abner.chang@...>

This is the commit for creating the patches for
widely review in Platform Spec HSC task group

Signed-off-by: Abner Chang <abner.chang@...>
Reviewed-by: Alistair Francis <alistair.francis@...>

Alistair

---
 riscv-plic.adoc | 306 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 306 insertions(+)
 create mode 100644 riscv-plic.adoc

diff --git a/riscv-plic.adoc b/riscv-plic.adoc
new file mode 100644
index 0000000..b770e0e
--- /dev/null
+++ b/riscv-plic.adoc
@@ -0,0 +1,306 @@
+= *RISC-V Platform-Level Interrupt Controller Specification*
+
+== Copyright and license information
+
+This RISC-V PLIC specification is
+
+[%hardbreaks]
+(C) 2017 Drew Barbier <drew@...>
+(C) 2018-2019 Palmer Dabbelt <palmer@...>
+(C) 2019 Abner Chang, Hewlett Packard Enterprise <abner.chang@...>
+
+It is licensed under the Creative Commons Attribution 4.0
International
+License (CC-BY 4.0).  The full license text is available at
+https://creativecommons.org/licenses/by/4.0/.
+
+== Introduction
+
+This document contains the RISC-V platform-level interrupt controller
(PLIC)
+specification, which defines an interrupt controller specifically
designed to
+work in the context of RISC-V systems.  The PLIC multiplexes various
device
+interrupts onto the external interrupt lines of Hart contexts, with
+hardware support for interrupt priorities. +
+This specification defines the general PLIC architecture and operation
parameters.
+The PLIC which claimed as PLIC-Compliant standard PLIC should follow
the
+implementations mentioned in sections below.
+
+.Figure 1 RISC-V PLIC Interrupt Architecture Block Diagram
+image::Images/PLIC.jpg[GitHub,1000,643,
link=https://github.com/riscv/riscv-plic-spec/blob/master/Images/PLIC.jpg
]
+
+== RISC-V PLIC Operation Parameters
+
+General PLIC operation parameter register blocks are defined in this
spec, those are: +
+
+- *Interrupt Priorities registers:* +
+   The interrupt priority for each interrupt source. +
+
+- *Interrupt Pending Bits registers:* +
+   The interrupt pending status of each interrupt source. +
+  
+- *Interrupt Enables registers:* +
+   The enablement of interrupt source of each context. +
+
+- *Priority Thresholds registers:* +
+   The interrupt priority threshold of each context. +
+
+- *Interrupt Claim registers:* +
+   The register to acquire interrupt source ID of each context. +
+  
+- *Interrupt Completion registers:* +
+   The register to send interrupt completion message to the associated
gateway. +
+
++
+
+Below is the figure of PLIC Operation Parameter Block Diagram,
+
+.Figure 2 PLIC Operation Parameter Block Diagram
+image::Images/PLICArch.jpg[GitHub,
link=https://github.com/riscv/riscv-plic-spec/blob/master/Images/PLICArch.jpg
]
+
+== Memory Map
+
+The `base address of PLIC Memory Map` is platform implementation-
specific.
+
+*PLIC Memory Map*
+
+       base + 0x000000: Reserved (interrupt source 0 does not exist)
+       base + 0x000004: Interrupt source 1 priority
+       base + 0x000008: Interrupt source 2 priority
+       ...
+       base + 0x000FFC: Interrupt source 1023 priority
+       base + 0x001000: Interrupt Pending bit 0-31
+       base + 0x00107C: Interrupt Pending bit 992-1023
+       ...     
+       base + 0x002000: Enable bits for sources 0-31 on context 0
+       base + 0x002004: Enable bits for sources 32-63 on context 0
+       ...
+       base + 0x00207F: Enable bits for sources 992-1023 on context 0
+       base + 0x002080: Enable bits for sources 0-31 on context 1
+       base + 0x002084: Enable bits for sources 32-63 on context
1     
+       ...
+       base + 0x0020FF: Enable bits for sources 992-1023 on context 1
+       base + 0x002100: Enable bits for sources 0-31 on context 2
+       base + 0x002104: Enable bits for sources 32-63 on context
2     
+       ...
+       base + 0x00217F: Enable bits for sources 992-1023 on context 2
+       ...
+       base + 0x1F1F80: Enable bits for sources 0-31 on context 15871
+       base + 0x1F1F84: Enable bits for sources 32-63 on context
15871         
+       base + 0x1F1FFF: Enable bits for sources 992-1023 on context
15871
+       ...     
+       base + 0x1FFFFC: Reserved
+       base + 0x200000: Priority threshold for context 0
+       base + 0x200004: Claim/complete for context 0
+       base + 0x200008: Reserved
+       ...
+       base + 0x200FFC: Reserved
+       base + 0x201000: Priority threshold for context 1
+       base + 0x201004: Claim/complete for context 1
+       ...
+       base + 0x3FFE000: Priority threshold for context 15871
+       base + 0x3FFE004: Claim/complete for context 15871
+       base + 0x3FFE008: Reserved
+       ...     
+       base + 0x3FFFFFC: Reserved
+       
+Sections below describe the control register blocks of PLIC operation
parameters.
+
+== Register Width
+
+The memory map register width is in 32-bit.
+
+== Interrupt Priorities
+
+If PLIC supports Interrupt Priorities, then each PLIC interrupt source
can be assigned a priority by writing to its 32-bit
+memory-mapped `priority` register.  A priority value of 0 is reserved
to mean ''never interrupt'' and effectively
+disables the interrupt. Priority 1 is the lowest active priority while
the maximum level of priority depends on
+PLIC implementation. Ties between global interrupts of the same
priority are broken by the Interrupt ID; interrupts
+with the lowest ID have the highest
+effective priority. +
+ +
+The base address of Interrupt Source Priority block within PLIC Memory
Map region is fixed at 0x000000.
+
+[cols="15%,20%,20%,45%"]
+|===
+| *PLIC Register Block Name*| *Function*|*Register Block Size in
Byte*| *Description*
+|Interrupt Source Priority
+|Interrupt Source Priority #0 to #1023
+|1024 * 4 = 4096(0x1000) bytes
+|This is a continuously memory block which contains PLIC Interrupt
Source Priority. Total 1024 Interrupt Source Priority
+in this memory block. Interrupt Source Priority #0 is reserved which
indicates it does not exist.
+|===
+
+*PLIC Interrupt Source Priority Memory Map* +
+
+       0x000000: Reserved (interrupt source 0 does not exist)
+       0x000004: Interrupt source 1 priority
+       0x000008: Interrupt source 2 priority
+       ...
+       0x000FFC: Interrupt source 1023 priority
+
+== Interrupt Pending Bits
+
+The current status of the interrupt source pending bits in the PLIC
core can be
+read from the pending array, organized as 32-bit register.  The
pending bit
+for interrupt ID N is stored in bit (N mod 32) of word (N/32).  Bit 0
+of word 0, which represents the non-existent interrupt source 0, is
hardwired
+to zero.
+
+A pending bit in the PLIC core can be cleared by setting the
associated enable
+bit then performing a claim. +
+ +
+The base address of Interrupt Pending Bits block within PLIC Memory
Map region is fixed at 0x001000.
+
+[cols="15%,20%,20%,45%"]
+|===
+| *PLIC Register Block Name* | *Function*|*Register Block Size in
Byte*| *Description*
+|Interrupt Pending Bits
+|Interrupt Pending Bit of Interrupt Source #0 to #N
+|1024 / 8 = 128(0x80) bytes
+|This is a continuously memory block contains PLIC Interrupt Pending
Bits. Each Interrupt Pending Bit occupies 1-bit from this register
block.
+|===
+
+*PLIC Interrupt Pending Bits Memory Map* +
+
+       0x001000: Interrupt Source #0 to #31 Pending Bits
+       ...
+       0x00107C: Interrupt Source #992 to #1023 Pending Bits
+
+
+== Interrupt Enables
+
+Each global interrupt can be enabled by setting the corresponding bit
in the
+`enables` register. The `enables` registers are accessed as a
contiguous array
+of 32-bit registers, packed the same way as the `pending` bits. Bit 0
of enable
+register 0 represents the non-existent interrupt ID 0 and is hardwired
to 0.
+PLIC has 15872 Interrupt Enable blocks for the contexts. The `context`
is referred
+to the specific privilege mode in the specific Hart of specific RISC-V
processor
+instance. How PLIC organizes interrupts for the contexts (Hart and
privilege mode)
+is out of RISC-V PLIC specification scope, however it must be spec-out
in vendor's
+PLIC specification. +
+ +
+The base address of Interrupt Enable Bits block within PLIC Memory Map
region is fixed at 0x002000. +
+ +
+[cols="15%,20%,20%,45%"]
+|===
+| *PLIC Register Block Name* | *Function*|*Register Block Size in
Byte*| *Description*
+|Interrupt Enable Bits
+|Interrupt Enable Bit of Interrupt Source #0 to #1023 for 15872
contexts
+|(1024 / 8) * 15872 = 2031616(0x1f0000) bytes
+|This is a continuously memory block contains PLIC Interrupt Enable
Bits of 15872 contexts.
+Each Interrupt Enable Bit occupies 1-bit from this register block and
total 15872 Interrupt
+Enable Bit blocks
+|===
+
+*PLIC Interrupt Enable Bits Memory Map* +
+
+       0x002000: Interrupt Source #0 to #31 Enable Bits on context 0
+       ...
+       0x00207F: Interrupt Source #992 to #1023 Enable Bits on context
0
+       0x002080: Interrupt Source #0 to #31 Enable Bits on context 1
+       ...
+       0x0020FF: Interrupt Source #992 to #1023 Enable Bits on context
1
+       0x002100: Interrupt Source #0 to #31 Enable Bits on context 2
+       ...
+       0x00217F: Interrupt Source #992 to #1023 Enable Bits on context
2
+       0x002180: Interrupt Source #0 to #31 Enable Bits on context 3
+       ...
+       0x0021FF: Interrupt Source #992 to #1023 Enable Bits on context
3
+       ...
+       ...
+       ...
+       0x1F1F80: Interrupt Source #0 to #31 on context 15871   
+       ...     
+       0x1F1F80: Interrupt Source #992 to #1023 on context 15871
+       
+== Priority Thresholds
+
+PLIC provides context based `threshold register` for the settings of a
interrupt priority
+threshold of each context. The `threshold register` is a WARL field.
The PLIC will mask all
+PLIC interrupts of a priority less than or equal to `threshold`.  For
example,
+a`threshold` value of zero permits all interrupts with non-zero
priority. +
+ +
+The base address of Priority Thresholds register block is located at
4K alignement starts
+from offset 0x200000.
+
+[cols="15%,20%,20%,45%"]
+|===
+| *PLIC Register Block Name* | *Function*|*Register Block Size in
Byte*| *Description*
+|Priority Threshold
+|Priority Threshold for 15872 contexts
+|4096 * 15872 = 65011712(0x3e00000) bytes
+|This is the register of Priority Thresholds setting for each conetxt
+|===
+
+*PLIC Interrupt Priority Thresholds Memory Map* +
+
+       0x200000: Priority threshold for context 0
+       0x201000: Priority threshold for context 1
+       0x202000: Priority threshold for context 2
+       0x203000: Priority threshold for context 3
+       ...
+       ...
+       ...
+       0x3FFF000: Priority threshold for context 15871
+       
+== Interrupt Claim Process
+
+The PLIC can perform an interrupt claim by reading the
`claim/complete`
+register, which returns the ID of the highest priority pending
interrupt or
+zero if there is no pending interrupt.  A successful claim will also
atomically
+clear the corresponding pending bit on the interrupt source. +
+The PLIC can perform a claim at any time and the claim operation is
not affected
+by the setting of the priority threshold register. +
+The Interrupt Claim Process register is context based and is located
at
+(4K alignement + 4) starts from offset 0x200000.
+
+[cols="15%,20%,20%,45%"]
+|===
+| *PLIC Register Block Name* | *Function*|*Register Block Size in
Byte*| *Description*
+|Interrupt Claim Register
+|Interrupt Claim Process for 15872 contexts
+|4096 * 15872 = 65011712(0x3e00000) bytes
+|This is the register used to acquire interrupt ID for each conetxt
+|===
+
+*PLIC Interrupt Claim Process Memory Map* +
+
+       0x200004: Interrupt Claim Process for context 0
+       0x201004: Interrupt Claim Process for context 1
+       0x202004: Interrupt Claim Process for context 2
+       0x203004: Interrupt Claim Process for context 3
+       ...
+       ...
+       ...
+       0x3FFF004: Interrupt Claim Process for context 15871
+       
+## Interrupt Completion
+
+The PLIC signals it has completed executing an interrupt handler by
writing the
+interrupt ID it received from the claim to the `claim/complete`
register.  The
+PLIC does not check whether the completion ID is the same as the last
claim ID
+for that target.  If the completion ID does not match an interrupt
source that
+is currently enabled for the target, the completion is silently
ignored. +
+The Interrupt Completion registers are context based and located at
the same address
+with Interrupt Claim Process register, which is at (4K alignement + 4)
starts from
+offset 0x200000.
+ +
+[cols="15%,20%,20%,45%"]
+|===
+| *PLIC Register Block Name* | *Registers*|*Register Block Size in
Byte*| *Description*
+|Interrupt Completion Register
+|Interrupt Completion  for 15872 contexts
+|4096 * 15872 = 65011712(0x3e00000) bytes
+|This is register to write to complete Interrupt process
+|===
+
+*PLIC Interrupt Completion Memory Map* +
+
+       0x200004: Interrupt Completion for context 0
+       0x201004: Interrupt Completion for context 1
+       0x202004: Interrupt Completion for context 2
+       0x203004: Interrupt Completion for context 3
+       ...
+       ...
+       ...
+       0x3FFF004: Interrupt Completion for context 15871
+


atishp@...
 

On Sun, 2021-06-20 at 21:32 +0800, Abner Chang wrote:
From: Abner Chang <abner.chang@...>

This is the commit for creating the patches for
widely review in Platform Spec HSC task group

Signed-off-by: Abner Chang <abner.chang@...>
---
 riscv-plic.adoc | 306 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 306 insertions(+)
 create mode 100644 riscv-plic.adoc

diff --git a/riscv-plic.adoc b/riscv-plic.adoc
new file mode 100644
index 0000000..b770e0e
--- /dev/null
+++ b/riscv-plic.adoc
@@ -0,0 +1,306 @@
+= *RISC-V Platform-Level Interrupt Controller Specification*
+
+== Copyright and license information
+
+This RISC-V PLIC specification is
+
+[%hardbreaks]
+(C) 2017 Drew Barbier <drew@...>
+(C) 2018-2019 Palmer Dabbelt <palmer@...>
+(C) 2019 Abner Chang, Hewlett Packard Enterprise <
abner.chang@...>
+
+It is licensed under the Creative Commons Attribution 4.0
International
+License (CC-BY 4.0).  The full license text is available at
+https://creativecommons.org/licenses/by/4.0/.
+
+== Introduction
+
+This document contains the RISC-V platform-level interrupt controller
(PLIC)
+specification, which defines an interrupt controller specifically
designed to
+work in the context of RISC-V systems.  The PLIC multiplexes various
device
+interrupts onto the external interrupt lines of Hart contexts, with
+hardware support for interrupt priorities. +
+This specification defines the general PLIC architecture and operation
parameters.
+The PLIC which claimed as PLIC-Compliant standard PLIC should follow
the
+implementations mentioned in sections below.
+
+.Figure 1 RISC-V PLIC Interrupt Architecture Block Diagram
+image::Images/PLIC.jpg[GitHub,1000,643, link=
https://github.com/riscv/riscv-plic-spec/blob/master/Images/PLIC.jpg]
+
+== RISC-V PLIC Operation Parameters
+
+General PLIC operation parameter register blocks are defined in this
spec, those are: +
+
+- *Interrupt Priorities registers:* +
+   The interrupt priority for each interrupt source. +
+
+- *Interrupt Pending Bits registers:* +
+   The interrupt pending status of each interrupt source. +
+  
+- *Interrupt Enables registers:* +
+   The enablement of interrupt source of each context. +
+
+- *Priority Thresholds registers:* +
+   The interrupt priority threshold of each context. +
+
+- *Interrupt Claim registers:* +
+   The register to acquire interrupt source ID of each context. +
+  
+- *Interrupt Completion registers:* +
+   The register to send interrupt completion message to the associated
gateway. +
+
++
+
+Below is the figure of PLIC Operation Parameter Block Diagram,
+
+.Figure 2 PLIC Operation Parameter Block Diagram
+image::Images/PLICArch.jpg[GitHub, link=
https://github.com/riscv/riscv-plic-spec/blob/master/Images/PLICArch.jpg
]
+
+== Memory Map
+
+The `base address of PLIC Memory Map` is platform implementation-
specific.
+
+*PLIC Memory Map*
+
+       base + 0x000000: Reserved (interrupt source 0 does not exist)
+       base + 0x000004: Interrupt source 1 priority
+       base + 0x000008: Interrupt source 2 priority
+       ...
+       base + 0x000FFC: Interrupt source 1023 priority
+       base + 0x001000: Interrupt Pending bit 0-31
+       base + 0x00107C: Interrupt Pending bit 992-1023
+       ...     
+       base + 0x002000: Enable bits for sources 0-31 on context 0
+       base + 0x002004: Enable bits for sources 32-63 on context 0
+       ...
+       base + 0x00207F: Enable bits for sources 992-1023 on context 0
+       base + 0x002080: Enable bits for sources 0-31 on context 1
+       base + 0x002084: Enable bits for sources 32-63 on context
1     
+       ...
+       base + 0x0020FF: Enable bits for sources 992-1023 on context 1
+       base + 0x002100: Enable bits for sources 0-31 on context 2
+       base + 0x002104: Enable bits for sources 32-63 on context
2     
+       ...
+       base + 0x00217F: Enable bits for sources 992-1023 on context 2
+       ...
+       base + 0x1F1F80: Enable bits for sources 0-31 on context 15871
+       base + 0x1F1F84: Enable bits for sources 32-63 on context
15871         
+       base + 0x1F1FFF: Enable bits for sources 992-1023 on context
15871
+       ...     
+       base + 0x1FFFFC: Reserved
+       base + 0x200000: Priority threshold for context 0
+       base + 0x200004: Claim/complete for context 0
+       base + 0x200008: Reserved
+       ...
+       base + 0x200FFC: Reserved
+       base + 0x201000: Priority threshold for context 1
+       base + 0x201004: Claim/complete for context 1
+       ...
+       base + 0x3FFE000: Priority threshold for context 15871
+       base + 0x3FFE004: Claim/complete for context 15871
+       base + 0x3FFE008: Reserved
+       ...     
+       base + 0x3FFFFFC: Reserved
+       
+Sections below describe the control register blocks of PLIC operation
parameters.
+
+== Register Width
+
+The memory map register width is in 32-bit.
+
+== Interrupt Priorities
+
+If PLIC supports Interrupt Priorities, then each PLIC interrupt source
can be assigned a priority by writing to its 32-bit
+memory-mapped `priority` register.  A priority value of 0 is reserved
to mean ''never interrupt'' and effectively
+disables the interrupt. Priority 1 is the lowest active priority while
the maximum level of priority depends on
+PLIC implementation. Ties between global interrupts of the same
priority are broken by the Interrupt ID; interrupts
+with the lowest ID have the highest
+effective priority. +
+ +
+The base address of Interrupt Source Priority block within PLIC Memory
Map region is fixed at 0x000000.
+
+[cols="15%,20%,20%,45%"]
+|===
+| *PLIC Register Block Name*| *Function*|*Register Block Size in
Byte*| *Description*
+|Interrupt Source Priority
+|Interrupt Source Priority #0 to #1023
+|1024 * 4 = 4096(0x1000) bytes
+|This is a continuously memory block which contains PLIC Interrupt
Source Priority. Total 1024 Interrupt Source Priority
+in this memory block. Interrupt Source Priority #0 is reserved which
indicates it does not exist.
+|===
+
+*PLIC Interrupt Source Priority Memory Map* +
+
+       0x000000: Reserved (interrupt source 0 does not exist)
+       0x000004: Interrupt source 1 priority
+       0x000008: Interrupt source 2 priority
+       ...
+       0x000FFC: Interrupt source 1023 priority
+
+== Interrupt Pending Bits
+
+The current status of the interrupt source pending bits in the PLIC
core can be
+read from the pending array, organized as 32-bit register.  The
pending bit
+for interrupt ID N is stored in bit (N mod 32) of word (N/32).  Bit 0
+of word 0, which represents the non-existent interrupt source 0, is
hardwired
+to zero.
+
+A pending bit in the PLIC core can be cleared by setting the
associated enable
+bit then performing a claim. +
+ +
+The base address of Interrupt Pending Bits block within PLIC Memory
Map region is fixed at 0x001000.
+
+[cols="15%,20%,20%,45%"]
+|===
+| *PLIC Register Block Name* | *Function*|*Register Block Size in
Byte*| *Description*
+|Interrupt Pending Bits
+|Interrupt Pending Bit of Interrupt Source #0 to #N
+|1024 / 8 = 128(0x80) bytes
+|This is a continuously memory block contains PLIC Interrupt Pending
Bits. Each Interrupt Pending Bit occupies 1-bit from this register
block.
+|===
+
+*PLIC Interrupt Pending Bits Memory Map* +
+
+       0x001000: Interrupt Source #0 to #31 Pending Bits
+       ...
+       0x00107C: Interrupt Source #992 to #1023 Pending Bits
+
+
+== Interrupt Enables
+
+Each global interrupt can be enabled by setting the corresponding bit
in the
+`enables` register. The `enables` registers are accessed as a
contiguous array
+of 32-bit registers, packed the same way as the `pending` bits. Bit 0
of enable
+register 0 represents the non-existent interrupt ID 0 and is hardwired
to 0.
+PLIC has 15872 Interrupt Enable blocks for the contexts. The `context`
is referred
+to the specific privilege mode in the specific Hart of specific RISC-V
processor
+instance. How PLIC organizes interrupts for the contexts (Hart and
privilege mode)
+is out of RISC-V PLIC specification scope, however it must be spec-out
in vendor's
+PLIC specification. +
+ +
+The base address of Interrupt Enable Bits block within PLIC Memory Map
region is fixed at 0x002000. +
+ +
+[cols="15%,20%,20%,45%"]
+|===
+| *PLIC Register Block Name* | *Function*|*Register Block Size in
Byte*| *Description*
+|Interrupt Enable Bits
+|Interrupt Enable Bit of Interrupt Source #0 to #1023 for 15872
contexts
+|(1024 / 8) * 15872 = 2031616(0x1f0000) bytes
+|This is a continuously memory block contains PLIC Interrupt Enable
Bits of 15872 contexts.
+Each Interrupt Enable Bit occupies 1-bit from this register block and
total 15872 Interrupt
+Enable Bit blocks
+|===
+
+*PLIC Interrupt Enable Bits Memory Map* +
+
+       0x002000: Interrupt Source #0 to #31 Enable Bits on context 0
+       ...
+       0x00207F: Interrupt Source #992 to #1023 Enable Bits on context
0
+       0x002080: Interrupt Source #0 to #31 Enable Bits on context 1
+       ...
+       0x0020FF: Interrupt Source #992 to #1023 Enable Bits on context
1
+       0x002100: Interrupt Source #0 to #31 Enable Bits on context 2
+       ...
+       0x00217F: Interrupt Source #992 to #1023 Enable Bits on context
2
+       0x002180: Interrupt Source #0 to #31 Enable Bits on context 3
+       ...
+       0x0021FF: Interrupt Source #992 to #1023 Enable Bits on context
3
+       ...
+       ...
+       ...
+       0x1F1F80: Interrupt Source #0 to #31 on context 15871   
+       ...     
+       0x1F1F80: Interrupt Source #992 to #1023 on context 15871
+       
+== Priority Thresholds
+
+PLIC provides context based `threshold register` for the settings of a
interrupt priority
+threshold of each context. The `threshold register` is a WARL field.
The PLIC will mask all
+PLIC interrupts of a priority less than or equal to `threshold`.  For
example,
+a`threshold` value of zero permits all interrupts with non-zero
priority. +
+ +
+The base address of Priority Thresholds register block is located at
4K alignement starts
+from offset 0x200000.
+
+[cols="15%,20%,20%,45%"]
+|===
+| *PLIC Register Block Name* | *Function*|*Register Block Size in
Byte*| *Description*
+|Priority Threshold
+|Priority Threshold for 15872 contexts
+|4096 * 15872 = 65011712(0x3e00000) bytes
+|This is the register of Priority Thresholds setting for each conetxt
+|===
+
+*PLIC Interrupt Priority Thresholds Memory Map* +
+
+       0x200000: Priority threshold for context 0
+       0x201000: Priority threshold for context 1
+       0x202000: Priority threshold for context 2
+       0x203000: Priority threshold for context 3
+       ...
+       ...
+       ...
+       0x3FFF000: Priority threshold for context 15871
+       
+== Interrupt Claim Process
+
+The PLIC can perform an interrupt claim by reading the
`claim/complete`
+register, which returns the ID of the highest priority pending
interrupt or
+zero if there is no pending interrupt.  A successful claim will also
atomically
+clear the corresponding pending bit on the interrupt source. +
+The PLIC can perform a claim at any time and the claim operation is
not affected
+by the setting of the priority threshold register. +
+The Interrupt Claim Process register is context based and is located
at
+(4K alignement + 4) starts from offset 0x200000.
+
+[cols="15%,20%,20%,45%"]
+|===
+| *PLIC Register Block Name* | *Function*|*Register Block Size in
Byte*| *Description*
+|Interrupt Claim Register
+|Interrupt Claim Process for 15872 contexts
+|4096 * 15872 = 65011712(0x3e00000) bytes
+|This is the register used to acquire interrupt ID for each conetxt
+|===
+
+*PLIC Interrupt Claim Process Memory Map* +
+
+       0x200004: Interrupt Claim Process for context 0
+       0x201004: Interrupt Claim Process for context 1
+       0x202004: Interrupt Claim Process for context 2
+       0x203004: Interrupt Claim Process for context 3
+       ...
+       ...
+       ...
+       0x3FFF004: Interrupt Claim Process for context 15871
+       
+## Interrupt Completion
+
+The PLIC signals it has completed executing an interrupt handler by
writing the
+interrupt ID it received from the claim to the `claim/complete`
register.  The
+PLIC does not check whether the completion ID is the same as the last
claim ID
+for that target.  If the completion ID does not match an interrupt
source that
+is currently enabled for the target, the completion is silently
ignored. +
+The Interrupt Completion registers are context based and located at
the same address
+with Interrupt Claim Process register, which is at (4K alignement + 4)
starts from
+offset 0x200000.
+ +
+[cols="15%,20%,20%,45%"]
+|===
+| *PLIC Register Block Name* | *Registers*|*Register Block Size in
Byte*| *Description*
+|Interrupt Completion Register
+|Interrupt Completion  for 15872 contexts
+|4096 * 15872 = 65011712(0x3e00000) bytes
+|This is register to write to complete Interrupt process
+|===
+
+*PLIC Interrupt Completion Memory Map* +
+
+       0x200004: Interrupt Completion for context 0
+       0x201004: Interrupt Completion for context 1
+       0x202004: Interrupt Completion for context 2
+       0x203004: Interrupt Completion for context 3
+       ...
+       ...
+       ...
+       0x3FFF004: Interrupt Completion for context 15871
+
I think it will be good to provide additional clarification in the
beginning about the number of interrupts/contexts. Something along the
lines:

The PLIC specification supports up-to 1024 interrupts and 15872
contexts. But the actual number of interrupts and context depends on
the PLIC implementation. However, the implement must adhere to the
offset of each register within the PLIC block.

Apart from that, LGTM.
Reviewed-by: Atish Patra <atish.patra@...>

--
Regards,
Atish


Abner Chang
 


Atish Patra <Atish.Patra@...> 於 2021年7月2日 週五 上午2:40寫道:
On Sun, 2021-06-20 at 21:32 +0800, Abner Chang wrote:
> From: Abner Chang <abner.chang@...>
>
> This is the commit for creating the patches for
> widely review in Platform Spec HSC task group
>
> Signed-off-by: Abner Chang <abner.chang@...>
> ---
>  riscv-plic.adoc | 306 ++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 306 insertions(+)
>  create mode 100644 riscv-plic.adoc
>
> diff --git a/riscv-plic.adoc b/riscv-plic.adoc
> new file mode 100644
> index 0000000..b770e0e
> --- /dev/null
> +++ b/riscv-plic.adoc
> @@ -0,0 +1,306 @@
> += *RISC-V Platform-Level Interrupt Controller Specification*
> +
> +== Copyright and license information
> +
> +This RISC-V PLIC specification is
> +
> +[%hardbreaks]
> +(C) 2017 Drew Barbier <drew@...>
> +(C) 2018-2019 Palmer Dabbelt <palmer@...>
> +(C) 2019 Abner Chang, Hewlett Packard Enterprise <
> abner.chang@...>
> +
> +It is licensed under the Creative Commons Attribution 4.0
> International
> +License (CC-BY 4.0).  The full license text is available at
> +https://creativecommons.org/licenses/by/4.0/.
> +
> +== Introduction
> +
> +This document contains the RISC-V platform-level interrupt controller
> (PLIC)
> +specification, which defines an interrupt controller specifically
> designed to
> +work in the context of RISC-V systems.  The PLIC multiplexes various
> device
> +interrupts onto the external interrupt lines of Hart contexts, with
> +hardware support for interrupt priorities. +
> +This specification defines the general PLIC architecture and operation
> parameters.
> +The PLIC which claimed as PLIC-Compliant standard PLIC should follow
> the
> +implementations mentioned in sections below.
> +
> +.Figure 1 RISC-V PLIC Interrupt Architecture Block Diagram
> +image::Images/PLIC.jpg[GitHub,1000,643, link=
> https://github.com/riscv/riscv-plic-spec/blob/master/Images/PLIC.jpg]
> +
> +== RISC-V PLIC Operation Parameters
> +
> +General PLIC operation parameter register blocks are defined in this
> spec, those are: +
> +
> +- *Interrupt Priorities registers:* +
> +   The interrupt priority for each interrupt source. +
> +
> +- *Interrupt Pending Bits registers:* +
> +   The interrupt pending status of each interrupt source. +
> +  
> +- *Interrupt Enables registers:* +
> +   The enablement of interrupt source of each context. +
> +
> +- *Priority Thresholds registers:* +
> +   The interrupt priority threshold of each context. +
> +
> +- *Interrupt Claim registers:* +
> +   The register to acquire interrupt source ID of each context. +
> +  
> +- *Interrupt Completion registers:* +
> +   The register to send interrupt completion message to the associated
> gateway. +
> +
> ++
> +
> +Below is the figure of PLIC Operation Parameter Block Diagram,
> +
> +.Figure 2 PLIC Operation Parameter Block Diagram
> +image::Images/PLICArch.jpg[GitHub, link=
> https://github.com/riscv/riscv-plic-spec/blob/master/Images/PLICArch.jpg
> ]
> +
> +== Memory Map
> +
> +The `base address of PLIC Memory Map` is platform implementation-
> specific.
> +
> +*PLIC Memory Map*
> +
> +       base + 0x000000: Reserved (interrupt source 0 does not exist)
> +       base + 0x000004: Interrupt source 1 priority
> +       base + 0x000008: Interrupt source 2 priority
> +       ...
> +       base + 0x000FFC: Interrupt source 1023 priority
> +       base + 0x001000: Interrupt Pending bit 0-31
> +       base + 0x00107C: Interrupt Pending bit 992-1023
> +       ...     
> +       base + 0x002000: Enable bits for sources 0-31 on context 0
> +       base + 0x002004: Enable bits for sources 32-63 on context 0
> +       ...
> +       base + 0x00207F: Enable bits for sources 992-1023 on context 0
> +       base + 0x002080: Enable bits for sources 0-31 on context 1
> +       base + 0x002084: Enable bits for sources 32-63 on context
> 1     
> +       ...
> +       base + 0x0020FF: Enable bits for sources 992-1023 on context 1
> +       base + 0x002100: Enable bits for sources 0-31 on context 2
> +       base + 0x002104: Enable bits for sources 32-63 on context
> 2     
> +       ...
> +       base + 0x00217F: Enable bits for sources 992-1023 on context 2
> +       ...
> +       base + 0x1F1F80: Enable bits for sources 0-31 on context 15871
> +       base + 0x1F1F84: Enable bits for sources 32-63 on context
> 15871         
> +       base + 0x1F1FFF: Enable bits for sources 992-1023 on context
> 15871
> +       ...     
> +       base + 0x1FFFFC: Reserved
> +       base + 0x200000: Priority threshold for context 0
> +       base + 0x200004: Claim/complete for context 0
> +       base + 0x200008: Reserved
> +       ...
> +       base + 0x200FFC: Reserved
> +       base + 0x201000: Priority threshold for context 1
> +       base + 0x201004: Claim/complete for context 1
> +       ...
> +       base + 0x3FFE000: Priority threshold for context 15871
> +       base + 0x3FFE004: Claim/complete for context 15871
> +       base + 0x3FFE008: Reserved
> +       ...     
> +       base + 0x3FFFFFC: Reserved
> +       
> +Sections below describe the control register blocks of PLIC operation
> parameters.
> +
> +== Register Width
> +
> +The memory map register width is in 32-bit.
> +
> +== Interrupt Priorities
> +
> +If PLIC supports Interrupt Priorities, then each PLIC interrupt source
> can be assigned a priority by writing to its 32-bit
> +memory-mapped `priority` register.  A priority value of 0 is reserved
> to mean ''never interrupt'' and effectively
> +disables the interrupt. Priority 1 is the lowest active priority while
> the maximum level of priority depends on
> +PLIC implementation. Ties between global interrupts of the same
> priority are broken by the Interrupt ID; interrupts
> +with the lowest ID have the highest
> +effective priority. +
> + +
> +The base address of Interrupt Source Priority block within PLIC Memory
> Map region is fixed at 0x000000.
> +
> +[cols="15%,20%,20%,45%"]
> +|===
> +| *PLIC Register Block Name*| *Function*|*Register Block Size in
> Byte*| *Description*
> +|Interrupt Source Priority
> +|Interrupt Source Priority #0 to #1023
> +|1024 * 4 = 4096(0x1000) bytes
> +|This is a continuously memory block which contains PLIC Interrupt
> Source Priority. Total 1024 Interrupt Source Priority
> +in this memory block. Interrupt Source Priority #0 is reserved which
> indicates it does not exist.
> +|===
> +
> +*PLIC Interrupt Source Priority Memory Map* +
> +
> +       0x000000: Reserved (interrupt source 0 does not exist)
> +       0x000004: Interrupt source 1 priority
> +       0x000008: Interrupt source 2 priority
> +       ...
> +       0x000FFC: Interrupt source 1023 priority
> +
> +== Interrupt Pending Bits
> +
> +The current status of the interrupt source pending bits in the PLIC
> core can be
> +read from the pending array, organized as 32-bit register.  The
> pending bit
> +for interrupt ID N is stored in bit (N mod 32) of word (N/32).  Bit 0
> +of word 0, which represents the non-existent interrupt source 0, is
> hardwired
> +to zero.
> +
> +A pending bit in the PLIC core can be cleared by setting the
> associated enable
> +bit then performing a claim. +
> + +
> +The base address of Interrupt Pending Bits block within PLIC Memory
> Map region is fixed at 0x001000.
> +
> +[cols="15%,20%,20%,45%"]
> +|===
> +| *PLIC Register Block Name* | *Function*|*Register Block Size in
> Byte*| *Description*
> +|Interrupt Pending Bits
> +|Interrupt Pending Bit of Interrupt Source #0 to #N
> +|1024 / 8 = 128(0x80) bytes
> +|This is a continuously memory block contains PLIC Interrupt Pending
> Bits. Each Interrupt Pending Bit occupies 1-bit from this register
> block.
> +|===
> +
> +*PLIC Interrupt Pending Bits Memory Map* +
> +
> +       0x001000: Interrupt Source #0 to #31 Pending Bits
> +       ...
> +       0x00107C: Interrupt Source #992 to #1023 Pending Bits
> +
> +
> +== Interrupt Enables
> +
> +Each global interrupt can be enabled by setting the corresponding bit
> in the
> +`enables` register. The `enables` registers are accessed as a
> contiguous array
> +of 32-bit registers, packed the same way as the `pending` bits. Bit 0
> of enable
> +register 0 represents the non-existent interrupt ID 0 and is hardwired
> to 0.
> +PLIC has 15872 Interrupt Enable blocks for the contexts. The `context`
> is referred
> +to the specific privilege mode in the specific Hart of specific RISC-V
> processor
> +instance. How PLIC organizes interrupts for the contexts (Hart and
> privilege mode)
> +is out of RISC-V PLIC specification scope, however it must be spec-out
> in vendor's
> +PLIC specification. +
> + +
> +The base address of Interrupt Enable Bits block within PLIC Memory Map
> region is fixed at 0x002000. +
> + +
> +[cols="15%,20%,20%,45%"]
> +|===
> +| *PLIC Register Block Name* | *Function*|*Register Block Size in
> Byte*| *Description*
> +|Interrupt Enable Bits
> +|Interrupt Enable Bit of Interrupt Source #0 to #1023 for 15872
> contexts
> +|(1024 / 8) * 15872 = 2031616(0x1f0000) bytes
> +|This is a continuously memory block contains PLIC Interrupt Enable
> Bits of 15872 contexts.
> +Each Interrupt Enable Bit occupies 1-bit from this register block and
> total 15872 Interrupt
> +Enable Bit blocks
> +|===
> +
> +*PLIC Interrupt Enable Bits Memory Map* +
> +
> +       0x002000: Interrupt Source #0 to #31 Enable Bits on context 0
> +       ...
> +       0x00207F: Interrupt Source #992 to #1023 Enable Bits on context
> 0
> +       0x002080: Interrupt Source #0 to #31 Enable Bits on context 1
> +       ...
> +       0x0020FF: Interrupt Source #992 to #1023 Enable Bits on context
> 1
> +       0x002100: Interrupt Source #0 to #31 Enable Bits on context 2
> +       ...
> +       0x00217F: Interrupt Source #992 to #1023 Enable Bits on context
> 2
> +       0x002180: Interrupt Source #0 to #31 Enable Bits on context 3
> +       ...
> +       0x0021FF: Interrupt Source #992 to #1023 Enable Bits on context
> 3
> +       ...
> +       ...
> +       ...
> +       0x1F1F80: Interrupt Source #0 to #31 on context 15871   
> +       ...     
> +       0x1F1F80: Interrupt Source #992 to #1023 on context 15871
> +       
> +== Priority Thresholds
> +
> +PLIC provides context based `threshold register` for the settings of a
> interrupt priority
> +threshold of each context. The `threshold register` is a WARL field.
> The PLIC will mask all
> +PLIC interrupts of a priority less than or equal to `threshold`.  For
> example,
> +a`threshold` value of zero permits all interrupts with non-zero
> priority. +
> + +
> +The base address of Priority Thresholds register block is located at
> 4K alignement starts
> +from offset 0x200000.
> +
> +[cols="15%,20%,20%,45%"]
> +|===
> +| *PLIC Register Block Name* | *Function*|*Register Block Size in
> Byte*| *Description*
> +|Priority Threshold
> +|Priority Threshold for 15872 contexts
> +|4096 * 15872 = 65011712(0x3e00000) bytes
> +|This is the register of Priority Thresholds setting for each conetxt
> +|===
> +
> +*PLIC Interrupt Priority Thresholds Memory Map* +
> +
> +       0x200000: Priority threshold for context 0
> +       0x201000: Priority threshold for context 1
> +       0x202000: Priority threshold for context 2
> +       0x203000: Priority threshold for context 3
> +       ...
> +       ...
> +       ...
> +       0x3FFF000: Priority threshold for context 15871
> +       
> +== Interrupt Claim Process
> +
> +The PLIC can perform an interrupt claim by reading the
> `claim/complete`
> +register, which returns the ID of the highest priority pending
> interrupt or
> +zero if there is no pending interrupt.  A successful claim will also
> atomically
> +clear the corresponding pending bit on the interrupt source. +
> +The PLIC can perform a claim at any time and the claim operation is
> not affected
> +by the setting of the priority threshold register. +
> +The Interrupt Claim Process register is context based and is located
> at
> +(4K alignement + 4) starts from offset 0x200000.
> +
> +[cols="15%,20%,20%,45%"]
> +|===
> +| *PLIC Register Block Name* | *Function*|*Register Block Size in
> Byte*| *Description*
> +|Interrupt Claim Register
> +|Interrupt Claim Process for 15872 contexts
> +|4096 * 15872 = 65011712(0x3e00000) bytes
> +|This is the register used to acquire interrupt ID for each conetxt
> +|===
> +
> +*PLIC Interrupt Claim Process Memory Map* +
> +
> +       0x200004: Interrupt Claim Process for context 0
> +       0x201004: Interrupt Claim Process for context 1
> +       0x202004: Interrupt Claim Process for context 2
> +       0x203004: Interrupt Claim Process for context 3
> +       ...
> +       ...
> +       ...
> +       0x3FFF004: Interrupt Claim Process for context 15871
> +       
> +## Interrupt Completion
> +
> +The PLIC signals it has completed executing an interrupt handler by
> writing the
> +interrupt ID it received from the claim to the `claim/complete`
> register.  The
> +PLIC does not check whether the completion ID is the same as the last
> claim ID
> +for that target.  If the completion ID does not match an interrupt
> source that
> +is currently enabled for the target, the completion is silently
> ignored. +
> +The Interrupt Completion registers are context based and located at
> the same address
> +with Interrupt Claim Process register, which is at (4K alignement + 4)
> starts from
> +offset 0x200000.
> + +
> +[cols="15%,20%,20%,45%"]
> +|===
> +| *PLIC Register Block Name* | *Registers*|*Register Block Size in
> Byte*| *Description*
> +|Interrupt Completion Register
> +|Interrupt Completion  for 15872 contexts
> +|4096 * 15872 = 65011712(0x3e00000) bytes
> +|This is register to write to complete Interrupt process
> +|===
> +
> +*PLIC Interrupt Completion Memory Map* +
> +
> +       0x200004: Interrupt Completion for context 0
> +       0x201004: Interrupt Completion for context 1
> +       0x202004: Interrupt Completion for context 2
> +       0x203004: Interrupt Completion for context 3
> +       ...
> +       ...
> +       ...
> +       0x3FFF004: Interrupt Completion for context 15871
> +

I think it will be good to provide additional clarification in the
beginning about the number of interrupts/contexts. Something along the
lines:

The PLIC specification supports up-to 1024 interrupts and 15872
contexts. But the actual number of interrupts and context depends on
the PLIC implementation. However, the implement must adhere to the
offset of each register within the PLIC block.

Added to spec. 

Apart from that, LGTM.
Reviewed-by: Atish Patra <atish.patra@...>

Merged to riscv-plic-spec with Atish and Alistair's Reviewed-by.
Abner

--
Regards,
Atish