vm_init.c revision 127869
133965Sjdp/* 278828Sobrien * Copyright (c) 1991, 1993 378828Sobrien * The Regents of the University of California. All rights reserved. 4213274Srpaulo * 5213274Srpaulo * This code is derived from software contributed to Berkeley by 633965Sjdp * The Mach Operating System project at Carnegie-Mellon University. 778828Sobrien * 878828Sobrien * Redistribution and use in source and binary forms, with or without 978828Sobrien * modification, are permitted provided that the following conditions 1078828Sobrien * are met: 1178828Sobrien * 1. Redistributions of source code must retain the above copyright 1278828Sobrien * notice, this list of conditions and the following disclaimer. 1378828Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1478828Sobrien * notice, this list of conditions and the following disclaimer in the 1578828Sobrien * documentation and/or other materials provided with the distribution. 1678828Sobrien * 3. All advertising materials mentioning features or use of this software 1778828Sobrien * must display the following acknowledgement: 1878828Sobrien * This product includes software developed by the University of 19213274Srpaulo * California, Berkeley and its contributors. 2078828Sobrien * 4. Neither the name of the University nor the names of its contributors 2133965Sjdp * may be used to endorse or promote products derived from this software 2233965Sjdp * without specific prior written permission. 2333965Sjdp * 2433965Sjdp * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2533965Sjdp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2633965Sjdp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2733965Sjdp * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2833965Sjdp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2933965Sjdp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3033965Sjdp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3133965Sjdp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3233965Sjdp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3333965Sjdp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3433965Sjdp * SUCH DAMAGE. 3533965Sjdp * 3633965Sjdp * from: @(#)vm_init.c 8.1 (Berkeley) 6/11/93 3733965Sjdp * 3833965Sjdp * 3933965Sjdp * Copyright (c) 1987, 1990 Carnegie-Mellon University. 4033965Sjdp * All rights reserved. 4133965Sjdp * 4233965Sjdp * Authors: Avadis Tevanian, Jr., Michael Wayne Young 4333965Sjdp * 4433965Sjdp * Permission to use, copy, modify and distribute this software and 4533965Sjdp * its documentation is hereby granted, provided that both the copyright 4633965Sjdp * notice and this permission notice appear in all copies of the 4733965Sjdp * software, derivative works or modified versions, and any portions 4833965Sjdp * thereof, and that both notices appear in supporting documentation. 4933965Sjdp * 5033965Sjdp * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 5133965Sjdp * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 5233965Sjdp * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 5333965Sjdp * 5433965Sjdp * Carnegie Mellon requests users of this software to return to 5533965Sjdp * 5633965Sjdp * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 5733965Sjdp * School of Computer Science 5833965Sjdp * Carnegie Mellon University 5933965Sjdp * Pittsburgh PA 15213-3890 6033965Sjdp * 61213274Srpaulo * any improvements or extensions that they make and grant Carnegie the 62213274Srpaulo * rights to redistribute these changes. 6333965Sjdp */ 6433965Sjdp 6533965Sjdp/* 6633965Sjdp * Initialize the Virtual Memory subsystem. 67213274Srpaulo */ 68213274Srpaulo 69213274Srpaulo#include <sys/cdefs.h> 70213274Srpaulo__FBSDID("$FreeBSD: head/sys/vm/vm_init.c 127869 2004-04-05 00:37:50Z alc $"); 71213274Srpaulo 72213274Srpaulo#include <sys/param.h> 73213274Srpaulo#include <sys/kernel.h> 7489857Sobrien#include <sys/lock.h> 7533965Sjdp#include <sys/mutex.h> 7633965Sjdp#include <sys/proc.h> 7733965Sjdp#include <sys/systm.h> 7833965Sjdp#include <sys/selinfo.h> 7933965Sjdp#include <sys/pipe.h> 8033965Sjdp#include <sys/bio.h> 8133965Sjdp#include <sys/buf.h> 8277298Sobrien 8333965Sjdp#include <vm/vm.h> 8433965Sjdp#include <vm/vm_param.h> 8533965Sjdp#include <vm/vm_kern.h> 8633965Sjdp#include <vm/vm_object.h> 8789857Sobrien#include <vm/vm_page.h> 8889857Sobrien#include <vm/vm_map.h> 8989857Sobrien#include <vm/vm_pager.h> 9089857Sobrien#include <vm/vm_extern.h> 9189857Sobrien 9289857Sobrienlong physmem; 9389857Sobrien 9489857Sobrien/* 9589857Sobrien * System initialization 96213274Srpaulo */ 97213274Srpaulostatic void vm_mem_init(void *); 9833965SjdpSYSINIT(vm_mem, SI_SUB_VM, SI_ORDER_FIRST, vm_mem_init, NULL) 9933965Sjdp 10033965Sjdp/* 10133965Sjdp * vm_init initializes the virtual memory system. 10233965Sjdp * This is done only by the first cpu up. 10333965Sjdp * 10433965Sjdp * The start and end address of physical memory is passed in. 10533965Sjdp */ 10633965Sjdp/* ARGSUSED*/ 10733965Sjdpstatic void 10833965Sjdpvm_mem_init(dummy) 109213274Srpaulo void *dummy; 11033965Sjdp{ 11189857Sobrien /* 11233965Sjdp * Initializes resident memory structures. From here on, all physical 11333965Sjdp * memory is accounted for, and we use only virtual addresses. 11433965Sjdp */ 11533965Sjdp vm_set_page_size(); 11633965Sjdp virtual_avail = vm_page_startup(virtual_avail); 117213274Srpaulo 118213274Srpaulo /* 119213274Srpaulo * Initialize other VM packages 120213274Srpaulo */ 121213274Srpaulo vm_object_init(); 122213274Srpaulo vm_map_startup(); 123213274Srpaulo kmem_init(virtual_avail, virtual_end); 124213274Srpaulo pmap_init(); 125213274Srpaulo vm_pager_init(); 126213274Srpaulo} 127213274Srpaulo 128213274Srpaulovoid 129213274Srpaulovm_ksubmap_init(struct kva_md_info *kmi) 130213274Srpaulo{ 131213274Srpaulo vm_offset_t firstaddr; 132213274Srpaulo caddr_t v; 13333965Sjdp vm_size_t size = 0; 13433965Sjdp long physmem_est; 13560484Sobrien vm_offset_t minaddr; 13633965Sjdp vm_offset_t maxaddr; 13733965Sjdp vm_map_t clean_map; 13833965Sjdp 13960484Sobrien /* 14060484Sobrien * Allocate space for system data structures. 14160484Sobrien * The first available kernel virtual address is in "v". 14260484Sobrien * As pages of kernel virtual memory are allocated, "v" is incremented. 14333965Sjdp * As pages of memory are allocated and cleared, 14433965Sjdp * "firstaddr" is incremented. 14533965Sjdp * An index into the kernel page table corresponding to the 14677298Sobrien * virtual memory address maintained in "v" is kept in "mapaddr". 14777298Sobrien */ 14877298Sobrien 14933965Sjdp /* 15033965Sjdp * Make two passes. The first pass calculates how much memory is 15133965Sjdp * needed and allocates it. The second pass assigns virtual 152213274Srpaulo * addresses to the various data structures. 153213274Srpaulo */ 154213274Srpaulo firstaddr = 0; 155213274Srpauloagain: 156213274Srpaulo v = (caddr_t)firstaddr; 157213274Srpaulo 158213274Srpaulo v = kern_timeout_callwheel_alloc(v); 159213274Srpaulo 160213274Srpaulo /* 161213274Srpaulo * Discount the physical memory larger than the size of kernel_map 162213274Srpaulo * to avoid eating up all of KVA space. 163213274Srpaulo */ 164213274Srpaulo if (kernel_map->first_free == NULL) { 165213274Srpaulo printf("Warning: no free entries in kernel_map.\n"); 166213274Srpaulo physmem_est = physmem; 167213274Srpaulo } else { 168213274Srpaulo physmem_est = lmin(physmem, btoc(kernel_map->max_offset - 169213274Srpaulo kernel_map->min_offset)); 170213274Srpaulo } 171213274Srpaulo 172213274Srpaulo v = kern_vfs_bio_buffer_alloc(v, physmem_est); 173213274Srpaulo 17433965Sjdp /* 17533965Sjdp * End of first pass, size has been calculated so allocate memory 17633965Sjdp */ 17733965Sjdp if (firstaddr == 0) { 17833965Sjdp size = (vm_size_t)v; 17933965Sjdp firstaddr = kmem_alloc(kernel_map, round_page(size)); 18033965Sjdp if (firstaddr == 0) 18133965Sjdp panic("startup: no room for tables"); 18233965Sjdp goto again; 18333965Sjdp } 18433965Sjdp 18533965Sjdp /* 18633965Sjdp * End of second pass, addresses have been assigned 18733965Sjdp */ 18833965Sjdp if ((vm_size_t)((char *)v - firstaddr) != size) 18933965Sjdp panic("startup: table size inconsistency"); 19033965Sjdp 19133965Sjdp clean_map = kmem_suballoc(kernel_map, &kmi->clean_sva, &kmi->clean_eva, 19233965Sjdp (nbuf*BKVASIZE) + (nswbuf*MAXPHYS) + pager_map_size); 19333965Sjdp buffer_map = kmem_suballoc(clean_map, &kmi->buffer_sva, 19433965Sjdp &kmi->buffer_eva, (nbuf*BKVASIZE)); 19533965Sjdp buffer_map->system_map = 1; 19633965Sjdp pager_map = kmem_suballoc(clean_map, &kmi->pager_sva, &kmi->pager_eva, 19733965Sjdp (nswbuf*MAXPHYS) + pager_map_size); 19833965Sjdp pager_map->system_map = 1; 199213274Srpaulo exec_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr, 20033965Sjdp (16*(ARG_MAX+(PAGE_SIZE*3)))); 20133965Sjdp pipe_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr, maxpipekva); 20233965Sjdp 20333965Sjdp /* 20433965Sjdp * XXX: Mbuf system machine-specific initializations should 20533965Sjdp * go here, if anywhere. 20633965Sjdp */ 20733965Sjdp 20833965Sjdp /* 20933965Sjdp * Initialize the callouts we just allocated. 21033965Sjdp */ 21133965Sjdp kern_timeout_callwheel_init(); 21233965Sjdp} 21333965Sjdp 21433965Sjdp