1 /* $NetBSD: machdep.c,v 1.30 2014/03/31 11:25:49 martin Exp $ */ 2 3 /*- 4 * Copyright (c) 2001 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include <sys/cdefs.h> 30 __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.30 2014/03/31 11:25:49 martin Exp $"); 31 32 #include "opt_ddb.h" 33 #include "opt_kloader.h" 34 #include "opt_kloader_kernel_path.h" 35 36 #include <sys/param.h> 37 #include <sys/systm.h> 38 #include <sys/kernel.h> 39 #include <sys/buf.h> 40 #include <sys/reboot.h> 41 #include <sys/mount.h> 42 #include <sys/kcore.h> 43 #include <sys/boot_flag.h> 44 #include <sys/device.h> 45 46 #include <uvm/uvm_extern.h> 47 48 #ifdef DDB 49 #include <machine/db_machdep.h> 50 #include <ddb/db_sym.h> 51 #include <ddb/db_extern.h> 52 #ifndef DB_ELFSIZE 53 #error Must define DB_ELFSIZE! 54 #endif 55 #define ELFSIZE DB_ELFSIZE 56 #include <sys/exec_elf.h> 57 #endif 58 59 #include <dev/cons.h> /* cntab access (cpu_reboot) */ 60 #include <machine/bootinfo.h> 61 #include <machine/psl.h> 62 #include <machine/intr.h>/* hardintr_init */ 63 #include <playstation2/playstation2/sifbios.h> 64 #include <playstation2/playstation2/interrupt.h> 65 66 #if defined KLOADER_KERNEL_PATH && !defined KLOADER 67 #error "define KLOADER" 68 #endif 69 #ifdef KLOADER 70 #include <machine/kloader.h> 71 #endif 72 73 struct cpu_info cpu_info_store; 74 75 struct vm_map *mb_map; 76 struct vm_map *phys_map; 77 phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX]; 78 int mem_cluster_cnt; 79 80 #ifdef DEBUG 81 static void bootinfo_dump(void); 82 #endif 83 84 void mach_init(void); 85 /* 86 * Do all the stuff that locore normally does before calling main(). 87 */ 88 void 89 mach_init(void) 90 { 91 extern char kernel_text[], edata[], end[]; 92 void *kernend; 93 struct pcb *pcb0; 94 vaddr_t v; 95 paddr_t start; 96 size_t size; 97 98 /* 99 * Clear the BSS segment. 100 */ 101 kernend = (void *)mips_round_page(end); 102 memset(edata, 0, kernend - edata); 103 104 /* disable all interrupt */ 105 interrupt_init_bootstrap(); 106 107 /* enable SIF BIOS */ 108 sifbios_init(); 109 110 consinit(); 111 112 printf("kernel_text=%p edata=%p end=%p\n", kernel_text, edata, end); 113 114 #ifdef DEBUG 115 bootinfo_dump(); 116 #endif 117 uvm_setpagesize(); 118 physmem = atop(PS2_MEMORY_SIZE); 119 120 /* 121 * Copy exception-dispatch code down to exception vector. 122 * Initialize locore-function vector. 123 * Clear out the I and D caches. 124 */ 125 mips_vector_init(); 126 127 /* 128 * Load the rest of the available pages into the VM system. 129 */ 130 start = (paddr_t)round_page(MIPS_KSEG0_TO_PHYS(kernend)); 131 size = PS2_MEMORY_SIZE - start - BOOTINFO_BLOCK_SIZE; 132 memset((void *)MIPS_PHYS_TO_KSEG1(start), 0, size); 133 134 /* kernel itself */ 135 mem_clusters[0].start = trunc_page(MIPS_KSEG0_TO_PHYS(kernel_text)); 136 mem_clusters[0].size = start - mem_clusters[0].start; 137 /* heap */ 138 mem_clusters[1].start = start; 139 mem_clusters[1].size = size; 140 /* load */ 141 printf("load memory %#lx, %#x\n", start, size); 142 uvm_page_physload(atop(start), atop(start + size), 143 atop(start), atop(start + size), VM_FREELIST_DEFAULT); 144 145 strcpy(cpu_model, "SONY PlayStation 2"); 146 147 /* 148 * Initialize error message buffer (at end of core). 149 */ 150 mips_init_msgbuf(); 151 152 pmap_bootstrap(); 153 154 /* 155 * Allocate uarea page for lwp0 and set it. 156 */ 157 v = uvm_pageboot_alloc(USPACE); 158 159 pcb0 = lwp_getpcb(&lwp0); 160 pcb0->pcb_context[11] = PSL_LOWIPL; /* SR */ 161 #ifdef IPL_ICU_MASK 162 pcb0->pcb_ppl = 0; 163 #endif 164 165 lwp0.l_md.md_regs = (struct frame *)(v + USPACE) - 1 166 } 167 168 /* 169 * Allocate memory for variable-sized tables, 170 */ 171 void 172 cpu_startup(void) 173 { 174 vaddr_t minaddr, maxaddr; 175 char pbuf[9]; 176 177 /* 178 * Good {morning,afternoon,evening,night}. 179 */ 180 printf("%s%s", copyright, version); 181 printf("%s\n", cpu_model); 182 format_bytes(pbuf, sizeof(pbuf), ctob(physmem)); 183 printf("total memory = %s\n", pbuf); 184 185 minaddr = 0; 186 /* 187 * Allocate a submap for physio. 188 */ 189 phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 190 VM_PHYS_SIZE, 0, false, NULL); 191 192 /* 193 * (No need to allocate an mbuf cluster submap. Mbuf clusters 194 * are allocated via the pool allocator, and we use KSEG to 195 * map those pages.) 196 */ 197 198 format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free)); 199 printf("avail memory = %s\n", pbuf); 200 } 201 202 void 203 cpu_reboot(int howto, char *bootstr) 204 { 205 #ifdef KLOADER 206 struct kloader_bootinfo kbi; 207 #endif 208 static int waittime = -1; 209 210 /* Take a snapshot before clobbering any registers. */ 211 if (curlwp) 212 savectx(curpcb); 213 214 if (cold) { 215 howto |= RB_HALT; 216 goto haltsys; 217 } 218 219 /* If "always halt" was specified as a boot flag, obey. */ 220 if (boothowto & RB_HALT) { 221 howto |= RB_HALT; 222 } 223 224 #ifdef KLOADER 225 /* No bootinfo is required. */ 226 kloader_bootinfo_set(&kbi, 0, NULL, NULL, true); 227 #ifndef KLOADER_KERNEL_PATH 228 #define KLOADER_KERNEL_PATH "/netbsd" 229 #endif 230 if ((howto & RB_HALT) == 0) 231 kloader_reboot_setup(KLOADER_KERNEL_PATH); 232 #endif 233 234 boothowto = howto; 235 if ((howto & RB_NOSYNC) == 0 && (waittime < 0)) { 236 waittime = 0; 237 vfs_shutdown(); 238 239 /* 240 * If we've been adjusting the clock, the todr 241 * will be out of synch; adjust it now. 242 */ 243 resettodr(); 244 } 245 246 splhigh(); 247 248 if (howto & RB_DUMP) 249 dumpsys(); 250 251 haltsys: 252 doshutdownhooks(); 253 254 pmf_system_shutdown(boothowto); 255 256 if ((howto & RB_POWERDOWN) == RB_POWERDOWN) 257 sifbios_halt(0); /* power down */ 258 else if (howto & RB_HALT) 259 sifbios_halt(1); /* halt */ 260 else { 261 #ifdef KLOADER 262 kloader_reboot(); 263 /* NOTREACHED */ 264 #endif 265 sifbios_halt(2); /* reset */ 266 } 267 268 while (1) 269 ; 270 /* NOTREACHED */ 271 } 272 273 #ifdef DEBUG 274 void 275 bootinfo_dump(void) 276 { 277 printf("devconf=%#x, option=%#x, rtc=%#x, pcmcia_type=%#x," 278 "sysconf=%#x\n", 279 BOOTINFO_REF(BOOTINFO_DEVCONF), 280 BOOTINFO_REF(BOOTINFO_OPTION_PTR), 281 BOOTINFO_REF(BOOTINFO_RTC), 282 BOOTINFO_REF(BOOTINFO_PCMCIA_TYPE), 283 BOOTINFO_REF(BOOTINFO_SYSCONF)); 284 } 285 #endif /* DEBUG */ 286