mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-20 11:57:12 -04:00
Update documentation of interrupt framework
This commit is contained in:
parent
be975eaa9d
commit
09aad340b1
5 changed files with 100 additions and 75 deletions
|
@ -12,6 +12,8 @@ Ibex implements all the Control and Status Registers (CSRs) listed in the follow
|
|||
+---------+--------------------+--------+-----------------------------------------------+
|
||||
| 0x301 | ``misa`` | WARL | Machine ISA and Extensions |
|
||||
+---------+--------------------+--------+-----------------------------------------------+
|
||||
| 0x304 | ``mie`` | WARL | Machine Interrupt Enable Register |
|
||||
+---------+--------------------+--------+-----------------------------------------------+
|
||||
| 0x305 | ``mtvec`` | WARL | Machine Trap-Vector Base Address |
|
||||
+---------+--------------------+--------+-----------------------------------------------+
|
||||
| 0x320 | ``mcountinhibit`` | RW | Machine Counter-Inhibit Register |
|
||||
|
@ -20,7 +22,7 @@ Ibex implements all the Control and Status Registers (CSRs) listed in the follow
|
|||
+---------+--------------------+--------+-----------------------------------------------+
|
||||
| . . . . |
|
||||
+---------+--------------------+--------+-----------------------------------------------+
|
||||
| 0x33F | ``mhpmevent31`` | WARL | Machine performance-monitoring event selector |
|
||||
| 0x33F | ``mhpmevent31`` | WARL | Machine Performance-Monitoring Event Selector |
|
||||
+---------+--------------------+--------+-----------------------------------------------+
|
||||
| 0x340 | ``mscratch`` | RW | Machine Scratch Register |
|
||||
+---------+--------------------+--------+-----------------------------------------------+
|
||||
|
@ -30,6 +32,8 @@ Ibex implements all the Control and Status Registers (CSRs) listed in the follow
|
|||
+---------+--------------------+--------+-----------------------------------------------+
|
||||
| 0x343 | ``mtval`` | WARL | Machine Trap Value Register |
|
||||
+---------+--------------------+--------+-----------------------------------------------+
|
||||
| 0x344 | ``mip`` | R | Machine Interrupt Pending Register |
|
||||
+---------+--------------------+--------+-----------------------------------------------+
|
||||
| 0x7B0 | ``dcsr`` | RW | Debug Control and Status Register |
|
||||
+---------+--------------------+--------+-----------------------------------------------+
|
||||
| 0x7B1 | ``dpc`` | RW | Debug PC |
|
||||
|
@ -96,6 +100,30 @@ CSR Address: ``0x301``
|
|||
On Ibex, ``misa`` is hard-wired, i.e. it will remain unchanged after any write.
|
||||
|
||||
|
||||
Machine Interrupt Enable Register (mie)
|
||||
---------------------------------------
|
||||
|
||||
CSR Address: ``0x304``
|
||||
|
||||
Reset Value: ``0x0000_0000``
|
||||
|
||||
``mie`` is a WARL register which allows to individually enable/disable local interrupts.
|
||||
After reset, all interrupts are disabled.
|
||||
|
||||
+-------+--------------------------------------------------------------------------------------+
|
||||
| Bit# | Interrupt |
|
||||
+-------+--------------------------------------------------------------------------------------+
|
||||
| 30:16 | Machine Fast Interrupt Enables: Set bit x+16 to enable |
|
||||
| | fast interrupt ``irq_fast_i[x]``. |
|
||||
+-------+--------------------------------------------------------------------------------------+
|
||||
| 11 | **Machine External Interrupt Enable (MEIE):** If set, ``irq_external_i`` is enabled. |
|
||||
+-------+--------------------------------------------------------------------------------------+
|
||||
| 7 | **Machine Timer Interrupt Enable (MTIE):** If set, ``irq_timer_i`` is enabled. |
|
||||
+-------+--------------------------------------------------------------------------------------+
|
||||
| 3 | **Machine Software Interrupt Enable (MSIE):** if set, ``irq_software_i`` is enabled. |
|
||||
+-------+--------------------------------------------------------------------------------------+
|
||||
|
||||
|
||||
Machine Trap-Vector Base Address (mtvec)
|
||||
----------------------------------------
|
||||
|
||||
|
@ -153,6 +181,30 @@ When an exception is encountered, this register can hold exception-specific info
|
|||
For all other exceptions, ``mtval`` is 0.
|
||||
|
||||
|
||||
Machine Interrupt Pending Register (mip)
|
||||
----------------------------------------
|
||||
|
||||
CSR Address: ``0x344``
|
||||
|
||||
Reset Value: ``0x0000_0000``
|
||||
|
||||
``mip`` is a read-only register indicating pending interrupt requests.
|
||||
A particular bit in the register reads as one if the corresponding interrupt input signal is high and if the interrupt is enabled in the ``mie`` CSR.
|
||||
|
||||
+-------+---------------------------------------------------------------------------------------+
|
||||
| Bit# | Interrupt |
|
||||
+-------+---------------------------------------------------------------------------------------+
|
||||
| 30:16 | Machine Fast Interrupts Pending: If bit x+16 is set, |
|
||||
| | fast interrupt ``irq_fast_i[x]`` is pending. |
|
||||
+-------+---------------------------------------------------------------------------------------+
|
||||
| 11 | **Machine External Interrupt Pending (MEIP):** If set, ``irq_external_i`` is pending. |
|
||||
+-------+---------------------------------------------------------------------------------------+
|
||||
| 7 | **Machine Timer Interrupt Pending (MTIP):** If set, ``irq_timer_i`` is pending. |
|
||||
+-------+---------------------------------------------------------------------------------------+
|
||||
| 3 | **Machine Software Interrupt Pending (MSIP):** if set, ``irq_software_i`` is pending. |
|
||||
+-------+---------------------------------------------------------------------------------------+
|
||||
|
||||
|
||||
.. _csr-mhartid:
|
||||
|
||||
Hardware Thread ID (mhartid)
|
||||
|
|
|
@ -6,7 +6,7 @@ Exceptions and Interrupts
|
|||
Ibex implements trap handling for interrupts and exceptions according to the RISC-V Privileged Specification, version 1.11.
|
||||
|
||||
All exceptions cause the core to jump to the base address of the vector table in the ``mtvec`` CSR.
|
||||
Interrupts are handled in vectored mode, i.e., the core jumps to the base address plus four times the interrupt cause number.
|
||||
Interrupts are handled in vectored mode, i.e., the core jumps to the base address plus four times the interrupt ID.
|
||||
|
||||
The base address of the vector table is given by the boot address (must be aligned to 256 bytes, i.e., its least significant byte must be 0x00).
|
||||
The most significant 3 bytes of the boot address given to the core are used for the first instruction fetch of the core and as the basis of the interrupt vector table.
|
||||
|
@ -18,12 +18,47 @@ It is assumed that the boot address is supplied via a register to avoid long pat
|
|||
Interrupts
|
||||
----------
|
||||
|
||||
Interrupts can only be enabled/disabled on a global basis and not individually.
|
||||
The global interrupt enable is done via the ``mstatus`` CSR.
|
||||
Ibex supports the following interrupts.
|
||||
|
||||
It is assumed that there is a separate event/interrupt controller outside of the core that performs masking and buffering of multiple interrupt requests.
|
||||
When an interrupt is taken, the core gives an acknowledge signal to the external event/interrupt controller as well as the interrupt ID taken.
|
||||
Check :ref:`interrupts` for more details.
|
||||
+-------------------------+-------+--------------------------------------------------+
|
||||
| Interrupt Input Signal | ID | Description |
|
||||
+=========================+=======+==================================================+
|
||||
| ``irq_nm_i`` | 31 | Non-maskable interrupt (NMI) |
|
||||
+-------------------------+-------+--------------------------------------------------+
|
||||
| ``irq_fast_i[14:0]`` | 30:16 | 15 fast, local interrupts |
|
||||
+-------------------------+-------+--------------------------------------------------+
|
||||
| ``irq_external_i`` | 11 | Connected to platform-level interrupt controller |
|
||||
+-------------------------+-------+--------------------------------------------------+
|
||||
| ``irq_timer_i`` | 7 | Connected to timer module |
|
||||
+-------------------------+-------+--------------------------------------------------+
|
||||
| ``irq_software_i`` | 3 | Connected to memory-mapped (inter-processor) |
|
||||
| | | interrupt register |
|
||||
+-------------------------+-------+--------------------------------------------------+
|
||||
|
||||
All interrupts except for the non-maskable interrupt (NMI) are controlled via the ``mstatus``, ``mie`` and ``mip`` CSRs.
|
||||
After reset, all interrupts are disabled.
|
||||
To enable interrupts, both the global interrupt enable (MIE) bit in the ``mstatus`` CSR and the corresponding individual interrupt enable bit in the ``mie`` CSR need to be set.
|
||||
For more information, see the :ref:`cs-registers` documentation.
|
||||
|
||||
If multiple interrupts are pending, the highest priority is given to the interrupt with the highest ID.
|
||||
|
||||
The NMI is enabled independent of the values in the ``mstatus`` and ``mie`` CSRs, and it is not visible through the ``mip`` CSR.
|
||||
It has interrupt ID 31, i.e., it has the highest priority of all interrupts and the core jumps to the trap-handler base address (in ``mtvec``) plus 0x7C to handle the NMI.
|
||||
|
||||
All interrupt lines are level-sensitive.
|
||||
It is assumed that the interrupt handler signals completion of the handling routine to the interrupt source, e.g., through a memory-mapped register, which then deasserts the corresponding interrupt line.
|
||||
|
||||
In debug mode, all interrupts including the NMI are ignored independent of ``mstatus``.MIE and the content of the ``mie`` CSR.
|
||||
|
||||
|
||||
Recoverable Non-Maskable Interrupt
|
||||
----------------------------------
|
||||
|
||||
To support recovering from an NMI happening during a trap handling routine, Ibex features additional CSRs for backing up ``mstatus``.MPP, ``mstatus``.MPIE, ``mepc`` and ``mcause``.
|
||||
These CSRs are not accessible by software running on the core.
|
||||
|
||||
These CSRs are nonstandard.
|
||||
For more information, see `the corresponding proposal <https://github.com/riscv/riscv-isa-manual/issues/261>`_.
|
||||
|
||||
|
||||
Exceptions
|
||||
|
|
|
@ -14,7 +14,6 @@ Ibex User Manual
|
|||
cs_registers
|
||||
performance_counters
|
||||
exception_interrupts
|
||||
interrupts
|
||||
debug
|
||||
tracer
|
||||
rvfi
|
||||
|
|
|
@ -48,10 +48,11 @@ Instantiation Template
|
|||
.data_err_i (),
|
||||
|
||||
// Interrupt inputs
|
||||
.irq_i (),
|
||||
.irq_id_i (),
|
||||
.irq_ack_o (),
|
||||
.irq_id_o (),
|
||||
.irq_software_i (),
|
||||
.irq_timer_i (),
|
||||
.irq_external_i (),
|
||||
.irq_fast_i (),
|
||||
.irq_nm_i (),
|
||||
|
||||
// Debug interface
|
||||
.debug_req_i (),
|
||||
|
@ -103,7 +104,7 @@ Interfaces
|
|||
+-------------------------+------------------------------------------------------------------------+
|
||||
| ``data_*`` | Load-store unit interface, see :ref:`load-store-unit` |
|
||||
+-------------------------+------------------------------------------------------------------------+
|
||||
| ``irq_*`` | Interrupt interface, see :ref:`interrupts` |
|
||||
| ``irq_*`` | Interrupt inputs, see :ref:`exceptions-interrupts` |
|
||||
+-------------------------+------------------------------------------------------------------------+
|
||||
| ``debug_*`` | Debug interface, see :ref:`debug-support` |
|
||||
+-------------------------+-------------------------+-----+----------------------------------------+
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
.. _interrupts:
|
||||
|
||||
Interrupts
|
||||
==========
|
||||
|
||||
Ibex requires a separate event/interrupt controller outside of the core that performs masking and buffering of multiple interrupt requests.
|
||||
Communication with this event/interrupt controller is established through the following external core interface:
|
||||
|
||||
+-------------------------+-----------+-----------------------------------------------+
|
||||
| Signal | Direction | Description |
|
||||
+=========================+===========+===============================================+
|
||||
| ``irq_i`` | in | Interrupt event, level sensitive |
|
||||
+-------------------------+-----------+-----------------------------------------------+
|
||||
| ``irq_id_i[4:0]`` | in | Interrupt ID |
|
||||
+-------------------------+-----------+-----------------------------------------------+
|
||||
| ``irq_ack_o`` | out | Interrupt acknowledgment |
|
||||
+-------------------------+-----------+-----------------------------------------------+
|
||||
| ``irq_id_o[4:0]`` | out | Interrupt acknowledgment ID |
|
||||
+-------------------------+-----------+-----------------------------------------------+
|
||||
|
||||
When external interrupts are enabled, the core will serve interrupt requests.
|
||||
An interrupt request is signaled with ``irq_i`` being high.
|
||||
The interrupt ID is signaled by ``irq_id_i`` and determines the address offset in the interrupt vector table of the core (see :ref:`exceptions-interrupts`).
|
||||
|
||||
Once the interrupt processing is completed, the core asserts ``irq_ack_o`` for one clock cycle and signals the identifier that has been completed in ``irq_id_o``.
|
||||
|
||||
.. important::
|
||||
|
||||
The core may not start interrupt processing in the same cycle the level changes.
|
||||
|
||||
:numref:`irq-processing` shows the signal timing during a standard interrupt cycle.
|
||||
|
||||
.. wavedrom::
|
||||
:name: irq-processing
|
||||
:caption: Interrupt processing
|
||||
|
||||
{ "signal": [
|
||||
{ "name": "clk_i", "wave": "p...", "period": 2 },
|
||||
{ "name": "irq_i", "wave": "01..|.0." },
|
||||
{ "name": "irq_id_i", "wave": "x=..|.x.", "data": ["ID0"] },
|
||||
{ "name": "irq_ack_o", "wave": "0...|10." },
|
||||
{ "name": "irq_id_id", "wave": "x...|=x.", "data": ["ID0"] }
|
||||
]
|
||||
}
|
||||
|
||||
As the interrupt identifier is registered once it is handled, it is allowed that the interrupt identifier at the input changes.
|
||||
This behavior can be used to handle interrupt priorities.
|
||||
But as the core may already have started interrupt processing, it is necessary to check the acknowledged ID.
|
||||
An example cycle is shown in :numref:`irq-processing-prio`.
|
||||
|
||||
.. wavedrom::
|
||||
:name: irq-processing-prio
|
||||
:caption: Interrupt processing with prioritization. The processing of ``ID0`` has already started.
|
||||
|
||||
{ "signal": [
|
||||
{ "name": "clk_i", "wave": "p...", "period": 2 },
|
||||
{ "name": "irq_i", "wave": "01..|.1." },
|
||||
{ "name": "irq_id_i", "wave": "x=.=|...", "data": ["ID0", "ID1"] },
|
||||
{ "name": "irq_ack_o", "wave": "0...|10." },
|
||||
{ "name": "irq_id_id", "wave": "x...|=x.", "data": ["ID0"] }
|
||||
]
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue