diff options
Diffstat (limited to 'arch/sparc/mm')
-rw-r--r-- | arch/sparc/mm/Makefile | 3 | ||||
-rw-r--r-- | arch/sparc/mm/leon_mm.c | 2 | ||||
-rw-r--r-- | arch/sparc/mm/srmmu.c | 25 | ||||
-rw-r--r-- | arch/sparc/mm/srmmu_access.S | 82 |
4 files changed, 106 insertions, 6 deletions
diff --git a/arch/sparc/mm/Makefile b/arch/sparc/mm/Makefile index 69ffd3112fed..30c3eccfdf5a 100644 --- a/arch/sparc/mm/Makefile +++ b/arch/sparc/mm/Makefile | |||
@@ -8,8 +8,9 @@ obj-$(CONFIG_SPARC64) += ultra.o tlb.o tsb.o gup.o | |||
8 | obj-y += fault_$(BITS).o | 8 | obj-y += fault_$(BITS).o |
9 | obj-y += init_$(BITS).o | 9 | obj-y += init_$(BITS).o |
10 | obj-$(CONFIG_SPARC32) += extable.o srmmu.o iommu.o io-unit.o | 10 | obj-$(CONFIG_SPARC32) += extable.o srmmu.o iommu.o io-unit.o |
11 | obj-$(CONFIG_SPARC32) += srmmu_access.o | ||
11 | obj-$(CONFIG_SPARC32) += hypersparc.o viking.o tsunami.o swift.o | 12 | obj-$(CONFIG_SPARC32) += hypersparc.o viking.o tsunami.o swift.o |
12 | obj-$(CONFIG_SPARC_LEON)+= leon_mm.o | 13 | obj-$(CONFIG_SPARC32) += leon_mm.o |
13 | 14 | ||
14 | # Only used by sparc64 | 15 | # Only used by sparc64 |
15 | obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o | 16 | obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o |
diff --git a/arch/sparc/mm/leon_mm.c b/arch/sparc/mm/leon_mm.c index 4c67ae6e5023..5bed085a2c17 100644 --- a/arch/sparc/mm/leon_mm.c +++ b/arch/sparc/mm/leon_mm.c | |||
@@ -32,7 +32,7 @@ static inline unsigned long leon_get_ctable_ptr(void) | |||
32 | } | 32 | } |
33 | 33 | ||
34 | 34 | ||
35 | unsigned long srmmu_swprobe(unsigned long vaddr, unsigned long *paddr) | 35 | unsigned long leon_swprobe(unsigned long vaddr, unsigned long *paddr) |
36 | { | 36 | { |
37 | 37 | ||
38 | unsigned int ctxtbl; | 38 | unsigned int ctxtbl; |
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c index 256db6b22c54..62e3f5773303 100644 --- a/arch/sparc/mm/srmmu.c +++ b/arch/sparc/mm/srmmu.c | |||
@@ -646,6 +646,23 @@ static void __init srmmu_allocate_ptable_skeleton(unsigned long start, | |||
646 | } | 646 | } |
647 | } | 647 | } |
648 | 648 | ||
649 | /* These flush types are not available on all chips... */ | ||
650 | static inline unsigned long srmmu_probe(unsigned long vaddr) | ||
651 | { | ||
652 | unsigned long retval; | ||
653 | |||
654 | if (sparc_cpu_model != sparc_leon) { | ||
655 | |||
656 | vaddr &= PAGE_MASK; | ||
657 | __asm__ __volatile__("lda [%1] %2, %0\n\t" : | ||
658 | "=r" (retval) : | ||
659 | "r" (vaddr | 0x400), "i" (ASI_M_FLUSH_PROBE)); | ||
660 | } else { | ||
661 | retval = leon_swprobe(vaddr, 0); | ||
662 | } | ||
663 | return retval; | ||
664 | } | ||
665 | |||
649 | /* | 666 | /* |
650 | * This is much cleaner than poking around physical address space | 667 | * This is much cleaner than poking around physical address space |
651 | * looking at the prom's page table directly which is what most | 668 | * looking at the prom's page table directly which is what most |
@@ -665,7 +682,7 @@ static void __init srmmu_inherit_prom_mappings(unsigned long start, | |||
665 | break; /* probably wrap around */ | 682 | break; /* probably wrap around */ |
666 | if(start == 0xfef00000) | 683 | if(start == 0xfef00000) |
667 | start = KADB_DEBUGGER_BEGVM; | 684 | start = KADB_DEBUGGER_BEGVM; |
668 | if(!(prompte = srmmu_hwprobe(start))) { | 685 | if(!(prompte = srmmu_probe(start))) { |
669 | start += PAGE_SIZE; | 686 | start += PAGE_SIZE; |
670 | continue; | 687 | continue; |
671 | } | 688 | } |
@@ -674,12 +691,12 @@ static void __init srmmu_inherit_prom_mappings(unsigned long start, | |||
674 | what = 0; | 691 | what = 0; |
675 | 692 | ||
676 | if(!(start & ~(SRMMU_REAL_PMD_MASK))) { | 693 | if(!(start & ~(SRMMU_REAL_PMD_MASK))) { |
677 | if(srmmu_hwprobe((start-PAGE_SIZE) + SRMMU_REAL_PMD_SIZE) == prompte) | 694 | if(srmmu_probe((start-PAGE_SIZE) + SRMMU_REAL_PMD_SIZE) == prompte) |
678 | what = 1; | 695 | what = 1; |
679 | } | 696 | } |
680 | 697 | ||
681 | if(!(start & ~(SRMMU_PGDIR_MASK))) { | 698 | if(!(start & ~(SRMMU_PGDIR_MASK))) { |
682 | if(srmmu_hwprobe((start-PAGE_SIZE) + SRMMU_PGDIR_SIZE) == | 699 | if(srmmu_probe((start-PAGE_SIZE) + SRMMU_PGDIR_SIZE) == |
683 | prompte) | 700 | prompte) |
684 | what = 2; | 701 | what = 2; |
685 | } | 702 | } |
@@ -1156,7 +1173,7 @@ static void turbosparc_flush_page_to_ram(unsigned long page) | |||
1156 | #ifdef TURBOSPARC_WRITEBACK | 1173 | #ifdef TURBOSPARC_WRITEBACK |
1157 | volatile unsigned long clear; | 1174 | volatile unsigned long clear; |
1158 | 1175 | ||
1159 | if (srmmu_hwprobe(page)) | 1176 | if (srmmu_probe(page)) |
1160 | turbosparc_flush_page_cache(page); | 1177 | turbosparc_flush_page_cache(page); |
1161 | clear = srmmu_get_fstatus(); | 1178 | clear = srmmu_get_fstatus(); |
1162 | #endif | 1179 | #endif |
diff --git a/arch/sparc/mm/srmmu_access.S b/arch/sparc/mm/srmmu_access.S new file mode 100644 index 000000000000..d0a67b2c2383 --- /dev/null +++ b/arch/sparc/mm/srmmu_access.S | |||
@@ -0,0 +1,82 @@ | |||
1 | /* Assembler variants of srmmu access functions. | ||
2 | * Implemented in assembler to allow run-time patching. | ||
3 | * LEON uses a different ASI for MMUREGS than SUN. | ||
4 | * | ||
5 | * The leon_1insn_patch infrastructure is used | ||
6 | * for the run-time patching. | ||
7 | */ | ||
8 | |||
9 | #include <linux/linkage.h> | ||
10 | |||
11 | #include <asm/asmmacro.h> | ||
12 | #include <asm/pgtsrmmu.h> | ||
13 | #include <asm/asi.h> | ||
14 | |||
15 | /* unsigned int srmmu_get_mmureg(void) */ | ||
16 | ENTRY(srmmu_get_mmureg) | ||
17 | LEON_PI(lda [%g0] ASI_LEON_MMUREGS, %o0) | ||
18 | SUN_PI_(lda [%g0] ASI_M_MMUREGS, %o0) | ||
19 | retl | ||
20 | nop | ||
21 | ENDPROC(srmmu_get_mmureg) | ||
22 | |||
23 | /* void srmmu_set_mmureg(unsigned long regval) */ | ||
24 | ENTRY(srmmu_set_mmureg) | ||
25 | LEON_PI(sta %o0, [%g0] ASI_LEON_MMUREGS) | ||
26 | SUN_PI_(sta %o0, [%g0] ASI_M_MMUREGS) | ||
27 | retl | ||
28 | nop | ||
29 | ENDPROC(srmmu_set_mmureg) | ||
30 | |||
31 | /* void srmmu_set_ctable_ptr(unsigned long paddr) */ | ||
32 | ENTRY(srmmu_set_ctable_ptr) | ||
33 | /* paddr = ((paddr >> 4) & SRMMU_CTX_PMASK); */ | ||
34 | srl %o0, 4, %g1 | ||
35 | and %g1, SRMMU_CTX_PMASK, %g1 | ||
36 | |||
37 | mov SRMMU_CTXTBL_PTR, %g2 | ||
38 | LEON_PI(sta %g1, [%g2] ASI_LEON_MMUREGS) | ||
39 | SUN_PI_(sta %g1, [%g2] ASI_M_MMUREGS) | ||
40 | retl | ||
41 | nop | ||
42 | ENDPROC(srmmu_set_ctable_ptr) | ||
43 | |||
44 | |||
45 | /* void srmmu_set_context(int context) */ | ||
46 | ENTRY(srmmu_set_context) | ||
47 | mov SRMMU_CTX_REG, %g1 | ||
48 | LEON_PI(sta %o0, [%g1] ASI_LEON_MMUREGS) | ||
49 | SUN_PI_(sta %o0, [%g1] ASI_M_MMUREGS) | ||
50 | retl | ||
51 | nop | ||
52 | ENDPROC(srmmu_set_context) | ||
53 | |||
54 | |||
55 | /* int srmmu_get_context(void) */ | ||
56 | ENTRY(srmmu_get_context) | ||
57 | mov SRMMU_CTX_REG, %o0 | ||
58 | LEON_PI(lda [%o0] ASI_LEON_MMUREGS, %o0) | ||
59 | SUN_PI_(lda [%o0] ASI_M_MMUREGS, %o0) | ||
60 | retl | ||
61 | nop | ||
62 | ENDPROC(srmmu_get_context) | ||
63 | |||
64 | |||
65 | /* unsigned int srmmu_get_fstatus(void) */ | ||
66 | ENTRY(srmmu_get_fstatus) | ||
67 | mov SRMMU_FAULT_STATUS, %o0 | ||
68 | LEON_PI(lda [%o0] ASI_LEON_MMUREGS, %o0) | ||
69 | SUN_PI_(lda [%o0] ASI_M_MMUREGS, %o0) | ||
70 | retl | ||
71 | nop | ||
72 | ENDPROC(srmmu_get_fstatus) | ||
73 | |||
74 | |||
75 | /* unsigned int srmmu_get_faddr(void) */ | ||
76 | ENTRY(srmmu_get_faddr) | ||
77 | mov SRMMU_FAULT_ADDR, %o0 | ||
78 | LEON_PI(lda [%o0] ASI_LEON_MMUREGS, %o0) | ||
79 | SUN_PI_(lda [%o0] ASI_M_MMUREGS, %o0) | ||
80 | retl | ||
81 | nop | ||
82 | ENDPROC(srmmu_get_faddr) | ||