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