* [PATCH 4/5] powerpc/book3e-64: Add helper function to setup IVORs
From: Kumar Gala @ 2009-08-19 5:08 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev
In-Reply-To: <1250658513-13009-3-git-send-email-galak@kernel.crashing.org>
Not all 64-bit Book-3E parts will have fixed IVORs so add a function that
cpusetup code can call to setup the base IVORs (0..15) to match the fixed
offsets. We need to 'or' part of interrupt_base_book3e into the IVORs
since on parts that have them the IVPR doesn't extend as far down.
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
arch/powerpc/include/asm/exception-64e.h | 4 ++++
arch/powerpc/kernel/exceptions-64e.S | 19 +++++++++++++++++++
2 files changed, 23 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/include/asm/exception-64e.h b/arch/powerpc/include/asm/exception-64e.h
index 94cb3d7..6d53f31 100644
--- a/arch/powerpc/include/asm/exception-64e.h
+++ b/arch/powerpc/include/asm/exception-64e.h
@@ -196,6 +196,10 @@ exc_##label##_book3e:
#define TLB_MISS_STATS_SAVE_INFO
#endif
+#define SET_IVOR(vector_number, vector_offset) \
+ li r3,vector_offset@l; \
+ ori r3,r3,interrupt_base_book3e@l; \
+ mtspr SPRN_IVOR##vector_number,r3;
#endif /* _ASM_POWERPC_EXCEPTION_64E_H */
diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S
index 3611b0e..662236c 100644
--- a/arch/powerpc/kernel/exceptions-64e.S
+++ b/arch/powerpc/kernel/exceptions-64e.S
@@ -782,5 +782,24 @@ _STATIC(init_thread_book3e)
blr
+_GLOBAL(__setup_base_ivors)
+ SET_IVOR(0, 0x020) /* Critical Input */
+ SET_IVOR(1, 0x000) /* Machine Check */
+ SET_IVOR(2, 0x060) /* Data Storage */
+ SET_IVOR(3, 0x080) /* Instruction Storage */
+ SET_IVOR(4, 0x0a0) /* External Input */
+ SET_IVOR(5, 0x0c0) /* Alignment */
+ SET_IVOR(6, 0x0e0) /* Program */
+ SET_IVOR(7, 0x100) /* FP Unavailable */
+ SET_IVOR(8, 0x120) /* System Call */
+ SET_IVOR(9, 0x140) /* Auxiliary Processor Unavailable */
+ SET_IVOR(10, 0x160) /* Decrementer */
+ SET_IVOR(11, 0x180) /* Fixed Interval Timer */
+ SET_IVOR(12, 0x1a0) /* Watchdog Timer */
+ SET_IVOR(13, 0x1c0) /* Data TLB Error */
+ SET_IVOR(14, 0x1e0) /* Instruction TLB Error */
+ SET_IVOR(15, 0x040) /* Debug */
+ sync
+ blr
--
1.6.0.6
^ permalink raw reply related
* [PATCH 2/5] powerpc/book3e-64: Move the default cpu table entry
From: Kumar Gala @ 2009-08-19 5:08 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev
In-Reply-To: <1250658513-13009-1-git-send-email-galak@kernel.crashing.org>
Move the default cpu entry table for CONFIG_PPC_BOOK3E_64 to the
very end since we will probably want to support both 32-bit and
64-bit kernels for some processors that are higher up in the list.
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
arch/powerpc/kernel/cputable.c | 49 ++++++++++++++++++++++------------------
1 files changed, 27 insertions(+), 22 deletions(-)
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 9f38ecb..0b9c913 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -89,8 +89,12 @@ extern void __restore_cpu_power7(void);
#define COMMON_USER_PA6T (COMMON_USER_PPC64 | PPC_FEATURE_PA6T |\
PPC_FEATURE_TRUE_LE | \
PPC_FEATURE_HAS_ALTIVEC_COMP)
+#ifdef CONFIG_PPC_BOOK3E_64
+#define COMMON_USER_BOOKE (COMMON_USER_PPC64 | PPC_FEATURE_BOOKE)
+#else
#define COMMON_USER_BOOKE (PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \
PPC_FEATURE_BOOKE)
+#endif
static struct cpu_spec __initdata cpu_specs[] = {
#ifdef CONFIG_PPC_BOOK3S_64
@@ -509,28 +513,6 @@ static struct cpu_spec __initdata cpu_specs[] = {
.platform = "power4",
}
#endif /* CONFIG_PPC_BOOK3S_64 */
-#ifdef CONFIG_PPC_BOOK3E_64
- { /* This is a default entry to get going, to be replaced by
- * a real one at some stage
- */
-#define CPU_FTRS_BASE_BOOK3E (CPU_FTR_USE_TB | \
- CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_SMT | \
- CPU_FTR_NODSISRALIGN | CPU_FTR_NOEXECUTE)
- .pvr_mask = 0x00000000,
- .pvr_value = 0x00000000,
- .cpu_name = "Book3E",
- .cpu_features = CPU_FTRS_BASE_BOOK3E,
- .cpu_user_features = COMMON_USER_PPC64,
- .mmu_features = MMU_FTR_TYPE_3E | MMU_FTR_USE_TLBILX |
- MMU_FTR_USE_TLBIVAX_BCAST |
- MMU_FTR_LOCK_BCAST_INVAL,
- .icache_bsize = 64,
- .dcache_bsize = 64,
- .num_pmcs = 0,
- .machine_check = machine_check_generic,
- .platform = "power6",
- },
-#endif
#ifdef CONFIG_PPC32
#if CLASSIC_PPC
@@ -1846,6 +1828,29 @@ static struct cpu_spec __initdata cpu_specs[] = {
}
#endif /* CONFIG_E500 */
#endif /* CONFIG_PPC32 */
+
+#ifdef CONFIG_PPC_BOOK3E_64
+ { /* This is a default entry to get going, to be replaced by
+ * a real one at some stage
+ */
+#define CPU_FTRS_BASE_BOOK3E (CPU_FTR_USE_TB | \
+ CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_SMT | \
+ CPU_FTR_NODSISRALIGN | CPU_FTR_NOEXECUTE)
+ .pvr_mask = 0x00000000,
+ .pvr_value = 0x00000000,
+ .cpu_name = "Book3E",
+ .cpu_features = CPU_FTRS_BASE_BOOK3E,
+ .cpu_user_features = COMMON_USER_PPC64,
+ .mmu_features = MMU_FTR_TYPE_3E | MMU_FTR_USE_TLBILX |
+ MMU_FTR_USE_TLBIVAX_BCAST |
+ MMU_FTR_LOCK_BCAST_INVAL,
+ .icache_bsize = 64,
+ .dcache_bsize = 64,
+ .num_pmcs = 0,
+ .machine_check = machine_check_generic,
+ .platform = "power6",
+ },
+#endif
};
static struct cpu_spec the_cpu_spec;
--
1.6.0.6
^ permalink raw reply related
* [PATCH 3/5] powerpc/book3e-64: Wait til generic_calibrate_decr to enable decrementer
From: Kumar Gala @ 2009-08-19 5:08 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev
In-Reply-To: <1250658513-13009-2-git-send-email-galak@kernel.crashing.org>
Match what we do on 32-bit Book-E processors and enable the decrementer
in generic_calibrate_decr. We need to make sure we disable the
decrementer early in boot since we currently use lazy (soft) interrupt
on 64-bit Book-E and possible get a decrementer exception before we
are ready for it.
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
arch/powerpc/kernel/exceptions-64e.S | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S
index 695d484..3611b0e 100644
--- a/arch/powerpc/kernel/exceptions-64e.S
+++ b/arch/powerpc/kernel/exceptions-64e.S
@@ -774,9 +774,11 @@ _STATIC(init_thread_book3e)
/* Make sure interrupts are off */
wrteei 0
- /* disable watchdog and FIT and enable DEC interrupts */
- lis r3,TCR_DIE@h
+ /* disable all timers and clear out status */
+ li r3,0
mtspr SPRN_TCR,r3
+ mfspr r3,SPRN_TSR
+ mtspr SPRN_TSR,r3
blr
--
1.6.0.6
^ permalink raw reply related
* [PATCH 1/5] powerpc/mm: Add MMU features for TLB reservation & Paired MAS registers
From: Kumar Gala @ 2009-08-19 5:08 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev
Support for TLB reservation (or TLB Write Conditional) and Paired MAS
registers are optional for a processor implementation so we handle
them via MMU feature sections.
We currently only used paired MAS registers to access the full RPN + perm
bits that are kept in MAS7||MAS3. We assume that if an implementation has
hardware page table at this time it also implements in TLB reservations.
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
arch/powerpc/include/asm/mmu.h | 9 +++++++++
arch/powerpc/mm/tlb_low_64e.S | 36 +++++++++++++++++++++++++++++++++++-
2 files changed, 44 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h
index 2fcfefc..7ffbb65 100644
--- a/arch/powerpc/include/asm/mmu.h
+++ b/arch/powerpc/include/asm/mmu.h
@@ -58,6 +58,15 @@
*/
#define MMU_FTR_TLBIE_206 ASM_CONST(0x00400000)
+/* Enable use of TLB reservation. Processor should support tlbsrx.
+ * instruction and MAS0[WQ].
+ */
+#define MMU_FTR_USE_TLBRSRV ASM_CONST(0x00800000)
+
+/* Use paired MAS registers (MAS7||MAS3, etc.)
+ */
+#define MMU_FTR_USE_PAIRED_MAS ASM_CONST(0x01000000)
+
#ifndef __ASSEMBLY__
#include <asm/cputable.h>
diff --git a/arch/powerpc/mm/tlb_low_64e.S b/arch/powerpc/mm/tlb_low_64e.S
index 10d524d..5b8e274 100644
--- a/arch/powerpc/mm/tlb_low_64e.S
+++ b/arch/powerpc/mm/tlb_low_64e.S
@@ -189,12 +189,16 @@ normal_tlb_miss:
clrrdi r14,r14,3
or r10,r15,r14
+BEGIN_MMU_FTR_SECTION
/* Set the TLB reservation and seach for existing entry. Then load
* the entry.
*/
PPC_TLBSRX_DOT(0,r16)
ld r14,0(r10)
beq normal_tlb_miss_done
+MMU_FTR_SECTION_ELSE
+ ld r14,0(r10)
+ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_USE_TLBRSRV)
finish_normal_tlb_miss:
/* Check if required permissions are met */
@@ -241,7 +245,14 @@ finish_normal_tlb_miss:
bne 1f
li r11,MAS3_SW|MAS3_UW
andc r15,r15,r11
-1: mtspr SPRN_MAS7_MAS3,r15
+1:
+BEGIN_MMU_FTR_SECTION
+ srdi r16,r15,32
+ mtspr SPRN_MAS3,r15
+ mtspr SPRN_MAS7,r16
+MMU_FTR_SECTION_ELSE
+ mtspr SPRN_MAS7_MAS3,r15
+ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_USE_PAIRED_MAS)
tlbwe
@@ -311,11 +322,13 @@ virt_page_table_tlb_miss:
rlwinm r10,r10,0,16,1 /* Clear TID */
mtspr SPRN_MAS1,r10
1:
+BEGIN_MMU_FTR_SECTION
/* Search if we already have a TLB entry for that virtual address, and
* if we do, bail out.
*/
PPC_TLBSRX_DOT(0,r16)
beq virt_page_table_tlb_miss_done
+END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_TLBRSRV)
/* Now, we need to walk the page tables. First check if we are in
* range.
@@ -367,7 +380,14 @@ virt_page_table_tlb_miss:
*/
clrldi r11,r15,4 /* remove region ID from RPN */
ori r10,r11,1 /* Or-in SR */
+
+BEGIN_MMU_FTR_SECTION
+ srdi r16,r10,32
+ mtspr SPRN_MAS3,r10
+ mtspr SPRN_MAS7,r16
+MMU_FTR_SECTION_ELSE
mtspr SPRN_MAS7_MAS3,r10
+ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_USE_PAIRED_MAS)
tlbwe
@@ -618,7 +638,14 @@ htw_tlb_miss:
#else
ori r10,r15,(BOOK3E_PAGESZ_4K << MAS3_SPSIZE_SHIFT)
#endif
+
+BEGIN_MMU_FTR_SECTION
+ srdi r16,r10,32
+ mtspr SPRN_MAS3,r10
+ mtspr SPRN_MAS7,r16
+MMU_FTR_SECTION_ELSE
mtspr SPRN_MAS7_MAS3,r10
+ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_USE_PAIRED_MAS)
tlbwe
@@ -700,7 +727,14 @@ tlb_load_linear:
clrrdi r10,r16,30 /* 1G page index */
clrldi r10,r10,4 /* clear region bits */
ori r10,r10,MAS3_SR|MAS3_SW|MAS3_SX
+
+BEGIN_MMU_FTR_SECTION
+ srdi r16,r10,32
+ mtspr SPRN_MAS3,r10
+ mtspr SPRN_MAS7,r16
+MMU_FTR_SECTION_ELSE
mtspr SPRN_MAS7_MAS3,r10
+ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_USE_PAIRED_MAS)
tlbwe
--
1.6.0.6
^ permalink raw reply related
* [PATCH] powerpc/mm: Cleanup handling of execute permission v2
From: Benjamin Herrenschmidt @ 2009-08-19 5:00 UTC (permalink / raw)
To: linuxppc-dev list
This is an attempt at cleaning up a bit the way we handle execute
permission on powerpc. _PAGE_HWEXEC is gone, _PAGE_EXEC is now only
defined by CPUs that can do something with it, and the myriad of
#ifdef's in the I$/D$ coherency code is reduced to 2 cases that
hopefully should cover everything.
The logic on BookE is a little bit different than what it was though
not by much. Since now, _PAGE_EXEC will be set by the generic code
for executable pages, we need to filter out if they are unclean and
recover it. However, I don't expect the code to be more bloated than
it already was in that area due to that change.
I could boast that this brings proper enforcing of per-page execute
permissions to all BookE and 40x but in fact, we've had that now for
some time as a side effect of my previous rework in that area (and
I didn't even know it :-) We would only enable execute permission if
the page was cache clean and we would only cache clean it if we took
and exec fault. Since we now enforce that the later only work if
VM_EXEC is part of the VMA flags, we de-fact already enforce per-page
execute permissions... Unless I missed something
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
This version restores the missing (oops) cache flush in
ptep_set_access_flags() which broke BookE.
diff --git a/arch/powerpc/include/asm/pgtable-ppc32.h b/arch/powerpc/include/asm/pgtable-ppc32.h
index c9ff9d7..f2c52e2 100644
--- a/arch/powerpc/include/asm/pgtable-ppc32.h
+++ b/arch/powerpc/include/asm/pgtable-ppc32.h
@@ -186,7 +186,7 @@ static inline unsigned long pte_update(pte_t *p,
#endif /* !PTE_ATOMIC_UPDATES */
#ifdef CONFIG_44x
- if ((old & _PAGE_USER) && (old & _PAGE_HWEXEC))
+ if ((old & _PAGE_USER) && (old & _PAGE_EXEC))
icache_44x_need_flush = 1;
#endif
return old;
@@ -217,7 +217,7 @@ static inline unsigned long long pte_update(pte_t *p,
#endif /* !PTE_ATOMIC_UPDATES */
#ifdef CONFIG_44x
- if ((old & _PAGE_USER) && (old & _PAGE_HWEXEC))
+ if ((old & _PAGE_USER) && (old & _PAGE_EXEC))
icache_44x_need_flush = 1;
#endif
return old;
@@ -267,8 +267,7 @@ static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
{
unsigned long bits = pte_val(entry) &
- (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW |
- _PAGE_HWEXEC | _PAGE_EXEC);
+ (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
pte_update(ptep, 0, bits);
}
diff --git a/arch/powerpc/include/asm/pgtable-ppc64.h b/arch/powerpc/include/asm/pgtable-ppc64.h
index 200ec2d..806abe7 100644
--- a/arch/powerpc/include/asm/pgtable-ppc64.h
+++ b/arch/powerpc/include/asm/pgtable-ppc64.h
@@ -313,8 +313,7 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr,
static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
{
unsigned long bits = pte_val(entry) &
- (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW |
- _PAGE_EXEC | _PAGE_HWEXEC);
+ (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
#ifdef PTE_ATOMIC_UPDATES
unsigned long old, tmp;
diff --git a/arch/powerpc/include/asm/pte-40x.h b/arch/powerpc/include/asm/pte-40x.h
index 07630fa..6c3e1f4 100644
--- a/arch/powerpc/include/asm/pte-40x.h
+++ b/arch/powerpc/include/asm/pte-40x.h
@@ -46,7 +46,7 @@
#define _PAGE_RW 0x040 /* software: Writes permitted */
#define _PAGE_DIRTY 0x080 /* software: dirty page */
#define _PAGE_HWWRITE 0x100 /* hardware: Dirty & RW, set in exception */
-#define _PAGE_HWEXEC 0x200 /* hardware: EX permission */
+#define _PAGE_EXEC 0x200 /* hardware: EX permission */
#define _PAGE_ACCESSED 0x400 /* software: R: page referenced */
#define _PMD_PRESENT 0x400 /* PMD points to page of PTEs */
diff --git a/arch/powerpc/include/asm/pte-44x.h b/arch/powerpc/include/asm/pte-44x.h
index 37e98bc..4192b9b 100644
--- a/arch/powerpc/include/asm/pte-44x.h
+++ b/arch/powerpc/include/asm/pte-44x.h
@@ -78,7 +78,7 @@
#define _PAGE_PRESENT 0x00000001 /* S: PTE valid */
#define _PAGE_RW 0x00000002 /* S: Write permission */
#define _PAGE_FILE 0x00000004 /* S: nonlinear file mapping */
-#define _PAGE_HWEXEC 0x00000004 /* H: Execute permission */
+#define _PAGE_EXEC 0x00000004 /* H: Execute permission */
#define _PAGE_ACCESSED 0x00000008 /* S: Page referenced */
#define _PAGE_DIRTY 0x00000010 /* S: Page dirty */
#define _PAGE_SPECIAL 0x00000020 /* S: Special page */
diff --git a/arch/powerpc/include/asm/pte-8xx.h b/arch/powerpc/include/asm/pte-8xx.h
index 8c6e312..94e9797 100644
--- a/arch/powerpc/include/asm/pte-8xx.h
+++ b/arch/powerpc/include/asm/pte-8xx.h
@@ -36,7 +36,6 @@
/* These five software bits must be masked out when the entry is loaded
* into the TLB.
*/
-#define _PAGE_EXEC 0x0008 /* software: i-cache coherency required */
#define _PAGE_GUARDED 0x0010 /* software: guarded access */
#define _PAGE_DIRTY 0x0020 /* software: page changed */
#define _PAGE_RW 0x0040 /* software: user write access allowed */
diff --git a/arch/powerpc/include/asm/pte-book3e.h b/arch/powerpc/include/asm/pte-book3e.h
index 1d27c77..9800565 100644
--- a/arch/powerpc/include/asm/pte-book3e.h
+++ b/arch/powerpc/include/asm/pte-book3e.h
@@ -37,12 +37,13 @@
#define _PAGE_WRITETHRU 0x800000 /* W: cache write-through */
/* "Higher level" linux bit combinations */
-#define _PAGE_EXEC _PAGE_BAP_SX /* Can be executed from potentially */
-#define _PAGE_HWEXEC _PAGE_BAP_UX /* .. and was cache cleaned */
-#define _PAGE_RW (_PAGE_BAP_SW | _PAGE_BAP_UW) /* User write permission */
-#define _PAGE_KERNEL_RW (_PAGE_BAP_SW | _PAGE_BAP_SR | _PAGE_DIRTY)
-#define _PAGE_KERNEL_RO (_PAGE_BAP_SR)
-#define _PAGE_USER (_PAGE_BAP_UR | _PAGE_BAP_SR) /* Can be read */
+#define _PAGE_EXEC _PAGE_BAP_UX /* .. and was cache cleaned */
+#define _PAGE_RW (_PAGE_BAP_SW | _PAGE_BAP_UW) /* User write permission */
+#define _PAGE_KERNEL_RW (_PAGE_BAP_SW | _PAGE_BAP_SR | _PAGE_DIRTY)
+#define _PAGE_KERNEL_RO (_PAGE_BAP_SR)
+#define _PAGE_KERNEL_RWX (_PAGE_BAP_SW | _PAGE_BAP_SR | _PAGE_DIRTY | _PAGE_BAP_SX)
+#define _PAGE_KERNEL_ROX (_PAGE_BAP_SR | _PAGE_BAP_SX)
+#define _PAGE_USER (_PAGE_BAP_UR | _PAGE_BAP_SR) /* Can be read */
#define _PAGE_HASHPTE 0
#define _PAGE_BUSY 0
diff --git a/arch/powerpc/include/asm/pte-common.h b/arch/powerpc/include/asm/pte-common.h
index 8bb6464..c3b6507 100644
--- a/arch/powerpc/include/asm/pte-common.h
+++ b/arch/powerpc/include/asm/pte-common.h
@@ -13,9 +13,6 @@
#ifndef _PAGE_HWWRITE
#define _PAGE_HWWRITE 0
#endif
-#ifndef _PAGE_HWEXEC
-#define _PAGE_HWEXEC 0
-#endif
#ifndef _PAGE_EXEC
#define _PAGE_EXEC 0
#endif
@@ -48,10 +45,16 @@
#define PMD_PAGE_SIZE(pmd) bad_call_to_PMD_PAGE_SIZE()
#endif
#ifndef _PAGE_KERNEL_RO
-#define _PAGE_KERNEL_RO 0
+#define _PAGE_KERNEL_RO 0
+#endif
+#ifndef _PAGE_KERNEL_ROX
+#define _PAGE_KERNEL_ROX (_PAGE_EXEC)
#endif
#ifndef _PAGE_KERNEL_RW
-#define _PAGE_KERNEL_RW (_PAGE_DIRTY | _PAGE_RW | _PAGE_HWWRITE)
+#define _PAGE_KERNEL_RW (_PAGE_DIRTY | _PAGE_RW | _PAGE_HWWRITE)
+#endif
+#ifndef _PAGE_KERNEL_RWX
+#define _PAGE_KERNEL_RWX (_PAGE_DIRTY | _PAGE_RW | _PAGE_HWWRITE | _PAGE_EXEC)
#endif
#ifndef _PAGE_HPTEFLAGS
#define _PAGE_HPTEFLAGS _PAGE_HASHPTE
@@ -96,8 +99,7 @@ extern unsigned long bad_call_to_PMD_PAGE_SIZE(void);
#define PAGE_PROT_BITS (_PAGE_GUARDED | _PAGE_COHERENT | _PAGE_NO_CACHE | \
_PAGE_WRITETHRU | _PAGE_ENDIAN | _PAGE_4K_PFN | \
_PAGE_USER | _PAGE_ACCESSED | \
- _PAGE_RW | _PAGE_HWWRITE | _PAGE_DIRTY | \
- _PAGE_EXEC | _PAGE_HWEXEC)
+ _PAGE_RW | _PAGE_HWWRITE | _PAGE_DIRTY | _PAGE_EXEC)
/*
* We define 2 sets of base prot bits, one for basic pages (ie,
@@ -154,11 +156,9 @@ extern unsigned long bad_call_to_PMD_PAGE_SIZE(void);
_PAGE_NO_CACHE)
#define PAGE_KERNEL_NCG __pgprot(_PAGE_BASE_NC | _PAGE_KERNEL_RW | \
_PAGE_NO_CACHE | _PAGE_GUARDED)
-#define PAGE_KERNEL_X __pgprot(_PAGE_BASE | _PAGE_KERNEL_RW | _PAGE_EXEC | \
- _PAGE_HWEXEC)
+#define PAGE_KERNEL_X __pgprot(_PAGE_BASE | _PAGE_KERNEL_RWX)
#define PAGE_KERNEL_RO __pgprot(_PAGE_BASE | _PAGE_KERNEL_RO)
-#define PAGE_KERNEL_ROX __pgprot(_PAGE_BASE | _PAGE_KERNEL_RO | _PAGE_EXEC | \
- _PAGE_HWEXEC)
+#define PAGE_KERNEL_ROX __pgprot(_PAGE_BASE | _PAGE_KERNEL_ROX)
/* Protection used for kernel text. We want the debuggers to be able to
* set breakpoints anywhere, so don't write protect the kernel text
diff --git a/arch/powerpc/include/asm/pte-fsl-booke.h b/arch/powerpc/include/asm/pte-fsl-booke.h
index 10820f5..ce8a9e9 100644
--- a/arch/powerpc/include/asm/pte-fsl-booke.h
+++ b/arch/powerpc/include/asm/pte-fsl-booke.h
@@ -23,7 +23,7 @@
#define _PAGE_FILE 0x00002 /* S: when !present: nonlinear file mapping */
#define _PAGE_RW 0x00004 /* S: Write permission (SW) */
#define _PAGE_DIRTY 0x00008 /* S: Page dirty */
-#define _PAGE_HWEXEC 0x00010 /* H: SX permission */
+#define _PAGE_EXEC 0x00010 /* H: SX permission */
#define _PAGE_ACCESSED 0x00020 /* S: Page referenced */
#define _PAGE_ENDIAN 0x00040 /* H: E bit */
diff --git a/arch/powerpc/include/asm/pte-hash32.h b/arch/powerpc/include/asm/pte-hash32.h
index 16e571c..4aad413 100644
--- a/arch/powerpc/include/asm/pte-hash32.h
+++ b/arch/powerpc/include/asm/pte-hash32.h
@@ -26,7 +26,6 @@
#define _PAGE_WRITETHRU 0x040 /* W: cache write-through */
#define _PAGE_DIRTY 0x080 /* C: page changed */
#define _PAGE_ACCESSED 0x100 /* R: page referenced */
-#define _PAGE_EXEC 0x200 /* software: i-cache coherency required */
#define _PAGE_RW 0x400 /* software: user write access allowed */
#define _PAGE_SPECIAL 0x800 /* software: Special page */
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S
index 656cfb2..711368b 100644
--- a/arch/powerpc/kernel/head_44x.S
+++ b/arch/powerpc/kernel/head_44x.S
@@ -497,7 +497,7 @@ tlb_44x_patch_hwater_D:
mtspr SPRN_MMUCR,r12
/* Make up the required permissions */
- li r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_HWEXEC
+ li r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC
/* Compute pgdir/pmd offset */
rlwinm r12, r10, PPC44x_PGD_OFF_SHIFT, PPC44x_PGD_OFF_MASK_BIT, 29
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
index eca8048..2c5af52 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -643,7 +643,7 @@ interrupt_base:
4:
/* Make up the required permissions */
- li r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_HWEXEC
+ li r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC
FIND_PTE
andc. r13,r13,r11 /* Check permission */
@@ -742,7 +742,7 @@ finish_tlb_load:
#endif
mtspr SPRN_MAS2, r12
- li r10, (_PAGE_HWEXEC | _PAGE_PRESENT)
+ li r10, (_PAGE_EXEC | _PAGE_PRESENT)
rlwimi r10, r11, 31, 29, 29 /* extract _PAGE_DIRTY into SW */
and r12, r11, r10
andi. r10, r11, _PAGE_USER /* Test for _PAGE_USER */
diff --git a/arch/powerpc/mm/40x_mmu.c b/arch/powerpc/mm/40x_mmu.c
index 29954dc..f5e7b9c 100644
--- a/arch/powerpc/mm/40x_mmu.c
+++ b/arch/powerpc/mm/40x_mmu.c
@@ -105,7 +105,7 @@ unsigned long __init mmu_mapin_ram(void)
while (s >= LARGE_PAGE_SIZE_16M) {
pmd_t *pmdp;
- unsigned long val = p | _PMD_SIZE_16M | _PAGE_HWEXEC | _PAGE_HWWRITE;
+ unsigned long val = p | _PMD_SIZE_16M | _PAGE_EXEC | _PAGE_HWWRITE;
pmdp = pmd_offset(pud_offset(pgd_offset_k(v), v), v);
pmd_val(*pmdp++) = val;
@@ -120,7 +120,7 @@ unsigned long __init mmu_mapin_ram(void)
while (s >= LARGE_PAGE_SIZE_4M) {
pmd_t *pmdp;
- unsigned long val = p | _PMD_SIZE_4M | _PAGE_HWEXEC | _PAGE_HWWRITE;
+ unsigned long val = p | _PMD_SIZE_4M | _PAGE_EXEC | _PAGE_HWWRITE;
pmdp = pmd_offset(pud_offset(pgd_offset_k(v), v), v);
pmd_val(*pmdp) = val;
diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
index cafb2a2..cfc2499 100644
--- a/arch/powerpc/mm/pgtable.c
+++ b/arch/powerpc/mm/pgtable.c
@@ -128,28 +128,6 @@ void pte_free_finish(void)
#endif /* CONFIG_SMP */
-/*
- * Handle i/d cache flushing, called from set_pte_at() or ptep_set_access_flags()
- */
-static pte_t do_dcache_icache_coherency(pte_t pte)
-{
- unsigned long pfn = pte_pfn(pte);
- struct page *page;
-
- if (unlikely(!pfn_valid(pfn)))
- return pte;
- page = pfn_to_page(pfn);
-
- if (!PageReserved(page) && !test_bit(PG_arch_1, &page->flags)) {
- pr_devel("do_dcache_icache_coherency... flushing\n");
- flush_dcache_icache_page(page);
- set_bit(PG_arch_1, &page->flags);
- }
- else
- pr_devel("do_dcache_icache_coherency... already clean\n");
- return __pte(pte_val(pte) | _PAGE_HWEXEC);
-}
-
static inline int is_exec_fault(void)
{
return current->thread.regs && TRAP(current->thread.regs) == 0x400;
@@ -157,49 +135,139 @@ static inline int is_exec_fault(void)
/* We only try to do i/d cache coherency on stuff that looks like
* reasonably "normal" PTEs. We currently require a PTE to be present
- * and we avoid _PAGE_SPECIAL and _PAGE_NO_CACHE
+ * and we avoid _PAGE_SPECIAL and _PAGE_NO_CACHE. We also only do that
+ * on userspace PTEs
*/
static inline int pte_looks_normal(pte_t pte)
{
return (pte_val(pte) &
- (_PAGE_PRESENT | _PAGE_SPECIAL | _PAGE_NO_CACHE)) ==
- (_PAGE_PRESENT);
+ (_PAGE_PRESENT | _PAGE_SPECIAL | _PAGE_NO_CACHE | _PAGE_USER)) ==
+ (_PAGE_PRESENT | _PAGE_USER);
}
-#if defined(CONFIG_PPC_STD_MMU)
+struct page * maybe_pte_to_page(pte_t pte)
+{
+ unsigned long pfn = pte_pfn(pte);
+ struct page *page;
+
+ if (unlikely(!pfn_valid(pfn)))
+ return NULL;
+ page = pfn_to_page(pfn);
+ if (PageReserved(page))
+ return NULL;
+ return page;
+}
+
+#if defined(CONFIG_PPC_STD_MMU) || _PAGE_EXEC == 0
+
/* Server-style MMU handles coherency when hashing if HW exec permission
- * is supposed per page (currently 64-bit only). Else, we always flush
- * valid PTEs in set_pte.
+ * is supposed per page (currently 64-bit only). If not, then, we always
+ * flush the cache for valid PTEs in set_pte. Embedded CPU without HW exec
+ * support falls into the same category.
*/
-static inline int pte_need_exec_flush(pte_t pte, int set_pte)
+
+static pte_t set_pte_filter(pte_t pte)
{
- return set_pte && pte_looks_normal(pte) &&
- !(cpu_has_feature(CPU_FTR_COHERENT_ICACHE) ||
- cpu_has_feature(CPU_FTR_NOEXECUTE));
+ pte = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
+ if (pte_looks_normal(pte) && !(cpu_has_feature(CPU_FTR_COHERENT_ICACHE) ||
+ cpu_has_feature(CPU_FTR_NOEXECUTE))) {
+ struct page *pg = maybe_pte_to_page(pte);
+ if (!pg)
+ return pte;
+ if (!test_bit(PG_arch_1, &pg->flags)) {
+ flush_dcache_icache_page(pg);
+ set_bit(PG_arch_1, &pg->flags);
+ }
+ }
+ return pte;
}
-#elif _PAGE_HWEXEC == 0
-/* Embedded type MMU without HW exec support (8xx only so far), we flush
- * the cache for any present PTE
- */
-static inline int pte_need_exec_flush(pte_t pte, int set_pte)
+
+static pte_t set_access_flags_filter(pte_t pte, struct vm_area_struct *vma,
+ int dirty)
{
- return set_pte && pte_looks_normal(pte);
+ return pte;
}
-#else
-/* Other embedded CPUs with HW exec support per-page, we flush on exec
- * fault if HWEXEC is not set
+
+#else /* defined(CONFIG_PPC_STD_MMU) || _PAGE_EXEC == 0 */
+
+/* Embedded type MMU with HW exec support. This is a bit more complicated
+ * as we don't have two bits to spare for _PAGE_EXEC and _PAGE_HWEXEC so
+ * instead we "filter out" the exec permission for non clean pages.
*/
-static inline int pte_need_exec_flush(pte_t pte, int set_pte)
+static pte_t set_pte_filter(pte_t pte)
{
- return pte_looks_normal(pte) && is_exec_fault() &&
- !(pte_val(pte) & _PAGE_HWEXEC);
+ struct page *pg;
+
+ /* No exec permission in the first place, move on */
+ if (!(pte_val(pte) & _PAGE_EXEC) || !pte_looks_normal(pte))
+ return pte;
+
+ /* If you set _PAGE_EXEC on weird pages you're on your own */
+ pg = maybe_pte_to_page(pte);
+ if (unlikely(!pg))
+ return pte;
+
+ /* If the page clean, we move on */
+ if (test_bit(PG_arch_1, &pg->flags))
+ return pte;
+
+ /* If it's an exec fault, we flush the cache and make it clean */
+ if (is_exec_fault()) {
+ flush_dcache_icache_page(pg);
+ set_bit(PG_arch_1, &pg->flags);
+ return pte;
+ }
+
+ /* Else, we filter out _PAGE_EXEC */
+ return __pte(pte_val(pte) & ~_PAGE_EXEC);
}
-#endif
+
+static pte_t set_access_flags_filter(pte_t pte, struct vm_area_struct *vma,
+ int dirty)
+{
+ struct page *pg;
+
+ /* So here, we only care about exec faults, as we use them
+ * to recover lost _PAGE_EXEC and perform I$/D$ coherency
+ * if necessary. Also if _PAGE_EXEC is already set, same deal,
+ * we just bail out
+ */
+ if (dirty || (pte_val(pte) & _PAGE_EXEC) || !is_exec_fault())
+ return pte;
+
+#ifdef CONFIG_DEBUG_VM
+ /* So this is an exec fault, _PAGE_EXEC is not set. If it was
+ * an error we would have bailed out earlier in do_page_fault()
+ * but let's make sure of it
+ */
+ if (WARN_ON(!(vma->vm_flags & VM_EXEC)))
+ return pte;
+#endif /* CONFIG_DEBUG_VM */
+
+ /* If you set _PAGE_EXEC on weird pages you're on your own */
+ pg = maybe_pte_to_page(pte);
+ if (unlikely(!pg))
+ goto bail;
+
+ /* If the page is already clean, we move on */
+ if (test_bit(PG_arch_1, &pg->flags))
+ goto bail;
+
+ /* Clean the page and set PG_arch_1 */
+ flush_dcache_icache_page(pg);
+ set_bit(PG_arch_1, &pg->flags);
+
+ bail:
+ return __pte(pte_val(pte) | _PAGE_EXEC);
+}
+
+#endif /* !(defined(CONFIG_PPC_STD_MMU) || _PAGE_EXEC == 0) */
/*
* set_pte stores a linux PTE into the linux page table.
*/
-void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte)
+void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep,
+ pte_t pte)
{
#ifdef CONFIG_DEBUG_VM
WARN_ON(pte_present(*ptep));
@@ -208,9 +276,7 @@ void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte
* this context might not have been activated yet when this
* is called.
*/
- pte = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
- if (pte_need_exec_flush(pte, 1))
- pte = do_dcache_icache_coherency(pte);
+ pte = set_pte_filter(pte);
/* Perform the setting of the PTE */
__set_pte_at(mm, addr, ptep, pte, 0);
@@ -227,8 +293,7 @@ int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address,
pte_t *ptep, pte_t entry, int dirty)
{
int changed;
- if (!dirty && pte_need_exec_flush(entry, 0))
- entry = do_dcache_icache_coherency(entry);
+ entry = set_access_flags_filter(entry, vma, dirty);
changed = !pte_same(*(ptep), entry);
if (changed) {
if (!(vma->vm_flags & VM_HUGETLB))
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 5422169..cb96cb2 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -142,7 +142,7 @@ ioremap_flags(phys_addr_t addr, unsigned long size, unsigned long flags)
flags |= _PAGE_DIRTY | _PAGE_HWWRITE;
/* we don't want to let _PAGE_USER and _PAGE_EXEC leak out */
- flags &= ~(_PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC);
+ flags &= ~(_PAGE_USER | _PAGE_EXEC);
return __ioremap_caller(addr, size, flags, __builtin_return_address(0));
}
diff --git a/arch/powerpc/mm/tlb_low_64e.S b/arch/powerpc/mm/tlb_low_64e.S
index 10d524d..cd92f62 100644
--- a/arch/powerpc/mm/tlb_low_64e.S
+++ b/arch/powerpc/mm/tlb_low_64e.S
@@ -133,7 +133,7 @@
/* We do the user/kernel test for the PID here along with the RW test
*/
- li r11,_PAGE_PRESENT|_PAGE_HWEXEC /* Base perm */
+ li r11,_PAGE_PRESENT|_PAGE_EXEC /* Base perm */
oris r11,r11,_PAGE_ACCESSED@h
cmpldi cr0,r15,0 /* Check for user region */
@@ -256,7 +256,7 @@ normal_tlb_miss_done:
normal_tlb_miss_access_fault:
/* We need to check if it was an instruction miss */
- andi. r10,r11,_PAGE_HWEXEC
+ andi. r10,r11,_PAGE_EXEC
bne 1f
ld r14,EX_TLB_DEAR(r12)
ld r15,EX_TLB_ESR(r12)
--
1.6.1.2.14.gf26b5
^ permalink raw reply related
* Re: [PATCH] powerpc/mm: Fix assert_pte_locked to work properly on uniprocessor
From: Benjamin Herrenschmidt @ 2009-08-19 3:35 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <1250644900-32133-1-git-send-email-galak@kernel.crashing.org>
On Tue, 2009-08-18 at 20:21 -0500, Kumar Gala wrote:
> Since the pte_lockptr is a spinlock it gets optimized away on
> uniprocessor builds so using spin_is_locked is not correct. We can use
> assert_spin_locked instead and get the proper behavior between UP and
> SMP builds.
Thanks. Applied.
Cheers,
Ben.
> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
> ---
> arch/powerpc/mm/pgtable.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
> index 627767d..4b9a27d 100644
> --- a/arch/powerpc/mm/pgtable.c
> +++ b/arch/powerpc/mm/pgtable.c
> @@ -242,7 +242,7 @@ void assert_pte_locked(struct mm_struct *mm, unsigned long addr)
> BUG_ON(pud_none(*pud));
> pmd = pmd_offset(pud, addr);
> BUG_ON(!pmd_present(*pmd));
> - BUG_ON(!spin_is_locked(pte_lockptr(mm, pmd)));
> + assert_spin_locked(pte_lockptr(mm, pmd));
> }
> #endif /* CONFIG_DEBUG_VM */
>
^ permalink raw reply
* Re: [PATCH] USB: fsl_qe_udc: Add fsl,mpc8323-qe-usb compatible entry
From: Li Yang @ 2009-08-19 3:19 UTC (permalink / raw)
To: Anton Vorontsov
Cc: David Brownell, Greg Kroah-Hartman, linuxppc-dev, linux-usb,
Scott Wood
In-Reply-To: <20090818222335.GA28135@oksana.dev.rtsoft.ru>
On Wed, Aug 19, 2009 at 6:23 AM, Anton
Vorontsov<avorontsov@ru.mvista.com> wrote:
> Current bindings specify that "fsl,mpc8323-qe-usb" compatible entry
> should be used as a base match for QE UDCs, so update the driver to
> comply with the bindings.
>
> Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
Acked-by: Li Yang <leoli@freescale.com>
- Leo
^ permalink raw reply
* Re: [PATCH] spinlock: __raw_spin_is_locked() should return true for UP
From: Linus Torvalds @ 2009-08-19 2:40 UTC (permalink / raw)
To: Kumar Gala
Cc: peterz, linux-kernel, Steven Rostedt, linuxppc-dev, mingo, tglx
In-Reply-To: <BB2762BC-C760-4D4C-BDCF-76EFD3E1B18D@kernel.crashing.org>
On Tue, 18 Aug 2009, Kumar Gala wrote:
>
> I agree its a little too easy to abuse spin_is_locked. However we should be
> consistent between spin_is_locked on UP between with and without
> CONFIG_DEBUG_SPINLOCK enabled.
No we shouldn't.
With CONFIG_DEBUG_SPINLOCK, you have an actual lock variable for debugging
purposes, so spin_is_locked() can clearly return a _valid_ answer, and
should do so.
Without DEBUG_SPINLOCK, there isn't any answer to return.
So there's no way we can or should be consistent. In one case an answer
exists, in another one the answer is meaningless and doesn't exist.
> How much of this do we want to try and address in .31?
Absolutely nothing.
> The PPC test really should be using assert_spin_locked and I'll send a patch
> to Ben for that.
Yes, that's the correct fix.
Linus
^ permalink raw reply
* Re: [PATCH v2] powerpc/85xx: Add eSDHC support for MPC8536DS boards
From: Anton Vorontsov @ 2009-08-19 1:51 UTC (permalink / raw)
To: Kumar Gala
Cc: Ben Dooks, linux-kernel, sdhci-devel, linuxppc-dev, Andrew Morton,
Pierre Ossman, David Vrabel
In-Reply-To: <F58A75CD-73CC-4F75-AF51-2BCC0B828E84@kernel.crashing.org>
On Tue, Aug 18, 2009 at 08:24:17PM -0500, Kumar Gala wrote:
>
> On Aug 18, 2009, at 6:38 PM, Anton Vorontsov wrote:
>
> >This patch simply adds sdhci node to the device tree.
> >
> >We specify clock-frequency manually, so that eSDHC will work without
> >upgrading U-Boot. Though, that'll only work for default setup (1500
> >MHz) on new board revisions. For non-default setups, it's recommended
> >to upgrade U-Boot, since it will fixup clock-frequency automatically.
> >
> >Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
>
> out of interest the 85xx eSDHC don't need the sdhci,wp-inverted
> property?
Yes, eSDHC controllers in MPC85xx report normal state in its
registers.
But the funny thing is that the switch itself is inverted,
so to enable writing, on MPC8569E-MDS and MPC8536DS boards
we have to place card's write protect tab into "lock" position.
Unfortunately we can't fix that in software since controller
doesn't permit write operations if it detects write-protected
state. On the bright side, IIRC MPC8536DS revision history
says that WP line level is fixed via BCSR upgrade. Not sure
if it is possible to fix it for MPC8569E-MDS.
--
Anton Vorontsov
email: cbouatmailru@gmail.com
irc://irc.freenode.net/bd2
^ permalink raw reply
* Re: powerpc/405ex: Support cuImage for PPC405EX
From: tiejun.chen @ 2009-08-19 1:45 UTC (permalink / raw)
To: Josh Boyer; +Cc: linuxppc-dev
In-Reply-To: <20090818132835.GA2530@zod.rchland.ibm.com>
Josh Boyer wrote:
> On Tue, Aug 18, 2009 at 10:28:02AM +0800, Tiejun Chen wrote:
>> Summary: powerpc/405ex: Support cuImage for PPC405EX
>> Reviewers: Benjmain and linux-ppc
>> ----------------------------------------------------
>> These patch series are used to support cuImage on the kilauea board based on PPC405ex.
>>
>> Tested on the amcc kilauea board:
>
> Hm. The U-Boot version that ships on the AMCC Kilauea board is FDT aware, so
> cuImage shouldn't be needed at all. I'm slightly confused why we need this.
That the newer u-boot can aware extra on Kilauea is really as you said. But I
think I/we need to consider some other requirements for 405EX, such as only
using one image for convenient on embedded system, and u-boot don't pass dtb for
kernel since it will be isolated with one customer software layer.
And actually to support old U-boot compatibility is original *goal* of
implementing cuImage in kernel as we know. Right?
As Documentation/powerpc/bootwrapper.txt I think the kernel should support more
image variant to satisfy different requirement. Sometimes that is also beyond we
can discuss here.
> Are you using it for some other board derived from 405EX that doesn't have
> an FDT aware U-Boot?
>
Yes, this is really another factor. Anyway thinks your comments.
Best Reards
Tiejun
> josh
>
^ permalink raw reply
* Re: [PATCH v2] powerpc/85xx: Add eSDHC support for MPC8536DS boards
From: Kumar Gala @ 2009-08-19 1:24 UTC (permalink / raw)
To: avorontsov
Cc: Ben Dooks, linux-kernel, sdhci-devel, linuxppc-dev, Andrew Morton,
Pierre Ossman, David Vrabel
In-Reply-To: <20090818233818.GA29042@oksana.dev.rtsoft.ru>
On Aug 18, 2009, at 6:38 PM, Anton Vorontsov wrote:
> This patch simply adds sdhci node to the device tree.
>
> We specify clock-frequency manually, so that eSDHC will work without
> upgrading U-Boot. Though, that'll only work for default setup (1500
> MHz) on new board revisions. For non-default setups, it's recommended
> to upgrade U-Boot, since it will fixup clock-frequency automatically.
>
> Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
out of interest the 85xx eSDHC don't need the sdhci,wp-inverted
property?
- k
^ permalink raw reply
* [PATCH] powerpc/mm: Fix assert_pte_locked to work properly on uniprocessor
From: Kumar Gala @ 2009-08-19 1:21 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev
Since the pte_lockptr is a spinlock it gets optimized away on
uniprocessor builds so using spin_is_locked is not correct. We can use
assert_spin_locked instead and get the proper behavior between UP and
SMP builds.
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
arch/powerpc/mm/pgtable.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
index 627767d..4b9a27d 100644
--- a/arch/powerpc/mm/pgtable.c
+++ b/arch/powerpc/mm/pgtable.c
@@ -242,7 +242,7 @@ void assert_pte_locked(struct mm_struct *mm, unsigned long addr)
BUG_ON(pud_none(*pud));
pmd = pmd_offset(pud, addr);
BUG_ON(!pmd_present(*pmd));
- BUG_ON(!spin_is_locked(pte_lockptr(mm, pmd)));
+ assert_spin_locked(pte_lockptr(mm, pmd));
}
#endif /* CONFIG_DEBUG_VM */
--
1.6.0.6
^ permalink raw reply related
* Re: [PATCH] spinlock: __raw_spin_is_locked() should return true for UP
From: Kumar Gala @ 2009-08-19 1:17 UTC (permalink / raw)
To: Steven Rostedt
Cc: peterz, linux-kernel, linuxppc-dev, mingo, Linus Torvalds, tglx
In-Reply-To: <alpine.DEB.2.00.0908182003430.18648@gandalf.stny.rr.com>
On Aug 18, 2009, at 7:07 PM, Steven Rostedt wrote:
> On Tue, 18 Aug 2009, Linus Torvalds wrote:
>>
>>> Thinking about it, UP probably should have spin_is_locked always
>>> return
>>> false, but if you want to make sure you are not in a critical
>>> section
>>> with the lock not held, then use assert_spin_locked, which on UP
>>> should be
>>> a nop.
>>
>> That's what we do. That said, I also think we should generally try to
>> avoid the kind of code that depends on spin_is_locked always
>> returning
>> false, for the same reason we should try to avoid any code that
>> depends on
>> it always returning true.
>
> Perhaps we can deprecate spin_is_locked and replace it with
> "expect_spin_locked" and "expect_spin_unlocked" which on SMP would
> return
> true and false respectively if the lock was locked. But both would
> always
> return true on UP.
>
> Or do some thing similar, that would remove the ambiguity on UP.
I agree its a little too easy to abuse spin_is_locked. However we
should be consistent between spin_is_locked on UP between with and
without CONFIG_DEBUG_SPINLOCK enabled. How much of this do we want to
try and address in .31?
The PPC test really should be using assert_spin_locked and I'll send a
patch to Ben for that.
- k
^ permalink raw reply
* Re: [PATCH] spinlock: __raw_spin_is_locked() should return true for UP
From: Steven Rostedt @ 2009-08-19 0:07 UTC (permalink / raw)
To: Linus Torvalds; +Cc: peterz, linux-kernel, linuxppc-dev, mingo, tglx
In-Reply-To: <alpine.LFD.2.01.0908181640120.3158@localhost.localdomain>
On Tue, 18 Aug 2009, Linus Torvalds wrote:
>
> > Thinking about it, UP probably should have spin_is_locked always return
> > false, but if you want to make sure you are not in a critical section
> > with the lock not held, then use assert_spin_locked, which on UP should be
> > a nop.
>
> That's what we do. That said, I also think we should generally try to
> avoid the kind of code that depends on spin_is_locked always returning
> false, for the same reason we should try to avoid any code that depends on
> it always returning true.
Perhaps we can deprecate spin_is_locked and replace it with
"expect_spin_locked" and "expect_spin_unlocked" which on SMP would return
true and false respectively if the lock was locked. But both would always
return true on UP.
Or do some thing similar, that would remove the ambiguity on UP.
-- Steve
^ permalink raw reply
* Re: [PATCH] spinlock: __raw_spin_is_locked() should return true for UP
From: Linus Torvalds @ 2009-08-18 23:52 UTC (permalink / raw)
To: Steven Rostedt; +Cc: peterz, linux-kernel, linuxppc-dev, mingo, tglx
In-Reply-To: <alpine.DEB.2.00.0908181931180.28398@gandalf.stny.rr.com>
On Tue, 18 Aug 2009, Steven Rostedt wrote:
>
> > The thing is, some people may assert that a lock is held, but others could
> > easily be looping until it's not held using something like
> >
> > while (spin_is_locked(lock))
> > cpu_relax();
>
> Wouldn't something like that be really racey? And anyone doing such a
> thing had better have that code within an #ifdef CONFIG_SMP.
Sure, it's hopefully inside a #ifdef CONFIG_SMP.
And no, it's not necessarily racy. Sure, it's race in itself if that's all
you are doing, but I could imagine writing that kind of code if I knew
some lock was likely held, and I wanted to avoid doing a "try_lock()"
until it got released.
The point is, "spin_is_locked()" is simply not a well-defined operation in
this case. It could go either way.
And for the original case, we actually have a function for that:
assert_spin_locked(x)
which goes away on UP. Exactly because
BUG_ON(!spin_is_locked(x))
is not a good thing to do!
> > so it's hard to tell whether it should return true or false in the case
> > where spin-locking simply doesn't exist.
>
> Actually, I did have a case where I would use it and would expect a return
> of 0. That was in the experimental printk code to see if it was safe to
> wakeup the klogd. I once had a check of the current cpu runqueue lock is
> locked, and if it was, not to wake up klogd. I'm sure there's other cases
> like this as well.
Yeah, "spin_is_locked()" can be useful for those kinds of things. A
heuristic for whether we should do something based on whether some other
CPU holds it (or we migth have recursion).
Exactly like it can be useful for doing the BUG_ON thing. But in both
cases it's a bit iffy.
> Thinking about it, UP probably should have spin_is_locked always return
> false, but if you want to make sure you are not in a critical section
> with the lock not held, then use assert_spin_locked, which on UP should be
> a nop.
That's what we do. That said, I also think we should generally try to
avoid the kind of code that depends on spin_is_locked always returning
false, for the same reason we should try to avoid any code that depends on
it always returning true.
Linus
^ permalink raw reply
* Re: [PATCH 4/8] powerpc/qe&cpm: Implement static inline stubs for non-QE/CPM builds
From: Anton Vorontsov @ 2009-08-18 23:47 UTC (permalink / raw)
To: Greg KH
Cc: David Brownell, linux-kernel, linuxppc-dev, spi-devel-general,
Andrew Morton
In-Reply-To: <20090818222747.GB4354@suse.de>
On Tue, Aug 18, 2009 at 03:27:47PM -0700, Greg KH wrote:
> On Wed, Aug 19, 2009 at 02:04:18AM +0400, Anton Vorontsov wrote:
> > This is needed to avoid ugly #ifdefs in drivers. Also update fsl_qe_udc
> > driver so that now it doesn't define its own versions that cause build
> > breakage when the generic stubs are used.
> >
> > Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
>
> As you're just deleting code, I'll ack that :)
>
> Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
>
> Hopefully you have tested building this thing...
Yep, thanks!
--
Anton Vorontsov
email: cbouatmailru@gmail.com
irc://irc.freenode.net/bd2
^ permalink raw reply
* [PATCH v2] powerpc/85xx: Add eSDHC support for MPC8536DS boards
From: Anton Vorontsov @ 2009-08-18 23:38 UTC (permalink / raw)
To: Kumar Gala
Cc: Ben Dooks, linux-kernel, sdhci-devel, linuxppc-dev, Andrew Morton,
Pierre Ossman, David Vrabel
In-Reply-To: <A17F24A0-87E0-4FFA-9C14-DF57D8A9D015@kernel.crashing.org>
This patch simply adds sdhci node to the device tree.
We specify clock-frequency manually, so that eSDHC will work without
upgrading U-Boot. Though, that'll only work for default setup (1500
MHz) on new board revisions. For non-default setups, it's recommended
to upgrade U-Boot, since it will fixup clock-frequency automatically.
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
On Tue, Aug 11, 2009 at 08:48:32AM -0500, Kumar Gala wrote:
> On Aug 7, 2009, at 2:58 PM, Anton Vorontsov wrote:
> >This patch simply adds sdhci node to the device tree.
> >
> >We specify clock-frequency manually, so that eSDHC will work without
> >upgrading U-Boot. Though, that'll only work for default setup (1500
> >MHz) on new board revisions. For non-default setups, it's recommended
> >to upgrade U-Boot, since it will fixup clock-frequency automatically.
> >
> >Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
> >---
> >arch/powerpc/boot/dts/mpc8536ds.dts | 8 ++++++++
> >1 files changed, 8 insertions(+), 0 deletions(-)
>
> Can you update the mpc8536ds_36b.dts as well (its in my next branch)
Sure thing.
arch/powerpc/boot/dts/mpc8536ds.dts | 8 ++++++++
arch/powerpc/boot/dts/mpc8536ds_36b.dts | 8 ++++++++
2 files changed, 16 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/boot/dts/mpc8536ds.dts b/arch/powerpc/boot/dts/mpc8536ds.dts
index 22caf69..815cebb 100644
--- a/arch/powerpc/boot/dts/mpc8536ds.dts
+++ b/arch/powerpc/boot/dts/mpc8536ds.dts
@@ -250,6 +250,14 @@
phy_type = "ulpi";
};
+ sdhci@2e000 {
+ compatible = "fsl,mpc8536-esdhc", "fsl,esdhc";
+ reg = <0x2e000 0x1000>;
+ interrupts = <72 0x2>;
+ interrupt-parent = <&mpic>;
+ clock-frequency = <250000000>;
+ };
+
serial0: serial@4500 {
cell-index = <0>;
device_type = "serial";
diff --git a/arch/powerpc/boot/dts/mpc8536ds_36b.dts b/arch/powerpc/boot/dts/mpc8536ds_36b.dts
index 113ed8b..d95b260 100644
--- a/arch/powerpc/boot/dts/mpc8536ds_36b.dts
+++ b/arch/powerpc/boot/dts/mpc8536ds_36b.dts
@@ -250,6 +250,14 @@
phy_type = "ulpi";
};
+ sdhci@2e000 {
+ compatible = "fsl,mpc8536-esdhc", "fsl,esdhc";
+ reg = <0x2e000 0x1000>;
+ interrupts = <72 0x2>;
+ interrupt-parent = <&mpic>;
+ clock-frequency = <250000000>;
+ };
+
serial0: serial@4500 {
cell-index = <0>;
device_type = "serial";
--
1.6.3.3
^ permalink raw reply related
* Re: [PATCH] spinlock: __raw_spin_is_locked() should return true for UP
From: Steven Rostedt @ 2009-08-18 23:36 UTC (permalink / raw)
To: Linus Torvalds; +Cc: peterz, linux-kernel, linuxppc-dev, mingo, tglx
In-Reply-To: <alpine.LFD.2.01.0908181618420.3158@localhost.localdomain>
On Tue, 18 Aug 2009, Linus Torvalds wrote:
>
>
> On Tue, 18 Aug 2009, Kumar Gala wrote:
> >
> > For some reason __raw_spin_is_locked() has been returning false for the
> > uni-processor, non-CONFIG_DEBUG_SPINLOCK. The UP + CONFIG_DEBUG_SPINLOCK
> > handles this correctly.
> >
> > Found this by enabling CONFIG_DEBUG_VM on PPC and hitting always hitting
> > a BUG_ON that was testing to make sure the pte_lock was held.
> >
> > Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
> > ---
> >
> > Linus, a fix for 2.6.31
>
> This really isn't all that clear.
>
> The thing is, some people may assert that a lock is held, but others could
> easily be looping until it's not held using something like
>
> while (spin_is_locked(lock))
> cpu_relax();
Wouldn't something like that be really racey? And anyone doing such a
thing had better have that code within an #ifdef CONFIG_SMP.
>
> so it's hard to tell whether it should return true or false in the case
> where spin-locking simply doesn't exist.
Actually, I did have a case where I would use it and would expect a return
of 0. That was in the experimental printk code to see if it was safe to
wakeup the klogd. I once had a check of the current cpu runqueue lock is
locked, and if it was, not to wake up klogd. I'm sure there's other cases
like this as well.
Thinking about it, UP probably should have spin_is_locked always return
false, but if you want to make sure you are not in a critical section
with the lock not held, then use assert_spin_locked, which on UP should be
a nop.
-- Steve
^ permalink raw reply
* [PATCH 3/3] powerpc/85xx: Add QE USB support for MPC8569E-MDS boards
From: Anton Vorontsov @ 2009-08-18 23:28 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev
- Add gpio-controller node for BCSR17, it is used to control USB
speed and VBUS;
- Add timer node for QE GTM, needed for USB host;
- Add usb node itself;
- Add some probing code for BCSR GPIOs.
NOTE: QE USB doesn't work on prototype boards, but should work on
pilot boards if specs and schematics are correct, though we
don't have the pilot boards to actually test it.
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
arch/powerpc/boot/dts/mpc8569mds.dts | 45 +++++++++++++++++++++++++++++
arch/powerpc/platforms/85xx/mpc85xx_mds.c | 4 ++
2 files changed, 49 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/boot/dts/mpc8569mds.dts b/arch/powerpc/boot/dts/mpc8569mds.dts
index a680165..880f896 100644
--- a/arch/powerpc/boot/dts/mpc8569mds.dts
+++ b/arch/powerpc/boot/dts/mpc8569mds.dts
@@ -99,8 +99,18 @@
};
bcsr@1,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
compatible = "fsl,mpc8569mds-bcsr";
reg = <1 0 0x8000>;
+ ranges = <0 1 0 0x8000>;
+
+ bcsr17: gpio-controller@11 {
+ #gpio-cells = <2>;
+ compatible = "fsl,mpc8569mds-bcsr-gpio";
+ reg = <0x11 0x1>;
+ gpio-controller;
+ };
};
nand@3,0 {
@@ -315,6 +325,14 @@
gpio-controller;
};
+ qe_pio_f: gpio-controller@a0 {
+ #gpio-cells = <2>;
+ compatible = "fsl,mpc8569-qe-pario-bank",
+ "fsl,mpc8323-qe-pario-bank";
+ reg = <0xa0 0x18>;
+ gpio-controller;
+ };
+
pio1: ucc_pin@01 {
pio-map = <
/* port pin dir open_drain assignment has_irq */
@@ -419,6 +437,16 @@
interrupt-parent = <&mpic>;
};
+ timer@440 {
+ compatible = "fsl,mpc8569-qe-gtm",
+ "fsl,qe-gtm", "fsl,gtm";
+ reg = <0x440 0x40>;
+ interrupts = <12 13 14 15>;
+ interrupt-parent = <&qeic>;
+ /* Filled in by U-Boot */
+ clock-frequency = <0>;
+ };
+
spi@4c0 {
#address-cells = <1>;
#size-cells = <0>;
@@ -446,6 +474,23 @@
mode = "cpu";
};
+ usb@6c0 {
+ compatible = "fsl,mpc8569-qe-usb",
+ "fsl,mpc8323-qe-usb";
+ reg = <0x6c0 0x40 0x8b00 0x100>;
+ interrupts = <11>;
+ interrupt-parent = <&qeic>;
+ fsl,fullspeed-clock = "clk5";
+ fsl,lowspeed-clock = "brg10";
+ gpios = <&qe_pio_f 3 0 /* USBOE */
+ &qe_pio_f 4 0 /* USBTP */
+ &qe_pio_f 5 0 /* USBTN */
+ &qe_pio_f 6 0 /* USBRP */
+ &qe_pio_f 8 0 /* USBRN */
+ &bcsr17 6 0 /* SPEED */
+ &bcsr17 5 1>; /* POWER */
+ };
+
enet0: ucc@2000 {
device_type = "network";
compatible = "ucc_geth";
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
index 60ed9c0..173d459 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
@@ -47,6 +47,7 @@
#include <asm/udbg.h>
#include <sysdev/fsl_soc.h>
#include <sysdev/fsl_pci.h>
+#include <sysdev/simple_gpio.h>
#include <asm/qe.h>
#include <asm/qe_ic.h>
#include <asm/mpic.h>
@@ -291,6 +292,9 @@ static struct of_device_id mpc85xx_ids[] = {
static int __init mpc85xx_publish_devices(void)
{
+ if (machine_is(mpc8569_mds))
+ simple_gpiochip_init("fsl,mpc8569mds-bcsr-gpio");
+
/* Publish the QE devices */
of_platform_bus_probe(NULL, mpc85xx_ids, NULL);
--
1.6.3.3
^ permalink raw reply related
* [PATCH 2/3] powerpc/82xx: Add CPM USB Gadget support for MPC8272ADS boards
From: Anton Vorontsov @ 2009-08-18 23:28 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev
- Add usb node;
- Configure pins and clocks;
- Enable USB function in BCSR.
The support was successfully tested using serial and ethernet gadget
drivers.
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
arch/powerpc/boot/dts/mpc8272ads.dts | 8 ++++++++
arch/powerpc/platforms/82xx/mpc8272_ads.c | 14 ++++++++++++++
2 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/boot/dts/mpc8272ads.dts b/arch/powerpc/boot/dts/mpc8272ads.dts
index 60f3327..e802ebd 100644
--- a/arch/powerpc/boot/dts/mpc8272ads.dts
+++ b/arch/powerpc/boot/dts/mpc8272ads.dts
@@ -173,6 +173,14 @@
fsl,cpm-command = <0xce00000>;
};
+ usb@11b60 {
+ compatible = "fsl,mpc8272-cpm-usb";
+ reg = <0x11b60 0x40 0x8b00 0x100>;
+ interrupts = <11 8>;
+ interrupt-parent = <&PIC>;
+ mode = "peripheral";
+ };
+
mdio@10d40 {
device_type = "mdio";
compatible = "fsl,mpc8272ads-mdio-bitbang",
diff --git a/arch/powerpc/platforms/82xx/mpc8272_ads.c b/arch/powerpc/platforms/82xx/mpc8272_ads.c
index 67e2184..30394b4 100644
--- a/arch/powerpc/platforms/82xx/mpc8272_ads.c
+++ b/arch/powerpc/platforms/82xx/mpc8272_ads.c
@@ -99,6 +99,15 @@ static struct cpm_pin mpc8272_ads_pins[] = {
/* I2C */
{3, 14, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_OPENDRAIN},
{3, 15, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_OPENDRAIN},
+
+ /* USB */
+ {2, 10, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
+ {2, 11, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
+ {2, 20, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
+ {2, 24, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
+ {3, 23, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
+ {3, 24, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
+ {3, 25, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
};
static void __init init_ioports(void)
@@ -112,6 +121,8 @@ static void __init init_ioports(void)
cpm2_clk_setup(CPM_CLK_SCC1, CPM_BRG1, CPM_CLK_RX);
cpm2_clk_setup(CPM_CLK_SCC1, CPM_BRG1, CPM_CLK_TX);
+ cpm2_clk_setup(CPM_CLK_SCC3, CPM_CLK8, CPM_CLK_RX);
+ cpm2_clk_setup(CPM_CLK_SCC3, CPM_CLK8, CPM_CLK_TX);
cpm2_clk_setup(CPM_CLK_SCC4, CPM_BRG4, CPM_CLK_RX);
cpm2_clk_setup(CPM_CLK_SCC4, CPM_BRG4, CPM_CLK_TX);
cpm2_clk_setup(CPM_CLK_FCC1, CPM_CLK11, CPM_CLK_RX);
@@ -147,6 +158,7 @@ static void __init mpc8272_ads_setup_arch(void)
#define BCSR1_FETH_RST 0x04000000
#define BCSR1_RS232_EN1 0x02000000
#define BCSR1_RS232_EN2 0x01000000
+#define BCSR3_USB_nEN 0x80000000
#define BCSR3_FETHIEN2 0x10000000
#define BCSR3_FETH2_RST 0x08000000
@@ -156,6 +168,8 @@ static void __init mpc8272_ads_setup_arch(void)
clrbits32(&bcsr[3], BCSR3_FETHIEN2);
setbits32(&bcsr[3], BCSR3_FETH2_RST);
+ clrbits32(&bcsr[3], BCSR3_USB_nEN);
+
iounmap(bcsr);
init_ioports();
--
1.6.3.3
^ permalink raw reply related
* [PATCH 1/3] powerpc/82xx: Fix BCSR bits for MPC8272ADS boards
From: Anton Vorontsov @ 2009-08-18 23:28 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev
mpc8272_ads.c is using BCSR bits definitions from pq2ads.h, but
according to User's Guide the bits are wrong for MPC8272ADS boards
(I guess definitions from pq2ads should only be used for PQ2FADS
boards).
So, let's introduce our own definitions for MPC8272ADS, and don't
include pq2ads.h.
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
arch/powerpc/platforms/82xx/mpc8272_ads.c | 8 +++++++-
1 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/platforms/82xx/mpc8272_ads.c b/arch/powerpc/platforms/82xx/mpc8272_ads.c
index 8054c68..67e2184 100644
--- a/arch/powerpc/platforms/82xx/mpc8272_ads.c
+++ b/arch/powerpc/platforms/82xx/mpc8272_ads.c
@@ -29,7 +29,6 @@
#include <sysdev/fsl_soc.h>
#include <sysdev/cpm2_pic.h>
-#include "pq2ads.h"
#include "pq2.h"
static void __init mpc8272_ads_pic_init(void)
@@ -144,6 +143,13 @@ static void __init mpc8272_ads_setup_arch(void)
return;
}
+#define BCSR1_FETHIEN 0x08000000
+#define BCSR1_FETH_RST 0x04000000
+#define BCSR1_RS232_EN1 0x02000000
+#define BCSR1_RS232_EN2 0x01000000
+#define BCSR3_FETHIEN2 0x10000000
+#define BCSR3_FETH2_RST 0x08000000
+
clrbits32(&bcsr[1], BCSR1_RS232_EN1 | BCSR1_RS232_EN2 | BCSR1_FETHIEN);
setbits32(&bcsr[1], BCSR1_FETH_RST);
--
1.6.3.3
^ permalink raw reply related
* Re: [PATCH] spinlock: __raw_spin_is_locked() should return true for UP
From: Linus Torvalds @ 2009-08-18 23:20 UTC (permalink / raw)
To: Kumar Gala; +Cc: peterz, linux-kernel, rostedt, linuxppc-dev, mingo, tglx
In-Reply-To: <1250635343-32546-1-git-send-email-galak@kernel.crashing.org>
On Tue, 18 Aug 2009, Kumar Gala wrote:
>
> For some reason __raw_spin_is_locked() has been returning false for the
> uni-processor, non-CONFIG_DEBUG_SPINLOCK. The UP + CONFIG_DEBUG_SPINLOCK
> handles this correctly.
>
> Found this by enabling CONFIG_DEBUG_VM on PPC and hitting always hitting
> a BUG_ON that was testing to make sure the pte_lock was held.
>
> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
> ---
>
> Linus, a fix for 2.6.31
This really isn't all that clear.
The thing is, some people may assert that a lock is held, but others could
easily be looping until it's not held using something like
while (spin_is_locked(lock))
cpu_relax();
so it's hard to tell whether it should return true or false in the case
where spin-locking simply doesn't exist.
Linus
^ permalink raw reply
* RE: Jumbo Frames, sil24 SATA driver, and kswapd0 page allocation failures
From: Jonathan Haws @ 2009-08-18 22:56 UTC (permalink / raw)
To: Chris Friesen; +Cc: linuxppc-dev@lists.ozlabs.org
In-Reply-To: <4A83442B.6080305@nortel.com>
> If the hardware supports it, the best way to deal with it is to set
> up
> the driver so that it only ever deals in single pages. =20
I am working on fixing the driver to support NETIF_F_SG and have changed ho=
w it receives packets to follow how the e1000 driver does it.
Here is where I am at:
When I get the first part of the frame, I allocate an skb for the packet. =
I call dev->page =3D alloc_page(GFP_ATOMIC) to allocate a page for the 4080=
bytes coming from the MAL.
I then setup a DMA mapping for that page to get the data out of the MAL (th=
e original code simply used dma_map_single, but I need a page).
Once the DMA map has been setup and data transferred, I call skb_fill_page_=
desc() to put the data into the skb. I then wrote a function called emac_c=
onsume_page, which unmaps the DMA mapping, frees the page, and updates the =
lengths in the skb.
The relevant source code is at the end of this email.
My problem is this:
When I run this code, it appears to create the fragmented packet just fine,=
but when it passes it up the stack, the kernel spits out these bugs, one a=
fter another:
BUG: Bad page state in process swapper pfn:0ee9b
page:c051f360 flags:(null) count:-3 mapcount:0 mapping:(null) index:766
Call Trace:
[c032bc30] [c0006ef0] show_stack+0x44/0x16c (unreliable)
[c032bc70] [c006c438] bad_page+0x94/0x130
[c032bc90] [c006d4a0] get_page_from_freelist+0x458/0x4d4
[c032bd20] [c006d5f4] __alloc_pages_nodemask+0xd8/0x4f8
[c032bda0] [c01a1174] emac_poll_rx+0x300/0x9c8
[c032bdf0] [c019cb64] mal_poll+0xa8/0x1ec
[c032be20] [c01cf218] net_rx_action+0x9c/0x1b4
[c032be50] [c0039678] __do_softirq+0xc4/0x148
[c032be90] [c0004d18] do_softirq+0x78/0x80
[c032bea0] [c0039264] irq_exit+0x64/0x7c
[c032beb0] [c0005210] do_IRQ+0x9c/0xb4
[c032bed0] [c000fa7c] ret_from_except+0x0/0x18
[c032bf90] [c000808c] cpu_idle+0xdc/0xec
[c032bfb0] [c00028fc] rest_init+0x70/0x84
[c032bfc0] [c02e0864] start_kernel+0x240/0x2c4
[c032bff0] [c0002254] start_here+0x44/0xb0
BUG: Bad page state in process swapper pfn:0ee8c
page:c051f180 flags:(null) count:-3 mapcount:0 mapping:(null) index:757
Call Trace:
[c032bc30] [c0006ef0] show_stack+0x44/0x16c (unreliable)
[c032bc70] [c006c438] bad_page+0x94/0x130
[c032bc90] [c006d4a0] get_page_from_freelist+0x458/0x4d4
[c032bd20] [c006d5f4] __alloc_pages_nodemask+0xd8/0x4f8
[c032bda0] [c01a1174] emac_poll_rx+0x300/0x9c8
[c032bdf0] [c019cb64] mal_poll+0xa8/0x1ec
[c032be20] [c01cf218] net_rx_action+0x9c/0x1b4
[c032be50] [c0039678] __do_softirq+0xc4/0x148
[c032be90] [c0004d18] do_softirq+0x78/0x80
[c032bea0] [c0039264] irq_exit+0x64/0x7c
[c032beb0] [c0005210] do_IRQ+0x9c/0xb4
[c032bed0] [c000fa7c] ret_from_except+0x0/0x18
[c032bf90] [c000808c] cpu_idle+0xdc/0xec
[c032bfb0] [c00028fc] rest_init+0x70/0x84
[c032bfc0] [c02e0864] start_kernel+0x240/0x2c4
[c032bff0] [c0002254] start_here+0x44/0xb0
I know that I am missing something when it comes to allocating the pages fo=
r the fragments, but when I compare my methodology to the e1000 driver, the=
y appear to be functionally the same?
Any ideas? I can send the entire source file for the driver if needs be.
Thanks!
Jonathan
Here is the source:
static int emac_poll_rx(void *param, int budget)
{
... /* Other code is here */
push_packet:
skb->dev =3D dev->ndev;
skb->protocol =3D eth_type_trans(skb, dev->ndev);
emac_rx_csum(dev, skb, ctrl);
if (unlikely(netif_receive_skb(skb) =3D=3D NET_RX_DROP))
++dev->estats.rx_dropped_stack;
next:
++dev->stats.rx_packets;
skip:
dev->stats.rx_bytes +=3D len;
slot =3D (slot + 1) % NUM_RX_BUFF;
--budget;
++received;
continue;
sg:
if (ctrl & MAL_RX_CTRL_FIRST) {
BUG_ON(dev->rx_sg_skb);
if (unlikely(emac_alloc_rx_skb2(dev, slot, GFP_ATOMIC))) {
DBG(dev, "rx OOM %d (%d) (%d)" NL, slot, dev->rx_skb_size, len);
++dev->estats.rx_dropped_oom;
emac_recycle_rx_skb(dev, slot, 0);
} else {
dev->rx_sg_skb =3D skb;
skb_fill_page_desc(dev->rx_sg_skb, 0, dev->page, 0, len);
emac_consume_page(dev, len, slot);
dev->rx_sg_skb->len +=3D ETH_HLEN;
}
} else if (!emac_rx_sg_append(dev, slot) && (ctrl & MAL_RX_CTRL_LAST)) {
skb =3D dev->rx_sg_skb;
dev->rx_sg_skb =3D NULL;
ctrl &=3D EMAC_BAD_RX_MASK;
if (unlikely(ctrl && ctrl !=3D EMAC_RX_TAH_BAD_CSUM)) {
emac_parse_rx_error(dev, ctrl);
++dev->estats.rx_dropped_error;
dev_kfree_skb(skb);
len =3D 0;
} else
goto push_packet;
}
... /* Other code is here */
} /* end of emac_poll_rx */
static inline int emac_alloc_rx_skb2(struct emac_instance *dev, int slot,
gfp_t flags)
{
struct sk_buff *skb =3D alloc_skb(242, flags);
if (unlikely(!skb))
return -ENOMEM;
dev->rx_skb[slot] =3D skb;
dev->rx_desc[slot].data_len =3D 0;
dev->page =3D alloc_page(flags);
DBG(dev, "emac_alloc_skb2: page %x" NL, dev->page);
if(unlikely(!dev->page))
{
return -1;
}
dev->rx_desc[slot].data_ptr =3D dma_map_page(&dev->ofdev->dev, dev->page, =
0, 4096, DMA_FROM_DEVICE);
wmb();
dev->rx_desc[slot].ctrl =3D MAL_RX_CTRL_EMPTY |
(slot =3D=3D (NUM_RX_BUFF - 1) ? MAL_RX_CTRL_WRAP : 0);
return 0;
} /* end of emac_alloc_rx_skb2 */
static inline void emac_consume_page(struct emac_instance* dev, int length,=
int slot)
{
dma_unmap_page(&dev->ofdev->dev, dev->rx_desc[slot].data_ptr, 4096, DMA_FR=
OM_DEVICE);
wmb();
__free_page(dev->page);
dev->page =3D NULL;
dev->rx_sg_skb->len +=3D length;
dev->rx_sg_skb->data_len +=3D length;
dev->rx_sg_skb->truesize +=3D length;
}
static inline int emac_rx_sg_append(struct emac_instance *dev, int slot)
{
if (likely(dev->rx_sg_skb !=3D NULL)) {
int len =3D dev->rx_desc[slot].data_len;
int tot_len =3D dev->rx_sg_skb->len + len;
if (unlikely(tot_len + 2 > dev->max_mtu)) {
++dev->estats.rx_dropped_mtu;
dev_kfree_skb(dev->rx_sg_skb);
dev->rx_sg_skb =3D NULL;
} else {
dev->page =3D alloc_page(GFP_ATOMIC);
if(unlikely(!dev->page))
{
return -ENOMEM;
}
dev->rx_desc[slot].data_ptr =3D dma_map_page(&dev->ofdev->dev, dev->page=
, 0, 4096, DMA_FROM_DEVICE);
dev->rx_desc[slot].data_len =3D 0;
wmb();
dev->rx_desc[slot].ctrl =3D MAL_RX_CTRL_EMPTY | (slot =3D=3D (NUM_RX_BUF=
F - 1) ? MAL_RX_CTRL_WRAP : 0);
skb_fill_page_desc(dev->rx_sg_skb, skb_shinfo(dev->rx_sg_skb)->nr_frags,=
dev->page, 0, len);
emac_consume_page(dev, len, slot);
return 0;
}
}
emac_recycle_rx_skb(dev, slot, 0);
return -1;
} /* end of emac_rx_sg_append */
^ permalink raw reply
* Re: [PATCH v2] qe_lib: Set gpio data before changing the direction to output
From: Anton Vorontsov @ 2009-08-18 22:56 UTC (permalink / raw)
To: Timur Tabi; +Cc: linuxppc-dev, Michael Barkowski
In-Reply-To: <4A8B2C1C.3060403@freescale.com>
On Tue, Aug 18, 2009 at 05:33:00PM -0500, Timur Tabi wrote:
> Anton Vorontsov wrote:
> > On Tue, Aug 18, 2009 at 05:20:44PM -0400, Michael Barkowski wrote:
> >> This avoids having a short glitch if the desired initial value is not
> >> the same as what was previously in the data register.
> >>
> >> Signed-off-by: Michael Barkowski <michaelbarkowski@ruggedcom.com>
> >
> > Acked-by: Anton Vorontsov <avorontsov@ru.mvista.com>
>
> I don't have the time to test this patch, so I abstain from acking. :-)
> If Anton likes it, that's good enough for me.
You made me doubt for a moment. :-) Thanks for the suspiciousness.
What happens if a pin was previously configured as input? Does our
write to the data register survive? For MPC8xxx GPIO controllers
it does. And randomly taken QE spec says:
A write to CPDAT is latched, and if the corresponding CPDIR
bits have configured the port pin as an output, the latched
value is driven onto the respective pin. However, if the
corresponding CPDIR bits have configured the port pin as an
input, the latched value is prevented from reaching the pin.
I guess we're safe, but Michael, could you actually test it
(if not already)?
Thanks!
--
Anton Vorontsov
email: cbouatmailru@gmail.com
irc://irc.freenode.net/bd2
^ permalink raw reply
* [PATCH] spinlock: __raw_spin_is_locked() should return true for UP
From: Kumar Gala @ 2009-08-18 22:42 UTC (permalink / raw)
To: Linus Torvalds; +Cc: peterz, linux-kernel, rostedt, linuxppc-dev, mingo, tglx
For some reason __raw_spin_is_locked() has been returning false for the
uni-processor, non-CONFIG_DEBUG_SPINLOCK. The UP + CONFIG_DEBUG_SPINLOCK
handles this correctly.
Found this by enabling CONFIG_DEBUG_VM on PPC and hitting always hitting
a BUG_ON that was testing to make sure the pte_lock was held.
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
Linus, a fix for 2.6.31
include/linux/spinlock_up.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/include/linux/spinlock_up.h b/include/linux/spinlock_up.h
index d4841ed..2b372e0 100644
--- a/include/linux/spinlock_up.h
+++ b/include/linux/spinlock_up.h
@@ -57,7 +57,7 @@ static inline void __raw_spin_unlock(raw_spinlock_t *lock)
#define __raw_write_unlock(lock) do { (void)(lock); } while (0)
#else /* DEBUG_SPINLOCK */
-#define __raw_spin_is_locked(lock) ((void)(lock), 0)
+#define __raw_spin_is_locked(lock) ((void)(lock), 1)
/* for sched.c and kernel_lock.c: */
# define __raw_spin_lock(lock) do { (void)(lock); } while (0)
# define __raw_spin_lock_flags(lock, flags) do { (void)(lock); } while (0)
--
1.6.0.6
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox