Loading...
# Copyright (c) 2021 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0

menu "Virtual Memory Support"

config KERNEL_VM_SUPPORT
	bool
	help
	  Hidden option to enable virtual memory Kconfigs.

if KERNEL_VM_SUPPORT

DT_CHOSEN_Z_SRAM := zephyr,sram

config KERNEL_VM_BASE
	hex "Virtual address space base address"
	default $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_SRAM))
	help
	  Define the base of the kernel's address space.

	  By default, this is the same as the DT_CHOSEN_Z_SRAM physical base SRAM
	  address from DTS, in which case RAM will be identity-mapped. Some
	  architectures may require RAM to be mapped in this way; they may have
	  just one RAM region and doing this makes linking much simpler, as
	  at least when the kernel boots all virtual RAM addresses are the same
	  as their physical address (demand paging at runtime may later modify
	  this for non-pinned page frames).

	  Otherwise, if RAM isn't identity-mapped:
	  1. It is the architecture's responsibility to transition the
	  instruction pointer to virtual addresses at early boot before
	  entering the kernel at z_cstart().
	  2. The underlying architecture may impose constraints on the bounds of
	  the kernel's address space, such as not overlapping physical RAM
	  regions if RAM is not identity-mapped, or the virtual and physical
	  base addresses being aligned to some common value (which allows
	  double-linking of paging structures to make the instruction pointer
	  transition simpler).

	  Zephyr does not implement a split address space and if multiple
	  page tables are in use, they all have the same virtual-to-physical
	  mappings (with potentially different permissions).

config KERNEL_VM_OFFSET
	hex "Kernel offset within address space"
	default 0
	help
	  Offset that the kernel image begins within its address space,
	  if this is not the same offset from the beginning of RAM.

	  Some care may need to be taken in selecting this value. In certain
	  build-time cases, or when a physical address cannot be looked up
	  in page tables, the equation:

	      virt = phys + ((KERNEL_VM_BASE + KERNEL_VM_OFFSET) -
	                     (SRAM_BASE_ADDRESS + SRAM_OFFSET))

	  Will be used to convert between physical and virtual addresses for
	  memory that is mapped at boot.

	  This uncommon and is only necessary if the beginning of VM and
	  physical memory have dissimilar alignment.

config KERNEL_VM_SIZE
	hex "Size of kernel address space in bytes"
	default 0x800000
	help
	  Size of the kernel's address space. Constraining this helps control
	  how much total memory can be used for page tables.

	  The difference between KERNEL_VM_BASE and KERNEL_VM_SIZE indicates the
	  size of the virtual region for runtime memory mappings. This is needed
	  for mapping driver MMIO regions, as well as special RAM mapping use-cases
	  such as VSDO pages, memory mapped thread stacks, and anonymous memory
	  mappings. The kernel itself will be mapped in here as well at boot.

	  Systems with very large amounts of memory (such as 512M or more)
	  will want to use a 64-bit build of Zephyr, there are no plans to
	  implement a notion of "high" memory in Zephyr to work around physical
	  RAM size larger than the defined bounds of the virtual address space.

config KERNEL_DIRECT_MAP
	bool "Memory region direct-map support"
	depends on MMU
	help
	  This enables the direct-map support, namely the region can be 1:1
	  mapping between virtual address and physical address.

	  If the specific memory region is in the virtual memory space and
	  there isn't overlap with the existed mappings, it will reserve the
	  region from the virtual memory space and do the mapping, otherwise
	  it will fail. And any attempt across the boundary of the virtual
	  memory space will fail.

	  Note that this is for compatibility and portable apps shouldn't
	  be using it.

endif # KERNEL_VM_SUPPORT

menuconfig MMU
	bool "MMU features"
	depends on CPU_HAS_MMU
	select KERNEL_VM_SUPPORT
	help
	  This option is enabled when the CPU's memory management unit is active
	  and the arch_mem_map() API is available.

if MMU
config MMU_PAGE_SIZE
	hex "Size of smallest granularity MMU page"
	default 0x1000
	help
	  Size of memory pages. Varies per MMU but 4K is common. For MMUs that
	  support multiple page sizes, put the smallest one here.

menuconfig DEMAND_PAGING
	bool "Demand paging [EXPERIMENTAL]"
	depends on ARCH_HAS_DEMAND_PAGING
	help
	  Enable demand paging. Requires architecture support in how the kernel
	  is linked and the implementation of an eviction algorithm and a
	  backing store for evicted pages.

if DEMAND_PAGING
config DEMAND_MAPPING
	bool "Allow on-demand memory mappings"
	depends on ARCH_HAS_DEMAND_MAPPING
	default y
	help
	  When this is enabled, RAM-based memory mappings don't actually
	  allocate memory at mem_map time. They are made to be populated
	  at access time using the demand paging mechanism instead.

config DEMAND_PAGING_ALLOW_IRQ
	bool "Allow interrupts during page-ins/outs"
	help
	  Allow interrupts to be serviced while pages are being evicted or
	  retrieved from the backing store. This is much better for system
	  latency, but any code running in interrupt context that page faults
	  will cause a kernel panic. Such code must work with exclusively pinned
	  code and data pages.

	  The scheduler is still disabled during this operation.

	  If this option is disabled, the page fault servicing logic
	  runs with interrupts disabled for the entire operation. However,
	  ISRs may also page fault.

config DEMAND_PAGING_PAGE_FRAMES_RESERVE
	int "Number of page frames reserved for paging"
	default 32 if !LINKER_GENERIC_SECTIONS_PRESENT_AT_BOOT
	default 0
	help
	  This sets the number of page frames that will be reserved for
	  paging that do not count towards free memory. This is to
	  ensure that there are some page frames available for paging
	  code and data. Otherwise, it would be possible to exhaust
	  all page frames via anonymous memory mappings.

config DEMAND_PAGING_STATS
	bool "Gather Demand Paging Statistics"
	help
	  This enables gathering various statistics related to demand paging,
	  e.g. number of pagefaults. This is useful for tuning eviction
	  algorithms and optimizing backing store.

	  Should say N in production system as this is not without cost.

config DEMAND_PAGING_STATS_USING_TIMING_FUNCTIONS
	bool "Use Timing Functions to Gather Demand Paging Statistics"
	select TIMING_FUNCTIONS_NEED_AT_BOOT
	help
	  Use timing functions to gather various demand paging statistics.

config DEMAND_PAGING_THREAD_STATS
	bool "Gather per Thread Demand Paging Statistics"
	depends on DEMAND_PAGING_STATS
	help
	  This enables gathering per thread statistics related to demand
	  paging.

	  Should say N in production system as this is not without cost.

config DEMAND_PAGING_TIMING_HISTOGRAM
	bool "Gather Demand Paging Execution Timing Histogram"
	depends on DEMAND_PAGING_STATS
	help
	  This gathers the histogram of execution time on page eviction
	  selection, and backing store page in and page out.

	  Should say N in production system as this is not without cost.

config DEMAND_PAGING_TIMING_HISTOGRAM_NUM_BINS
	int "Number of bins (buckets) in Demand Paging Timing Histogram"
	depends on DEMAND_PAGING_TIMING_HISTOGRAM
	default 10
	help
	  Defines the number of bins (buckets) in the histogram used for
	  gathering execution timing information for demand paging.

	  This requires k_mem_paging_eviction_histogram_bounds[] and
	  k_mem_paging_backing_store_histogram_bounds[] to define
	  the upper bounds for each bin. See kernel/statistics.c for
	  information.

endif # DEMAND_PAGING
endif # MMU

config KERNEL_VM_USE_CUSTOM_MEM_RANGE_CHECK
	bool
	help
	  Use custom memory range check functions instead of the generic
	  checks in k_mem_phys_addr() and k_mem_virt_addr().

	  sys_mm_is_phys_addr_in_range() and
	  sys_mm_is_virt_addr_in_range() must be implemented.

endmenu # Virtual Memory Support