Sat Jun 20 13:10:14 2009 UTC ()
make this build with DEBUG_MEMLOAD in all combinations of 32bit, 32bit PAE and 64bit


(cegger)
diff -r1.31 -r1.32 src/sys/arch/x86/x86/x86_machdep.c

cvs diff -r1.31 -r1.32 src/sys/arch/x86/x86/x86_machdep.c (switch to unified diff)

--- src/sys/arch/x86/x86/x86_machdep.c 2009/03/21 15:01:57 1.31
+++ src/sys/arch/x86/x86/x86_machdep.c 2009/06/20 13:10:14 1.32
@@ -1,826 +1,830 @@ @@ -1,826 +1,830 @@
1/* $NetBSD: x86_machdep.c,v 1.31 2009/03/21 15:01:57 ad Exp $ */ 1/* $NetBSD: x86_machdep.c,v 1.32 2009/06/20 13:10:14 cegger Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2002, 2006, 2007 YAMAMOTO Takashi, 4 * Copyright (c) 2002, 2006, 2007 YAMAMOTO Takashi,
5 * Copyright (c) 2005, 2008, 2009 The NetBSD Foundation, Inc. 5 * Copyright (c) 2005, 2008, 2009 The NetBSD Foundation, Inc.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * This code is derived from software contributed to The NetBSD Foundation 8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Julio M. Merino Vidal. 9 * by Julio M. Merino Vidal.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer. 15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright 16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the 17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution. 18 * documentation and/or other materials provided with the distribution.
19 * 19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE. 30 * POSSIBILITY OF SUCH DAMAGE.
31 */ 31 */
32 32
33#include <sys/cdefs.h> 33#include <sys/cdefs.h>
34__KERNEL_RCSID(0, "$NetBSD: x86_machdep.c,v 1.31 2009/03/21 15:01:57 ad Exp $"); 34__KERNEL_RCSID(0, "$NetBSD: x86_machdep.c,v 1.32 2009/06/20 13:10:14 cegger Exp $");
35 35
36#include "opt_modular.h" 36#include "opt_modular.h"
37 37
38#include <sys/types.h> 38#include <sys/types.h>
39#include <sys/param.h> 39#include <sys/param.h>
40#include <sys/systm.h> 40#include <sys/systm.h>
41#include <sys/kcore.h> 41#include <sys/kcore.h>
42#include <sys/errno.h> 42#include <sys/errno.h>
43#include <sys/kauth.h> 43#include <sys/kauth.h>
44#include <sys/mutex.h> 44#include <sys/mutex.h>
45#include <sys/cpu.h> 45#include <sys/cpu.h>
46#include <sys/intr.h> 46#include <sys/intr.h>
47#include <sys/atomic.h> 47#include <sys/atomic.h>
48#include <sys/module.h> 48#include <sys/module.h>
49#include <sys/sysctl.h> 49#include <sys/sysctl.h>
50#include <sys/extent.h> 50#include <sys/extent.h>
51 51
52#include <x86/cpu_msr.h> 52#include <x86/cpu_msr.h>
53#include <x86/cpuvar.h> 53#include <x86/cpuvar.h>
54#include <x86/cputypes.h> 54#include <x86/cputypes.h>
55#include <x86/machdep.h> 55#include <x86/machdep.h>
56#include <x86/pio.h> 56#include <x86/pio.h>
57 57
58#include <dev/isa/isareg.h> 58#include <dev/isa/isareg.h>
59#include <dev/ic/i8042reg.h> 59#include <dev/ic/i8042reg.h>
60 60
61#include <machine/bootinfo.h> 61#include <machine/bootinfo.h>
62#include <machine/vmparam.h> 62#include <machine/vmparam.h>
63 63
64#include <uvm/uvm_extern.h> 64#include <uvm/uvm_extern.h>
65 65
66int check_pa_acc(paddr_t, vm_prot_t); 66int check_pa_acc(paddr_t, vm_prot_t);
67 67
68/* --------------------------------------------------------------------- */ 68/* --------------------------------------------------------------------- */
69 69
70/* 70/*
71 * Main bootinfo structure. This is filled in by the bootstrap process 71 * Main bootinfo structure. This is filled in by the bootstrap process
72 * done in locore.S based on the information passed by the boot loader. 72 * done in locore.S based on the information passed by the boot loader.
73 */ 73 */
74struct bootinfo bootinfo; 74struct bootinfo bootinfo;
75 75
76/* --------------------------------------------------------------------- */ 76/* --------------------------------------------------------------------- */
77 77
78/* 78/*
79 * Given the type of a bootinfo entry, looks for a matching item inside 79 * Given the type of a bootinfo entry, looks for a matching item inside
80 * the bootinfo structure. If found, returns a pointer to it (which must 80 * the bootinfo structure. If found, returns a pointer to it (which must
81 * then be casted to the appropriate bootinfo_* type); otherwise, returns 81 * then be casted to the appropriate bootinfo_* type); otherwise, returns
82 * NULL. 82 * NULL.
83 */ 83 */
84void * 84void *
85lookup_bootinfo(int type) 85lookup_bootinfo(int type)
86{ 86{
87 bool found; 87 bool found;
88 int i; 88 int i;
89 struct btinfo_common *bic; 89 struct btinfo_common *bic;
90 90
91 bic = (struct btinfo_common *)(bootinfo.bi_data); 91 bic = (struct btinfo_common *)(bootinfo.bi_data);
92 found = FALSE; 92 found = FALSE;
93 for (i = 0; i < bootinfo.bi_nentries && !found; i++) { 93 for (i = 0; i < bootinfo.bi_nentries && !found; i++) {
94 if (bic->type == type) 94 if (bic->type == type)
95 found = TRUE; 95 found = TRUE;
96 else 96 else
97 bic = (struct btinfo_common *) 97 bic = (struct btinfo_common *)
98 ((uint8_t *)bic + bic->len); 98 ((uint8_t *)bic + bic->len);
99 } 99 }
100 100
101 return found ? bic : NULL; 101 return found ? bic : NULL;
102} 102}
103 103
104/* 104/*
105 * check_pa_acc: check if given pa is accessible. 105 * check_pa_acc: check if given pa is accessible.
106 */ 106 */
107int 107int
108check_pa_acc(paddr_t pa, vm_prot_t prot) 108check_pa_acc(paddr_t pa, vm_prot_t prot)
109{ 109{
110 extern phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX]; 110 extern phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX];
111 extern int mem_cluster_cnt; 111 extern int mem_cluster_cnt;
112 int i; 112 int i;
113 113
114 for (i = 0; i < mem_cluster_cnt; i++) { 114 for (i = 0; i < mem_cluster_cnt; i++) {
115 const phys_ram_seg_t *seg = &mem_clusters[i]; 115 const phys_ram_seg_t *seg = &mem_clusters[i];
116 paddr_t lstart = seg->start; 116 paddr_t lstart = seg->start;
117 117
118 if (lstart <= pa && pa - lstart <= seg->size) { 118 if (lstart <= pa && pa - lstart <= seg->size) {
119 return 0; 119 return 0;
120 } 120 }
121 } 121 }
122 122
123 return kauth_authorize_machdep(kauth_cred_get(), 123 return kauth_authorize_machdep(kauth_cred_get(),
124 KAUTH_MACHDEP_UNMANAGEDMEM, NULL, NULL, NULL, NULL); 124 KAUTH_MACHDEP_UNMANAGEDMEM, NULL, NULL, NULL, NULL);
125} 125}
126 126
127/* 127/*
128 * This function is to initialize the mutex used by x86/msr_ipifuncs.c. 128 * This function is to initialize the mutex used by x86/msr_ipifuncs.c.
129 */ 129 */
130void 130void
131x86_init(void) 131x86_init(void)
132{ 132{
133#ifndef XEN 133#ifndef XEN
134 msr_cpu_broadcast_initmtx(); 134 msr_cpu_broadcast_initmtx();
135#endif 135#endif
136} 136}
137 137
138#ifdef MODULAR 138#ifdef MODULAR
139/* 139/*
140 * Push any modules loaded by the boot loader. 140 * Push any modules loaded by the boot loader.
141 */ 141 */
142void 142void
143module_init_md(void) 143module_init_md(void)
144{ 144{
145 struct btinfo_modulelist *biml; 145 struct btinfo_modulelist *biml;
146 struct bi_modulelist_entry *bi, *bimax; 146 struct bi_modulelist_entry *bi, *bimax;
147 147
148 biml = lookup_bootinfo(BTINFO_MODULELIST); 148 biml = lookup_bootinfo(BTINFO_MODULELIST);
149 if (biml == NULL) { 149 if (biml == NULL) {
150 aprint_debug("No module info at boot\n"); 150 aprint_debug("No module info at boot\n");
151 return; 151 return;
152 } 152 }
153 153
154 bi = (struct bi_modulelist_entry *)((uint8_t *)biml + sizeof(*biml)); 154 bi = (struct bi_modulelist_entry *)((uint8_t *)biml + sizeof(*biml));
155 bimax = bi + biml->num; 155 bimax = bi + biml->num;
156 for (; bi < bimax; bi++) { 156 for (; bi < bimax; bi++) {
157 if (bi->type != BI_MODULE_ELF) { 157 if (bi->type != BI_MODULE_ELF) {
158 aprint_debug("Skipping non-ELF module\n"); 158 aprint_debug("Skipping non-ELF module\n");
159 continue; 159 continue;
160 } 160 }
161 aprint_debug("Prep module path=%s len=%d pa=%x\n", bi->path, 161 aprint_debug("Prep module path=%s len=%d pa=%x\n", bi->path,
162 bi->len, bi->base); 162 bi->len, bi->base);
163 KASSERT(trunc_page(bi->base) == bi->base); 163 KASSERT(trunc_page(bi->base) == bi->base);
164 (void)module_prime((void *)((uintptr_t)bi->base + KERNBASE), 164 (void)module_prime((void *)((uintptr_t)bi->base + KERNBASE),
165 bi->len); 165 bi->len);
166 } 166 }
167} 167}
168#endif /* MODULAR */ 168#endif /* MODULAR */
169 169
170void 170void
171cpu_need_resched(struct cpu_info *ci, int flags) 171cpu_need_resched(struct cpu_info *ci, int flags)
172{ 172{
173 struct cpu_info *cur; 173 struct cpu_info *cur;
174 lwp_t *l; 174 lwp_t *l;
175 175
176 KASSERT(kpreempt_disabled()); 176 KASSERT(kpreempt_disabled());
177 cur = curcpu(); 177 cur = curcpu();
178 l = ci->ci_data.cpu_onproc; 178 l = ci->ci_data.cpu_onproc;
179 ci->ci_want_resched |= flags; 179 ci->ci_want_resched |= flags;
180 180
181 if (__predict_false((l->l_pflag & LP_INTR) != 0)) { 181 if (__predict_false((l->l_pflag & LP_INTR) != 0)) {
182 /* 182 /*
183 * No point doing anything, it will switch soon. 183 * No point doing anything, it will switch soon.
184 * Also here to prevent an assertion failure in 184 * Also here to prevent an assertion failure in
185 * kpreempt() due to preemption being set on a 185 * kpreempt() due to preemption being set on a
186 * soft interrupt LWP. 186 * soft interrupt LWP.
187 */ 187 */
188 return; 188 return;
189 } 189 }
190 190
191 if (l == ci->ci_data.cpu_idlelwp) { 191 if (l == ci->ci_data.cpu_idlelwp) {
192 if (ci == cur) 192 if (ci == cur)
193 return; 193 return;
194#ifndef XEN /* XXX review when Xen gets MP support */ 194#ifndef XEN /* XXX review when Xen gets MP support */
195 if (x86_cpu_idle == x86_cpu_idle_halt) 195 if (x86_cpu_idle == x86_cpu_idle_halt)
196 x86_send_ipi(ci, 0); 196 x86_send_ipi(ci, 0);
197#endif 197#endif
198 return; 198 return;
199 } 199 }
200 200
201 if ((flags & RESCHED_KPREEMPT) != 0) { 201 if ((flags & RESCHED_KPREEMPT) != 0) {
202#ifdef __HAVE_PREEMPTION 202#ifdef __HAVE_PREEMPTION
203 atomic_or_uint(&l->l_dopreempt, DOPREEMPT_ACTIVE); 203 atomic_or_uint(&l->l_dopreempt, DOPREEMPT_ACTIVE);
204 if (ci == cur) { 204 if (ci == cur) {
205 softint_trigger(1 << SIR_PREEMPT); 205 softint_trigger(1 << SIR_PREEMPT);
206 } else { 206 } else {
207 x86_send_ipi(ci, X86_IPI_KPREEMPT); 207 x86_send_ipi(ci, X86_IPI_KPREEMPT);
208 } 208 }
209#endif 209#endif
210 } else { 210 } else {
211 aston(l, X86_AST_PREEMPT); 211 aston(l, X86_AST_PREEMPT);
212 if (ci == cur) { 212 if (ci == cur) {
213 return; 213 return;
214 } 214 }
215 if ((flags & RESCHED_IMMED) != 0) { 215 if ((flags & RESCHED_IMMED) != 0) {
216 x86_send_ipi(ci, 0); 216 x86_send_ipi(ci, 0);
217 } 217 }
218 } 218 }
219} 219}
220 220
221void 221void
222cpu_signotify(struct lwp *l) 222cpu_signotify(struct lwp *l)
223{ 223{
224 224
225 KASSERT(kpreempt_disabled()); 225 KASSERT(kpreempt_disabled());
226 aston(l, X86_AST_GENERIC); 226 aston(l, X86_AST_GENERIC);
227 if (l->l_cpu != curcpu()) 227 if (l->l_cpu != curcpu())
228 x86_send_ipi(l->l_cpu, 0); 228 x86_send_ipi(l->l_cpu, 0);
229} 229}
230 230
231void 231void
232cpu_need_proftick(struct lwp *l) 232cpu_need_proftick(struct lwp *l)
233{ 233{
234 234
235 KASSERT(kpreempt_disabled()); 235 KASSERT(kpreempt_disabled());
236 KASSERT(l->l_cpu == curcpu()); 236 KASSERT(l->l_cpu == curcpu());
237 237
238 l->l_pflag |= LP_OWEUPC; 238 l->l_pflag |= LP_OWEUPC;
239 aston(l, X86_AST_GENERIC); 239 aston(l, X86_AST_GENERIC);
240} 240}
241 241
242bool 242bool
243cpu_intr_p(void) 243cpu_intr_p(void)
244{ 244{
245 int idepth; 245 int idepth;
246 246
247 kpreempt_disable(); 247 kpreempt_disable();
248 idepth = curcpu()->ci_idepth; 248 idepth = curcpu()->ci_idepth;
249 kpreempt_enable(); 249 kpreempt_enable();
250 return (idepth >= 0); 250 return (idepth >= 0);
251} 251}
252 252
253#ifdef __HAVE_PREEMPTION 253#ifdef __HAVE_PREEMPTION
254/* 254/*
255 * Called to check MD conditions that would prevent preemption, and to 255 * Called to check MD conditions that would prevent preemption, and to
256 * arrange for those conditions to be rechecked later. 256 * arrange for those conditions to be rechecked later.
257 */ 257 */
258bool 258bool
259cpu_kpreempt_enter(uintptr_t where, int s) 259cpu_kpreempt_enter(uintptr_t where, int s)
260{ 260{
261 struct cpu_info *ci; 261 struct cpu_info *ci;
262 lwp_t *l; 262 lwp_t *l;
263 263
264 KASSERT(kpreempt_disabled()); 264 KASSERT(kpreempt_disabled());
265 265
266 l = curlwp; 266 l = curlwp;
267 ci = curcpu(); 267 ci = curcpu();
268 268
269 /* 269 /*
270 * If SPL raised, can't go. Note this implies that spin 270 * If SPL raised, can't go. Note this implies that spin
271 * mutexes at IPL_NONE are _not_ valid to use. 271 * mutexes at IPL_NONE are _not_ valid to use.
272 */ 272 */
273 if (s > IPL_PREEMPT) { 273 if (s > IPL_PREEMPT) {
274 softint_trigger(1 << SIR_PREEMPT); 274 softint_trigger(1 << SIR_PREEMPT);
275 aston(l, X86_AST_PREEMPT); /* paranoid */ 275 aston(l, X86_AST_PREEMPT); /* paranoid */
276 return false; 276 return false;
277 } 277 }
278 278
279 /* Must save cr2 or it could be clobbered. */ 279 /* Must save cr2 or it could be clobbered. */
280 ((struct pcb *)l->l_addr)->pcb_cr2 = rcr2(); 280 ((struct pcb *)l->l_addr)->pcb_cr2 = rcr2();
281 281
282 return true; 282 return true;
283} 283}
284 284
285/* 285/*
286 * Called after returning from a kernel preemption, and called with 286 * Called after returning from a kernel preemption, and called with
287 * preemption disabled. 287 * preemption disabled.
288 */ 288 */
289void 289void
290cpu_kpreempt_exit(uintptr_t where) 290cpu_kpreempt_exit(uintptr_t where)
291{ 291{
292 extern char x86_copyfunc_start, x86_copyfunc_end; 292 extern char x86_copyfunc_start, x86_copyfunc_end;
293 293
294 KASSERT(kpreempt_disabled()); 294 KASSERT(kpreempt_disabled());
295 295
296 /* 296 /*
297 * If we interrupted any of the copy functions we must reload 297 * If we interrupted any of the copy functions we must reload
298 * the pmap when resuming, as they cannot tolerate it being 298 * the pmap when resuming, as they cannot tolerate it being
299 * swapped out. 299 * swapped out.
300 */ 300 */
301 if (where >= (uintptr_t)&x86_copyfunc_start && 301 if (where >= (uintptr_t)&x86_copyfunc_start &&
302 where < (uintptr_t)&x86_copyfunc_end) { 302 where < (uintptr_t)&x86_copyfunc_end) {
303 pmap_load(); 303 pmap_load();
304 } 304 }
305 305
306 /* Restore cr2 only after the pmap, as pmap_load can block. */ 306 /* Restore cr2 only after the pmap, as pmap_load can block. */
307 lcr2(((struct pcb *)curlwp->l_addr)->pcb_cr2); 307 lcr2(((struct pcb *)curlwp->l_addr)->pcb_cr2);
308} 308}
309 309
310/* 310/*
311 * Return true if preemption is disabled for MD reasons. Must be called 311 * Return true if preemption is disabled for MD reasons. Must be called
312 * with preemption disabled, and thus is only for diagnostic checks. 312 * with preemption disabled, and thus is only for diagnostic checks.
313 */ 313 */
314bool 314bool
315cpu_kpreempt_disabled(void) 315cpu_kpreempt_disabled(void)
316{ 316{
317 317
318 return curcpu()->ci_ilevel > IPL_NONE; 318 return curcpu()->ci_ilevel > IPL_NONE;
319} 319}
320#endif /* __HAVE_PREEMPTION */ 320#endif /* __HAVE_PREEMPTION */
321 321
322void (*x86_cpu_idle)(void); 322void (*x86_cpu_idle)(void);
323static char x86_cpu_idle_text[16]; 323static char x86_cpu_idle_text[16];
324 324
325SYSCTL_SETUP(sysctl_machdep_cpu_idle, "sysctl machdep cpu_idle") 325SYSCTL_SETUP(sysctl_machdep_cpu_idle, "sysctl machdep cpu_idle")
326{ 326{
327 const struct sysctlnode *mnode, *node; 327 const struct sysctlnode *mnode, *node;
328 328
329 sysctl_createv(NULL, 0, NULL, &mnode, 329 sysctl_createv(NULL, 0, NULL, &mnode,
330 CTLFLAG_PERMANENT, CTLTYPE_NODE, "machdep", NULL, 330 CTLFLAG_PERMANENT, CTLTYPE_NODE, "machdep", NULL,
331 NULL, 0, NULL, 0, CTL_MACHDEP, CTL_EOL); 331 NULL, 0, NULL, 0, CTL_MACHDEP, CTL_EOL);
332 332
333 sysctl_createv(NULL, 0, &mnode, &node, 333 sysctl_createv(NULL, 0, &mnode, &node,
334 CTLFLAG_PERMANENT, CTLTYPE_STRING, "idle-mechanism", 334 CTLFLAG_PERMANENT, CTLTYPE_STRING, "idle-mechanism",
335 SYSCTL_DESCR("Mechanism used for the idle loop."), 335 SYSCTL_DESCR("Mechanism used for the idle loop."),
336 NULL, 0, x86_cpu_idle_text, 0, 336 NULL, 0, x86_cpu_idle_text, 0,
337 CTL_CREATE, CTL_EOL); 337 CTL_CREATE, CTL_EOL);
338} 338}
339 339
340void 340void
341x86_cpu_idle_init(void) 341x86_cpu_idle_init(void)
342{ 342{
343#ifndef XEN 343#ifndef XEN
344 if ((curcpu()->ci_feature2_flags & CPUID2_MONITOR) == 0 || 344 if ((curcpu()->ci_feature2_flags & CPUID2_MONITOR) == 0 ||
345 cpu_vendor == CPUVENDOR_AMD) { 345 cpu_vendor == CPUVENDOR_AMD) {
346 strlcpy(x86_cpu_idle_text, "halt", sizeof(x86_cpu_idle_text)); 346 strlcpy(x86_cpu_idle_text, "halt", sizeof(x86_cpu_idle_text));
347 x86_cpu_idle = x86_cpu_idle_halt; 347 x86_cpu_idle = x86_cpu_idle_halt;
348 } else { 348 } else {
349 strlcpy(x86_cpu_idle_text, "mwait", sizeof(x86_cpu_idle_text)); 349 strlcpy(x86_cpu_idle_text, "mwait", sizeof(x86_cpu_idle_text));
350 x86_cpu_idle = x86_cpu_idle_mwait; 350 x86_cpu_idle = x86_cpu_idle_mwait;
351 } 351 }
352#else 352#else
353 strlcpy(x86_cpu_idle_text, "xen", sizeof(x86_cpu_idle_text)); 353 strlcpy(x86_cpu_idle_text, "xen", sizeof(x86_cpu_idle_text));
354 x86_cpu_idle = x86_cpu_idle_xen; 354 x86_cpu_idle = x86_cpu_idle_xen;
355#endif 355#endif
356} 356}
357 357
358 358
359#ifndef XEN 359#ifndef XEN
360 360
361#define KBTOB(x) ((size_t)(x) * 1024UL) 361#define KBTOB(x) ((size_t)(x) * 1024UL)
362#define MBTOB(x) ((size_t)(x) * 1024UL * 1024UL) 362#define MBTOB(x) ((size_t)(x) * 1024UL * 1024UL)
363 363
364extern paddr_t avail_start, avail_end; 364extern paddr_t avail_start, avail_end;
365 365
366static int 366static int
367add_mem_cluster(phys_ram_seg_t *seg_clusters, int seg_cluster_cnt, 367add_mem_cluster(phys_ram_seg_t *seg_clusters, int seg_cluster_cnt,
368 struct extent *iomem_ex, 368 struct extent *iomem_ex,
369 uint64_t seg_start, uint64_t seg_end, uint32_t type) 369 uint64_t seg_start, uint64_t seg_end, uint32_t type)
370{ 370{
371 uint64_t new_physmem = 0; 371 uint64_t new_physmem = 0;
372 phys_ram_seg_t *cluster; 372 phys_ram_seg_t *cluster;
373 int i; 373 int i;
374 374
375#ifdef i386 375#ifdef i386
376#define TOPLIMIT 0x100000000ULL 376#define TOPLIMIT 0x100000000ULL
377#else 377#else
378#define TOPLIMIT 0x100000000000ULL 378#define TOPLIMIT 0x100000000000ULL
379#endif 379#endif
380 380
381 if (seg_end > TOPLIMIT) { 381 if (seg_end > TOPLIMIT) {
382 aprint_verbose("WARNING: skipping large memory map entry: " 382 aprint_verbose("WARNING: skipping large memory map entry: "
383 "0x%"PRIx64"/0x%"PRIx64"/0x%x\n", 383 "0x%"PRIx64"/0x%"PRIx64"/0x%x\n",
384 seg_start, 384 seg_start,
385 (seg_end - seg_start), 385 (seg_end - seg_start),
386 type); 386 type);
387 return seg_cluster_cnt; 387 return seg_cluster_cnt;
388 } 388 }
389 389
390 /* 390 /*
391 * XXX Chop the last page off the size so that 391 * XXX Chop the last page off the size so that
392 * XXX it can fit in avail_end. 392 * XXX it can fit in avail_end.
393 */ 393 */
394 if (seg_end == TOPLIMIT) 394 if (seg_end == TOPLIMIT)
395 seg_end -= PAGE_SIZE; 395 seg_end -= PAGE_SIZE;
396 396
397 if (seg_end <= seg_start) 397 if (seg_end <= seg_start)
398 return seg_cluster_cnt; 398 return seg_cluster_cnt;
399 399
400 for (i = 0; i < seg_cluster_cnt; i++) { 400 for (i = 0; i < seg_cluster_cnt; i++) {
401 cluster = &seg_clusters[i]; 401 cluster = &seg_clusters[i];
402 if ((cluster->start == round_page(seg_start)) 402 if ((cluster->start == round_page(seg_start))
403 && (cluster->size == trunc_page(seg_end) - cluster->start)) 403 && (cluster->size == trunc_page(seg_end) - cluster->start))
404 { 404 {
405#ifdef DEBUG_MEMLOAD 405#ifdef DEBUG_MEMLOAD
406 printf("WARNING: skipping duplicate segment entry\n"); 406 printf("WARNING: skipping duplicate segment entry\n");
407#endif 407#endif
408 return seg_cluster_cnt; 408 return seg_cluster_cnt;
409 } 409 }
410 } 410 }
411 411
412 /* 412 /*
413 * Allocate the physical addresses used by RAM 413 * Allocate the physical addresses used by RAM
414 * from the iomem extent map. This is done before 414 * from the iomem extent map. This is done before
415 * the addresses are page rounded just to make 415 * the addresses are page rounded just to make
416 * sure we get them all. 416 * sure we get them all.
417 */ 417 */
418 if (seg_start < 0x100000000ULL) { 418 if (seg_start < 0x100000000ULL) {
419 uint64_t io_end; 419 uint64_t io_end;
420 420
421 if (seg_end > 0x100000000ULL) 421 if (seg_end > 0x100000000ULL)
422 io_end = 0x100000000ULL; 422 io_end = 0x100000000ULL;
423 else 423 else
424 io_end = seg_end; 424 io_end = seg_end;
425 425
426 if (iomem_ex != NULL && extent_alloc_region(iomem_ex, seg_start, 426 if (iomem_ex != NULL && extent_alloc_region(iomem_ex, seg_start,
427 io_end - seg_start, EX_NOWAIT)) { 427 io_end - seg_start, EX_NOWAIT)) {
428 /* XXX What should we do? */ 428 /* XXX What should we do? */
429 printf("WARNING: CAN't ALLOCATE MEMORY SEGMENT " 429 printf("WARNING: CAN't ALLOCATE MEMORY SEGMENT "
430 "(0x%"PRIx64"/0x%"PRIx64"/0x%x) FROM " 430 "(0x%"PRIx64"/0x%"PRIx64"/0x%x) FROM "
431 "IOMEM EXTENT MAP!\n", 431 "IOMEM EXTENT MAP!\n",
432 seg_start, seg_end - seg_start, type); 432 seg_start, seg_end - seg_start, type);
433 return seg_cluster_cnt; 433 return seg_cluster_cnt;
434 } 434 }
435 } 435 }
436 436
437 /* 437 /*
438 * If it's not free memory, skip it. 438 * If it's not free memory, skip it.
439 */ 439 */
440 if (type != BIM_Memory) 440 if (type != BIM_Memory)
441 return seg_cluster_cnt; 441 return seg_cluster_cnt;
442 442
443 /* XXX XXX XXX */ 443 /* XXX XXX XXX */
444 if (seg_cluster_cnt >= VM_PHYSSEG_MAX) 444 if (seg_cluster_cnt >= VM_PHYSSEG_MAX)
445 panic("%s: too many memory segments (increase VM_PHYSSEG_MAX)", 445 panic("%s: too many memory segments (increase VM_PHYSSEG_MAX)",
446 __func__); 446 __func__);
447 447
448#ifdef PHYSMEM_MAX_ADDR 448#ifdef PHYSMEM_MAX_ADDR
449 if (seg_start >= MBTOB(PHYSMEM_MAX_ADDR)) 449 if (seg_start >= MBTOB(PHYSMEM_MAX_ADDR))
450 return seg_cluster_cnt; 450 return seg_cluster_cnt;
451 if (seg_end > MBTOB(PHYSMEM_MAX_ADDR)) 451 if (seg_end > MBTOB(PHYSMEM_MAX_ADDR))
452 seg_end = MBTOB(PHYSMEM_MAX_ADDR); 452 seg_end = MBTOB(PHYSMEM_MAX_ADDR);
453#endif  453#endif
454 454
455 seg_start = round_page(seg_start); 455 seg_start = round_page(seg_start);
456 seg_end = trunc_page(seg_end); 456 seg_end = trunc_page(seg_end);
457 457
458 if (seg_start == seg_end) 458 if (seg_start == seg_end)
459 return seg_cluster_cnt; 459 return seg_cluster_cnt;
460 460
461 cluster = &seg_clusters[seg_cluster_cnt]; 461 cluster = &seg_clusters[seg_cluster_cnt];
462 cluster->start = seg_start; 462 cluster->start = seg_start;
463 if (iomem_ex != NULL) 463 if (iomem_ex != NULL)
464 new_physmem = physmem + atop(seg_end - seg_start); 464 new_physmem = physmem + atop(seg_end - seg_start);
465 465
466#ifdef PHYSMEM_MAX_SIZE 466#ifdef PHYSMEM_MAX_SIZE
467 if (iomem_ex != NULL) { 467 if (iomem_ex != NULL) {
468 if (physmem >= atop(MBTOB(PHYSMEM_MAX_SIZE))) 468 if (physmem >= atop(MBTOB(PHYSMEM_MAX_SIZE)))
469 return seg_cluster_cnt; 469 return seg_cluster_cnt;
470 if (new_physmem > atop(MBTOB(PHYSMEM_MAX_SIZE))) { 470 if (new_physmem > atop(MBTOB(PHYSMEM_MAX_SIZE))) {
471 seg_end = seg_start + MBTOB(PHYSMEM_MAX_SIZE) - ptoa(physmem); 471 seg_end = seg_start + MBTOB(PHYSMEM_MAX_SIZE) - ptoa(physmem);
472 new_physmem = atop(MBTOB(PHYSMEM_MAX_SIZE)); 472 new_physmem = atop(MBTOB(PHYSMEM_MAX_SIZE));
473 } 473 }
474 } 474 }
475#endif  475#endif
476 476
477 cluster->size = seg_end - seg_start; 477 cluster->size = seg_end - seg_start;
478 478
479 if (iomem_ex != NULL) { 479 if (iomem_ex != NULL) {
480 if (avail_end < seg_end) 480 if (avail_end < seg_end)
481 avail_end = seg_end; 481 avail_end = seg_end;
482 physmem = new_physmem; 482 physmem = new_physmem;
483 } 483 }
484 seg_cluster_cnt++; 484 seg_cluster_cnt++;
485 485
486 return seg_cluster_cnt; 486 return seg_cluster_cnt;
487} 487}
488 488
489int 489int
490initx86_parse_memmap(struct btinfo_memmap *bim, struct extent *iomem_ex) 490initx86_parse_memmap(struct btinfo_memmap *bim, struct extent *iomem_ex)
491{ 491{
492 uint64_t seg_start, seg_end; 492 uint64_t seg_start, seg_end;
493 uint64_t addr, size; 493 uint64_t addr, size;
494 uint32_t type; 494 uint32_t type;
495 int x; 495 int x;
496 496
497 KASSERT(bim != NULL); 497 KASSERT(bim != NULL);
498 KASSERT(bim->num > 0); 498 KASSERT(bim->num > 0);
499 499
500#ifdef DEBUG_MEMLOAD 500#ifdef DEBUG_MEMLOAD
501 printf("BIOS MEMORY MAP (%d ENTRIES):\n", bim->num); 501 printf("BIOS MEMORY MAP (%d ENTRIES):\n", bim->num);
502#endif 502#endif
503 for (x = 0; x < bim->num; x++) { 503 for (x = 0; x < bim->num; x++) {
504 addr = bim->entry[x].addr; 504 addr = bim->entry[x].addr;
505 size = bim->entry[x].size; 505 size = bim->entry[x].size;
506 type = bim->entry[x].type; 506 type = bim->entry[x].type;
507#ifdef DEBUG_MEMLOAD 507#ifdef DEBUG_MEMLOAD
508 printf(" addr 0x%"PRIx64" size 0x%"PRIx64" type 0x%x\n", 508 printf(" addr 0x%"PRIx64" size 0x%"PRIx64" type 0x%x\n",
509 addr, size, type); 509 addr, size, type);
510#endif 510#endif
511 511
512 /* 512 /*
513 * If the segment is not memory, skip it. 513 * If the segment is not memory, skip it.
514 */ 514 */
515 switch (type) { 515 switch (type) {
516 case BIM_Memory: 516 case BIM_Memory:
517 case BIM_ACPI: 517 case BIM_ACPI:
518 case BIM_NVS: 518 case BIM_NVS:
519 break; 519 break;
520 default: 520 default:
521 continue; 521 continue;
522 } 522 }
523 523
524 /* 524 /*
525 * If the segment is smaller than a page, skip it. 525 * If the segment is smaller than a page, skip it.
526 */ 526 */
527 if (size < NBPG) 527 if (size < NBPG)
528 continue; 528 continue;
529 529
530 seg_start = addr; 530 seg_start = addr;
531 seg_end = addr + size; 531 seg_end = addr + size;
532 532
533 /* 533 /*
534 * Avoid Compatibility Holes. 534 * Avoid Compatibility Holes.
535 * XXX Holes within memory space that allow access 535 * XXX Holes within memory space that allow access
536 * XXX to be directed to the PC-compatible frame buffer 536 * XXX to be directed to the PC-compatible frame buffer
537 * XXX (0xa0000-0xbffff),to adapter ROM space 537 * XXX (0xa0000-0xbffff),to adapter ROM space
538 * XXX (0xc0000-0xdffff), and to system BIOS space 538 * XXX (0xc0000-0xdffff), and to system BIOS space
539 * XXX (0xe0000-0xfffff). 539 * XXX (0xe0000-0xfffff).
540 * XXX Some laptop(for example,Toshiba Satellite2550X) 540 * XXX Some laptop(for example,Toshiba Satellite2550X)
541 * XXX report this area and occurred problems, 541 * XXX report this area and occurred problems,
542 * XXX so we avoid this area. 542 * XXX so we avoid this area.
543 */ 543 */
544 if (seg_start < 0x100000 && seg_end > 0xa0000) { 544 if (seg_start < 0x100000 && seg_end > 0xa0000) {
545 printf("WARNING: memory map entry overlaps " 545 printf("WARNING: memory map entry overlaps "
546 "with ``Compatibility Holes'': " 546 "with ``Compatibility Holes'': "
547 "0x%"PRIx64"/0x%"PRIx64"/0x%x\n", seg_start, 547 "0x%"PRIx64"/0x%"PRIx64"/0x%x\n", seg_start,
548 seg_end - seg_start, type); 548 seg_end - seg_start, type);
549 mem_cluster_cnt = add_mem_cluster( 549 mem_cluster_cnt = add_mem_cluster(
550 mem_clusters, mem_cluster_cnt, iomem_ex, 550 mem_clusters, mem_cluster_cnt, iomem_ex,
551 seg_start, 0xa0000, type); 551 seg_start, 0xa0000, type);
552 mem_cluster_cnt = add_mem_cluster( 552 mem_cluster_cnt = add_mem_cluster(
553 mem_clusters, mem_cluster_cnt, iomem_ex, 553 mem_clusters, mem_cluster_cnt, iomem_ex,
554 0x100000, seg_end, type); 554 0x100000, seg_end, type);
555 } else 555 } else
556 mem_cluster_cnt = add_mem_cluster( 556 mem_cluster_cnt = add_mem_cluster(
557 mem_clusters, mem_cluster_cnt, iomem_ex, 557 mem_clusters, mem_cluster_cnt, iomem_ex,
558 seg_start, seg_end, type); 558 seg_start, seg_end, type);
559 } 559 }
560 560
561 return 0; 561 return 0;
562} 562}
563 563
564int 564int
565initx86_fake_memmap(struct extent *iomem_ex) 565initx86_fake_memmap(struct extent *iomem_ex)
566{ 566{
567 phys_ram_seg_t *cluster; 567 phys_ram_seg_t *cluster;
568 KASSERT(mem_cluster_cnt == 0); 568 KASSERT(mem_cluster_cnt == 0);
569 569
570 /* 570 /*
571 * Allocate the physical addresses used by RAM from the iomem 571 * Allocate the physical addresses used by RAM from the iomem
572 * extent map. This is done before the addresses are 572 * extent map. This is done before the addresses are
573 * page rounded just to make sure we get them all. 573 * page rounded just to make sure we get them all.
574 */ 574 */
575 if (extent_alloc_region(iomem_ex, 0, KBTOB(biosbasemem), 575 if (extent_alloc_region(iomem_ex, 0, KBTOB(biosbasemem),
576 EX_NOWAIT)) 576 EX_NOWAIT))
577 { 577 {
578 /* XXX What should we do? */ 578 /* XXX What should we do? */
579 printf("WARNING: CAN'T ALLOCATE BASE MEMORY FROM " 579 printf("WARNING: CAN'T ALLOCATE BASE MEMORY FROM "
580 "IOMEM EXTENT MAP!\n"); 580 "IOMEM EXTENT MAP!\n");
581 } 581 }
582 582
583 cluster = &mem_clusters[0]; 583 cluster = &mem_clusters[0];
584 cluster->start = 0; 584 cluster->start = 0;
585 cluster->size = trunc_page(KBTOB(biosbasemem)); 585 cluster->size = trunc_page(KBTOB(biosbasemem));
586 physmem += atop(cluster->size); 586 physmem += atop(cluster->size);
587 587
588 if (extent_alloc_region(iomem_ex, IOM_END, KBTOB(biosextmem), 588 if (extent_alloc_region(iomem_ex, IOM_END, KBTOB(biosextmem),
589 EX_NOWAIT)) 589 EX_NOWAIT))
590 { 590 {
591 /* XXX What should we do? */ 591 /* XXX What should we do? */
592 printf("WARNING: CAN'T ALLOCATE EXTENDED MEMORY FROM " 592 printf("WARNING: CAN'T ALLOCATE EXTENDED MEMORY FROM "
593 "IOMEM EXTENT MAP!\n"); 593 "IOMEM EXTENT MAP!\n");
594 } 594 }
595 595
596#if NISADMA > 0  596#if NISADMA > 0
597 /* 597 /*
598 * Some motherboards/BIOSes remap the 384K of RAM that would 598 * Some motherboards/BIOSes remap the 384K of RAM that would
599 * normally be covered by the ISA hole to the end of memory 599 * normally be covered by the ISA hole to the end of memory
600 * so that it can be used. However, on a 16M system, this 600 * so that it can be used. However, on a 16M system, this
601 * would cause bounce buffers to be allocated and used. 601 * would cause bounce buffers to be allocated and used.
602 * This is not desirable behaviour, as more than 384K of 602 * This is not desirable behaviour, as more than 384K of
603 * bounce buffers might be allocated. As a work-around, 603 * bounce buffers might be allocated. As a work-around,
604 * we round memory down to the nearest 1M boundary if 604 * we round memory down to the nearest 1M boundary if
605 * we're using any isadma devices and the remapped memory 605 * we're using any isadma devices and the remapped memory
606 * is what puts us over 16M. 606 * is what puts us over 16M.
607 */ 607 */
608 if (biosextmem > (15*1024) && biosextmem < (16*1024)) { 608 if (biosextmem > (15*1024) && biosextmem < (16*1024)) {
609 char pbuf[9]; 609 char pbuf[9];
610 610
611 format_bytes(pbuf, sizeof(pbuf), 611 format_bytes(pbuf, sizeof(pbuf),
612 biosextmem - (15*1024)); 612 biosextmem - (15*1024));
613 printf("Warning: ignoring %s of remapped memory\n", 613 printf("Warning: ignoring %s of remapped memory\n",
614 pbuf); 614 pbuf);
615 biosextmem = (15*1024); 615 biosextmem = (15*1024);
616 } 616 }
617#endif 617#endif
618 cluster = &mem_clusters[1]; 618 cluster = &mem_clusters[1];
619 cluster->start = IOM_END; 619 cluster->start = IOM_END;
620 cluster->size = trunc_page(KBTOB(biosextmem)); 620 cluster->size = trunc_page(KBTOB(biosextmem));
621 physmem += atop(cluster->size); 621 physmem += atop(cluster->size);
622 622
623 mem_cluster_cnt = 2; 623 mem_cluster_cnt = 2;
624 624
625 avail_end = IOM_END + trunc_page(KBTOB(biosextmem)); 625 avail_end = IOM_END + trunc_page(KBTOB(biosextmem));
626 626
627 return 0; 627 return 0;
628} 628}
629 629
630#ifdef amd64 630#ifdef amd64
631extern vaddr_t kern_end; 631extern vaddr_t kern_end;
632extern vaddr_t module_start, module_end; 632extern vaddr_t module_start, module_end;
633#endif 633#endif
634 634
635int 635int
636initx86_load_memmap(paddr_t first_avail) 636initx86_load_memmap(paddr_t first_avail)
637{ 637{
638 uint64_t seg_start, seg_end; 638 uint64_t seg_start, seg_end;
639 uint64_t seg_start1, seg_end1; 639 uint64_t seg_start1, seg_end1;
640 int first16q, x; 640 int first16q, x;
641 641
642 /* 642 /*
643 * If we have 16M of RAM or less, just put it all on 643 * If we have 16M of RAM or less, just put it all on
644 * the default free list. Otherwise, put the first 644 * the default free list. Otherwise, put the first
645 * 16M of RAM on a lower priority free list (so that 645 * 16M of RAM on a lower priority free list (so that
646 * all of the ISA DMA'able memory won't be eaten up 646 * all of the ISA DMA'able memory won't be eaten up
647 * first-off). 647 * first-off).
648 */ 648 */
649 if (avail_end <= (16 * 1024 * 1024)) 649 if (avail_end <= (16 * 1024 * 1024))
650 first16q = VM_FREELIST_DEFAULT; 650 first16q = VM_FREELIST_DEFAULT;
651 else 651 else
652 first16q = VM_FREELIST_FIRST16; 652 first16q = VM_FREELIST_FIRST16;
653 653
654 /* Make sure the end of the space used by the kernel is rounded. */ 654 /* Make sure the end of the space used by the kernel is rounded. */
655 first_avail = round_page(first_avail); 655 first_avail = round_page(first_avail);
656 656
657#ifdef amd64 657#ifdef amd64
658 kern_end = KERNBASE + first_avail; 658 kern_end = KERNBASE + first_avail;
659 module_start = kern_end; 659 module_start = kern_end;
660 module_end = KERNBASE + NKL2_KIMG_ENTRIES * NBPD_L2; 660 module_end = KERNBASE + NKL2_KIMG_ENTRIES * NBPD_L2;
661#endif 661#endif
662 662
663 /* 663 /*
664 * Now, load the memory clusters (which have already been 664 * Now, load the memory clusters (which have already been
665 * rounded and truncated) into the VM system. 665 * rounded and truncated) into the VM system.
666 * 666 *
667 * NOTE: WE ASSUME THAT MEMORY STARTS AT 0 AND THAT THE KERNEL 667 * NOTE: WE ASSUME THAT MEMORY STARTS AT 0 AND THAT THE KERNEL
668 * IS LOADED AT IOM_END (1M). 668 * IS LOADED AT IOM_END (1M).
669 */ 669 */
670 for (x = 0; x < mem_cluster_cnt; x++) { 670 for (x = 0; x < mem_cluster_cnt; x++) {
671 const phys_ram_seg_t *cluster = &mem_clusters[x]; 671 const phys_ram_seg_t *cluster = &mem_clusters[x];
672 672
673 seg_start = cluster->start; 673 seg_start = cluster->start;
674 seg_end = cluster->start + cluster->size; 674 seg_end = cluster->start + cluster->size;
675 seg_start1 = 0; 675 seg_start1 = 0;
676 seg_end1 = 0; 676 seg_end1 = 0;
677 677
678 /* 678 /*
679 * Skip memory before our available starting point. 679 * Skip memory before our available starting point.
680 */ 680 */
681 if (seg_end <= avail_start) 681 if (seg_end <= avail_start)
682 continue; 682 continue;
683 683
684 if (avail_start >= seg_start && avail_start < seg_end) { 684 if (avail_start >= seg_start && avail_start < seg_end) {
685 if (seg_start != 0) 685 if (seg_start != 0)
686 panic("init_x86_64: memory doesn't start at 0"); 686 panic("init_x86_64: memory doesn't start at 0");
687 seg_start = avail_start; 687 seg_start = avail_start;
688 if (seg_start == seg_end) 688 if (seg_start == seg_end)
689 continue; 689 continue;
690 } 690 }
691 691
692 /* 692 /*
693 * If this segment contains the kernel, split it 693 * If this segment contains the kernel, split it
694 * in two, around the kernel. 694 * in two, around the kernel.
695 */ 695 */
696 if (seg_start <= IOM_END && first_avail <= seg_end) { 696 if (seg_start <= IOM_END && first_avail <= seg_end) {
697 seg_start1 = first_avail; 697 seg_start1 = first_avail;
698 seg_end1 = seg_end; 698 seg_end1 = seg_end;
699 seg_end = IOM_END; 699 seg_end = IOM_END;
700 KASSERT(seg_end < seg_end1); 700 KASSERT(seg_end < seg_end1);
701 } 701 }
702 702
703 /* First hunk */ 703 /* First hunk */
704 if (seg_start != seg_end) { 704 if (seg_start != seg_end) {
705 if (seg_start < (16 * 1024 * 1024) && 705 if (seg_start < (16 * 1024 * 1024) &&
706 first16q != VM_FREELIST_DEFAULT) { 706 first16q != VM_FREELIST_DEFAULT) {
707 uint64_t tmp; 707 uint64_t tmp;
708 708
709 if (seg_end > (16 * 1024 * 1024)) 709 if (seg_end > (16 * 1024 * 1024))
710 tmp = (16 * 1024 * 1024); 710 tmp = (16 * 1024 * 1024);
711 else 711 else
712 tmp = seg_end; 712 tmp = seg_end;
713 713
714 if (tmp != seg_start) { 714 if (tmp != seg_start) {
715#ifdef DEBUG_MEMLOAD 715#ifdef DEBUG_MEMLOAD
716 printf("loading 0x%"PRIx64"-0x%"PRIx64 716 printf("loading 0x%"PRIx64"-0x%"PRIx64
717 " (0x%lx-0x%lx)\n", 717 " (0x%"PRIx64"-0x%"PRIx64")\n",
718 seg_start, tmp, 718 seg_start, tmp,
719 atop(seg_start), atop(tmp)); 719 (uint64_t)atop(seg_start),
 720 (uint64_t)atop(tmp));
720#endif 721#endif
721 uvm_page_physload(atop(seg_start), 722 uvm_page_physload(atop(seg_start),
722 atop(tmp), atop(seg_start), 723 atop(tmp), atop(seg_start),
723 atop(tmp), first16q); 724 atop(tmp), first16q);
724 } 725 }
725 seg_start = tmp; 726 seg_start = tmp;
726 } 727 }
727 728
728 if (seg_start != seg_end) { 729 if (seg_start != seg_end) {
729#ifdef DEBUG_MEMLOAD 730#ifdef DEBUG_MEMLOAD
730 printf("loading 0x%"PRIx64"-0x%"PRIx64 731 printf("loading 0x%"PRIx64"-0x%"PRIx64
731 " (0x%lx-0x%lx)\n", 732 " (0x%"PRIx64"-0x%"PRIx64")\n",
732 seg_start, seg_end, 733 seg_start, seg_end,
733 atop(seg_start), atop(seg_end)); 734 (uint64_t)atop(seg_start),
 735 (uint64_t)atop(seg_end));
734#endif 736#endif
735 uvm_page_physload(atop(seg_start), 737 uvm_page_physload(atop(seg_start),
736 atop(seg_end), atop(seg_start), 738 atop(seg_end), atop(seg_start),
737 atop(seg_end), VM_FREELIST_DEFAULT); 739 atop(seg_end), VM_FREELIST_DEFAULT);
738 } 740 }
739 } 741 }
740 742
741 /* Second hunk */ 743 /* Second hunk */
742 if (seg_start1 != seg_end1) { 744 if (seg_start1 != seg_end1) {
743 if (seg_start1 < (16 * 1024 * 1024) && 745 if (seg_start1 < (16 * 1024 * 1024) &&
744 first16q != VM_FREELIST_DEFAULT) { 746 first16q != VM_FREELIST_DEFAULT) {
745 uint64_t tmp; 747 uint64_t tmp;
746 748
747 if (seg_end1 > (16 * 1024 * 1024)) 749 if (seg_end1 > (16 * 1024 * 1024))
748 tmp = (16 * 1024 * 1024); 750 tmp = (16 * 1024 * 1024);
749 else 751 else
750 tmp = seg_end1; 752 tmp = seg_end1;
751 753
752 if (tmp != seg_start1) { 754 if (tmp != seg_start1) {
753#ifdef DEBUG_MEMLOAD 755#ifdef DEBUG_MEMLOAD
754 printf("loading 0x%"PRIx64"-0x%"PRIx64 756 printf("loading 0x%"PRIx64"-0x%"PRIx64
755 " (0x%lx-0x%lx)\n", 757 " (0x%"PRIx64"-0x%"PRIx64")\n",
756 seg_start1, tmp, 758 seg_start1, tmp,
757 atop(seg_start1), atop(tmp)); 759 (uint64_t)atop(seg_start1),
 760 (uint64_t)atop(tmp));
758#endif 761#endif
759 uvm_page_physload(atop(seg_start1), 762 uvm_page_physload(atop(seg_start1),
760 atop(tmp), atop(seg_start1), 763 atop(tmp), atop(seg_start1),
761 atop(tmp), first16q); 764 atop(tmp), first16q);
762 } 765 }
763 seg_start1 = tmp; 766 seg_start1 = tmp;
764 } 767 }
765 768
766 if (seg_start1 != seg_end1) { 769 if (seg_start1 != seg_end1) {
767#ifdef DEBUG_MEMLOAD 770#ifdef DEBUG_MEMLOAD
768 printf("loading 0x%"PRIx64"-0x%"PRIx64 771 printf("loading 0x%"PRIx64"-0x%"PRIx64
769 " (0x%lx-0x%lx)\n", 772 " (0x%"PRIx64"-0x%"PRIx64")\n",
770 seg_start1, seg_end1, 773 seg_start1, seg_end1,
771 atop(seg_start1), atop(seg_end1)); 774 (uint64_t)atop(seg_start1),
 775 (uint64_t)atop(seg_end1));
772#endif 776#endif
773 uvm_page_physload(atop(seg_start1), 777 uvm_page_physload(atop(seg_start1),
774 atop(seg_end1), atop(seg_start1), 778 atop(seg_end1), atop(seg_start1),
775 atop(seg_end1), VM_FREELIST_DEFAULT); 779 atop(seg_end1), VM_FREELIST_DEFAULT);
776 } 780 }
777 } 781 }
778 } 782 }
779 783
780 return 0; 784 return 0;
781} 785}
782#endif 786#endif
783 787
784void 788void
785x86_reset(void) 789x86_reset(void)
786{ 790{
787 uint8_t b; 791 uint8_t b;
788 /* 792 /*
789 * The keyboard controller has 4 random output pins, one of which is 793 * The keyboard controller has 4 random output pins, one of which is
790 * connected to the RESET pin on the CPU in many PCs. We tell the 794 * connected to the RESET pin on the CPU in many PCs. We tell the
791 * keyboard controller to pulse this line a couple of times. 795 * keyboard controller to pulse this line a couple of times.
792 */ 796 */
793 outb(IO_KBD + KBCMDP, KBC_PULSE0); 797 outb(IO_KBD + KBCMDP, KBC_PULSE0);
794 delay(100000); 798 delay(100000);
795 outb(IO_KBD + KBCMDP, KBC_PULSE0); 799 outb(IO_KBD + KBCMDP, KBC_PULSE0);
796 delay(100000); 800 delay(100000);
797 801
798 /* 802 /*
799 * Attempt to force a reset via the Reset Control register at 803 * Attempt to force a reset via the Reset Control register at
800 * I/O port 0xcf9. Bit 2 forces a system reset when it 804 * I/O port 0xcf9. Bit 2 forces a system reset when it
801 * transitions from 0 to 1. Bit 1 selects the type of reset 805 * transitions from 0 to 1. Bit 1 selects the type of reset
802 * to attempt: 0 selects a "soft" reset, and 1 selects a 806 * to attempt: 0 selects a "soft" reset, and 1 selects a
803 * "hard" reset. We try a "hard" reset. The first write sets 807 * "hard" reset. We try a "hard" reset. The first write sets
804 * bit 1 to select a "hard" reset and clears bit 2. The 808 * bit 1 to select a "hard" reset and clears bit 2. The
805 * second write forces a 0 -> 1 transition in bit 2 to trigger 809 * second write forces a 0 -> 1 transition in bit 2 to trigger
806 * a reset. 810 * a reset.
807 */ 811 */
808 outb(0xcf9, 0x2); 812 outb(0xcf9, 0x2);
809 outb(0xcf9, 0x6); 813 outb(0xcf9, 0x6);
810 DELAY(500000); /* wait 0.5 sec to see if that did it */ 814 DELAY(500000); /* wait 0.5 sec to see if that did it */
811 815
812 /* 816 /*
813 * Attempt to force a reset via the Fast A20 and Init register 817 * Attempt to force a reset via the Fast A20 and Init register
814 * at I/O port 0x92. Bit 1 serves as an alternate A20 gate. 818 * at I/O port 0x92. Bit 1 serves as an alternate A20 gate.
815 * Bit 0 asserts INIT# when set to 1. We are careful to only 819 * Bit 0 asserts INIT# when set to 1. We are careful to only
816 * preserve bit 1 while setting bit 0. We also must clear bit 820 * preserve bit 1 while setting bit 0. We also must clear bit
817 * 0 before setting it if it isn't already clear. 821 * 0 before setting it if it isn't already clear.
818 */ 822 */
819 b = inb(0x92); 823 b = inb(0x92);
820 if (b != 0xff) { 824 if (b != 0xff) {
821 if ((b & 0x1) != 0) 825 if ((b & 0x1) != 0)
822 outb(0x92, b & 0xfe); 826 outb(0x92, b & 0xfe);
823 outb(0x92, b | 0x1); 827 outb(0x92, b | 0x1);
824 DELAY(500000); /* wait 0.5 sec to see if that did it */ 828 DELAY(500000); /* wait 0.5 sec to see if that did it */
825 } 829 }
826} 830}