xref: /netbsd-src/sys/arch/arm/ofw/ofwgencfg_machdep.c (revision bee3dfab549b89f1a37e3d2ab37c6186cbd9e929)
1*bee3dfabSskrll /*	$NetBSD: ofwgencfg_machdep.c,v 1.20 2019/07/16 14:41:44 skrll Exp $	*/
2d17cc4f0Sthorpej 
3d17cc4f0Sthorpej /*
4d17cc4f0Sthorpej  * Copyright 1997
5d17cc4f0Sthorpej  * Digital Equipment Corporation. All rights reserved.
6d17cc4f0Sthorpej  *
7d17cc4f0Sthorpej  * This software is furnished under license and may be used and
8d17cc4f0Sthorpej  * copied only in accordance with the following terms and conditions.
9d17cc4f0Sthorpej  * Subject to these conditions, you may download, copy, install,
10d17cc4f0Sthorpej  * use, modify and distribute this software in source and/or binary
11d17cc4f0Sthorpej  * form. No title or ownership is transferred hereby.
12d17cc4f0Sthorpej  *
13d17cc4f0Sthorpej  * 1) Any source code used, modified or distributed must reproduce
14d17cc4f0Sthorpej  *    and retain this copyright notice and list of conditions as
15d17cc4f0Sthorpej  *    they appear in the source file.
16d17cc4f0Sthorpej  *
17d17cc4f0Sthorpej  * 2) No right is granted to use any trade name, trademark, or logo of
18d17cc4f0Sthorpej  *    Digital Equipment Corporation. Neither the "Digital Equipment
19d17cc4f0Sthorpej  *    Corporation" name nor any trademark or logo of Digital Equipment
20d17cc4f0Sthorpej  *    Corporation may be used to endorse or promote products derived
21d17cc4f0Sthorpej  *    from this software without the prior written permission of
22d17cc4f0Sthorpej  *    Digital Equipment Corporation.
23d17cc4f0Sthorpej  *
24d17cc4f0Sthorpej  * 3) This software is provided "AS-IS" and any express or implied
25d17cc4f0Sthorpej  *    warranties, including but not limited to, any implied warranties
26d17cc4f0Sthorpej  *    of merchantability, fitness for a particular purpose, or
27d17cc4f0Sthorpej  *    non-infringement are disclaimed. In no event shall DIGITAL be
28d17cc4f0Sthorpej  *    liable for any damages whatsoever, and in particular, DIGITAL
29d17cc4f0Sthorpej  *    shall not be liable for special, indirect, consequential, or
30d17cc4f0Sthorpej  *    incidental damages or damages for lost profits, loss of
31d17cc4f0Sthorpej  *    revenue or loss of use, whether such damages arise in contract,
32d17cc4f0Sthorpej  *    negligence, tort, under statute, in equity, at law or otherwise,
33d17cc4f0Sthorpej  *    even if advised of the possibility of such damage.
34d17cc4f0Sthorpej  */
35d17cc4f0Sthorpej 
36d17cc4f0Sthorpej /*
37d17cc4f0Sthorpej  *  Kernel setup for the OFW Generic Configuration
38d17cc4f0Sthorpej  */
39d17cc4f0Sthorpej 
4008716eaeSlukem #include <sys/cdefs.h>
41*bee3dfabSskrll __KERNEL_RCSID(0, "$NetBSD: ofwgencfg_machdep.c,v 1.20 2019/07/16 14:41:44 skrll Exp $");
4208716eaeSlukem 
43d17cc4f0Sthorpej #include "opt_ddb.h"
44d17cc4f0Sthorpej 
45d17cc4f0Sthorpej #include <sys/types.h>
46d17cc4f0Sthorpej #include <sys/param.h>
47d17cc4f0Sthorpej #include <sys/systm.h>
48d17cc4f0Sthorpej #include <sys/reboot.h>
49d17cc4f0Sthorpej #include <sys/proc.h>
50d17cc4f0Sthorpej #include <sys/kernel.h>
51d17cc4f0Sthorpej #include <sys/exec.h>
5269a66687Sragge #include <sys/ksyms.h>
53cbab9cadSchs #include <sys/device.h>
54d17cc4f0Sthorpej 
55d17cc4f0Sthorpej #include <uvm/uvm_extern.h>
56d17cc4f0Sthorpej 
57d17cc4f0Sthorpej #include <dev/cons.h>
58d17cc4f0Sthorpej 
59d17cc4f0Sthorpej #include <machine/db_machdep.h>
60d17cc4f0Sthorpej #include <ddb/db_sym.h>
61d17cc4f0Sthorpej #include <ddb/db_extern.h>
62d17cc4f0Sthorpej 
63d17cc4f0Sthorpej #include <machine/frame.h>
64d17cc4f0Sthorpej #include <machine/bootconfig.h>
65d17cc4f0Sthorpej #include <machine/cpu.h>
66d17cc4f0Sthorpej #include <machine/intr.h>
67d471ccf3Smatt #include <machine/irqhandler.h>
6884e47229Sbjh21 #include <arm/arm32/machdep.h>
69d17cc4f0Sthorpej #include <arm/undefined.h>
70d17cc4f0Sthorpej 
71d17cc4f0Sthorpej #include <dev/ofw/openfirm.h>
72d17cc4f0Sthorpej #include <machine/ofw.h>
73d17cc4f0Sthorpej 
7469a66687Sragge #include "ksyms.h"
7569a66687Sragge 
76d17cc4f0Sthorpej /*
77d17cc4f0Sthorpej  *  Imported variables
78d17cc4f0Sthorpej  */
79d17cc4f0Sthorpej extern pv_addr_t undstack;
80d17cc4f0Sthorpej extern pv_addr_t abtstack;
81d17cc4f0Sthorpej extern pv_addr_t kernelstack;
82d17cc4f0Sthorpej extern u_int data_abort_handler_address;
83d17cc4f0Sthorpej extern u_int prefetch_abort_handler_address;
84d17cc4f0Sthorpej 
85d17cc4f0Sthorpej /*
86d17cc4f0Sthorpej  *  Imported routines
87d17cc4f0Sthorpej  */
8802cdf4d2Sdsl extern void data_abort_handler(trapframe_t *frame);
8902cdf4d2Sdsl extern void prefetch_abort_handler(trapframe_t *frame);
9002cdf4d2Sdsl extern void undefinedinstruction_bounce(trapframe_t *frame);
91338de10aSmatt int	ofbus_match(device_t, cfdata_t, void *);
92338de10aSmatt void	ofbus_attach(device_t, device_t, void *);
93d17cc4f0Sthorpej 
94d17cc4f0Sthorpej /* Local routines */
9502cdf4d2Sdsl static void process_kernel_args(void);
96d17cc4f0Sthorpej 
97d17cc4f0Sthorpej /*
98d17cc4f0Sthorpej  *  Exported variables
99d17cc4f0Sthorpej  */
100d17cc4f0Sthorpej BootConfig bootconfig;
101d17cc4f0Sthorpej char *boot_args = NULL;
102d17cc4f0Sthorpej char *boot_file = NULL;
103d17cc4f0Sthorpej #ifndef PMAP_STATIC_L1S
104d17cc4f0Sthorpej int max_processes = 64;			/* Default number */
105d17cc4f0Sthorpej #endif	/* !PMAP_STATIC_L1S */
106d17cc4f0Sthorpej 
107d17cc4f0Sthorpej int ofw_handleticks = 0;	/* set to TRUE by cpu_initclocks */
108d17cc4f0Sthorpej 
109338de10aSmatt CFATTACH_DECL_NEW(ofbus_root, 0,
110c5e91d44Sthorpej     ofbus_match, ofbus_attach, NULL, NULL);
111d17cc4f0Sthorpej 
112d17cc4f0Sthorpej /**************************************************************/
113d17cc4f0Sthorpej 
114d17cc4f0Sthorpej 
115d17cc4f0Sthorpej /*
116d17cc4f0Sthorpej  * void boot(int howto, char *bootstr)
117d17cc4f0Sthorpej  *
118d17cc4f0Sthorpej  * Reboots the system, in event of:
119d17cc4f0Sthorpej  *   - reboot system call
120d17cc4f0Sthorpej  *   - panic
121d17cc4f0Sthorpej  */
122d17cc4f0Sthorpej 
123d17cc4f0Sthorpej void
cpu_reboot(int howto,char * bootstr)124454af1c0Sdsl cpu_reboot(int howto, char *bootstr)
125d17cc4f0Sthorpej {
126d17cc4f0Sthorpej 	/* Just call OFW common routine. */
127d17cc4f0Sthorpej 	ofw_boot(howto, bootstr);
128d17cc4f0Sthorpej 
129d17cc4f0Sthorpej 	OF_boot("not reached -- stupid compiler");
130d17cc4f0Sthorpej }
131d17cc4f0Sthorpej 
132d17cc4f0Sthorpej 
133d17cc4f0Sthorpej /*
1343191d2a4Sbjh21  * u_int initarm(ofw_handle_t handle)
135d17cc4f0Sthorpej  *
136d17cc4f0Sthorpej  * Initial entry point on startup for a GENERIC OFW
137d17cc4f0Sthorpej  * system.  Called with MMU on, running in the OFW
138d17cc4f0Sthorpej  * client environment.
139d17cc4f0Sthorpej  *
140d17cc4f0Sthorpej  * Major tasks are:
141d17cc4f0Sthorpej  *  - read the bootargs out of OFW;
142d17cc4f0Sthorpej  *  - take over memory management from OFW;
143d17cc4f0Sthorpej  *  - set-up the stacks
144d17cc4f0Sthorpej  *  - set-up the exception handlers
145d17cc4f0Sthorpej  *
146d17cc4f0Sthorpej  * Return the new stackptr (va) for the SVC frame.
147d17cc4f0Sthorpej  *
148d17cc4f0Sthorpej  */
149*bee3dfabSskrll vaddr_t
initarm(void * cookie)1503191d2a4Sbjh21 initarm(void *cookie)
151d17cc4f0Sthorpej {
1523191d2a4Sbjh21 	ofw_handle_t ofw_handle = cookie;
1533191d2a4Sbjh21 
154d17cc4f0Sthorpej 	set_cpufuncs();
155d17cc4f0Sthorpej 
156d17cc4f0Sthorpej 	/* XXX - set this somewhere else? -JJK */
157d17cc4f0Sthorpej 	boothowto = 0;
158d17cc4f0Sthorpej 
159d17cc4f0Sthorpej 	/* Init the OFW interface. */
160d17cc4f0Sthorpej 	/* MUST do this before invoking any OFW client services! */
161d17cc4f0Sthorpej 	ofw_init(ofw_handle);
162d17cc4f0Sthorpej 
163d17cc4f0Sthorpej 	/* Initialize the console (which will call into OFW). */
164d17cc4f0Sthorpej 	/* This will allow us to see panic messages and other printf output. */
165d17cc4f0Sthorpej 	consinit();
166d17cc4f0Sthorpej 
167d17cc4f0Sthorpej 	/* Get boot info and process it. */
168d17cc4f0Sthorpej 	ofw_getbootinfo(&boot_file, &boot_args);
169d17cc4f0Sthorpej 	process_kernel_args();
170d17cc4f0Sthorpej 
171d17cc4f0Sthorpej 	/* Configure memory. */
172d17cc4f0Sthorpej 	ofw_configmem();
173d17cc4f0Sthorpej 
174d17cc4f0Sthorpej 	/*
175d17cc4f0Sthorpej 	 * Set-up stacks.
176d17cc4f0Sthorpej 	 * OFW has control of the interrupt frame.
177d17cc4f0Sthorpej 	 * The kernel stack for SVC mode will be updated on return from
178d17cc4f0Sthorpej 	 * this routine. All we need to do is prepare for abort-handling
179d17cc4f0Sthorpej 	 * and undefined exceptions.
180d17cc4f0Sthorpej 	 */
18195281cabSthorpej 	set_stackptr(PSR_UND32_MODE, undstack.pv_va + PAGE_SIZE);
18295281cabSthorpej 	set_stackptr(PSR_ABT32_MODE, abtstack.pv_va + PAGE_SIZE);
183d17cc4f0Sthorpej 
184d17cc4f0Sthorpej 	/* Set-up exception handlers.
185d17cc4f0Sthorpej 	 * Take control of selected vectors from OFW.
186d17cc4f0Sthorpej 	 * We take:  undefined, swi, pre-fetch abort, data abort, addrexc
187d17cc4f0Sthorpej 	 * OFW retains:  reset, irq, fiq
188d17cc4f0Sthorpej 	 */
18920b1bb26Sthorpej 	arm32_vector_init(ARM_VECTORS_LOW,
19020b1bb26Sthorpej 	    ARM_VEC_ALL & ~(ARM_VEC_RESET|ARM_VEC_IRQ|ARM_VEC_FIQ));
191d17cc4f0Sthorpej 
192d17cc4f0Sthorpej 	data_abort_handler_address = (u_int)data_abort_handler;
193d17cc4f0Sthorpej 	prefetch_abort_handler_address = (u_int)prefetch_abort_handler;
194d17cc4f0Sthorpej 	undefined_handler_address =
195d17cc4f0Sthorpej 	    (u_int)undefinedinstruction_bounce;	/* why is this needed? -JJK */
196d17cc4f0Sthorpej 
197d17cc4f0Sthorpej 	/* Initialise the undefined instruction handlers. */
198d17cc4f0Sthorpej 	undefined_init();
199d17cc4f0Sthorpej 
200d17cc4f0Sthorpej 	/* Set-up the IRQ system. */
201d17cc4f0Sthorpej 	irq_init();
202d17cc4f0Sthorpej 
20369a66687Sragge #ifdef DDB
20469a66687Sragge 	db_machine_init();
205d17cc4f0Sthorpej 	if (boothowto & RB_KDB)
206d17cc4f0Sthorpej 		Debugger();
207d17cc4f0Sthorpej #endif
208d17cc4f0Sthorpej 
209d17cc4f0Sthorpej 	/* Return the new stackbase. */
210d17cc4f0Sthorpej 	return(kernelstack.pv_va + USPACE_SVC_STACK_TOP);
211d17cc4f0Sthorpej }
212d17cc4f0Sthorpej 
213d17cc4f0Sthorpej 
214d17cc4f0Sthorpej /*
215d17cc4f0Sthorpej  *  Set various globals based on contents of boot_args
216d17cc4f0Sthorpej  *
217d17cc4f0Sthorpej  *  Note that this routine must NOT trash boot_args, as
218d17cc4f0Sthorpej  *  it is scanned by later routines.
219d17cc4f0Sthorpej  *
220d17cc4f0Sthorpej  *  There ought to be a routine in machdep.c that does
221d17cc4f0Sthorpej  *  the generic bits of this. -JJK
222d17cc4f0Sthorpej  */
223d17cc4f0Sthorpej static void
process_kernel_args(void)224d17cc4f0Sthorpej process_kernel_args(void)
225d17cc4f0Sthorpej {
226d17cc4f0Sthorpej 	/* Process all the generic ARM boot options */
227d17cc4f0Sthorpej 	parse_mi_bootargs(boot_args);
228d17cc4f0Sthorpej 
229d17cc4f0Sthorpej 	/* Check for ofwgencfg-specific args here. */
230d17cc4f0Sthorpej }
231d17cc4f0Sthorpej 
232d17cc4f0Sthorpej 
233d17cc4f0Sthorpej /*
234d17cc4f0Sthorpej  *  Walk the OFW device tree and configure found devices.
235d17cc4f0Sthorpej  *
236d17cc4f0Sthorpej  *  Move this into common OFW module? -JJK
237d17cc4f0Sthorpej  */
238d17cc4f0Sthorpej void
ofrootfound(void)239d17cc4f0Sthorpej ofrootfound(void)
240d17cc4f0Sthorpej {
241d17cc4f0Sthorpej 	int node;
242d17cc4f0Sthorpej 	struct ofbus_attach_args aa;
243d17cc4f0Sthorpej 
244d17cc4f0Sthorpej 	if (!(node = OF_peer(0)))
245d17cc4f0Sthorpej 		panic("No OFW root");
246d17cc4f0Sthorpej 	aa.oba_busname = "ofw";
247d17cc4f0Sthorpej 	aa.oba_phandle = node;
248d17cc4f0Sthorpej 	if (!config_rootfound("ofbus", &aa))
249d17cc4f0Sthorpej 		panic("ofw root ofbus not configured");
250d17cc4f0Sthorpej }
251