1 /* $NetBSD: shark_machdep.c,v 1.47 2021/08/17 22:00:31 andvar 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 <sys/cdefs.h> 41 __KERNEL_RCSID(0, "$NetBSD: shark_machdep.c,v 1.47 2021/08/17 22:00:31 andvar Exp $"); 42 43 #include "opt_ddb.h" 44 #include "opt_modular.h" 45 46 #include <sys/types.h> 47 #include <sys/param.h> 48 #include <sys/systm.h> 49 #include <sys/reboot.h> 50 #include <sys/proc.h> 51 #include <sys/kernel.h> 52 #include <sys/buf.h> 53 #include <sys/exec.h> 54 #include <sys/ksyms.h> 55 #include <sys/device.h> 56 #include <sys/cpu.h> 57 #include <sys/intr.h> 58 59 #include <uvm/uvm_extern.h> 60 61 #include <dev/cons.h> 62 #include <dev/ofw/openfirm.h> 63 #include <dev/isa/isavar.h> 64 #include <dev/ofisa/ofisavar.h> 65 66 #include <machine/db_machdep.h> 67 #include <ddb/db_sym.h> 68 #include <ddb/db_extern.h> 69 70 #include <arm/fiq.h> 71 #include <arm/locore.h> 72 #include <arm/undefined.h> 73 #include <arm/arm32/machdep.h> 74 75 #include <machine/bootconfig.h> 76 #include <machine/pio.h> 77 #include <machine/ofw.h> 78 #include <machine/isa_machdep.h> 79 #include <shark/shark/sequoia.h> 80 81 #include "isadma.h" 82 #include "vlpci.h" 83 84 #include "wd.h" 85 #include "cd.h" 86 #include "sd.h" 87 88 #if NWD > 0 || NSD > 0 || NCD > 0 89 #include <dev/ata/atavar.h> 90 #endif 91 #if NSD > 0 || NCD > 0 92 #include <dev/scsipi/scsi_all.h> 93 #include <dev/scsipi/scsipi_all.h> 94 #include <dev/scsipi/scsipiconf.h> 95 #endif 96 97 #include "ksyms.h" 98 99 /* 100 * Imported variables 101 */ 102 extern pv_addr_t irqstack; 103 extern pv_addr_t undstack; 104 extern pv_addr_t abtstack; 105 106 /* 107 * Imported routines 108 */ 109 extern void data_abort_handler(trapframe_t *frame); 110 extern void prefetch_abort_handler(trapframe_t *frame); 111 extern void undefinedinstruction_bounce(trapframe_t *frame); 112 extern void consinit(void); 113 int ofbus_match(device_t, cfdata_t, void *); 114 void ofbus_attach(device_t, device_t, void *); 115 116 117 paddr_t isa_io_physaddr, isa_mem_physaddr; 118 119 /* 120 * Exported variables 121 */ 122 BootConfig bootconfig; 123 char *boot_args = NULL; 124 char *boot_file = NULL; 125 extern char *booted_kernel; 126 #ifndef PMAP_STATIC_L1S 127 int max_processes = 64; /* Default number */ 128 #endif /* !PMAP_STATIC_L1S */ 129 130 int ofw_handleticks = 0; /* set to TRUE by cpu_initclocks */ 131 132 /* 133 * For faster cache cleaning we need two 16K banks of virtual address 134 * space that NOTHING else will access and then we alternate the cache 135 * cleaning between the two banks. 136 * The cache cleaning code requires 2 banks aligned 137 * on total size boundary so the banks can be alternated by 138 * xorring the size bit (assumes the bank size is a power of 2) 139 */ 140 extern unsigned int sa1_cache_clean_addr; 141 extern unsigned int sa1_cache_clean_size; 142 143 #if NVLPCI > 0 144 extern vaddr_t vlpci_mem_vaddr; 145 #endif 146 147 CFATTACH_DECL_NEW(ofbus_root, 0, 148 ofbus_match, ofbus_attach, NULL, NULL); 149 150 /* 151 * Exported routines 152 */ 153 /* Move to header file? */ 154 extern void cpu_reboot(int, char *); 155 extern void ofrootfound(void); 156 157 /* Local routines */ 158 static void process_kernel_args(void); 159 void ofw_device_register(device_t, void *); 160 161 /* Kernel text starts at the base of the kernel address space. */ 162 #define KERNEL_TEXT_BASE (KERNEL_BASE + 0x00000000) 163 164 /**************************************************************/ 165 166 167 /* 168 * void cpu_reboot(int howto, char *bootstr) 169 * 170 * Reboots the system, in evsent of: 171 * - reboot system call 172 * - panic 173 */ 174 175 void 176 cpu_reboot(int howto, char *bootstr) 177 { 178 /* Just call OFW common routine. */ 179 ofw_boot(howto, bootstr); 180 181 OF_boot("not reached -- stupid compiler"); 182 } 183 184 /* 185 * vaddr_t initarm(void *handle) 186 * 187 * Initial entry point on startup for a GENERIC OFW 188 * system. Called with MMU on, running in the OFW 189 * client environment. 190 * 191 * Major tasks are: 192 * - read the bootargs out of OFW; 193 * - take over memory management from OFW; 194 * - set-up the stacks 195 * - set-up the exception handlers 196 * 197 * Return the new stackptr (va) for the SVC frame. 198 * 199 */ 200 201 struct fiqhandler shark_fiqhandler; 202 struct fiqregs shark_fiqregs; 203 204 vaddr_t 205 initarm(void *arg) 206 { 207 ofw_handle_t ofw_handle = arg; 208 paddr_t pclean; 209 vaddr_t isa_io_virtaddr, isa_mem_virtaddr; 210 paddr_t isadmaphysbufs; 211 extern char shark_fiq[], shark_fiq_end[]; 212 213 /* Don't want to get hit with interrupts 'til we're ready. */ 214 (void)disable_interrupts(I32_bit | F32_bit); 215 216 set_cpufuncs(); 217 218 /* XXX - set these somewhere else? -JJK */ 219 boothowto = 0; 220 221 /* Init the OFW interface. */ 222 /* MUST do this before invoking any OFW client services! */ 223 ofw_init(ofw_handle); 224 225 /* Configure ISA stuff: must be done before consinit */ 226 ofw_configisa(&isa_io_physaddr, &isa_mem_physaddr); 227 228 /* Map-in ISA I/O and memory space. */ 229 /* XXX - this should be done in the isa-bus attach routine! -JJK */ 230 isa_mem_virtaddr = ofw_map(isa_mem_physaddr, L1_S_SIZE, 0); 231 isa_io_virtaddr = ofw_map(isa_io_physaddr, L1_S_SIZE, 0); 232 #if NVLPCI > 0 233 /* XXX should get address from OF */ 234 vlpci_mem_vaddr = ofw_map(0x02000000, 0x00100000, 0); 235 #endif 236 237 /* Set-up the ISA system: must be done before consinit */ 238 isa_init(isa_io_virtaddr, isa_mem_virtaddr); 239 240 /* Initialize the console (which will call into OFW). */ 241 /* This will allow us to see panic messages and other printf output. */ 242 consinit(); 243 244 /* Get boot info and process it. */ 245 ofw_getbootinfo(&boot_file, &boot_args); 246 process_kernel_args(); 247 248 ofw_configisadma(&isadmaphysbufs); 249 #if (NISADMA > 0) 250 isa_dma_init(); 251 #endif 252 253 /* allocate a cache clean space */ 254 if ((pclean = ofw_getcleaninfo()) != -1) { 255 sa1_cache_clean_addr = ofw_map(pclean, 0x4000 * 2, 256 L2_B | L2_C); 257 sa1_cache_clean_size = 0x4000; 258 } 259 260 /* Configure memory. */ 261 ofw_configmem(); 262 263 /* 264 * Set-up stacks. 265 * The kernel stack for SVC mode will be updated on return 266 * from this routine. 267 */ 268 set_stackptr(PSR_IRQ32_MODE, irqstack.pv_va + PAGE_SIZE); 269 set_stackptr(PSR_UND32_MODE, undstack.pv_va + PAGE_SIZE); 270 set_stackptr(PSR_ABT32_MODE, abtstack.pv_va + PAGE_SIZE); 271 272 /* Set-up exception handlers. */ 273 274 /* 275 * Take control of selected vectors from OFW. 276 * We take: undefined, swi, pre-fetch abort, data abort, addrexc, 277 * irq, fiq 278 * OFW retains: reset 279 */ 280 arm32_vector_init(ARM_VECTORS_LOW, ARM_VEC_ALL & ~ARM_VEC_RESET); 281 282 data_abort_handler_address = (u_int)data_abort_handler; 283 prefetch_abort_handler_address = (u_int)prefetch_abort_handler; 284 undefined_handler_address = 285 (u_int)undefinedinstruction_bounce; /* why is this needed? -JJK */ 286 287 /* Initialise the undefined instruction handlers. */ 288 undefined_init(); 289 290 /* Now for the SHARK-specific part of the FIQ set-up */ 291 shark_fiqhandler.fh_func = shark_fiq; 292 shark_fiqhandler.fh_size = shark_fiq_end - shark_fiq; 293 shark_fiqhandler.fh_flags = 0; 294 shark_fiqhandler.fh_regs = &shark_fiqregs; 295 296 shark_fiqregs.fr_r8 = isa_io_virtaddr; 297 shark_fiqregs.fr_r9 = 0; /* no routine right now */ 298 shark_fiqregs.fr_r10 = 0; /* no arg right now */ 299 shark_fiqregs.fr_r11 = 0; /* scratch */ 300 shark_fiqregs.fr_r12 = 0; /* scratch */ 301 shark_fiqregs.fr_r13 = 0; /* must set a stack when r9 is set! */ 302 303 if (fiq_claim(&shark_fiqhandler)) 304 panic("Cannot claim FIQ vector."); 305 306 #ifdef DDB 307 db_machine_init(); 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 value; 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, &value)) { 339 if (!value) 340 boothowto |= RB_QUIET; 341 else 342 boothowto &= ~RB_QUIET; 343 } 344 if (get_bootconf_option(args, "quiet", BOOTOPT_TYPE_BOOLEAN, &value)) { 345 if (value) 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(device_t dev, void *aux) 377 { 378 static device_t parent; 379 #if NSD > 0 || NCD > 0 380 static device_t scsipidev; 381 #endif 382 static char *boot_component; 383 struct ofbus_attach_args *oba; 384 char name[64]; 385 int i; 386 387 if (boot_component == NULL) { 388 char *cp; 389 boot_component = boot_file; 390 if (boot_component == NULL) 391 return; 392 cp = strrchr(boot_component, ':'); 393 if (cp != NULL) { 394 int cplen; 395 *cp++ = '\0'; 396 if (cp[0] == '\\') 397 cp++; 398 booted_kernel = cp; 399 400 /* Zap ".aout" suffix, arm32 libkvm now requires ELF */ 401 cplen = strlen(cp); 402 if (cplen > 5 && !strcmp(&cp[cplen-5], ".aout")) { 403 cp[cplen-5] = '\0'; 404 } 405 } 406 } 407 408 if (booted_device != NULL 409 || boot_component == NULL 410 || boot_component[0] == '\0') 411 return; 412 413 if (device_is_a(dev, "ofbus") || device_is_a(dev, "ofisa")) { 414 oba = aux; 415 } else if (parent == NULL) { 416 return; 417 } else if (parent == device_parent(dev) 418 && device_is_a(parent, "ofisa")) { 419 struct ofisa_attach_args *aa = aux; 420 oba = &aa->oba; 421 #if NWD > 0 || NSD > 0 || NCD > 0 422 } else if (device_parent(device_parent(dev)) != NULL 423 && parent == device_parent(device_parent(dev)) 424 && device_is_a(parent, "wdc")) { 425 #if NSD > 0 || NCD > 0 426 if (device_is_a(dev, "atapibus")) { 427 scsipidev = dev; 428 return; 429 } 430 #endif 431 #if NWD > 0 432 if (device_is_a(dev, "wd")) { 433 struct ata_device *adev = aux; 434 char *cp = strchr(boot_component, '@'); 435 if (cp != NULL 436 && adev->adev_drv_data->drive == strtoul(cp+1, NULL, 16) 437 && adev->adev_channel == 0) { 438 booted_device = dev; 439 return; 440 } 441 } 442 return; 443 #endif /* NWD > 0 */ 444 #if NSD > 0 || NCD > 0 445 } else if (scsipidev == device_parent(dev) 446 && (device_is_a(dev, "sd") || device_is_a(dev, "cd"))) { 447 struct scsipibus_attach_args *sa = aux; 448 char *cp = strchr(boot_component, '@'); 449 if (cp != NULL 450 && sa->sa_periph->periph_channel->chan_bustype->bustype_type == SCSIPI_BUSTYPE_ATAPI 451 && sa->sa_periph->periph_channel->chan_channel == 0 452 && sa->sa_periph->periph_target == strtoul(cp+1, NULL, 16)) { 453 booted_device = dev; 454 } 455 return; 456 #endif /* NSD > 0 || NCD > 0 */ 457 #endif /* NWD > 0 || NSD > 0 || NCD > 0 */ 458 } else { 459 return; 460 } 461 (void) of_packagename(oba->oba_phandle, name, sizeof name); 462 i = strlen(name); 463 if (!strncmp(name, &boot_component[1], i) 464 && (boot_component[i+1] == '/' || boot_component[i+1] == '\0')) { 465 boot_component += i + 1; 466 if (boot_component[0] == '/') { 467 parent = dev; 468 } else { 469 booted_device = dev; 470 } 471 } 472 } 473