diff options
author | davem <davem> | 2001-11-30 06:40:24 +0000 |
---|---|---|
committer | davem <davem> | 2001-11-30 06:40:24 +0000 |
commit | 504bada32c1809f35bdd14e0c25235616a35d871 (patch) | |
tree | cd74e2228d7e032d397545b9c13363b930e67d2a | |
parent | 8e92b6c1034b1e498670cd23c44341411c57e714 (diff) | |
download | netdev-vger-cvs-504bada32c1809f35bdd14e0c25235616a35d871.tar.gz |
Add support for >4MB kernels, only really
useful right now for net booting as SILO would
have big problems with such huge kernels.
From Kanoj.
-rw-r--r-- | arch/sparc64/kernel/head.S | 53 | ||||
-rw-r--r-- | arch/sparc64/kernel/smp.c | 9 | ||||
-rw-r--r-- | arch/sparc64/lib/blockops.S | 12 | ||||
-rw-r--r-- | arch/sparc64/mm/init.c | 29 |
4 files changed, 88 insertions, 15 deletions
diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S index 58617083e..60ee628d8 100644 --- a/arch/sparc64/kernel/head.S +++ b/arch/sparc64/kernel/head.S @@ -1,4 +1,4 @@ -/* $Id: head.S,v 1.82 2001-10-04 23:37:04 davem Exp $ +/* $Id: head.S,v 1.83 2001-11-30 06:40:24 davem Exp $ * head.S: Initial boot code for the Sparc64 port of Linux. * * Copyright (C) 1996,1997 David S. Miller (davem@caip.rutgers.edu) @@ -201,7 +201,7 @@ cheetah_got_tlbentry: add %l0, (1 << 3), %l0 /* Now lock the TTE we created into ITLB-0 and DTLB-0, - * entry 15. + * entry 15 (and maybe 14 too). */ sethi %hi(KERNBASE), %g3 set (0 << 16) | (15 << 3), %g7 @@ -215,6 +215,27 @@ cheetah_got_tlbentry: membar #Sync flush %g3 membar #Sync + sethi %hi(_end), %g3 /* Check for bigkernel case */ + or %g3, %lo(_end), %g3 + srl %g3, 23, %g3 /* Check if _end > 8M */ + brz,pt %g3, 2f + sethi %hi(0x400000), %g3 + or %g3, %lo(0x400000), %g3 + add %g5, %g3, %g5 /* New tte data */ + andn %g5, (_PAGE_G), %g5 + sethi %hi(KERNBASE+0x400000), %g3 + or %g3, %lo(KERNBASE+0x400000), %g3 + set (0 << 16) | (14 << 3), %g7 + stxa %g3, [%l7] ASI_DMMU + membar #Sync + stxa %g5, [%g7] ASI_DTLB_DATA_ACCESS + membar #Sync + stxa %g3, [%l7] ASI_IMMU + membar #Sync + stxa %g5, [%g7] ASI_ITLB_DATA_ACCESS + membar #Sync + flush %g3 + membar #Sync ba,pt %xcc, 1f nop @@ -345,7 +366,7 @@ spitfire_got_tlbentry: /* PROM never puts any TLB entries into the MMU with the lock bit - * set. So we gladly use tlb entry 63 for KERNBASE. + * set. So we gladly use tlb entry 63 for KERNBASE. And maybe 62 too. */ sethi %hi(KERNBASE), %g3 @@ -358,7 +379,31 @@ spitfire_got_tlbentry: membar #Sync flush %g3 membar #Sync - ba,pt %xcc, 1f + sethi %hi(_end), %g3 /* Check for bigkernel case */ + or %g3, %lo(_end), %g3 + srl %g3, 23, %g3 /* Check if _end > 8M */ + brz,pt %g3, 2f + sethi %hi(0x400000), %g3 + or %g3, %lo(0x400000), %g3 + add %g5, %g3, %g5 /* New tte data */ + andn %g5, (_PAGE_G), %g5 + sethi %hi(KERNBASE+0x400000), %g3 + or %g3, %lo(KERNBASE+0x400000), %g3 + mov ((SPITFIRE_HIGHEST_LOCKED_TLBENT-1) << 3), %g7 + stxa %g3, [%l7] ASI_DMMU + stxa %g5, [%g7] ASI_DTLB_DATA_ACCESS + membar #Sync + stxa %g3, [%l7] ASI_IMMU + stxa %g5, [%g7] ASI_ITLB_DATA_ACCESS + membar #Sync + flush %g3 + membar #Sync + sethi %hi(KERNBASE), %g3 /* Restore for fixup code below */ + stxa %g3, [%l7] ASI_DMMU + stxa %g3, [%l7] ASI_IMMU + flush %g3 + membar #Sync +2: ba,pt %xcc, 1f nop 1: set sun4u_init, %g2 diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index 97af544e7..971bc1b8e 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -137,6 +137,15 @@ void __init smp_callin(void) { int cpuid = hard_smp_processor_id(); unsigned long pstate; + extern int bigkernel; + extern unsigned long kern_locked_tte_data; + + if (bigkernel) { + prom_dtlb_load(sparc64_highest_locked_tlbent()-1, + kern_locked_tte_data + 0x400000, KERNBASE + 0x400000); + prom_itlb_load(sparc64_highest_locked_tlbent()-1, + kern_locked_tte_data + 0x400000, KERNBASE + 0x400000); + } inherit_locked_prom_mappings(0); diff --git a/arch/sparc64/lib/blockops.S b/arch/sparc64/lib/blockops.S index a72f48d05..fdf8eb3df 100644 --- a/arch/sparc64/lib/blockops.S +++ b/arch/sparc64/lib/blockops.S @@ -1,4 +1,4 @@ -/* $Id: blockops.S,v 1.38 2001-11-30 01:04:10 davem Exp $ +/* $Id: blockops.S,v 1.39 2001-11-30 06:40:24 davem Exp $ * blockops.S: UltraSparc block zero optimized routines. * * Copyright (C) 1996, 1998, 1999, 2000 David S. Miller (davem@redhat.com) @@ -17,10 +17,10 @@ fmovd %reg4, %f56; fmovd %reg5, %f58; \ fmovd %reg6, %f60; fmovd %reg7, %f62; -#define TLBTEMP_BASE (8 * 1024 * 1024) +#define TLBTEMP_BASE (16 * 1024 * 1024) #define DCACHE_SIZE (PAGE_SIZE * 2) -#define TLBTEMP_ENT1 (61 << 3) -#define TLBTEMP_ENT2 (62 << 3) +#define TLBTEMP_ENT1 (60 << 3) +#define TLBTEMP_ENT2 (61 << 3) #define TLBTEMP_ENTSZ (1 << 3) #if (PAGE_SHIFT == 13) || (PAGE_SHIFT == 19) @@ -52,7 +52,7 @@ copy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */ or %g2, %g3, %g2 add %o0, %o3, %o0 add %o0, %o1, %o1 -#define FIX_INSN_1 0x96102068 /* mov (13 << 3), %o3 */ +#define FIX_INSN_1 0x96102060 /* mov (12 << 3), %o3 */ cheetah_patch_1: mov TLBTEMP_ENT1, %o3 rdpr %pstate, %g3 @@ -345,7 +345,7 @@ clear_user_page: /* %o0=dest, %o1=vaddr */ or %g3, (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W), %g3 or %g1, %g3, %g1 add %o0, %o3, %o0 -#define FIX_INSN_2 0x96102070 /* mov (14 << 3), %o3 */ +#define FIX_INSN_2 0x96102068 /* mov (13 << 3), %o3 */ cheetah_patch_2: mov TLBTEMP_ENT2, %o3 rdpr %pstate, %g3 diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index c91ec472b..f5b092537 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.205 2001-11-19 19:03:08 davem Exp $ +/* $Id: init.c,v 1.206 2001-11-30 06:40:24 davem Exp $ * arch/sparc64/mm/init.c * * Copyright (C) 1996-1999 David S. Miller (davem@caip.rutgers.edu) @@ -63,6 +63,8 @@ extern unsigned int sparc_ramdisk_size; struct page *mem_map_zero; +int bigkernel = 0; + int do_check_pgt_cache(int low, int high) { int freed = 0; @@ -505,6 +507,10 @@ static void inherit_prom_mappings(void) (unsigned long) KERNBASE, prom_get_mmu_ihandle()); + if (bigkernel) + remap_func(((tte_data + 0x400000) & _PAGE_PADDR), + (unsigned long) KERNBASE + 0x400000, prom_get_mmu_ihandle()); + /* Flush out that temporary mapping. */ spitfire_flush_dtlb_nucleus_page(0x0); spitfire_flush_itlb_nucleus_page(0x0); @@ -512,6 +518,12 @@ static void inherit_prom_mappings(void) /* Now lock us back into the TLBs via OBP. */ prom_dtlb_load(sparc64_highest_locked_tlbent(), tte_data, tte_vaddr); prom_itlb_load(sparc64_highest_locked_tlbent(), tte_data, tte_vaddr); + if (bigkernel) { + prom_dtlb_load(sparc64_highest_locked_tlbent()-1, tte_data + 0x400000, + tte_vaddr + 0x400000); + prom_itlb_load(sparc64_highest_locked_tlbent()-1, tte_data + 0x400000, + tte_vaddr + 0x400000); + } /* Re-read translations property. */ if ((n = prom_getproperty(node, "translations", (char *)trans, tsz)) == -1) { @@ -528,6 +540,8 @@ static void inherit_prom_mappings(void) unsigned long avoid_start = (unsigned long) KERNBASE; unsigned long avoid_end = avoid_start + (4 * 1024 * 1024); + if (bigkernel) + avoid_end += (4 * 1024 * 1024); if (vaddr < avoid_start) { unsigned long top = vaddr + size; @@ -714,7 +728,8 @@ void inherit_locked_prom_mappings(int save_p) } } if (tlb_type == spitfire) { - for (i = 0; i < SPITFIRE_HIGHEST_LOCKED_TLBENT; i++) { + int high = SPITFIRE_HIGHEST_LOCKED_TLBENT - bigkernel; + for (i = 0; i < high; i++) { unsigned long data; /* Spitfire Errata #32 workaround */ @@ -752,7 +767,7 @@ void inherit_locked_prom_mappings(int save_p) } } - for (i = 0; i < SPITFIRE_HIGHEST_LOCKED_TLBENT; i++) { + for (i = 0; i < high; i++) { unsigned long data; /* Spitfire Errata #32 workaround */ @@ -790,7 +805,9 @@ void inherit_locked_prom_mappings(int save_p) } } } else if (tlb_type == cheetah) { - for (i = 0; i < CHEETAH_HIGHEST_LOCKED_TLBENT; i++) { + int high = CHEETAH_HIGHEST_LOCKED_TLBENT - bigkernel; + + for (i = 0; i < high; i++) { unsigned long data; data = cheetah_get_ldtlb_data(i); @@ -814,7 +831,7 @@ void inherit_locked_prom_mappings(int save_p) } } - for (i = 0; i < CHEETAH_HIGHEST_LOCKED_TLBENT; i++) { + for (i = 0; i < high; i++) { unsigned long data; data = cheetah_get_litlb_data(i); @@ -1282,6 +1299,8 @@ void __init paging_init(void) set_bit(0, mmu_context_bmap); real_end = (unsigned long)&_end; + if ((real_end > ((unsigned long)KERNBASE + 0x400000)) && (tlb_type == spitfire)) + bigkernel = 1; #ifdef CONFIG_BLK_DEV_INITRD if (sparc_ramdisk_image) real_end = (PAGE_ALIGN(real_end) + PAGE_ALIGN(sparc_ramdisk_size)); |