1 /* $NetBSD: machdep.c,v 1.4 2002/03/17 11:37:55 simonb Exp $ */ 2 3 /* 4 * Copyright 2000, 2001 5 * Broadcom Corporation. All rights reserved. 6 * 7 * This software is furnished under license and may be used and copied only 8 * in accordance with the following terms and conditions. Subject to these 9 * conditions, you may download, copy, install, use, modify and distribute 10 * modified or unmodified copies of this software in source and/or binary 11 * form. No title or ownership is transferred hereby. 12 * 13 * 1) Any source code used, modified or distributed must reproduce and 14 * retain this copyright notice and list of conditions as they appear in 15 * the source file. 16 * 17 * 2) No right is granted to use any trade name, trademark, or logo of 18 * Broadcom Corporation. Neither the "Broadcom Corporation" name nor any 19 * trademark or logo of Broadcom Corporation may be used to endorse or 20 * promote products derived from this software without the prior written 21 * permission of Broadcom Corporation. 22 * 23 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR IMPLIED 24 * WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF 25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR 26 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM BE LIABLE 27 * FOR ANY DAMAGES WHATSOEVER, AND IN PARTICULAR, BROADCOM SHALL NOT BE 28 * LIABLE FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 31 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 32 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 33 * OR OTHERWISE), EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36 /* 37 * Copyright (c) 2000 Soren S. Jorvang. All rights reserved. 38 * 39 * Redistribution and use in source and binary forms, with or without 40 * modification, are permitted provided that the following conditions 41 * are met: 42 * 1. Redistributions of source code must retain the above copyright 43 * notice, this list of conditions, and the following disclaimer. 44 * 2. Redistributions in binary form must reproduce the above copyright 45 * notice, this list of conditions and the following disclaimer in the 46 * documentation and/or other materials provided with the distribution. 47 * 48 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 51 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 58 * SUCH DAMAGE. 59 */ 60 61 #include "opt_ddb.h" 62 #include "opt_execfmt.h" 63 64 #include <sys/param.h> 65 #include <sys/systm.h> 66 #include <sys/kernel.h> 67 #include <sys/map.h> 68 #include <sys/proc.h> 69 #include <sys/buf.h> 70 #include <sys/reboot.h> 71 #include <sys/conf.h> 72 #include <sys/file.h> 73 #include <sys/malloc.h> 74 #include <sys/mbuf.h> 75 #include <sys/msgbuf.h> 76 #include <sys/device.h> 77 #include <sys/user.h> 78 #include <sys/exec.h> 79 #include <sys/sysctl.h> 80 #include <sys/mount.h> 81 #include <sys/syscallargs.h> 82 #include <sys/kcore.h> 83 84 #include <uvm/uvm_extern.h> 85 86 #include <machine/cpu.h> 87 #include <machine/reg.h> 88 #include <machine/psl.h> 89 #include <machine/pte.h> 90 #include <machine/autoconf.h> 91 #include <machine/intr.h> 92 #include <machine/swarm.h> 93 #include <mips/locore.h> 94 95 #include <mips/cfe/cfe_xiocb.h> 96 #include <mips/cfe/cfe_api.h> 97 98 #if 0 /* XXXCGD */ 99 #include <machine/nvram.h> 100 #endif /* XXXCGD */ 101 #include <machine/leds.h> 102 103 #ifdef DDB 104 #include <machine/db_machdep.h> 105 #include <ddb/db_access.h> 106 #include <ddb/db_sym.h> 107 #include <ddb/db_extern.h> 108 #ifndef DB_ELFSIZE 109 #error Must define DB_ELFSIZE! 110 #endif 111 #define ELFSIZE DB_ELFSIZE 112 #include <sys/exec_elf.h> 113 #endif 114 115 #include <dev/cons.h> 116 117 #ifdef IKOS 118 #include <sbmips/ikos/ikosvar.h> 119 #endif 120 121 /* For sysctl. */ 122 char machine[] = MACHINE; 123 char machine_arch[] = MACHINE_ARCH; 124 char cpu_model[] = "sb1250"; 125 126 /* Our exported CPU info. Only one for now */ 127 struct cpu_info cpu_info_store; 128 129 /* Maps for VM objects. */ 130 struct vm_map *exec_map = NULL; 131 struct vm_map *mb_map = NULL; 132 struct vm_map *phys_map = NULL; 133 134 int physmem; /* Total physical memory */ 135 136 char bootstring[512]; /* Boot command */ 137 int netboot; /* Are we netbooting? */ 138 int cfe_present; 139 140 struct bootinfo_v1 bootinfo; 141 142 phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX]; 143 int mem_cluster_cnt; 144 145 void configure(void); 146 void mach_init(long,long,long,long); 147 148 /* 149 * safepri is a safe priority for sleep to set for a spin-wait during 150 * autoconfiguration or after a panic. Used as an argument to splx(). 151 */ 152 int safepri = MIPS_INT_MASK | MIPS_SR_INT_IE; 153 154 extern caddr_t esym; 155 extern struct user *proc0paddr; 156 157 /* 158 * Do all the stuff that locore normally does before calling main(). 159 */ 160 void 161 mach_init(fwhandle,magic,bootdata,reserved) 162 long fwhandle; 163 long magic; 164 long bootdata; 165 long reserved; 166 { 167 caddr_t kernend, v, p0; 168 u_long first, last; 169 vsize_t size; 170 extern char edata[], end[]; 171 int i; 172 u_int memsize; 173 uint32_t config; 174 175 /* XXX this code must run on the target cpu */ 176 config = mips3_cp0_config_read(); 177 config &= ~MIPS3_CONFIG_K0_MASK; 178 config |= 0x05; /* XXX. cacheable coherent */ 179 mips3_cp0_config_write(config); 180 181 /* XXXCGD */ 182 #ifdef SBMIPS_MEM_SIZE 183 memsize = SBMIPS_MEM_SIZE; 184 #else 185 memsize = 32 * 1024 * 1024; 186 #endif 187 memsize += MIPS_KSEG0_START; 188 189 /* 190 * Clear the BSS segment. 191 */ 192 #ifdef DDB 193 if (memcmp(((Elf_Ehdr *)end)->e_ident, ELFMAG, SELFMAG) == 0 && 194 ((Elf_Ehdr *)end)->e_ident[EI_CLASS] == ELFCLASS) { 195 esym = end; 196 esym += ((Elf_Ehdr *)end)->e_entry; 197 kernend = (caddr_t)mips_round_page(esym); 198 bzero(edata, end - edata); 199 } else 200 #endif 201 { 202 kernend = (caddr_t)mips_round_page(end); 203 memset(edata, 0, kernend - edata); 204 } 205 206 /* 207 * Copy the bootinfo structure from the boot loader. 208 * this has to be done before mips_vector_init is 209 * called because we may need CFE's TLB handler 210 */ 211 212 cfe_present = 0; 213 if (magic == BOOTINFO_MAGIC) 214 bcopy((struct bootinfo_v1 *)bootdata, &bootinfo, 215 sizeof bootinfo); 216 else if (reserved == CFE_EPTSEAL) { 217 magic = BOOTINFO_MAGIC; 218 bzero(&bootinfo, sizeof bootinfo); 219 bootinfo.version = BOOTINFO_VERSION; 220 bootinfo.fwhandle = fwhandle; 221 bootinfo.fwentry = bootdata; 222 } 223 224 #ifdef IKOS 225 ikoscons_output_bufsize = IKOSCONS_OUTPUT_BUFSIZE; 226 memsize -= ikoscons_output_bufsize; 227 ikoscons_output_buf = 228 (void *)MIPS_PHYS_TO_KSEG1(MIPS_KSEG0_TO_PHYS(memsize)); 229 memset(ikoscons_output_buf, 0, ikoscons_output_bufsize); 230 #endif 231 232 /* 233 * physmem is measured in pages 234 * XXX does this need to be set for 'consinit', 'uvm_setpagesize', 235 * XXX or 'mips_vector_init'? not that I can tell right now... 236 * XXX if CFE is present, this will be recalculated. 237 * XXX 238 * XXX Does 'physmem' want to be the total amount of RAM in the 239 * XXX system, or the amount that is available to us? 240 */ 241 physmem = btoc(memsize - MIPS_KSEG0_START); 242 243 consinit(); 244 245 uvm_setpagesize(); 246 247 /* 248 * Copy exception-dispatch code down to exception vector. 249 * Initialize locore-function vector. 250 * Clear out the I and D caches. 251 */ 252 mips_vector_init(); 253 254 #if 0 255 *(unsigned long long *)0xb0020440 = 3; 256 #endif 257 258 printf("fwhandle=%08X magic=%08X bootdata=%08X reserved=%08X\n", 259 (u_int) fwhandle,(u_int) magic,(u_int) bootdata,(u_int) reserved); 260 261 if (magic == BOOTINFO_MAGIC) { 262 int idx; 263 int added; 264 cfe_xuint_t start,len,type; 265 266 cfe_init(fwhandle); 267 cfe_present = 1; 268 269 idx = 0; 270 physmem = 0; 271 mem_cluster_cnt = 0; 272 while (cfe_getmeminfo(idx,&start,&len,&type) == 0) { 273 added = 0; 274 printf("Memory Block #%d start %08llX len %08llX: %s: ", 275 idx, start, len, (type == CFE_MI_AVAILABLE) ? 276 "Available" : "Reserved"); 277 if ((type == CFE_MI_AVAILABLE) && 278 (mem_cluster_cnt < VM_PHYSSEG_MAX)) { 279 /* 280 * XXX Ignore memory above 256MB for now, it 281 * XXX needs special handling. 282 */ 283 if (start < (256*1024*1024)) { 284 physmem += btoc(((int) len)); 285 mem_clusters[mem_cluster_cnt].start = 286 (long) start; 287 mem_clusters[mem_cluster_cnt].size = 288 (long) len; 289 mem_cluster_cnt++; 290 added = 1; 291 } 292 } 293 if (added) 294 printf("added to map\n"); 295 else 296 printf("not added to map\n"); 297 idx++; 298 } 299 300 } else { 301 /* 302 * Handle the case of not being called from the firmware. 303 */ 304 mem_clusters[0].start = 0; 305 mem_clusters[0].size = ctob(physmem); 306 mem_cluster_cnt = 1; 307 } 308 309 310 for (i = 0; i < sizeof(bootinfo.boot_flags); i++) { 311 switch (bootinfo.boot_flags[i]) { 312 case '\0': 313 break; 314 case ' ': 315 continue; 316 case '-': 317 while (bootinfo.boot_flags[i] != ' ' && 318 bootinfo.boot_flags[i] != '\0') { 319 switch (bootinfo.boot_flags[i]) { 320 case 'a': 321 boothowto |= RB_ASKNAME; 322 break; 323 case 'd': 324 boothowto |= RB_KDB; 325 break; 326 case 's': 327 boothowto |= RB_SINGLE; 328 break; 329 } 330 i++; 331 } 332 } 333 if (memcmp("single", &bootinfo.boot_flags[i], 5) == 0) 334 boothowto |= RB_SINGLE; 335 if (memcmp("nfsroot=", &bootinfo.boot_flags[i], 8) == 0) 336 netboot = 1; 337 /* 338 * XXX Select root device from 'root=/dev/hd[abcd][1234]' too. 339 */ 340 } 341 342 /* 343 * Load the rest of the available pages into the VM system. 344 * The first chunk is tricky because we have to avoid the 345 * kernel, but the rest are easy. 346 */ 347 first = round_page(MIPS_KSEG0_TO_PHYS(kernend)); 348 last = mem_clusters[0].start + mem_clusters[0].size; 349 uvm_page_physload(atop(first), atop(last), atop(first), atop(last), 350 VM_FREELIST_DEFAULT); 351 352 for (i = 1; i < mem_cluster_cnt; i++) { 353 first = round_page(mem_clusters[i].start); 354 last = mem_clusters[i].start + mem_clusters[i].size; 355 uvm_page_physload(atop(first), atop(last), atop(first), 356 atop(last), VM_FREELIST_DEFAULT); 357 } 358 359 /* 360 * Initialize error message buffer (at end of core). 361 */ 362 mips_init_msgbuf(); 363 364 /* 365 * Allocate space for proc0's USPACE 366 */ 367 p0 = (caddr_t)pmap_steal_memory(USPACE, NULL, NULL); 368 proc0.p_addr = proc0paddr = (struct user *)p0; 369 proc0.p_md.md_regs = (struct frame *)(p0 + USPACE) - 1; 370 curpcb = &proc0.p_addr->u_pcb; 371 curpcb->pcb_context[11] = MIPS_INT_MASK | MIPS_SR_INT_IE; /* SR */ 372 373 /* 374 * Allocate space for system data structures. These data structures 375 * are allocated here instead of cpu_startup() because physical 376 * memory is directly addressable. We don't have to map these into 377 * virtual address space. 378 */ 379 size = (vsize_t)allocsys(NULL, NULL); 380 v = (caddr_t)pmap_steal_memory(size, NULL, NULL); 381 if ((allocsys(v, NULL) - v) != size) 382 panic("mach_init: table size inconsistency"); 383 384 pmap_bootstrap(); 385 386 /* 387 * Initialize debuggers, and break into them, if appropriate. 388 */ 389 #if defined(DDB) 390 ddb_init(0, 0, 0); 391 #endif 392 393 if (boothowto & RB_KDB) { 394 #if defined(DDB) 395 Debugger(); 396 #endif 397 } 398 } 399 400 /* 401 * Allocate memory for variable-sized tables, 402 */ 403 void 404 cpu_startup() 405 { 406 unsigned i; 407 int base, residual; 408 vaddr_t minaddr, maxaddr; 409 vsize_t size; 410 char pbuf[9]; 411 412 /* 413 * Good {morning,afternoon,evening,night}. 414 */ 415 printf(version); 416 format_bytes(pbuf, sizeof(pbuf), ctob(physmem)); 417 printf("%s memory", pbuf); 418 419 /* 420 * Allocate virtual address space for file I/O buffers. 421 * Note they are different than the array of headers, 'buf', 422 * and usually occupy more virtual memory than physical. 423 */ 424 size = MAXBSIZE * nbuf; 425 if (uvm_map(kernel_map, (vaddr_t *)&buffers, round_page(size), 426 NULL, UVM_UNKNOWN_OFFSET, 0, 427 UVM_MAPFLAG(UVM_PROT_NONE, UVM_PROT_NONE, UVM_INH_NONE, 428 UVM_ADV_NORMAL, 0)) != 0) 429 panic("startup: cannot allocate VM for buffers"); 430 minaddr = (vaddr_t)buffers; 431 base = bufpages / nbuf; 432 residual = bufpages % nbuf; 433 for (i = 0; i < nbuf; i++) { 434 vsize_t curbufsize; 435 vaddr_t curbuf; 436 struct vm_page *pg; 437 438 /* 439 * Each buffer has MAXBSIZE bytes of VM space allocated. Of 440 * that MAXBSIZE space, we allocate and map (base+1) pages 441 * for the first "residual" buffers, and then we allocate 442 * "base" pages for the rest. 443 */ 444 curbuf = (vaddr_t) buffers + (i * MAXBSIZE); 445 curbufsize = NBPG * ((i < residual) ? (base + 1) : base); 446 447 while (curbufsize) { 448 pg = uvm_pagealloc(NULL, 0, NULL, 0); 449 if (pg == NULL) 450 panic("cpu_startup: not enough memory for " 451 "buffer cache"); 452 pmap_kenter_pa(curbuf, VM_PAGE_TO_PHYS(pg), 453 VM_PROT_READ|VM_PROT_WRITE); 454 curbuf += PAGE_SIZE; 455 curbufsize -= PAGE_SIZE; 456 } 457 } 458 459 /* 460 * Allocate a submap for exec arguments. This map effectively 461 * limits the number of processes exec'ing at any time. 462 */ 463 exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 16 * NCARGS, 464 VM_MAP_PAGEABLE, FALSE, NULL); 465 /* 466 * Allocate a submap for physio. 467 */ 468 phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, VM_PHYS_SIZE, 469 0, FALSE, NULL); 470 471 472 /* 473 * (No need to allocate an mbuf cluster submap. Mbuf clusters 474 * are allocated via the pool allocator, and we use KSEG to 475 * map those pages.) 476 */ 477 478 format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free)); 479 printf(", %s free", pbuf); 480 format_bytes(pbuf, sizeof(pbuf), bufpages * NBPG); 481 printf(", %s in %d buffers\n", pbuf, nbuf); 482 483 /* 484 * Set up buffers, so they can be used to read disk labels. 485 */ 486 bufinit(); 487 } 488 489 int 490 cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) 491 int *name; 492 u_int namelen; 493 void *oldp; 494 size_t *oldlenp; 495 void *newp; 496 size_t newlen; 497 struct proc *p; 498 { 499 /* All sysctl names at this level are terminal. */ 500 if (namelen != 1) 501 return ENOTDIR; 502 503 switch (name[0]) { 504 default: 505 return EOPNOTSUPP; 506 } 507 } 508 509 int waittime = -1; 510 511 void 512 cpu_reboot(howto, bootstr) 513 int howto; 514 char *bootstr; 515 { 516 /* Take a snapshot before clobbering any registers. */ 517 if (curproc) 518 savectx((struct user *)curpcb); 519 520 if (cold) { 521 howto |= RB_HALT; 522 goto haltsys; 523 } 524 525 /* If "always halt" was specified as a boot flag, obey. */ 526 if (boothowto & RB_HALT) 527 howto |= RB_HALT; 528 529 boothowto = howto; 530 if ((howto & RB_NOSYNC) == 0 && (waittime < 0)) { 531 waittime = 0; 532 vfs_shutdown(); 533 534 /* 535 * If we've been adjusting the clock, the todr 536 * will be out of synch; adjust it now. 537 */ 538 resettodr(); 539 } 540 541 splhigh(); 542 543 if (howto & RB_DUMP) 544 dumpsys(); 545 546 haltsys: 547 doshutdownhooks(); 548 549 if (howto & RB_HALT) { 550 printf("\n"); 551 printf("The operating system has halted.\n"); 552 printf("Please press any key to reboot.\n\n"); 553 cnpollc(1); /* For proper keyboard command handling */ 554 cngetc(); 555 cnpollc(0); 556 } 557 558 printf("rebooting...\n\n"); 559 560 if (cfe_present) { 561 cfe_exit(1, (howto & RB_DUMP) ? 1 : 0); 562 printf("cfe_exit didn't!\n"); 563 } 564 565 delay(500000); 566 567 #if defined(IKOS) && defined(REALLY_IKOS) 568 *(volatile char *)MIPS_PHYS_TO_KSEG1(0x408000) = 0; 569 #else 570 { 571 static int broken; 572 573 if (!broken) { 574 broken = 1; 575 __asm__ ( "move $4, %0 ; break 0x3ff" : : "r"(howto) ); 576 } 577 } 578 #endif 579 580 printf("WARNING: reboot failed!\n"); 581 582 for (;;); 583 } 584 585 static void 586 cswarm_setled(u_int index, char c) 587 { 588 volatile u_char *led_ptr = 589 (void *)MIPS_PHYS_TO_KSEG1(SWARM_LEDS_PHYS); 590 591 if (index < 4) 592 led_ptr[0x20 + ((3 - index) << 3)] = c; 593 } 594 595 void 596 cswarm_setleds(const char *str) 597 { 598 int i; 599 600 for (i = 0; i < 4 && str[i]; i++) 601 cswarm_setled(i, str[i]); 602 for (; i < 4; i++) 603 cswarm_setled(' ', str[i]); 604 } 605 606 int 607 sbmips_cca_for_pa(paddr_t pa) 608 { 609 int rv; 610 611 /* Check each DRAM region. */ 612 if ((pa >= 0x0000000000 && pa <= 0x000fffffff) || /* DRAM 0 */ 613 (pa >= 0x0080000000 && pa <= 0x008fffffff) || /* DRAM 1 */ 614 (pa >= 0x0090000000 && pa <= 0x009fffffff) || /* DRAM 2 */ 615 (pa >= 0x00c0000000 && pa <= 0x00cfffffff) || /* DRAM 3 */ 616 #ifdef _MIPS_PADDR_T_64BIT 617 (pa >= 0x0100000000 && pa <= 0x07ffffffff) || /* DRAM exp */ 618 #endif 619 0) { 620 rv = 5; /* Cacheable coherent. */ 621 goto done; 622 } 623 624 rv = 2; /* Uncached. */ 625 done: 626 return (rv); 627 } 628