1 /* $NetBSD: machdep.c,v 1.10 2010/12/20 00:25:32 matt Exp $ */ 2 3 /* 4 * Copyright (c) 2002 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Lennart Augustsson (lennart@augustsson.net) at Sandburst Corp. 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 /* 33 * Copyright (C) 1995, 1996 Wolfgang Solfrank. 34 * Copyright (C) 1995, 1996 TooLs GmbH. 35 * All rights reserved. 36 * 37 * Redistribution and use in source and binary forms, with or without 38 * modification, are permitted provided that the following conditions 39 * are met: 40 * 1. Redistributions of source code must retain the above copyright 41 * notice, this list of conditions and the following disclaimer. 42 * 2. Redistributions in binary form must reproduce the above copyright 43 * notice, this list of conditions and the following disclaimer in the 44 * documentation and/or other materials provided with the distribution. 45 * 3. All advertising materials mentioning features or use of this software 46 * must display the following acknowledgement: 47 * This product includes software developed by TooLs GmbH. 48 * 4. The name of TooLs GmbH may not be used to endorse or promote products 49 * derived from this software without specific prior written permission. 50 * 51 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 52 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 53 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 54 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 56 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 57 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 58 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 59 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 60 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 61 */ 62 63 #include <sys/cdefs.h> 64 __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.10 2010/12/20 00:25:32 matt Exp $"); 65 66 #include "opt_compat_netbsd.h" 67 #include "opt_ddb.h" 68 #include "opt_ddbparam.h" 69 #include "opt_inet.h" 70 #include "opt_ccitt.h" 71 #include "opt_iso.h" 72 #include "opt_ns.h" 73 #include "opt_ipkdb.h" 74 75 #include <sys/param.h> 76 #include <sys/buf.h> 77 #include <sys/conf.h> 78 #include <sys/device.h> 79 #include <sys/exec.h> 80 #include <sys/extent.h> 81 #include <sys/kernel.h> 82 #include <sys/kgdb.h> 83 #include <sys/malloc.h> 84 #include <sys/mbuf.h> 85 #include <sys/mount.h> 86 #include <sys/msgbuf.h> 87 #include <sys/proc.h> 88 #include <sys/reboot.h> 89 #include <sys/syscallargs.h> 90 #include <sys/syslog.h> 91 #include <sys/sysctl.h> 92 #include <sys/systm.h> 93 #include <sys/ksyms.h> 94 95 #include <uvm/uvm_extern.h> 96 97 #include <net/netisr.h> 98 99 #include <machine/bus.h> 100 #include <machine/db_machdep.h> 101 #include <machine/intr.h> 102 #include <machine/pio.h> 103 #include <machine/pmap.h> 104 #include <machine/powerpc.h> 105 #include <machine/trap.h> 106 #include <machine/pmppc.h> 107 108 #include <powerpc/oea/bat.h> 109 #include <arch/powerpc/pic/picvar.h> 110 111 #include <ddb/db_extern.h> 112 113 #include <dev/cons.h> 114 115 #include <dev/ic/cpc700reg.h> 116 #include <dev/ic/cpc700uic.h> 117 118 #include "com.h" 119 #if (NCOM > 0) 120 #include <sys/termios.h> 121 #include <dev/ic/comreg.h> 122 #include <dev/ic/comvar.h> 123 #endif 124 125 #include "ksyms.h" 126 127 struct powerpc_bus_space pmppc_mem_tag = { 128 _BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_MEM_TYPE, 129 0, 0, 0xffffffff, 130 NULL, 131 }; 132 struct powerpc_bus_space pmppc_pci_io_tag = { 133 _BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_MEM_TYPE, 134 0, CPC_PCI_IO_BASE, 0xffffffff, 135 NULL, 136 }; 137 138 static char ex_storage[1][EXTENT_FIXED_STORAGE_SIZE(8)] 139 __attribute__((aligned(8))); 140 141 142 #ifdef KGDB 143 char kgdb_devname[] = KGDB_DEVNAME; 144 int comkgdbaddr = KGDB_DEVADDR; 145 int comkgdbrate = KGDB_DEVRATE; 146 147 #ifndef KGDB_DEVMODE 148 #define KGDB_DEVMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */ 149 #endif 150 int comkgdbmode = KGDB_DEVMODE; 151 152 void kgdb_port_init(void); 153 #endif /* KGDB */ 154 155 /* 156 * Global variables used here and there 157 */ 158 struct mem_region physmemr[2], availmemr[2]; 159 160 struct a_config a_config; 161 162 void initppc(u_int, u_int, u_int, void *); /* Called from locore */ 163 void pmppc_setup(void); 164 void setleds(int leds); 165 166 void 167 initppc(u_int startkernel, u_int endkernel, u_int args, void *btinfo) 168 { 169 extern void consinit(void); 170 extern u_long ticks_per_sec; 171 extern unsigned char edata[], end[]; 172 173 memset(&edata, 0, end - edata); /* clear BSS */ 174 175 pmppc_setup(); 176 177 physmemr[0].start = 0; 178 physmemr[0].size = a_config.a_mem_size; 179 physmemr[1].size = 0; 180 availmemr[0].start = (endkernel + PGOFSET) & ~PGOFSET; 181 availmemr[0].size = a_config.a_mem_size - availmemr[0].start; 182 availmemr[1].size = 0; 183 184 #ifdef BOOTHOWTO 185 /* 186 * boothowto 187 */ 188 boothowto = BOOTHOWTO; 189 #endif 190 191 if (bus_space_init(&pmppc_mem_tag, "iomem", 192 ex_storage[0], sizeof(ex_storage[0]))) 193 panic("bus_space_init failed"); 194 195 /* 196 * Initialize the BAT registers 197 */ 198 oea_batinit( 199 PMPPC_FLASH_BASE, BAT_BL_256M, /* flash (etc) memory 256M area */ 200 CPC_PCI_MEM_BASE, BAT_BL_256M, /* PCI memory 256M area */ 201 CPC_PCI_IO_BASE, BAT_BL_128M, /* PCI I/O 128M area */ 202 0); 203 204 /* 205 * Set up trap vectors 206 */ 207 oea_init(NULL); 208 209 /* 210 * Get CPU clock 211 */ 212 ticks_per_sec = a_config.a_bus_freq; 213 ticks_per_sec /= 4; /* 4 cycles per DEC tick */ 214 cpu_timebase = ticks_per_sec; 215 216 /* 217 * Set up console. 218 */ 219 consinit(); /* XXX should not be here */ 220 221 printf("console set up\n"); 222 223 /* 224 * Set the page size. 225 */ 226 uvm_setpagesize(); 227 228 /* 229 * Initialize pmap module. 230 */ 231 pmap_bootstrap(startkernel, endkernel); 232 233 #ifdef IPKDB 234 /* 235 * Now trap to IPKDB 236 */ 237 ipkdb_init(); 238 if (boothowto & RB_KDB) 239 ipkdb_connect(0); 240 #endif 241 #ifdef KGDB 242 kgdb_port_init(); 243 if (boothowto & RB_KDB) { 244 kgdb_debug_init = 1; 245 kgdb_connect(1); 246 } 247 #endif 248 } 249 250 void 251 mem_regions(struct mem_region **mem, struct mem_region **avail) 252 { 253 *mem = physmemr; 254 *avail = availmemr; 255 } 256 257 /* 258 * Machine dependent startup code. 259 */ 260 void 261 cpu_startup(void) 262 { 263 264 oea_startup(NULL); 265 266 /* 267 * Now that we have VM, malloc()s are OK in bus_space. 268 */ 269 bus_space_mallocok(); 270 271 /* Set up the PCI bus tag. */ 272 if (bus_space_init(&pmppc_pci_io_tag, "pcimem", NULL, 0)) 273 panic("bus_space_init pci failed"); 274 275 /* Set up interrupt controller */ 276 cpc700_init_intr(&pmppc_mem_tag, CPC_UIC_BASE, 277 CPC_INTR_MASK(PMPPC_I_ETH_INT), 0); 278 279 pic_init(); 280 (void)setup_cpc700(); 281 oea_install_extint(pic_ext_intr); 282 283 #if 0 284 /* XXX doesn't seem to be needed anymore */ 285 /* 286 * Now allow hardware interrupts. 287 */ 288 __asm volatile ("mfmsr %0; ori %0,%0,%1; mtmsr %0" 289 : "=r"(msr) : "K"(PSL_EE)); 290 #endif 291 } 292 293 /* 294 * consinit 295 * Initialize system console. 296 */ 297 void 298 consinit(void) 299 { 300 static int initted; 301 #if (NCOM > 0) 302 bus_space_tag_t tag; 303 #endif 304 305 if (initted) 306 return; 307 initted = 1; 308 309 #if (NCOM > 0) 310 tag = &pmppc_mem_tag; 311 312 if(comcnattach(tag, CPC_COM0, 9600, CPC_COM_SPEED(a_config.a_bus_freq), 313 COM_TYPE_NORMAL, 314 ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8))) 315 panic("can't init serial console"); 316 else 317 return; 318 #endif 319 320 panic("console device missing -- serial console not in kernel"); 321 /* Of course, this is moot if there is no console... */ 322 } 323 324 #ifdef KGDB 325 void 326 kgdb_port_init(void) 327 { 328 #if (NCOM > 0) 329 if(!strcmp(kgdb_devname, "com")) { 330 bus_space_tag_t tag = &pmppc_mem_tag; 331 com_kgdb_attach(tag, comkgdbaddr, comkgdbrate, 332 CPC_COM_SPEED(a_config.a_bus_freq), 333 COM_TYPE_NORMAL, comkgdbmode); 334 } 335 #endif 336 } 337 #endif 338 339 /* 340 * Halt or reboot the machine after syncing/dumping according to howto. 341 */ 342 void 343 cpu_reboot(int howto, char *what) 344 { 345 static int syncing; 346 static char str[256]; 347 char *ap = str, *ap1 = ap; 348 extern void disable_intr(void); 349 350 boothowto = howto; 351 if (!cold && !(howto & RB_NOSYNC) && !syncing) { 352 syncing = 1; 353 vfs_shutdown(); /* sync */ 354 resettodr(); /* set wall clock */ 355 } 356 splhigh(); 357 if (howto & RB_HALT) { 358 doshutdownhooks(); 359 pmf_system_shutdown(boothowto); 360 printf("halted\n\n"); 361 while(1); 362 } 363 if (!cold && (howto & RB_DUMP)) 364 oea_dumpsys(); 365 doshutdownhooks(); 366 367 pmf_system_shutdown(boothowto); 368 printf("rebooting\n\n"); 369 if (what && *what) { 370 if (strlen(what) > sizeof str - 5) 371 printf("boot string too large, ignored\n"); 372 else { 373 strcpy(str, what); 374 ap1 = ap = str + strlen(str); 375 *ap++ = ' '; 376 } 377 } 378 *ap++ = '-'; 379 if (howto & RB_SINGLE) 380 *ap++ = 's'; 381 if (howto & RB_KDB) 382 *ap++ = 'd'; 383 *ap++ = 0; 384 if (ap[-2] == '-') 385 *ap1 = 0; 386 387 disable_intr(); 388 389 /* Write the two byte reset sequence to the reset register. */ 390 out8(PMPPC_RESET, PMPPC_RESET_SEQ_STEP1); 391 out8(PMPPC_RESET, PMPPC_RESET_SEQ_STEP2); 392 393 while (1); 394 } 395 396 void 397 setleds(int leds) 398 { 399 out8(PMPPC_LEDS, leds); 400 } 401 402 void 403 pmppc_setup(void) 404 { 405 uint config0, config1; 406 407 config0 = in8(PMPPC_CONFIG0); 408 config1 = in8(PMPPC_CONFIG1); 409 410 /* from page 2-8 in the Artesyn User's manual */ 411 a_config.a_boot_device = config1 & 0x80 ? A_BOOT_FLASH : A_BOOT_ROM; 412 a_config.a_has_ecc = (config1 & 0x40) != 0; 413 switch (config1 & 0x30) { 414 case 0x00: a_config.a_mem_size = 32 * 1024 * 1024; break; 415 case 0x10: a_config.a_mem_size = 64 * 1024 * 1024; break; 416 case 0x20: a_config.a_mem_size = 128 * 1024 * 1024; break; 417 case 0x30: a_config.a_mem_size = 256 * 1024 * 1024; break; 418 } 419 a_config.a_l2_cache = (config1 >> 2) & 3; 420 switch (config1 & 0x03) { 421 case 0x00: a_config.a_bus_freq = 66666666; break; 422 case 0x01: a_config.a_bus_freq = 83333333; break; 423 case 0x02: a_config.a_bus_freq = 100000000; break; 424 case 0x03: a_config.a_bus_freq = 0; break; /* XXX */ 425 } 426 a_config.a_is_monarch = (config0 & 0x80) == 0; 427 a_config.a_has_eth = (config0 & 0x20) != 0; 428 a_config.a_has_rtc = (config0 & 0x10) == 0; 429 switch (config0 & 0x0c) { 430 case 0x00: a_config.a_flash_size = 256 * 1024 * 1024; break; 431 case 0x04: a_config.a_flash_size = 128 * 1024 * 1024; break; 432 case 0x08: a_config.a_flash_size = 64 * 1024 * 1024; break; 433 case 0x0c: a_config.a_flash_size = 32 * 1024 * 1024; break; 434 } 435 switch (config0 & 0x03) { 436 case 0x00: a_config.a_flash_width = 64; break; 437 case 0x01: a_config.a_flash_width = 32; break; 438 case 0x02: a_config.a_flash_width = 16; break; 439 case 0x03: a_config.a_flash_width = 0; break; 440 } 441 } 442