2 * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
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
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.
23 * @APPLE_LICENSE_HEADER_END@
29 * Mach Operating System
30 * Copyright (c) 1991,1990,1989, 1988 Carnegie Mellon University
31 * All Rights Reserved.
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.
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.
43 * Carnegie Mellon requests users of this software to return to
45 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
46 * School of Computer Science
47 * Carnegie Mellon University
48 * Pittsburgh PA 15213-3890
50 * any improvements or extensions that they make and grant Carnegie Mellon
51 * the rights to redistribute these changes.
55 #include <platforms.h>
58 #include <fast_idle.h>
60 #include <mach/i386/vm_param.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>
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>
76 #include <vm/vm_kern.h>
77 #include <i386/pmap.h>
80 #include <i386/misc_protos.h>
81 #include <i386/mp_slave_boot.h>
83 #include <mach/boot_info.h>
84 #include <mach/thread_status.h>
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
;
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
;
101 /* parameters passed from bootstrap loader */
102 int cnvmem
= 0; /* must be in .data section */
106 extern char edata
, end
;
110 #include <mach-o/loader.h>
111 vm_offset_t edata
, etext
, end
;
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
;
123 * Basic VM initialization.
126 i386_vm_init(unsigned int maxmem
, KernelBootArgs_t
*args
)
128 int i
,j
; /* Standard index vars. */
129 vm_size_t bios_hole_size
;
132 /* Now retrieve addresses for end, edata, and etext
133 * from MACH-O headers.
136 sectTEXTB
= (void *) getsegdatafromheader(
137 &_mh_execute_header
, "__TEXT", §SizeTEXT
);
138 sectDATAB
= (void *) getsegdatafromheader(
139 &_mh_execute_header
, "__DATA", §SizeDATA
);
140 sectOBJCB
= (void *) getsegdatafromheader(
141 &_mh_execute_header
, "__OBJC", §SizeOBJC
);
142 sectLINKB
= (void *) getsegdatafromheader(
143 &_mh_execute_header
, "__LINKEDIT", §SizeLINK
);
144 sectPRELINKB
= (void *) getsegdatafromheader(
145 &_mh_execute_header
, "__PRELINK", §SizePRELINK
);
147 etext
= (vm_offset_t
) sectTEXTB
+ sectSizeTEXT
;
148 edata
= (vm_offset_t
) sectDATAB
+ sectSizeDATA
;
155 bzero((char *)&edata
,(unsigned)(&end
- &edata
));
158 /* Now copy over various boot args bits.. */
159 cnvmem
= args
->convmem
;
160 extmem
= args
->extmem
;
163 * Initialize the pic prior to any possible call to an spl.
170 * Initialize the Event Trace Analysis Package
171 * Static Phase: 1 of 2
176 * Compute the memory size.
180 /* First two pages are used to boot the other cpus. */
181 /* TODO - reclaim pages after all cpus have booted */
183 first_addr
= MP_FIRST_ADDR
;
188 /* BIOS leaves data in low memory */
189 last_addr
= 1024*1024 + extmem
*1024;
191 /* extended memory starts at 1MB */
193 bios_hole_size
= 1024*1024 - trunc_page((vm_offset_t
)(1024 * cnvmem
));
196 * Initialize for pmap_free_pages and pmap_next_page.
197 * These guys should be page-aligned.
200 hole_start
= trunc_page((vm_offset_t
)(1024 * cnvmem
));
201 hole_end
= round_page((vm_offset_t
)first_avail
);
208 * We're currently limited to 512 MB max physical memory.
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
);
220 if (maxmem
< (last_addr
) - bios_hole_size
)
221 last_addr
= maxmem
+ bios_hole_size
;
224 first_addr
= round_page(first_addr
);
225 last_addr
= trunc_page(last_addr
);
226 mem_size
= last_addr
- bios_hole_size
;
228 max_mem
= (uint64_t)mem_size
;
231 avail_start
= first_addr
;
232 avail_end
= last_addr
;
233 avail_next
= avail_start
;
236 interrupt_stack_alloc();
237 #endif /* NCPUS > 1 */
240 * Initialize kernel physical map.
241 * Kernel virtual address starts at VM_KERNEL_MIN_ADDRESS.
245 avail_remaining
= atop((avail_end
- avail_start
) -
246 (hole_end
- hole_start
));
250 pmap_free_pages(void)
252 return avail_remaining
;
259 if (avail_next
== avail_end
)
264 if (avail_next
== hole_start
)
265 avail_next
= hole_end
;
267 *pn
= (ppnum_t
)i386_btop(avail_next
);
268 avail_next
+= PAGE_SIZE
;
278 return ((avail_start
<= x
) && (x
< avail_end
));