aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/mm
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2005-09-22 00:49:32 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2005-09-22 00:49:32 -0400
commit1ac4f5ebaa496a23ab4a148c9864d7e30a6c6cd3 (patch)
tree1ab1e111f596b8c66c741e63f14d721cb1818c7a /arch/sparc64/mm
parent059deb693ec191e563ec69533d24f3feff0b78cd (diff)
[SPARC64]: Remove ktlb.S instruction patching.
This was kind of ugly, and actually buggy. The bug was that we didn't handle a machine with memory starting > 4GB. If the 'prompmd' was allocated in physical memory > 4GB we'd croak because the obp_iaddr_patch and obp_daddr_patch things only supported a 32-bit physical address. So fix this by just loading the appropriate values from two variables in the kernel image, which is locked into the TLB and thus accesses to them can't cause a recursive TLB miss. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/mm')
-rw-r--r--arch/sparc64/mm/init.c32
1 files changed, 12 insertions, 20 deletions
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;