1 /* $NetBSD: ibm40x_machdep.c,v 1.2 2003/12/30 12:33:19 pk Exp $ */ 2 3 /* 4 * Copyright 2001, 2002 Wasabi Systems, Inc. 5 * All rights reserved. 6 * 7 * Written by Eduardo Horvath and Simon Burge for Wasabi Systems, Inc. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed for the NetBSD Project by 20 * Wasabi Systems, Inc. 21 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 22 * or promote products derived from this software without specific prior 23 * written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 * POSSIBILITY OF SUCH DAMAGE. 36 */ 37 38 /* 39 * Copyright (C) 1995, 1996 Wolfgang Solfrank. 40 * Copyright (C) 1995, 1996 TooLs GmbH. 41 * All rights reserved. 42 * 43 * Redistribution and use in source and binary forms, with or without 44 * modification, are permitted provided that the following conditions 45 * are met: 46 * 1. Redistributions of source code must retain the above copyright 47 * notice, this list of conditions and the following disclaimer. 48 * 2. Redistributions in binary form must reproduce the above copyright 49 * notice, this list of conditions and the following disclaimer in the 50 * documentation and/or other materials provided with the distribution. 51 * 3. All advertising materials mentioning features or use of this software 52 * must display the following acknowledgement: 53 * This product includes software developed by TooLs GmbH. 54 * 4. The name of TooLs GmbH may not be used to endorse or promote products 55 * derived from this software without specific prior written permission. 56 * 57 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 58 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 59 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 60 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 61 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 62 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 63 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 64 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 65 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 66 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 67 */ 68 69 #include <sys/cdefs.h> 70 __KERNEL_RCSID(0, "$NetBSD: ibm40x_machdep.c,v 1.2 2003/12/30 12:33:19 pk Exp $"); 71 72 #include "opt_compat_netbsd.h" 73 #include "opt_ddb.h" 74 #include "opt_kgdb.h" 75 #include "opt_ipkdb.h" 76 77 #include <sys/param.h> 78 #include <sys/buf.h> 79 #include <sys/exec.h> 80 #include <sys/malloc.h> 81 #include <sys/mbuf.h> 82 #include <sys/mount.h> 83 #include <sys/msgbuf.h> 84 #include <sys/proc.h> 85 #include <sys/reboot.h> 86 #include <sys/sa.h> 87 #include <sys/syscallargs.h> 88 #include <sys/syslog.h> 89 #include <sys/systm.h> 90 #include <sys/kernel.h> 91 #include <sys/user.h> 92 #include <sys/boot_flag.h> 93 #include <sys/properties.h> 94 #include <sys/ksyms.h> 95 96 #include <uvm/uvm_extern.h> 97 98 #include <net/netisr.h> 99 100 #if defined(DDB) 101 #include <machine/db_machdep.h> 102 #include <ddb/db_extern.h> 103 #endif 104 105 #if defined(KGDB) 106 #include <sys/kgdb.h> 107 #endif 108 109 #if defined(IPKDB) 110 #include <ipkdb/ipkdb.h> 111 #endif 112 113 #include <machine/bus.h> 114 #include <machine/trap.h> 115 #include <machine/powerpc.h> 116 #include <powerpc/spr.h> 117 #include <powerpc/ibm4xx/dcr405gp.h> 118 119 /* 120 * Global variables used here and there 121 */ 122 struct vm_map *exec_map = NULL; 123 struct vm_map *mb_map = NULL; 124 struct vm_map *phys_map = NULL; 125 126 char machine[] = MACHINE; /* from <machine/param.h> */ 127 char machine_arch[] = MACHINE_ARCH; /* from <machine/param.h> */ 128 129 #define MEMREGIONS 8 130 struct mem_region physmemr[MEMREGIONS]; /* Hard code memory */ 131 struct mem_region availmemr[MEMREGIONS];/* Who's supposed to set these up? */ 132 133 struct board_cfg_data board_data; 134 struct propdb *board_info = NULL; 135 136 extern struct user *proc0paddr; 137 138 paddr_t msgbuf_paddr; 139 vaddr_t msgbuf_vaddr; 140 141 142 void 143 ibm4xx_init_board_data(void *info_block, u_int startkernel) 144 { 145 /* Initialize cache info for memcpy, etc. */ 146 cpu_probe_cache(); 147 148 /* Save info block */ 149 memcpy(&board_data, info_block, sizeof(board_data)); 150 151 memset(physmemr, 0, sizeof physmemr); 152 memset(availmemr, 0, sizeof availmemr); 153 physmemr[0].start = 0; 154 physmemr[0].size = board_data.mem_size & ~PGOFSET; 155 /* Lower memory reserved by eval board BIOS */ 156 availmemr[0].start = startkernel; 157 availmemr[0].size = board_data.mem_size - availmemr[0].start; 158 } 159 160 void 161 ibm4xx_init(void (*handler)(void)) 162 { 163 extern int defaulttrap, defaultsize; 164 extern int sctrap, scsize; 165 extern int alitrap, alisize; 166 extern int dsitrap, dsisize; 167 extern int isitrap, isisize; 168 extern int mchktrap, mchksize; 169 extern int tlbimiss4xx, tlbim4size; 170 extern int tlbdmiss4xx, tlbdm4size; 171 extern int pitfitwdog, pitfitwdogsize; 172 extern int debugtrap, debugsize; 173 extern int errata51handler, errata51size; 174 #ifdef DDB 175 extern int ddblow, ddbsize; 176 #endif 177 #ifdef IPKDB 178 extern int ipkdblow, ipkdbsize; 179 #endif 180 uintptr_t exc; 181 struct cpu_info * const ci = curcpu(); 182 183 /* Initialize cache info for memcpy, etc. */ 184 cpu_probe_cache(); 185 186 /* 187 * Initialize lwp0 and current pcb and pmap pointers. 188 */ 189 KASSERT(ci != NULL); 190 KASSERT(curcpu() == ci); 191 lwp0.l_cpu = ci; 192 lwp0.l_addr = proc0paddr; 193 memset(lwp0.l_addr, 0, sizeof *lwp0.l_addr); 194 KASSERT(lwp0.l_cpu != NULL); 195 196 curpcb = &proc0paddr->u_pcb; 197 memset(curpcb, 0, sizeof(*curpcb)); 198 curpcb->pcb_pm = pmap_kernel(); 199 200 /* 201 * Set up trap vectors 202 */ 203 for (exc = EXC_RSVD; exc <= EXC_LAST; exc += 0x100) 204 switch (exc) { 205 default: 206 memcpy((void *)exc, &defaulttrap, (size_t)&defaultsize); 207 break; 208 case EXC_EXI: 209 /* 210 * This one is (potentially) installed during autoconf 211 */ 212 break; 213 case EXC_SC: 214 memcpy((void *)EXC_SC, &sctrap, (size_t)&scsize); 215 break; 216 case EXC_ALI: 217 memcpy((void *)EXC_ALI, &alitrap, (size_t)&alisize); 218 break; 219 case EXC_DSI: 220 memcpy((void *)EXC_DSI, &dsitrap, (size_t)&dsisize); 221 break; 222 case EXC_ISI: 223 memcpy((void *)EXC_ISI, &isitrap, (size_t)&isisize); 224 break; 225 case EXC_MCHK: 226 memcpy((void *)EXC_MCHK, &mchktrap, (size_t)&mchksize); 227 break; 228 case EXC_ITMISS: 229 memcpy((void *)EXC_ITMISS, &tlbimiss4xx, 230 (size_t)&tlbim4size); 231 break; 232 case EXC_DTMISS: 233 memcpy((void *)EXC_DTMISS, &tlbdmiss4xx, 234 (size_t)&tlbdm4size); 235 break; 236 /* 237 * EXC_PIT, EXC_FIT, EXC_WDOG handlers 238 * are spaced by 0x10 bytes only.. 239 */ 240 case EXC_PIT: 241 memcpy((void *)EXC_PIT, &pitfitwdog, 242 (size_t)&pitfitwdogsize); 243 break; 244 case EXC_DEBUG: 245 memcpy((void *)EXC_DEBUG, &debugtrap, 246 (size_t)&debugsize); 247 break; 248 case EXC_DTMISS|EXC_ALI: 249 /* PPC405GP Rev D errata item 51 */ 250 memcpy((void *)(EXC_DTMISS|EXC_ALI), &errata51handler, 251 (size_t)&errata51size); 252 break; 253 #if defined(DDB) || defined(IPKDB) 254 case EXC_PGM: 255 #if defined(DDB) 256 memcpy((void *)exc, &ddblow, (size_t)&ddbsize); 257 #elif defined(IPKDB) 258 memcpy((void *)exc, &ipkdblow, (size_t)&ipkdbsize); 259 #endif 260 #endif /* DDB | IPKDB */ 261 break; 262 } 263 264 __syncicache((void *)EXC_RST, EXC_LAST - EXC_RST + 0x100); 265 mtspr(SPR_EVPR, 0); /* Set Exception vector base */ 266 267 consinit(); 268 269 /* Handle trap instruction as PGM exception */ 270 { 271 int dbcr0; 272 asm volatile("mfspr %0,%1":"=r"(dbcr0):"K"(SPR_DBCR0)); 273 asm volatile("mtspr %0,%1"::"K"(SPR_DBCR0),"r"(dbcr0 & ~DBCR0_TDE)); 274 } 275 276 /* 277 * external interrupt handler install 278 */ 279 if (handler) 280 ibm4xx_install_extint(handler); 281 282 /* 283 * Now enable translation (and machine checks/recoverable interrupts). 284 */ 285 asm volatile ("mfmsr %0; ori %0,%0,%1; mtmsr %0; isync" 286 : : "r"(0), "K"(PSL_IR|PSL_DR)); 287 /* XXXX PSL_ME - With ME set kernel gets stuck... */ 288 289 KASSERT(curcpu() == ci); 290 } 291 292 void 293 ibm4xx_install_extint(void (*handler)(void)) 294 { 295 extern int extint, extsize; 296 extern u_long extint_call; 297 u_long offset = (u_long)handler - (u_long)&extint_call; 298 int msr; 299 300 #ifdef DIAGNOSTIC 301 if (offset > 0x1ffffff) 302 panic("install_extint: too far away"); 303 #endif 304 asm volatile ("mfmsr %0; wrteei 0" : "=r"(msr)); 305 extint_call = (extint_call & 0xfc000003) | offset; 306 memcpy((void *)EXC_EXI, &extint, (size_t)&extsize); 307 __syncicache((void *)&extint_call, sizeof extint_call); 308 __syncicache((void *)EXC_EXI, (int)&extsize); 309 asm volatile ("mtmsr %0" :: "r"(msr)); 310 } 311 312 /* 313 * Machine dependent startup code. 314 */ 315 316 char msgbuf[MSGBUFSIZE]; 317 318 void 319 ibm4xx_startup(const char *model) 320 { 321 vaddr_t minaddr, maxaddr; 322 char pbuf[9]; 323 324 KASSERT(curcpu() != NULL); 325 KASSERT(lwp0.l_cpu != NULL); 326 KASSERT(curcpu()->ci_intstk != 0); 327 KASSERT(curcpu()->ci_intrdepth == -1); 328 329 /* 330 * Initialize error message buffer (at end of core). 331 */ 332 #if 0 /* For some reason this fails... --Artem 333 * Besides, do we really have to put it at the end of core? 334 * Let's use static buffer for now 335 */ 336 if (!(msgbuf_vaddr = uvm_km_alloc(kernel_map, round_page(MSGBUFSIZE)))) 337 panic("startup: no room for message buffer"); 338 for (i = 0; i < btoc(MSGBUFSIZE); i++) 339 pmap_kenter_pa(msgbuf_vaddr + i * PAGE_SIZE, 340 msgbuf_paddr + i * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE); 341 initmsgbuf((caddr_t)msgbuf_vaddr, round_page(MSGBUFSIZE)); 342 #else 343 initmsgbuf((caddr_t)msgbuf, round_page(MSGBUFSIZE)); 344 #endif 345 346 printf("%s", version); 347 if (model != NULL) 348 printf("Model: %s\n", model); 349 350 format_bytes(pbuf, sizeof(pbuf), ctob(physmem)); 351 printf("total memory = %s\n", pbuf); 352 353 minaddr = 0; 354 /* 355 * Allocate a submap for exec arguments. This map effectively 356 * limits the number of processes exec'ing at any time. 357 */ 358 exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 359 16*NCARGS, VM_MAP_PAGEABLE, FALSE, NULL); 360 361 /* 362 * Allocate a submap for physio 363 */ 364 phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 365 VM_PHYS_SIZE, 0, FALSE, NULL); 366 367 /* 368 * No need to allocate an mbuf cluster submap. Mbuf clusters 369 * are allocated via the pool allocator, and we use direct-mapped 370 * pool pages. 371 */ 372 373 format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free)); 374 printf("avail memory = %s\n", pbuf); 375 } 376 377 void 378 ibm4xx_setup_propdb(void) 379 { 380 /* 381 * Set up the board properties database. 382 */ 383 if (!(board_info = propdb_create("board info"))) 384 panic("Cannot create board info database"); 385 386 if (board_info_set("mem-size", &board_data.mem_size, 387 sizeof(&board_data.mem_size), PROP_CONST, 0)) 388 panic("setting mem-size"); 389 if (board_info_set("sip0-mac-addr", &board_data.mac_address_pci, 390 sizeof(&board_data.mac_address_pci), PROP_CONST, 0)) 391 panic("setting sip0-mac-addr"); 392 if (board_info_set("processor-frequency", &board_data.processor_speed, 393 sizeof(&board_data.processor_speed), PROP_CONST, 0)) 394 panic("setting processor-frequency"); 395 } 396 397 398 /* 399 * Crash dump handling. 400 */ 401 void 402 ibm4xx_dumpsys(void) 403 { 404 printf("dumpsys: TBD\n"); 405 } 406 407 /* 408 * Soft networking interrupts. 409 */ 410 void 411 softnet(void) 412 { 413 int isr; 414 415 isr = netisr; 416 netisr = 0; 417 418 #define DONETISR(bit, fn) do { \ 419 if (isr & (1 << bit)) \ 420 fn(); \ 421 } while (0) 422 423 #include <net/netisr_dispatch.h> 424 425 #undef DONETISR 426 427 } 428 429 /* 430 * Soft tty interrupts. 431 */ 432 #include "com.h" 433 void 434 softserial(void) 435 { 436 #if NCOM > 0 437 void comsoft(void); /* XXX from dev/ic/com.c */ 438 439 comsoft(); 440 #endif 441 } 442 443 void 444 mem_regions(struct mem_region **mem, struct mem_region **avail) 445 { 446 *mem = physmemr; 447 *avail = availmemr; 448 } 449