diff options
-rw-r--r-- | arch/sparc64/kernel/ktlb.S | 31 | ||||
-rw-r--r-- | arch/sparc64/mm/init.c | 32 |
2 files changed, 24 insertions, 39 deletions
diff --git a/arch/sparc64/kernel/ktlb.S b/arch/sparc64/kernel/ktlb.S index b7176792c9a2..a591bc0ebc7b 100644 --- a/arch/sparc64/kernel/ktlb.S +++ b/arch/sparc64/kernel/ktlb.S | |||
@@ -15,8 +15,6 @@ | |||
15 | .text | 15 | .text |
16 | .align 32 | 16 | .align 32 |
17 | 17 | ||
18 | .globl sparc64_vpte_patchme1 | ||
19 | .globl sparc64_vpte_patchme2 | ||
20 | /* | 18 | /* |
21 | * On a second level vpte miss, check whether the original fault is to the OBP | 19 | * On a second level vpte miss, check whether the original fault is to the OBP |
22 | * range (note that this is only possible for instruction miss, data misses to | 20 | * range (note that this is only possible for instruction miss, data misses to |
@@ -33,18 +31,17 @@ sparc64_vpte_nucleus: | |||
33 | */ | 31 | */ |
34 | sethi %hi(LOW_OBP_ADDRESS), %g5 | 32 | sethi %hi(LOW_OBP_ADDRESS), %g5 |
35 | cmp %g4, %g5 | 33 | cmp %g4, %g5 |
36 | blu,pn %xcc, sparc64_vpte_patchme1 | 34 | blu,pn %xcc, kern_vpte |
37 | mov 0x1, %g5 | 35 | mov 0x1, %g5 |
38 | sllx %g5, 32, %g5 | 36 | sllx %g5, 32, %g5 |
39 | cmp %g4, %g5 | 37 | cmp %g4, %g5 |
40 | blu,pn %xcc, obp_iaddr_patch | 38 | blu,pn %xcc, vpte_insn_obp |
41 | nop | 39 | nop |
42 | 40 | ||
43 | /* These two instructions are patched by paginig_init(). */ | 41 | /* These two instructions are patched by paginig_init(). */ |
44 | sparc64_vpte_patchme1: | 42 | kern_vpte: |
45 | sethi %hi(0), %g5 | 43 | sethi %hi(swapper_pgd_zero), %g5 |
46 | sparc64_vpte_patchme2: | 44 | lduw [%g5 + %lo(swapper_pgd_zero)], %g5 |
47 | or %g5, %lo(0), %g5 | ||
48 | 45 | ||
49 | /* With kernel PGD in %g5, branch back into dtlb_backend. */ | 46 | /* With kernel PGD in %g5, branch back into dtlb_backend. */ |
50 | ba,pt %xcc, sparc64_kpte_continue | 47 | ba,pt %xcc, sparc64_kpte_continue |
@@ -60,11 +57,9 @@ vpte_noent: | |||
60 | stxa %g4, [%g1 + %g1] ASI_DMMU | 57 | stxa %g4, [%g1 + %g1] ASI_DMMU |
61 | done | 58 | done |
62 | 59 | ||
63 | .globl obp_iaddr_patch | 60 | vpte_insn_obp: |
64 | obp_iaddr_patch: | 61 | sethi %hi(prom_pmd_phys), %g5 |
65 | /* These two instructions patched by inherit_prom_mappings(). */ | 62 | ldx [%g5 + %lo(prom_pmd_phys)], %g5 |
66 | sethi %hi(0), %g5 | ||
67 | or %g5, %lo(0), %g5 | ||
68 | 63 | ||
69 | /* Behave as if we are at TL0. */ | 64 | /* Behave as if we are at TL0. */ |
70 | wrpr %g0, 1, %tl | 65 | wrpr %g0, 1, %tl |
@@ -100,11 +95,9 @@ obp_iaddr_patch: | |||
100 | stxa %g5, [%g0] ASI_ITLB_DATA_IN | 95 | stxa %g5, [%g0] ASI_ITLB_DATA_IN |
101 | retry | 96 | retry |
102 | 97 | ||
103 | .globl obp_daddr_patch | 98 | kvmap_do_obp: |
104 | obp_daddr_patch: | 99 | sethi %hi(prom_pmd_phys), %g5 |
105 | /* These two instructions patched by inherit_prom_mappings(). */ | 100 | ldx [%g5 + %lo(prom_pmd_phys)], %g5 |
106 | sethi %hi(0), %g5 | ||
107 | or %g5, %lo(0), %g5 | ||
108 | 101 | ||
109 | /* Get PMD offset. */ | 102 | /* Get PMD offset. */ |
110 | srlx %g4, 23, %g6 | 103 | srlx %g4, 23, %g6 |
@@ -159,7 +152,7 @@ kvmap_check_obp: | |||
159 | mov 0x1, %g5 | 152 | mov 0x1, %g5 |
160 | sllx %g5, 32, %g5 | 153 | sllx %g5, 32, %g5 |
161 | cmp %g4, %g5 | 154 | cmp %g4, %g5 |
162 | blu,pn %xcc, obp_daddr_patch | 155 | blu,pn %xcc, kvmap_do_obp |
163 | nop | 156 | nop |
164 | 157 | ||
165 | kvmap_vmalloc_addr: | 158 | kvmap_vmalloc_addr: |
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index fdb1ebb308c9..aaf9a3eee997 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/fs.h> | 20 | #include <linux/fs.h> |
21 | #include <linux/seq_file.h> | 21 | #include <linux/seq_file.h> |
22 | #include <linux/kprobes.h> | 22 | #include <linux/kprobes.h> |
23 | #include <linux/cache.h> | ||
23 | 24 | ||
24 | #include <asm/head.h> | 25 | #include <asm/head.h> |
25 | #include <asm/system.h> | 26 | #include <asm/system.h> |
@@ -45,10 +46,10 @@ struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS]; | |||
45 | unsigned long *sparc64_valid_addr_bitmap; | 46 | unsigned long *sparc64_valid_addr_bitmap; |
46 | 47 | ||
47 | /* Ugly, but necessary... -DaveM */ | 48 | /* Ugly, but necessary... -DaveM */ |
48 | unsigned long phys_base; | 49 | unsigned long phys_base __read_mostly; |
49 | unsigned long kern_base; | 50 | unsigned long kern_base __read_mostly; |
50 | unsigned long kern_size; | 51 | unsigned long kern_size __read_mostly; |
51 | unsigned long pfn_base; | 52 | unsigned long pfn_base __read_mostly; |
52 | 53 | ||
53 | /* This is even uglier. We have a problem where the kernel may not be | 54 | /* This is even uglier. We have a problem where the kernel may not be |
54 | * located at phys_base. However, initial __alloc_bootmem() calls need to | 55 | * located at phys_base. However, initial __alloc_bootmem() calls need to |
@@ -73,7 +74,7 @@ extern unsigned long sparc_ramdisk_image64; | |||
73 | extern unsigned int sparc_ramdisk_image; | 74 | extern unsigned int sparc_ramdisk_image; |
74 | extern unsigned int sparc_ramdisk_size; | 75 | extern unsigned int sparc_ramdisk_size; |
75 | 76 | ||
76 | struct page *mem_map_zero; | 77 | struct page *mem_map_zero __read_mostly; |
77 | 78 | ||
78 | int bigkernel = 0; | 79 | int bigkernel = 0; |
79 | 80 | ||
@@ -318,6 +319,10 @@ extern void register_prom_callbacks(void); | |||
318 | /* Exported for SMP bootup purposes. */ | 319 | /* Exported for SMP bootup purposes. */ |
319 | unsigned long kern_locked_tte_data; | 320 | unsigned long kern_locked_tte_data; |
320 | 321 | ||
322 | /* Exported for kernel TLB miss handling in ktlb.S */ | ||
323 | unsigned long prom_pmd_phys __read_mostly; | ||
324 | unsigned int swapper_pgd_zero __read_mostly; | ||
325 | |||
321 | void __init early_pgtable_allocfail(char *type) | 326 | void __init early_pgtable_allocfail(char *type) |
322 | { | 327 | { |
323 | prom_printf("inherit_prom_mappings: Cannot alloc kernel %s.\n", type); | 328 | prom_printf("inherit_prom_mappings: Cannot alloc kernel %s.\n", type); |
@@ -364,7 +369,6 @@ static void inherit_prom_mappings(void) | |||
364 | pmd_t *pmdp; | 369 | pmd_t *pmdp; |
365 | pte_t *ptep; | 370 | pte_t *ptep; |
366 | int node, n, i, tsz; | 371 | int node, n, i, tsz; |
367 | extern unsigned int obp_iaddr_patch[2], obp_daddr_patch[2]; | ||
368 | 372 | ||
369 | node = prom_finddevice("/virtual-memory"); | 373 | node = prom_finddevice("/virtual-memory"); |
370 | n = prom_getproplen(node, "translations"); | 374 | n = prom_getproplen(node, "translations"); |
@@ -434,13 +438,7 @@ static void inherit_prom_mappings(void) | |||
434 | } | 438 | } |
435 | } | 439 | } |
436 | } | 440 | } |
437 | phys_page = __pa(prompmd); | 441 | prom_pmd_phys = __pa(prompmd); |
438 | obp_iaddr_patch[0] |= (phys_page >> 10); | ||
439 | obp_iaddr_patch[1] |= (phys_page & 0x3ff); | ||
440 | flushi((long)&obp_iaddr_patch[0]); | ||
441 | obp_daddr_patch[0] |= (phys_page >> 10); | ||
442 | obp_daddr_patch[1] |= (phys_page & 0x3ff); | ||
443 | flushi((long)&obp_daddr_patch[0]); | ||
444 | 442 | ||
445 | /* Now fixup OBP's idea about where we really are mapped. */ | 443 | /* Now fixup OBP's idea about where we really are mapped. */ |
446 | prom_printf("Remapping the kernel... "); | 444 | prom_printf("Remapping the kernel... "); |
@@ -1407,8 +1405,6 @@ static unsigned long last_valid_pfn; | |||
1407 | void __init paging_init(void) | 1405 | void __init paging_init(void) |
1408 | { | 1406 | { |
1409 | extern pmd_t swapper_pmd_dir[1024]; | 1407 | extern pmd_t swapper_pmd_dir[1024]; |
1410 | extern unsigned int sparc64_vpte_patchme1[1]; | ||
1411 | extern unsigned int sparc64_vpte_patchme2[1]; | ||
1412 | unsigned long alias_base = kern_base + PAGE_OFFSET; | 1408 | unsigned long alias_base = kern_base + PAGE_OFFSET; |
1413 | unsigned long second_alias_page = 0; | 1409 | unsigned long second_alias_page = 0; |
1414 | unsigned long pt, flags, end_pfn, pages_avail; | 1410 | unsigned long pt, flags, end_pfn, pages_avail; |
@@ -1502,11 +1498,7 @@ void __init paging_init(void) | |||
1502 | pud_set(pud_offset(&swapper_pg_dir[0], 0), | 1498 | pud_set(pud_offset(&swapper_pg_dir[0], 0), |
1503 | swapper_pmd_dir + (shift / sizeof(pgd_t))); | 1499 | swapper_pmd_dir + (shift / sizeof(pgd_t))); |
1504 | 1500 | ||
1505 | sparc64_vpte_patchme1[0] |= | 1501 | swapper_pgd_zero = pgd_val(init_mm.pgd[0]); |
1506 | (((unsigned long)pgd_val(init_mm.pgd[0])) >> 10); | ||
1507 | sparc64_vpte_patchme2[0] |= | ||
1508 | (((unsigned long)pgd_val(init_mm.pgd[0])) & 0x3ff); | ||
1509 | flushi((long)&sparc64_vpte_patchme1[0]); | ||
1510 | 1502 | ||
1511 | /* Setup bootmem... */ | 1503 | /* Setup bootmem... */ |
1512 | pages_avail = 0; | 1504 | pages_avail = 0; |