1 /* $NetBSD: machdep.c,v 1.6 2002/09/25 22:21:14 thorpej Exp $ */ 2 3 /* 4 * Copyright (C) 1995, 1996 Wolfgang Solfrank. 5 * Copyright (C) 1995, 1996 TooLs GmbH. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by TooLs GmbH. 19 * 4. The name of TooLs GmbH may not be used to endorse or promote products 20 * derived from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 28 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include "opt_compat_netbsd.h" 35 #include "opt_mvmetype.h" 36 #include "opt_ddb.h" 37 38 #include <sys/param.h> 39 #include <sys/buf.h> 40 #include <sys/conf.h> 41 #include <sys/device.h> 42 #include <sys/exec.h> 43 #include <sys/kernel.h> 44 #include <sys/malloc.h> 45 #include <sys/mbuf.h> 46 #include <sys/mount.h> 47 #include <sys/msgbuf.h> 48 #include <sys/proc.h> 49 #include <sys/reboot.h> 50 #include <sys/syscallargs.h> 51 #include <sys/syslog.h> 52 #include <sys/systm.h> 53 #include <sys/user.h> 54 55 #include <uvm/uvm_extern.h> 56 57 #include <sys/sysctl.h> 58 59 #include <net/netisr.h> 60 61 #include <machine/autoconf.h> 62 #include <machine/bat.h> 63 #include <machine/bootinfo.h> 64 #include <machine/bus.h> 65 #include <machine/intr.h> 66 #include <machine/pmap.h> 67 #include <machine/platform.h> 68 #include <machine/powerpc.h> 69 #include <machine/trap.h> 70 71 #include <dev/cons.h> 72 73 #if 0 74 #include "vga.h" 75 #if (NVGA > 0) 76 #include <dev/ic/mc6845reg.h> 77 #include <dev/ic/pcdisplayvar.h> 78 #include <dev/ic/vgareg.h> 79 #include <dev/ic/vgavar.h> 80 #endif 81 82 #include "pckbc.h" 83 #if (NPCKBC > 0) 84 #include <dev/isa/isareg.h> 85 #include <dev/ic/i8042reg.h> 86 #include <dev/ic/pckbcvar.h> 87 #endif 88 #endif 89 90 #include "com.h" 91 #if (NCOM > 0) 92 #include <sys/termios.h> 93 #include <dev/ic/comreg.h> 94 #include <dev/ic/comvar.h> 95 void comsoft(void); 96 #endif 97 98 #ifdef DDB 99 #include <machine/db_machdep.h> 100 #include <ddb/db_extern.h> 101 #endif 102 103 void initppc(u_long, u_long, void *); 104 void strayintr(int); 105 int lcsplx(int); 106 107 108 /* 109 * Global variables used here and there 110 */ 111 struct mvmeppc_bootinfo bootinfo; 112 113 vaddr_t mvmeppc_intr_reg; /* PReP-compatible interrupt vector register */ 114 115 struct mem_region physmemr[2], availmemr[2]; 116 117 paddr_t avail_end; /* XXX temporary */ 118 119 void 120 initppc(startkernel, endkernel, btinfo) 121 u_long startkernel, endkernel; 122 void *btinfo; 123 { 124 #ifdef DDB 125 extern void *startsym, *endsym; 126 #endif 127 128 /* 129 * Copy bootinfo. 130 */ 131 memcpy(&bootinfo, btinfo, sizeof(bootinfo)); 132 133 /* 134 * Figure out the board family/type. 135 */ 136 ident_platform(); 137 138 if (platform == NULL) { 139 extern void _mvmeppc_unsup_board(const char *, const char *); 140 char msg[80]; 141 142 sprintf(msg, "Unsupported model: MVME%04x", 143 bootinfo.bi_modelnumber); 144 _mvmeppc_unsup_board(msg, &msg[strlen(msg)]); 145 /* NOTREACHED */ 146 } 147 148 /* 149 * Set memory region 150 */ 151 physmemr[0].start = 0; 152 physmemr[0].size = bootinfo.bi_memsize & ~PGOFSET; 153 availmemr[0].start = (endkernel + PGOFSET) & ~PGOFSET; 154 availmemr[0].size = bootinfo.bi_memsize - availmemr[0].start; 155 avail_end = physmemr[0].start + physmemr[0].size; /* XXX temporary */ 156 157 /* 158 * Set CPU clock 159 */ 160 { 161 extern u_long ticks_per_sec, ns_per_tick; 162 163 ticks_per_sec = bootinfo.bi_clocktps; 164 ns_per_tick = 1000000000 / ticks_per_sec; 165 } 166 167 /* 168 * boothowto 169 */ 170 mpc6xx_batinit( 171 MVMEPPC_PHYS_BASE_IO, BAT_BL_256M, 172 MVMEPPC_PHYS_BASE_MEM, BAT_BL_256M, 173 0); 174 175 /* 176 * Install vectors and interrupt handler. 177 */ 178 mpc6xx_init(platform->ext_intr); 179 180 #ifdef DEBUG 181 /* 182 * i386 port says, that this shouldn't be here, 183 * but I really think the console should be initialized 184 * as early as possible. 185 */ 186 consinit(); 187 #endif 188 /* 189 * Set the page size. 190 */ 191 uvm_setpagesize(); 192 193 /* 194 * Initialize pmap module. 195 */ 196 pmap_bootstrap(startkernel, endkernel, NULL); 197 198 #ifdef DDB 199 ddb_init((int)((u_long)endsym - (u_long)startsym), startsym, endsym); 200 201 if (boothowto & RB_KDB) 202 Debugger(); 203 #endif 204 } 205 206 void 207 mem_regions(mem, avail) 208 struct mem_region **mem, **avail; 209 { 210 211 *mem = physmemr; 212 *avail = availmemr; 213 } 214 215 /* 216 * Machine dependent startup code. 217 */ 218 void 219 cpu_startup() 220 { 221 char modelbuf[256]; 222 223 /* 224 * Mapping PReP-compatible interrput vector register. 225 */ 226 mvmeppc_intr_reg = (vaddr_t) mapiodev(MVMEPPC_INTR_REG, NBPG); 227 if (!mvmeppc_intr_reg) 228 panic("startup: no room for interrupt register"); 229 230 sprintf(modelbuf, "%s\nCore Speed: %dMHz, Bus Speed: %dMHz\n", 231 platform->model, 232 bootinfo.bi_mpuspeed/1000000, 233 bootinfo.bi_busspeed/1000000); 234 mpc6xx_startup(modelbuf); 235 236 /* 237 * Now allow hardware interrupts. 238 */ 239 { 240 int msr; 241 242 splraise(-1); 243 __asm __volatile ("mfmsr %0; ori %0,%0,%1; mtmsr %0" 244 : "=r"(msr) : "K"(PSL_EE)); 245 } 246 247 mvmeppc_bus_space_init(); 248 } 249 250 /* 251 * consinit 252 * Initialize system console. 253 */ 254 void 255 consinit() 256 { 257 static int initted = 0; 258 259 if (initted) 260 return; 261 initted = 1; 262 263 #if 0 264 265 #if (NPFB > 0) 266 if (!strcmp(consinfo->devname, "fb")) { 267 pfb_cnattach(consinfo->addr); 268 #if (NPCKBC > 0) 269 pckbc_cnattach(&mvmeppc_isa_io_space_tag, IO_KBD, KBCMDP, 270 PCKBC_KBD_SLOT); 271 #endif 272 return; 273 } 274 #endif 275 276 #if (NVGA > 0) || (NGTEN > 0) 277 if (!strcmp(consinfo->devname, "vga")) { 278 #if (NGTEN > 0) 279 if (!gten_cnattach(&mvmeppc_mem_space_tag)) 280 goto dokbd; 281 #endif 282 #if (NVGA > 0) 283 if (!vga_cnattach(&mvmeppc_io_space_tag, &mvmeppc_mem_space_tag, 284 -1, 1)) 285 goto dokbd; 286 #endif 287 dokbd: 288 #if (NPCKBC > 0) 289 pckbc_cnattach(&mvmeppc_isa_io_space_tag, IO_KBD, KBCMDP, 290 PCKBC_KBD_SLOT); 291 #endif 292 return; 293 } 294 #endif /* PC | VGA */ 295 296 #endif 297 298 #if (NCOM > 0) 299 if (!strcmp(bootinfo.bi_consoledev, "PC16550")) { 300 bus_space_tag_t tag = &mvmeppc_isa_io_bs_tag; 301 bus_addr_t caddr[2] = {0x3f8, 0x2f8}; 302 int rv; 303 rv = comcnattach(tag, caddr[bootinfo.bi_consolechan], 304 bootinfo.bi_consolespeed, COM_FREQ, 305 bootinfo.bi_consolecflag); 306 if (rv) 307 panic("can't init serial console"); 308 309 return; 310 } 311 #endif 312 panic("invalid console device %s", bootinfo.bi_consoledev); 313 } 314 315 /* 316 * Soft tty interrupts. 317 */ 318 void 319 softserial() 320 { 321 322 #if (NCOM > 0) 323 comsoft(); 324 #endif 325 } 326 327 /* 328 * Stray interrupts. 329 */ 330 void 331 strayintr(irq) 332 int irq; 333 { 334 335 log(LOG_ERR, "stray interrupt %d\n", irq); 336 } 337 338 /* 339 * Halt or reboot the machine after syncing/dumping according to howto. 340 */ 341 void 342 cpu_reboot(howto, what) 343 int howto; 344 char *what; 345 { 346 static int syncing; 347 348 if (cold) { 349 howto |= RB_HALT; 350 goto halt_sys; 351 } 352 353 boothowto = howto; 354 if ((howto & RB_NOSYNC) == 0 && syncing == 0) { 355 syncing = 1; 356 vfs_shutdown(); /* sync */ 357 resettodr(); /* set wall clock */ 358 } 359 360 /* Disable intr */ 361 splhigh(); 362 363 /* Do dump if requested */ 364 if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP) 365 mpc6xx_dumpsys(); 366 367 halt_sys: 368 doshutdownhooks(); 369 370 if (howto & RB_HALT) { 371 printf("\n"); 372 printf("The operating system has halted.\n"); 373 printf("Please press any key to reboot.\n\n"); 374 cnpollc(1); /* for proper keyboard command handling */ 375 cngetc(); 376 cnpollc(0); 377 } 378 379 printf("rebooting...\n\n"); 380 381 #if 0 382 (*platform->reset)(); 383 #endif 384 385 for (;;) 386 continue; 387 /* NOTREACHED */ 388 } 389 390 /* 391 * lcsplx() is called from locore; it is an open-coded version of 392 * splx() differing in that it returns the previous priority level. 393 */ 394 int 395 lcsplx(ipl) 396 int ipl; 397 { 398 int oldcpl; 399 400 __asm__ volatile("sync; eieio\n"); /* reorder protect */ 401 oldcpl = cpl; 402 cpl = ipl; 403 if (ipending & ~ipl) 404 do_pending_int(); 405 __asm__ volatile("sync; eieio\n"); /* reorder protect */ 406 407 return (oldcpl); 408 } 409