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$"); 44178172Simp 45183771Simp#include "opt_ddb.h" 46178172Simp#include "opt_md.h" 47178172Simp 48178172Simp#include <sys/param.h> 49178172Simp#include <sys/proc.h> 50178172Simp#include <sys/systm.h> 51178172Simp#include <sys/buf.h> 52178172Simp#include <sys/bus.h> 53178172Simp#include <sys/conf.h> 54178172Simp#include <sys/cpu.h> 55178172Simp#include <sys/kernel.h> 56178172Simp#include <sys/linker.h> 57178172Simp#include <sys/malloc.h> 58178172Simp#include <sys/mbuf.h> 59178172Simp#include <sys/msgbuf.h> 60178172Simp#include <sys/reboot.h> 61248084Sattilio#include <sys/rwlock.h> 62178172Simp#include <sys/sched.h> 63178172Simp#include <sys/sysctl.h> 64178172Simp#include <sys/sysproto.h> 65178172Simp#include <sys/vmmeter.h> 66178172Simp 67178172Simp#include <vm/vm.h> 68178172Simp#include <vm/vm_kern.h> 69178172Simp#include <vm/vm_object.h> 70178172Simp#include <vm/vm_page.h> 71178172Simp#include <vm/pmap.h> 72178172Simp#include <vm/vm_map.h> 73178172Simp#include <vm/vm_pager.h> 74178172Simp#include <vm/vm_extern.h> 75178172Simp#include <sys/socket.h> 76178172Simp 77178172Simp#include <sys/user.h> 78202046Simp#include <sys/interrupt.h> 79178172Simp#include <sys/cons.h> 80178172Simp#include <sys/syslog.h> 81202046Simp#include <machine/asm.h> 82202046Simp#include <machine/bootinfo.h> 83178172Simp#include <machine/cache.h> 84202046Simp#include <machine/clock.h> 85178172Simp#include <machine/cpu.h> 86202830Simp#include <machine/cpuregs.h> 87202909Sgonzo#include <machine/elf.h> 88202046Simp#include <machine/hwfunc.h> 89202046Simp#include <machine/intr_machdep.h> 90178172Simp#include <machine/md_var.h> 91209243Sjchandra#include <machine/tlb.h> 92178172Simp#ifdef DDB 93178172Simp#include <sys/kdb.h> 94178172Simp#include <ddb/ddb.h> 95178172Simp#endif 96178172Simp 97178172Simp#include <sys/random.h> 98178172Simp#include <net/if.h> 99178172Simp 100178172Simp#define BOOTINFO_DEBUG 0 101178172Simp 102178172Simpchar machine[] = "mips"; 103178172SimpSYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, "Machine class"); 104178172Simp 105217516Simpchar cpu_model[80]; 106178172SimpSYSCTL_STRING(_hw, HW_MODEL, model, CTLFLAG_RD, cpu_model, 0, "Machine model"); 107178172Simp 108217516Simpchar cpu_board[80]; 109217516SimpSYSCTL_STRING(_hw, OID_AUTO, board, CTLFLAG_RD, cpu_board, 0, "Machine board"); 110217516Simp 111178172Simpint cold = 1; 112178172Simplong realmem = 0; 113202046Simplong Maxmem = 0; 114178172Simpint cpu_clock = MIPS_DEFAULT_HZ; 115178172SimpSYSCTL_INT(_hw, OID_AUTO, clockrate, CTLFLAG_RD, 116178172Simp &cpu_clock, 0, "CPU instruction clock rate"); 117178172Simpint clocks_running = 0; 118178172Simp 119178172Simpvm_offset_t kstack0; 120178172Simp 121203180Sneel/* 122203180Sneel * Each entry in the pcpu_space[] array is laid out in the following manner: 123203180Sneel * struct pcpu for cpu 'n' pcpu_space[n] 124209243Sjchandra * boot stack for cpu 'n' pcpu_space[n] + PAGE_SIZE * 2 - CALLFRAME_SIZ 125203180Sneel * 126203180Sneel * Note that the boot stack grows downwards and we assume that we never 127203180Sneel * use enough stack space to trample over the 'struct pcpu' that is at 128203180Sneel * the beginning of the array. 129203180Sneel * 130203180Sneel * The array is aligned on a (PAGE_SIZE * 2) boundary so that the 'struct pcpu' 131203180Sneel * is always in the even page frame of the wired TLB entry on SMP kernels. 132203180Sneel * 133203180Sneel * The array is in the .data section so that the stack does not get zeroed out 134203180Sneel * when the .bss section is zeroed. 135203180Sneel */ 136203180Sneelchar pcpu_space[MAXCPU][PAGE_SIZE * 2] \ 137203180Sneel __aligned(PAGE_SIZE * 2) __section(".data"); 138203180Sneel 139203180Sneelstruct pcpu *pcpup = (struct pcpu *)pcpu_space; 140178172Simp 141217345Sjchandravm_paddr_t phys_avail[PHYS_AVAIL_ENTRIES + 2]; 142217345Sjchandravm_paddr_t physmem_desc[PHYS_AVAIL_ENTRIES + 2]; 143214903Sgonzovm_paddr_t dump_avail[PHYS_AVAIL_ENTRIES + 2]; 144202046Simp 145178172Simp#ifdef UNIMPLEMENTED 146178172Simpstruct platform platform; 147178172Simp#endif 148178172Simp 149178172Simpstatic void cpu_startup(void *); 150178172SimpSYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL); 151178172Simp 152178172Simpstruct kva_md_info kmi; 153178172Simp 154178172Simpint cpucfg; /* Value of processor config register */ 155178172Simpint num_tlbentries = 64; /* Size of the CPU tlb */ 156178172Simpint cputype; 157178172Simp 158178172Simpextern char MipsException[], MipsExceptionEnd[]; 159178172Simp 160178172Simp/* TLB miss handler address and end */ 161178172Simpextern char MipsTLBMiss[], MipsTLBMissEnd[]; 162178172Simp 163178172Simp/* Cache error handler */ 164178172Simpextern char MipsCache[], MipsCacheEnd[]; 165178172Simp 166226517Sjchandra/* MIPS wait skip region */ 167226517Sjchandraextern char MipsWaitStart[], MipsWaitEnd[]; 168226517Sjchandra 169178172Simpextern char edata[], end[]; 170202909Sgonzo#ifdef DDB 171202909Sgonzoextern vm_offset_t ksym_start, ksym_end; 172202909Sgonzo#endif 173178172Simp 174178172Simpu_int32_t bootdev; 175178172Simpstruct bootinfo bootinfo; 176202909Sgonzo/* 177202909Sgonzo * First kseg0 address available for use. By default it's equal to &end. 178202909Sgonzo * But in some cases there might be additional data placed right after 179202909Sgonzo * _end by loader or ELF trampoline. 180202909Sgonzo */ 181202909Sgonzovm_offset_t kernel_kseg0_end = (vm_offset_t)&end; 182178172Simp 183178172Simpstatic void 184178172Simpcpu_startup(void *dummy) 185178172Simp{ 186178172Simp 187178172Simp if (boothowto & RB_VERBOSE) 188178172Simp bootverbose++; 189178172Simp 190219106Sjchandra printf("real memory = %ju (%juK bytes)\n", ptoa((uintmax_t)realmem), 191219106Sjchandra ptoa((uintmax_t)realmem) / 1024); 192187305Simp 193178172Simp /* 194178172Simp * Display any holes after the first chunk of extended memory. 195178172Simp */ 196178172Simp if (bootverbose) { 197178172Simp int indx; 198178172Simp 199178172Simp printf("Physical memory chunk(s):\n"); 200178172Simp for (indx = 0; phys_avail[indx + 1] != 0; indx += 2) { 201219106Sjchandra vm_paddr_t size1 = phys_avail[indx + 1] - phys_avail[indx]; 202178172Simp 203219106Sjchandra printf("0x%08jx - 0x%08jx, %ju bytes (%ju pages)\n", 204219106Sjchandra (uintmax_t)phys_avail[indx], 205219106Sjchandra (uintmax_t)phys_avail[indx + 1] - 1, 206219106Sjchandra (uintmax_t)size1, 207219106Sjchandra (uintmax_t)size1 / PAGE_SIZE); 208178172Simp } 209178172Simp } 210178172Simp 211178172Simp vm_ksubmap_init(&kmi); 212178172Simp 213217354Sjchandra printf("avail memory = %ju (%juMB)\n", 214217354Sjchandra ptoa((uintmax_t)cnt.v_free_count), 215217354Sjchandra ptoa((uintmax_t)cnt.v_free_count) / 1048576); 216202046Simp cpu_init_interrupts(); 217178172Simp 218178172Simp /* 219178172Simp * Set up buffers, so they can be used to read disk labels. 220178172Simp */ 221178172Simp bufinit(); 222178172Simp vm_pager_bufferinit(); 223178172Simp} 224178172Simp 225178172Simp/* 226178172Simp * Shutdown the CPU as much as possible 227178172Simp */ 228178172Simpvoid 229178172Simpcpu_reset(void) 230178172Simp{ 231187294Simp 232187294Simp platform_reset(); 233178172Simp} 234178172Simp 235192323Smarcel/* 236192323Smarcel * Flush the D-cache for non-DMA I/O so that the I-cache can 237192323Smarcel * be made coherent later. 238192323Smarcel */ 239192323Smarcelvoid 240192323Smarcelcpu_flush_dcache(void *ptr, size_t len) 241192323Smarcel{ 242192323Smarcel /* TBD */ 243192323Smarcel} 244192323Smarcel 245178172Simp/* Get current clock frequency for the given cpu id. */ 246178172Simpint 247178172Simpcpu_est_clockrate(int cpu_id, uint64_t *rate) 248178172Simp{ 249178172Simp 250187294Simp return (ENXIO); 251178172Simp} 252178172Simp 253178172Simp/* 254178172Simp * Shutdown the CPU as much as possible 255178172Simp */ 256178172Simpvoid 257178172Simpcpu_halt(void) 258178172Simp{ 259178172Simp for (;;) 260178172Simp ; 261178172Simp} 262178172Simp 263210098SimpSYSCTL_STRUCT(_machdep, OID_AUTO, bootinfo, CTLFLAG_RD, &bootinfo, 264187326Simp bootinfo, "Bootinfo struct: kernel filename, BIOS harddisk geometry, etc"); 265187326Simp 266178172Simp/* 267202046Simp * Initialize per cpu data structures, include curthread. 268178172Simp */ 269178172Simpvoid 270202046Simpmips_pcpu0_init() 271178172Simp{ 272178172Simp /* Initialize pcpu info of cpu-zero */ 273203180Sneel pcpu_init(PCPU_ADDR(0), 0, sizeof(struct pcpu)); 274202046Simp PCPU_SET(curthread, &thread0); 275202046Simp} 276202046Simp 277202046Simp/* 278202046Simp * Initialize mips and configure to run kernel 279202046Simp */ 280202046Simpvoid 281202046Simpmips_proc0_init(void) 282202046Simp{ 283203180Sneel#ifdef SMP 284203180Sneel if (platform_processor_id() != 0) 285203180Sneel panic("BSP must be processor number 0"); 286203180Sneel#endif 287202046Simp proc_linkup0(&proc0, &thread0); 288202046Simp 289202046Simp KASSERT((kstack0 & PAGE_MASK) == 0, 290202046Simp ("kstack0 is not aligned on a page boundary: 0x%0lx", 291202046Simp (long)kstack0)); 292202046Simp thread0.td_kstack = kstack0; 293202046Simp thread0.td_kstack_pages = KSTACK_PAGES; 294178172Simp /* 295178172Simp * Do not use cpu_thread_alloc to initialize these fields 296178172Simp * thread0 is the only thread that has kstack located in KSEG0 297178172Simp * while cpu_thread_alloc handles kstack allocated in KSEG2. 298178172Simp */ 299206819Sjmallett thread0.td_pcb = (struct pcb *)(thread0.td_kstack + 300206819Sjmallett thread0.td_kstack_pages * PAGE_SIZE) - 1; 301178172Simp thread0.td_frame = &thread0.td_pcb->pcb_regs; 302187326Simp 303199114Sgonzo /* Steal memory for the dynamic per-cpu area. */ 304199114Sgonzo dpcpu_init((void *)pmap_steal_memory(DPCPU_SIZE), 0); 305199114Sgonzo 306202046Simp PCPU_SET(curpcb, thread0.td_pcb); 307178172Simp /* 308178172Simp * There is no need to initialize md_upte array for thread0 as it's 309178172Simp * located in .bss section and should be explicitly zeroed during 310178172Simp * kernel initialization. 311178172Simp */ 312202046Simp} 313178172Simp 314202046Simpvoid 315202046Simpcpu_initclocks(void) 316202046Simp{ 317210403Smav 318202046Simp platform_initclocks(); 319210403Smav cpu_initclocks_bsp(); 320178172Simp} 321178172Simp 322178172Simpstruct msgbuf *msgbufp=0; 323178172Simp 324178172Simp/* 325178172Simp * Initialize the hardware exception vectors, and the jump table used to 326178172Simp * call locore cache and TLB management functions, based on the kind 327178172Simp * of CPU the kernel is running on. 328178172Simp */ 329178172Simpvoid 330178172Simpmips_vector_init(void) 331178172Simp{ 332178172Simp /* 333226517Sjchandra * Make sure that the Wait region logic is not been 334226517Sjchandra * changed 335226517Sjchandra */ 336226517Sjchandra if (MipsWaitEnd - MipsWaitStart != 16) 337226517Sjchandra panic("startup: MIPS wait region not correct"); 338226517Sjchandra /* 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 350239671Srwatson /* 351239671Srwatson * XXXRW: Why don't we install the XTLB handler for all 64-bit 352239671Srwatson * architectures? 353239671Srwatson */ 354239671Srwatson#if defined(__mips_n64) || defined(CPU_RMI) || defined(CPU_NLM) || defined (CPU_BERI) 355239671Srwatson/* Fake, but sufficient, for the 32-bit with 64-bit hardware addresses */ 356232615Sjmallett bcopy(MipsTLBMiss, (void *)MIPS_XTLB_MISS_EXC_VEC, 357178172Simp MipsTLBMissEnd - MipsTLBMiss); 358178172Simp#endif 359178172Simp 360232615Sjmallett bcopy(MipsException, (void *)MIPS_GEN_EXC_VEC, 361178172Simp MipsExceptionEnd - MipsException); 362178172Simp 363232615Sjmallett bcopy(MipsCache, (void *)MIPS_CACHE_ERR_EXC_VEC, 364178172Simp MipsCacheEnd - MipsCache); 365178172Simp 366178172Simp /* 367178172Simp * Clear out the I and D caches. 368178172Simp */ 369178172Simp mips_icache_sync_all(); 370178172Simp mips_dcache_wbinv_all(); 371178172Simp 372178172Simp /* 373178172Simp * Mask all interrupts. Each interrupt will be enabled 374178172Simp * when handler is installed for it 375178172Simp */ 376212632Sneel set_intr_mask(0); 377202697Sneel 378178172Simp /* Clear BEV in SR so we start handling our own exceptions */ 379210038Simp mips_wr_status(mips_rd_status() & ~MIPS_SR_BEV); 380178172Simp} 381178172Simp 382178172Simp/* 383202909Sgonzo * Fix kernel_kseg0_end address in case trampoline placed debug sympols 384202909Sgonzo * data there 385202909Sgonzo */ 386202909Sgonzovoid 387202909Sgonzomips_postboot_fixup(void) 388202909Sgonzo{ 389232998Sgonzo static char fake_preload[256]; 390232998Sgonzo caddr_t preload_ptr = (caddr_t)&fake_preload[0]; 391232998Sgonzo size_t size = 0; 392232998Sgonzo 393233019Sgonzo#define PRELOAD_PUSH_VALUE(type, value) do { \ 394233019Sgonzo *(type *)(preload_ptr + size) = (value); \ 395233019Sgonzo size += sizeof(type); \ 396233019Sgonzo} while (0); 397233019Sgonzo 398232998Sgonzo /* 399232998Sgonzo * Provide kernel module file information 400232998Sgonzo */ 401233019Sgonzo PRELOAD_PUSH_VALUE(uint32_t, MODINFO_NAME); 402233019Sgonzo PRELOAD_PUSH_VALUE(uint32_t, strlen("kernel") + 1); 403232998Sgonzo strcpy((char*)(preload_ptr + size), "kernel"); 404232998Sgonzo size += strlen("kernel") + 1; 405232998Sgonzo size = roundup(size, sizeof(u_long)); 406232998Sgonzo 407233019Sgonzo PRELOAD_PUSH_VALUE(uint32_t, MODINFO_TYPE); 408233019Sgonzo PRELOAD_PUSH_VALUE(uint32_t, strlen("elf kernel") + 1); 409232998Sgonzo strcpy((char*)(preload_ptr + size), "elf kernel"); 410232998Sgonzo size += strlen("elf kernel") + 1; 411232998Sgonzo size = roundup(size, sizeof(u_long)); 412232998Sgonzo 413233019Sgonzo PRELOAD_PUSH_VALUE(uint32_t, MODINFO_ADDR); 414233019Sgonzo PRELOAD_PUSH_VALUE(uint32_t, sizeof(vm_offset_t)); 415233019Sgonzo PRELOAD_PUSH_VALUE(vm_offset_t, KERNLOADADDR); 416232998Sgonzo size = roundup(size, sizeof(u_long)); 417232998Sgonzo 418233019Sgonzo PRELOAD_PUSH_VALUE(uint32_t, MODINFO_SIZE); 419233019Sgonzo PRELOAD_PUSH_VALUE(uint32_t, sizeof(size_t)); 420233019Sgonzo PRELOAD_PUSH_VALUE(size_t, (size_t)&end - KERNLOADADDR); 421232998Sgonzo size = roundup(size, sizeof(u_long)); 422232998Sgonzo 423232998Sgonzo /* End marker */ 424233019Sgonzo PRELOAD_PUSH_VALUE(uint32_t, 0); 425233019Sgonzo PRELOAD_PUSH_VALUE(uint32_t, 0); 426232998Sgonzo 427233019Sgonzo#undef PRELOAD_PUSH_VALUE 428233019Sgonzo 429232998Sgonzo KASSERT((size < sizeof(fake_preload)), 430232998Sgonzo ("fake preload size is more thenallocated")); 431232998Sgonzo 432232998Sgonzo preload_metadata = (void *)fake_preload; 433232998Sgonzo 434202909Sgonzo#ifdef DDB 435202909Sgonzo Elf_Size *trampoline_data = (Elf_Size*)kernel_kseg0_end; 436202909Sgonzo Elf_Size symtabsize = 0; 437202909Sgonzo 438202909Sgonzo if (trampoline_data[0] == SYMTAB_MAGIC) { 439202909Sgonzo symtabsize = trampoline_data[1]; 440202909Sgonzo kernel_kseg0_end += 2 * sizeof(Elf_Size); 441202909Sgonzo /* start of .symtab */ 442202909Sgonzo ksym_start = kernel_kseg0_end; 443202909Sgonzo kernel_kseg0_end += symtabsize; 444202909Sgonzo /* end of .strtab */ 445202909Sgonzo ksym_end = kernel_kseg0_end; 446202909Sgonzo } 447202909Sgonzo#endif 448202909Sgonzo} 449202909Sgonzo 450203697Sneel#ifdef SMP 451178172Simpvoid 452203697Sneelmips_pcpu_tlb_init(struct pcpu *pcpu) 453178172Simp{ 454203180Sneel vm_paddr_t pa; 455209243Sjchandra pt_entry_t pte; 456203180Sneel 457203180Sneel /* 458203180Sneel * Map the pcpu structure at the virtual address 'pcpup'. 459203180Sneel * We use a wired tlb index to do this one-time mapping. 460203180Sneel */ 461203180Sneel pa = vtophys(pcpu); 462209482Sjchandra pte = PTE_D | PTE_V | PTE_G | PTE_C_CACHE; 463209243Sjchandra tlb_insert_wired(PCPU_TLB_ENTRY, (vm_offset_t)pcpup, 464209243Sjchandra TLBLO_PA_TO_PFN(pa) | pte, 465209243Sjchandra TLBLO_PA_TO_PFN(pa + PAGE_SIZE) | pte); 466203697Sneel} 467203180Sneel#endif 468203697Sneel 469203697Sneel/* 470203697Sneel * Initialise a struct pcpu. 471203697Sneel */ 472203697Sneelvoid 473203697Sneelcpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size) 474203697Sneel{ 475203697Sneel 476203697Sneel pcpu->pc_next_asid = 1; 477203697Sneel pcpu->pc_asid_generation = 1; 478203697Sneel#ifdef SMP 479216862Sjmallett if ((vm_offset_t)pcpup >= VM_MIN_KERNEL_ADDRESS && 480216862Sjmallett (vm_offset_t)pcpup <= VM_MAX_KERNEL_ADDRESS) { 481203697Sneel mips_pcpu_tlb_init(pcpu); 482216862Sjmallett } 483203697Sneel#endif 484178172Simp} 485178172Simp 486178172Simpint 487178172Simpfill_dbregs(struct thread *td, struct dbreg *dbregs) 488178172Simp{ 489178172Simp 490178172Simp /* No debug registers on mips */ 491178172Simp return (ENOSYS); 492178172Simp} 493178172Simp 494178172Simpint 495178172Simpset_dbregs(struct thread *td, struct dbreg *dbregs) 496178172Simp{ 497178172Simp 498178172Simp /* No debug registers on mips */ 499178172Simp return (ENOSYS); 500178172Simp} 501178172Simp 502178172Simpvoid 503178172Simpspinlock_enter(void) 504178172Simp{ 505178172Simp struct thread *td; 506214835Sjhb register_t intr; 507178172Simp 508178172Simp td = curthread; 509214835Sjhb if (td->td_md.md_spinlock_count == 0) { 510214835Sjhb intr = intr_disable(); 511214835Sjhb td->td_md.md_spinlock_count = 1; 512214835Sjhb td->td_md.md_saved_intr = intr; 513214835Sjhb } else 514214835Sjhb td->td_md.md_spinlock_count++; 515178172Simp critical_enter(); 516178172Simp} 517178172Simp 518178172Simpvoid 519178172Simpspinlock_exit(void) 520178172Simp{ 521178172Simp struct thread *td; 522214835Sjhb register_t intr; 523178172Simp 524178172Simp td = curthread; 525178172Simp critical_exit(); 526214835Sjhb intr = td->td_md.md_saved_intr; 527178172Simp td->td_md.md_spinlock_count--; 528178172Simp if (td->td_md.md_spinlock_count == 0) 529214835Sjhb intr_restore(intr); 530178172Simp} 531178172Simp 532178172Simp/* 533178172Simp * call platform specific code to halt (until next interrupt) for the idle loop 534178172Simp */ 535178172Simpvoid 536178471Sjeffcpu_idle(int busy) 537178172Simp{ 538216862Sjmallett KASSERT((mips_rd_status() & MIPS_SR_INT_IE) != 0, 539216862Sjmallett ("interrupts disabled in idle process.")); 540216862Sjmallett KASSERT((mips_rd_status() & MIPS_INT_MASK) != 0, 541216862Sjmallett ("all interrupts masked in idle process.")); 542216862Sjmallett 543216862Sjmallett if (!busy) { 544216862Sjmallett critical_enter(); 545216862Sjmallett cpu_idleclock(); 546216862Sjmallett } 547226517Sjchandra mips_wait(); 548216862Sjmallett if (!busy) { 549216862Sjmallett cpu_activeclock(); 550216862Sjmallett critical_exit(); 551216862Sjmallett } 552178172Simp} 553178172Simp 554187293Simpint 555187293Simpcpu_idle_wakeup(int cpu) 556178172Simp{ 557178172Simp 558187293Simp return (0); 559178172Simp} 560202046Simp 561202046Simpint 562217345Sjchandrais_cacheable_mem(vm_paddr_t pa) 563202046Simp{ 564202046Simp int i; 565202046Simp 566202046Simp for (i = 0; physmem_desc[i + 1] != 0; i += 2) { 567217345Sjchandra if (pa >= physmem_desc[i] && pa < physmem_desc[i + 1]) 568202046Simp return (1); 569202046Simp } 570202046Simp 571202046Simp return (0); 572202046Simp} 573