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 */ 62 extern char kernel_text[]; 63 64 /* These are defined by the linker */ 65 extern char etext[], edata[], end[]; 66 int nsym; 67 char *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 */ 74 int cputype = CPU_68030; 75 int mmutype = MMU_68030; 76 77 /* 78 * Now our own stuff. 79 */ 80 81 extern struct pcb *curpcb; 82 83 /* First C code called by locore.s */ 84 void _bootstrap(void); 85 86 static void _vm_init(void); 87 88 #if defined(DDB) 89 static void _save_symtab(void); 90 91 /* 92 * Preserve DDB symbols and strings by setting esym. 93 */ 94 static 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 */ 144 static 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 */ 194 void 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