]> git.saurik.com Git - apple/xnu.git/blob - osfmk/i386/i386_vm_init.c
xnu-517.tar.gz
[apple/xnu.git] / osfmk / i386 / i386_vm_init.c
1 /*
2 * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25 /*
26 * @OSF_COPYRIGHT@
27 */
28 /*
29 * Mach Operating System
30 * Copyright (c) 1991,1990,1989, 1988 Carnegie Mellon University
31 * All Rights Reserved.
32 *
33 * Permission to use, copy, modify and distribute this software and its
34 * documentation is hereby granted, provided that both the copyright
35 * notice and this permission notice appear in all copies of the
36 * software, derivative works or modified versions, and any portions
37 * thereof, and that both notices appear in supporting documentation.
38 *
39 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
40 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
41 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
42 *
43 * Carnegie Mellon requests users of this software to return to
44 *
45 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
46 * School of Computer Science
47 * Carnegie Mellon University
48 * Pittsburgh PA 15213-3890
49 *
50 * any improvements or extensions that they make and grant Carnegie Mellon
51 * the rights to redistribute these changes.
52 */
53
54 #include <cpus.h>
55 #include <platforms.h>
56 #include <mach_kdb.h>
57 #include <himem.h>
58 #include <fast_idle.h>
59
60 #include <mach/i386/vm_param.h>
61
62 #include <string.h>
63 #include <mach/vm_param.h>
64 #include <mach/vm_prot.h>
65 #include <mach/machine.h>
66 #include <mach/time_value.h>
67 #include <kern/etap_macros.h>
68 #include <kern/spl.h>
69 #include <kern/assert.h>
70 #include <kern/debug.h>
71 #include <kern/misc_protos.h>
72 #include <kern/cpu_data.h>
73 #include <kern/processor.h>
74 #include <vm/vm_page.h>
75 #include <vm/pmap.h>
76 #include <vm/vm_kern.h>
77 #include <i386/pmap.h>
78 #include <i386/ipl.h>
79 #include <i386/pio.h>
80 #include <i386/misc_protos.h>
81 #include <i386/mp_slave_boot.h>
82 #ifdef __MACHO__
83 #include <mach/boot_info.h>
84 #include <mach/thread_status.h>
85 #endif
86
87 vm_size_t mem_size = 0;
88 vm_offset_t first_addr = 0; /* set by start.s - keep out of bss */
89 vm_offset_t first_avail = 0;/* first after page tables */
90 vm_offset_t last_addr;
91
92 uint64_t max_mem;
93 uint64_t sane_size;
94
95 vm_offset_t avail_start, avail_end;
96 vm_offset_t virtual_avail, virtual_end;
97 vm_offset_t hole_start, hole_end;
98 vm_offset_t avail_next;
99 unsigned int avail_remaining;
100
101 /* parameters passed from bootstrap loader */
102 int cnvmem = 0; /* must be in .data section */
103 int extmem = 0;
104
105 #ifndef __MACHO__
106 extern char edata, end;
107 #endif
108
109 #ifdef __MACHO__
110 #include <mach-o/loader.h>
111 vm_offset_t edata, etext, end;
112
113 extern struct mach_header _mh_execute_header;
114 void *sectTEXTB; int sectSizeTEXT;
115 void *sectDATAB; int sectSizeDATA;
116 void *sectOBJCB; int sectSizeOBJC;
117 void *sectLINKB; int sectSizeLINK;
118 void *sectPRELINKB; int sectSizePRELINK;
119
120 #endif
121
122 /*
123 * Basic VM initialization.
124 */
125 void
126 i386_vm_init(unsigned int maxmem, KernelBootArgs_t *args)
127 {
128 int i,j; /* Standard index vars. */
129 vm_size_t bios_hole_size;
130
131 #ifdef __MACHO__
132 /* Now retrieve addresses for end, edata, and etext
133 * from MACH-O headers.
134 */
135
136 sectTEXTB = (void *) getsegdatafromheader(
137 &_mh_execute_header, "__TEXT", &sectSizeTEXT);
138 sectDATAB = (void *) getsegdatafromheader(
139 &_mh_execute_header, "__DATA", &sectSizeDATA);
140 sectOBJCB = (void *) getsegdatafromheader(
141 &_mh_execute_header, "__OBJC", &sectSizeOBJC);
142 sectLINKB = (void *) getsegdatafromheader(
143 &_mh_execute_header, "__LINKEDIT", &sectSizeLINK);
144 sectPRELINKB = (void *) getsegdatafromheader(
145 &_mh_execute_header, "__PRELINK", &sectSizePRELINK);
146
147 etext = (vm_offset_t) sectTEXTB + sectSizeTEXT;
148 edata = (vm_offset_t) sectDATAB + sectSizeDATA;
149 #endif
150 #ifndef __MACHO__
151 /*
152 * Zero the BSS.
153 */
154
155 bzero((char *)&edata,(unsigned)(&end - &edata));
156 #endif
157
158 /* Now copy over various boot args bits.. */
159 cnvmem = args->convmem;
160 extmem = args->extmem;
161
162 /*
163 * Initialize the pic prior to any possible call to an spl.
164 */
165
166 set_cpu_model();
167 vm_set_page_size();
168
169 /*
170 * Initialize the Event Trace Analysis Package
171 * Static Phase: 1 of 2
172 */
173 etap_init_phase1();
174
175 /*
176 * Compute the memory size.
177 */
178
179 #if NCPUS > 1
180 /* First two pages are used to boot the other cpus. */
181 /* TODO - reclaim pages after all cpus have booted */
182
183 first_addr = MP_FIRST_ADDR;
184 #else
185 first_addr = 0x1000;
186 #endif
187
188 /* BIOS leaves data in low memory */
189 last_addr = 1024*1024 + extmem*1024;
190
191 /* extended memory starts at 1MB */
192
193 bios_hole_size = 1024*1024 - trunc_page((vm_offset_t)(1024 * cnvmem));
194
195 /*
196 * Initialize for pmap_free_pages and pmap_next_page.
197 * These guys should be page-aligned.
198 */
199
200 hole_start = trunc_page((vm_offset_t)(1024 * cnvmem));
201 hole_end = round_page((vm_offset_t)first_avail);
202
203 /*
204 * compute mem_size
205 */
206
207 /*
208 * We're currently limited to 512 MB max physical memory.
209 */
210 #define M (1024*1024)
211 #define MAXMEM (512*M)
212 if ((maxmem == 0) && (last_addr - bios_hole_size > MAXMEM)) {
213 printf("Physical memory %d MB, "\
214 "maximum usable memory limited to %d MB\n",
215 (last_addr - bios_hole_size)/M, MAXMEM/M);
216 maxmem = MAXMEM;
217 }
218
219 if (maxmem != 0) {
220 if (maxmem < (last_addr) - bios_hole_size)
221 last_addr = maxmem + bios_hole_size;
222 }
223
224 first_addr = round_page(first_addr);
225 last_addr = trunc_page(last_addr);
226 mem_size = last_addr - bios_hole_size;
227
228 max_mem = (uint64_t)mem_size;
229 sane_size = max_mem;
230
231 avail_start = first_addr;
232 avail_end = last_addr;
233 avail_next = avail_start;
234
235 #if NCPUS > 1
236 interrupt_stack_alloc();
237 #endif /* NCPUS > 1 */
238
239 /*
240 * Initialize kernel physical map.
241 * Kernel virtual address starts at VM_KERNEL_MIN_ADDRESS.
242 */
243 pmap_bootstrap(0);
244
245 avail_remaining = atop((avail_end - avail_start) -
246 (hole_end - hole_start));
247 }
248
249 unsigned int
250 pmap_free_pages(void)
251 {
252 return avail_remaining;
253 }
254
255 boolean_t
256 pmap_next_page(
257 ppnum_t *pn)
258 {
259 if (avail_next == avail_end)
260 return FALSE;
261
262 /* skip the hole */
263
264 if (avail_next == hole_start)
265 avail_next = hole_end;
266
267 *pn = (ppnum_t)i386_btop(avail_next);
268 avail_next += PAGE_SIZE;
269 avail_remaining--;
270
271 return TRUE;
272 }
273
274 boolean_t
275 pmap_valid_page(
276 vm_offset_t x)
277 {
278 return ((avail_start <= x) && (x < avail_end));
279 }