1 /* $NetBSD: machdep.c,v 1.4 2002/11/25 11:26:22 scw Exp $ */ 2 3 /* 4 * Copyright (c) 1988 University of Utah. 5 * Copyright (c) 1992, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by 9 * the Systems Programming Group of the University of Utah Computer 10 * Science Department, The Mach Operating System project at 11 * Carnegie-Mellon University and Ralph Campbell. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 3. All advertising materials mentioning features or use of this software 22 * must display the following acknowledgement: 23 * This product includes software developed by the University of 24 * California, Berkeley and its contributors. 25 * 4. Neither the name of the University nor the names of its contributors 26 * may be used to endorse or promote products derived from this software 27 * without specific prior written permission. 28 * 29 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 30 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 32 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 39 * SUCH DAMAGE. 40 * 41 * @(#)machdep.c 8.3 (Berkeley) 1/12/94 42 * from: Utah Hdr: machdep.c 1.63 91/04/24 43 */ 44 45 #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 46 __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.4 2002/11/25 11:26:22 scw Exp $"); 47 48 #include "opt_ddb.h" 49 #include "opt_kgdb.h" 50 51 #include "opt_memsize.h" 52 #include "opt_ethaddr.h" 53 54 #include <sys/param.h> 55 #include <sys/systm.h> 56 #include <sys/kernel.h> 57 #include <sys/buf.h> 58 #include <sys/reboot.h> 59 #include <sys/user.h> 60 #include <sys/mount.h> 61 #include <sys/kcore.h> 62 #include <sys/boot_flag.h> 63 #include <sys/termios.h> 64 65 #include <net/if.h> 66 #include <net/if_ether.h> 67 68 #include <uvm/uvm_extern.h> 69 70 #include <dev/cons.h> 71 72 #ifdef DDB 73 #include <machine/db_machdep.h> 74 #include <ddb/db_extern.h> 75 #endif 76 77 #include <mips/cache.h> 78 #include <mips/locore.h> 79 #include <machine/yamon.h> 80 81 #include <evbmips/alchemy/pb1000var.h> 82 #include <mips/alchemy/include/aureg.h> 83 #include <mips/alchemy/include/auvar.h> 84 #include <mips/alchemy/include/aubusvar.h> 85 86 #include "aucom.h" 87 #if NAUCOM > 0 88 #include <mips/alchemy/dev/aucomvar.h> 89 90 #ifndef CONSPEED 91 #define CONSPEED TTYDEF_SPEED 92 #endif 93 int aucomcnrate = CONSPEED; 94 #endif /* NAUCOM > 0 */ 95 96 /* The following are used externally (sysctl_hw). */ 97 extern char cpu_model[]; 98 99 struct user *proc0paddr; 100 101 /* Our exported CPU info; we can have only one. */ 102 struct cpu_info cpu_info_store; 103 104 /* Maps for VM objects. */ 105 struct vm_map *exec_map = NULL; 106 struct vm_map *mb_map = NULL; 107 struct vm_map *phys_map = NULL; 108 109 int physmem; /* # pages of physical memory */ 110 int maxmem; /* max memory per process */ 111 112 int mem_cluster_cnt; 113 phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX]; 114 115 yamon_env_var *yamon_envp; 116 struct pb1000_config pb1000_configuration; 117 struct propdb *alchemy_prop_info; 118 119 void mach_init(int, char **, yamon_env_var *, u_long); /* XXX */ 120 121 void 122 mach_init(int argc, char **argv, yamon_env_var *envp, u_long memsize) 123 { 124 struct pb1000_config *pbc = &pb1000_configuration; 125 bus_space_handle_t sh; 126 caddr_t kernend; 127 const char *cp; 128 u_long first, last; 129 caddr_t v; 130 int howto, i; 131 132 extern char edata[], end[]; /* XXX */ 133 134 /* clear the BSS segment */ 135 kernend = (caddr_t)mips_round_page(end); 136 memset(edata, 0, kernend - (caddr_t)edata); 137 138 /* set cpu model info for sysctl_hw */ 139 strcpy(cpu_model, "Alchemy Semiconductor Pb1000"); 140 141 /* save the yamon environment pointer */ 142 yamon_envp = envp; 143 144 /* Use YAMON callbacks for early console I/O */ 145 cn_tab = &yamon_promcd; 146 147 /* 148 * Set up the exception vectors and cpu-specific function 149 * vectors early on. We need the wbflush() vector set up 150 * before comcnattach() is called (or at least before the 151 * first printf() after that is called). 152 * Also clears the I+D caches. 153 */ 154 mips_vector_init(); 155 156 /* 157 * Set the VM page size. 158 */ 159 uvm_setpagesize(); 160 161 /* 162 * Initialize bus space tags. 163 */ 164 au_cpureg_bus_mem_init(&pbc->pc_cpuregt, pbc); 165 aubus_st = &pbc->pc_cpuregt; /* XXX: for aubus.c */ 166 167 /* 168 * Calibrate the timer, delay() relies on this. 169 */ 170 bus_space_map(&pbc->pc_cpuregt, PC_BASE, PC_SIZE, 0, &sh); 171 au_cal_timers(&pbc->pc_cpuregt, sh); 172 bus_space_unmap(&pbc->pc_cpuregt, sh, PC_SIZE); 173 174 /* 175 * Bring up the console. 176 */ 177 #if NAUCOM > 0 178 /* 179 * Delay to allow firmware putchars to complete. 180 * FIFO depth * character time. 181 * character time = (1000000 / (defaultrate / 10)) 182 */ 183 delay(160000000 / aucomcnrate); 184 if (aucomcnattach(&pbc->pc_cpuregt, UART0_BASE, aucomcnrate, 185 curcpu()->ci_cpu_freq / 4, 186 (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8) != 0) 187 panic("pb1000: unable to initialize serial console"); 188 #else 189 panic("pb1000: not configured to use serial console"); 190 #endif /* NAUCOM > 0 */ 191 192 /* 193 * Look at arguments passed to us and compute boothowto. 194 */ 195 boothowto = RB_AUTOBOOT; 196 #ifdef KADB 197 boothowto |= RB_KDB; 198 #endif 199 for (i = 1; i < argc; i++) { 200 for (cp = argv[i]; *cp; cp++) { 201 /* Ignore superfluous '-', if there is one */ 202 if (*cp == '-') 203 continue; 204 205 howto = 0; 206 BOOT_FLAG(*cp, howto); 207 if (! howto) 208 printf("bootflag '%c' not recognised\n", *cp); 209 else 210 boothowto |= howto; 211 } 212 } 213 214 /* 215 * Determine the memory size. Use the `memsize' PMON 216 * variable. If that's not available, panic. 217 * 218 * Note: Reserve the first page! That's where the trap 219 * vectors are located. 220 */ 221 222 #if defined(MEMSIZE) 223 memsize = MEMSIZE; 224 #else 225 if (memsize == 0) { 226 if ((cp = yamon_getenv("memsize")) != NULL) 227 memsize = strtoul(cp, NULL, 0); 228 else { 229 printf("FATAL: `memsize' YAMON variable not set. Set it to\n"); 230 printf(" the amount of memory (in MB) and try again.\n"); 231 printf(" Or, build a kernel with the `MEMSIZE' " 232 "option.\n"); 233 panic("pb1000_init"); 234 } 235 } 236 #endif /* MEMSIZE */ 237 printf("Memory size: 0x%08lx\n", memsize); 238 physmem = btoc(memsize); 239 240 mem_clusters[mem_cluster_cnt].start = NBPG; 241 mem_clusters[mem_cluster_cnt].size = 242 memsize - mem_clusters[mem_cluster_cnt].start; 243 mem_cluster_cnt++; 244 245 /* 246 * Load the rest of the available pages into the VM system. 247 */ 248 first = round_page(MIPS_KSEG0_TO_PHYS(kernend)); 249 last = mem_clusters[0].start + mem_clusters[0].size; 250 uvm_page_physload(atop(first), atop(last), atop(first), atop(last), 251 VM_FREELIST_DEFAULT); 252 253 /* 254 * Initialize message buffer (at end of core). 255 */ 256 mips_init_msgbuf(); 257 258 /* 259 * Compute the size of system data structures. pmap_bootstrap() 260 * needs some of this information. 261 */ 262 memsize = (u_long)allocsys(NULL, NULL); 263 264 /* 265 * Initialize the virtual memory system. 266 */ 267 pmap_bootstrap(); 268 269 /* 270 * Init mapping for u page(s) for proc0. 271 */ 272 v = (caddr_t) uvm_pageboot_alloc(USPACE); 273 proc0.p_addr = proc0paddr = (struct user *) v; 274 proc0.p_md.md_regs = (struct frame *)(v + USPACE) - 1; 275 curpcb = &proc0.p_addr->u_pcb; 276 curpcb->pcb_context[11] = MIPS_INT_MASK | MIPS_SR_INT_IE; /* SR */ 277 278 /* 279 * Allocate space for system data structures. These data structures 280 * are allocated here instead of cpu_startup() because physical 281 * memory is directly addressable. We don't have to map these into 282 * the virtual address space. 283 */ 284 v = (caddr_t)uvm_pageboot_alloc(memsize); 285 if ((allocsys(v, NULL) - v) != memsize) 286 panic("mach_init: table size inconsistency"); 287 288 /* 289 * Initialize debuggers, and break into them, if appropriate. 290 */ 291 #ifdef DDB 292 ddb_init(0, 0, 0); 293 if (boothowto & RB_KDB) 294 Debugger(); 295 #endif 296 } 297 298 void 299 consinit(void) 300 { 301 302 /* 303 * Everything related to console initialization is done 304 * in mach_init(). 305 */ 306 } 307 308 void 309 cpu_startup(void) 310 { 311 char pbuf[9]; 312 vaddr_t minaddr, maxaddr; 313 vsize_t size; 314 u_int i, base, residual; 315 #ifdef DEBUG 316 extern int pmapdebug; /* XXX */ 317 int opmapdebug = pmapdebug; 318 319 pmapdebug = 0; /* Shut up pmap debug during bootstrap */ 320 #endif 321 322 /* 323 * Good {morning,afternoon,evening,night}. 324 */ 325 printf(version); 326 printf("%s\n", cpu_model); 327 format_bytes(pbuf, sizeof(pbuf), ctob(physmem)); 328 printf("total memory = %s\n", pbuf); 329 330 /* 331 * Allocate virtual address space for file I/O buffers. 332 * Note they are different than the array of headers, 'buf', 333 * and usually occupy more virtual memory than physical. 334 */ 335 size = MAXBSIZE * nbuf; 336 if (uvm_map(kernel_map, (vaddr_t *)&buffers, round_page(size), 337 NULL, UVM_UNKNOWN_OFFSET, 0, 338 UVM_MAPFLAG(UVM_PROT_NONE, UVM_PROT_NONE, UVM_INH_NONE, 339 UVM_ADV_NORMAL, 0)) != 0) 340 panic("cpu_startup: cannot allocate VM for buffers"); 341 342 minaddr = (vaddr_t)buffers; 343 if ((bufpages / nbuf) >= btoc(MAXBSIZE)) { 344 bufpages = btoc(MAXBSIZE) * nbuf; /* do not overallocate RAM */ 345 } 346 base = bufpages / nbuf; 347 residual = bufpages % nbuf; 348 349 /* now allocate RAM for buffers */ 350 for (i = 0; i < nbuf; i++) { 351 vsize_t curbufsize; 352 vaddr_t curbuf; 353 struct vm_page *pg; 354 355 /* 356 * Each buffer has MAXBSIZE bytes of VM space allocated. Of 357 * that MAXBSIZE space, we allocate and map (base+1) pages 358 * for the first "residual" buffers, and then we allocate 359 * "base" pages for the rest. 360 */ 361 curbuf = (vaddr_t)buffers + (i * MAXBSIZE); 362 curbufsize = NBPG * ((i < residual) ? (base+1) : base); 363 364 while (curbufsize) { 365 pg = uvm_pagealloc(NULL, 0, NULL, 0); 366 if (pg == NULL) 367 panic("cpu_startup: not enough memory for " 368 "buffer cache"); 369 pmap_kenter_pa(curbuf, VM_PAGE_TO_PHYS(pg), 370 VM_PROT_READ|VM_PROT_WRITE); 371 curbuf += PAGE_SIZE; 372 curbufsize -= PAGE_SIZE; 373 } 374 } 375 pmap_update(pmap_kernel()); 376 377 /* 378 * Allocate a submap for exec arguments. This map effectively 379 * limits the number of processes exec'ing at any time. 380 */ 381 exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 382 16 * NCARGS, VM_MAP_PAGEABLE, FALSE, NULL); 383 384 /* 385 * Allocate a submap for physio 386 */ 387 phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 388 VM_PHYS_SIZE, 0, FALSE, NULL); 389 390 /* 391 * No need to allocate an mbuf cluster submap. Mbuf clusters 392 * are allocated via the pool allocator, and we use KSEG to 393 * map those pages. 394 */ 395 396 #ifdef DEBUG 397 pmapdebug = opmapdebug; 398 #endif 399 format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free)); 400 printf("avail memory = %s\n", pbuf); 401 format_bytes(pbuf, sizeof(pbuf), bufpages * NBPG); 402 printf("using %u buffers containing %s of memory\n", nbuf, pbuf); 403 404 /* 405 * Set up buffers, so they can be used to read disklabels. 406 */ 407 bufinit(); 408 409 /* 410 * Set up the chip/board properties database. 411 */ 412 if (!(alchemy_prop_info = propdb_create("board info"))) 413 panic("Cannot create board info database"); 414 } 415 416 void 417 cpu_reboot(int howto, char *bootstr) 418 { 419 static int waittime = -1; 420 421 /* Take a snapshot before clobbering any registers. */ 422 if (curproc) 423 savectx((struct user *)curpcb); 424 425 /* If "always halt" was specified as a boot flag, obey. */ 426 if (boothowto & RB_HALT) 427 howto |= RB_HALT; 428 429 boothowto = howto; 430 431 /* If system is cold, just halt. */ 432 if (cold) { 433 boothowto |= RB_HALT; 434 goto haltsys; 435 } 436 437 if ((boothowto & RB_NOSYNC) == 0 && waittime < 0) { 438 waittime = 0; 439 440 /* 441 * Synchronize the disks.... 442 */ 443 vfs_shutdown(); 444 445 /* 446 * If we've been adjusting the clock, the todr 447 * will be out of synch; adjust it now. 448 */ 449 resettodr(); 450 } 451 452 /* Disable interrupts. */ 453 splhigh(); 454 455 if (boothowto & RB_DUMP) 456 dumpsys(); 457 458 haltsys: 459 /* Run any shutdown hooks. */ 460 doshutdownhooks(); 461 462 #if 1 463 /* XXX 464 * For some reason we are leaving the ethernet MAC in a state where 465 * YAMON isn't happy with it. So just call the reset vector (grr, 466 * Alchemy YAMON doesn't have a "reset" command). 467 */ 468 printf("reseting board...\n\n"); 469 mips_icache_sync_all(); 470 mips_dcache_wbinv_all(); 471 asm volatile("jr %0" :: "r"(MIPS_RESET_EXC_VEC)); 472 #else 473 printf("%s\n\n", ((howto & RB_HALT) != 0) ? "halted." : "rebooting..."); 474 yamon_exit(boothowto); 475 printf("Oops, back from yamon_exit()\n\nSpinning..."); 476 #endif 477 for (;;) 478 /* spin forever */ ; /* XXX */ 479 /*NOTREACHED*/ 480 } 481