Home | History | Annotate | Line # | Download | only in shark
      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