aboutsummaryrefslogtreecommitdiff
path: root/src/plic.tex
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2017-02-01 20:41:47 -0800
committerAndrew Waterman <andrew@sifive.com>2017-02-01 20:41:47 -0800
commitab6f8c9bd7bc85361fcf35667d1fddfaf367a53f (patch)
tree716a2118ca0565dbb4e7903723f283ae4dd13c46 /src/plic.tex
parent207a7c6ee51aa2fd74d4618cd1369ddc21706b9e (diff)
downloadriscv-isa-manual-ab6f8c9bd7bc85361fcf35667d1fddfaf367a53f.zip
riscv-isa-manual-ab6f8c9bd7bc85361fcf35667d1fddfaf367a53f.tar.gz
riscv-isa-manual-ab6f8c9bd7bc85361fcf35667d1fddfaf367a53f.tar.bz2
Reorganize directory structure
Diffstat (limited to 'src/plic.tex')
-rw-r--r--src/plic.tex427
1 files changed, 427 insertions, 0 deletions
diff --git a/src/plic.tex b/src/plic.tex
new file mode 100644
index 0000000..798b139
--- /dev/null
+++ b/src/plic.tex
@@ -0,0 +1,427 @@
+\chapter{Platform-Level Interrupt Controller (PLIC)}
+\label{plic}
+
+This chapter describes the general architecture for the RISC-V
+platform-level interrupt controller (PLIC), which prioritizes and
+distributes global interrupts in a RISC-V system.
+
+\section{PLIC Overview}
+
+Figure~\ref{fig:plic} provides a quick overview of PLIC operation.
+The PLIC connects global {\em interrupt sources}, which are usually
+I/O devices, to {\em interrupt targets}, which are usually {\em hart
+ contexts}. The PLIC contains multiple {\em interrupt gateways}, one
+per interrupt source, together with a {\em PLIC core} that performs
+interrupt prioritization and routing. Global interrupts are sent from
+their source to an {\em interrupt gateway} that processes the
+interrupt signal from each source and sends a single {\em interrupt
+ request} to the PLIC core, which latches these in the core interrupt
+pending bits (IP). Each interrupt source is assigned a separate
+priority. The PLIC core contains a matrix of interrupt enable (IE)
+bits to select the interrupts that are enabled for each target. The
+PLIC core forwards an {\em interrupt notification} to one or more
+targets if the targets have any pending interrupts enabled, and the
+priority of the pending interrupts exceeds a per-target threshold.
+When the target takes the external interrupt, it sends an {\em
+ interrupt claim} request to retrieve the identifier of the
+highest-priority global interrupt source pending for that target from
+the PLIC core, which then clears the corresponding interrupt source
+pending bit. After the target has serviced the interrupt, it sends
+the associated interrupt gateway an {\em interrupt completion} message
+and the interrupt gateway can now forward another interrupt request
+for the same source to the PLIC. The rest of this chapter describes
+each of these components in detail, though many details are
+necessarily platform specific.
+
+\begin{figure}[tb]
+\centering
+\includegraphics[width=\textwidth]{figs/PLIC-block-diagram.pdf}
+\caption{Platform-Level Interrupt Controller (PLIC) conceptual block
+ diagram. The figure shows the first two of potentially many
+ interrupt sources, and the first two of potentially many interrupt
+ targets. The figure is just intended to show the logic of the
+ PLIC's operation, not to represent a realistic implementation
+ strategy.}
+\label{fig:plic}
+\end{figure}
+
+\section{Interrupt Sources}
+
+RISC-V harts can have both local and global interrupt sources. Only
+global interrupt sources are handled by the PLIC.
+
+\subsection{Local Interrupt Sources}
+
+Each hart has a number of {\em local interrupt sources} that do not
+pass through the PLIC, including the standard software interrupts and
+timer interrupts for each privilege level. Local interrupts can be
+serviced quickly since there will be minimal latency between the
+source and the servicing hart, no arbitration is required to determine
+which hart will service the request, and the servicing hart can
+quickly determine the interrupt source using the {\tt mcause}
+register.
+
+All local interrupts follow a level-based model, where an interrupt is
+pending if the corresponding bit in {\tt mip} is set. The interrupt
+handler must clear the hardware condition that is causing the {\tt
+ mip} bit to be set to avoid retaking the interrupt after re-enabling
+interrupts on exit from the interrupt handler.
+
+Additional non-standard local interrupt sources can be made visible to
+machine-mode by adding them to the high bits of the {\tt mip}/{\tt
+ mie} registers, with corresponding additional cause values returned
+in the {\tt mcause} register. These additional non-standard local
+interrupts may also be made visible to lower privilege levels, using
+the corresponding bits in the {\tt mideleg} register. The priority of
+non-standard local interrupt sources relative to external, timer, and
+software interrupts is platform-specific.
+
+\subsection{Global Interrupt Sources}
+
+{\em Global interrupt sources} are those that are prioritized and
+distributed by the PLIC. Depending on the platform-specific PLIC
+implementation, any global interrupt source could be routed to any
+hart context.
+
+Global interrupt sources can take many forms, including
+level-triggered, edge-triggered, and message-signalled. Some sources
+might queue up a number of interrupt requests. All global interrupt
+sources are converted to a common interrupt request format for the
+PLIC.
+
+\section{Interrupt Targets and Hart Contexts}
+
+Interrupt targets are usually hart contexts, where a hart context is a
+given privilege mode on a given hart (though there are other possible
+interrupt targets, such as DMA engines). Not all hart contexts need
+be interrupt targets, in particular, if a processor core does not
+support delegating external interrupts to lower-privilege modes, then
+the lower-privilege hart contexts will not be interrupt targets.
+Interrupt notifications generated by the PLIC appear in the {\tt
+ meip}/{\tt heip}/{\tt seip}/{\tt ueip} bits of the {\tt mip}/{\tt
+ hip}/{\tt sip}/{\tt uip} registers for M/H/S/U modes respectively.
+The notifications only appear in lower-privilege {\em x}{\tt ip}
+registers if external interrupts have been delegated to the
+lower-privilege modes.
+
+Each processor core must define a policy on how simultaneous active
+interrupts are taken by multiple hart contexts on the core. For the
+simple case of a single stack of hart contexts, one for each supported
+privileged mode, interrupts for higher-privilege contexts can preempt
+execution of interrupt handlers for lower-privilege contexts. A
+multithreaded processor core could run multiple independent interrupt
+handlers on different hart contexts at the same time. A processor
+core could also provide hart contexts that are only used for interrupt
+handling to reduce interrupt service latency, and these might preempt
+interrupt handlers for other harts on the same core.
+
+The PLIC treats each interrupt target independently and does not take
+into account any interrupt prioritization scheme used by a component
+that contains multiple interrupt targets. As a result, the PLIC
+provides no concept of interrupt preemption or nesting so this must be
+handled by the cores hosting multiple interrupt target contexts.
+
+\section{Interrupt Gateways}
+
+The interrupt gateways are responsible for converting global interrupt
+signals into a common interrupt request format, and for controlling
+the flow of interrupt requests to the PLIC core. At most one
+interrupt request per interrupt source can be pending in the PLIC core
+at any time, indicated by setting the source's IP bit. The gateway
+only forwards a new interrupt request to the PLIC core after receiving
+notification that the interrupt handler servicing the previous
+interrupt request from the same source has completed.
+
+If the global interrupt source uses level-sensitive interrupts, the
+gateway will convert the first assertion of the interrupt level into
+an interrupt request, but thereafter the gateway will not forward an
+additional interrupt request until it receives an interrupt completion
+message. On receiving an interrupt completion message, if the
+interrupt is level-triggered and the interrupt is still asserted, a
+new interrupt request will be forwarded to the PLIC core. The gateway
+does not have the facility to retract an interrupt request once
+forwarded to the PLIC core. If a level-sensitive interrupt source
+deasserts the interrupt after the PLIC core accepts the request and
+before the interrupt is serviced, the interrupt request remains
+present in the IP bit of the PLIC core and will be serviced by a
+handler, which will then have to determine that the interrupt device
+no longer requires service.
+
+If the global interrupt source was edge-triggered, the gateway will
+convert the first matching signal edge into an interrupt request.
+Depending on the design of the device and the interrupt handler,
+inbetween sending an interrupt request and receiving notice of its
+handler's completion, the gateway might either ignore additional
+matching edges or increment a counter of pending interrupts. In
+either case, the next interrupt request will not be forwarded to the
+PLIC core until the previous completion message has been received. If
+the gateway has a pending interrupt counter, the counter will be
+decremented when the interrupt request is accepted by the PLIC core.
+
+Unlike dedicated-wire interrupt signals, message-signalled interrupts
+(MSIs) are sent over the system interconnect via a message packet that
+describes which interrupt is being asserted. The message is decoded
+to select an interrupt gateway, and the relevant gateway then handles
+the MSI similar to an edge-triggered interrupt.
+
+\section{Interrupt Identifiers (IDs)}
+
+Global interrupt sources are assigned small unsigned integer
+identifiers, beginning at the value 1. An interrupt ID of 0 is
+reserved to mean ``no interrupt''.
+
+Interrupt identifiers are also used to break ties when two or more
+interrupt sources have the same assigned priority. Smaller values of
+interrupt ID take precedence over larger values of interrupt ID.
+
+\section{Interrupt Priorities}
+
+Interrupt priorities are small unsigned integers, with a
+platform-specific maximum number of supported levels. The priority
+value 0 is reserved to mean ``never interrupt'', and interrupt
+priority increases with increasing integer values.
+
+Each global interrupt source has an associated interrupt priority held
+in a platform-specific memory-mapped register. Different interrupt
+sources need not support the same set of priority values. A valid
+implementation can hardwire all input priority levels. Interrupt
+source priority registers should be \warl\ fields to allow software to
+determine the number and position of read-write bits in each priority
+specification, if any. To simplify discovery of supported priority
+values, each priority register must support any combination of values
+in the bits that are variable within the register, i.e., if there are
+two variable bits in the register, all four combinations of values in
+those bits must operate as valid priority levels.
+
+\begin{commentary}
+ In the degenerate case, all priorities can be hardwired to the value
+ 1, in which case input priorities are effectively determined by
+ interrupt ID.
+
+ The supported priority values can be determined as follows: 1) write
+ all zeros to the priority register then 2) read back the value. Any
+ set bits are hardwired to 1. Next, 3) write all ones to the
+ register, and 4) read back the value. Any clear bits are hardwired
+ to 0. Any set bits that were not found to be hardwired in step 2 are
+ variable. The supported priority levels are the set of values
+ obtained by substituting all combinations of ones and zeros in the
+ variable bits within the priority field.
+\end{commentary}
+
+\section{Interrupt Enables}
+
+Each target has a vector of interrupt enable (IE) bits, one per
+interrupt source. The target will not receive interrupts from sources
+that are disabled. The IE bits for a single target should be packed
+together as a bit vector in platform-specific memory-mapped control
+registers to support rapid context switching of the IE bits for a
+target. IE bits are \warl\ fields that can be hardwired to either 0
+or 1.
+
+\begin{commentary}
+A large number of potential IE bits might be hardwired to zero in
+cases where some interrupt sources can only be routed to
+a subset of targets.
+
+A larger number of bits might be wired to 1 for an embedded device
+with fixed interrupt routing. Interrupt priorities, thresholds, and
+hart-internal interrupt masking provide considerable flexibility in
+ignoring external interrupts even if a global interrupt source is
+always enabled.
+\end{commentary}
+
+\section{Interrupt Priority Thresholds}
+
+Each interrupt target has an associated priority threshold, held in a
+platform-specific memory-mapped register. Only active interrupts that
+have a priority strictly greater than the threshold will cause a
+interrupt notification to be sent to the target. Different interrupt
+targets need not support the same set of priority threshold values.
+Interrupt target threshold registers should be \warl\ fields to allow
+software to determine the supported thresholds. A threshold register
+should always be able to hold the value zero, in which case, no
+interrupts are masked. If implemented, the threshold register will
+usually also be able to hold the maximum priority level, in which case
+all interrupts are masked.
+
+\begin{commentary}
+A simple valid implementation is to hardwire the threshold to zero, in
+which case it has no effect, and the individual enable bits will have
+to be saved and restored to attain the same effect. While the
+function of the threshold can be achieved by changing the
+interrupt-enable bits, manipulating a single threshold value avoids
+the target having to consider the individual priority levels of each
+interrupt source, and saving and restoring all the interrupt enables.
+Changing the threshold quickly might be especially important for
+systems that move frequently between power states.
+\end{commentary}
+
+\section{Interrupt Notifications}
+
+Each interrupt target has an {\em external interrupt pending} (EIP)
+bit in the PLIC core that indicates that the corresponding target has
+a pending interrupt waiting for service. The value in EIP can change
+as a result of changes to state in the PLIC core, brought on by
+interrupt sources, interrupt targets, or other agents manipulating
+register values in the PLIC. The value in EIP is communicated to the
+destination target as an interrupt notification. If the target is a
+RISC-V hart context, the interrupt notifications arrive on the {\tt
+ meip}/{\tt heip}/{\tt seip}/{\tt ueip} bits depending on the
+privilege level of the hart context.
+
+\begin{commentary}
+In simple systems, the interrupt notifications will be simple wires
+connected to the processor implementing a hart. In more complex
+platforms, the notifications might be routed as messages across a
+system interconnect.
+\end{commentary}
+
+The PLIC hardware only supports multicasting of interrupts, such that
+all enabled targets will receive interrupt notifications for a given
+active interrupt.
+
+\begin{commentary}
+Multicasting provides rapid response since the fastest responder
+claims the interrupt, but can be wasteful in high-interrupt-rate
+scenarios if multiple harts take a trap for an interrupt that only one
+can successfully claim. Software can modulate the PLIC IE bits as
+part of each interrupt handler to provide alternate policies, such as
+interrupt affinity or round-robin unicasting.
+\end{commentary}
+
+Depending on the platform architecture and the method used to
+transport interrupt notifications, these might take some time to be
+received at the targets. The PLIC is guaranteed to eventually deliver
+all state changes in EIP to all targets, provided there is no
+intervening activity in the PLIC core.
+
+\begin{commentary}
+The value in an interrupt notification is only guaranteed to hold an
+EIP value that was valid at some point in the past. In particular, a
+second target can respond and claim an interrupt while a notification
+to the first target is still in flight, such that when the first
+target tries to claim the interrupt it finds it has no active
+interrupts in the PLIC core.
+\end{commentary}
+
+\section{Interrupt Claims}
+
+Sometime after a target receives an interrupt notification, it might
+decide to service the interrupt. The target sends an {\em interrupt
+ claim} message to the PLIC core, which will usually be implemented
+as a non-idempotent memory-mapped I/O control register read. On
+receiving a claim message, the PLIC core will atomically determine the
+ID of the highest-priority pending interrupt for the target and then
+clear down the corresponding source's IP bit. The PLIC core will then
+return the ID to the target. The PLIC core will return an ID of zero,
+if there were no pending interrupts for the target when the claim was
+serviced.
+
+After the highest-priority pending interrupt is claimed by a target
+and the corresponding IP bit is cleared, other lower-priority pending
+interrupts might then become visible to the target, and so the PLIC
+EIP bit might not be cleared after a claim. The interrupt handler
+can check the local {\tt meip}/{\tt heip}/{\tt seip}/{\tt ueip} bits
+before exiting the handler, to allow more efficient service of other
+interrupts without first restoring the interrupted context and taking
+another interrupt trap.
+
+It is always legal for a hart to perform a claim even if the EIP is
+not set. In particular, a hart could set the threshold value to maximum
+to disable interrupt notifications and instead poll for active
+interrupts using periodic claim requests, though a simpler approach to
+implement polling would be to clear the external interrupt enable in
+the corresponding {\em x}{\tt ie} register for privilege mode {\em x}.
+
+\section{Interrupt Completion}
+
+After a handler has completed service of an interrupt, the associated
+gateway must be sent an interrupt completion message, usually as a
+write to a non-idempotent memory-mapped I/O control register. The
+gateway will only forward additional interrupts to the PLIC core after
+receiving the completion message.
+
+\section{Interrupt Flow}
+
+Figure~\ref{fig:intflow} shows the messages flowing between agents
+when handling interrupts via the PLIC.
+
+\begin{figure}[hb!]
+\centering
+\includegraphics[width=4.0in]{figs/PLIC-interrupt-flow.pdf}
+\caption{ Flow of interrupt processing via the PLIC.}
+\label{fig:intflow}
+\end{figure}
+
+The gateway will only forward a single interrupt request at a time to
+the PLIC, and not forward subsequent interrupts requests until an
+interrupt completion is received. The PLIC will set the IP bit once
+it accepts an interrupt request from the gateway, and sometime later
+forward an interrupt notification to the target. The target might
+take a while to respond to a new interrupt arriving, but will then
+send an interrupt claim request to the PLIC core to obtain the
+interrupt ID. The PLIC core will atomically return the ID and clear
+the corresponding IP bit, after which no other target can claim the
+same interrupt request. Once the handler has processed the interrupt,
+it sends an interrupt completion message to the gateway to allow a new
+interrupt request.
+
+\section{PLIC Core Specification}
+
+The operation of the PLIC core can be specified as a non-deterministic
+finite-state machine with input and output messsage queues, with the
+following atomic actions:
+
+\begin{itemize}
+
+\item {\bf Write Register: } A message containing a register write
+ request is dequeued. One of the internal registers is written,
+ where an internal register can be a priority, an interrupt-enable
+ (IE), or a threshold.
+
+\item {\bf Accept Request: } If the IP bit corresponding to the
+ interrupt source is clear, a message containing an interrupt request
+ from a gateway is dequeued and the IP bit is set.
+
+\item {\bf Process Claim: } An interrupt claim message is dequeued. A
+ claim-response message is enqueued to the requester with the ID of
+ the highest-priority active interrupt for that target, and the IP
+ bit corresponding to this interrupt source is cleared.
+
+\end{itemize}
+
+The value in the EIP bit is determined as a combinational function of
+the PLIC Core state. Interrupt notifications are sent via an
+autonomous process that ensures the EIP value is eventually reflected
+at the target.
+
+Note that the operation of the interrupt gateways is decoupled from
+the PLIC core. A gateway can handle parsing of interrupt signals and
+processing interrupt completion messages concurrently with other
+operations in the PLIC core.
+
+\begin{commentary}
+Figure~\ref{fig:plic} is a high-level conceptual view of the PLIC
+design. The PLIC core can be implemented in many ways provided its
+behavior can always be understood as following from some sequential
+ordering of these atomic actions. In particular, the PLIC might
+process multiple actions in a single clock cycle, or might process
+each action over many clock cycles.
+\end{commentary}
+
+\section{Controlling Access to the PLIC}
+
+In the expected use case, only machine mode accesses the source
+priority, source pending, and target interrupt enables to configure
+the interrupt subsystem. Lower-privilege modes access these features
+via ABI, SBI, or HBI calls. The interrupt enables act as a protection
+mechanism where a target can only signal completion to an interrupt
+gateway that is currently enabled for that target.
+
+Interrupt handlers that run with lower than machine-mode privilege
+need only be able to perform a claim read and a completion write, and
+to set their target threshold value. The memory map for these
+registers should allow machine mode to protect different targets from
+each other's accesses, using either physical memory protection or
+virtual memory page protections.
+