@micro-os-plus/architecture-riscv 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/CHANGELOG.md +152 -0
  2. package/CMakeLists.txt +87 -0
  3. package/LICENSE +21 -0
  4. package/README.md +317 -0
  5. package/include/micro-os-plus/architecture-riscv/core-functions-inlines.h +86 -0
  6. package/include/micro-os-plus/architecture-riscv/core-functions.h +105 -0
  7. package/include/micro-os-plus/architecture-riscv/csr-functions-inlines.h +466 -0
  8. package/include/micro-os-plus/architecture-riscv/csr-functions.h +241 -0
  9. package/include/micro-os-plus/architecture-riscv/declarations.h +58 -0
  10. package/include/micro-os-plus/architecture-riscv/defines.h +185 -0
  11. package/include/micro-os-plus/architecture-riscv/device-functions-inlines.h +235 -0
  12. package/include/micro-os-plus/architecture-riscv/device-functions.h +166 -0
  13. package/include/micro-os-plus/architecture-riscv/instructions-inlines.h +172 -0
  14. package/include/micro-os-plus/architecture-riscv/instructions.h +153 -0
  15. package/include/micro-os-plus/architecture-riscv/platform-functions-inlines.h +81 -0
  16. package/include/micro-os-plus/architecture-riscv/platform-functions.h +75 -0
  17. package/include/micro-os-plus/architecture-riscv/plic-functions.h +278 -0
  18. package/include/micro-os-plus/architecture-riscv/semihosting-inlines.h +79 -0
  19. package/include/micro-os-plus/architecture-riscv/types.h +135 -0
  20. package/include/micro-os-plus/architecture.h +38 -0
  21. package/linker-scripts/README.md +7 -0
  22. package/linker-scripts/sections-flash.ld +425 -0
  23. package/linker-scripts/sections-ram.ld +425 -0
  24. package/linker-scripts/sections.ld +377 -0
  25. package/meson.build +46 -0
  26. package/package.json +37 -0
  27. package/src/.gitkeep +0 -0
  28. package/xpack.json +23 -0
@@ -0,0 +1,278 @@
1
+ /*
2
+ * This file is part of the µOS++ distribution.
3
+ * (https://github.com/micro-os-plus/)
4
+ * Copyright (c) 2017 Liviu Ionescu.
5
+ *
6
+ * Permission to use, copy, modify, and/or distribute this software
7
+ * for any purpose is hereby granted, under the terms of the MIT license.
8
+ *
9
+ * If a copy of the license was not distributed with this file, it can
10
+ * be obtained from https://opensource.org/licenses/MIT/.
11
+ */
12
+
13
+ #ifndef MICRO_OS_PLUS_ARCHITECTURE_RISCV_PLIC_FUNCTIONS_H_
14
+ #define MICRO_OS_PLUS_ARCHITECTURE_RISCV_PLIC_FUNCTIONS_H_
15
+
16
+ // ----------------------------------------------------------------------------
17
+
18
+ #include <micro-os-plus/architecture-riscv/types.h>
19
+
20
+ #include <stdbool.h>
21
+
22
+ // ----------------------------------------------------------------------------
23
+
24
+ // RISC-V PLIC support functions.
25
+
26
+ #if defined(__cplusplus)
27
+
28
+ // ----------------------------------------------------------------------------
29
+
30
+ namespace riscv
31
+ {
32
+ namespace plic
33
+ {
34
+ // ------------------------------------------------------------------------
35
+
36
+ using source_t = riscv_plic_source_t;
37
+ using priority_t = riscv_plic_priority_t;
38
+
39
+ /**
40
+ * @brief Initialize the interrupt controller.
41
+ * @par Parameters
42
+ * None.
43
+ * @par Returns
44
+ * Nothing.
45
+ *
46
+ * @details
47
+ * Do not assume the controller registers were cleared by reset,
48
+ * instead set them explicitly to reasonable default values, for
49
+ * example disable all interrupts and set the threshold to zero.
50
+ *
51
+ * @note
52
+ * This function must be called from each target (hart).
53
+ */
54
+ void
55
+ initialize (void);
56
+
57
+ /**
58
+ * @brief Clear all PLIC priorities.
59
+ * @par Parameters
60
+ * None.
61
+ * @par Returns
62
+ * Nothing.
63
+ *
64
+ * @details
65
+ * Do not assume the controller registers were cleared by reset,
66
+ * instead set them explicitly to reasonable default values, for
67
+ * example set all priorities to 0.
68
+ *
69
+ * @note
70
+ * The priorities are unique for the entire PLIC, do not call
71
+ * this function from each target (hart), since it might
72
+ * override values set by other targets.
73
+ */
74
+ void
75
+ clear_priorities (void);
76
+
77
+ /**
78
+ * @brief Set the interrupt threshold for the current target (hart).
79
+ * @param [in] priority The new threshold value.
80
+ * @return The previous threshold value.
81
+ *
82
+ * @details
83
+ * Each interrupt target (usually a hart) has an associated
84
+ * priority threshold, held in
85
+ * a platform-specific memory-mapped register. Only active
86
+ * interrupts that have a priority strictly greater than the
87
+ * threshold will cause an interrupt notification to be sent
88
+ * to the target.
89
+ *
90
+ * Different interrupt targets need not support the same set of
91
+ * priority threshold values. Interrupt target threshold registers
92
+ * should be WARL fields to allow software to determine the
93
+ * supported thresholds. A threshold register should always be
94
+ * able to hold the value zero, in which case, no interrupts
95
+ * are masked. If implemented, the threshold register will usually
96
+ * also be able to hold the maximum priority level, in which case
97
+ * all interrupts are masked.
98
+ */
99
+ priority_t
100
+ threshold (priority_t priority);
101
+
102
+ /**
103
+ * @brief Get the interrupt threshold for the current target (hart).
104
+ * @par Parameters
105
+ * None.
106
+ * @return The threshold value.
107
+ */
108
+ priority_t
109
+ threshold (void);
110
+
111
+ /**
112
+ * @brief Enable an interrupt for the current target (hart).
113
+ * @param [in] global_interrupt_id The id of the global interrupt
114
+ * source.
115
+ * @par Returns
116
+ * Nothing.
117
+ */
118
+ void
119
+ enable_interrupt (source_t global_interrupt_id);
120
+
121
+ /**
122
+ * @brief Disable an interrupt for the current target (hart).
123
+ * @param [in] global_interrupt_id The id of the global interrupt
124
+ * source.
125
+ * @par Returns
126
+ * Nothing.
127
+ */
128
+ void
129
+ disable_interrupt (source_t global_interrupt_id);
130
+
131
+ /**
132
+ * @brief Check if an interrupt is enabled for the current target
133
+ * (hart).
134
+ * @param [in] global_interrupt_id The id of the global interrupt
135
+ * source.
136
+ * @retval true The interrupt is enabled.
137
+ * @retval false The interrupt is disabled.
138
+ */
139
+ bool
140
+ is_interrupt_enabled (source_t global_interrupt_id);
141
+
142
+ /**
143
+ * @brief Set the priority of an interrupt.
144
+ * @param [in] global_interrupt_id The id of the global interrupt
145
+ * source.
146
+ * @param [in] priority The interrupt priority.
147
+ * @par Returns
148
+ * Nothing.
149
+ */
150
+ void
151
+ priority (source_t global_interrupt_id, priority_t priority);
152
+
153
+ /**
154
+ * @brief Get the priority of an interrupt.
155
+ * @param [in] global_interrupt_id The id of the global interrupt
156
+ * source.
157
+ * @return The current priority.
158
+ */
159
+ priority_t
160
+ priority (source_t global_interrupt_id);
161
+
162
+ /**
163
+ * @brief Claim an interrupt for the current target (hart).
164
+ * @par Parameters
165
+ * None.
166
+ * @return The highest priority pending interrupt or 0, if there
167
+ * are no pending interrupts.
168
+ *
169
+ * @details
170
+ * Sometime after a target receives an interrupt notification, it
171
+ * might decide to service the interrupt. The target sends an
172
+ * interrupt claim message to the PLIC core, which will usually
173
+ * be implemented as a non-idempotent memory-mapped I/O control
174
+ * register read. On receiving a claim message, the PLIC core will
175
+ * atomically determine the ID of the highest-priority pending
176
+ * interrupt for the target and then clear down the corresponding
177
+ * source's IP bit. The PLIC core will then return the ID to the
178
+ * target. The PLIC core will return an ID of zero, if there were
179
+ * no pending interrupts for the target when the claim was serviced.
180
+ *
181
+ * After the highest-priority pending interrupt is claimed by a
182
+ * target and the corresponding IP bit is cleared, other
183
+ * lower-priority pending interrupts might then become visible
184
+ * to the target, and so the PLIC EIP bit might not be cleared
185
+ * after a claim. The interrupt handler can check the local
186
+ * `meip/seip/ueip` bits before exiting the handler, to allow
187
+ * more efficient service of other interrupts without first
188
+ * restoring the interrupted context and taking another interrupt
189
+ * trap.
190
+ *
191
+ * It is always legal for a hart to perform a claim even if the EIP
192
+ * is not set. In particular, a hart could set the threshold value
193
+ * to maximum to disable interrupt notifications and instead poll
194
+ * for active interrupts using periodic claim requests, though a
195
+ * simpler approach to implement polling would be to clear the
196
+ * external interrupt enable in the corresponding `xie` register
197
+ * for privilege mode `x`.
198
+ */
199
+ source_t
200
+ claim_interrupt (void);
201
+
202
+ /**
203
+ * @brief Send the completion message to the interrupt target (hart).
204
+ * @param [in] global_interrupt_id The id of the global interrupt
205
+ * source.
206
+ * @par Returns
207
+ * Nothing.
208
+ *
209
+ * @details
210
+ * After a handler has completed service of an interrupt, the
211
+ * associated gateway must be sent an interrupt completion message,
212
+ * usually as a write to a non-idempotent memory-mapped I/O control
213
+ * register. The gateway will only forward additional interrupts to
214
+ * the PLIC core after receiving the completion message.
215
+ */
216
+ void
217
+ complete_interrupt (source_t global_interrupt_id);
218
+
219
+ // ------------------------------------------------------------------------
220
+ } // namespace plic
221
+ } // namespace riscv
222
+
223
+ #endif // defined(__cplusplus)
224
+
225
+ // ============================================================================
226
+
227
+ #if defined(__cplusplus)
228
+ extern "C"
229
+ {
230
+ #endif // defined(__cplusplus)
231
+
232
+ // --------------------------------------------------------------------------
233
+
234
+ void
235
+ riscv_plic_initialize (void);
236
+
237
+ void
238
+ riscv_plic_clear_priorities (void);
239
+
240
+ static riscv_plic_priority_t
241
+ riscv_plic_write_threshold (riscv_plic_priority_t priority);
242
+
243
+ static riscv_plic_priority_t
244
+ riscv_plic_read_threshold (void);
245
+
246
+ static void
247
+ riscv_plic_enable_interrupt (riscv_plic_source_t global_interrupt_id);
248
+
249
+ static void
250
+ riscv_plic_disable_interrupt (riscv_plic_source_t global_interrupt_id);
251
+
252
+ static bool
253
+ riscv_plic_is_interrupt_enabled (riscv_plic_source_t global_interrupt_id);
254
+
255
+ static void
256
+ riscv_plic_write_priority (riscv_plic_source_t global_interrupt_id,
257
+ riscv_plic_priority_t priority);
258
+
259
+ static riscv_plic_priority_t
260
+ riscv_plic_read_priority (riscv_plic_source_t global_interrupt_id);
261
+
262
+ static riscv_plic_source_t
263
+ riscv_plic_claim_interrupt (void);
264
+
265
+ static void
266
+ riscv_plic_complete_interrupt (riscv_plic_source_t global_interrupt_id);
267
+
268
+ // --------------------------------------------------------------------------
269
+
270
+ #if defined(__cplusplus)
271
+ }
272
+ #endif // defined(__cplusplus)
273
+
274
+ // ----------------------------------------------------------------------------
275
+
276
+ #endif // MICRO_OS_PLUS_ARCHITECTURE_RISCV_PLIC_FUNCTIONS_H_
277
+
278
+ // ----------------------------------------------------------------------------
@@ -0,0 +1,79 @@
1
+ /*
2
+ * This file is part of the µOS++ distribution.
3
+ * (https://github.com/micro-os-plus/)
4
+ * Copyright (c) 2015 Liviu Ionescu.
5
+ *
6
+ * Permission to use, copy, modify, and/or distribute this software
7
+ * for any purpose is hereby granted, under the terms of the MIT license.
8
+ *
9
+ * If a copy of the license was not distributed with this file, it can
10
+ * be obtained from https://opensource.org/licenses/MIT/.
11
+ */
12
+
13
+ #ifndef MICRO_OS_PLUS_ARCHITECTURE_RISCV_ARCH_SEMIHOSTING_INLINES_H_
14
+ #define MICRO_OS_PLUS_ARCHITECTURE_RISCV_ARCH_SEMIHOSTING_INLINES_H_
15
+
16
+ // ----------------------------------------------------------------------------
17
+
18
+ #if defined(__cplusplus)
19
+ extern "C"
20
+ {
21
+ #endif // defined(__cplusplus)
22
+
23
+ // --------------------------------------------------------------------------
24
+
25
+ // The hint that differentiates the semihosting call.
26
+ #define RISCV_SEMIHOSTING_CALL_NUMBER 7
27
+
28
+ // --------------------------------------------------------------------------
29
+
30
+ // Type of each entry in a parameter block.
31
+ typedef micro_os_plus_architecture_register_t
32
+ micro_os_plus_semihosting_param_block_t;
33
+ // Type of result.
34
+ typedef micro_os_plus_architecture_signed_register_t
35
+ micro_os_plus_semihosting_response_t;
36
+
37
+ // --------------------------------------------------------------------------
38
+
39
+ static inline __attribute__ ((always_inline))
40
+ micro_os_plus_semihosting_response_t
41
+ micro_os_plus_semihosting_call_host (int reason, void* arg)
42
+ {
43
+ micro_os_plus_semihosting_response_t value;
44
+
45
+ __asm__ volatile(
46
+
47
+ " mv a0, %[rsn] \n"
48
+ " mv a1, %[arg] \n"
49
+
50
+ " .balign 16 \n"
51
+ // Workaround for RISC-V lack of multiple EBREAKs.
52
+ " .option push \n"
53
+ " .option norvc \n"
54
+ " slli x0, x0, 0x1f \n"
55
+ " ebreak \n"
56
+ " srai x0, x0, %[swi] \n"
57
+ " .option pop \n"
58
+
59
+ " mv %[val], a0"
60
+
61
+ : [val] "=r"(value) /* Outputs */
62
+ : [rsn] "r"(reason), [arg] "r"(arg), [swi] "i"(RISCV_SEMIHOSTING_CALL_NUMBER) /* Inputs */
63
+ : "a0", "a1", "a2", "a3", "a4", "a5", "memory" /* Clobbers */
64
+ );
65
+
66
+ return value;
67
+ }
68
+
69
+ // --------------------------------------------------------------------------
70
+
71
+ #if defined(__cplusplus)
72
+ }
73
+ #endif // defined(__cplusplus)
74
+
75
+ // ----------------------------------------------------------------------------
76
+
77
+ #endif // MICRO_OS_PLUS_ARCHITECTURE_RISCV_ARCH_SEMIHOSTING_INLINES_H_
78
+
79
+ // ----------------------------------------------------------------------------
@@ -0,0 +1,135 @@
1
+ /*
2
+ * This file is part of the µOS++ distribution.
3
+ * (https://github.com/micro-os-plus/)
4
+ * Copyright (c) 2017 Liviu Ionescu.
5
+ *
6
+ * Permission to use, copy, modify, and/or distribute this software
7
+ * for any purpose is hereby granted, under the terms of the MIT license.
8
+ *
9
+ * If a copy of the license was not distributed with this file, it can
10
+ * be obtained from https://opensource.org/licenses/MIT/.
11
+ */
12
+
13
+ #ifndef MICRO_OS_PLUS_ARCHITECTURE_RISCV_ARCH_TYPES_H_
14
+ #define MICRO_OS_PLUS_ARCHITECTURE_RISCV_ARCH_TYPES_H_
15
+
16
+ // ----------------------------------------------------------------------------
17
+
18
+ #include <stdint.h>
19
+
20
+ #if defined(__cplusplus)
21
+ extern "C"
22
+ {
23
+ #endif // defined(__cplusplus)
24
+
25
+ #if __riscv_xlen == 32
26
+ typedef uint32_t riscv_architecture_register_t;
27
+ typedef int32_t riscv_architecture_signed_register_t;
28
+ #elif __riscv_xlen == 64
29
+ typedef uint64_t riscv_architecture_register_t;
30
+ typedef int64_t riscv_architecture_signed_register_t;
31
+ #endif // __riscv_xlen
32
+
33
+ typedef riscv_architecture_register_t micro_os_plus_architecture_register_t;
34
+ typedef riscv_architecture_signed_register_t
35
+ micro_os_plus_architecture_signed_register_t;
36
+
37
+ typedef void (*riscv_core_trap_handler_ptr_t) (void);
38
+
39
+ // --------------------------------------------------------------------------
40
+
41
+ typedef enum
42
+ {
43
+ riscv_exception_misaligned_fetch = 0,
44
+ riscv_exception_fault_fetch = 1,
45
+ riscv_exception_illegal_instruction = 2,
46
+ riscv_exception_breakpoint = 3,
47
+ riscv_exception_misaligned_load = 4,
48
+ riscv_exception_fault_load = 5,
49
+ riscv_exception_misaligned_store = 6,
50
+ riscv_exception_fault_store = 7,
51
+ riscv_exception_user_ecall = 8,
52
+ riscv_exception_supervisor_ecall = 9,
53
+ /* 10 */
54
+ riscv_exception_machine_ecall = 11,
55
+ riscv_exception_page_fetch = 12,
56
+ riscv_exception_page_load = 13,
57
+ /* 14 */
58
+ riscv_exception_page_store = 15
59
+ } riscv_exceptions_enum_t;
60
+
61
+ #define RISCV_EXCEPTIONS_LAST_NUMBER (15u)
62
+
63
+ // --------------------------------------------------------------------------
64
+ // Values from Table 3.6.
65
+
66
+ typedef enum
67
+ {
68
+ riscv_interrupt_local_user_software = 0,
69
+ riscv_interrupt_local_supervisor_software = 1,
70
+ /* 2 reserved */
71
+ riscv_interrupt_local_machine_software = 3,
72
+ riscv_interrupt_local_user_timer = 4,
73
+ riscv_interrupt_local_supervisor_timer = 5,
74
+ /* 6 reserved */
75
+ riscv_interrupt_local_machine_timer = 7,
76
+ riscv_interrupt_local_user_ext = 8,
77
+ riscv_interrupt_local_supervisor_ext = 9,
78
+ /* 10 reserved */
79
+ riscv_interrupt_local_machine_ext = 11,
80
+ /* 12 reserved */
81
+ /* 13 reserved */
82
+ /* 14 reserved */
83
+ /* 15 reserved */
84
+ } riscv_interrupts_local_enum_t;
85
+
86
+ // --------------------------------------------------------------------------
87
+
88
+ #if defined(__cplusplus)
89
+ }
90
+ #endif // defined(__cplusplus)
91
+
92
+ // ============================================================================
93
+
94
+ #if defined(__cplusplus)
95
+
96
+ // ----------------------------------------------------------------------------
97
+
98
+ namespace riscv::architecture
99
+ {
100
+ // --------------------------------------------------------------------------
101
+
102
+ using register_t = riscv_architecture_register_t;
103
+ using signed_register_t = riscv_architecture_signed_register_t;
104
+
105
+ // --------------------------------------------------------------------------
106
+ } // namespace riscv::architecture
107
+
108
+ namespace riscv::core
109
+ {
110
+ // --------------------------------------------------------------------------
111
+
112
+ using trap_handler_ptr_t = riscv_core_trap_handler_ptr_t;
113
+
114
+ // --------------------------------------------------------------------------
115
+ } // namespace riscv::core
116
+
117
+ namespace micro_os_plus::architecture
118
+ {
119
+ // --------------------------------------------------------------------------
120
+
121
+ using register_t = riscv_architecture_register_t;
122
+ using signed_register_t = riscv_architecture_signed_register_t;
123
+
124
+ // --------------------------------------------------------------------------
125
+ } // namespace micro_os_plus::architecture
126
+
127
+ // ----------------------------------------------------------------------------
128
+
129
+ #endif // defined(__cplusplus)
130
+
131
+ // ----------------------------------------------------------------------------
132
+
133
+ #endif // MICRO_OS_PLUS_ARCHITECTURE_RISCV_ARCH_TYPES_H_
134
+
135
+ // ----------------------------------------------------------------------------
@@ -0,0 +1,38 @@
1
+ /*
2
+ * This file is part of the µOS++ distribution.
3
+ * (https://github.com/micro-os-plus/)
4
+ * Copyright (c) 2017 Liviu Ionescu.
5
+ *
6
+ * Permission to use, copy, modify, and/or distribute this software
7
+ * for any purpose is hereby granted, under the terms of the MIT license.
8
+ *
9
+ * If a copy of the license was not distributed with this file, it can
10
+ * be obtained from https://opensource.org/licenses/MIT/.
11
+ */
12
+
13
+ #ifndef MICRO_OS_PLUS_ARCHITECTURE_H_
14
+ #define MICRO_OS_PLUS_ARCHITECTURE_H_
15
+
16
+ // ----------------------------------------------------------------------------
17
+
18
+ #include <micro-os-plus/architecture-riscv/defines.h>
19
+
20
+ #include <micro-os-plus/architecture-riscv/types.h>
21
+ #include <micro-os-plus/architecture-riscv/declarations.h>
22
+
23
+ #include <micro-os-plus/architecture-riscv/instructions.h>
24
+ #include <micro-os-plus/architecture-riscv/instructions-inlines.h>
25
+
26
+ #include <micro-os-plus/architecture-riscv/csr-functions.h>
27
+ #include <micro-os-plus/architecture-riscv/csr-functions-inlines.h>
28
+
29
+ #include <micro-os-plus/architecture-riscv/core-functions.h>
30
+ #include <micro-os-plus/architecture-riscv/core-functions-inlines.h>
31
+
32
+ #include <micro-os-plus/architecture-riscv/semihosting-inlines.h>
33
+
34
+ // ----------------------------------------------------------------------------
35
+
36
+ #endif // MICRO_OS_PLUS_ARCHITECTURE_H_
37
+
38
+ // ----------------------------------------------------------------------------
@@ -0,0 +1,7 @@
1
+ # linker-scripts
2
+
3
+ Generic architecture scripts.
4
+
5
+ The configuration running from RAM is intended for the QEMU `virt` machine.
6
+
7
+ May be re-defined at specific device level.