1 /* $NetBSD: machdep.c,v 1.21 2002/09/25 22:21:18 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_ddb.h" 36 #include "opt_inet.h" 37 #include "opt_ccitt.h" 38 #include "opt_iso.h" 39 #include "opt_ns.h" 40 #include "opt_ipkdb.h" 41 42 #include <sys/param.h> 43 #include <sys/buf.h> 44 #include <sys/conf.h> 45 #include <sys/device.h> 46 #include <sys/exec.h> 47 #include <sys/kernel.h> 48 #include <sys/malloc.h> 49 #include <sys/mbuf.h> 50 #include <sys/mount.h> 51 #include <sys/msgbuf.h> 52 #include <sys/proc.h> 53 #include <sys/reboot.h> 54 #include <sys/syscallargs.h> 55 #include <sys/syslog.h> 56 #include <sys/sysctl.h> 57 #include <sys/systm.h> 58 #include <sys/user.h> 59 60 #include <uvm/uvm.h> 61 #include <uvm/uvm_extern.h> 62 63 #include <net/netisr.h> 64 65 #include <powerpc/mpc6xx/bat.h> 66 #include <machine/bus.h> 67 #include <machine/db_machdep.h> 68 #include <machine/intr.h> 69 #include <machine/pmap.h> 70 #include <machine/powerpc.h> 71 #include <machine/trap.h> 72 73 #include <powerpc/openpic.h> 74 75 #include <ddb/db_extern.h> 76 77 #include <dev/cons.h> 78 79 #include "vga.h" 80 #if (NVGA > 0) 81 #include <dev/ic/mc6845reg.h> 82 #include <dev/ic/pcdisplayvar.h> 83 #include <dev/ic/vgareg.h> 84 #include <dev/ic/vgavar.h> 85 #endif 86 87 #include "isa.h" 88 #if (NISA > 0) 89 void isa_intr_init(void); 90 #endif 91 92 #include "pckbc.h" 93 #if (NPCKBC > 0) 94 #include <dev/isa/isareg.h> 95 #include <dev/ic/i8042reg.h> 96 #include <dev/ic/pckbcvar.h> 97 #endif 98 99 #include "com.h" 100 #if (NCOM > 0) 101 #include <sys/termios.h> 102 #include <dev/ic/comreg.h> 103 #include <dev/ic/comvar.h> 104 #endif 105 106 /* 107 * Global variables used here and there 108 */ 109 110 #define OFMEMREGIONS 32 111 struct mem_region physmemr[OFMEMREGIONS], availmemr[OFMEMREGIONS]; 112 113 char *bootpath; 114 unsigned char *eumb_base; 115 116 paddr_t avail_end; /* XXX temporary */ 117 118 void initppc __P((u_int, u_int, u_int, void *)); /* Called from locore */ 119 void strayintr __P((int)); 120 void lcsplx __P((int)); 121 122 #ifdef DDB 123 extern void *startsym, *endsym; 124 #endif 125 extern void consinit (void); 126 extern void ext_intr (void); 127 128 void 129 initppc(u_int startkernel, u_int endkernel, u_int args, void *btinfo) 130 { 131 132 #if 1 133 { extern unsigned char *edata, *end; 134 memset(&edata, 0, (u_int) &end - (u_int) &edata); 135 } 136 #endif 137 138 /* 139 * Hardcode 32MB for now--we should probe for this or get it 140 * from a boot loader, but for now, we are booting via an 141 * S-record loader. 142 */ 143 { /* XXX AKB */ 144 u_int32_t physmemsize; 145 146 physmemsize = 32 * 1024 * 1024; 147 physmemr[0].start = 0; 148 physmemr[0].size = physmemsize; 149 physmemr[1].size = 0; 150 availmemr[0].start = (endkernel + PGOFSET) & ~PGOFSET; 151 availmemr[0].size = physmemsize - availmemr[0].start; 152 availmemr[1].size = 0; 153 } 154 avail_end = physmemr[0].start + physmemr[0].size; /* XXX temporary */ 155 156 /* 157 * Get CPU clock 158 */ 159 { /* XXX AKB */ 160 extern u_long ticks_per_sec, ns_per_tick; 161 162 ticks_per_sec = 100000000; /* 100 MHz */ 163 /* ticks_per_sec = 66000000; * 66 MHz */ 164 ticks_per_sec /= 4; /* 4 cycles per DEC tick */ 165 cpu_timebase = ticks_per_sec; 166 ns_per_tick = 1000000000 / ticks_per_sec; 167 } 168 169 /* 170 * boothowto 171 */ 172 boothowto = RB_SINGLE; 173 174 sandpoint_bus_space_init(); 175 176 consinit(); 177 printf("avail_end %x\n", (unsigned) avail_end); 178 printf("availmemr[0].start %x\n", (unsigned) availmemr[0].start); 179 printf("availmemr[0].size %x\n", (unsigned) availmemr[0].size); 180 181 /* 182 * Initialize BAT registers. Map the EUMB MEMORY 1M area to the 183 * end of the address space This includes the PCI/ISA 16M I/O space, 184 * PCI configuration registers, etc. 185 */ 186 mpc6xx_batinit( 187 SANDPOINT_BUS_SPACE_EUMB, BAT_BL_64M, 188 SANDPOINT_BUS_SPACE_MEM, BAT_BL_256M, 189 0); 190 191 eumb_base = (unsigned char *) SANDPOINT_BUS_SPACE_EUMB; 192 193 194 /* 195 * Set up trap vectors and interrupt handler 196 */ 197 mpc6xx_init(ext_intr); 198 199 /* 200 * Set EUMB base address 201 */ 202 out32rb(SANDPOINT_PCI_CONFIG_ADDR, 0x80000078); 203 out32rb(SANDPOINT_PCI_CONFIG_DATA, SANDPOINT_BUS_SPACE_EUMB); 204 out32rb(SANDPOINT_PCI_CONFIG_ADDR, 0); 205 206 openpic_init(eumb_base + 0x40000); 207 #if (NISA > 0) 208 isa_intr_init(); 209 #endif 210 211 /* 212 * Set the page size. 213 */ 214 uvm_setpagesize(); 215 216 /* 217 * Initialize pmap module. 218 */ 219 pmap_bootstrap(startkernel, endkernel, NULL); 220 221 #ifdef DDB 222 ddb_init((int)((u_int)endsym - (u_int)startsym), startsym, endsym); 223 #endif 224 #ifdef IPKDB 225 /* 226 * Now trap to IPKDB 227 */ 228 ipkdb_init(); 229 if (boothowto & RB_KDB) 230 ipkdb_connect(0); 231 #endif 232 } 233 234 void 235 mem_regions(struct mem_region **mem, struct mem_region **avail) 236 { 237 *mem = physmemr; 238 *avail = availmemr; 239 } 240 241 /* 242 * Machine dependent startup code. 243 */ 244 void 245 cpu_startup(void) 246 { 247 int msr; 248 249 mpc6xx_startup(NULL); 250 251 /* 252 * Now that we have VM, malloc()s are OK in bus_space. 253 */ 254 sandpoint_bus_space_mallocok(); 255 256 /* 257 * Now allow hardware interrupts. 258 */ 259 splhigh(); 260 __asm __volatile ("mfmsr %0; ori %0,%0,%1; mtmsr %0" 261 : "=r"(msr) 262 : "K"(PSL_EE)); 263 } 264 265 /* 266 * consinit 267 * Initialize system console. 268 */ 269 void 270 consinit(void) 271 { 272 static int initted; 273 #if (NCOM > 0) 274 bus_space_tag_t tag; 275 #endif 276 277 if (initted) 278 return; 279 initted = 1; 280 281 #if (NCOM > 0) 282 tag = &sandpoint_isa_io_bs_tag; 283 284 if(comcnattach(tag, 0x3F8, 38400, COM_FREQ, 285 ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8))) 286 panic("can't init serial console"); 287 else 288 return; 289 #endif 290 291 panic("console device missing -- serial console not in kernel"); 292 /* Of course, this is moot if there is no console... */ 293 } 294 295 #if (NPCKBC > 0) && (NPCKBD == 0) 296 /* 297 * glue code to support old console code with the 298 * mi keyboard controller driver 299 */ 300 int 301 pckbc_machdep_cnattach(pckbc_tag_t kbctag, pckbc_slot_t kbcslot) 302 { 303 #if (NPC > 0) 304 return (pcconskbd_cnattach(kbctag, kbcslot)); 305 #else 306 return (ENXIO); 307 #endif 308 } 309 #endif 310 311 /* 312 * Stray interrupts. 313 */ 314 void 315 strayintr(int irq) 316 { 317 log(LOG_ERR, "stray interrupt %d\n", irq); 318 } 319 320 /* 321 * Halt or reboot the machine after syncing/dumping according to howto. 322 */ 323 void 324 cpu_reboot(int howto, char *what) 325 { 326 static int syncing; 327 static char str[256]; 328 char *ap = str, *ap1 = ap; 329 330 boothowto = howto; 331 if (!cold && !(howto & RB_NOSYNC) && !syncing) { 332 syncing = 1; 333 vfs_shutdown(); /* sync */ 334 resettodr(); /* set wall clock */ 335 } 336 splhigh(); 337 if (howto & RB_HALT) { 338 doshutdownhooks(); 339 printf("halted\n\n"); 340 while(1); 341 } 342 if (!cold && (howto & RB_DUMP)) 343 mpc6xx_dumpsys(); 344 doshutdownhooks(); 345 printf("rebooting\n\n"); 346 if (what && *what) { 347 if (strlen(what) > sizeof str - 5) 348 printf("boot string too large, ignored\n"); 349 else { 350 strcpy(str, what); 351 ap1 = ap = str + strlen(str); 352 *ap++ = ' '; 353 } 354 } 355 *ap++ = '-'; 356 if (howto & RB_SINGLE) 357 *ap++ = 's'; 358 if (howto & RB_KDB) 359 *ap++ = 'd'; 360 *ap++ = 0; 361 if (ap[-2] == '-') 362 *ap1 = 0; 363 #if 1 364 { extern void sandpoint_reboot __P((void)); 365 sandpoint_reboot(); 366 } 367 #endif 368 while (1); 369 } 370 371 void 372 lcsplx(int ipl) 373 { 374 splx(ipl); 375 } 376