diff options
Diffstat (limited to 'arch/sparc64/mm/init.c')
-rw-r--r-- | arch/sparc64/mm/init.c | 98 |
1 files changed, 5 insertions, 93 deletions
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index ec47de494c1f..e0b9eebf21ce 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c | |||
@@ -505,108 +505,20 @@ static int read_obp_translations(void) | |||
505 | return n; | 505 | return n; |
506 | } | 506 | } |
507 | 507 | ||
508 | static inline void early_spitfire_errata32(void) | ||
509 | { | ||
510 | /* Spitfire Errata #32 workaround */ | ||
511 | /* NOTE: Using plain zero for the context value is | ||
512 | * correct here, we are not using the Linux trap | ||
513 | * tables yet so we should not use the special | ||
514 | * UltraSPARC-III+ page size encodings yet. | ||
515 | */ | ||
516 | __asm__ __volatile__("stxa %0, [%1] %2\n\t" | ||
517 | "flush %%g6" | ||
518 | : /* No outputs */ | ||
519 | : "r" (0), "r" (PRIMARY_CONTEXT), | ||
520 | "i" (ASI_DMMU)); | ||
521 | } | ||
522 | |||
523 | static void lock_remap_func_page(unsigned long phys_page) | ||
524 | { | ||
525 | unsigned long tte_data = (phys_page | pgprot_val(PAGE_KERNEL)); | ||
526 | |||
527 | if (tlb_type == spitfire) { | ||
528 | /* Lock this into i/d tlb entry 59 */ | ||
529 | __asm__ __volatile__( | ||
530 | "stxa %%g0, [%2] %3\n\t" | ||
531 | "stxa %0, [%1] %4\n\t" | ||
532 | "membar #Sync\n\t" | ||
533 | "flush %%g6\n\t" | ||
534 | "stxa %%g0, [%2] %5\n\t" | ||
535 | "stxa %0, [%1] %6\n\t" | ||
536 | "membar #Sync\n\t" | ||
537 | "flush %%g6" | ||
538 | : /* no outputs */ | ||
539 | : "r" (tte_data), "r" (59 << 3), "r" (TLB_TAG_ACCESS), | ||
540 | "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), | ||
541 | "i" (ASI_IMMU), "i" (ASI_ITLB_DATA_ACCESS) | ||
542 | : "memory"); | ||
543 | } else { | ||
544 | /* Lock this into i/d tlb-0 entry 11 */ | ||
545 | __asm__ __volatile__( | ||
546 | "stxa %%g0, [%2] %3\n\t" | ||
547 | "stxa %0, [%1] %4\n\t" | ||
548 | "membar #Sync\n\t" | ||
549 | "flush %%g6\n\t" | ||
550 | "stxa %%g0, [%2] %5\n\t" | ||
551 | "stxa %0, [%1] %6\n\t" | ||
552 | "membar #Sync\n\t" | ||
553 | "flush %%g6" | ||
554 | : /* no outputs */ | ||
555 | : "r" (tte_data), "r" ((0 << 16) | (11 << 3)), | ||
556 | "r" (TLB_TAG_ACCESS), "i" (ASI_DMMU), | ||
557 | "i" (ASI_DTLB_DATA_ACCESS), "i" (ASI_IMMU), | ||
558 | "i" (ASI_ITLB_DATA_ACCESS) | ||
559 | : "memory"); | ||
560 | } | ||
561 | } | ||
562 | |||
563 | static void remap_kernel(void) | 508 | static void remap_kernel(void) |
564 | { | 509 | { |
565 | unsigned long phys_page, tte_vaddr, tte_data; | 510 | unsigned long phys_page, tte_vaddr, tte_data; |
566 | void (*remap_func)(unsigned long, unsigned long, int); | ||
567 | int tlb_ent = sparc64_highest_locked_tlbent(); | 511 | int tlb_ent = sparc64_highest_locked_tlbent(); |
568 | 512 | ||
569 | early_spitfire_errata32(); | ||
570 | |||
571 | if (tlb_type == spitfire) | ||
572 | phys_page = spitfire_get_dtlb_data(tlb_ent); | ||
573 | else | ||
574 | phys_page = cheetah_get_ldtlb_data(tlb_ent); | ||
575 | |||
576 | phys_page &= _PAGE_PADDR; | ||
577 | phys_page += ((unsigned long)&prom_boot_page - | ||
578 | (unsigned long)KERNBASE); | ||
579 | |||
580 | lock_remap_func_page(phys_page); | ||
581 | |||
582 | tte_vaddr = (unsigned long) KERNBASE; | 513 | tte_vaddr = (unsigned long) KERNBASE; |
583 | 514 | phys_page = (prom_boot_mapping_phys_low >> 22UL) << 22UL; | |
584 | early_spitfire_errata32(); | 515 | tte_data = (phys_page | (_PAGE_VALID | _PAGE_SZ4MB | |
585 | 516 | _PAGE_CP | _PAGE_CV | _PAGE_P | | |
586 | if (tlb_type == spitfire) | 517 | _PAGE_L | _PAGE_W)); |
587 | tte_data = spitfire_get_dtlb_data(tlb_ent); | ||
588 | else | ||
589 | tte_data = cheetah_get_ldtlb_data(tlb_ent); | ||
590 | 518 | ||
591 | kern_locked_tte_data = tte_data; | 519 | kern_locked_tte_data = tte_data; |
592 | 520 | ||
593 | remap_func = (void *) ((unsigned long) &prom_remap - | 521 | /* Now lock us into the TLBs via OBP. */ |
594 | (unsigned long) &prom_boot_page); | ||
595 | |||
596 | early_spitfire_errata32(); | ||
597 | |||
598 | phys_page = tte_data & _PAGE_PADDR; | ||
599 | remap_func(phys_page, KERNBASE, prom_get_mmu_ihandle()); | ||
600 | if (bigkernel) | ||
601 | remap_func(phys_page + 0x400000, | ||
602 | KERNBASE + 0x400000, | ||
603 | prom_get_mmu_ihandle()); | ||
604 | |||
605 | /* Flush out that temporary mapping. */ | ||
606 | spitfire_flush_dtlb_nucleus_page(0x0); | ||
607 | spitfire_flush_itlb_nucleus_page(0x0); | ||
608 | |||
609 | /* Now lock us back into the TLBs via OBP. */ | ||
610 | prom_dtlb_load(tlb_ent, tte_data, tte_vaddr); | 522 | prom_dtlb_load(tlb_ent, tte_data, tte_vaddr); |
611 | prom_itlb_load(tlb_ent, tte_data, tte_vaddr); | 523 | prom_itlb_load(tlb_ent, tte_data, tte_vaddr); |
612 | if (bigkernel) { | 524 | if (bigkernel) { |