1 /* $NetBSD: shark_machdep.c,v 1.4 2002/05/03 21:28:11 rjs Exp $ */ 2 3 /* 4 * Copyright 1997 5 * Digital Equipment Corporation. All rights reserved. 6 * 7 * This software is furnished under license and may be used and 8 * copied only in accordance with the following terms and conditions. 9 * Subject to these conditions, you may download, copy, install, 10 * use, modify and distribute 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 14 * and retain this copyright notice and list of conditions as 15 * they appear in the source file. 16 * 17 * 2) No right is granted to use any trade name, trademark, or logo of 18 * Digital Equipment Corporation. Neither the "Digital Equipment 19 * Corporation" name nor any trademark or logo of Digital Equipment 20 * Corporation may be used to endorse or promote products derived 21 * from this software without the prior written permission of 22 * Digital Equipment Corporation. 23 * 24 * 3) This software is provided "AS-IS" and any express or implied 25 * warranties, including but not limited to, any implied warranties 26 * of merchantability, fitness for a particular purpose, or 27 * non-infringement are disclaimed. In no event shall DIGITAL be 28 * liable for any damages whatsoever, and in particular, DIGITAL 29 * shall not be liable for special, indirect, consequential, or 30 * incidental damages or damages for lost profits, loss of 31 * revenue or loss of use, whether such damages arise in contract, 32 * negligence, tort, under statute, in equity, at law or otherwise, 33 * even if advised of the possibility of such damage. 34 */ 35 36 /* 37 * Kernel setup for the SHARK Configuration 38 */ 39 40 #include "opt_ddb.h" 41 42 #include <sys/types.h> 43 #include <sys/param.h> 44 #include <sys/systm.h> 45 #include <sys/reboot.h> 46 #include <sys/proc.h> 47 #include <sys/kernel.h> 48 #include <sys/buf.h> 49 #include <sys/exec.h> 50 51 #include <uvm/uvm_extern.h> 52 53 #include <arm/fiq.h> 54 55 #include <dev/cons.h> 56 57 #include <machine/db_machdep.h> 58 #include <ddb/db_sym.h> 59 #include <ddb/db_extern.h> 60 61 #include <machine/frame.h> 62 #include <machine/bootconfig.h> 63 #include <machine/cpu.h> 64 #include <machine/intr.h> 65 #include <machine/pio.h> 66 #include <arm/undefined.h> 67 68 #include "opt_ipkdb.h" 69 70 #include <dev/ofw/openfirm.h> 71 #include <machine/ofw.h> 72 #include <machine/isa_machdep.h> 73 #include <dev/isa/isavar.h> 74 #include <dev/ofisa/ofisavar.h> 75 #include <shark/shark/sequoia.h> 76 77 #include "wd.h" 78 #include "cd.h" 79 #include "sd.h" 80 81 #if NWD > 0 || NSD > 0 || NCD > 0 82 #include <dev/ata/atavar.h> 83 #include <dev/ata/wdvar.h> 84 #endif 85 #if NSD > 0 || NCD > 0 86 #include <dev/scsipi/scsi_all.h> 87 #include <dev/scsipi/scsipi_all.h> 88 #include <dev/scsipi/scsipiconf.h> 89 #endif 90 91 /* 92 * Imported variables 93 */ 94 extern pv_addr_t irqstack; 95 extern pv_addr_t undstack; 96 extern pv_addr_t abtstack; 97 extern pv_addr_t kernelstack; 98 extern u_int data_abort_handler_address; 99 extern u_int prefetch_abort_handler_address; 100 extern u_int undefined_handler_address; 101 102 /* 103 * Imported routines 104 */ 105 extern void parse_mi_bootargs __P((char *args)); 106 extern void data_abort_handler __P((trapframe_t *frame)); 107 extern void prefetch_abort_handler __P((trapframe_t *frame)); 108 extern void undefinedinstruction_bounce __P((trapframe_t *frame)); 109 extern void consinit __P((void)); 110 int ofbus_match __P((struct device *, struct cfdata *, void *)); 111 void ofbus_attach __P((struct device *, struct device *, void *)); 112 113 114 /* 115 * Exported variables 116 */ 117 BootConfig bootconfig; 118 char *boot_args = NULL; 119 char *boot_file = NULL; 120 extern char *booted_kernel; 121 #ifndef PMAP_STATIC_L1S 122 int max_processes = 64; /* Default number */ 123 #endif /* !PMAP_STATIC_L1S */ 124 125 int ofw_handleticks = 0; /* set to TRUE by cpu_initclocks */ 126 127 /* 128 * For faster cache cleaning we need two 16K banks of virtual address 129 * space that NOTHING else will access and then we alternate the cache 130 * cleaning between the two banks. 131 * The cache cleaning code requires requires 2 banks aligned 132 * on total size boundry so the banks can be alternated by 133 * xorring the size bit (assumes the bank size is a power of 2) 134 */ 135 extern unsigned int sa1_cache_clean_addr; 136 extern unsigned int sa1_cache_clean_size; 137 138 struct cfattach ofbus_root_ca = { 139 sizeof(struct device), ofbus_match, ofbus_attach 140 }; 141 142 143 /* 144 * Exported routines 145 */ 146 /* Move to header file? */ 147 extern void cpu_reboot __P((int, char *)); 148 extern vm_offset_t initarm __P((ofw_handle_t)); 149 extern void ofrootfound __P((void)); 150 151 /* Local routines */ 152 static void process_kernel_args __P((void)); 153 154 155 /**************************************************************/ 156 157 158 /* 159 * void cpu_reboot(int howto, char *bootstr) 160 * 161 * Reboots the system, in evsent of: 162 * - reboot system call 163 * - panic 164 */ 165 166 void 167 cpu_reboot(howto, bootstr) 168 int howto; 169 char *bootstr; 170 { 171 /* Just call OFW common routine. */ 172 ofw_boot(howto, bootstr); 173 174 OF_boot("not reached -- stupid compiler"); 175 } 176 177 /* 178 * vm_offset_t initarm(ofw_handle_t handle) 179 * 180 * Initial entry point on startup for a GENERIC OFW 181 * system. Called with MMU on, running in the OFW 182 * client environment. 183 * 184 * Major tasks are: 185 * - read the bootargs out of OFW; 186 * - take over memory management from OFW; 187 * - set-up the stacks 188 * - set-up the exception handlers 189 * 190 * Return the new stackptr (va) for the SVC frame. 191 * 192 */ 193 194 struct fiqhandler shark_fiqhandler; 195 struct fiqregs shark_fiqregs; 196 197 vm_offset_t 198 initarm(ofw_handle) 199 ofw_handle_t ofw_handle; 200 { 201 vm_offset_t pclean; 202 vm_offset_t isa_io_physaddr, isa_mem_physaddr; 203 vm_offset_t isa_io_virtaddr, isa_mem_virtaddr; 204 vm_offset_t isadmaphysbufs; 205 extern char shark_fiq[], shark_fiq_end[]; 206 207 /* Don't want to get hit with interrupts 'til we're ready. */ 208 (void)disable_interrupts(I32_bit | F32_bit); 209 210 set_cpufuncs(); 211 212 /* XXX - set these somewhere else? -JJK */ 213 boothowto = 0; 214 215 /* Init the OFW interface. */ 216 /* MUST do this before invoking any OFW client services! */ 217 ofw_init(ofw_handle); 218 219 /* Configure ISA stuff: must be done before consinit */ 220 ofw_configisa(&isa_io_physaddr, &isa_mem_physaddr); 221 222 /* Map-in ISA I/O and memory space. */ 223 /* XXX - this should be done in the isa-bus attach routine! -JJK */ 224 isa_mem_virtaddr = ofw_map(isa_mem_physaddr, L1_S_SIZE, 0); 225 isa_io_virtaddr = ofw_map(isa_io_physaddr, L1_S_SIZE, 0); 226 227 /* Set-up the ISA system: must be done before consinit */ 228 isa_init(isa_io_virtaddr, isa_mem_virtaddr); 229 230 /* Initialize the console (which will call into OFW). */ 231 /* This will allow us to see panic messages and other printf output. */ 232 consinit(); 233 234 /* Get boot info and process it. */ 235 ofw_getbootinfo(&boot_file, &boot_args); 236 process_kernel_args(); 237 238 ofw_configisadma(&isadmaphysbufs); 239 isa_dma_init(); 240 241 /* allocate a cache clean space */ 242 if ((pclean = ofw_getcleaninfo()) != -1) { 243 sa1_cache_clean_addr = ofw_map(pclean, 0x4000 * 2, 244 L2_B | L2_C); 245 sa1_cache_clean_size = 0x4000; 246 } 247 248 /* Configure memory. */ 249 ofw_configmem(); 250 251 /* 252 * Set-up stacks. 253 * The kernel stack for SVC mode will be updated on return 254 * from this routine. 255 */ 256 set_stackptr(PSR_IRQ32_MODE, irqstack.pv_va + NBPG); 257 set_stackptr(PSR_UND32_MODE, undstack.pv_va + NBPG); 258 set_stackptr(PSR_ABT32_MODE, abtstack.pv_va + NBPG); 259 260 /* Set-up exception handlers. */ 261 262 /* 263 * Take control of selected vectors from OFW. 264 * We take: undefined, swi, pre-fetch abort, data abort, addrexc, 265 * irq, fiq 266 * OFW retains: reset 267 */ 268 arm32_vector_init(ARM_VECTORS_LOW, ARM_VEC_ALL & ~ARM_VEC_RESET); 269 270 data_abort_handler_address = (u_int)data_abort_handler; 271 prefetch_abort_handler_address = (u_int)prefetch_abort_handler; 272 undefined_handler_address = 273 (u_int)undefinedinstruction_bounce; /* why is this needed? -JJK */ 274 275 /* Initialise the undefined instruction handlers. */ 276 undefined_init(); 277 278 /* Now for the SHARK-specific part of the FIQ set-up */ 279 shark_fiqhandler.fh_func = shark_fiq; 280 shark_fiqhandler.fh_size = shark_fiq_end - shark_fiq; 281 shark_fiqhandler.fh_flags = 0; 282 shark_fiqhandler.fh_regs = &shark_fiqregs; 283 284 shark_fiqregs.fr_r8 = isa_io_virtaddr; 285 shark_fiqregs.fr_r9 = 0; /* no routine right now */ 286 shark_fiqregs.fr_r10 = 0; /* no arg right now */ 287 shark_fiqregs.fr_r11 = 0; /* scratch */ 288 shark_fiqregs.fr_r12 = 0; /* scratch */ 289 shark_fiqregs.fr_r13 = 0; /* must set a stack when r9 is set! */ 290 291 if (fiq_claim(&shark_fiqhandler)) 292 panic("Cannot claim FIQ vector.\n"); 293 294 #ifdef DDB 295 db_machine_init(); 296 #ifdef __ELF__ 297 ddb_init(0, NULL, NULL); /* XXX */ 298 #else 299 { 300 struct exec *kernexec = (struct exec *)KERNEL_TEXT_BASE; 301 extern int end; 302 extern char *esym; 303 304 ddb_init(kernexec->a_syms, &end, esym); 305 } 306 #endif /* __ELF__ */ 307 308 if (boothowto & RB_KDB) 309 Debugger(); 310 #endif 311 312 /* Return the new stackbase. */ 313 return(kernelstack.pv_va + USPACE_SVC_STACK_TOP); 314 } 315 316 317 /* 318 * Set various globals based on contents of boot_args 319 * 320 * Note that this routine must NOT trash boot_args, as 321 * it is scanned by later routines. 322 */ 323 static void 324 process_kernel_args(void) 325 { 326 #ifdef RB_QUIET 327 int bool; 328 #endif 329 330 #if defined(RB_QUIET) && defined(BOOT_QUIETLY) 331 boothowto |= RB_QUIET; 332 #endif 333 334 /* Process all the generic ARM boot options */ 335 parse_mi_bootargs(boot_args); 336 337 #ifdef RB_QUIET 338 if (get_bootconf_option(args, "noquiet", BOOTOPT_TYPE_BOOLEAN, &bool)) { 339 if (!bool) 340 boothowto |= RB_QUIET; 341 else 342 boothowto &= ~RB_QUIET; 343 } 344 if (get_bootconf_option(args, "quiet", BOOTOPT_TYPE_BOOLEAN, &bool)) { 345 if (bool) 346 boothowto |= RB_QUIET; 347 else 348 boothowto &= ~RB_QUIET; 349 } 350 #endif 351 352 /* Check for ofwgencfg-specific args here. */ 353 } 354 355 356 /* 357 * Walk the OFW device tree and configure found devices. 358 * 359 * Move this into common OFW module? -JJK 360 */ 361 void 362 ofrootfound(void) 363 { 364 int node; 365 struct ofbus_attach_args aa; 366 367 if (!(node = OF_peer(0))) 368 panic("No OFW root"); 369 aa.oba_busname = "ofw"; 370 aa.oba_phandle = node; 371 if (!config_rootfound("ofbus", &aa)) 372 panic("ofw root ofbus not configured"); 373 } 374 375 void 376 ofw_device_register(struct device *dev, void *aux) 377 { 378 static struct device *parent; 379 #if NSD > 0 || NCD > 0 380 static struct device *scsipidev; 381 #endif 382 static char *boot_component; 383 struct ofbus_attach_args *oba; 384 const char *cd_name = dev->dv_cfdata->cf_driver->cd_name; 385 char name[64]; 386 int i; 387 388 if (boot_component == NULL) { 389 char *cp; 390 boot_component = boot_file; 391 if (boot_component == NULL) 392 return; 393 cp = strrchr(boot_component, ':'); 394 if (cp != NULL) { 395 *cp++ = '\0'; 396 if (cp[0] == '\\') 397 cp++; 398 booted_kernel = cp; 399 } 400 } 401 402 if (booted_device != NULL 403 || boot_component == NULL 404 || boot_component[0] == '\0') 405 return; 406 407 if (!strcmp(cd_name, "ofbus") || !strcmp(cd_name, "ofisa")) { 408 oba = aux; 409 } else if (parent == NULL) { 410 return; 411 } else if (parent == dev->dv_parent 412 && !strcmp(parent->dv_cfdata->cf_driver->cd_name, "ofisa")) { 413 struct ofisa_attach_args *aa = aux; 414 oba = &aa->oba; 415 #if NWD > 0 || NSD > 0 || NCD > 0 416 } else if (parent == dev->dv_parent 417 && !strcmp(parent->dv_cfdata->cf_driver->cd_name, "wdc")) { 418 #if NSD > 0 || NCD > 0 419 if (!strcmp(cd_name, "atapibus")) { 420 scsipidev = dev; 421 return; 422 } 423 #endif 424 #if NWD > 0 425 if (!strcmp(cd_name, "wd")) { 426 struct ata_device *adev = aux; 427 char *cp = strchr(boot_component, '@'); 428 if (cp != NULL 429 && adev->adev_drv_data->drive == strtoul(cp+1, NULL, 16) 430 && adev->adev_channel == 0) { 431 booted_device = dev; 432 return; 433 } 434 } 435 return; 436 #endif /* NWD > 0 */ 437 #if NSD > 0 || NCD > 0 438 } else if (scsipidev == dev->dv_parent 439 && (!strcmp(cd_name, "sd") || !strcmp(cd_name, "cd"))) { 440 struct scsipibus_attach_args *sa = aux; 441 char *cp = strchr(boot_component, '@'); 442 if (cp != NULL 443 && sa->sa_periph->periph_channel->chan_bustype->bustype_type == SCSIPI_BUSTYPE_ATAPI 444 && sa->sa_periph->periph_channel->chan_channel == 0 445 && sa->sa_periph->periph_target == strtoul(cp+1, NULL, 16)) { 446 booted_device = dev; 447 } 448 return; 449 #endif /* NSD > 0 || NCD > 0 */ 450 #endif /* NWD > 0 || NSD > 0 || NCD > 0 */ 451 } else { 452 return; 453 } 454 (void) of_packagename(oba->oba_phandle, name, sizeof name); 455 i = strlen(name); 456 if (!strncmp(name, &boot_component[1], i) 457 && (boot_component[i+1] == '/' || boot_component[i+1] == '\0')) { 458 boot_component += i + 1; 459 if (boot_component[0] == '/') { 460 parent = dev; 461 } else { 462 booted_device = dev; 463 } 464 } 465 } 466