machdep.c revision 1.3
1/* $NetBSD: machdep.c,v 1.3 2008/04/28 20:23:17 martin 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.3 2008/04/28 20:23:17 martin 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/user.h> 94#include <sys/ksyms.h> 95 96#include <uvm/uvm.h> 97#include <uvm/uvm_extern.h> 98 99#include <net/netisr.h> 100 101#include <machine/bus.h> 102#include <machine/db_machdep.h> 103#include <machine/intr.h> 104#include <machine/pio.h> 105#include <machine/pmap.h> 106#include <machine/powerpc.h> 107#include <machine/trap.h> 108#include <machine/pmppc.h> 109 110#include <powerpc/oea/bat.h> 111#include <arch/powerpc/pic/picvar.h> 112 113#include <ddb/db_extern.h> 114 115#include <dev/cons.h> 116 117#include <dev/ic/cpc700reg.h> 118#include <dev/ic/cpc700uic.h> 119 120#include "com.h" 121#if (NCOM > 0) 122#include <sys/termios.h> 123#include <dev/ic/comreg.h> 124#include <dev/ic/comvar.h> 125#endif 126 127#include "ksyms.h" 128 129struct powerpc_bus_space pmppc_mem_tag = { 130 _BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_MEM_TYPE, 131 0, 0, 0xffffffff, 132 NULL, 133}; 134struct powerpc_bus_space pmppc_pci_io_tag = { 135 _BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_MEM_TYPE, 136 0, CPC_PCI_IO_BASE, 0xffffffff, 137 NULL, 138}; 139 140static char ex_storage[1][EXTENT_FIXED_STORAGE_SIZE(8)] 141 __attribute__((aligned(8))); 142 143 144#ifdef KGDB 145char kgdb_devname[] = KGDB_DEVNAME; 146int comkgdbaddr = KGDB_DEVADDR; 147int comkgdbrate = KGDB_DEVRATE; 148 149#ifndef KGDB_DEVMODE 150#define KGDB_DEVMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */ 151#endif 152int comkgdbmode = KGDB_DEVMODE; 153 154void kgdb_port_init(void); 155#endif /* KGDB */ 156 157/* 158 * Global variables used here and there 159 */ 160struct mem_region physmemr[2], availmemr[2]; 161 162struct a_config a_config; 163 164void initppc(u_int, u_int, u_int, void *); /* Called from locore */ 165void pmppc_setup(void); 166void setleds(int leds); 167 168/* 169 * Force cpu_info to be in the data segment to avoid the 170 * memset() blowing away the data set up by locore.S. 171 */ 172#if 0 173 /* this is defined in powerpc/oea/cpu_subr.c, I don't understand the above 174 * comment however. 175 */ 176struct cpu_info cpu_info[1] = { { .ci_curlwp = &lwp0, }, }; 177#endif 178 179void 180initppc(u_int startkernel, u_int endkernel, u_int args, void *btinfo) 181{ 182 extern void consinit(void); 183 extern u_long ticks_per_sec; 184 extern unsigned char edata[], end[]; 185 186 memset(&edata, 0, end - edata); /* clear BSS */ 187 188 pmppc_setup(); 189 190 physmemr[0].start = 0; 191 physmemr[0].size = a_config.a_mem_size; 192 physmemr[1].size = 0; 193 availmemr[0].start = (endkernel + PGOFSET) & ~PGOFSET; 194 availmemr[0].size = a_config.a_mem_size - availmemr[0].start; 195 availmemr[1].size = 0; 196 197#ifdef BOOTHOWTO 198 /* 199 * boothowto 200 */ 201 boothowto = BOOTHOWTO; 202#endif 203 204 if (bus_space_init(&pmppc_mem_tag, "iomem", 205 ex_storage[0], sizeof(ex_storage[0]))) 206 panic("bus_space_init failed"); 207 208 /* 209 * Get CPU clock 210 */ 211 ticks_per_sec = a_config.a_bus_freq; 212 ticks_per_sec /= 4; /* 4 cycles per DEC tick */ 213 cpu_timebase = ticks_per_sec; 214 cpu_initclocks(); 215 216 /* 217 * Initialize the BAT registers 218 */ 219 oea_batinit( 220 PMPPC_FLASH_BASE, BAT_BL_256M, /* flash (etc) memory 256M area */ 221 CPC_PCI_MEM_BASE, BAT_BL_256M, /* PCI memory 256M area */ 222 CPC_PCI_IO_BASE, BAT_BL_128M, /* PCI I/O 128M area */ 223 0); 224 225 /* 226 * Set up trap vectors 227 */ 228 oea_init(NULL); 229 230 /* 231 * Set up console. 232 */ 233 consinit(); /* XXX should not be here */ 234 235 printf("console set up\n"); 236 237 /* 238 * Set the page size. 239 */ 240 uvm_setpagesize(); 241 242 /* 243 * Initialize pmap module. 244 */ 245 pmap_bootstrap(startkernel, endkernel); 246 247#if NKSYMS || defined(DDB) || defined(LKM) 248#ifdef SYMTAB_SPACE 249 ksyms_init(0, NULL, NULL); 250#else 251 #error "No SYMTAB_SPACE" 252#endif 253#endif 254#ifdef IPKDB 255 /* 256 * Now trap to IPKDB 257 */ 258 ipkdb_init(); 259 if (boothowto & RB_KDB) 260 ipkdb_connect(0); 261#endif 262#ifdef KGDB 263 kgdb_port_init(); 264 if (boothowto & RB_KDB) { 265 kgdb_debug_init = 1; 266 kgdb_connect(1); 267 } 268#endif 269} 270 271void 272mem_regions(struct mem_region **mem, struct mem_region **avail) 273{ 274 *mem = physmemr; 275 *avail = availmemr; 276} 277 278/* 279 * Machine dependent startup code. 280 */ 281void 282cpu_startup() 283{ 284 285 oea_startup(NULL); 286 287 /* 288 * Now that we have VM, malloc()s are OK in bus_space. 289 */ 290 bus_space_mallocok(); 291 292 /* Set up the PCI bus tag. */ 293 if (bus_space_init(&pmppc_pci_io_tag, "pcimem", NULL, 0)) 294 panic("bus_space_init pci failed"); 295 296 /* Set up interrupt controller */ 297 cpc700_init_intr(&pmppc_mem_tag, CPC_UIC_BASE, 298 CPC_INTR_MASK(PMPPC_I_ETH_INT), 0); 299 300 pic_init(); 301 (void)setup_cpc700(); 302 oea_install_extint(pic_ext_intr); 303 304#if 0 305/* XXX doesn't seem to be needed anymore */ 306 /* 307 * Now allow hardware interrupts. 308 */ 309 __asm volatile ("mfmsr %0; ori %0,%0,%1; mtmsr %0" 310 : "=r"(msr) : "K"(PSL_EE)); 311#endif 312} 313 314/* 315 * consinit 316 * Initialize system console. 317 */ 318void 319consinit(void) 320{ 321 static int initted; 322#if (NCOM > 0) 323 bus_space_tag_t tag; 324#endif 325 326 if (initted) 327 return; 328 initted = 1; 329 330#if (NCOM > 0) 331 tag = &pmppc_mem_tag; 332 333 if(comcnattach(tag, CPC_COM0, 9600, CPC_COM_SPEED(a_config.a_bus_freq), 334 COM_TYPE_NORMAL, 335 ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8))) 336 panic("can't init serial console"); 337 else 338 return; 339#endif 340 341 panic("console device missing -- serial console not in kernel"); 342 /* Of course, this is moot if there is no console... */ 343} 344 345#ifdef KGDB 346void 347kgdb_port_init(void) 348{ 349#if (NCOM > 0) 350 if(!strcmp(kgdb_devname, "com")) { 351 bus_space_tag_t tag = &pmppc_mem_tag; 352 com_kgdb_attach(tag, comkgdbaddr, comkgdbrate, 353 CPC_COM_SPEED(a_config.a_bus_freq), 354 COM_TYPE_NORMAL, comkgdbmode); 355 } 356#endif 357} 358#endif 359 360/* 361 * Halt or reboot the machine after syncing/dumping according to howto. 362 */ 363void 364cpu_reboot(int howto, char *what) 365{ 366 static int syncing; 367 static char str[256]; 368 char *ap = str, *ap1 = ap; 369 extern void disable_intr(void); 370 371 boothowto = howto; 372 if (!cold && !(howto & RB_NOSYNC) && !syncing) { 373 syncing = 1; 374 vfs_shutdown(); /* sync */ 375 resettodr(); /* set wall clock */ 376 } 377 splhigh(); 378 if (howto & RB_HALT) { 379 doshutdownhooks(); 380 printf("halted\n\n"); 381 while(1); 382 } 383 if (!cold && (howto & RB_DUMP)) 384 oea_dumpsys(); 385 doshutdownhooks(); 386 printf("rebooting\n\n"); 387 if (what && *what) { 388 if (strlen(what) > sizeof str - 5) 389 printf("boot string too large, ignored\n"); 390 else { 391 strcpy(str, what); 392 ap1 = ap = str + strlen(str); 393 *ap++ = ' '; 394 } 395 } 396 *ap++ = '-'; 397 if (howto & RB_SINGLE) 398 *ap++ = 's'; 399 if (howto & RB_KDB) 400 *ap++ = 'd'; 401 *ap++ = 0; 402 if (ap[-2] == '-') 403 *ap1 = 0; 404 405 disable_intr(); 406 407 /* Write the two byte reset sequence to the reset register. */ 408 out8(PMPPC_RESET, PMPPC_RESET_SEQ_STEP1); 409 out8(PMPPC_RESET, PMPPC_RESET_SEQ_STEP2); 410 411 while (1); 412} 413 414void 415setleds(int leds) 416{ 417 out8(PMPPC_LEDS, leds); 418} 419 420void 421pmppc_setup(void) 422{ 423 uint config0, config1; 424 425 config0 = in8(PMPPC_CONFIG0); 426 config1 = in8(PMPPC_CONFIG1); 427 428 /* from page 2-8 in the Artesyn User's manual */ 429 a_config.a_boot_device = config1 & 0x80 ? A_BOOT_FLASH : A_BOOT_ROM; 430 a_config.a_has_ecc = (config1 & 0x40) != 0; 431 switch (config1 & 0x30) { 432 case 0x00: a_config.a_mem_size = 32 * 1024 * 1024; break; 433 case 0x10: a_config.a_mem_size = 64 * 1024 * 1024; break; 434 case 0x20: a_config.a_mem_size = 128 * 1024 * 1024; break; 435 case 0x30: a_config.a_mem_size = 256 * 1024 * 1024; break; 436 } 437 a_config.a_l2_cache = (config1 >> 2) & 3; 438 switch (config1 & 0x03) { 439 case 0x00: a_config.a_bus_freq = 66666666; break; 440 case 0x01: a_config.a_bus_freq = 83333333; break; 441 case 0x02: a_config.a_bus_freq = 100000000; break; 442 case 0x03: a_config.a_bus_freq = 0; break; /* XXX */ 443 } 444 a_config.a_is_monarch = (config0 & 0x80) == 0; 445 a_config.a_has_eth = (config0 & 0x20) != 0; 446 a_config.a_has_rtc = (config0 & 0x10) == 0; 447 switch (config0 & 0x0c) { 448 case 0x00: a_config.a_flash_size = 256 * 1024 * 1024; break; 449 case 0x04: a_config.a_flash_size = 128 * 1024 * 1024; break; 450 case 0x08: a_config.a_flash_size = 64 * 1024 * 1024; break; 451 case 0x0c: a_config.a_flash_size = 32 * 1024 * 1024; break; 452 } 453 switch (config0 & 0x03) { 454 case 0x00: a_config.a_flash_width = 64; break; 455 case 0x01: a_config.a_flash_width = 32; break; 456 case 0x02: a_config.a_flash_width = 16; break; 457 case 0x03: a_config.a_flash_width = 0; break; 458 } 459} 460