1 /*- 2 * Copyright (C) 1995, 1996 Wolfgang Solfrank. 3 * Copyright (C) 1995, 1996 TooLs GmbH. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by TooLs GmbH. 17 * 4. The name of TooLs GmbH may not be used to endorse or promote products 18 * derived from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 /*- 32 * Copyright (C) 2001 Benno Rice 33 * All rights reserved. 34 * 35 * Redistribution and use in source and binary forms, with or without 36 * modification, are permitted provided that the following conditions 37 * are met: 38 * 1. Redistributions of source code must retain the above copyright 39 * notice, this list of conditions and the following disclaimer. 40 * 2. Redistributions in binary form must reproduce the above copyright 41 * notice, this list of conditions and the following disclaimer in the 42 * documentation and/or other materials provided with the distribution. 43 * 44 * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR 45 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 46 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 47 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 49 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 50 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 51 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 52 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 53 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 54 * $NetBSD: machdep.c,v 1.74.2.1 2000/11/01 16:13:48 tv Exp $ 55 */ 56 57 #include <sys/cdefs.h> 58 __FBSDID("$FreeBSD$"); 59 60 #include "opt_ddb.h" 61 #include "opt_kstack_pages.h" 62 #include "opt_platform.h" 63 64 #include <sys/endian.h> 65 #include <sys/param.h> 66 #include <sys/proc.h> 67 #include <sys/systm.h> 68 #include <sys/bio.h> 69 #include <sys/buf.h> 70 #include <sys/bus.h> 71 #include <sys/cons.h> 72 #include <sys/cpu.h> 73 #include <sys/eventhandler.h> 74 #include <sys/exec.h> 75 #include <sys/imgact.h> 76 #include <sys/kdb.h> 77 #include <sys/kernel.h> 78 #include <sys/ktr.h> 79 #include <sys/linker.h> 80 #include <sys/lock.h> 81 #include <sys/malloc.h> 82 #include <sys/mbuf.h> 83 #include <sys/msgbuf.h> 84 #include <sys/mutex.h> 85 #include <sys/ptrace.h> 86 #include <sys/reboot.h> 87 #include <sys/rwlock.h> 88 #include <sys/signalvar.h> 89 #include <sys/syscallsubr.h> 90 #include <sys/sysctl.h> 91 #include <sys/sysent.h> 92 #include <sys/sysproto.h> 93 #include <sys/ucontext.h> 94 #include <sys/uio.h> 95 #include <sys/vmmeter.h> 96 #include <sys/vnode.h> 97 98 #include <net/netisr.h> 99 100 #include <vm/vm.h> 101 #include <vm/vm_extern.h> 102 #include <vm/vm_kern.h> 103 #include <vm/vm_page.h> 104 #include <vm/vm_map.h> 105 #include <vm/vm_object.h> 106 #include <vm/vm_pager.h> 107 108 #include <machine/altivec.h> 109 #ifndef __powerpc64__ 110 #include <machine/bat.h> 111 #endif 112 #include <machine/cpu.h> 113 #include <machine/elf.h> 114 #include <machine/fpu.h> 115 #include <machine/hid.h> 116 #include <machine/kdb.h> 117 #include <machine/md_var.h> 118 #include <machine/metadata.h> 119 #include <machine/mmuvar.h> 120 #include <machine/pcb.h> 121 #include <machine/reg.h> 122 #include <machine/sigframe.h> 123 #include <machine/spr.h> 124 #include <machine/trap.h> 125 #include <machine/vmparam.h> 126 #include <machine/ofw_machdep.h> 127 128 #include <ddb/ddb.h> 129 130 #include <dev/ofw/openfirm.h> 131 132 #ifdef __powerpc64__ 133 #include "mmu_oea64.h" 134 #endif 135 136 #ifndef __powerpc64__ 137 struct bat battable[16]; 138 #endif 139 140 int radix_mmu = 0; 141 142 #ifndef __powerpc64__ 143 /* Bits for running on 64-bit systems in 32-bit mode. */ 144 extern void *testppc64, *testppc64size; 145 extern void *restorebridge, *restorebridgesize; 146 extern void *rfid_patch, *rfi_patch1, *rfi_patch2; 147 extern void *trapcode64; 148 149 extern Elf_Addr _GLOBAL_OFFSET_TABLE_[]; 150 #endif 151 152 extern void *rstcode, *rstcodeend; 153 extern void *trapcode, *trapcodeend; 154 extern void *hypertrapcode, *hypertrapcodeend; 155 extern void *generictrap, *generictrap64; 156 extern void *alitrap, *aliend; 157 extern void *dsitrap, *dsiend; 158 extern void *decrint, *decrsize; 159 extern void *extint, *extsize; 160 extern void *dblow, *dbend; 161 extern void *imisstrap, *imisssize; 162 extern void *dlmisstrap, *dlmisssize; 163 extern void *dsmisstrap, *dsmisssize; 164 165 extern void *ap_pcpu; 166 extern void __restartkernel(vm_offset_t, vm_offset_t, vm_offset_t, void *, uint32_t, register_t offset, register_t msr); 167 extern void __restartkernel_virtual(vm_offset_t, vm_offset_t, vm_offset_t, void *, uint32_t, register_t offset, register_t msr); 168 169 void aim_early_init(vm_offset_t fdt, vm_offset_t toc, vm_offset_t ofentry, 170 void *mdp, uint32_t mdp_cookie); 171 void aim_cpu_init(vm_offset_t toc); 172 173 void 174 aim_early_init(vm_offset_t fdt, vm_offset_t toc, vm_offset_t ofentry, void *mdp, 175 uint32_t mdp_cookie) 176 { 177 register_t scratch; 178 179 /* 180 * If running from an FDT, make sure we are in real mode to avoid 181 * tromping on firmware page tables. Everything in the kernel assumes 182 * 1:1 mappings out of firmware, so this won't break anything not 183 * already broken. This doesn't work if there is live OF, since OF 184 * may internally use non-1:1 mappings. 185 */ 186 if (ofentry == 0) 187 mtmsr(mfmsr() & ~(PSL_IR | PSL_DR)); 188 189 #ifdef __powerpc64__ 190 /* 191 * Relocate to high memory so that the kernel 192 * can execute from the direct map. 193 * 194 * If we are in virtual mode already, use a special entry point 195 * that sets up a temporary DMAP to execute from until we can 196 * properly set up the MMU. 197 */ 198 if ((vm_offset_t)&aim_early_init < DMAP_BASE_ADDRESS) { 199 if (mfmsr() & PSL_DR) { 200 __restartkernel_virtual(fdt, 0, ofentry, mdp, 201 mdp_cookie, DMAP_BASE_ADDRESS, mfmsr()); 202 } else { 203 __restartkernel(fdt, 0, ofentry, mdp, mdp_cookie, 204 DMAP_BASE_ADDRESS, mfmsr()); 205 } 206 } 207 #endif 208 209 /* Various very early CPU fix ups */ 210 switch (mfpvr() >> 16) { 211 /* 212 * PowerPC 970 CPUs have a misfeature requested by Apple that 213 * makes them pretend they have a 32-byte cacheline. Turn this 214 * off before we measure the cacheline size. 215 */ 216 case IBM970: 217 case IBM970FX: 218 case IBM970MP: 219 case IBM970GX: 220 scratch = mfspr(SPR_HID5); 221 scratch &= ~HID5_970_DCBZ_SIZE_HI; 222 mtspr(SPR_HID5, scratch); 223 break; 224 #ifdef __powerpc64__ 225 case IBMPOWER7: 226 case IBMPOWER7PLUS: 227 case IBMPOWER8: 228 case IBMPOWER8E: 229 case IBMPOWER8NVL: 230 case IBMPOWER9: 231 /* XXX: get from ibm,slb-size in device tree */ 232 n_slbs = 32; 233 break; 234 #endif 235 } 236 } 237 238 void 239 aim_cpu_init(vm_offset_t toc) 240 { 241 size_t trap_offset, trapsize; 242 vm_offset_t trap; 243 register_t msr; 244 uint8_t *cache_check; 245 int cacheline_warn; 246 #ifndef __powerpc64__ 247 register_t scratch; 248 int ppc64; 249 #endif 250 251 trap_offset = 0; 252 cacheline_warn = 0; 253 254 /* General setup for AIM CPUs */ 255 psl_kernset = PSL_EE | PSL_ME | PSL_IR | PSL_DR | PSL_RI; 256 257 #ifdef __powerpc64__ 258 psl_kernset |= PSL_SF; 259 if (mfmsr() & PSL_HV) 260 psl_kernset |= PSL_HV; 261 262 #if BYTE_ORDER == LITTLE_ENDIAN 263 psl_kernset |= PSL_LE; 264 #endif 265 266 #endif 267 psl_userset = psl_kernset | PSL_PR; 268 #ifdef __powerpc64__ 269 psl_userset32 = psl_userset & ~PSL_SF; 270 #endif 271 272 /* 273 * Zeroed bits in this variable signify that the value of the bit 274 * in its position is allowed to vary between userspace contexts. 275 * 276 * All other bits are required to be identical for every userspace 277 * context. The actual *value* of the bit is determined by 278 * psl_userset and/or psl_userset32, and is not allowed to change. 279 * 280 * Remember to update this set when implementing support for 281 * *conditionally* enabling a processor facility. Failing to do 282 * this will cause swapcontext() in userspace to break when a 283 * process uses a conditionally-enabled facility. 284 * 285 * When *unconditionally* implementing support for a processor 286 * facility, update psl_userset / psl_userset32 instead. 287 * 288 * See the access control check in set_mcontext(). 289 */ 290 psl_userstatic = ~(PSL_VSX | PSL_VEC | PSL_FP | PSL_FE0 | PSL_FE1); 291 /* 292 * Mask bits from the SRR1 that aren't really the MSR: 293 * Bits 1-4, 10-15 (ppc32), 33-36, 42-47 (ppc64) 294 */ 295 psl_userstatic &= ~0x783f0000UL; 296 297 /* 298 * Initialize the interrupt tables and figure out our cache line 299 * size and whether or not we need the 64-bit bridge code. 300 */ 301 302 /* 303 * Disable translation in case the vector area hasn't been 304 * mapped (G5). Note that no OFW calls can be made until 305 * translation is re-enabled. 306 */ 307 308 msr = mfmsr(); 309 mtmsr((msr & ~(PSL_IR | PSL_DR)) | PSL_RI); 310 311 /* 312 * Measure the cacheline size using dcbz 313 * 314 * Use EXC_PGM as a playground. We are about to overwrite it 315 * anyway, we know it exists, and we know it is cache-aligned. 316 */ 317 318 cache_check = (void *)EXC_PGM; 319 320 for (cacheline_size = 0; cacheline_size < 0x100; cacheline_size++) 321 cache_check[cacheline_size] = 0xff; 322 323 __asm __volatile("dcbz 0,%0":: "r" (cache_check) : "memory"); 324 325 /* Find the first byte dcbz did not zero to get the cache line size */ 326 for (cacheline_size = 0; cacheline_size < 0x100 && 327 cache_check[cacheline_size] == 0; cacheline_size++); 328 329 /* Work around psim bug */ 330 if (cacheline_size == 0) { 331 cacheline_warn = 1; 332 cacheline_size = 32; 333 } 334 335 #ifndef __powerpc64__ 336 /* 337 * Figure out whether we need to use the 64 bit PMAP. This works by 338 * executing an instruction that is only legal on 64-bit PPC (mtmsrd), 339 * and setting ppc64 = 0 if that causes a trap. 340 */ 341 342 ppc64 = 1; 343 344 bcopy(&testppc64, (void *)EXC_PGM, (size_t)&testppc64size); 345 __syncicache((void *)EXC_PGM, (size_t)&testppc64size); 346 347 __asm __volatile("\ 348 mfmsr %0; \ 349 mtsprg2 %1; \ 350 \ 351 mtmsrd %0; \ 352 mfsprg2 %1;" 353 : "=r"(scratch), "=r"(ppc64)); 354 355 if (ppc64) 356 cpu_features |= PPC_FEATURE_64; 357 358 /* 359 * Now copy restorebridge into all the handlers, if necessary, 360 * and set up the trap tables. 361 */ 362 363 if (cpu_features & PPC_FEATURE_64) { 364 /* Patch the two instances of rfi -> rfid */ 365 bcopy(&rfid_patch,&rfi_patch1,4); 366 #ifdef KDB 367 /* rfi_patch2 is at the end of dbleave */ 368 bcopy(&rfid_patch,&rfi_patch2,4); 369 #endif 370 } 371 #else /* powerpc64 */ 372 cpu_features |= PPC_FEATURE_64; 373 #endif 374 375 trapsize = (size_t)&trapcodeend - (size_t)&trapcode; 376 377 /* 378 * Copy generic handler into every possible trap. Special cases will get 379 * different ones in a minute. 380 */ 381 for (trap = EXC_RST; trap < EXC_LAST; trap += 0x20) 382 bcopy(&trapcode, (void *)trap, trapsize); 383 384 #ifndef __powerpc64__ 385 if (cpu_features & PPC_FEATURE_64) { 386 /* 387 * Copy a code snippet to restore 32-bit bridge mode 388 * to the top of every non-generic trap handler 389 */ 390 391 trap_offset += (size_t)&restorebridgesize; 392 bcopy(&restorebridge, (void *)EXC_RST, trap_offset); 393 bcopy(&restorebridge, (void *)EXC_DSI, trap_offset); 394 bcopy(&restorebridge, (void *)EXC_ALI, trap_offset); 395 bcopy(&restorebridge, (void *)EXC_PGM, trap_offset); 396 bcopy(&restorebridge, (void *)EXC_MCHK, trap_offset); 397 bcopy(&restorebridge, (void *)EXC_TRC, trap_offset); 398 bcopy(&restorebridge, (void *)EXC_BPT, trap_offset); 399 } else { 400 /* 401 * Use an IBAT and a DBAT to map the bottom 256M segment. 402 * 403 * It is very important to do it *now* to avoid taking a 404 * fault in .text / .data before the MMU is bootstrapped, 405 * because until then, the translation data has not been 406 * copied over from OpenFirmware, so our DSI/ISI will fail 407 * to find a match. 408 */ 409 410 battable[0x0].batl = BATL(0x00000000, BAT_M, BAT_PP_RW); 411 battable[0x0].batu = BATU(0x00000000, BAT_BL_256M, BAT_Vs); 412 413 __asm (".balign 32; \n" 414 "mtibatu 0,%0; mtibatl 0,%1; isync; \n" 415 "mtdbatu 0,%0; mtdbatl 0,%1; isync" 416 :: "r"(battable[0].batu), "r"(battable[0].batl)); 417 } 418 #else 419 trapsize = (size_t)&hypertrapcodeend - (size_t)&hypertrapcode; 420 bcopy(&hypertrapcode, (void *)(EXC_HEA + trap_offset), trapsize); 421 bcopy(&hypertrapcode, (void *)(EXC_HMI + trap_offset), trapsize); 422 bcopy(&hypertrapcode, (void *)(EXC_HVI + trap_offset), trapsize); 423 bcopy(&hypertrapcode, (void *)(EXC_SOFT_PATCH + trap_offset), trapsize); 424 #endif 425 426 bcopy(&rstcode, (void *)(EXC_RST + trap_offset), (size_t)&rstcodeend - 427 (size_t)&rstcode); 428 429 #ifdef KDB 430 bcopy(&dblow, (void *)(EXC_MCHK + trap_offset), (size_t)&dbend - 431 (size_t)&dblow); 432 bcopy(&dblow, (void *)(EXC_PGM + trap_offset), (size_t)&dbend - 433 (size_t)&dblow); 434 bcopy(&dblow, (void *)(EXC_TRC + trap_offset), (size_t)&dbend - 435 (size_t)&dblow); 436 bcopy(&dblow, (void *)(EXC_BPT + trap_offset), (size_t)&dbend - 437 (size_t)&dblow); 438 #endif 439 bcopy(&alitrap, (void *)(EXC_ALI + trap_offset), (size_t)&aliend - 440 (size_t)&alitrap); 441 bcopy(&dsitrap, (void *)(EXC_DSI + trap_offset), (size_t)&dsiend - 442 (size_t)&dsitrap); 443 444 /* Set address of generictrap for self-reloc calculations */ 445 *((void **)TRAP_GENTRAP) = &generictrap; 446 #ifdef __powerpc64__ 447 /* Set TOC base so that the interrupt code can get at it */ 448 *((void **)TRAP_ENTRY) = &generictrap; 449 *((register_t *)TRAP_TOCBASE) = toc; 450 #else 451 /* Set branch address for trap code */ 452 if (cpu_features & PPC_FEATURE_64) 453 *((void **)TRAP_ENTRY) = &generictrap64; 454 else 455 *((void **)TRAP_ENTRY) = &generictrap; 456 *((void **)TRAP_TOCBASE) = _GLOBAL_OFFSET_TABLE_; 457 458 /* G2-specific TLB miss helper handlers */ 459 bcopy(&imisstrap, (void *)EXC_IMISS, (size_t)&imisssize); 460 bcopy(&dlmisstrap, (void *)EXC_DLMISS, (size_t)&dlmisssize); 461 bcopy(&dsmisstrap, (void *)EXC_DSMISS, (size_t)&dsmisssize); 462 #endif 463 __syncicache(EXC_RSVD, EXC_LAST - EXC_RSVD); 464 465 /* 466 * Restore MSR 467 */ 468 mtmsr(msr); 469 470 /* Warn if cachline size was not determined */ 471 if (cacheline_warn == 1) { 472 printf("WARNING: cacheline size undetermined, setting to 32\n"); 473 } 474 475 /* 476 * Initialise virtual memory. Use BUS_PROBE_GENERIC priority 477 * in case the platform module had a better idea of what we 478 * should do. 479 */ 480 if (cpu_features2 & PPC_FEATURE2_ARCH_3_00) { 481 radix_mmu = 0; 482 TUNABLE_INT_FETCH("radix_mmu", &radix_mmu); 483 if (radix_mmu) 484 pmap_mmu_install(MMU_TYPE_RADIX, BUS_PROBE_GENERIC); 485 else 486 pmap_mmu_install(MMU_TYPE_G5, BUS_PROBE_GENERIC); 487 } else if (cpu_features & PPC_FEATURE_64) 488 pmap_mmu_install(MMU_TYPE_G5, BUS_PROBE_GENERIC); 489 else 490 pmap_mmu_install(MMU_TYPE_OEA, BUS_PROBE_GENERIC); 491 } 492 493 /* 494 * Shutdown the CPU as much as possible. 495 */ 496 void 497 cpu_halt(void) 498 { 499 500 OF_exit(); 501 } 502 503 int 504 ptrace_single_step(struct thread *td) 505 { 506 struct trapframe *tf; 507 508 tf = td->td_frame; 509 tf->srr1 |= PSL_SE; 510 511 return (0); 512 } 513 514 int 515 ptrace_clear_single_step(struct thread *td) 516 { 517 struct trapframe *tf; 518 519 tf = td->td_frame; 520 tf->srr1 &= ~PSL_SE; 521 522 return (0); 523 } 524 525 void 526 kdb_cpu_clear_singlestep(void) 527 { 528 529 kdb_frame->srr1 &= ~PSL_SE; 530 } 531 532 void 533 kdb_cpu_set_singlestep(void) 534 { 535 536 kdb_frame->srr1 |= PSL_SE; 537 } 538 539 /* 540 * Initialise a struct pcpu. 541 */ 542 void 543 cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t sz) 544 { 545 #ifdef __powerpc64__ 546 /* Copy the SLB contents from the current CPU */ 547 memcpy(pcpu->pc_aim.slb, PCPU_GET(aim.slb), sizeof(pcpu->pc_aim.slb)); 548 #endif 549 } 550 551 /* Return 0 on handled success, otherwise signal number. */ 552 int 553 cpu_machine_check(struct thread *td, struct trapframe *frame, int *ucode) 554 { 555 #ifdef __powerpc64__ 556 /* 557 * This block is 64-bit CPU specific currently. Punt running in 32-bit 558 * mode on 64-bit CPUs. 559 */ 560 /* Check if the important information is in DSISR */ 561 if ((frame->srr1 & SRR1_MCHK_DATA) != 0) { 562 printf("Machine check, DSISR: %016lx\n", frame->cpu.aim.dsisr); 563 /* SLB multi-hit is recoverable. */ 564 if ((frame->cpu.aim.dsisr & DSISR_MC_SLB_MULTIHIT) != 0) 565 return (0); 566 if ((frame->cpu.aim.dsisr & 567 (DSISR_MC_DERAT_MULTIHIT | DSISR_MC_TLB_MULTIHIT)) != 0) { 568 pmap_tlbie_all(); 569 return (0); 570 } 571 /* TODO: Add other machine check recovery procedures. */ 572 } else { 573 if ((frame->srr1 & SRR1_MCHK_IFETCH_M) == SRR1_MCHK_IFETCH_SLBMH) 574 return (0); 575 } 576 #endif 577 *ucode = BUS_OBJERR; 578 return (SIGBUS); 579 } 580 581 #ifndef __powerpc64__ 582 uint64_t 583 va_to_vsid(pmap_t pm, vm_offset_t va) 584 { 585 return ((pm->pm_sr[(uintptr_t)va >> ADDR_SR_SHFT]) & SR_VSID_MASK); 586 } 587 588 #endif 589 590 /* 591 * These functions need to provide addresses that both (a) work in real mode 592 * (or whatever mode/circumstances the kernel is in in early boot (now)) and 593 * (b) can still, in principle, work once the kernel is going. Because these 594 * rely on existing mappings/real mode, unmap is a no-op. 595 */ 596 vm_offset_t 597 pmap_early_io_map(vm_paddr_t pa, vm_size_t size) 598 { 599 KASSERT(!pmap_bootstrapped, ("Not available after PMAP started!")); 600 601 /* 602 * If we have the MMU up in early boot, assume it is 1:1. Otherwise, 603 * try to get the address in a memory region compatible with the 604 * direct map for efficiency later. 605 */ 606 if (mfmsr() & PSL_DR) 607 return (pa); 608 else 609 return (DMAP_BASE_ADDRESS + pa); 610 } 611 612 void 613 pmap_early_io_unmap(vm_offset_t va, vm_size_t size) 614 { 615 616 KASSERT(!pmap_bootstrapped, ("Not available after PMAP started!")); 617 } 618 619 /* From p3-53 of the MPC7450 RISC Microprocessor Family Reference Manual */ 620 void 621 flush_disable_caches(void) 622 { 623 register_t msr; 624 register_t msscr0; 625 register_t cache_reg; 626 volatile uint32_t *memp; 627 uint32_t temp; 628 int i; 629 int x; 630 631 msr = mfmsr(); 632 powerpc_sync(); 633 mtmsr(msr & ~(PSL_EE | PSL_DR)); 634 msscr0 = mfspr(SPR_MSSCR0); 635 msscr0 &= ~MSSCR0_L2PFE; 636 mtspr(SPR_MSSCR0, msscr0); 637 powerpc_sync(); 638 isync(); 639 /* 7e00066c: dssall */ 640 __asm__ __volatile__(".long 0x7e00066c; sync"); 641 powerpc_sync(); 642 isync(); 643 __asm__ __volatile__("dcbf 0,%0" :: "r"(0)); 644 __asm__ __volatile__("dcbf 0,%0" :: "r"(0)); 645 __asm__ __volatile__("dcbf 0,%0" :: "r"(0)); 646 647 /* Lock the L1 Data cache. */ 648 mtspr(SPR_LDSTCR, mfspr(SPR_LDSTCR) | 0xFF); 649 powerpc_sync(); 650 isync(); 651 652 mtspr(SPR_LDSTCR, 0); 653 654 /* 655 * Perform this in two stages: Flush the cache starting in RAM, then do it 656 * from ROM. 657 */ 658 memp = (volatile uint32_t *)0x00000000; 659 for (i = 0; i < 128 * 1024; i++) { 660 temp = *memp; 661 __asm__ __volatile__("dcbf 0,%0" :: "r"(memp)); 662 memp += 32/sizeof(*memp); 663 } 664 665 memp = (volatile uint32_t *)0xfff00000; 666 x = 0xfe; 667 668 for (; x != 0xff;) { 669 mtspr(SPR_LDSTCR, x); 670 for (i = 0; i < 128; i++) { 671 temp = *memp; 672 __asm__ __volatile__("dcbf 0,%0" :: "r"(memp)); 673 memp += 32/sizeof(*memp); 674 } 675 x = ((x << 1) | 1) & 0xff; 676 } 677 mtspr(SPR_LDSTCR, 0); 678 679 cache_reg = mfspr(SPR_L2CR); 680 if (cache_reg & L2CR_L2E) { 681 cache_reg &= ~(L2CR_L2IO_7450 | L2CR_L2DO_7450); 682 mtspr(SPR_L2CR, cache_reg); 683 powerpc_sync(); 684 mtspr(SPR_L2CR, cache_reg | L2CR_L2HWF); 685 while (mfspr(SPR_L2CR) & L2CR_L2HWF) 686 ; /* Busy wait for cache to flush */ 687 powerpc_sync(); 688 cache_reg &= ~L2CR_L2E; 689 mtspr(SPR_L2CR, cache_reg); 690 powerpc_sync(); 691 mtspr(SPR_L2CR, cache_reg | L2CR_L2I); 692 powerpc_sync(); 693 while (mfspr(SPR_L2CR) & L2CR_L2I) 694 ; /* Busy wait for L2 cache invalidate */ 695 powerpc_sync(); 696 } 697 698 cache_reg = mfspr(SPR_L3CR); 699 if (cache_reg & L3CR_L3E) { 700 cache_reg &= ~(L3CR_L3IO | L3CR_L3DO); 701 mtspr(SPR_L3CR, cache_reg); 702 powerpc_sync(); 703 mtspr(SPR_L3CR, cache_reg | L3CR_L3HWF); 704 while (mfspr(SPR_L3CR) & L3CR_L3HWF) 705 ; /* Busy wait for cache to flush */ 706 powerpc_sync(); 707 cache_reg &= ~L3CR_L3E; 708 mtspr(SPR_L3CR, cache_reg); 709 powerpc_sync(); 710 mtspr(SPR_L3CR, cache_reg | L3CR_L3I); 711 powerpc_sync(); 712 while (mfspr(SPR_L3CR) & L3CR_L3I) 713 ; /* Busy wait for L3 cache invalidate */ 714 powerpc_sync(); 715 } 716 717 mtspr(SPR_HID0, mfspr(SPR_HID0) & ~HID0_DCE); 718 powerpc_sync(); 719 isync(); 720 721 mtmsr(msr); 722 } 723 724 #ifndef __powerpc64__ 725 void 726 mpc745x_sleep() 727 { 728 static u_quad_t timebase = 0; 729 static register_t sprgs[4]; 730 static register_t srrs[2]; 731 732 jmp_buf resetjb; 733 struct thread *fputd; 734 struct thread *vectd; 735 register_t hid0; 736 register_t msr; 737 register_t saved_msr; 738 739 ap_pcpu = pcpup; 740 741 PCPU_SET(restore, &resetjb); 742 743 saved_msr = mfmsr(); 744 fputd = PCPU_GET(fputhread); 745 vectd = PCPU_GET(vecthread); 746 if (fputd != NULL) 747 save_fpu(fputd); 748 if (vectd != NULL) 749 save_vec(vectd); 750 if (setjmp(resetjb) == 0) { 751 sprgs[0] = mfspr(SPR_SPRG0); 752 sprgs[1] = mfspr(SPR_SPRG1); 753 sprgs[2] = mfspr(SPR_SPRG2); 754 sprgs[3] = mfspr(SPR_SPRG3); 755 srrs[0] = mfspr(SPR_SRR0); 756 srrs[1] = mfspr(SPR_SRR1); 757 timebase = mftb(); 758 powerpc_sync(); 759 flush_disable_caches(); 760 hid0 = mfspr(SPR_HID0); 761 hid0 = (hid0 & ~(HID0_DOZE | HID0_NAP)) | HID0_SLEEP; 762 powerpc_sync(); 763 isync(); 764 msr = mfmsr() | PSL_POW; 765 mtspr(SPR_HID0, hid0); 766 powerpc_sync(); 767 768 while (1) 769 mtmsr(msr); 770 } 771 /* XXX: The mttb() means this *only* works on single-CPU systems. */ 772 mttb(timebase); 773 PCPU_SET(curthread, curthread); 774 PCPU_SET(curpcb, curthread->td_pcb); 775 pmap_activate(curthread); 776 powerpc_sync(); 777 mtspr(SPR_SPRG0, sprgs[0]); 778 mtspr(SPR_SPRG1, sprgs[1]); 779 mtspr(SPR_SPRG2, sprgs[2]); 780 mtspr(SPR_SPRG3, sprgs[3]); 781 mtspr(SPR_SRR0, srrs[0]); 782 mtspr(SPR_SRR1, srrs[1]); 783 mtmsr(saved_msr); 784 if (fputd == curthread) 785 enable_fpu(curthread); 786 if (vectd == curthread) 787 enable_vec(curthread); 788 powerpc_sync(); 789 } 790 #endif 791