aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordavem <davem>2001-11-30 06:40:24 +0000
committerdavem <davem>2001-11-30 06:40:24 +0000
commit504bada32c1809f35bdd14e0c25235616a35d871 (patch)
treecd74e2228d7e032d397545b9c13363b930e67d2a
parent8e92b6c1034b1e498670cd23c44341411c57e714 (diff)
downloadnetdev-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.S53
-rw-r--r--arch/sparc64/kernel/smp.c9
-rw-r--r--arch/sparc64/lib/blockops.S12
-rw-r--r--arch/sparc64/mm/init.c29
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));