* [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).