diff options
| -rw-r--r-- | arch/ppc/kernel/head_8xx.S | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/arch/ppc/kernel/head_8xx.S b/arch/ppc/kernel/head_8xx.S index de0978742221..3e6ca7f5843f 100644 --- a/arch/ppc/kernel/head_8xx.S +++ b/arch/ppc/kernel/head_8xx.S | |||
| @@ -375,6 +375,8 @@ DataStoreTLBMiss: | |||
| 375 | lis r11, swapper_pg_dir@h | 375 | lis r11, swapper_pg_dir@h |
| 376 | ori r11, r11, swapper_pg_dir@l | 376 | ori r11, r11, swapper_pg_dir@l |
| 377 | rlwimi r10, r11, 0, 2, 19 | 377 | rlwimi r10, r11, 0, 2, 19 |
| 378 | stw r12, 16(r0) | ||
| 379 | b LoadLargeDTLB | ||
| 378 | 3: | 380 | 3: |
| 379 | lwz r11, 0(r10) /* Get the level 1 entry */ | 381 | lwz r11, 0(r10) /* Get the level 1 entry */ |
| 380 | rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */ | 382 | rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */ |
| @@ -430,6 +432,81 @@ DataStoreTLBMiss: | |||
| 430 | InstructionTLBError: | 432 | InstructionTLBError: |
| 431 | b InstructionAccess | 433 | b InstructionAccess |
| 432 | 434 | ||
| 435 | LoadLargeDTLB: | ||
| 436 | li r12, 0 | ||
| 437 | lwz r11, 0(r10) /* Get the level 1 entry */ | ||
| 438 | rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */ | ||
| 439 | beq 3f /* If zero, don't try to find a pte */ | ||
| 440 | |||
| 441 | /* We have a pte table, so load fetch the pte from the table. | ||
| 442 | */ | ||
| 443 | ori r11, r11, 1 /* Set valid bit in physical L2 page */ | ||
| 444 | DO_8xx_CPU6(0x3b80, r3) | ||
| 445 | mtspr SPRN_MD_TWC, r11 /* Load pte table base address */ | ||
| 446 | mfspr r10, SPRN_MD_TWC /* ....and get the pte address */ | ||
| 447 | lwz r10, 0(r10) /* Get the pte */ | ||
| 448 | |||
| 449 | /* Insert the Guarded flag into the TWC from the Linux PTE. | ||
| 450 | * It is bit 27 of both the Linux PTE and the TWC (at least | ||
| 451 | * I got that right :-). It will be better when we can put | ||
| 452 | * this into the Linux pgd/pmd and load it in the operation | ||
| 453 | * above. | ||
| 454 | */ | ||
| 455 | rlwimi r11, r10, 0, 27, 27 | ||
| 456 | |||
| 457 | rlwimi r12, r10, 0, 0, 9 /* extract phys. addr */ | ||
| 458 | mfspr r3, SPRN_MD_EPN | ||
| 459 | rlwinm r3, r3, 0, 0, 9 /* extract virtual address */ | ||
| 460 | tophys(r3, r3) | ||
| 461 | cmpw r3, r12 /* only use 8M page if it is a direct | ||
| 462 | kernel mapping */ | ||
| 463 | bne 1f | ||
| 464 | ori r11, r11, MD_PS8MEG | ||
| 465 | li r12, 1 | ||
| 466 | b 2f | ||
| 467 | 1: | ||
| 468 | li r12, 0 /* can't use 8MB TLB, so zero r12. */ | ||
| 469 | 2: | ||
| 470 | DO_8xx_CPU6(0x3b80, r3) | ||
| 471 | mtspr SPRN_MD_TWC, r11 | ||
| 472 | |||
| 473 | /* The Linux PTE won't go exactly into the MMU TLB. | ||
| 474 | * Software indicator bits 21, 22 and 28 must be clear. | ||
| 475 | * Software indicator bits 24, 25, 26, and 27 must be | ||
| 476 | * set. All other Linux PTE bits control the behavior | ||
| 477 | * of the MMU. | ||
| 478 | */ | ||
| 479 | 3: li r11, 0x00f0 | ||
| 480 | rlwimi r10, r11, 0, 24, 28 /* Set 24-27, clear 28 */ | ||
| 481 | cmpwi r12, 1 | ||
| 482 | bne 4f | ||
| 483 | ori r10, r10, 0x8 | ||
| 484 | |||
| 485 | mfspr r12, SPRN_MD_EPN | ||
| 486 | lis r3, 0xff80 /* 10-19 must be clear for 8MB TLB */ | ||
| 487 | ori r3, r3, 0x0fff | ||
| 488 | and r12, r3, r12 | ||
| 489 | DO_8xx_CPU6(0x3780, r3) | ||
| 490 | mtspr SPRN_MD_EPN, r12 | ||
| 491 | |||
| 492 | lis r3, 0xff80 /* 10-19 must be clear for 8MB TLB */ | ||
| 493 | ori r3, r3, 0x0fff | ||
| 494 | and r10, r3, r10 | ||
| 495 | 4: | ||
| 496 | DO_8xx_CPU6(0x3d80, r3) | ||
| 497 | mtspr SPRN_MD_RPN, r10 /* Update TLB entry */ | ||
| 498 | |||
| 499 | mfspr r10, SPRN_M_TW /* Restore registers */ | ||
| 500 | lwz r11, 0(r0) | ||
| 501 | mtcr r11 | ||
| 502 | lwz r11, 4(r0) | ||
| 503 | |||
| 504 | lwz r12, 16(r0) | ||
| 505 | #ifdef CONFIG_8xx_CPU6 | ||
| 506 | lwz r3, 8(r0) | ||
| 507 | #endif | ||
| 508 | rfi | ||
| 509 | |||
| 433 | /* This is the data TLB error on the MPC8xx. This could be due to | 510 | /* This is the data TLB error on the MPC8xx. This could be due to |
| 434 | * many reasons, including a dirty update to a pte. We can catch that | 511 | * many reasons, including a dirty update to a pte. We can catch that |
| 435 | * one here, but anything else is an error. First, we track down the | 512 | * one here, but anything else is an error. First, we track down the |
