machdep.c revision 210038
1178172Simp    /*	$OpenBSD: machdep.c,v 1.33 1998/09/15 10:58:54 pefo Exp $	*/
2178172Simp/* tracked to 1.38 */
3178172Simp/*
4178172Simp * Copyright (c) 1988 University of Utah.
5178172Simp * Copyright (c) 1992, 1993
6178172Simp *	The Regents of the University of California.  All rights reserved.
7178172Simp *
8178172Simp * This code is derived from software contributed to Berkeley by
9178172Simp * the Systems Programming Group of the University of Utah Computer
10178172Simp * Science Department, The Mach Operating System project at
11178172Simp * Carnegie-Mellon University and Ralph Campbell.
12178172Simp *
13178172Simp * Redistribution and use in source and binary forms, with or without
14178172Simp * modification, are permitted provided that the following conditions
15178172Simp * are met:
16178172Simp * 1. Redistributions of source code must retain the above copyright
17178172Simp *    notice, this list of conditions and the following disclaimer.
18178172Simp * 2. Redistributions in binary form must reproduce the above copyright
19178172Simp *    notice, this list of conditions and the following disclaimer in the
20178172Simp *    documentation and/or other materials provided with the distribution.
21178172Simp * 4. Neither the name of the University nor the names of its contributors
22178172Simp *    may be used to endorse or promote products derived from this software
23178172Simp *    without specific prior written permission.
24178172Simp *
25178172Simp * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26178172Simp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27178172Simp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28178172Simp * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29178172Simp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30178172Simp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31178172Simp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32178172Simp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33178172Simp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34178172Simp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35178172Simp * SUCH DAMAGE.
36178172Simp *
37178172Simp *	from: @(#)machdep.c	8.3 (Berkeley) 1/12/94
38178172Simp *	Id: machdep.c,v 1.33 1998/09/15 10:58:54 pefo Exp
39187305Simp *	JNPR: machdep.c,v 1.11.2.3 2007/08/29 12:24:49
40178172Simp */
41178172Simp
42178172Simp#include <sys/cdefs.h>
43178172Simp__FBSDID("$FreeBSD: head/sys/mips/mips/machdep.c 210038 2010-07-14 00:41:22Z imp $");
44178172Simp
45202046Simp#include "opt_cputype.h"
46183771Simp#include "opt_ddb.h"
47178172Simp#include "opt_md.h"
48183771Simp#include "opt_msgbuf.h"
49178172Simp
50178172Simp#include <sys/param.h>
51178172Simp#include <sys/proc.h>
52178172Simp#include <sys/systm.h>
53178172Simp#include <sys/buf.h>
54178172Simp#include <sys/bus.h>
55178172Simp#include <sys/conf.h>
56178172Simp#include <sys/cpu.h>
57178172Simp#include <sys/kernel.h>
58178172Simp#include <sys/linker.h>
59178172Simp#include <sys/malloc.h>
60178172Simp#include <sys/mbuf.h>
61178172Simp#include <sys/msgbuf.h>
62178172Simp#include <sys/reboot.h>
63178172Simp#include <sys/sched.h>
64178172Simp#include <sys/sysctl.h>
65178172Simp#include <sys/sysproto.h>
66178172Simp#include <sys/vmmeter.h>
67178172Simp
68178172Simp#include <vm/vm.h>
69178172Simp#include <vm/vm_kern.h>
70178172Simp#include <vm/vm_object.h>
71178172Simp#include <vm/vm_page.h>
72178172Simp#include <vm/pmap.h>
73178172Simp#include <vm/vm_map.h>
74178172Simp#include <vm/vm_pager.h>
75178172Simp#include <vm/vm_extern.h>
76178172Simp#include <sys/socket.h>
77178172Simp
78178172Simp#include <sys/user.h>
79202046Simp#include <sys/interrupt.h>
80178172Simp#include <sys/cons.h>
81178172Simp#include <sys/syslog.h>
82202046Simp#include <machine/asm.h>
83202046Simp#include <machine/bootinfo.h>
84178172Simp#include <machine/cache.h>
85202046Simp#include <machine/clock.h>
86178172Simp#include <machine/cpu.h>
87202830Simp#include <machine/cpuregs.h>
88202909Sgonzo#include <machine/elf.h>
89202046Simp#include <machine/hwfunc.h>
90202046Simp#include <machine/intr_machdep.h>
91178172Simp#include <machine/md_var.h>
92209243Sjchandra#include <machine/tlb.h>
93178172Simp#ifdef DDB
94178172Simp#include <sys/kdb.h>
95178172Simp#include <ddb/ddb.h>
96178172Simp#endif
97178172Simp
98178172Simp#include <sys/random.h>
99178172Simp#include <net/if.h>
100178172Simp
101178172Simp#define	BOOTINFO_DEBUG	0
102178172Simp
103178172Simpchar machine[] = "mips";
104178172SimpSYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, "Machine class");
105178172Simp
106178172Simpstatic char cpu_model[30];
107178172SimpSYSCTL_STRING(_hw, HW_MODEL, model, CTLFLAG_RD, cpu_model, 0, "Machine model");
108178172Simp
109178172Simpint cold = 1;
110178172Simplong realmem = 0;
111202046Simplong Maxmem = 0;
112178172Simpint cpu_clock = MIPS_DEFAULT_HZ;
113178172SimpSYSCTL_INT(_hw, OID_AUTO, clockrate, CTLFLAG_RD,
114178172Simp    &cpu_clock, 0, "CPU instruction clock rate");
115178172Simpint clocks_running = 0;
116178172Simp
117178172Simpvm_offset_t kstack0;
118178172Simp
119203180Sneel/*
120203180Sneel * Each entry in the pcpu_space[] array is laid out in the following manner:
121203180Sneel * struct pcpu for cpu 'n'	pcpu_space[n]
122209243Sjchandra * boot stack for cpu 'n'	pcpu_space[n] + PAGE_SIZE * 2 - CALLFRAME_SIZ
123203180Sneel *
124203180Sneel * Note that the boot stack grows downwards and we assume that we never
125203180Sneel * use enough stack space to trample over the 'struct pcpu' that is at
126203180Sneel * the beginning of the array.
127203180Sneel *
128203180Sneel * The array is aligned on a (PAGE_SIZE * 2) boundary so that the 'struct pcpu'
129203180Sneel * is always in the even page frame of the wired TLB entry on SMP kernels.
130203180Sneel *
131203180Sneel * The array is in the .data section so that the stack does not get zeroed out
132203180Sneel * when the .bss section is zeroed.
133203180Sneel */
134203180Sneelchar pcpu_space[MAXCPU][PAGE_SIZE * 2] \
135203180Sneel	__aligned(PAGE_SIZE * 2) __section(".data");
136203180Sneel
137203180Sneelstruct pcpu *pcpup = (struct pcpu *)pcpu_space;
138178172Simp
139202046Simpvm_offset_t phys_avail[PHYS_AVAIL_ENTRIES + 2];
140202046Simpvm_offset_t physmem_desc[PHYS_AVAIL_ENTRIES + 2];
141202046Simp
142178172Simp#ifdef UNIMPLEMENTED
143178172Simpstruct platform platform;
144178172Simp#endif
145178172Simp
146178172Simpstatic void cpu_startup(void *);
147178172SimpSYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL);
148178172Simp
149178172Simpstruct kva_md_info kmi;
150178172Simp
151178172Simpint cpucfg;			/* Value of processor config register */
152178172Simpint num_tlbentries = 64;	/* Size of the CPU tlb */
153178172Simpint cputype;
154178172Simp
155178172Simpextern char MipsException[], MipsExceptionEnd[];
156178172Simp
157178172Simp/* TLB miss handler address and end */
158178172Simpextern char MipsTLBMiss[], MipsTLBMissEnd[];
159178172Simp
160178172Simp/* Cache error handler */
161178172Simpextern char MipsCache[], MipsCacheEnd[];
162178172Simp
163178172Simpextern char edata[], end[];
164202909Sgonzo#ifdef DDB
165202909Sgonzoextern vm_offset_t ksym_start, ksym_end;
166202909Sgonzo#endif
167178172Simp
168178172Simpu_int32_t bootdev;
169178172Simpstruct bootinfo bootinfo;
170202909Sgonzo/*
171202909Sgonzo * First kseg0 address available for use. By default it's equal to &end.
172202909Sgonzo * But in some cases there might be additional data placed right after
173202909Sgonzo * _end by loader or ELF trampoline.
174202909Sgonzo */
175202909Sgonzovm_offset_t kernel_kseg0_end = (vm_offset_t)&end;
176178172Simp
177178172Simpstatic void
178178172Simpcpu_startup(void *dummy)
179178172Simp{
180178172Simp
181178172Simp	if (boothowto & RB_VERBOSE)
182178172Simp		bootverbose++;
183178172Simp
184187305Simp	printf("real memory  = %lu (%luK bytes)\n", ptoa(realmem),
185187305Simp	    ptoa(realmem) / 1024);
186187305Simp
187178172Simp	/*
188178172Simp	 * Display any holes after the first chunk of extended memory.
189178172Simp	 */
190178172Simp	if (bootverbose) {
191178172Simp		int indx;
192178172Simp
193178172Simp		printf("Physical memory chunk(s):\n");
194178172Simp		for (indx = 0; phys_avail[indx + 1] != 0; indx += 2) {
195202046Simp			uintptr_t size1 = phys_avail[indx + 1] - phys_avail[indx];
196178172Simp
197202046Simp			printf("0x%08llx - 0x%08llx, %llu bytes (%llu pages)\n",
198202046Simp			    (unsigned long long)phys_avail[indx],
199202046Simp			    (unsigned long long)phys_avail[indx + 1] - 1,
200202046Simp			    (unsigned long long)size1,
201202046Simp			    (unsigned long long)size1 / PAGE_SIZE);
202178172Simp		}
203178172Simp	}
204178172Simp
205178172Simp	vm_ksubmap_init(&kmi);
206178172Simp
207178172Simp	printf("avail memory = %lu (%luMB)\n", ptoa(cnt.v_free_count),
208178172Simp	    ptoa(cnt.v_free_count) / 1048576);
209202046Simp	cpu_init_interrupts();
210178172Simp
211178172Simp	/*
212178172Simp	 * Set up buffers, so they can be used to read disk labels.
213178172Simp	 */
214178172Simp	bufinit();
215178172Simp	vm_pager_bufferinit();
216178172Simp}
217178172Simp
218178172Simp/*
219178172Simp * Shutdown the CPU as much as possible
220178172Simp */
221178172Simpvoid
222178172Simpcpu_reset(void)
223178172Simp{
224187294Simp
225187294Simp	platform_reset();
226178172Simp}
227178172Simp
228192323Smarcel/*
229192323Smarcel * Flush the D-cache for non-DMA I/O so that the I-cache can
230192323Smarcel * be made coherent later.
231192323Smarcel */
232192323Smarcelvoid
233192323Smarcelcpu_flush_dcache(void *ptr, size_t len)
234192323Smarcel{
235192323Smarcel	/* TBD */
236192323Smarcel}
237192323Smarcel
238178172Simp/* Get current clock frequency for the given cpu id. */
239178172Simpint
240178172Simpcpu_est_clockrate(int cpu_id, uint64_t *rate)
241178172Simp{
242178172Simp
243187294Simp	return (ENXIO);
244178172Simp}
245178172Simp
246178172Simp/*
247178172Simp * Shutdown the CPU as much as possible
248178172Simp */
249178172Simpvoid
250178172Simpcpu_halt(void)
251178172Simp{
252178172Simp	for (;;)
253178172Simp		;
254178172Simp}
255178172Simp
256187326SimpSYSCTL_STRUCT(_machdep, CPU_BOOTINFO, bootinfo, CTLFLAG_RD, &bootinfo,
257187326Simp    bootinfo, "Bootinfo struct: kernel filename, BIOS harddisk geometry, etc");
258187326Simp
259178172Simp#ifdef PORT_TO_JMIPS
260178172Simpstatic int
261178172Simpsysctl_machdep_adjkerntz(SYSCTL_HANDLER_ARGS)
262178172Simp{
263178172Simp}
264178172Simp
265178172SimpSYSCTL_PROC(_machdep, CPU_ADJKERNTZ, adjkerntz, CTLTYPE_INT | CTLFLAG_RW,
266181236Strhodes    &adjkerntz, 0, sysctl_machdep_adjkerntz, "I",
267181236Strhodes    "Local offset from GMT in seconds");
268178172SimpSYSCTL_INT(_machdep, CPU_DISRTCSET, disable_rtc_set, CTLFLAG_RW,
269181236Strhodes    &disable_rtc_set, 0, "Disable setting the real time clock to system time");
270178172SimpSYSCTL_INT(_machdep, CPU_WALLCLOCK, wall_cmos_clock, CTLFLAG_RW,
271181236Strhodes    &wall_cmos_clock, 0, "Wall CMOS clock assumed");
272178172Simp#endif	/* PORT_TO_JMIPS */
273178172Simp
274178172Simp/*
275202046Simp * Initialize per cpu data structures, include curthread.
276178172Simp */
277178172Simpvoid
278202046Simpmips_pcpu0_init()
279178172Simp{
280178172Simp	/* Initialize pcpu info of cpu-zero */
281203180Sneel	pcpu_init(PCPU_ADDR(0), 0, sizeof(struct pcpu));
282202046Simp	PCPU_SET(curthread, &thread0);
283202046Simp}
284202046Simp
285202046Simp/*
286202046Simp * Initialize mips and configure to run kernel
287202046Simp */
288202046Simpvoid
289202046Simpmips_proc0_init(void)
290202046Simp{
291203180Sneel#ifdef SMP
292203180Sneel	if (platform_processor_id() != 0)
293203180Sneel		panic("BSP must be processor number 0");
294203180Sneel#endif
295202046Simp	proc_linkup0(&proc0, &thread0);
296202046Simp
297202046Simp	KASSERT((kstack0 & PAGE_MASK) == 0,
298202046Simp		("kstack0 is not aligned on a page boundary: 0x%0lx",
299202046Simp		(long)kstack0));
300202046Simp	thread0.td_kstack = kstack0;
301202046Simp	thread0.td_kstack_pages = KSTACK_PAGES;
302178172Simp	/*
303178172Simp	 * Do not use cpu_thread_alloc to initialize these fields
304178172Simp	 * thread0 is the only thread that has kstack located in KSEG0
305178172Simp	 * while cpu_thread_alloc handles kstack allocated in KSEG2.
306178172Simp	 */
307206819Sjmallett	thread0.td_pcb = (struct pcb *)(thread0.td_kstack +
308206819Sjmallett	    thread0.td_kstack_pages * PAGE_SIZE) - 1;
309178172Simp	thread0.td_frame = &thread0.td_pcb->pcb_regs;
310187326Simp
311199114Sgonzo	/* Steal memory for the dynamic per-cpu area. */
312199114Sgonzo	dpcpu_init((void *)pmap_steal_memory(DPCPU_SIZE), 0);
313199114Sgonzo
314202046Simp	PCPU_SET(curpcb, thread0.td_pcb);
315178172Simp	/*
316178172Simp	 * There is no need to initialize md_upte array for thread0 as it's
317178172Simp	 * located in .bss section and should be explicitly zeroed during
318178172Simp	 * kernel initialization.
319178172Simp	 */
320202046Simp}
321178172Simp
322202046Simpvoid
323202046Simpcpu_initclocks(void)
324202046Simp{
325202046Simp	platform_initclocks();
326178172Simp}
327178172Simp
328178172Simpstruct msgbuf *msgbufp=0;
329178172Simp
330178172Simp/*
331178172Simp * Initialize the hardware exception vectors, and the jump table used to
332178172Simp * call locore cache and TLB management functions, based on the kind
333178172Simp * of CPU the kernel is running on.
334178172Simp */
335178172Simpvoid
336178172Simpmips_vector_init(void)
337178172Simp{
338178172Simp	/*
339178172Simp	 * Copy down exception vector code.
340178172Simp	 */
341178172Simp	if (MipsTLBMissEnd - MipsTLBMiss > 0x80)
342178172Simp		panic("startup: UTLB code too large");
343178172Simp
344178172Simp	if (MipsCacheEnd - MipsCache > 0x80)
345178172Simp		panic("startup: Cache error code too large");
346178172Simp
347210038Simp	bcopy(MipsTLBMiss, (void *)MIPS_UTLB_MISS_EXC_VEC,
348178172Simp	      MipsTLBMissEnd - MipsTLBMiss);
349178172Simp
350208165Srrs#if defined(TARGET_OCTEON) || defined(TARGET_XLR_XLS)
351178172Simp/* Fake, but sufficient, for the 32-bit with 64-bit hardware addresses  */
352210038Simp	bcopy(MipsTLBMiss, (void *)MIPS3_XTLB_MISS_EXC_VEC,
353178172Simp	      MipsTLBMissEnd - MipsTLBMiss);
354178172Simp#endif
355178172Simp
356210038Simp	bcopy(MipsException, (void *)MIPS3_GEN_EXC_VEC,
357178172Simp	      MipsExceptionEnd - MipsException);
358178172Simp
359210038Simp	bcopy(MipsCache, (void *)MIPS3_CACHE_ERR_EXC_VEC,
360178172Simp	      MipsCacheEnd - MipsCache);
361178172Simp
362178172Simp	/*
363178172Simp	 * Clear out the I and D caches.
364178172Simp	 */
365178172Simp	mips_icache_sync_all();
366178172Simp	mips_dcache_wbinv_all();
367178172Simp
368178172Simp	/*
369178172Simp	 * Mask all interrupts. Each interrupt will be enabled
370178172Simp	 * when handler is installed for it
371178172Simp	 */
372210038Simp	set_intr_mask(MIPS_SR_INT_MASK);
373202697Sneel
374178172Simp	/* Clear BEV in SR so we start handling our own exceptions */
375210038Simp	mips_wr_status(mips_rd_status() & ~MIPS_SR_BEV);
376178172Simp}
377178172Simp
378178172Simp/*
379202909Sgonzo * Fix kernel_kseg0_end address in case trampoline placed debug sympols
380202909Sgonzo * data there
381202909Sgonzo */
382202909Sgonzovoid
383202909Sgonzomips_postboot_fixup(void)
384202909Sgonzo{
385202909Sgonzo#ifdef DDB
386202909Sgonzo	Elf_Size *trampoline_data = (Elf_Size*)kernel_kseg0_end;
387202909Sgonzo	Elf_Size symtabsize = 0;
388202909Sgonzo
389202909Sgonzo	if (trampoline_data[0] == SYMTAB_MAGIC) {
390202909Sgonzo		symtabsize = trampoline_data[1];
391202909Sgonzo		kernel_kseg0_end += 2 * sizeof(Elf_Size);
392202909Sgonzo		/* start of .symtab */
393202909Sgonzo		ksym_start = kernel_kseg0_end;
394202909Sgonzo		kernel_kseg0_end += symtabsize;
395202909Sgonzo		/* end of .strtab */
396202909Sgonzo		ksym_end = kernel_kseg0_end;
397202909Sgonzo	}
398202909Sgonzo#endif
399202909Sgonzo}
400202909Sgonzo
401202909Sgonzo/*
402202830Simp * Many SoCs have a means to reset the core itself.  Others do not, or
403202830Simp * the method is unknown to us.  For those cases, we jump to the mips
404202830Simp * reset vector and hope for the best.  This works well in practice.
405202830Simp */
406202830Simpvoid
407202830Simpmips_generic_reset()
408202830Simp{
409202830Simp	((void(*)(void))(intptr_t)MIPS_VEC_RESET)();
410202830Simp}
411202830Simp
412203697Sneel#ifdef SMP
413178172Simpvoid
414203697Sneelmips_pcpu_tlb_init(struct pcpu *pcpu)
415178172Simp{
416203180Sneel	vm_paddr_t pa;
417209243Sjchandra	pt_entry_t pte;
418203180Sneel
419203180Sneel	/*
420203180Sneel	 * Map the pcpu structure at the virtual address 'pcpup'.
421203180Sneel	 * We use a wired tlb index to do this one-time mapping.
422203180Sneel	 */
423203180Sneel	pa = vtophys(pcpu);
424209482Sjchandra	pte = PTE_D | PTE_V | PTE_G | PTE_C_CACHE;
425209243Sjchandra	tlb_insert_wired(PCPU_TLB_ENTRY, (vm_offset_t)pcpup,
426209243Sjchandra			 TLBLO_PA_TO_PFN(pa) | pte,
427209243Sjchandra			 TLBLO_PA_TO_PFN(pa + PAGE_SIZE) | pte);
428203697Sneel}
429203180Sneel#endif
430203697Sneel
431203697Sneel/*
432203697Sneel * Initialise a struct pcpu.
433203697Sneel */
434203697Sneelvoid
435203697Sneelcpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size)
436203697Sneel{
437203697Sneel
438203697Sneel	pcpu->pc_next_asid = 1;
439203697Sneel	pcpu->pc_asid_generation = 1;
440203697Sneel#ifdef SMP
441203697Sneel	if ((vm_offset_t)pcpup >= VM_MIN_KERNEL_ADDRESS)
442203697Sneel		mips_pcpu_tlb_init(pcpu);
443203697Sneel#endif
444178172Simp}
445178172Simp
446178172Simpint
447178172Simpfill_dbregs(struct thread *td, struct dbreg *dbregs)
448178172Simp{
449178172Simp
450178172Simp	/* No debug registers on mips */
451178172Simp	return (ENOSYS);
452178172Simp}
453178172Simp
454178172Simpint
455178172Simpset_dbregs(struct thread *td, struct dbreg *dbregs)
456178172Simp{
457178172Simp
458178172Simp	/* No debug registers on mips */
459178172Simp	return (ENOSYS);
460178172Simp}
461178172Simp
462178172Simpvoid
463178172Simpspinlock_enter(void)
464178172Simp{
465178172Simp	struct thread *td;
466178172Simp
467178172Simp	td = curthread;
468178172Simp	if (td->td_md.md_spinlock_count == 0)
469206717Sjmallett		td->td_md.md_saved_intr = intr_disable();
470178172Simp	td->td_md.md_spinlock_count++;
471178172Simp	critical_enter();
472178172Simp}
473178172Simp
474178172Simpvoid
475178172Simpspinlock_exit(void)
476178172Simp{
477178172Simp	struct thread *td;
478178172Simp
479178172Simp	td = curthread;
480178172Simp	critical_exit();
481178172Simp	td->td_md.md_spinlock_count--;
482178172Simp	if (td->td_md.md_spinlock_count == 0)
483206717Sjmallett		intr_restore(td->td_md.md_saved_intr);
484178172Simp}
485178172Simp
486178172Simp/*
487178172Simp * call platform specific code to halt (until next interrupt) for the idle loop
488178172Simp */
489178172Simpvoid
490178471Sjeffcpu_idle(int busy)
491178172Simp{
492210038Simp	if (mips_rd_status() & MIPS_SR_INT_IE)
493178172Simp		__asm __volatile ("wait");
494178172Simp	else
495178172Simp		panic("ints disabled in idleproc!");
496178172Simp}
497178172Simp
498187293Simpvoid
499187293Simpdumpsys(struct dumperinfo *di __unused)
500178471Sjeff{
501178471Sjeff
502187293Simp	printf("Kernel dumps not implemented on this architecture\n");
503178471Sjeff}
504178471Sjeff
505187293Simpint
506187293Simpcpu_idle_wakeup(int cpu)
507178172Simp{
508178172Simp
509187293Simp	return (0);
510178172Simp}
511202046Simp
512202046Simpint
513202046Simpis_physical_memory(vm_offset_t addr)
514202046Simp{
515202046Simp	int i;
516202046Simp
517202046Simp	for (i = 0; physmem_desc[i + 1] != 0; i += 2) {
518202046Simp		if (addr >= physmem_desc[i] && addr < physmem_desc[i + 1])
519202046Simp			return (1);
520202046Simp	}
521202046Simp
522202046Simp	return (0);
523202046Simp}
524