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