aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/mm/init.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2006-02-09 05:52:44 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-03-20 04:12:03 -0500
commitd82ace7dc4073b090a55b9740700e32b9a9ae302 (patch)
treed5aa8e10664b05bbfe31eacf95e2066c03cab102 /arch/sparc64/mm/init.c
parent1d2f1f90a1e004b0c1b8a73ed4394a93f09104b3 (diff)
[SPARC64]: Detect sun4v early in boot process.
We look for "SUNW,sun4v" in the 'compatible' property of the root OBP device tree node. Protect every %ver register access, to make sure it is not touched on sun4v, as %ver is hyperprivileged there. Lock kernel TLB entries using hypervisor calls instead of calls into OBP. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/mm/init.c')
-rw-r--r--arch/sparc64/mm/init.c58
1 files changed, 46 insertions, 12 deletions
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
index 6504d6eb5372..e602b857071a 100644
--- a/arch/sparc64/mm/init.c
+++ b/arch/sparc64/mm/init.c
@@ -514,6 +514,29 @@ static void __init read_obp_translations(void)
514 } 514 }
515} 515}
516 516
517static void __init hypervisor_tlb_lock(unsigned long vaddr,
518 unsigned long pte,
519 unsigned long mmu)
520{
521 register unsigned long func asm("%o0");
522 register unsigned long arg0 asm("%o1");
523 register unsigned long arg1 asm("%o2");
524 register unsigned long arg2 asm("%o3");
525 register unsigned long arg3 asm("%o4");
526
527 func = HV_FAST_MMU_MAP_PERM_ADDR;
528 arg0 = vaddr;
529 arg1 = 0;
530 arg2 = pte;
531 arg3 = mmu;
532 __asm__ __volatile__("ta 0x80"
533 : "=&r" (func), "=&r" (arg0),
534 "=&r" (arg1), "=&r" (arg2),
535 "=&r" (arg3)
536 : "0" (func), "1" (arg0), "2" (arg1),
537 "3" (arg2), "4" (arg3));
538}
539
517static void __init remap_kernel(void) 540static void __init remap_kernel(void)
518{ 541{
519 unsigned long phys_page, tte_vaddr, tte_data; 542 unsigned long phys_page, tte_vaddr, tte_data;
@@ -527,19 +550,30 @@ static void __init remap_kernel(void)
527 550
528 kern_locked_tte_data = tte_data; 551 kern_locked_tte_data = tte_data;
529 552
530 /* Now lock us into the TLBs via OBP. */ 553 /* Now lock us into the TLBs via Hypervisor or OBP. */
531 prom_dtlb_load(tlb_ent, tte_data, tte_vaddr); 554 if (tlb_type == hypervisor) {
532 prom_itlb_load(tlb_ent, tte_data, tte_vaddr); 555 hypervisor_tlb_lock(tte_vaddr, tte_data, HV_MMU_DMMU);
533 if (bigkernel) { 556 hypervisor_tlb_lock(tte_vaddr, tte_data, HV_MMU_IMMU);
534 tlb_ent -= 1; 557 if (bigkernel) {
535 prom_dtlb_load(tlb_ent, 558 tte_vaddr += 0x400000;
536 tte_data + 0x400000, 559 tte_data += 0x400000;
537 tte_vaddr + 0x400000); 560 hypervisor_tlb_lock(tte_vaddr, tte_data, HV_MMU_DMMU);
538 prom_itlb_load(tlb_ent, 561 hypervisor_tlb_lock(tte_vaddr, tte_data, HV_MMU_IMMU);
539 tte_data + 0x400000, 562 }
540 tte_vaddr + 0x400000); 563 } else {
564 prom_dtlb_load(tlb_ent, tte_data, tte_vaddr);
565 prom_itlb_load(tlb_ent, tte_data, tte_vaddr);
566 if (bigkernel) {
567 tlb_ent -= 1;
568 prom_dtlb_load(tlb_ent,
569 tte_data + 0x400000,
570 tte_vaddr + 0x400000);
571 prom_itlb_load(tlb_ent,
572 tte_data + 0x400000,
573 tte_vaddr + 0x400000);
574 }
575 sparc64_highest_unlocked_tlb_ent = tlb_ent - 1;
541 } 576 }
542 sparc64_highest_unlocked_tlb_ent = tlb_ent - 1;
543 if (tlb_type == cheetah_plus) { 577 if (tlb_type == cheetah_plus) {
544 sparc64_kern_pri_context = (CTX_CHEETAH_PLUS_CTX0 | 578 sparc64_kern_pri_context = (CTX_CHEETAH_PLUS_CTX0 |
545 CTX_CHEETAH_PLUS_NUC); 579 CTX_CHEETAH_PLUS_NUC);