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