1/* $NetBSD: vmparam.h,v 1.14.8.2 2026/06/03 18:17:02 martin Exp $ */
2
3/*-
4 * Copyright (c) 2014, 2020 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Matt Thomas of 3am Software Foundry, and Nick Hudson.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#ifndef _RISCV_VMPARAM_H_
33#define _RISCV_VMPARAM_H_
34
35#include <riscv/param.h>
36
37#ifdef _KERNEL_OPT
38#include "opt_multiprocessor.h"
39#endif
40
41/*
42 * Machine dependent VM constants for RISCV.
43 */
44
45/*
46 * We use a 4K page on both RV64 and RV32 systems.
47 * Override PAGE_* definitions to compile-time constants.
48 */
49#define PAGE_SHIFT PGSHIFT
50#define PAGE_SIZE (1 << PAGE_SHIFT)
51#define PAGE_MASK (PAGE_SIZE - 1)
52
53#ifdef _LP64
54/*
55 * Default pager_map of 16MB is awfully small. There is plenty
56 * of VA so use it.
57 */
58#define PAGER_MAP_DEFAULT_SIZE (512 * 1024 * 1024)
59
60/*
61 * Defaults for Unified Buffer Cache parameters.
62 */
63
64#ifndef UBC_WINSHIFT
65#define UBC_WINSHIFT 16 /* 64kB */
66#endif
67#ifndef UBC_NWINS
68#define UBC_NWINS 4096 /* 256MB */
69#endif
70#endif
71
72/*
73 * USRSTACK is the top (end) of the user stack.
74 *
75 * USRSTACK needs to start a page below the maxuser address so that a memory
76 * access with a maximum displacement (0x7ff) won't cross into the kernel's
77 * address space. We use PAGE_SIZE instead of 0x800 since these need to be
78 * page-aligned.
79 */
80#define USRSTACK (VM_MAXUSER_ADDRESS - PAGE_SIZE) /* Start of user stack */
81#define USRSTACK32 ((uint32_t)VM_MAXUSER_ADDRESS32 - PAGE_SIZE)
82
83/*
84 * Virtual memory related constants, all in bytes
85 */
86#ifndef MAXTSIZ
87#define MAXTSIZ (128*1024*1024) /* max text size */
88#endif
89#ifndef DFLDSIZ
90#define DFLDSIZ (256*1024*1024) /* initial data size limit */
91#endif
92#ifndef MAXDSIZ
93#define MAXDSIZ (1536*1024*1024) /* max data size */
94#endif
95#ifndef DFLSSIZ
96#define DFLSSIZ (4*1024*1024) /* initial stack size limit */
97#endif
98#ifndef MAXSSIZ
99#define MAXSSIZ (120*1024*1024) /* max stack size */
100#endif
101
102/*
103 * Virtual memory related constants, all in bytes
104 */
105#ifndef DFLDSIZ32
106#define DFLDSIZ32 DFLDSIZ /* initial data size limit */
107#endif
108#ifndef MAXDSIZ32
109#define MAXDSIZ32 MAXDSIZ /* max data size */
110#endif
111#ifndef DFLSSIZ32
112#define DFLSSIZ32 DFLTSIZ /* initial stack size limit */
113#endif
114#ifndef MAXSSIZ32
115#define MAXSSIZ32 MAXSSIZ /* max stack size */
116#endif
117
118/*
119 * PTEs for mapping user space into the kernel for phyio operations.
120 * The default PTE number is enough to cover 8 disks * MAXBSIZE.
121 */
122#ifndef USRIOSIZE
123#define USRIOSIZE (MAXBSIZE/PAGE_SIZE * 8)
124#endif
125
126/*
127 * User/kernel map constants.
128 */
129#define VM_MIN_ADDRESS ((vaddr_t)PAGE_SIZE)
130#ifdef _LP64 /* Sv39 / Sv48 / Sv57 */
131/*
132 * SV39 gives 1 << (39 - 1) address space to kernel and same to userland.
133 * This is 256GiB each. Split the kernel space in two and use the top half
134 * for direct map.
135 *
136 * kernel virtual space layout:
137 * 0xffff_ffc0_0000_0000 - 64GiB KERNEL VM Space (inc. text/data/bss)
138 * (0xffff_ffc0_4000_0000 +1GiB) KERNEL VM start of KVA
139 * (0xffff_ffd0_0000_0000 64GiB) reserved
140 * 0xffff_ffe0_0000_0000 - 128GiB direct mapping
141 */
142#define VM_MAXUSER_ADDRESS ((vaddr_t)0x0000004000000000 - 16 * PAGE_SIZE)
143#define VM_MIN_KERNEL_ADDRESS ((vaddr_t)0xffffffc000000000)
144#define VM_MAX_KERNEL_ADDRESS ((vaddr_t)0xffffffd000000000)
145
146#else /* Sv32 */
147
148/*
149 * kernel virtual space layout without direct map (common case)
150 *
151 * 0x8000_0000 - 256MB kernel text/data/bss
152 * 0x9000_0000 - 1536MB Kernel VM Space
153 * 0xf000_0000 - 256MB IO
154 *
155 * kernel virtual space layout with KASAN
156 *
157 * 0x8000_0000 - 256MB kernel text/data/bss
158 * 0x9000_0000 - 768MB Kernel VM Space
159 * 0xc000_0000 - 128MB (KASAN SHADOW MAP)
160 * 0xc800_0000 - 640MB (spare)
161 * 0xf000_0000 - 256MB IO
162 *
163 * kernel virtual space layout with direct map (1GB limited)
164 * 0x8000_0000 - 1024MB kernel text/data/bss and direct map start
165 * 0xc000_0000 - 768MB Kernel VM Space
166 * 0xf000_0000 - 256MB IO
167 *
168 */
169
170#define VM_MAXUSER_ADDRESS ((vaddr_t)-0x7fffffff-1)/* 0xffff_ffff_8000_0000 */
171#define VM_MIN_KERNEL_ADDRESS ((vaddr_t)-0x7fffffff-1)/* 0xffff_ffff_8000_0000 */
172#define VM_MAX_KERNEL_ADDRESS ((vaddr_t)-0x10000000) /* 0xffff_ffff_f000_0000 */
173
174#endif
175
176#define VM_KERNEL_BASE VM_MIN_KERNEL_ADDRESS
177#define VM_KERNEL_SIZE 0x2000000 /* 32 MiB (8 / 16 megapages) */
178#define VM_KERNEL_DTB_BASE (VM_KERNEL_BASE + VM_KERNEL_SIZE)
179#define VM_KERNEL_DTB_SIZE 0x1000000 /* 16 MiB (4 / 8 megapages) */
180#define VM_KERNEL_IO_BASE (VM_KERNEL_DTB_BASE + VM_KERNEL_DTB_SIZE)
181#define VM_KERNEL_IO_SIZE 0x1000000 /* 16 MiB (4 / 8 megapages) */
182
183#define VM_KERNEL_RESERVED (VM_KERNEL_SIZE + VM_KERNEL_DTB_SIZE + VM_KERNEL_IO_SIZE)
184
185#define VM_KERNEL_VM_BASE (VM_MIN_KERNEL_ADDRESS + VM_KERNEL_RESERVED)
186#define VM_KERNEL_VM_SIZE (VM_MAX_KERNEL_ADDRESS - VM_KERNEL_VM_BASE)
187
188#define VM_MAX_ADDRESS VM_MAXUSER_ADDRESS
189#define VM_MAXUSER_ADDRESS32 ((vaddr_t)(1UL << 31))/* 0x0000000080000000 */
190
191#ifdef _LP64
192/*
193 * Since we have the address space, we map all of physical memory (RAM)
194 * using gigapages on SV39, terapages on SV48 and petapages on SV57.
195 */
196#define RISCV_DIRECTMAP_MASK ((vaddr_t) 0xffffffe000000000L)
197#define RISCV_DIRECTMAP_SIZE (-RISCV_DIRECTMAP_MASK - PAGE_SIZE) /* 128GiB */
198#define RISCV_DIRECTMAP_START RISCV_DIRECTMAP_MASK
199#define RISCV_DIRECTMAP_END (RISCV_DIRECTMAP_START + RISCV_DIRECTMAP_SIZE)
200#define RISCV_DIRECTMAP_P(va) (((vaddr_t) (va) & RISCV_DIRECTMAP_MASK) == RISCV_DIRECTMAP_MASK)
201#define RISCV_PA_TO_KVA(pa) ((vaddr_t) ((pa) | RISCV_DIRECTMAP_START))
202#define RISCV_KVA_TO_PA(va) ((paddr_t) ((va) & ~RISCV_DIRECTMAP_MASK))
203#endif
204
205/*
206 * The address to which unspecified mapping requests default
207 */
208#define __USE_TOPDOWN_VM
209
210#define VM_DEFAULT_ADDRESS_TOPDOWN(da, sz) \
211 trunc_page(USRSTACK - MAXSSIZ - (sz) - user_stack_guard_size)
212#define VM_DEFAULT_ADDRESS_BOTTOMUP(da, sz) \
213 round_page((vaddr_t)(da) + (vsize_t)maxdmap)
214
215#define VM_DEFAULT_ADDRESS32_TOPDOWN(da, sz) \
216 trunc_page(USRSTACK32 - MAXSSIZ32 - (sz) - user_stack_guard_size)
217#define VM_DEFAULT_ADDRESS32_BOTTOMUP(da, sz) \
218 round_page((vaddr_t)(da) + (vsize_t)MAXDSIZ32)
219
220/* virtual sizes (bytes) for various kernel submaps */
221#define VM_PHYS_SIZE (USRIOSIZE*PAGE_SIZE)
222
223/*
224 * max number of non-contig chunks of physical RAM you can have
225 */
226#define VM_PHYSSEG_MAX 64
227
228/*
229 * when converting a physical address to a vm_page structure, we
230 * want to use a binary search on the chunks of physical memory
231 * to find our RAM
232 */
233#define VM_PHYSSEG_STRAT VM_PSTRAT_BSEARCH
234
235#ifndef VM_NFREELIST
236#define VM_NFREELIST 2 /* 2 distinct memory segments */
237#define VM_FREELIST_DEFAULT 0
238#define VM_FREELIST_DIRECTMAP 1
239#endif
240
241#ifdef _KERNEL
242#ifdef _LP64
243void * cpu_uarea_alloc(bool);
244bool cpu_uarea_free(void *);
245#endif
246#endif
247
248#endif /* ! _RISCV_VMPARAM_H_ */