linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH][RFT] Extended BAT features, take 2
@ 2005-10-22 13:54 Rupert Eibauer
  2005-10-23  0:39 ` Paul Mackerras
  0 siblings, 1 reply; 6+ messages in thread
From: Rupert Eibauer @ 2005-10-22 13:54 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev

Hello,

Here is the updated patch. Please test.

What this patch actually does:
- Make CONFIG_PHYS_64BIT selectable for the 6xx family
- Make the BATs use 36-Bit addressing and use large BATs
  when available on the processor.
- Make use of the 4 additional BATs on some processors.

Changes to the old patch:
- Removed all additional configuration options
- Merged LARGE_BATS with PHYS_64BIT because there seems to be no processor 
  supporting only one of these features (I am not sure about the e500v2, 
  but maybe somebody else is sure)

Rupert

diff -urN linux-2.6.13.3.orig/arch/ppc/Kconfig linux-2.6.13.3/arch/ppc/Kconfig
--- linux-2.6.13.3.orig/arch/ppc/Kconfig	Fri Oct 21 05:42:59 2005
+++ linux-2.6.13.3/arch/ppc/Kconfig	Fri Oct 21 21:05:09 2005
@@ -115,8 +115,8 @@
 	default y if E500 && PHYS_64BIT
 
 config PHYS_64BIT
-	bool 'Large physical address support' if E500
-	depends on 44x || E500
+	bool 'Large physical address support' if E500 || 6xx
+	depends on 44x || E500 || 6xx
 	default y if 44x
 	---help---
 	  This option enables kernel support for larger than 32-bit physical
diff -urN linux-2.6.13.3.orig/arch/ppc/kernel/cpu_setup_6xx.S linux-2.6.13.3/arch/ppc/kernel/cpu_setup_6xx.S
--- linux-2.6.13.3.orig/arch/ppc/kernel/cpu_setup_6xx.S	Fri Oct 21 05:49:53 2005
+++ linux-2.6.13.3/arch/ppc/kernel/cpu_setup_6xx.S	Fri Oct 21 21:07:06 2005
@@ -228,14 +228,18 @@
 	/* All of the bits we have to set.....
 	 */
 	ori	r11,r11,HID0_SGE | HID0_FOLD | HID0_BHTE
-	ori	r11,r11,HID0_LRSTK | HID0_BTIC
-	oris	r11,r11,HID0_DPM@h
+	ori	r11,r11,HID0_LRSTK | HID0_BTIC | HID0_XBSEN
+	oris	r11,r11,(HID0_DPM | HID0_XAEN)@h
 BEGIN_FTR_SECTION
 	xori	r11,r11,HID0_BTIC
 END_FTR_SECTION_IFSET(CPU_FTR_NO_BTIC)
 BEGIN_FTR_SECTION
 	xoris	r11,r11,HID0_DPM@h	/* disable dynamic power mgmt */
 END_FTR_SECTION_IFSET(CPU_FTR_NO_DPM)
+BEGIN_FTR_SECTION
+	xori	r11,r11,HID0_XBSEN
+	xoris	r11,r11,HID0_XAEN@h
+END_FTR_SECTION_IFCLR(CPU_FTR_BIG_PHYS)
 
 	/* All of the bits we have to clear....
 	 */
diff -urN linux-2.6.13.3.orig/arch/ppc/kernel/cputable.c linux-2.6.13.3/arch/ppc/kernel/cputable.c
--- linux-2.6.13.3.orig/arch/ppc/kernel/cputable.c	Fri Oct 21 05:49:53 2005
+++ linux-2.6.13.3/arch/ppc/kernel/cputable.c	Fri Oct 21 21:11:55 2005
@@ -62,6 +62,12 @@
 #define PPC_FEATURE_SPE_COMP       	0
 #endif
 
+#ifndef CONFIG_PHYS_64BIT
+#define CPU_FTR_BIG_PHYS_COMP		CPU_FTR_BIG_PHYS
+#else
+#define CPU_FTR_BIG_PHYS_COMP		0
+#endif
+
 /* We need to mark all pages as being coherent if we're SMP or we
  * have a 74[45]x and an MPC107 host bridge.
  */
@@ -428,6 +434,7 @@
 			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
 			CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
 			CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
+			CPU_FTR_BIG_PHYS_COMP |
 			CPU_FTR_HAS_HIGH_BATS | CPU_FTR_NEED_COHERENT,
 		.cpu_user_features	= COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
 		.icache_bsize		= 32,
@@ -445,6 +452,7 @@
 			CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
 			CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
 			CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_L3_DISABLE_NAP |
+			CPU_FTR_BIG_PHYS_COMP |
 			CPU_FTR_NEED_COHERENT | CPU_FTR_HAS_HIGH_BATS,
 		.cpu_user_features	= COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
 		.icache_bsize		= 32,
@@ -462,6 +470,7 @@
 			CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
 			CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
 			CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS |
+			CPU_FTR_BIG_PHYS_COMP |
 			CPU_FTR_NEED_COHERENT,
 		.cpu_user_features	= COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
 		.icache_bsize		= 32,
@@ -478,6 +487,7 @@
 			CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR |
 			CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
 			CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
+			CPU_FTR_BIG_PHYS_COMP |
 			CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS |
 			CPU_FTR_NEED_COHERENT | CPU_FTR_NO_BTIC,
 		.cpu_user_features	= COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
@@ -496,6 +506,7 @@
 			CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
 			CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
 			CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS |
+			CPU_FTR_BIG_PHYS_COMP |
 			CPU_FTR_NEED_COHERENT | CPU_FTR_NO_BTIC,
 		.cpu_user_features	= COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
 		.icache_bsize		= 32,
@@ -513,6 +524,7 @@
 			CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
 			CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 |
 			CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS |
+			CPU_FTR_BIG_PHYS_COMP |
 			CPU_FTR_NEED_COHERENT,
 		.cpu_user_features	= COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
 		.icache_bsize		= 32,
@@ -529,6 +541,7 @@
 			CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR |
 			CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE |
 			CPU_FTR_SPEC7450 | CPU_FTR_NAP_DISABLE_L2_PR |
+			CPU_FTR_BIG_PHYS_COMP |
 			CPU_FTR_HAS_HIGH_BATS | CPU_FTR_NEED_COHERENT,
 		.cpu_user_features	= COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
 		.icache_bsize		= 32,
diff -urN linux-2.6.13.3.orig/arch/ppc/kernel/head.S linux-2.6.13.3/arch/ppc/kernel/head.S
--- linux-2.6.13.3.orig/arch/ppc/kernel/head.S	Fri Oct 21 05:49:53 2005
+++ linux-2.6.13.3/arch/ppc/kernel/head.S	Fri Oct 21 21:12:17 2005
@@ -1165,6 +1165,12 @@
 	LOAD_BAT(1,r3,r4,r5)
 	LOAD_BAT(2,r3,r4,r5)
 	LOAD_BAT(3,r3,r4,r5)
+BEGIN_FTR_SECTION
+	LOAD_BAT(4,r3,r4,r5)
+	LOAD_BAT(5,r3,r4,r5)
+	LOAD_BAT(6,r3,r4,r5)
+	LOAD_BAT(7,r3,r4,r5)
+END_FTR_SECTION_IFSET(CPU_FTR_HAS_HIGH_BATS)
 #endif /* CONFIG_POWER4 */
 	blr
 
diff -urN linux-2.6.13.3.orig/arch/ppc/mm/pgtable.c linux-2.6.13.3/arch/ppc/mm/pgtable.c
--- linux-2.6.13.3.orig/arch/ppc/mm/pgtable.c	Fri Oct 21 05:49:53 2005
+++ linux-2.6.13.3/arch/ppc/mm/pgtable.c	Fri Oct 21 05:53:49 2005
@@ -55,8 +55,8 @@
 
 #ifdef HAVE_BATS
 extern unsigned long v_mapped_by_bats(unsigned long va);
-extern unsigned long p_mapped_by_bats(unsigned long pa);
-void setbat(int index, unsigned long virt, unsigned long phys,
+extern unsigned long p_mapped_by_bats(phys_addr_t pa);
+void setbat(int index, unsigned long virt, phys_addr_t phys,
 	    unsigned int size, int flags);
 
 #else /* !HAVE_BATS */
@@ -339,7 +339,7 @@
 	/*
 	 * Use a BAT for this if possible...
 	 */
-	if (io_bat_index < 2 && is_power_of_2(size)
+	if (io_bat_index < (ppc_bat_count() - 2) && is_power_of_2(size)
 	    && (virt & (size - 1)) == 0 && (phys & (size - 1)) == 0) {
 		setbat(io_bat_index, virt, phys, size, flags);
 		++io_bat_index;
diff -urN linux-2.6.13.3.orig/arch/ppc/mm/ppc_mmu.c linux-2.6.13.3/arch/ppc/mm/ppc_mmu.c
--- linux-2.6.13.3.orig/arch/ppc/mm/ppc_mmu.c	Fri Oct 21 05:49:53 2005
+++ linux-2.6.13.3/arch/ppc/mm/ppc_mmu.c	Fri Oct 21 21:15:07 2005
@@ -47,13 +47,13 @@
 #else
 	u32	word[2];
 #endif
-} BATS[4][2];			/* 4 pairs of IBAT, DBAT */
+} BATS[8][2];			/* 8 pairs of IBAT, DBAT */
 
 struct batrange {		/* stores address ranges mapped by BATs */
 	unsigned long start;
 	unsigned long limit;
-	unsigned long phys;
-} bat_addrs[4];
+	phys_addr_t phys;
+} bat_addrs[8];
 
 /*
  * Return PA for this VA if it is mapped by a BAT, or 0
@@ -70,7 +70,7 @@
 /*
  * Return VA for a given PA or 0 if not mapped
  */
-unsigned long p_mapped_by_bats(unsigned long pa)
+unsigned long p_mapped_by_bats(phys_addr_t pa)
 {
 	int b;
 	for (b = 0; b < 4; ++b)
@@ -87,13 +87,14 @@
 	return 0;
 #else
 	unsigned long tot, bl, done;
-	unsigned long max_size = (256<<20);
+	unsigned long max_size = ppc_max_bat_size();
 	unsigned long align;
+	int bat_nbr = ppc_bat_count() - 2;
 
 	if (__map_without_bats)
 		return 0;
 
-	/* Set up BAT2 and if necessary BAT3 to cover RAM. */
+	/* Set up BAT[2|6] and if necessary BAT[3|7] to cover RAM. */
 
 	/* Make sure we don't map a block larger than the
 	   smallest alignment of the physical address. */
@@ -109,16 +110,17 @@
 			break;
 	}
 
-	setbat(2, KERNELBASE, PPC_MEMSTART, bl, _PAGE_RAM);
-	done = (unsigned long)bat_addrs[2].limit - KERNELBASE + 1;
-	if ((done < tot) && !bat_addrs[3].limit) {
-		/* use BAT3 to cover a bit more */
+	setbat(bat_nbr, KERNELBASE, PPC_MEMSTART, bl, _PAGE_RAM);
+	done = (unsigned long)bat_addrs[bat_nbr].limit - KERNELBASE + 1;
+	bat_nbr++;
+	if ((done < tot) && !bat_addrs[bat_nbr].limit) {
+		/* use BAT[3|7] to cover a bit more */
 		tot -= done;
 		for (bl = 128<<10; bl < max_size; bl <<= 1)
 			if (bl * 2 > tot)
 				break;
-		setbat(3, KERNELBASE+done, PPC_MEMSTART+done, bl, _PAGE_RAM);
-		done = (unsigned long)bat_addrs[3].limit - KERNELBASE + 1;
+		setbat(bat_nbr, KERNELBASE+done, PPC_MEMSTART+done, bl, _PAGE_RAM);
+		done = (unsigned long)bat_addrs[bat_nbr].limit - KERNELBASE + 1;
 	}
 
 	return done;
@@ -130,7 +132,7 @@
  * The parameters are not checked; in particular size must be a power
  * of 2 between 128k and 256M.
  */
-void __init setbat(int index, unsigned long virt, unsigned long phys,
+void __init setbat(int index, unsigned long virt, phys_addr_t phys,
 		   unsigned int size, int flags)
 {
 	unsigned int bl;
@@ -148,6 +150,9 @@
 		wimgxpp = flags & (_PAGE_WRITETHRU | _PAGE_NO_CACHE
 				   | _PAGE_COHERENT | _PAGE_GUARDED);
 		wimgxpp |= (flags & _PAGE_RW)? BPP_RW: BPP_RX;
+#ifdef CONFIG_PHYS_64BIT
+		wimgxpp |= ((phys >> 30) & 4) | ((phys >> 24) & 0xe00);
+#endif
 		bat[1].word[0] = virt | (bl << 2) | 2; /* Vs=1, Vp=0 */
 		bat[1].word[1] = phys | wimgxpp;
 #ifndef CONFIG_KGDB /* want user access for breakpoints */
diff -urN linux-2.6.13.3.orig/include/asm-ppc/mmu.h linux-2.6.13.3/include/asm-ppc/mmu.h
--- linux-2.6.13.3.orig/include/asm-ppc/mmu.h	Fri Oct 21 05:44:49 2005
+++ linux-2.6.13.3/include/asm-ppc/mmu.h	Fri Oct 21 21:23:55 2005
@@ -18,11 +18,19 @@
 #ifndef CONFIG_PHYS_64BIT
 typedef unsigned long phys_addr_t;
 #define PHYS_FMT	"%.8lx"
+#define cpu_has_bigphys() 0
+#define ppc_max_bat_size() (256<<20)
 #else
 typedef unsigned long long phys_addr_t;
 extern phys_addr_t fixup_bigphys_addr(phys_addr_t, phys_addr_t);
 #define PHYS_FMT	"%16Lx"
+#define cpu_has_bigphys() cpu_has_feature(CPU_FTR_BIG_PHYS)
+/* We don't allow 4G Bat's because it doesn't fit into size_t */
+#define ppc_max_bat_size() \
+	(cpu_has_feature(CPU_FTR_BIG_PHYS)?(2<<30):(256<<20))
 #endif
+
+#define ppc_bat_count() (cpu_has_feature(CPU_FTR_HAS_HIGH_BATS) ? 8 : 4)
 
 /* Default "unsigned long" context */
 typedef unsigned long mm_context_t;

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH][RFT] Extended BAT features, take 2
  2005-10-22 13:54 [PATCH][RFT] Extended BAT features, take 2 Rupert Eibauer
@ 2005-10-23  0:39 ` Paul Mackerras
  2005-10-23  9:36   ` Rupert Eibauer
  0 siblings, 1 reply; 6+ messages in thread
From: Paul Mackerras @ 2005-10-23  0:39 UTC (permalink / raw)
  To: Rupert Eibauer; +Cc: linuxppc-dev

Rupert Eibauer writes:

> What this patch actually does:
> - Make CONFIG_PHYS_64BIT selectable for the 6xx family

Why?  What does this gain us?  We still can't use RAM above the 4GB
point AFAICS.

Paul.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH][RFT] Extended BAT features, take 2
  2005-10-23  0:39 ` Paul Mackerras
@ 2005-10-23  9:36   ` Rupert Eibauer
  2005-10-23  9:55     ` Benjamin Herrenschmidt
  0 siblings, 1 reply; 6+ messages in thread
From: Rupert Eibauer @ 2005-10-23  9:36 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev

On Sunday 23 October 2005 02:39, Paul Mackerras wrote:
> Rupert Eibauer writes:
> 
> > What this patch actually does:
> > - Make CONFIG_PHYS_64BIT selectable for the 6xx family
> 
> Why?  What does this gain us?  

I have I/O resources there which are not reachable in 32 bit mode.

> We still can't use RAM above the 4GB point AFAICS.

Does this mean the page tables do not support 63 bit?

Rupert

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH][RFT] Extended BAT features, take 2
  2005-10-23  9:36   ` Rupert Eibauer
@ 2005-10-23  9:55     ` Benjamin Herrenschmidt
  2005-10-23 11:03       ` Rupert Eibauer
  2005-10-23 13:27       ` Rupert Eibauer
  0 siblings, 2 replies; 6+ messages in thread
From: Benjamin Herrenschmidt @ 2005-10-23  9:55 UTC (permalink / raw)
  To: Rupert Eibauer; +Cc: linuxppc-dev

On Sun, 2005-10-23 at 11:36 +0200, Rupert Eibauer wrote:
> On Sunday 23 October 2005 02:39, Paul Mackerras wrote:
> > Rupert Eibauer writes:
> > 
> > > What this patch actually does:
> > > - Make CONFIG_PHYS_64BIT selectable for the 6xx family
> > 
> > Why?  What does this gain us?  
> 
> I have I/O resources there which are not reachable in 32 bit mode.
> 
> > We still can't use RAM above the 4GB point AFAICS.
> 
> Does this mean the page tables do not support 63 bit?

Not with the current code. At least not for those CPUs.

Ben.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH][RFT] Extended BAT features, take 2
  2005-10-23  9:55     ` Benjamin Herrenschmidt
@ 2005-10-23 11:03       ` Rupert Eibauer
  2005-10-23 13:27       ` Rupert Eibauer
  1 sibling, 0 replies; 6+ messages in thread
From: Rupert Eibauer @ 2005-10-23 11:03 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev

On Sunday 23 October 2005 11:55, Benjamin Herrenschmidt wrote:
> On Sun, 2005-10-23 at 11:36 +0200, Rupert Eibauer wrote:
> > On Sunday 23 October 2005 02:39, Paul Mackerras wrote:
> > > Rupert Eibauer writes:
> > > 
> > > > What this patch actually does:
> > > > - Make CONFIG_PHYS_64BIT selectable for the 6xx family
> > > 
> > > Why?  What does this gain us?  
> > 
> > I have I/O resources there which are not reachable in 32 bit mode.
> > 
> > > We still can't use RAM above the 4GB point AFAICS.
> > 
> > Does this mean the page tables do not support 63 bit?
> 
> Not with the current code. At least not for those CPUs.

I meant 36 bit, but I think you have guessed correctly what I mean.
CONFIG_PHYS_64BIT should really be named CONFIG_PHYS_36BIT.

I have put some more effort into understanding how the page tables work,
and came to the following patch. Maybe this addition makes my previous
patch more attractive to Paul.

Correctness not guaranted, I cannot test it on my hardware.

Rupert

--- pgtable.h.orig	Sun Oct 23 12:18:18 2005
+++ pgtable.h	Sun Oct 23 12:36:55 2005
@@ -446,11 +446,23 @@
 #define PFN_SHIFT_OFFSET	(PAGE_SHIFT)
 #endif
 
-#define pte_pfn(x)		(pte_val(x) >> PFN_SHIFT_OFFSET)
+#if !defined(CONFIG_PTE_64BIT) && defined(CONFIG_PHYS_64BIT)
+#define pfn_36bit_pte_bits(pfn)		((pfn >> (32 - 2 - PAGE_SHIFT) & 4) |\
+					((pfn >> (33 - 9 - PAGE_SHIFT)) & 0xe00))
+
+#define pte_36bit_pfn_bits(pte_val)	((((pte) & 4) << (32 - 2 - PAGE_SHIFT) |\
+					(((pte) & 0xe00) << (33 - 9 - PAGE_SHIFT))
+#else
+#define pfn_36bit_pte_bits(pfn)		0
+#define pte_36bit_pfn_bits(pte_val)	0
+#endif
+
+#define pte_pfn(x)		((pte_val(x) >> PFN_SHIFT_OFFSET) | \
+					((get_highbits_36(pte_val(x))) << (32 - PAGE_SHIFT)))
 #define pte_page(x)		pfn_to_page(pte_pfn(x))
 
 #define pfn_pte(pfn, prot)	__pte(((pte_basic_t)(pfn) << PFN_SHIFT_OFFSET) |\
-					pgprot_val(prot))
+					pgprot_val(prot) | pfn_36bit_pte_bits(pfn))
 #define mk_pte(page, prot)	pfn_pte(page_to_pfn(page), prot)
 
 /*

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH][RFT] Extended BAT features, take 2
  2005-10-23  9:55     ` Benjamin Herrenschmidt
  2005-10-23 11:03       ` Rupert Eibauer
@ 2005-10-23 13:27       ` Rupert Eibauer
  1 sibling, 0 replies; 6+ messages in thread
From: Rupert Eibauer @ 2005-10-23 13:27 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev

Please don't test my last patch, it will breaks some page table code.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2005-10-23 13:12 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-10-22 13:54 [PATCH][RFT] Extended BAT features, take 2 Rupert Eibauer
2005-10-23  0:39 ` Paul Mackerras
2005-10-23  9:36   ` Rupert Eibauer
2005-10-23  9:55     ` Benjamin Herrenschmidt
2005-10-23 11:03       ` Rupert Eibauer
2005-10-23 13:27       ` Rupert Eibauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).