1 /* $NetBSD: locore2.c,v 1.26 2001/09/05 14:18:10 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 * 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 #define ELFSIZE 32 47 #include <sys/exec_elf.h> 48 49 #include <uvm/uvm_extern.h> 50 51 #include <machine/cpu.h> 52 #include <machine/db_machdep.h> 53 #include <machine/dvma.h> 54 #include <machine/idprom.h> 55 #include <machine/leds.h> 56 #include <machine/mon.h> 57 #include <machine/pmap.h> 58 #include <machine/pte.h> 59 60 #include <sun3/sun3/interreg.h> 61 #include <sun3/sun3/machdep.h> 62 #include <sun3/sun3/vector.h> 63 64 /* This is defined in locore.s */ 65 extern char kernel_text[]; 66 67 /* These are defined by the linker */ 68 extern char etext[], edata[], end[]; 69 int nsym; 70 char *ssym, *esym; 71 72 /* 73 * XXX: m68k common code needs these... 74 * ... but this port does not need to deal with anything except 75 * an mc68030, so these two variables are always ignored. 76 */ 77 int cputype = CPU_68030; 78 int mmutype = MMU_68030; 79 80 /* 81 * Now our own stuff. 82 */ 83 84 struct user *proc0paddr; /* proc[0] pcb address (u-area VA) */ 85 extern struct pcb *curpcb; 86 87 /* First C code called by locore.s */ 88 void _bootstrap __P((void)); 89 90 static void _vm_init __P((void)); 91 92 #if defined(DDB) && !defined(SYMTAB_SPACE) 93 static void _save_symtab __P((void)); 94 95 /* 96 * Preserve DDB symbols and strings by setting esym. 97 */ 98 static void 99 _save_symtab() 100 { 101 int i; 102 Elf_Ehdr *ehdr; 103 Elf_Shdr *shp; 104 vaddr_t minsym, maxsym; 105 106 /* 107 * Check the ELF headers. 108 */ 109 110 ehdr = (void *)end; 111 if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG) != 0 || 112 ehdr->e_ident[EI_CLASS] != ELFCLASS32) { 113 mon_printf("_save_symtab: bad ELF magic\n"); 114 return; 115 } 116 117 /* 118 * Find the end of the symbols and strings. 119 */ 120 121 maxsym = 0; 122 minsym = ~maxsym; 123 shp = (Elf_Shdr *)(end + ehdr->e_shoff); 124 for (i = 0; i < ehdr->e_shnum; i++) { 125 if (shp[i].sh_type != SHT_SYMTAB && 126 shp[i].sh_type != SHT_STRTAB) { 127 continue; 128 } 129 minsym = min(minsym, (vaddr_t)end + shp[i].sh_offset); 130 maxsym = max(maxsym, (vaddr_t)end + shp[i].sh_offset + 131 shp[i].sh_size); 132 } 133 nsym = 1; 134 ssym = (char *)ehdr; 135 esym = (char *)maxsym; 136 } 137 #endif /* DDB && !SYMTAB_SPACE */ 138 139 /* 140 * This function is called from _bootstrap() to initialize 141 * pre-vm-sytem virtual memory. All this really does is to 142 * set virtual_avail to the first page following preloaded 143 * data (i.e. the kernel and its symbol table) and special 144 * things that may be needed very early (proc0 upages). 145 * Once that is done, pmap_bootstrap() is called to do the 146 * usual preparations for our use of the MMU. 147 */ 148 static void 149 _vm_init() 150 { 151 vaddr_t nextva; 152 153 /* 154 * First preserve our symbol table, which might have been 155 * loaded after our BSS area by the boot loader. However, 156 * if DDB is not part of this kernel, ignore the symbols. 157 */ 158 esym = end + 4; 159 #if defined(DDB) && !defined(SYMTAB_SPACE) 160 /* This will advance esym past the symbols. */ 161 _save_symtab(); 162 #endif 163 164 /* 165 * Steal some special-purpose, already mapped pages. 166 * Note: msgbuf is setup in machdep.c:cpu_startup() 167 */ 168 nextva = m68k_round_page(esym); 169 170 /* 171 * Setup the u-area pages (stack, etc.) for proc0. 172 * This is done very early (here) to make sure the 173 * fault handler works in case we hit an early bug. 174 * (The fault handler may reference proc0 stuff.) 175 */ 176 proc0paddr = (struct user *) nextva; 177 nextva += USPACE; 178 memset((caddr_t)proc0paddr, 0, USPACE); 179 proc0.p_addr = proc0paddr; 180 181 /* 182 * Now that proc0 exists, make it the "current" one. 183 */ 184 curproc = &proc0; 185 curpcb = &proc0paddr->u_pcb; 186 187 /* This does most of the real work. */ 188 pmap_bootstrap(nextva); 189 } 190 191 /* 192 * This is called from locore.s just after the kernel is remapped 193 * to its proper address, but before the call to main(). The work 194 * done here corresponds to various things done in locore.s on the 195 * hp300 port (and other m68k) but which we prefer to do in C code. 196 * Also do setup specific to the Sun PROM monitor and IDPROM here. 197 */ 198 void 199 _bootstrap() 200 { 201 202 /* First, Clear BSS. */ 203 memset(edata, 0, end - edata); 204 205 /* Set v_handler, get boothowto. */ 206 sunmon_init(); 207 208 /* Handle kernel mapping, pmap_bootstrap(), etc. */ 209 _vm_init(); 210 211 /* 212 * Find and save OBIO mappings needed early, 213 * and call some init functions. 214 */ 215 obio_init(); 216 217 /* 218 * Point interrupts/exceptions to our vector table. 219 * (Until now, we use the one setup by the PROM.) 220 * 221 * This is done after obio_init() / intreg_init() finds 222 * the interrupt register and disables the NMI clock so 223 * it will not cause "spurrious level 7" complaints. 224 * Done after _vm_init so the PROM can debug that. 225 */ 226 setvbr((void **)vector_table); 227 /* Interrupts are enabled later, after autoconfig. */ 228 229 /* 230 * Find the IDPROM and copy it to memory. 231 * Needs obio_init and setvbr earlier. 232 */ 233 idprom_init(); 234 235 /* 236 * Turn on the LEDs so we know power is on. 237 * Needs idprom_init and obio_init earlier. 238 */ 239 leds_init(); 240 } 241