1 /* $NetBSD: shark_machdep.c,v 1.10 2002/10/05 17:01:51 chs 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 CFATTACH_DECL(ofbus_root, sizeof(struct device), 139 ofbus_match, ofbus_attach, NULL, NULL); 140 141 /* 142 * Exported routines 143 */ 144 /* Move to header file? */ 145 extern void cpu_reboot __P((int, char *)); 146 extern vm_offset_t initarm __P((ofw_handle_t)); 147 extern void ofrootfound __P((void)); 148 149 /* Local routines */ 150 static void process_kernel_args __P((void)); 151 void ofw_device_register(struct device *, void *); 152 153 /**************************************************************/ 154 155 156 /* 157 * void cpu_reboot(int howto, char *bootstr) 158 * 159 * Reboots the system, in evsent of: 160 * - reboot system call 161 * - panic 162 */ 163 164 void 165 cpu_reboot(howto, bootstr) 166 int howto; 167 char *bootstr; 168 { 169 /* Just call OFW common routine. */ 170 ofw_boot(howto, bootstr); 171 172 OF_boot("not reached -- stupid compiler"); 173 } 174 175 /* 176 * vm_offset_t initarm(ofw_handle_t handle) 177 * 178 * Initial entry point on startup for a GENERIC OFW 179 * system. Called with MMU on, running in the OFW 180 * client environment. 181 * 182 * Major tasks are: 183 * - read the bootargs out of OFW; 184 * - take over memory management from OFW; 185 * - set-up the stacks 186 * - set-up the exception handlers 187 * 188 * Return the new stackptr (va) for the SVC frame. 189 * 190 */ 191 192 struct fiqhandler shark_fiqhandler; 193 struct fiqregs shark_fiqregs; 194 195 vm_offset_t 196 initarm(ofw_handle) 197 ofw_handle_t ofw_handle; 198 { 199 vm_offset_t pclean; 200 vm_offset_t isa_io_physaddr, isa_mem_physaddr; 201 vm_offset_t isa_io_virtaddr, isa_mem_virtaddr; 202 vm_offset_t isadmaphysbufs; 203 extern char shark_fiq[], shark_fiq_end[]; 204 205 /* Don't want to get hit with interrupts 'til we're ready. */ 206 (void)disable_interrupts(I32_bit | F32_bit); 207 208 set_cpufuncs(); 209 210 /* XXX - set these somewhere else? -JJK */ 211 boothowto = 0; 212 213 /* Init the OFW interface. */ 214 /* MUST do this before invoking any OFW client services! */ 215 ofw_init(ofw_handle); 216 217 /* Configure ISA stuff: must be done before consinit */ 218 ofw_configisa(&isa_io_physaddr, &isa_mem_physaddr); 219 220 /* Map-in ISA I/O and memory space. */ 221 /* XXX - this should be done in the isa-bus attach routine! -JJK */ 222 isa_mem_virtaddr = ofw_map(isa_mem_physaddr, L1_S_SIZE, 0); 223 isa_io_virtaddr = ofw_map(isa_io_physaddr, L1_S_SIZE, 0); 224 225 /* Set-up the ISA system: must be done before consinit */ 226 isa_init(isa_io_virtaddr, isa_mem_virtaddr); 227 228 /* Initialize the console (which will call into OFW). */ 229 /* This will allow us to see panic messages and other printf output. */ 230 consinit(); 231 232 /* Get boot info and process it. */ 233 ofw_getbootinfo(&boot_file, &boot_args); 234 process_kernel_args(); 235 236 ofw_configisadma(&isadmaphysbufs); 237 isa_dma_init(); 238 239 /* allocate a cache clean space */ 240 if ((pclean = ofw_getcleaninfo()) != -1) { 241 sa1_cache_clean_addr = ofw_map(pclean, 0x4000 * 2, 242 L2_B | L2_C); 243 sa1_cache_clean_size = 0x4000; 244 } 245 246 /* Configure memory. */ 247 ofw_configmem(); 248 249 /* 250 * Set-up stacks. 251 * The kernel stack for SVC mode will be updated on return 252 * from this routine. 253 */ 254 set_stackptr(PSR_IRQ32_MODE, irqstack.pv_va + NBPG); 255 set_stackptr(PSR_UND32_MODE, undstack.pv_va + NBPG); 256 set_stackptr(PSR_ABT32_MODE, abtstack.pv_va + NBPG); 257 258 /* Set-up exception handlers. */ 259 260 /* 261 * Take control of selected vectors from OFW. 262 * We take: undefined, swi, pre-fetch abort, data abort, addrexc, 263 * irq, fiq 264 * OFW retains: reset 265 */ 266 arm32_vector_init(ARM_VECTORS_LOW, ARM_VEC_ALL & ~ARM_VEC_RESET); 267 268 data_abort_handler_address = (u_int)data_abort_handler; 269 prefetch_abort_handler_address = (u_int)prefetch_abort_handler; 270 undefined_handler_address = 271 (u_int)undefinedinstruction_bounce; /* why is this needed? -JJK */ 272 273 /* Initialise the undefined instruction handlers. */ 274 undefined_init(); 275 276 /* Now for the SHARK-specific part of the FIQ set-up */ 277 shark_fiqhandler.fh_func = shark_fiq; 278 shark_fiqhandler.fh_size = shark_fiq_end - shark_fiq; 279 shark_fiqhandler.fh_flags = 0; 280 shark_fiqhandler.fh_regs = &shark_fiqregs; 281 282 shark_fiqregs.fr_r8 = isa_io_virtaddr; 283 shark_fiqregs.fr_r9 = 0; /* no routine right now */ 284 shark_fiqregs.fr_r10 = 0; /* no arg right now */ 285 shark_fiqregs.fr_r11 = 0; /* scratch */ 286 shark_fiqregs.fr_r12 = 0; /* scratch */ 287 shark_fiqregs.fr_r13 = 0; /* must set a stack when r9 is set! */ 288 289 if (fiq_claim(&shark_fiqhandler)) 290 panic("Cannot claim FIQ vector."); 291 292 #ifdef DDB 293 db_machine_init(); 294 #ifdef __ELF__ 295 ddb_init(0, NULL, NULL); /* XXX */ 296 #else 297 { 298 struct exec *kernexec = (struct exec *)KERNEL_TEXT_BASE; 299 extern int end; 300 extern char *esym; 301 302 ddb_init(kernexec->a_syms, &end, esym); 303 } 304 #endif /* __ELF__ */ 305 306 if (boothowto & RB_KDB) 307 Debugger(); 308 #endif 309 310 /* Return the new stackbase. */ 311 return(kernelstack.pv_va + USPACE_SVC_STACK_TOP); 312 } 313 314 315 /* 316 * Set various globals based on contents of boot_args 317 * 318 * Note that this routine must NOT trash boot_args, as 319 * it is scanned by later routines. 320 */ 321 static void 322 process_kernel_args(void) 323 { 324 #ifdef RB_QUIET 325 int bool; 326 #endif 327 328 #if defined(RB_QUIET) && defined(BOOT_QUIETLY) 329 boothowto |= RB_QUIET; 330 #endif 331 332 /* Process all the generic ARM boot options */ 333 parse_mi_bootargs(boot_args); 334 335 #ifdef RB_QUIET 336 if (get_bootconf_option(args, "noquiet", BOOTOPT_TYPE_BOOLEAN, &bool)) { 337 if (!bool) 338 boothowto |= RB_QUIET; 339 else 340 boothowto &= ~RB_QUIET; 341 } 342 if (get_bootconf_option(args, "quiet", BOOTOPT_TYPE_BOOLEAN, &bool)) { 343 if (bool) 344 boothowto |= RB_QUIET; 345 else 346 boothowto &= ~RB_QUIET; 347 } 348 #endif 349 350 /* Check for ofwgencfg-specific args here. */ 351 } 352 353 354 /* 355 * Walk the OFW device tree and configure found devices. 356 * 357 * Move this into common OFW module? -JJK 358 */ 359 void 360 ofrootfound(void) 361 { 362 int node; 363 struct ofbus_attach_args aa; 364 365 if (!(node = OF_peer(0))) 366 panic("No OFW root"); 367 aa.oba_busname = "ofw"; 368 aa.oba_phandle = node; 369 if (!config_rootfound("ofbus", &aa)) 370 panic("ofw root ofbus not configured"); 371 } 372 373 void 374 ofw_device_register(struct device *dev, void *aux) 375 { 376 static struct device *parent; 377 #if NSD > 0 || NCD > 0 378 static struct device *scsipidev; 379 #endif 380 static char *boot_component; 381 struct ofbus_attach_args *oba; 382 const char *cd_name = dev->dv_cfdata->cf_name; 383 char name[64]; 384 int i; 385 386 if (boot_component == NULL) { 387 char *cp; 388 boot_component = boot_file; 389 if (boot_component == NULL) 390 return; 391 cp = strrchr(boot_component, ':'); 392 if (cp != NULL) { 393 *cp++ = '\0'; 394 if (cp[0] == '\\') 395 cp++; 396 booted_kernel = cp; 397 } 398 } 399 400 if (booted_device != NULL 401 || boot_component == NULL 402 || boot_component[0] == '\0') 403 return; 404 405 if (!strcmp(cd_name, "ofbus") || !strcmp(cd_name, "ofisa")) { 406 oba = aux; 407 } else if (parent == NULL) { 408 return; 409 } else if (parent == dev->dv_parent 410 && !strcmp(parent->dv_cfdata->cf_name, "ofisa")) { 411 struct ofisa_attach_args *aa = aux; 412 oba = &aa->oba; 413 #if NWD > 0 || NSD > 0 || NCD > 0 414 } else if (parent == dev->dv_parent 415 && !strcmp(parent->dv_cfdata->cf_name, "wdc")) { 416 #if NSD > 0 || NCD > 0 417 if (!strcmp(cd_name, "atapibus")) { 418 scsipidev = dev; 419 return; 420 } 421 #endif 422 #if NWD > 0 423 if (!strcmp(cd_name, "wd")) { 424 struct ata_device *adev = aux; 425 char *cp = strchr(boot_component, '@'); 426 if (cp != NULL 427 && adev->adev_drv_data->drive == strtoul(cp+1, NULL, 16) 428 && adev->adev_channel == 0) { 429 booted_device = dev; 430 return; 431 } 432 } 433 return; 434 #endif /* NWD > 0 */ 435 #if NSD > 0 || NCD > 0 436 } else if (scsipidev == dev->dv_parent 437 && (!strcmp(cd_name, "sd") || !strcmp(cd_name, "cd"))) { 438 struct scsipibus_attach_args *sa = aux; 439 char *cp = strchr(boot_component, '@'); 440 if (cp != NULL 441 && sa->sa_periph->periph_channel->chan_bustype->bustype_type == SCSIPI_BUSTYPE_ATAPI 442 && sa->sa_periph->periph_channel->chan_channel == 0 443 && sa->sa_periph->periph_target == strtoul(cp+1, NULL, 16)) { 444 booted_device = dev; 445 } 446 return; 447 #endif /* NSD > 0 || NCD > 0 */ 448 #endif /* NWD > 0 || NSD > 0 || NCD > 0 */ 449 } else { 450 return; 451 } 452 (void) of_packagename(oba->oba_phandle, name, sizeof name); 453 i = strlen(name); 454 if (!strncmp(name, &boot_component[1], i) 455 && (boot_component[i+1] == '/' || boot_component[i+1] == '\0')) { 456 boot_component += i + 1; 457 if (boot_component[0] == '/') { 458 parent = dev; 459 } else { 460 booted_device = dev; 461 } 462 } 463 } 464