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
cpu_reboot(int howto,char * bootstr)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
initarm(void * arg)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
process_kernel_args(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
ofrootfound(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
ofw_device_register(device_t dev,void * aux)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