aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64')
-rw-r--r--arch/sparc64/kernel/ktlb.S31
-rw-r--r--arch/sparc64/mm/init.c32
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(). */
44sparc64_vpte_patchme1: 42kern_vpte:
45 sethi %hi(0), %g5 43 sethi %hi(swapper_pgd_zero), %g5
46sparc64_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 60vpte_insn_obp:
64obp_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 98kvmap_do_obp:
104obp_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
165kvmap_vmalloc_addr: 158kvmap_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];
45unsigned long *sparc64_valid_addr_bitmap; 46unsigned long *sparc64_valid_addr_bitmap;
46 47
47/* Ugly, but necessary... -DaveM */ 48/* Ugly, but necessary... -DaveM */
48unsigned long phys_base; 49unsigned long phys_base __read_mostly;
49unsigned long kern_base; 50unsigned long kern_base __read_mostly;
50unsigned long kern_size; 51unsigned long kern_size __read_mostly;
51unsigned long pfn_base; 52unsigned 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;
73extern unsigned int sparc_ramdisk_image; 74extern unsigned int sparc_ramdisk_image;
74extern unsigned int sparc_ramdisk_size; 75extern unsigned int sparc_ramdisk_size;
75 76
76struct page *mem_map_zero; 77struct page *mem_map_zero __read_mostly;
77 78
78int bigkernel = 0; 79int 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. */
319unsigned long kern_locked_tte_data; 320unsigned long kern_locked_tte_data;
320 321
322/* Exported for kernel TLB miss handling in ktlb.S */
323unsigned long prom_pmd_phys __read_mostly;
324unsigned int swapper_pgd_zero __read_mostly;
325
321void __init early_pgtable_allocfail(char *type) 326void __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;
1407void __init paging_init(void) 1405void __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;