1*52887a38Smpi /* $OpenBSD: uvm_init.c,v 1.42 2021/03/20 10:24:21 mpi Exp $ */
23a40dae1Sart /* $NetBSD: uvm_init.c,v 1.14 2000/06/27 17:29:23 mrg Exp $ */
3cd7ee8acSart
4cd7ee8acSart /*
5cd7ee8acSart * Copyright (c) 1997 Charles D. Cranor and Washington University.
6cd7ee8acSart * All rights reserved.
7cd7ee8acSart *
8cd7ee8acSart * Redistribution and use in source and binary forms, with or without
9cd7ee8acSart * modification, are permitted provided that the following conditions
10cd7ee8acSart * are met:
11cd7ee8acSart * 1. Redistributions of source code must retain the above copyright
12cd7ee8acSart * notice, this list of conditions and the following disclaimer.
13cd7ee8acSart * 2. Redistributions in binary form must reproduce the above copyright
14cd7ee8acSart * notice, this list of conditions and the following disclaimer in the
15cd7ee8acSart * documentation and/or other materials provided with the distribution.
16cd7ee8acSart *
17cd7ee8acSart * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18cd7ee8acSart * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19cd7ee8acSart * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20cd7ee8acSart * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21cd7ee8acSart * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22cd7ee8acSart * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23cd7ee8acSart * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24cd7ee8acSart * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25cd7ee8acSart * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26cd7ee8acSart * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27cd7ee8acSart *
28cd7ee8acSart * from: Id: uvm_init.c,v 1.1.2.3 1998/02/06 05:15:27 chs Exp
29cd7ee8acSart */
30cd7ee8acSart
31cd7ee8acSart /*
32cd7ee8acSart * uvm_init.c: init the vm system.
33cd7ee8acSart */
34cd7ee8acSart
35cd7ee8acSart #include <sys/param.h>
36cd7ee8acSart #include <sys/systm.h>
37cd7ee8acSart #include <sys/filedesc.h>
38627a59d1Smpi #include <sys/percpu.h>
39cd7ee8acSart #include <sys/resourcevar.h>
40cd7ee8acSart #include <sys/mman.h>
41cd7ee8acSart #include <sys/malloc.h>
42cd7ee8acSart #include <sys/vnode.h>
437cfce8f0Sderaadt #include <sys/pool.h>
44cd7ee8acSart
45cd7ee8acSart #include <uvm/uvm.h>
46181c6205Sariane #include <uvm/uvm_addr.h>
47cd7ee8acSart
48cd7ee8acSart /*
49cd7ee8acSart * struct uvm: we store all global vars in this structure to make them
50cd7ee8acSart * easier to spot...
51cd7ee8acSart */
52cd7ee8acSart
53cd7ee8acSart struct uvm uvm; /* decl */
54cd7ee8acSart struct uvmexp uvmexp; /* decl */
55cd7ee8acSart
56627a59d1Smpi COUNTERS_BOOT_MEMORY(uvmexp_countersboot, exp_ncounters);
57627a59d1Smpi struct cpumem *uvmexp_counters = COUNTERS_BOOT_INITIALIZER(uvmexp_countersboot);
58627a59d1Smpi
595de1d0f0Smiod #if defined(VM_MIN_KERNEL_ADDRESS)
605de1d0f0Smiod vaddr_t vm_min_kernel_address = VM_MIN_KERNEL_ADDRESS;
615de1d0f0Smiod #else
625de1d0f0Smiod vaddr_t vm_min_kernel_address;
635de1d0f0Smiod #endif
645de1d0f0Smiod
65cd7ee8acSart /*
66cd7ee8acSart * local prototypes
67cd7ee8acSart */
68cd7ee8acSart
69cd7ee8acSart /*
70cd7ee8acSart * uvm_init: init the VM system. called from kern/init_main.c.
71cd7ee8acSart */
72*52887a38Smpi
73cd7ee8acSart void
uvm_init(void)742023d591Soga uvm_init(void)
75cd7ee8acSart {
76cd7ee8acSart vaddr_t kvm_start, kvm_end;
77cd7ee8acSart
78*52887a38Smpi /*
79*52887a38Smpi * Ensure that the hardware set the page size.
80*52887a38Smpi */
81cd7ee8acSart if (uvmexp.pagesize == 0) {
82cd7ee8acSart panic("uvm_init: page size not set");
83cd7ee8acSart }
84cd7ee8acSart averunnable.fscale = FSCALE;
85cd7ee8acSart
86cd7ee8acSart /*
87*52887a38Smpi * Init the page sub-system. This includes allocating the vm_page
88*52887a38Smpi * structures, and setting up all the page queues (and locks).
89*52887a38Smpi * Available memory will be put in the "free" queue, kvm_start and
90*52887a38Smpi * kvm_end will be set to the area of kernel virtual memory which
91*52887a38Smpi * is available for general use.
92cd7ee8acSart */
93cd7ee8acSart uvm_page_init(&kvm_start, &kvm_end);
94cd7ee8acSart
95cd7ee8acSart /*
96*52887a38Smpi * Init the map sub-system.
97*52887a38Smpi *
98*52887a38Smpi * Allocates the static pool of vm_map_entry structures that are
99*52887a38Smpi * used for "special" kernel maps (e.g. kernel_map, kmem_map, etc...).
100cd7ee8acSart */
101cd7ee8acSart uvm_map_init();
102cd7ee8acSart
103cd7ee8acSart /*
104*52887a38Smpi * Setup the kernel's virtual memory data structures. This includes
105*52887a38Smpi * setting up the kernel_map/kernel_object.
106cd7ee8acSart */
1075de1d0f0Smiod uvm_km_init(vm_min_kernel_address, kvm_start, kvm_end);
108cd7ee8acSart
109cd7ee8acSart /*
1101c7ad6bdSmiod * step 4.5: init (tune) the fault recovery code.
1111c7ad6bdSmiod */
1121c7ad6bdSmiod uvmfault_init();
1131c7ad6bdSmiod
1141c7ad6bdSmiod /*
115*52887a38Smpi * Init the pmap module. The pmap module is free to allocate
116cd7ee8acSart * memory for its private use (e.g. pvlists).
117cd7ee8acSart */
118cd7ee8acSart pmap_init();
119cd7ee8acSart
120cd7ee8acSart /*
12118b79dc7Sdlg * step 6: init uvm_km_page allocator memory.
12218b79dc7Sdlg */
12318b79dc7Sdlg uvm_km_page_init();
12418b79dc7Sdlg
12518b79dc7Sdlg /*
126*52887a38Smpi * Make kernel memory allocators ready for use.
127*52887a38Smpi * After this call the malloc memory allocator can be used.
128cd7ee8acSart */
129cd7ee8acSart kmeminit();
130cd7ee8acSart
131cd7ee8acSart /*
13218b79dc7Sdlg * step 7.5: init the dma allocator, which is backed by pools.
13372570117Sderaadt */
13472570117Sderaadt dma_alloc_init();
13572570117Sderaadt
13672570117Sderaadt /*
137*52887a38Smpi * Init all pagers and the pager_map.
138cd7ee8acSart */
139cd7ee8acSart uvm_pager_init();
140cd7ee8acSart
141cd7ee8acSart /*
14218b79dc7Sdlg * step 9: init anonymous memory system
143cd7ee8acSart */
14435164244Stedu amap_init();
145cd7ee8acSart
146cd7ee8acSart /*
14718b79dc7Sdlg * step 10: start uvm_km_page allocator thread.
1485aad79a8Skurt */
14918b79dc7Sdlg uvm_km_page_lateinit();
1505aad79a8Skurt
1515aad79a8Skurt /*
1527bcb8cc6Soga * the VM system is now up! now that malloc is up we can
1537bcb8cc6Soga * enable paging of kernel objects.
154cd7ee8acSart */
1555de1d0f0Smiod uao_create(VM_KERNEL_SPACE_SIZE, UAO_FLAG_KERNSWAP);
156cd7ee8acSart
157cd7ee8acSart /*
15897bf7b32Smiod * reserve some unmapped space for malloc/pool use after free usage
15997bf7b32Smiod */
16097bf7b32Smiod #ifdef DEADBEEF0
1615ce612feSart kvm_start = trunc_page(DEADBEEF0) - PAGE_SIZE;
16297bf7b32Smiod if (uvm_map(kernel_map, &kvm_start, 3 * PAGE_SIZE,
1631e8cdc2eSderaadt NULL, UVM_UNKNOWN_OFFSET, 0, UVM_MAPFLAG(PROT_NONE,
16415cd8707Sguenther PROT_NONE, MAP_INHERIT_NONE, MADV_RANDOM, UVM_FLAG_FIXED)))
165859d5ed4Skrw panic("uvm_init: cannot reserve dead beef @0x%x", DEADBEEF0);
16697bf7b32Smiod #endif
16797bf7b32Smiod #ifdef DEADBEEF1
1685ce612feSart kvm_start = trunc_page(DEADBEEF1) - PAGE_SIZE;
16997bf7b32Smiod if (uvm_map(kernel_map, &kvm_start, 3 * PAGE_SIZE,
1701e8cdc2eSderaadt NULL, UVM_UNKNOWN_OFFSET, 0, UVM_MAPFLAG(PROT_NONE,
17115cd8707Sguenther PROT_NONE, MAP_INHERIT_NONE, MADV_RANDOM, UVM_FLAG_FIXED)))
172859d5ed4Skrw panic("uvm_init: cannot reserve dead beef @0x%x", DEADBEEF1);
17397bf7b32Smiod #endif
17497bf7b32Smiod /*
175*52887a38Smpi * Init anonymous memory systems.
176cd7ee8acSart */
1778d0b5bafSpedro uvm_anon_init();
178181c6205Sariane
17959399f65Sariane #ifndef SMALL_KERNEL
180181c6205Sariane /*
181181c6205Sariane * Switch kernel and kmem_map over to a best-fit allocator,
182181c6205Sariane * instead of walking the tree.
183181c6205Sariane */
184181c6205Sariane uvm_map_set_uaddr(kernel_map, &kernel_map->uaddr_any[3],
185181c6205Sariane uaddr_bestfit_create(vm_map_min(kernel_map),
186181c6205Sariane vm_map_max(kernel_map)));
187181c6205Sariane uvm_map_set_uaddr(kmem_map, &kmem_map->uaddr_any[3],
188181c6205Sariane uaddr_bestfit_create(vm_map_min(kmem_map),
189181c6205Sariane vm_map_max(kmem_map)));
19059399f65Sariane #endif /* !SMALL_KERNEL */
191cd7ee8acSart }
192627a59d1Smpi
193627a59d1Smpi void
uvm_init_percpu(void)194627a59d1Smpi uvm_init_percpu(void)
195627a59d1Smpi {
196627a59d1Smpi uvmexp_counters = counters_alloc_ncpus(uvmexp_counters, exp_ncounters);
197627a59d1Smpi }
198