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 @@ .text .align 32 - .globl sparc64_vpte_patchme1 - .globl sparc64_vpte_patchme2 /* * On a second level vpte miss, check whether the original fault is to the OBP * range (note that this is only possible for instruction miss, data misses to @@ -33,18 +31,17 @@ sparc64_vpte_nucleus: */ sethi %hi(LOW_OBP_ADDRESS), %g5 cmp %g4, %g5 - blu,pn %xcc, sparc64_vpte_patchme1 + blu,pn %xcc, kern_vpte mov 0x1, %g5 sllx %g5, 32, %g5 cmp %g4, %g5 - blu,pn %xcc, obp_iaddr_patch + blu,pn %xcc, vpte_insn_obp nop /* These two instructions are patched by paginig_init(). */ -sparc64_vpte_patchme1: - sethi %hi(0), %g5 -sparc64_vpte_patchme2: - or %g5, %lo(0), %g5 +kern_vpte: + sethi %hi(swapper_pgd_zero), %g5 + lduw [%g5 + %lo(swapper_pgd_zero)], %g5 /* With kernel PGD in %g5, branch back into dtlb_backend. */ ba,pt %xcc, sparc64_kpte_continue @@ -60,11 +57,9 @@ vpte_noent: stxa %g4, [%g1 + %g1] ASI_DMMU done - .globl obp_iaddr_patch -obp_iaddr_patch: - /* These two instructions patched by inherit_prom_mappings(). */ - sethi %hi(0), %g5 - or %g5, %lo(0), %g5 +vpte_insn_obp: + sethi %hi(prom_pmd_phys), %g5 + ldx [%g5 + %lo(prom_pmd_phys)], %g5 /* Behave as if we are at TL0. */ wrpr %g0, 1, %tl @@ -100,11 +95,9 @@ obp_iaddr_patch: stxa %g5, [%g0] ASI_ITLB_DATA_IN retry - .globl obp_daddr_patch -obp_daddr_patch: - /* These two instructions patched by inherit_prom_mappings(). */ - sethi %hi(0), %g5 - or %g5, %lo(0), %g5 +kvmap_do_obp: + sethi %hi(prom_pmd_phys), %g5 + ldx [%g5 + %lo(prom_pmd_phys)], %g5 /* Get PMD offset. */ srlx %g4, 23, %g6 @@ -159,7 +152,7 @@ kvmap_check_obp: mov 0x1, %g5 sllx %g5, 32, %g5 cmp %g4, %g5 - blu,pn %xcc, obp_daddr_patch + blu,pn %xcc, kvmap_do_obp nop 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 @@ #include #include #include +#include #include #include @@ -45,10 +46,10 @@ struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS]; unsigned long *sparc64_valid_addr_bitmap; /* Ugly, but necessary... -DaveM */ -unsigned long phys_base; -unsigned long kern_base; -unsigned long kern_size; -unsigned long pfn_base; +unsigned long phys_base __read_mostly; +unsigned long kern_base __read_mostly; +unsigned long kern_size __read_mostly; +unsigned long pfn_base __read_mostly; /* This is even uglier. We have a problem where the kernel may not be * located at phys_base. However, initial __alloc_bootmem() calls need to @@ -73,7 +74,7 @@ extern unsigned long sparc_ramdisk_image64; extern unsigned int sparc_ramdisk_image; extern unsigned int sparc_ramdisk_size; -struct page *mem_map_zero; +struct page *mem_map_zero __read_mostly; int bigkernel = 0; @@ -318,6 +319,10 @@ extern void register_prom_callbacks(void); /* Exported for SMP bootup purposes. */ unsigned long kern_locked_tte_data; +/* Exported for kernel TLB miss handling in ktlb.S */ +unsigned long prom_pmd_phys __read_mostly; +unsigned int swapper_pgd_zero __read_mostly; + void __init early_pgtable_allocfail(char *type) { prom_printf("inherit_prom_mappings: Cannot alloc kernel %s.\n", type); @@ -364,7 +369,6 @@ static void inherit_prom_mappings(void) pmd_t *pmdp; pte_t *ptep; int node, n, i, tsz; - extern unsigned int obp_iaddr_patch[2], obp_daddr_patch[2]; node = prom_finddevice("/virtual-memory"); n = prom_getproplen(node, "translations"); @@ -434,13 +438,7 @@ static void inherit_prom_mappings(void) } } } - phys_page = __pa(prompmd); - obp_iaddr_patch[0] |= (phys_page >> 10); - obp_iaddr_patch[1] |= (phys_page & 0x3ff); - flushi((long)&obp_iaddr_patch[0]); - obp_daddr_patch[0] |= (phys_page >> 10); - obp_daddr_patch[1] |= (phys_page & 0x3ff); - flushi((long)&obp_daddr_patch[0]); + prom_pmd_phys = __pa(prompmd); /* Now fixup OBP's idea about where we really are mapped. */ prom_printf("Remapping the kernel... "); @@ -1407,8 +1405,6 @@ static unsigned long last_valid_pfn; void __init paging_init(void) { extern pmd_t swapper_pmd_dir[1024]; - extern unsigned int sparc64_vpte_patchme1[1]; - extern unsigned int sparc64_vpte_patchme2[1]; unsigned long alias_base = kern_base + PAGE_OFFSET; unsigned long second_alias_page = 0; unsigned long pt, flags, end_pfn, pages_avail; @@ -1502,11 +1498,7 @@ void __init paging_init(void) pud_set(pud_offset(&swapper_pg_dir[0], 0), swapper_pmd_dir + (shift / sizeof(pgd_t))); - sparc64_vpte_patchme1[0] |= - (((unsigned long)pgd_val(init_mm.pgd[0])) >> 10); - sparc64_vpte_patchme2[0] |= - (((unsigned long)pgd_val(init_mm.pgd[0])) & 0x3ff); - flushi((long)&sparc64_vpte_patchme1[0]); + swapper_pgd_zero = pgd_val(init_mm.pgd[0]); /* Setup bootmem... */ pages_avail = 0;