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 & DSISR_MC_DERAT_MULTIHIT) != 0) { 567 pmap_tlbie_all(); 568 return (0); 569 } 570 /* TODO: Add other machine check recovery procedures. */ 571 } else { 572 if ((frame->srr1 & SRR1_MCHK_IFETCH_M) == SRR1_MCHK_IFETCH_SLBMH) 573 return (0); 574 } 575 #endif 576 *ucode = BUS_OBJERR; 577 return (SIGBUS); 578 } 579 580 #ifndef __powerpc64__ 581 uint64_t 582 va_to_vsid(pmap_t pm, vm_offset_t va) 583 { 584 return ((pm->pm_sr[(uintptr_t)va >> ADDR_SR_SHFT]) & SR_VSID_MASK); 585 } 586 587 #endif 588 589 /* 590 * These functions need to provide addresses that both (a) work in real mode 591 * (or whatever mode/circumstances the kernel is in in early boot (now)) and 592 * (b) can still, in principle, work once the kernel is going. Because these 593 * rely on existing mappings/real mode, unmap is a no-op. 594 */ 595 vm_offset_t 596 pmap_early_io_map(vm_paddr_t pa, vm_size_t size) 597 { 598 KASSERT(!pmap_bootstrapped, ("Not available after PMAP started!")); 599 600 /* 601 * If we have the MMU up in early boot, assume it is 1:1. Otherwise, 602 * try to get the address in a memory region compatible with the 603 * direct map for efficiency later. 604 */ 605 if (mfmsr() & PSL_DR) 606 return (pa); 607 else 608 return (DMAP_BASE_ADDRESS + pa); 609 } 610 611 void 612 pmap_early_io_unmap(vm_offset_t va, vm_size_t size) 613 { 614 615 KASSERT(!pmap_bootstrapped, ("Not available after PMAP started!")); 616 } 617 618 /* From p3-53 of the MPC7450 RISC Microprocessor Family Reference Manual */ 619 void 620 flush_disable_caches(void) 621 { 622 register_t msr; 623 register_t msscr0; 624 register_t cache_reg; 625 volatile uint32_t *memp; 626 uint32_t temp; 627 int i; 628 int x; 629 630 msr = mfmsr(); 631 powerpc_sync(); 632 mtmsr(msr & ~(PSL_EE | PSL_DR)); 633 msscr0 = mfspr(SPR_MSSCR0); 634 msscr0 &= ~MSSCR0_L2PFE; 635 mtspr(SPR_MSSCR0, msscr0); 636 powerpc_sync(); 637 isync(); 638 /* 7e00066c: dssall */ 639 __asm__ __volatile__(".long 0x7e00066c; sync"); 640 powerpc_sync(); 641 isync(); 642 __asm__ __volatile__("dcbf 0,%0" :: "r"(0)); 643 __asm__ __volatile__("dcbf 0,%0" :: "r"(0)); 644 __asm__ __volatile__("dcbf 0,%0" :: "r"(0)); 645 646 /* Lock the L1 Data cache. */ 647 mtspr(SPR_LDSTCR, mfspr(SPR_LDSTCR) | 0xFF); 648 powerpc_sync(); 649 isync(); 650 651 mtspr(SPR_LDSTCR, 0); 652 653 /* 654 * Perform this in two stages: Flush the cache starting in RAM, then do it 655 * from ROM. 656 */ 657 memp = (volatile uint32_t *)0x00000000; 658 for (i = 0; i < 128 * 1024; i++) { 659 temp = *memp; 660 __asm__ __volatile__("dcbf 0,%0" :: "r"(memp)); 661 memp += 32/sizeof(*memp); 662 } 663 664 memp = (volatile uint32_t *)0xfff00000; 665 x = 0xfe; 666 667 for (; x != 0xff;) { 668 mtspr(SPR_LDSTCR, x); 669 for (i = 0; i < 128; i++) { 670 temp = *memp; 671 __asm__ __volatile__("dcbf 0,%0" :: "r"(memp)); 672 memp += 32/sizeof(*memp); 673 } 674 x = ((x << 1) | 1) & 0xff; 675 } 676 mtspr(SPR_LDSTCR, 0); 677 678 cache_reg = mfspr(SPR_L2CR); 679 if (cache_reg & L2CR_L2E) { 680 cache_reg &= ~(L2CR_L2IO_7450 | L2CR_L2DO_7450); 681 mtspr(SPR_L2CR, cache_reg); 682 powerpc_sync(); 683 mtspr(SPR_L2CR, cache_reg | L2CR_L2HWF); 684 while (mfspr(SPR_L2CR) & L2CR_L2HWF) 685 ; /* Busy wait for cache to flush */ 686 powerpc_sync(); 687 cache_reg &= ~L2CR_L2E; 688 mtspr(SPR_L2CR, cache_reg); 689 powerpc_sync(); 690 mtspr(SPR_L2CR, cache_reg | L2CR_L2I); 691 powerpc_sync(); 692 while (mfspr(SPR_L2CR) & L2CR_L2I) 693 ; /* Busy wait for L2 cache invalidate */ 694 powerpc_sync(); 695 } 696 697 cache_reg = mfspr(SPR_L3CR); 698 if (cache_reg & L3CR_L3E) { 699 cache_reg &= ~(L3CR_L3IO | L3CR_L3DO); 700 mtspr(SPR_L3CR, cache_reg); 701 powerpc_sync(); 702 mtspr(SPR_L3CR, cache_reg | L3CR_L3HWF); 703 while (mfspr(SPR_L3CR) & L3CR_L3HWF) 704 ; /* Busy wait for cache to flush */ 705 powerpc_sync(); 706 cache_reg &= ~L3CR_L3E; 707 mtspr(SPR_L3CR, cache_reg); 708 powerpc_sync(); 709 mtspr(SPR_L3CR, cache_reg | L3CR_L3I); 710 powerpc_sync(); 711 while (mfspr(SPR_L3CR) & L3CR_L3I) 712 ; /* Busy wait for L3 cache invalidate */ 713 powerpc_sync(); 714 } 715 716 mtspr(SPR_HID0, mfspr(SPR_HID0) & ~HID0_DCE); 717 powerpc_sync(); 718 isync(); 719 720 mtmsr(msr); 721 } 722 723 void 724 cpu_sleep() 725 { 726 static u_quad_t timebase = 0; 727 static register_t sprgs[4]; 728 static register_t srrs[2]; 729 730 jmp_buf resetjb; 731 struct thread *fputd; 732 struct thread *vectd; 733 register_t hid0; 734 register_t msr; 735 register_t saved_msr; 736 737 ap_pcpu = pcpup; 738 739 PCPU_SET(restore, &resetjb); 740 741 saved_msr = mfmsr(); 742 fputd = PCPU_GET(fputhread); 743 vectd = PCPU_GET(vecthread); 744 if (fputd != NULL) 745 save_fpu(fputd); 746 if (vectd != NULL) 747 save_vec(vectd); 748 if (setjmp(resetjb) == 0) { 749 sprgs[0] = mfspr(SPR_SPRG0); 750 sprgs[1] = mfspr(SPR_SPRG1); 751 sprgs[2] = mfspr(SPR_SPRG2); 752 sprgs[3] = mfspr(SPR_SPRG3); 753 srrs[0] = mfspr(SPR_SRR0); 754 srrs[1] = mfspr(SPR_SRR1); 755 timebase = mftb(); 756 powerpc_sync(); 757 flush_disable_caches(); 758 hid0 = mfspr(SPR_HID0); 759 hid0 = (hid0 & ~(HID0_DOZE | HID0_NAP)) | HID0_SLEEP; 760 powerpc_sync(); 761 isync(); 762 msr = mfmsr() | PSL_POW; 763 mtspr(SPR_HID0, hid0); 764 powerpc_sync(); 765 766 while (1) 767 mtmsr(msr); 768 } 769 platform_smp_timebase_sync(timebase, 0); 770 PCPU_SET(curthread, curthread); 771 PCPU_SET(curpcb, curthread->td_pcb); 772 pmap_activate(curthread); 773 powerpc_sync(); 774 mtspr(SPR_SPRG0, sprgs[0]); 775 mtspr(SPR_SPRG1, sprgs[1]); 776 mtspr(SPR_SPRG2, sprgs[2]); 777 mtspr(SPR_SPRG3, sprgs[3]); 778 mtspr(SPR_SRR0, srrs[0]); 779 mtspr(SPR_SRR1, srrs[1]); 780 mtmsr(saved_msr); 781 if (fputd == curthread) 782 enable_fpu(curthread); 783 if (vectd == curthread) 784 enable_vec(curthread); 785 powerpc_sync(); 786 } 787