OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [docs/] [datasheet/] [software_rte.adoc] - Blame information for rev 72

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 72 zero_gravi
:sectnums:
2
=== NEORV32 Runtime Environment
3
 
4
The NEORV32 software framework provides a minimal runtime environment (**RTE**) that takes care of a stable
5
and _safe_ execution environment by handling _all_ traps (= exceptions & interrupts). The RTE simplifies trap handling
6
by wrapping the CPU's _privileged architecture_ (i.e. trap-related CSRs) into a unified software API.
7
The NEORV32 RTE is a software library (`sw/lib/source/neorv32_rte.c`) that is part of the default processor library set.
8
It provides public functions via `sw/lib/include/neorv32_rte.h` for application interaction.
9
 
10
Once initialized, the RTE provides <<_default_rte_trap_handlers>> that catch all possible exceptions. These
11
default handlers just output a message via UART to inform the user when a certain trap has been triggered. The
12
default handlers can be overridden by the application code to install application-specific handler functions for each trap.
13
 
14
[IMPORTANT]
15
Using the RTE is **optional but highly recommended**. The RTE provides a simple and comfortable way of delegating
16
traps to application-specific handlers while making sure that all traps (even though they are not explicitly used
17
by the application) are handled correctly. Performance-optimized applications or embedded operating systems should
18
not use the RTE for delegating traps.
19
 
20
[NOTE]
21
For the **C standard runtime library** see section <>.
22
 
23
 
24
==== RTE Operation
25
 
26
The RTE handles the trap-related CSRs of the CPU's privileged architecture (<<_machine_trap_handling_csrs>>).
27
It initializes the <<_mtvec>> CSR, which provides the base entry point for all trap
28
handlers. The address stored to this register reflects the **first-level exception handler**, which is provided by the
29
NEORV32 RTE. Whenever an exception or interrupt is triggered this first-level handler is executed.
30
 
31
The first-level handler performs a complete context save, analyzes the source of the exception/interrupt and
32
calls the according **second-level exception handler**, which takes care of the actual exception/interrupt
33
handling. For this, the RTE manages a private look-up table to store the addresses of the according trap
34
handlers.
35
 
36
After the initial RTE setup, each entry in the RTE's trap handler's look-up table is initialized with a
37
<<_default_rte_trap_handlers>>. These default handler do not execute any trap-related operations - they
38
just output a message via the *primary UART (UART0)* to inform the user that a trap has occurred, that is not
39
handled by the actual application. After sending this message, the RTE tries to continue executing the user program.
40
 
41
 
42
==== Using the RTE
43
 
44
The NEORV32 is enabled by calling the RTE's setup function:
45
 
46
.Function Prototype: RTE Setup
47
[source,c]
48
----
49
void neorv32_rte_setup(void);
50
----
51
 
52
[NOTE]
53
The RTE should be enabled right at the beginning of the application's `main` function.
54
 
55
As mentioned above, _all_ traps will only trigger execution of the RTE's <<_default_rte_trap_handlers>>.
56
To use application-specific handlers, which actually _handle_ a trap, the default handlers can be overridden
57
by installing user-defined ones:
58
 
59
.Function Prototype: Installing an Application-Specific Trap Handler
60
[source,c]
61
----
62
int neorv32_rte_exception_install(uint8_t id, void (*handler)(void));
63
----
64
 
65
The first argument `id` defines the "trap ID" (for example a certain interrupt request) that shall be handled
66
by the user-defined handler. The second argument `*handler` is the actual function that implements the trap
67
handler. The function return zero on success and a non-zero value if an error occurred (invalid `id`). In this
68
case no modifications to the RTE's trap look-up-table will be made.
69
 
70
The custom handler functions need to have a specific format without any arguments an with no return value:
71
 
72
.Function Prototype: Custom Trap Handler
73
[source,c]
74
----
75
void custom_trap_handler_xyz(void) {
76
 
77
  // handle exception/interrupt...
78
}
79
----
80
 
81
.Custom Trap Handler Attributes
82
[WARNING]
83
Do NOT use the `((interrupt))` attribute for the application exception handler functions! This
84
will place a `mret` instruction to the end of it making it impossible to return to the first-level
85
exception handler of the RTE core, which will cause stack corruption.
86
 
87
The trap identifier `id` specifies the according trap cause. These can be an _asynchronous trap_ like
88
an interrupt from one of the processor modules or a _synchronous trap_ triggered by software-caused events
89
like an illegal instruction or an environment call instruction. The `sw/lib/include/neorv32_rte.h` library files
90
provides aliases for trap events supported by the CPU (see <<_neorv32_trap_listing>>) that can be used when
91
installing custom trap handler functions:
92
 
93
.RTE Trap ID List
94
[cols="<5,<12"]
95
[options="header",grid="rows"]
96
|=======================
97
| ID alias [C] | Description / trap causing event
98
| `RTE_TRAP_I_MISALIGNED` | instruction address misaligned
99
| `RTE_TRAP_I_ACCESS`     | instruction (bus) access fault
100
| `RTE_TRAP_I_ILLEGAL`    | illegal instruction
101
| `RTE_TRAP_BREAKPOINT`   | breakpoint (`ebreak` instruction)
102
| `RTE_TRAP_L_MISALIGNED` | load address misaligned
103
| `RTE_TRAP_L_ACCESS`     | load (bus) access fault
104
| `RTE_TRAP_S_MISALIGNED` | store address misaligned
105
| `RTE_TRAP_S_ACCESS`     | store (bus) access fault
106
| `RTE_TRAP_MENV_CALL`    | environment call from machine mode (`ecall` instruction)
107
| `RTE_TRAP_UENV_CALL`    | environment call from user mode (`ecall` instruction)
108
| `RTE_TRAP_MTI`          | machine timer interrupt
109
| `RTE_TRAP_MEI`          | machine external interrupt
110
| `RTE_TRAP_MSI`          | machine software interrupt
111
| `RTE_TRAP_FIRQ_0`       | fast interrupt channel 0
112
| `RTE_TRAP_FIRQ_1`       | fast interrupt channel 1
113
| `RTE_TRAP_FIRQ_2`       | fast interrupt channel 2
114
| `RTE_TRAP_FIRQ_3`       | fast interrupt channel 3
115
| `RTE_TRAP_FIRQ_4`       | fast interrupt channel 4
116
| `RTE_TRAP_FIRQ_5`       | fast interrupt channel 5
117
| `RTE_TRAP_FIRQ_6`       | fast interrupt channel 6
118
| `RTE_TRAP_FIRQ_7`       | fast interrupt channel 7
119
| `RTE_TRAP_FIRQ_8`       | fast interrupt channel 8
120
| `RTE_TRAP_FIRQ_9`       | fast interrupt channel 9
121
| `RTE_TRAP_FIRQ_10`      | fast interrupt channel 10
122
| `RTE_TRAP_FIRQ_11`      | fast interrupt channel 11
123
| `RTE_TRAP_FIRQ_12`      | fast interrupt channel 12
124
| `RTE_TRAP_FIRQ_13`      | fast interrupt channel 13
125
| `RTE_TRAP_FIRQ_14`      | fast interrupt channel 14
126
| `RTE_TRAP_FIRQ_15`      | fast interrupt channel 15
127
|=======================
128
 
129
The following example shows how to install a custom handler (`custom_mtime_irq_handler`) for handling
130
the RISC-V machine timer (MTIME) interrupt:
131
 
132
.Example: Installing the MTIME IRQ Handler
133
[source,c]
134
----
135
neorv32_rte_exception_install(RTE_TRAP_MTI, custom_mtime_irq_handler);
136
----
137
 
138
User-defined trap handlers can also be un-installed. This will remove the users trap handler from the RTE core
139
and will re-install the <<_default_rte_trap_handlers>> for the specific trap.
140
 
141
.Function Prototype: Installing an Application-Specific Trap Handler
142
[source,c]
143
----
144
int neorv32_rte_exception_uninstall(uint8_t id);
145
----
146
 
147
The argument `id` defines the identifier of the according trap that shall be un-installed. The function return zero
148
on success and a non-zero value if an error occurred (invalid `id`). In this case no modifications to the RTE's trap
149
look-up-table will be made.
150
 
151
The following example shows how to un-install the custom handler `custom_mtime_irq_handler` from the
152
RISC-V machine timer (MTIME) interrupt:
153
 
154
.Example: Removing the Custom MTIME IRQ Handler
155
[source,c]
156
----
157
neorv32_rte_exception_uninstall(RTE_TRAP_MTI);
158
----
159
 
160
 
161
==== Default RTE Trap Handlers
162
 
163
The default RTE trap handlers are executed when a certain trap is triggered that is not handled by a user-defined
164
application-specific trap handler. These default handler will just output a message giving additional debug information
165
via UART0 to inform the user and will try to resume normal execution of the application.
166
 
167
.Continuing Execution
168
[IMPORTAN]
169
In most cases the RTE can successfully continue operation when it catches an interrupt request, which is not handled
170
by the actual application program. However, if the RTE catches an un_handled exception like a bus access fault
171
continuing execution will most likely fail and the CPU will crash.
172
 
173
.RTE Default Trap Handler Output Example (Illegal Instruction)
174
[source]
175
----
176
 Illegal instruction @ PC=0x000002d6, MTVAL=0x00001537 
177
----
178
 
179
In this example the "Illegal instruction" _message_ describes the cause of the trap, which is an illegal instruction
180
exception here. `PC` shows the current program counter value when the trap occurred and `MTVAL` shows additional
181
debug information from the <<_mtval>> CSR. In this case it shows the encoding of the illegal instruction.
182
 
183
The specific _message_ corresponds to the trap code from the <<_mcause>> CSR (see <<_neorv32_trap_listing>>).
184
A full list of all messages and the according `mcause` trap codes are shown below.
185
 
186
.RTE Default Trap Handler Messages and According `mcause` Values
187
[cols="<5,^5"]
188
[options="header",grid="rows"]
189
|=======================
190
| Trap identifier | According `mcause` CSR value
191
| "Instruction address misaligned" | `0x00000000`
192
| "Instruction access fault"       | `0x00000001`
193
| "Illegal instruction"            | `0x00000002`
194
| "Breakpoint"                     | `0x00000003`
195
| "Load address misaligned"        | `0x00000004`
196
| "Load access fault"              | `0x00000005`
197
| "Store address misaligned"       | `0x00000006`
198
| "Store access fault"             | `0x00000007`
199
| "Environment call from U-mode"   | `0x00000008`
200
| "Environment call from M-mode"   | `0x0000000b`
201
| "Machine software interrupt"     | `0x80000003`
202
| "Machine timer interrupt"        | `0x80000007`
203
| "Machine external interrupt"     | `0x8000000b`
204
| "Fast interrupt 0"               | `0x80000010`
205
| "Fast interrupt 1"               | `0x80000011`
206
| "Fast interrupt 2"               | `0x80000012`
207
| "Fast interrupt 3"               | `0x80000013`
208
| "Fast interrupt 4"               | `0x80000014`
209
| "Fast interrupt 5"               | `0x80000015`
210
| "Fast interrupt 6"               | `0x80000016`
211
| "Fast interrupt 7"               | `0x80000017`
212
| "Fast interrupt 8"               | `0x80000018`
213
| "Fast interrupt 9"               | `0x80000019`
214
| "Fast interrupt a"               | `0x8000001a`
215
| "Fast interrupt b"               | `0x8000001b`
216
| "Fast interrupt c"               | `0x8000001c`
217
| "Fast interrupt d"               | `0x8000001d`
218
| "Fast interrupt e"               | `0x8000001e`
219
| "Fast interrupt f"               | `0x8000001f`
220
| "Unknown trap cause"             | _not defined_
221
|=======================
222
 
223
===== Bus Access Faults
224
 
225
For bus access faults the RTE default trap handlers also output the error code from the
226
<<_internal_bus_monitor_buskeeper>> to show the cause of the bus fault. One example is shown below.
227
 
228
.RTE Default Trap Handler Output Example (Load Access Bus Fault)
229
[source]
230
----
231
 Load access fault [TIMEOUT_ERR] @ PC=0x00000150, MTVAL=0xFFFFFF70 
232
----
233
 
234
The additional message encapsulated in `[ ]` shows the actual cause of the bus access fault.
235
Three different messages are possible here:
236
 
237
* `[TIMEOUT_ERR]`: The accessed memory-mapped module did not respond within the valid access time window.
238
In Most cases this is caused by accessing a module that has not been implemented or when accessing
239
"address space holes" (unused/unmapped addresses).
240
* `[DEVICE_ERR]`: The accesses memory-mapped module asserted it's error signal to indicate an invalid access.
241
For example this can be caused by trying to write to read-only registers or by writing data quantities (like a byte)
242
to devices that do not support sub-word write accesses.
243
* `[PMP_ERR]`: This indicates an access right violation caused by the <<_pmp_physical_memory_protection>>.

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.