Skip to content

Commit c971acf

Browse files
committed
wrote a paragraph about Matthia's interrupts management in FemtoRV
1 parent 99e4418 commit c971acf

File tree

1 file changed

+82
-2
lines changed

1 file changed

+82
-2
lines changed

FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/INTERRUPTS.md

Lines changed: 82 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
This is WIP, for now just a scratchpad with notes.
44

55
Goals:
6+
======
67

78
- create a step-by-step gentle introduction, morphing the processor
89
obtained at the end of Episode I into something that can run FreeRTOS
@@ -66,6 +67,7 @@ could be something like (first draft):
6667
particular about simulation / verilator etc...)
6768

6869
List of questions:
70+
==================
6971

7072
- what is the minimal list of CSRs and instructions needed to run FreeRTOS ? First guess:
7173
- mepc: saved PC
@@ -106,10 +108,88 @@ List of questions:
106108
- [(A)CLINT](https://github.com/riscv/riscv-aclint/blob/main/riscv-aclint.adoc)
107109
- [CLIC](https://github.com/riscv/riscv-fast-interrupt/blob/master/clic.adoc)
108110

109-
Links:
111+
Interrupts, Exception, Traps
112+
============================
113+
114+
Definitions
115+
-----------
116+
117+
- Exception: unusual condition of run-time associated with an instruction
118+
- Trap: synchronous transfer to a trap handler caused by exceptional condition
119+
- Interrupt: external event that occurs asynchronously
120+
(if I understand well, a trap is what you return from using Xret. An exception is
121+
what triggers a trap from the current instruction, and an interrupt is what triggers
122+
a trap asynchronously, from the timer, or from a special wire).
123+
124+
125+
Interrupts in existing FemtoRV cores
126+
------------------------------------
127+
128+
Matthias has developed three FemtoRVs with interrupt support:
129+
- intermissum (RV32-IM)
130+
- gracilis (RV32-IMC)
131+
- individua (RV32-IMAC)
132+
133+
The interrupt logic is common to the three of them. They
134+
have an additional wire `interrupt_request` that triggers an interrupt
135+
136+
They implement the following CSRs:
137+
- `mepc`: saved program counter
138+
- `mtvec`: address of the interrupt handler
139+
- `mstatus` bit x: interrupt enable
140+
- `mcause` bit x: interrupt cause (and lock: already in interrupt handler)
141+
- there is also an `interrupt_request_sticky` flipflop
142+
143+
Besides writing/reading the new CSRs (easy), we need to make three modifications in
144+
our core:
145+
- 1 how the `interrupt_request` discusses with the rest of the chip
146+
- 2 how (and when) do we jump to a trap handler
147+
- 3 how do we return from a trap handler (that is, what `mret` does)
148+
149+
**1: how `interrupt_request` discusses with `interrupt_sticky`:**
150+
151+
`interrupt_request` only talks to `interrupt_sticky`, and the rest of the chip only sees `interrupt_sticky`.
152+
- if `interrupt_request` goes high, `interrupt_sticky` goes high
153+
- if `interrupt_sticky` is high, it stays high until the interrupt has been processed (that is, until we go through
154+
the `execute` state that does what should be done with the interrupt).
110155

156+
**2: how (and when) do we jump to a trap handler ?**
157+
158+
we just need to do three things:
159+
- jump to the trap handler, that is, set `PC` to `mtvec`
160+
- save return address, that is, set `mepc` to `PC+4` (or `PC+2` if it is a RV32C instruction)
161+
- indicate that we are in a trap handler, by setting bit 31 of `mcause` (indicates that we are in an interrupt)
162+
163+
It is done in the `EXECUTE` stage under three conditions:
164+
- there is an interrupt pending (`interrupt_request_sticky` is asserted) and
165+
- interrupts are enabled (`MIE`, that is `mstatus`[3] is set) and
166+
- we are not in an interrupt handler already (`mcause`[31]) is not asserted
167+
168+
**3: how do we return from a trap handler ?**
169+
- reset `mcause[31]` to 0
170+
- jump to the return address in `mepc`
171+
172+
It is done in the `EXECUTE` state. `mepc` is selected by the `PC_next` mux when the current instruction is `mret`
173+
174+
**Another view of what happens when an interrupt is triggered**
175+
- 1 `interrupt_request` is asserted by the external interrupt source
176+
- 2 `interrupt_sticky` goes high (and remains high until we are in `EXECUTE`
177+
- 3 `EXECUTE` sets `mcause[31]`, saves the return address to `mepc` and jumps to the trap handler.
178+
`interrupt_sticky` goes low
179+
- 4 the instructions in the trap handler are executed until current instruction is `mret`
180+
- 5 `EXECUTE` processes `mret` (resets `mcause[31]` and jumps to `mepc`)
181+
182+
Question: in the Risc-V norm, `mstatus` has a `mip` bit (machine interrupt pending). Is it
183+
different or is it the same thing as our `interrupt_sticky` ?
184+
185+
Links:
186+
======
111187
- @cnlohr's [minirv32](https://github.com/cnlohr/mini-rv32ima)
112188

113-
- Linux-capable @ultraembedded's [exact-step](https://github.com/ultraembedded/exactstep/blob/master/cpu-rv32/rv32.cpp)
189+
- Linux-capable @ultraembedded's simulator [exact-step](https://github.com/ultraembedded/exactstep/blob/master/cpu-rv32/rv32.cpp)
114190

115191
- @regymm [quasi-soc](https://github.com/regymm/quasiSoC)
192+
193+
- @MrBossman [kisc-v](https://github.com/Mr-Bossman/KISC-V)
194+
195+
- @splinedrive [Kian risc-V](https://github.com/splinedrive/kianRiscV)

0 commit comments

Comments
 (0)