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