1 /* $NetBSD: machdep.c,v 1.109 2010/02/08 19:02:27 joerg Exp $ */ 2 3 /*- 4 * Copyright (c) 2006 Izumi Tsutsui. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 /* 28 * Copyright (c) 2000 Soren S. Jorvang. All rights reserved. 29 * 30 * Redistribution and use in source and binary forms, with or without 31 * modification, are permitted provided that the following conditions 32 * are met: 33 * 1. Redistributions of source code must retain the above copyright 34 * notice, this list of conditions, and the following disclaimer. 35 * 2. Redistributions in binary form must reproduce the above copyright 36 * notice, this list of conditions and the following disclaimer in the 37 * documentation and/or other materials provided with the distribution. 38 * 39 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 40 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 42 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 43 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 44 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 45 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 47 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 48 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 49 * SUCH DAMAGE. 50 */ 51 52 #include <sys/cdefs.h> 53 __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.109 2010/02/08 19:02:27 joerg Exp $"); 54 55 #include "opt_ddb.h" 56 #include "opt_kgdb.h" 57 #include "opt_modular.h" 58 #include "opt_execfmt.h" 59 60 #include <sys/param.h> 61 #include <sys/systm.h> 62 #include <sys/kernel.h> 63 #include <sys/proc.h> 64 #include <sys/reboot.h> 65 #include <sys/mount.h> 66 #include <sys/kcore.h> 67 #include <sys/boot_flag.h> 68 #include <sys/ksyms.h> 69 #include <sys/cpu.h> 70 #include <sys/device.h> 71 72 #include <uvm/uvm_extern.h> 73 74 #include <machine/bootinfo.h> 75 #include <machine/psl.h> 76 77 #include <mips/locore.h> 78 79 #include <dev/cons.h> 80 81 #include <cobalt/dev/gtreg.h> 82 83 #ifdef KGDB 84 #include <sys/kgdb.h> 85 #endif 86 87 #include "ksyms.h" 88 89 #if NKSYMS || defined(DDB) || defined(MODULAR) 90 #include <machine/db_machdep.h> 91 #include <ddb/db_extern.h> 92 #define ELFSIZE DB_ELFSIZE 93 #include <sys/exec_elf.h> 94 #endif 95 96 /* Our exported CPU info; we can have only one. */ 97 struct cpu_info cpu_info_store; 98 99 /* Maps for VM objects. */ 100 struct vm_map *phys_map = NULL; 101 102 int physmem; /* Total physical memory */ 103 void *bootinfo = NULL; /* pointer to bootinfo structure */ 104 105 char bootstring[512]; /* Boot command */ 106 int netboot; /* Are we netbooting? */ 107 108 char *nfsroot_bstr = NULL; 109 char *root_bstr = NULL; 110 int bootunit = -1; 111 int bootpart = -1; 112 113 int cpuspeed; 114 115 u_int cobalt_id; 116 static const char * const cobalt_model[] = 117 { 118 [COBALT_ID_QUBE2700] = "Cobalt Qube 2700", 119 [COBALT_ID_RAQ] = "Cobalt RaQ", 120 [COBALT_ID_QUBE2] = "Cobalt Qube 2", 121 [COBALT_ID_RAQ2] = "Cobalt RaQ 2" 122 }; 123 #define COBALT_MODELS __arraycount(cobalt_model) 124 125 phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX]; 126 int mem_cluster_cnt; 127 128 void mach_init(intptr_t, u_int, int32_t); 129 void decode_bootstring(void); 130 static char *strtok_light(char *, const char); 131 static u_int read_board_id(void); 132 133 /* 134 * safepri is a safe priority for sleep to set for a spin-wait during 135 * autoconfiguration or after a panic. Used as an argument to splx(). 136 */ 137 int safepri = MIPS1_PSL_LOWIPL; 138 139 extern char *esym; 140 141 /* 142 * Do all the stuff that locore normally does before calling main(). 143 */ 144 void 145 mach_init(intptr_t memsize, u_int bim, int32_t bip32) 146 { 147 void *bip = (void *)(intptr_t)bip32; 148 char *kernend; 149 u_long first, last; 150 extern char edata[], end[]; 151 const char *bi_msg; 152 #if NKSYMS || defined(DDB) || defined(MODULAR) 153 int nsym = 0; 154 char *ssym = 0; 155 struct btinfo_symtab *bi_syms; 156 #endif 157 struct btinfo_howto *bi_howto; 158 159 /* 160 * Clear the BSS segment (if needed). 161 */ 162 if (memcmp(((Elf_Ehdr *)end)->e_ident, ELFMAG, SELFMAG) == 0 && 163 ((Elf_Ehdr *)end)->e_ident[EI_CLASS] == ELFCLASS) { 164 esym = end; 165 #if NKSYMS || defined(DDB) || defined(MODULAR) 166 esym += ((Elf_Ehdr *)end)->e_entry; 167 #endif 168 kernend = (char *)mips_round_page(esym); 169 /* 170 * We don't have to clear BSS here 171 * since our bootloader already does it. 172 */ 173 #if 0 174 memset(edata, 0, end - edata); 175 #endif 176 } else { 177 kernend = (void *)mips_round_page(end); 178 /* 179 * No symbol table, so assume we are loaded by 180 * the firmware directly with "bfd" command. 181 * The firmware loader doesn't clear BSS of 182 * a loaded kernel, so do it here. 183 */ 184 memset(edata, 0, kernend - edata); 185 186 /* 187 * XXX 188 * lwp0 and cpu_info_store are allocated in BSS 189 * and initialized before mach_init() is called, 190 * so restore them again. 191 */ 192 lwp0.l_cpu = &cpu_info_store; 193 cpu_info_store.ci_curlwp = &lwp0; 194 } 195 196 /* Check for valid bootinfo passed from bootstrap */ 197 if (bim == BOOTINFO_MAGIC) { 198 struct btinfo_magic *bi_magic; 199 200 bootinfo = bip; 201 bi_magic = lookup_bootinfo(BTINFO_MAGIC); 202 if (bi_magic == NULL) { 203 bi_msg = "missing bootinfo structure"; 204 bim = (uintptr_t)bip; 205 } else if (bi_magic->magic != BOOTINFO_MAGIC) { 206 bi_msg = "invalid bootinfo structure"; 207 bim = bi_magic->magic; 208 } else 209 bi_msg = NULL; 210 } else { 211 bi_msg = "invalid bootinfo (standalone boot?)"; 212 } 213 214 #if NKSYMS || defined(DDB) || defined(MODULAR) 215 bi_syms = lookup_bootinfo(BTINFO_SYMTAB); 216 217 /* Load symbol table if present */ 218 if (bi_syms != NULL) { 219 nsym = bi_syms->nsym; 220 ssym = (void *)(intptr_t)bi_syms->ssym; 221 esym = (void *)(intptr_t)bi_syms->esym; 222 kernend = (void *)mips_round_page(esym); 223 } 224 #endif 225 226 bi_howto = lookup_bootinfo(BTINFO_HOWTO); 227 if (bi_howto != NULL) 228 boothowto = bi_howto->bi_howto; 229 230 cobalt_id = read_board_id(); 231 if (cobalt_id >= COBALT_MODELS || cobalt_model[cobalt_id] == NULL) 232 sprintf(cpu_model, "Cobalt unknown model (board ID %u)", 233 cobalt_id); 234 else 235 strcpy(cpu_model, cobalt_model[cobalt_id]); 236 237 switch (cobalt_id) { 238 case COBALT_ID_QUBE2700: 239 case COBALT_ID_RAQ: 240 cpuspeed = 150; /* MHz */ 241 break; 242 case COBALT_ID_QUBE2: 243 case COBALT_ID_RAQ2: 244 cpuspeed = 250; /* MHz */ 245 break; 246 default: 247 /* assume the fastest, so that delay(9) works */ 248 cpuspeed = 250; 249 break; 250 } 251 curcpu()->ci_cpu_freq = cpuspeed * 1000 * 1000; 252 curcpu()->ci_cycles_per_hz = (curcpu()->ci_cpu_freq + hz / 2) / hz; 253 curcpu()->ci_divisor_delay = 254 ((curcpu()->ci_cpu_freq + (1000000 / 2)) / 1000000); 255 /* all models have Rm5200, which is CPU_MIPS_DOUBLE_COUNT */ 256 curcpu()->ci_cycles_per_hz /= 2; 257 curcpu()->ci_divisor_delay /= 2; 258 259 physmem = btoc(memsize - MIPS_KSEG0_START); 260 261 consinit(); 262 263 if (bi_msg != NULL) 264 printf("%s: magic=%#x\n", bi_msg, bim); 265 266 uvm_setpagesize(); 267 268 /* 269 * Copy exception-dispatch code down to exception vector. 270 * Initialize locore-function vector. 271 * Clear out the I and D caches. 272 */ 273 mips_vector_init(); 274 275 /* 276 * The boot command is passed in the top 512 bytes, 277 * so don't clobber that. 278 */ 279 mem_clusters[0].start = 0; 280 mem_clusters[0].size = ctob(physmem) - 512; 281 mem_cluster_cnt = 1; 282 283 memcpy(bootstring, (char *)(memsize - 512), 512); 284 memset((char *)(memsize - 512), 0, 512); 285 bootstring[511] = '\0'; 286 287 decode_bootstring(); 288 289 #if NKSYMS || defined(DDB) || defined(MODULAR) 290 /* init symbols if present */ 291 if ((bi_syms != NULL) && (esym != NULL)) 292 ksyms_addsyms_elf(esym - ssym, ssym, esym); 293 #endif 294 #ifdef DDB 295 if (boothowto & RB_KDB) 296 Debugger(); 297 #endif 298 #ifdef KGDB 299 if (boothowto & RB_KDB) 300 kgdb_connect(0); 301 #endif 302 303 /* 304 * Load the rest of the available pages into the VM system. 305 */ 306 first = round_page(MIPS_KSEG0_TO_PHYS(kernend)); 307 last = mem_clusters[0].start + mem_clusters[0].size; 308 uvm_page_physload(atop(first), atop(last), atop(first), atop(last), 309 VM_FREELIST_DEFAULT); 310 311 /* 312 * Initialize error message buffer (at end of core). 313 */ 314 mips_init_msgbuf(); 315 316 pmap_bootstrap(); 317 318 mips_init_lwp0_uarea(); 319 } 320 321 /* 322 * Allocate memory for variable-sized tables, 323 */ 324 void 325 cpu_startup(void) 326 { 327 vaddr_t minaddr, maxaddr; 328 char pbuf[9]; 329 330 /* 331 * Good {morning,afternoon,evening,night}. 332 */ 333 printf("%s%s", copyright, version); 334 printf("%s\n", cpu_model); 335 format_bytes(pbuf, sizeof(pbuf), ctob(physmem)); 336 printf("total memory = %s\n", pbuf); 337 338 minaddr = 0; 339 /* 340 * Allocate a submap for physio. 341 */ 342 phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 343 VM_PHYS_SIZE, 0, false, NULL); 344 345 /* 346 * (No need to allocate an mbuf cluster submap. Mbuf clusters 347 * are allocated via the pool allocator, and we use KSEG to 348 * map those pages.) 349 */ 350 351 format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free)); 352 printf("avail memory = %s\n", pbuf); 353 } 354 355 static int waittime = -1; 356 357 void 358 cpu_reboot(int howto, char *bootstr) 359 { 360 361 /* Take a snapshot before clobbering any registers. */ 362 if (curlwp) 363 savectx(curpcb); 364 365 if (cold) { 366 howto |= RB_HALT; 367 goto haltsys; 368 } 369 370 /* If "always halt" was specified as a boot flag, obey. */ 371 if (boothowto & RB_HALT) 372 howto |= RB_HALT; 373 374 boothowto = howto; 375 if ((howto & RB_NOSYNC) == 0 && (waittime < 0)) { 376 waittime = 0; 377 vfs_shutdown(); 378 379 /* 380 * If we've been adjusting the clock, the todr 381 * will be out of synch; adjust it now. 382 */ 383 resettodr(); 384 } 385 386 splhigh(); 387 388 if (howto & RB_DUMP) 389 dumpsys(); 390 391 haltsys: 392 doshutdownhooks(); 393 394 pmf_system_shutdown(boothowto); 395 396 if (howto & RB_HALT) { 397 printf("\n"); 398 printf("The operating system has halted.\n"); 399 printf("Please press any key to reboot.\n\n"); 400 cnpollc(1); /* For proper keyboard command handling */ 401 cngetc(); 402 cnpollc(0); 403 } 404 405 printf("rebooting...\n\n"); 406 delay(500000); 407 408 *(volatile char *)MIPS_PHYS_TO_KSEG1(LED_ADDR) = LED_RESET; 409 printf("WARNING: reboot failed!\n"); 410 411 for (;;) 412 ; 413 } 414 415 416 void 417 decode_bootstring(void) 418 { 419 char *work; 420 char *equ; 421 int i; 422 423 /* break apart bootstring on ' ' boundries and itterate */ 424 work = strtok_light(bootstring, ' '); 425 while (work != '\0') { 426 /* if starts with '-', we got options, walk its decode */ 427 if (work[0] == '-') { 428 i = 1; 429 while (work[i] != ' ' && work[i] != '\0') { 430 BOOT_FLAG(work[i], boothowto); 431 i++; 432 } 433 } else 434 435 /* if it has a '=' its an assignment, switch and set */ 436 if ((equ = strchr(work, '=')) != '\0') { 437 if (memcmp("nfsroot=", work, 8) == 0) { 438 nfsroot_bstr = (equ + 1); 439 } else 440 if (memcmp("root=", work, 5) == 0) { 441 root_bstr = (equ + 1); 442 } 443 } else 444 445 /* else it a single value, switch and process */ 446 if (memcmp("single", work, 5) == 0) { 447 boothowto |= RB_SINGLE; 448 } else 449 if (memcmp("ro", work, 2) == 0) { 450 /* this is also inserted by the firmware */ 451 } 452 453 /* grab next token */ 454 work = strtok_light(NULL, ' '); 455 } 456 457 if (root_bstr != NULL) { 458 /* this should be of the form "/dev/hda1" */ 459 /* [abcd][1234] drive partition linux probe order */ 460 if ((memcmp("/dev/hd", root_bstr, 7) == 0) && 461 (strlen(root_bstr) == 9) ){ 462 bootunit = root_bstr[7] - 'a'; 463 bootpart = root_bstr[8] - '1'; 464 } 465 } 466 467 if (nfsroot_bstr != NULL) 468 netboot = 1; 469 } 470 471 472 static char * 473 strtok_light(char *str, const char sep) 474 { 475 static char *proc; 476 char *head; 477 char *work; 478 479 if (str != NULL) 480 proc = str; 481 if (proc == NULL) /* end of string return NULL */ 482 return proc; 483 484 head = proc; 485 486 work = strchr(proc, sep); 487 if (work == NULL) { /* we hit the end */ 488 proc = work; 489 } else { 490 proc = (work + 1); 491 *work = '\0'; 492 } 493 494 return head; 495 } 496 497 /* 498 * Look up information in bootinfo of boot loader. 499 */ 500 void * 501 lookup_bootinfo(unsigned int type) 502 { 503 struct btinfo_common *bt; 504 char *help = bootinfo; 505 506 /* Check for a bootinfo record first. */ 507 if (help == NULL) { 508 printf("##### help == NULL\n"); 509 return NULL; 510 } 511 512 do { 513 bt = (struct btinfo_common *)help; 514 printf("Type %d @%p\n", bt->type, (void *)(intptr_t)bt); 515 if (bt->type == type) 516 return (void *)help; 517 help += bt->next; 518 } while (bt->next != 0 && 519 (size_t)help < (size_t)bootinfo + BOOTINFO_SIZE); 520 521 return NULL; 522 } 523 524 /* 525 * Get board ID of cobalt models. 526 * 527 * The board ID info is stored at the PCI config register 528 * on the PCI-ISA bridge part of the VIA VT82C586 chipset. 529 * We can't use pci_conf_read(9) yet here, so read it directly. 530 */ 531 static u_int 532 read_board_id(void) 533 { 534 volatile uint32_t *pcicfg_addr, *pcicfg_data; 535 uint32_t reg; 536 537 #define PCIB_PCI_BUS 0 538 #define PCIB_PCI_DEV 9 539 #define PCIB_PCI_FUNC 0 540 #define PCIB_BOARD_ID_REG 0x94 541 #define COBALT_BOARD_ID(reg) ((reg & 0x000000f0) >> 4) 542 543 pcicfg_addr = (uint32_t *)MIPS_PHYS_TO_KSEG1(GT_BASE + GT_PCICFG_ADDR); 544 pcicfg_data = (uint32_t *)MIPS_PHYS_TO_KSEG1(GT_BASE + GT_PCICFG_DATA); 545 546 *pcicfg_addr = PCICFG_ENABLE | 547 (PCIB_PCI_BUS << 16) | (PCIB_PCI_DEV << 11) | (PCIB_PCI_FUNC << 8) | 548 PCIB_BOARD_ID_REG; 549 reg = *pcicfg_data; 550 *pcicfg_addr = 0; 551 552 return COBALT_BOARD_ID(reg); 553 } 554