|  | # 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 | 
|  |  | 
|  | menu "MMU Features" | 
|  |  | 
|  | config MMU | 
|  | bool | 
|  | 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 | 
|  | endmenu | 
|  |  | 
|  | 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 |