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