1# Copyright (c) 2016 Jean-Paul Etienne <fractalclone@gmail.com>
2# Copyright (c) 2024 Antmicro <www.antmicro.com>
3# SPDX-License-Identifier: Apache-2.0
4
5menu "RISCV Options"
6	depends on RISCV
7
8config ARCH
9	string
10	default "riscv"
11
12config FLOAT_HARD
13	bool "Hard-float calling convention"
14	default y
15	depends on FPU
16	help
17	  This option enables the hard-float calling convention.
18
19choice RISCV_GP_PURPOSE
20	prompt "Purpose of the global pointer (GP) register"
21	default RISCV_GP if RISCV_SOC_HAS_GP_RELATIVE_ADDRESSING
22
23config RISCV_GP
24	bool "RISC-V global pointer relative addressing"
25	depends on RISCV_SOC_HAS_GP_RELATIVE_ADDRESSING
26	help
27	  Use global pointer relative addressing for small globals declared
28	  anywhere in the executable. It can benefit performance and reduce
29	  the code size.
30
31	  Note: To support this feature, RISC-V SoC needs to initialize
32	  global pointer at program start or earlier than any instruction
33	  using GP relative addressing.
34
35config RISCV_CURRENT_VIA_GP
36	bool "Store current thread into the global pointer (GP) register"
37	depends on MP_MAX_NUM_CPUS > 1
38	select ARCH_HAS_CUSTOM_CURRENT_IMPL
39	help
40	  Store the current thread's pointer into the global pointer (GP) register.
41	  When is enabled, calls to `_current` & `k_sched_current_thread_query()` will
42	  be reduced to a single register read.
43
44endchoice # RISCV_GP_PURPOSE
45
46config RISCV_ALWAYS_SWITCH_THROUGH_ECALL
47	bool "Do not use mret outside a trap handler context"
48	depends on MULTITHREADING
49	help
50	  Use mret instruction only when in a trap handler.
51	  This is for RISC-V implementations that require every mret to be
52	  balanced with an ecall. This is not required by the RISC-V spec
53	  and most people should say n here to minimize context switching
54	  overhead.
55
56choice RISCV_SMP_IPI_IMPL
57	prompt "RISC-V SMP IPI implementation"
58	depends on SMP
59	default RISCV_SMP_IPI_CLINT if DT_HAS_SIFIVE_CLINT0_ENABLED
60	default RISCV_SMP_IPI_CUSTOM
61
62config RISCV_SMP_IPI_CLINT
63	bool "CLINT-based IPI"
64	depends on DT_HAS_SIFIVE_CLINT0_ENABLED
65	help
66	  Use CLINT-based IPI implementation.
67
68config RISCV_SMP_IPI_CUSTOM
69	bool "Custom IPI implementation"
70	help
71	  Allow custom IPI implementation.
72
73	  When this is selected, the following functions must be provided:
74	   - arch_sched_directed_ipi()
75	   - arch_flush_fpu_ipi() if CONFIG_FPU_SHARING
76	   - arch_spin_relax() if CONFIG_FPU_SHARING
77	   - arch_smp_init()
78
79endchoice # RISCV_SMP_IPI_IMPL
80
81menu "RISCV Processor Options"
82
83config INCLUDE_RESET_VECTOR
84	bool "Jumps to __initialize directly"
85	help
86	  Select 'y' here to use the Zephyr provided default implementation that
87	  jumps to `__initialize` directly. Otherwise a SOC needs to provide its
88	  custom `__reset` routine.
89
90config RISCV_PRIVILEGED
91	bool
92	select ARCH_HAS_RAMFUNC_SUPPORT if XIP
93	help
94	  Option selected by SoCs implementing the RISC-V privileged ISA.
95
96config RISCV_SOC_HAS_ISR_STACKING
97	bool
98	depends on !USERSPACE
99	help
100	  Enable low-level SOC-specific hardware stacking / unstacking
101	  operations during ISR. This hidden option needs to be selected by SoC
102	  if this feature is supported.
103
104	  Some SOCs implement a mechanism for which, on interrupt handling,
105	  part of the context is automatically saved by the hardware on the
106	  stack according to a custom ESF format. The same part of the context
107	  is automatically restored by hardware on mret.
108
109	  Enabling this option requires that the SoC provides a
110	  soc_isr_stacking.h header which defines the following:
111
112	  - SOC_ISR_SW_STACKING: macro guarded by _ASMLANGUAGE called by the
113	    IRQ wrapper assembly code on ISR entry to save in the ESF the
114	    remaining part of the context not pushed already on the stack by
115	    the hardware.
116
117	  - SOC_ISR_SW_UNSTACKING: macro guarded by _ASMLANGUAGE called by the
118	    IRQ wrapper assembly code on ISR exit to restore the part of the
119	    context from the ESF that won't be restored by hardware on mret.
120
121	  - SOC_ISR_STACKING_ESF_DECLARE: structure declaration for the ESF
122	    guarded by !_ASMLANGUAGE. The ESF should be defined to account for
123	    the hardware stacked registers in the proper order as they are
124	    saved on the stack by the hardware, and the registers saved by the
125	    software macros. The structure must be called 'struct arch_esf'.
126
127	  - SOC_ISR_STACKING_ESR_INIT: macro guarded by !_ASMLANGUAGE.
128	    Some hardware stacked registers should be initialized on init
129	    stack with proper values. This prevents from incorrect behavior
130	    on entry context switch when initial stack is restored.
131
132config RISCV_SOC_HAS_CUSTOM_IRQ_HANDLING
133	bool
134	help
135	  This allows the SoC to overwrite the irq handling. If enabled, the
136	  function __soc_handle_all_irqs has to be implemented. It shall service
137	  and clear all pending interrupts.
138
139config RISCV_SOC_HAS_CUSTOM_IRQ_LOCK_OPS
140	bool
141	help
142	  Hidden option to allow SoC to overwrite arch_irq_lock(),
143	  arch_irq_unlock() and arch_irq_unlocked() functions with
144	  platform-specific versions named z_soc_irq_lock(), z_soc_irq_unlock()
145	  and z_soc_irq_unlocked().
146
147	  Enable this hidden option and specialize the z_soc_* functions when
148	  the RISC-V SoC needs to do something different and more than reading and
149	  writing the mstatus register to lock and unlock the IRQs.
150
151config RISCV_SOC_HAS_CUSTOM_SYS_IO
152	bool
153	help
154	  Hidden option to allow SoC to overwrite sys_read*(), sys_write*() functions with
155	  platform-specific versions named z_soc_sys_read*() and z_soc_sys_write*().
156
157	  Enable this hidden option and specialize the z_soc_* functions when
158	  the RISC-V SoC needs to do something different and more than reading and
159	  writing the registers.
160
161config RISCV_SOC_HAS_GP_RELATIVE_ADDRESSING
162	bool
163	help
164	  Selected when SoC has implemented the initialization of global pointer (GP)
165	  at program start, or earlier than any instruction using GP relative addressing.
166
167config RISCV_SOC_CONTEXT_SAVE
168	bool "SOC-based context saving in IRQ handlers"
169	select RISCV_SOC_OFFSETS
170	help
171	  Enable low-level SOC-specific context management, for SOCs
172	  with extra state that must be saved when entering an
173	  interrupt/exception, and restored on exit. If unsure, leave
174	  this at the default value.
175
176	  Enabling this option requires that the SoC provide a
177	  soc_context.h header which defines the following macros:
178
179	  - SOC_ESF_MEMBERS: structure component declarations to
180	    allocate space for. The last such declaration should not
181	    end in a semicolon, for portability. The generic RISC-V
182	    architecture code will allocate space for these members in
183	    a "struct soc_esf" type (typedefed to soc_esf_t), which will
184	    be available if arch.h is included.
185
186	  - SOC_ESF_INIT: structure contents initializer for struct soc_esf
187	    state. The last initialized member should not end in a comma.
188
189	  The generic architecture IRQ wrapper will also call
190	  \_\_soc_save_context and \_\_soc_restore_context routines at
191	  ISR entry and exit, respectively. These should typically
192	  be implemented in assembly. If they were C functions, they
193	  would have these signatures:
194
195	  ``void __soc_save_context(soc_esf_t *state);``
196
197	  ``void __soc_restore_context(soc_esf_t *state);``
198
199	  The calls obey standard calling conventions; i.e., the state
200	  pointer address is in a0, and ra contains the return address.
201
202config RISCV_SOC_OFFSETS
203	bool "SOC-based offsets"
204	help
205	  Enabling this option requires that the SoC provide a soc_offsets.h
206	  header which defines the following macros:
207
208	  - GEN_SOC_OFFSET_SYMS(): a macro which expands to
209	    GEN_OFFSET_SYM(soc_esf_t, soc_specific_member) calls
210	    to ensure offset macros for SOC_ESF_MEMBERS are defined
211	    in offsets.h. The last one should not end in a semicolon.
212	    See gen_offset.h for more details.
213
214config RISCV_HAS_PLIC
215	bool
216	depends on RISCV_PRIVILEGED
217	help
218	  Does the SOC provide support for a Platform Level Interrupt Controller (PLIC).
219
220config RISCV_HAS_CLIC
221	bool
222	depends on RISCV_PRIVILEGED
223	select RISCV_ALWAYS_SWITCH_THROUGH_ECALL if MULTITHREADING
224	select CLIC_SUPPORT_INTERRUPT_LEVEL if !NRFX_CLIC
225	help
226	  Does the SOC provide support for a Core-Local Interrupt Controller (CLIC).
227
228config CLIC_SUPPORT_INTERRUPT_LEVEL
229	bool
230	depends on RISCV_HAS_CLIC
231	help
232	  For CLIC implementations with extended interrupt level, where
233	  higher-numbered interrupt levels can preempt lower-numbered interrupt
234	  levels. This option handles interrupt level in ISR to ensure proper
235	  nested ISR exits.
236
237config RISCV_SOC_EXCEPTION_FROM_IRQ
238	bool
239	help
240	  Option selected by SoCs that require a custom mechanism to check if
241	  an exception is the result of an interrupt or not. If selected,
242	  __soc_is_irq() needs to be implemented by the SoC.
243
244config RISCV_SOC_INTERRUPT_INIT
245	bool "SOC-based interrupt initialization"
246	help
247	  Enable SOC-based interrupt initialization
248	  (call soc_interrupt_init, within _IntLibInit when enabled)
249
250config RISCV_MCAUSE_EXCEPTION_MASK
251	hex
252	default 0x7FFFFFFFFFFFFFFF if 64BIT
253	default 0x7FFFFFFF
254	help
255	  Specify the bits to use for exception code in mcause register.
256
257config RISCV_GENERIC_TOOLCHAIN
258	bool "Compile using generic riscv32 toolchain"
259	default y
260	help
261	  Compile using generic riscv32 toolchain.
262	  Allow SOCs that have custom extended riscv ISA to still
263	  compile with generic riscv32 toolchain.
264
265config GEN_ISR_TABLES
266	default y
267
268config GEN_IRQ_VECTOR_TABLE
269	default n
270
271config RISCV_RESERVED_IRQ_ISR_TABLES_OFFSET
272	int
273	default 0
274	depends on GEN_ISR_TABLES
275	help
276	  On some RISCV platform the first interrupt vectors are primarly
277	  intended for inter-hart interrupt signaling and so retained for that
278	  purpose and not available. When this option is set, all the IRQ
279	  vectors are shifted by this offset value when installed into the
280	  software ISR table and the IRQ vector table. CONFIG_NUM_IRQS must be
281	  properly sized to take into account this offset. This is a hidden
282	  option which needs to be set per architecture and left alone.
283
284config NUM_IRQS
285	int
286
287config RV_BOOT_HART
288	int "Starting HART ID"
289	default 0
290	help
291	  This option sets the starting HART ID for the SMP core.
292	  For RISC-V systems such as MPFS and FU540 this would be set to 1 to
293	  skip the E51 HART 0 as it is not usable in SMP configurations.
294
295config RISCV_HART_MASK
296	int
297	default -1
298	help
299	  Configures the mask for the HART ID.
300	  For RISC-V systems with HART ID starting from non-zero value,
301	  i.e. 128, 129, ..(0x80, 8x81, ..), this can be configured to 63 (0x7f)
302	  such that we can extract the bits that start from 0.
303
304config EXTRA_EXCEPTION_INFO
305	bool "Collect extra exception info"
306	depends on EXCEPTION_DEBUG
307	help
308	  This option enables the collection of extra information, such as
309	  register state, when a fault occurs. This information can be useful
310	  to collect for post-mortem analysis and debug of issues.
311
312config RISCV_PMP
313	bool "RISC-V PMP Support"
314	select THREAD_STACK_INFO
315	select CPU_HAS_MPU
316	select ARCH_HAS_USERSPACE
317	select ARCH_HAS_STACK_PROTECTION
318	select MPU
319	select SRAM_REGION_PERMISSIONS
320	select ARCH_MEM_DOMAIN_SYNCHRONOUS_API if USERSPACE
321	select ARCH_MEM_DOMAIN_DATA if USERSPACE
322	select THREAD_LOCAL_STORAGE if USERSPACE
323	select ARCH_MEM_DOMAIN_SUPPORTS_ISOLATED_STACKS
324	select MEM_DOMAIN_ISOLATED_STACKS
325	help
326	  MCU implements Physical Memory Protection.
327
328if RISCV_PMP
329
330config PMP_SLOTS
331	int "Number of PMP slots"
332	default 8
333	help
334	  This is the number of PMP entries implemented by the hardware.
335	  Typical values are 8 or 16.
336
337config PMP_NO_TOR
338	bool
339	help
340	  Set this if TOR (Top Of Range) mode is not supported.
341
342config PMP_NO_NA4
343	bool
344	help
345	  Set this if NA4 (Naturally Aligned 4-byte) mode is not supported.
346
347config PMP_NO_NAPOT
348	bool
349	help
350	  Set this if NAPOT (Naturally Aligned Power Of Two) is not supported.
351
352config PMP_POWER_OF_TWO_ALIGNMENT
353	bool "Enforce power-of-two alignment on PMP memory areas" if !PMP_NO_TOR
354	default y if TEST_USERSPACE
355	default y if (PMP_SLOTS = 8)
356	default y if PMP_NO_TOR
357	select MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT
358	select GEN_PRIV_STACKS
359	help
360	  This option reduces the PMP slot usage but increases
361	  memory consumption. Useful when enabling userspace mode with
362	  many memory domains and/or few PMP slots available.
363
364config PMP_GRANULARITY
365	int "The granularity of PMP address matching"
366	default 8 if (PMP_NO_TOR && PMP_NO_NA4)
367	default 4
368	help
369	  The granularity must be a power of 2 greater than or equal to 4
370	  (ie 4, 8, 16, ...), but if neither TOR mode nor NA4 mode is
371	  supported, the minimum granularity is 8.
372
373endif #RISCV_PMP
374
375config PMP_STACK_GUARD
376	def_bool y
377	depends on HW_STACK_PROTECTION
378
379config PMP_STACK_GUARD_MIN_SIZE
380	int "Stack Guard area size"
381	depends on PMP_STACK_GUARD
382	default 1024 if 64BIT
383	default 512
384	help
385	  The Hardware Stack Protection implements a guard area at the bottom
386	  of the stack using the PMP to catch stack overflows by marking that
387	  guard area not accessible.
388
389	  This is the size of the guard area. This should be large enough to
390	  catch any sudden jump in stack pointer decrement, plus some
391	  wiggle room to accommodate the eventual overflow exception
392	  stack usage.
393
394# Implement the null pointer detection using the Physical Memory Protection
395# (PMP) Unit.
396config NULL_POINTER_EXCEPTION_DETECTION_PMP
397	bool "Use PMP for null pointer exception detection"
398	depends on RISCV_PMP
399	help
400	  Null pointer dereference detection implemented
401	  using PMP functionality.
402
403if NULL_POINTER_EXCEPTION_DETECTION_PMP
404
405config NULL_POINTER_EXCEPTION_REGION_SIZE
406	hex "Inaccessible region to implement null pointer detection"
407	default 0x10
408	help
409	  Use a PMP slot to make region (starting at address 0x0) inaccessible for
410	  detecting null pointer dereferencing (raising a CPU access fault).
411	  Minimum is 4 bytes.
412
413endif # NULL_POINTER_EXCEPTION_DETECTION_PMP
414
415config RISCV_IMPRECISE_FPU_STATE_TRACKING
416	bool "Imprecise implementation of FPU state tracking"
417	depends on FPU
418	help
419	  According to the RISC-V Instruction Set Manual: Volume II, Version 20240411
420	  (Section 3.1.6.6), some implementations may choose to track the dirtiness of
421	  the floating-point register state imprecisely by reporting the state to be
422	  dirty even when it has not been modified. This option reflects that.
423
424endmenu
425
426config MAIN_STACK_SIZE
427	default 4096 if 64BIT
428	default 2048 if PMP_STACK_GUARD
429
430config TEST_EXTRA_STACK_SIZE
431	default 1536
432
433config CMSIS_THREAD_MAX_STACK_SIZE
434	default 1024 if 64BIT
435
436config CMSIS_V2_THREAD_MAX_STACK_SIZE
437	default 1024 if 64BIT
438
439config ARCH_IRQ_VECTOR_TABLE_ALIGN
440	default 256
441
442config RISCV_TRAP_HANDLER_ALIGNMENT
443	int "Alignment of RISC-V trap handler in bytes"
444	default 64 if RISCV_HAS_CLIC
445	default 4
446	help
447	  This value configures the alignment of RISC-V trap handling
448	  code. The requirement for a particular alignment arises from
449	  the format of MTVEC register which is RISC-V platform-specific.
450	  The minimum alignment is 4 bytes according to the Spec.
451
452config GEN_IRQ_VECTOR_TABLE
453	select RISCV_VECTORED_MODE if RISCV_PRIVILEGED
454
455config ARCH_HAS_SINGLE_THREAD_SUPPORT
456	default y if !SMP
457
458config ARCH_HAS_STACKWALK
459	bool
460	default y
461	imply THREAD_STACK_INFO
462	help
463	  Internal config to indicate that the arch_stack_walk() API is implemented
464	  and it can be enabled.
465
466rsource "Kconfig.isa"
467
468endmenu
469