locore2.c revision 1.40
1/*	$NetBSD: locore2.c,v 1.40 2013/09/06 17:43:19 tsutsui 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 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: locore2.c,v 1.40 2013/09/06 17:43:19 tsutsui Exp $");
34
35#include "opt_ddb.h"
36
37#include <sys/param.h>
38#include <sys/systm.h>
39#include <sys/proc.h>
40#include <sys/reboot.h>
41#define ELFSIZE 32
42#include <sys/exec_elf.h>
43
44#include <uvm/uvm_extern.h>
45
46#include <dev/cons.h>
47
48#include <machine/cpu.h>
49#include <machine/db_machdep.h>
50#include <machine/dvma.h>
51#include <machine/idprom.h>
52#include <machine/leds.h>
53#include <machine/mon.h>
54#include <machine/pmap.h>
55#include <machine/pte.h>
56
57#include <sun3/sun3/interreg.h>
58#include <sun3/sun3/machdep.h>
59#include <sun68k/sun68k/vector.h>
60
61/* This is defined in locore.s */
62extern char kernel_text[];
63
64/* These are defined by the linker */
65extern char etext[], edata[], end[];
66int nsym;
67char *ssym, *esym;
68
69/*
70 * XXX: m68k common code needs these...
71 * ... but this port does not need to deal with anything except
72 * an mc68030, so these two variables are always ignored.
73 */
74int cputype = CPU_68030;
75int mmutype = MMU_68030;
76
77/*
78 * Now our own stuff.
79 */
80
81extern struct pcb *curpcb;
82
83/* First C code called by locore.s */
84void _bootstrap(void);
85
86static void _vm_init(void);
87
88#if defined(DDB)
89static void _save_symtab(void);
90
91/*
92 * Preserve DDB symbols and strings by setting esym.
93 */
94static void
95_save_symtab(void)
96{
97	int i;
98	Elf_Ehdr *ehdr;
99	Elf_Shdr *shp;
100	vaddr_t minsym, maxsym;
101
102	/*
103	 * Check the ELF headers.
104	 */
105
106	ehdr = (void *)end;
107	if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG) != 0 ||
108	    ehdr->e_ident[EI_CLASS] != ELFCLASS32) {
109		mon_printf("_save_symtab: bad ELF magic\n");
110		return;
111	}
112
113	/*
114	 * Find the end of the symbols and strings.
115	 */
116
117	maxsym = 0;
118	minsym = ~maxsym;
119	shp = (Elf_Shdr *)(end + ehdr->e_shoff);
120	for (i = 0; i < ehdr->e_shnum; i++) {
121		if (shp[i].sh_type != SHT_SYMTAB &&
122		    shp[i].sh_type != SHT_STRTAB) {
123			continue;
124		}
125		minsym = min(minsym, (vaddr_t)end + shp[i].sh_offset);
126		maxsym = max(maxsym, (vaddr_t)end + shp[i].sh_offset +
127			     shp[i].sh_size);
128	}
129	nsym = 1;
130	ssym = (char *)ehdr;
131	esym = (char *)maxsym;
132}
133#endif	/* DDB */
134
135/*
136 * This function is called from _bootstrap() to initialize
137 * pre-vm-sytem virtual memory.  All this really does is to
138 * set virtual_avail to the first page following preloaded
139 * data (i.e. the kernel and its symbol table) and special
140 * things that may be needed very early (lwp0 upages).
141 * Once that is done, pmap_bootstrap() is called to do the
142 * usual preparations for our use of the MMU.
143 */
144static void
145_vm_init(void)
146{
147	vaddr_t nextva;
148
149	/*
150	 * First preserve our symbol table, which might have been
151	 * loaded after our BSS area by the boot loader.  However,
152	 * if DDB is not part of this kernel, ignore the symbols.
153	 */
154	esym = end + 4;
155#if defined(DDB)
156	/* This will advance esym past the symbols. */
157	_save_symtab();
158#endif
159
160	/*
161	 * Steal some special-purpose, already mapped pages.
162	 * Note: msgbuf is setup in machdep.c:cpu_startup()
163	 */
164	nextva = m68k_round_page(esym);
165
166	/*
167	 * Setup the u-area pages (stack, etc.) for lwp0.
168	 * This is done very early (here) to make sure the
169	 * fault handler works in case we hit an early bug.
170	 * (The fault handler may reference lwp0 stuff.)
171	 */
172	uvm_lwp_setuarea(&lwp0, nextva);
173	memset((void *)nextva, 0, USPACE);
174
175	nextva += USPACE;
176
177	/*
178	 * Now that lwp0 exists, make it the "current" one.
179	 */
180	curlwp = &lwp0;
181	curpcb = lwp_getpcb(&lwp0);
182
183	/* This does most of the real work. */
184	pmap_bootstrap(nextva);
185}
186
187/*
188 * This is called from locore.s just after the kernel is remapped
189 * to its proper address, but before the call to main().  The work
190 * done here corresponds to various things done in locore.s on the
191 * hp300 port (and other m68k) but which we prefer to do in C code.
192 * Also do setup specific to the Sun PROM monitor and IDPROM here.
193 */
194void
195_bootstrap(void)
196{
197	extern struct consdev consdev_prom;	/* XXX */
198
199	/* First, Clear BSS. */
200	memset(edata, 0, end - edata);
201
202	/* Set v_handler, get boothowto. */
203	sunmon_init();
204
205	/*
206	 * Initialize console to point to the PROM (output only) table
207	 * for early printf calls.
208	 */
209	cn_tab = &consdev_prom;
210
211	/* Handle kernel mapping, pmap_bootstrap(), etc. */
212	_vm_init();
213
214	/*
215	 * Find and save OBIO mappings needed early,
216	 * and call some init functions.
217	 */
218	obio_init();
219
220	/*
221	 * Point interrupts/exceptions to our vector table.
222	 * (Until now, we use the one setup by the PROM.)
223	 *
224	 * This is done after obio_init() / intreg_init() finds
225	 * the interrupt register and disables the NMI clock so
226	 * it will not cause "spurrious level 7" complaints.
227	 * Done after _vm_init so the PROM can debug that.
228	 */
229	setvbr((void **)vector_table);
230	/* Interrupts are enabled later, after autoconfig. */
231
232	/*
233	 * Find the IDPROM and copy it to memory.
234	 * Needs obio_init and setvbr earlier.
235	 */
236	idprom_init();
237
238	/*
239	 * Turn on the LEDs so we know power is on.
240	 * Needs idprom_init and obio_init earlier.
241	 */
242	leds_init();
243}
244