machdep.c revision 1.106
1/* $NetBSD: machdep.c,v 1.106 2009/12/16 19:01:24 matt 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.106 2009/12/16 19:01:24 matt 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. */ 97struct cpu_info cpu_info_store; 98 99/* Maps for VM objects. */ 100struct vm_map *mb_map = NULL; 101struct vm_map *phys_map = NULL; 102 103int physmem; /* Total physical memory */ 104char *bootinfo = NULL; /* pointer to bootinfo structure */ 105 106char bootstring[512]; /* Boot command */ 107int netboot; /* Are we netbooting? */ 108 109char *nfsroot_bstr = NULL; 110char *root_bstr = NULL; 111int bootunit = -1; 112int bootpart = -1; 113 114int cpuspeed; 115 116u_int cobalt_id; 117static const char * const cobalt_model[] = 118{ 119 [COBALT_ID_QUBE2700] = "Cobalt Qube 2700", 120 [COBALT_ID_RAQ] = "Cobalt RaQ", 121 [COBALT_ID_QUBE2] = "Cobalt Qube 2", 122 [COBALT_ID_RAQ2] = "Cobalt RaQ 2" 123}; 124#define COBALT_MODELS __arraycount(cobalt_model) 125 126phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX]; 127int mem_cluster_cnt; 128 129void mach_init(unsigned int, u_int, char*); 130void decode_bootstring(void); 131static char *strtok_light(char *, const char); 132static u_int read_board_id(void); 133 134/* 135 * safepri is a safe priority for sleep to set for a spin-wait during 136 * autoconfiguration or after a panic. Used as an argument to splx(). 137 */ 138int safepri = MIPS1_PSL_LOWIPL; 139 140extern char *esym; 141 142/* 143 * Do all the stuff that locore normally does before calling main(). 144 */ 145void 146mach_init(unsigned int memsize, u_int bim, char *bip) 147{ 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 || bi_magic->magic != BOOTINFO_MAGIC) 203 bi_msg = "invalid bootinfo structure.\n"; 204 else 205 bi_msg = NULL; 206 } else 207 bi_msg = "invalid bootinfo (standalone boot?)\n"; 208 209#if NKSYMS || defined(DDB) || defined(MODULAR) 210 bi_syms = lookup_bootinfo(BTINFO_SYMTAB); 211 212 /* Load symbol table if present */ 213 if (bi_syms != NULL) { 214 nsym = bi_syms->nsym; 215 ssym = (void *)bi_syms->ssym; 216 esym = (void *)bi_syms->esym; 217 kernend = (void *)mips_round_page(esym); 218 } 219#endif 220 221 bi_howto = lookup_bootinfo(BTINFO_HOWTO); 222 if (bi_howto != NULL) 223 boothowto = bi_howto->bi_howto; 224 225 cobalt_id = read_board_id(); 226 if (cobalt_id >= COBALT_MODELS || cobalt_model[cobalt_id] == NULL) 227 sprintf(cpu_model, "Cobalt unknown model (board ID %u)", 228 cobalt_id); 229 else 230 strcpy(cpu_model, cobalt_model[cobalt_id]); 231 232 switch (cobalt_id) { 233 case COBALT_ID_QUBE2700: 234 case COBALT_ID_RAQ: 235 cpuspeed = 150; /* MHz */ 236 break; 237 case COBALT_ID_QUBE2: 238 case COBALT_ID_RAQ2: 239 cpuspeed = 250; /* MHz */ 240 break; 241 default: 242 /* assume the fastest, so that delay(9) works */ 243 cpuspeed = 250; 244 break; 245 } 246 curcpu()->ci_cpu_freq = cpuspeed * 1000 * 1000; 247 curcpu()->ci_cycles_per_hz = (curcpu()->ci_cpu_freq + hz / 2) / hz; 248 curcpu()->ci_divisor_delay = 249 ((curcpu()->ci_cpu_freq + (1000000 / 2)) / 1000000); 250 /* all models have Rm5200, which is CPU_MIPS_DOUBLE_COUNT */ 251 curcpu()->ci_cycles_per_hz /= 2; 252 curcpu()->ci_divisor_delay /= 2; 253 254 physmem = btoc(memsize - MIPS_KSEG0_START); 255 256 consinit(); 257 258 if (bi_msg != NULL) 259 printf(bi_msg); 260 261 uvm_setpagesize(); 262 263 /* 264 * Copy exception-dispatch code down to exception vector. 265 * Initialize locore-function vector. 266 * Clear out the I and D caches. 267 */ 268 mips_vector_init(); 269 270 /* 271 * The boot command is passed in the top 512 bytes, 272 * so don't clobber that. 273 */ 274 mem_clusters[0].start = 0; 275 mem_clusters[0].size = ctob(physmem) - 512; 276 mem_cluster_cnt = 1; 277 278 memcpy(bootstring, (char *)(memsize - 512), 512); 279 memset((char *)(memsize - 512), 0, 512); 280 bootstring[511] = '\0'; 281 282 decode_bootstring(); 283 284#if NKSYMS || defined(DDB) || defined(MODULAR) 285 /* init symbols if present */ 286 if ((bi_syms != NULL) && (esym != NULL)) 287 ksyms_addsyms_elf(esym - ssym, ssym, esym); 288#endif 289#ifdef DDB 290 if (boothowto & RB_KDB) 291 Debugger(); 292#endif 293#ifdef KGDB 294 if (boothowto & RB_KDB) 295 kgdb_connect(0); 296#endif 297 298 /* 299 * Load the rest of the available pages into the VM system. 300 */ 301 first = round_page(MIPS_KSEG0_TO_PHYS(kernend)); 302 last = mem_clusters[0].start + mem_clusters[0].size; 303 uvm_page_physload(atop(first), atop(last), atop(first), atop(last), 304 VM_FREELIST_DEFAULT); 305 306 /* 307 * Initialize error message buffer (at end of core). 308 */ 309 mips_init_msgbuf(); 310 311 pmap_bootstrap(); 312 313 mips_init_lwp0_uarea(); 314} 315 316/* 317 * Allocate memory for variable-sized tables, 318 */ 319void 320cpu_startup(void) 321{ 322 vaddr_t minaddr, maxaddr; 323 char pbuf[9]; 324 325 /* 326 * Good {morning,afternoon,evening,night}. 327 */ 328 printf("%s%s", copyright, version); 329 printf("%s\n", cpu_model); 330 format_bytes(pbuf, sizeof(pbuf), ctob(physmem)); 331 printf("total memory = %s\n", pbuf); 332 333 minaddr = 0; 334 /* 335 * Allocate a submap for physio. 336 */ 337 phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 338 VM_PHYS_SIZE, 0, false, NULL); 339 340 /* 341 * (No need to allocate an mbuf cluster submap. Mbuf clusters 342 * are allocated via the pool allocator, and we use KSEG to 343 * map those pages.) 344 */ 345 346 format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free)); 347 printf("avail memory = %s\n", pbuf); 348} 349 350static int waittime = -1; 351 352void 353cpu_reboot(int howto, char *bootstr) 354{ 355 356 /* Take a snapshot before clobbering any registers. */ 357 if (curlwp) 358 savectx(curpcb); 359 360 if (cold) { 361 howto |= RB_HALT; 362 goto haltsys; 363 } 364 365 /* If "always halt" was specified as a boot flag, obey. */ 366 if (boothowto & RB_HALT) 367 howto |= RB_HALT; 368 369 boothowto = howto; 370 if ((howto & RB_NOSYNC) == 0 && (waittime < 0)) { 371 waittime = 0; 372 vfs_shutdown(); 373 374 /* 375 * If we've been adjusting the clock, the todr 376 * will be out of synch; adjust it now. 377 */ 378 resettodr(); 379 } 380 381 splhigh(); 382 383 if (howto & RB_DUMP) 384 dumpsys(); 385 386 haltsys: 387 doshutdownhooks(); 388 389 pmf_system_shutdown(boothowto); 390 391 if (howto & RB_HALT) { 392 printf("\n"); 393 printf("The operating system has halted.\n"); 394 printf("Please press any key to reboot.\n\n"); 395 cnpollc(1); /* For proper keyboard command handling */ 396 cngetc(); 397 cnpollc(0); 398 } 399 400 printf("rebooting...\n\n"); 401 delay(500000); 402 403 *(volatile char *)MIPS_PHYS_TO_KSEG1(LED_ADDR) = LED_RESET; 404 printf("WARNING: reboot failed!\n"); 405 406 for (;;) 407 ; 408} 409 410 411void 412decode_bootstring(void) 413{ 414 char *work; 415 char *equ; 416 int i; 417 418 /* break apart bootstring on ' ' boundries and itterate */ 419 work = strtok_light(bootstring, ' '); 420 while (work != '\0') { 421 /* if starts with '-', we got options, walk its decode */ 422 if (work[0] == '-') { 423 i = 1; 424 while (work[i] != ' ' && work[i] != '\0') { 425 BOOT_FLAG(work[i], boothowto); 426 i++; 427 } 428 } else 429 430 /* if it has a '=' its an assignment, switch and set */ 431 if ((equ = strchr(work, '=')) != '\0') { 432 if (memcmp("nfsroot=", work, 8) == 0) { 433 nfsroot_bstr = (equ + 1); 434 } else 435 if (memcmp("root=", work, 5) == 0) { 436 root_bstr = (equ + 1); 437 } 438 } else 439 440 /* else it a single value, switch and process */ 441 if (memcmp("single", work, 5) == 0) { 442 boothowto |= RB_SINGLE; 443 } else 444 if (memcmp("ro", work, 2) == 0) { 445 /* this is also inserted by the firmware */ 446 } 447 448 /* grab next token */ 449 work = strtok_light(NULL, ' '); 450 } 451 452 if (root_bstr != NULL) { 453 /* this should be of the form "/dev/hda1" */ 454 /* [abcd][1234] drive partition linux probe order */ 455 if ((memcmp("/dev/hd", root_bstr, 7) == 0) && 456 (strlen(root_bstr) == 9) ){ 457 bootunit = root_bstr[7] - 'a'; 458 bootpart = root_bstr[8] - '1'; 459 } 460 } 461 462 if (nfsroot_bstr != NULL) 463 netboot = 1; 464} 465 466 467static char * 468strtok_light(char *str, const char sep) 469{ 470 static char *proc; 471 char *head; 472 char *work; 473 474 if (str != NULL) 475 proc = str; 476 if (proc == NULL) /* end of string return NULL */ 477 return proc; 478 479 head = proc; 480 481 work = strchr(proc, sep); 482 if (work == NULL) { /* we hit the end */ 483 proc = work; 484 } else { 485 proc = (work + 1); 486 *work = '\0'; 487 } 488 489 return head; 490} 491 492/* 493 * Look up information in bootinfo of boot loader. 494 */ 495void * 496lookup_bootinfo(int type) 497{ 498 struct btinfo_common *bt; 499 char *help = bootinfo; 500 501 /* Check for a bootinfo record first. */ 502 if (help == NULL) { 503 printf("##### help == NULL\n"); 504 return NULL; 505 } 506 507 do { 508 bt = (struct btinfo_common *)help; 509 printf("Type %d @0x%x\n", bt->type, (u_int)bt); 510 if (bt->type == type) 511 return (void *)help; 512 help += bt->next; 513 } while (bt->next != 0 && 514 (size_t)help < (size_t)bootinfo + BOOTINFO_SIZE); 515 516 return NULL; 517} 518 519/* 520 * Get board ID of cobalt models. 521 * 522 * The board ID info is stored at the PCI config register 523 * on the PCI-ISA bridge part of the VIA VT82C586 chipset. 524 * We can't use pci_conf_read(9) yet here, so read it directly. 525 */ 526static u_int 527read_board_id(void) 528{ 529 volatile uint32_t *pcicfg_addr, *pcicfg_data; 530 uint32_t reg; 531 532#define PCIB_PCI_BUS 0 533#define PCIB_PCI_DEV 9 534#define PCIB_PCI_FUNC 0 535#define PCIB_BOARD_ID_REG 0x94 536#define COBALT_BOARD_ID(reg) ((reg & 0x000000f0) >> 4) 537 538 pcicfg_addr = (uint32_t *)MIPS_PHYS_TO_KSEG1(GT_BASE + GT_PCICFG_ADDR); 539 pcicfg_data = (uint32_t *)MIPS_PHYS_TO_KSEG1(GT_BASE + GT_PCICFG_DATA); 540 541 *pcicfg_addr = PCICFG_ENABLE | 542 (PCIB_PCI_BUS << 16) | (PCIB_PCI_DEV << 11) | (PCIB_PCI_FUNC << 8) | 543 PCIB_BOARD_ID_REG; 544 reg = *pcicfg_data; 545 *pcicfg_addr = 0; 546 547 return COBALT_BOARD_ID(reg); 548} 549