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