locore2.c revision 1.21
1/*	$NetBSD: locore2.c,v 1.21 1998/07/04 22:18:44 jonathan Exp $	*/
2
3/*-
4 * Copyright (c) 1996 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Gordon W. Ross and Jeremy Cooper.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 *    must display the following acknowledgement:
20 *        This product includes software developed by the NetBSD
21 *        Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 *    contributors may be used to endorse or promote products derived
24 *    from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39#include "opt_ddb.h"
40
41#include <sys/param.h>
42#include <sys/systm.h>
43#include <sys/proc.h>
44#include <sys/reboot.h>
45#include <sys/user.h>
46#include <sys/exec_aout.h>
47
48#include <vm/vm.h>
49
50#include <machine/cpu.h>
51#include <machine/db_machdep.h>
52#include <machine/dvma.h>
53#include <machine/idprom.h>
54#include <machine/leds.h>
55#include <machine/mon.h>
56#include <machine/pmap.h>
57#include <machine/pte.h>
58
59#include <sun3/sun3/interreg.h>
60#include <sun3/sun3/machdep.h>
61#include <sun3/sun3/vector.h>
62
63/* This is defined in locore.s */
64extern char kernel_text[];
65
66/* These are defined by the linker */
67extern char etext[], edata[], end[];
68char *esym;	/* DDB */
69
70/*
71 * XXX: m68k common code needs these...
72 * ... but this port does not need to deal with anything except
73 * an mc68030, so these two variables are always ignored.
74 * XXX: Need to do something about <m68k/include/cpu.h>
75 */
76int cputype =  1;	/* CPU_68030 */
77int mmutype = -1;	/* MMU_68030 */
78
79/*
80 * Now our own stuff.
81 */
82
83struct user *proc0paddr;	/* proc[0] pcb address (u-area VA) */
84extern struct pcb *curpcb;
85
86/* First C code called by locore.s */
87void _bootstrap __P((struct exec));
88
89static void _vm_init __P((struct exec *kehp));
90
91#if defined(DDB) && !defined(SYMTAB_SPACE)
92static void _save_symtab __P((struct exec *kehp));
93
94/*
95 * Preserve DDB symbols and strings by setting esym.
96 */
97static void
98_save_symtab(kehp)
99	struct exec *kehp;	/* kernel exec header */
100{
101	int x, *symsz, *strsz;
102	char *endp, *errdesc;
103
104	/* Initialize */
105	endp = end;
106	symsz = (int*)end;
107
108	/*
109	 * Sanity-check the exec header.
110	 */
111	errdesc = "bad magic";
112	if ((kehp->a_midmag & 0xFFF0) != 0x0100)
113		goto err;
114
115	/* Boundary between text and data varries a little. */
116	errdesc = "bad header";
117	x = kehp->a_text + kehp->a_data;
118	if (x != (edata - kernel_text))
119		goto err;
120	if (kehp->a_bss != (end - edata))
121		goto err;
122	if (kehp->a_entry != (int)kernel_text)
123		goto err;
124	if (kehp->a_trsize || kehp->a_drsize)
125		goto err;
126	/* The exec header looks OK... */
127
128	/* Check the symtab length word. */
129	errdesc = "bad symbols/strings";
130	if (kehp->a_syms != *symsz)
131		goto err;
132	endp += sizeof(int);	/* past length word */
133	endp += *symsz;			/* past nlist array */
134
135	/* Sanity-check the string table length. */
136	strsz = (int*)endp;
137	if ((*strsz < 4) || (*strsz > 0x80000))
138		goto err;
139	/* OK, we have a valid symbol table. */
140	endp += *strsz;			/* past strings */
141
142	/* Success!  Advance esym past the symbol data. */
143	esym = endp;
144	return;
145
146 err:
147	/*
148	 * Make sure the later call to ddb_init()
149	 * will pass zero as the symbol table size.
150	 */
151	*symsz = 0;
152	mon_printf("_save_symtab: %s\n", errdesc);
153}
154#endif	/* DDB && !SYMTAB_SPACE */
155
156/*
157 * This function is called from _bootstrap() to initialize
158 * pre-vm-sytem virtual memory.  All this really does is to
159 * set virtual_avail to the first page following preloaded
160 * data (i.e. the kernel and its symbol table) and special
161 * things that may be needed very early (proc0 upages).
162 * Once that is done, pmap_bootstrap() is called to do the
163 * usual preparations for our use of the MMU.
164 */
165static void
166_vm_init(kehp)
167	struct exec *kehp;	/* kernel exec header */
168{
169	vm_offset_t nextva;
170
171	/*
172	 * First preserve our symbol table, which might have been
173	 * loaded after our BSS area by the boot loader.  However,
174	 * if DDB is not part of this kernel, ignore the symbols.
175	 */
176	esym = end + 4;
177#if defined(DDB) && !defined(SYMTAB_SPACE)
178	/* This will advance esym past the symbols. */
179	_save_symtab(kehp);
180#endif
181
182	/*
183	 * Steal some special-purpose, already mapped pages.
184	 * Note: msgbuf is setup in machdep.c:cpu_startup()
185	 */
186	nextva = m68k_round_page(esym);
187
188	/*
189	 * Setup the u-area pages (stack, etc.) for proc0.
190	 * This is done very early (here) to make sure the
191	 * fault handler works in case we hit an early bug.
192	 * (The fault handler may reference proc0 stuff.)
193	 */
194	proc0paddr = (struct user *) nextva;
195	nextva += USPACE;
196	bzero((caddr_t)proc0paddr, USPACE);
197	proc0.p_addr = proc0paddr;
198
199	/*
200	 * Now that proc0 exists, make it the "current" one.
201	 */
202	curproc = &proc0;
203	curpcb = &proc0paddr->u_pcb;
204
205	/* This does most of the real work. */
206	pmap_bootstrap(nextva);
207}
208
209/*
210 * This is called from locore.s just after the kernel is remapped
211 * to its proper address, but before the call to main().  The work
212 * done here corresponds to various things done in locore.s on the
213 * hp300 port (and other m68k) but which we prefer to do in C code.
214 * Also do setup specific to the Sun PROM monitor and IDPROM here.
215 */
216void
217_bootstrap(keh)
218	struct exec keh;	/* kernel exec header */
219{
220
221	/* First, Clear BSS. */
222	bzero(edata, end - edata);
223
224	/* Set v_handler, get boothowto. */
225	sunmon_init();
226
227	/* Handle kernel mapping, pmap_bootstrap(), etc. */
228	_vm_init(&keh);
229
230	/*
231	 * Find and save OBIO mappings needed early,
232	 * and call some init functions.
233	 */
234	obio_init();
235
236	/*
237	 * Point interrupts/exceptions to our vector table.
238	 * (Until now, we use the one setup by the PROM.)
239	 *
240	 * This is done after obio_init() / intreg_init() finds
241	 * the interrupt register and disables the NMI clock so
242	 * it will not cause "spurrious level 7" complaints.
243	 * Done after _vm_init so the PROM can debug that.
244	 */
245	setvbr((void **)vector_table);
246	/* Interrupts are enabled later, after autoconfig. */
247
248	/*
249	 * Find the IDPROM and copy it to memory.
250	 * Needs obio_init and setvbr earlier.
251	 */
252	idprom_init();
253
254	/*
255	 * Turn on the LEDs so we know power is on.
256	 * Needs idprom_init and obio_init earlier.
257	 */
258	leds_init();
259}
260