LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH][powerpc/85xx] P2020RDB Platform Support Added
From: Felix Radensky @ 2009-08-06  6:25 UTC (permalink / raw)
  To: Poonam Aggrwal; +Cc: linuxppc-dev, linuxppc-release
In-Reply-To: <1249532639-20070-1-git-send-email-poonam.aggrwal@freescale.com>

Hi, Poonam

Poonam Aggrwal wrote:
> Adds P2020RDB basic support in linux.
> Overview of P2020RDB platform
> 	- DDR
> 	  DDR2 1G
> 	- NOR Flash
> 	  16MByte
> 	- NAND Flash
> 	  32MByte
> 	- 3 Ethernet interfaces
> 	  1) etSEC1
> 		- RGMII
> 		- connected to a 5 port Vitesse Switch(VSC7385)
> 		- Switch is memory mapped through eLBC interface(CS#2)
> 		- IRQ1
> 	  2) etSEC2
> 		- SGMII
> 		- connected to VSC8221
> 		- IRQ2
> 	  3) etSEC3
> 		- RGMII
> 		- connected to VSC8641
> 		- IRQ3
> 	- 2 1X PCIe interfaces
> 	- SD/MMC ,USB
> 	- SPI EEPROM
> 	- Serial I2C EEPROM
>
> Signed-off-by: Poonam Aggrwal <poonam.aggrwal@freescale.com>
> ---
> based on http://www.kernel.org/pub/scm/linux/kernel/git/galak/powerpc.git
>  arch/powerpc/boot/dts/p2020rdb.dts        |  586 +++++++++++++++++++++++++++++
>  arch/powerpc/configs/mpc85xx_defconfig    |    1 +
>  arch/powerpc/platforms/85xx/Kconfig       |    9 +
>  arch/powerpc/platforms/85xx/Makefile      |    3 +-
>  arch/powerpc/platforms/85xx/mpc85xx_rdb.c |  141 +++++++
>  5 files changed, 739 insertions(+), 1 deletions(-)
>  create mode 100644 arch/powerpc/boot/dts/p2020rdb.dts
>  create mode 100644 arch/powerpc/platforms/85xx/mpc85xx_rdb.c
>
> diff --git a/arch/powerpc/boot/dts/p2020rdb.dts b/arch/powerpc/boot/dts/p2020rdb.dts
> new file mode 100644
> index 0000000..d6d8131
> --- /dev/null
> +++ b/arch/powerpc/boot/dts/p2020rdb.dts
> @@ -0,0 +1,586 @@
> +/*
> + * P2020 RDB Device Tree Source
> + *
> + * Copyright 2009 Freescale Semiconductor Inc.
> + *
> + * This program is free software; you can redistribute  it and/or modify it
> + * under  the terms of  the GNU General  Public License as published by the
> + * Free Software Foundation;  either version 2 of the  License, or (at your
> + * option) any later version.
> + */
> +
> +/dts-v1/;
> +/ {
> +	model = "fsl,P2020";
> +	compatible = "fsl,P2020RDB";
> +	#address-cells = <2>;
> +	#size-cells = <2>;
> +
> +	aliases {
> +		ethernet0 = &enet0;
> +		ethernet1 = &enet1;
> +		ethernet2 = &enet2;
> +		serial0 = &serial0;
> +		serial1 = &serial1;
> +		pci0 = &pci0;
> +		pci1 = &pci1;
> +	};
> +
> +	cpus {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		PowerPC,P2020@0 {
> +			device_type = "cpu";
> +			reg = <0x0>;
> +			next-level-cache = <&L2>;
> +		};
> +
> +		PowerPC,P2020@1 {
> +			device_type = "cpu";
> +			reg = <0x1>;
> +			next-level-cache = <&L2>;
> +		};
> +	};
> +
> +	memory {
> +		device_type = "memory";
> +	};
> +
> +	localbus@ffe05000 {
> +		#address-cells = <2>;
> +		#size-cells = <1>;
> +		compatible = "fsl,p2020-elbc", "fsl,elbc", "simple-bus";
> +		reg = <0 0xffe05000 0 0x1000>;
> +		interrupts = <19 2>;
> +		interrupt-parent = <&mpic>;
> +
> +		/* NOR and NAND Flashes */
> +		ranges = <0x0 0x0 0x0 0xef000000 0x01000000
> +			  0x1 0x0 0x0 0xffa00000 0x00040000
> +			  0x2 0x0 0x0 0xffb00000 0x08000000>;
>   

The comment is a bit misleading, CS2 is L2 switch. Also, are you sure
the CS2 range shouldn't look like
      
0x2 0x0 0x0 0xffb00000 0x00020000

That's what L2switch reg property suggests.            
> +
> +		nor@0,0 {
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +			compatible = "cfi-flash";
> +			reg = <0x0 0x0 0x1000000>;
> +			bank-width = <2>;
> +			device-width = <1>;
> +
> +			vitesse-7385-fw@0 {
> +				/* This location must not be altered  */
> +				/* 256KB for Vitesse 7385 Switch firmware */
> +				reg = <0x0 0x00040000>;
> +				label = "NOR (RO) Vitesse-7385 Firmware";
> +				read-only;
> +			};
>   
Partitions should be declared as

       partition@0 {
                   reg = ...
                   label = ...
                   ...
        } 

Felix.

^ permalink raw reply

* [PATCH v2] powerpc: Allow perf_counters to access user memory at interrupt time
From: Paul Mackerras @ 2009-08-06  4:57 UTC (permalink / raw)
  To: linuxppc-dev, linux-kernel

This provides a mechanism to allow the perf_counters code to access
user memory in a PMU interrupt routine.  Such an access can cause
various kinds of interrupt: SLB miss, MMU hash table miss, segment
table miss, or TLB miss, depending on the processor.  This commit
only deals with the classic/server processors that use an MMU hash
table, not processors that have software-loaded TLBs.

On 64-bit processors, an SLB miss interrupt on a user address will
update the slb_cache and slb_cache_ptr fields in the paca.  This is
OK except in the case where a PMU interrupt occurs in switch_slb,
which also accesses those fields.  To prevent this, we hard-disable
interrupts in switch_slb.  Interrupts are already soft-disabled at
this point, and will get hard-enabled when they get soft-enabled
later.

This also reworks slb_flush_and_rebolt: to avoid hard-disabling twice,
and to make sure that it clears the slb_cache_ptr when called from
other callers than switch_slb, the existing routine is renamed to
__slb_flush_and_rebolt, which is called by switch_slb and the new
version of slb_flush_and_rebolt.

Similarly, switch_stab (used on POWER3 and RS64 processors) gets a
hard_irq_disable() to protect the per-cpu variables used there and
in ste_allocate.

If a MMU hashtable miss interrupt occurs, normally we would call
hash_page to look up the Linux PTE for the address and create a HPTE.
However, hash_page is fairly complex and takes some locks, so to
avoid the possibility of deadlock, we check the preemption count
to see if we are in a (pseudo-)NMI handler, and if so, we don't call
hash_page but instead treat it like a bad access that will get
reported up through the exception table mechanism.  An interrupt
whose handler runs even though the interrupt occurred when
soft-disabled (such as the PMU interrupt) is considered a pseudo-NMI
handler, which should use nmi_enter()/nmi_exit() rather than
irq_enter()/irq_exit().

32-bit processors with an MMU hash table are already able to access
user memory at interrupt time.  Since we don't soft-disable on 32-bit,
we avoid the possibility of reentering hash_page, which runs with
interrupts disabled.

Signed-off-by: Paul Mackerras <paulus@samba.org>
---
Note, this version uses the NMI bit in the preempt count instead of
adding a paca field.

 arch/powerpc/include/asm/paca.h      |    2 +-
 arch/powerpc/kernel/asm-offsets.c    |    2 +
 arch/powerpc/kernel/exceptions-64s.S |   19 +++++++++++++++++
 arch/powerpc/mm/slb.c                |   37 +++++++++++++++++++++++----------
 arch/powerpc/mm/stab.c               |   11 +++++++++-
 5 files changed, 58 insertions(+), 13 deletions(-)

diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h
index c8a3cbf..63f8415 100644
--- a/arch/powerpc/include/asm/paca.h
+++ b/arch/powerpc/include/asm/paca.h
@@ -105,7 +105,7 @@ struct paca_struct {
 	u8 soft_enabled;		/* irq soft-enable flag */
 	u8 hard_enabled;		/* set if irqs are enabled in MSR */
 	u8 io_sync;			/* writel() needs spin_unlock sync */
-	u8 perf_counter_pending;	/* PM interrupt while soft-disabled */
+	u8 perf_counter_pending;	/* perf_counter stuff needs wakeup */
 
 	/* Stuff for accurate time accounting */
 	u64 user_time;			/* accumulated usermode TB ticks */
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 561b646..197b156 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -67,6 +67,8 @@ int main(void)
 	DEFINE(MMCONTEXTID, offsetof(struct mm_struct, context.id));
 #ifdef CONFIG_PPC64
 	DEFINE(AUDITCONTEXT, offsetof(struct task_struct, audit_context));
+	DEFINE(SIGSEGV, SIGSEGV);
+	DEFINE(NMI_MASK, NMI_MASK);
 #else
 	DEFINE(THREAD_INFO, offsetof(struct task_struct, stack));
 #endif /* CONFIG_PPC64 */
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index eb89811..8ac85e0 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -729,6 +729,11 @@ BEGIN_FTR_SECTION
 	bne-	do_ste_alloc		/* If so handle it */
 END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
 
+	clrrdi	r11,r1,THREAD_SHIFT
+	lwz	r0,TI_PREEMPT(r11)	/* If we're in an "NMI" */
+	andis.	r0,r0,NMI_MASK@h	/* (i.e. an irq when soft-disabled) */
+	bne	77f			/* then don't call hash_page now */
+
 	/*
 	 * On iSeries, we soft-disable interrupts here, then
 	 * hard-enable interrupts so that the hash_page code can spin on
@@ -833,6 +838,20 @@ handle_page_fault:
 	bl	.low_hash_fault
 	b	.ret_from_except
 
+/*
+ * We come here as a result of a DSI at a point where we don't want
+ * to call hash_page, such as when we are accessing memory (possibly
+ * user memory) inside a PMU interrupt that occurred while interrupts
+ * were soft-disabled.  We want to invoke the exception handler for
+ * the access, or panic if there isn't a handler.
+ */
+77:	bl	.save_nvgprs
+	mr	r4,r3
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	li	r5,SIGSEGV
+	bl	.bad_page_fault
+	b	.ret_from_except
+
 	/* here we have a segment miss */
 do_ste_alloc:
 	bl	.ste_allocate		/* try to insert stab entry */
diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c
index 5b7038f..a685652 100644
--- a/arch/powerpc/mm/slb.c
+++ b/arch/powerpc/mm/slb.c
@@ -92,15 +92,13 @@ static inline void create_shadowed_slbe(unsigned long ea, int ssize,
 		     : "memory" );
 }
 
-void slb_flush_and_rebolt(void)
+static void __slb_flush_and_rebolt(void)
 {
 	/* If you change this make sure you change SLB_NUM_BOLTED
 	 * appropriately too. */
 	unsigned long linear_llp, vmalloc_llp, lflags, vflags;
 	unsigned long ksp_esid_data, ksp_vsid_data;
 
-	WARN_ON(!irqs_disabled());
-
 	linear_llp = mmu_psize_defs[mmu_linear_psize].sllp;
 	vmalloc_llp = mmu_psize_defs[mmu_vmalloc_psize].sllp;
 	lflags = SLB_VSID_KERNEL | linear_llp;
@@ -117,12 +115,6 @@ void slb_flush_and_rebolt(void)
 		ksp_vsid_data = get_slb_shadow()->save_area[2].vsid;
 	}
 
-	/*
-	 * We can't take a PMU exception in the following code, so hard
-	 * disable interrupts.
-	 */
-	hard_irq_disable();
-
 	/* We need to do this all in asm, so we're sure we don't touch
 	 * the stack between the slbia and rebolting it. */
 	asm volatile("isync\n"
@@ -139,6 +131,21 @@ void slb_flush_and_rebolt(void)
 		     : "memory");
 }
 
+void slb_flush_and_rebolt(void)
+{
+
+	WARN_ON(!irqs_disabled());
+
+	/*
+	 * We can't take a PMU exception in the following code, so hard
+	 * disable interrupts.
+	 */
+	hard_irq_disable();
+
+	__slb_flush_and_rebolt();
+	get_paca()->slb_cache_ptr = 0;
+}
+
 void slb_vmalloc_update(void)
 {
 	unsigned long vflags;
@@ -180,12 +187,20 @@ static inline int esids_match(unsigned long addr1, unsigned long addr2)
 /* Flush all user entries from the segment table of the current processor. */
 void switch_slb(struct task_struct *tsk, struct mm_struct *mm)
 {
-	unsigned long offset = get_paca()->slb_cache_ptr;
+	unsigned long offset;
 	unsigned long slbie_data = 0;
 	unsigned long pc = KSTK_EIP(tsk);
 	unsigned long stack = KSTK_ESP(tsk);
 	unsigned long unmapped_base;
 
+	/*
+	 * We need interrupts hard-disabled here, not just soft-disabled,
+	 * so that a PMU interrupt can't occur, which might try to access
+	 * user memory (to get a stack trace) and possible cause an SLB miss
+	 * which would update the slb_cache/slb_cache_ptr fields in the PACA.
+	 */
+	hard_irq_disable();
+	offset = get_paca()->slb_cache_ptr;
 	if (!cpu_has_feature(CPU_FTR_NO_SLBIE_B) &&
 	    offset <= SLB_CACHE_ENTRIES) {
 		int i;
@@ -200,7 +215,7 @@ void switch_slb(struct task_struct *tsk, struct mm_struct *mm)
 		}
 		asm volatile("isync" : : : "memory");
 	} else {
-		slb_flush_and_rebolt();
+		__slb_flush_and_rebolt();
 	}
 
 	/* Workaround POWER5 < DD2.1 issue */
diff --git a/arch/powerpc/mm/stab.c b/arch/powerpc/mm/stab.c
index 98cd1dc..ab5fb48 100644
--- a/arch/powerpc/mm/stab.c
+++ b/arch/powerpc/mm/stab.c
@@ -164,7 +164,7 @@ void switch_stab(struct task_struct *tsk, struct mm_struct *mm)
 {
 	struct stab_entry *stab = (struct stab_entry *) get_paca()->stab_addr;
 	struct stab_entry *ste;
-	unsigned long offset = __get_cpu_var(stab_cache_ptr);
+	unsigned long offset;
 	unsigned long pc = KSTK_EIP(tsk);
 	unsigned long stack = KSTK_ESP(tsk);
 	unsigned long unmapped_base;
@@ -172,6 +172,15 @@ void switch_stab(struct task_struct *tsk, struct mm_struct *mm)
 	/* Force previous translations to complete. DRENG */
 	asm volatile("isync" : : : "memory");
 
+	/*
+	 * We need interrupts hard-disabled here, not just soft-disabled,
+	 * so that a PMU interrupt can't occur, which might try to access
+	 * user memory (to get a stack trace) and possible cause an STAB miss
+	 * which would update the stab_cache/stab_cache_ptr per-cpu variables.
+	 */
+	hard_irq_disable();
+
+	offset = __get_cpu_var(stab_cache_ptr);
 	if (offset <= NR_STAB_CACHE_ENTRIES) {
 		int i;
 
-- 
1.5.5.rc3.7.gba13

^ permalink raw reply related

* [PATCH v2] perf_counter: powerpc: Add callchain support
From: Paul Mackerras @ 2009-08-06  4:58 UTC (permalink / raw)
  To: linuxppc-dev, linux-kernel
In-Reply-To: <19066.25278.925555.133212@drongo.ozlabs.ibm.com>

This adds support for tracing callchains for powerpc, both 32-bit
and 64-bit, and both in the kernel and userspace, from PMU interrupt
context.

The first three entries stored for each callchain are the NIP (next
instruction pointer), LR (link register), and the contents of the LR
save area in the second stack frame (the first is ignored because the
ABI convention on powerpc is that functions save their return address
in their caller's stack frame).  Because functions don't have to save
their return address (LR value) and don't have to establish a stack
frame, it's possible for either or both of LR and the second stack
frame's LR save area to have valid return addresses in them.  This
is basically impossible to disambiguate without either reading the
code or looking at auxiliary information such as CFI tables.  Since
we don't want to do that at interrupt time, we store both LR and the
second stack frame's LR save area.

Once we get past the second stack frame, there is no ambiguity; all
return addresses we get are reliable.

For kernel traces, we check whether they are valid kernel instruction
addresses and store zero instead if they are not (rather than
omitting them, which would make it impossible for userspace to know
which was which).  We also store zero instead of the second stack
frame's LR save area value if it is the same as LR.

For kernel traces, we check for interrupt frames, and for user traces,
we check for signal frames.  In each case, since we're starting a new
trace, we store a PERF=5FCONTEXT=5FKERNEL/USER marker so that userspace=

knows that the next three entries are NIP, LR and the second stack fram=
e
for the interrupted context.

We read user memory with =5F=5Fget=5Fuser=5Finatomic.  On 64-bit, if th=
is
PMU interrupt occurred while interrupts are soft-disabled, and
there is no MMU hash table entry for the page, we will get an
-EFAULT return from =5F=5Fget=5Fuser=5Finatomic even if there is a vali=
d
Linux PTE for the page, since hash=5Fpage isn't reentrant.  Thus we
have code here to read the Linux PTE and access the page via the
kernel linear mapping.  Since 64-bit doesn't use (or need) highmem
there is no need to do kmap=5Fatomic.  On 32-bit, we don't do soft
interrupt disabling, so this complication doesn't occur and there
is no need to fall back to reading the Linux PTE, since hash=5Fpage
will get called automatically if necessary.

Note that we cannot get PMU interrupts in the interval during
context switch between switch=5Fmm (which switches the user address
space) and switch=5Fto (which actually changes current to the new
process).  On 64-bit this is because interrupts are hard-disabled
in switch=5Fmm and stay hard-disabled until they are soft-enabled
later, after switch=5Fto has returned.  So there is no possibility
of trying to do a user stack trace when the user address space is
not current's address space.

Signed-off-by: Paul Mackerras <paulus@samba.org>
---
 arch/powerpc/kernel/Makefile         |    2 +-
 arch/powerpc/kernel/perf=5Fcallchain.c |  520 ++++++++++++++++++++++++=
++++++++++
 2 files changed, 521 insertions(+), 1 deletions(-)
 create mode 100644 arch/powerpc/kernel/perf=5Fcallchain.c

diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefil=
e
index b73396b..9619285 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -97,7 +97,7 @@ obj64-$(CONFIG=5FAUDIT)=09=09+=3D compat=5Faudit.o
=20
 obj-$(CONFIG=5FDYNAMIC=5FFTRACE)=09+=3D ftrace.o
 obj-$(CONFIG=5FFUNCTION=5FGRAPH=5FTRACER)=09+=3D ftrace.o
-obj-$(CONFIG=5FPPC=5FPERF=5FCTRS)=09+=3D perf=5Fcounter.o
+obj-$(CONFIG=5FPPC=5FPERF=5FCTRS)=09+=3D perf=5Fcounter.o perf=5Fcallc=
hain.o
 obj64-$(CONFIG=5FPPC=5FPERF=5FCTRS)=09+=3D power4-pmu.o ppc970-pmu.o p=
ower5-pmu.o \
 =09=09=09=09   power5+-pmu.o power6-pmu.o power7-pmu.o
 obj32-$(CONFIG=5FPPC=5FPERF=5FCTRS)=09+=3D mpc7450-pmu.o
diff --git a/arch/powerpc/kernel/perf=5Fcallchain.c b/arch/powerpc/kern=
el/perf=5Fcallchain.c
new file mode 100644
index 0000000..ed13777
--- /dev/null
+++ b/arch/powerpc/kernel/perf=5Fcallchain.c
@@ -0,0 +1,520 @@
+/*
+ * Performance counter callchain support - powerpc architecture code
+ *
+ * Copyright =A9 2009 Paul Mackerras, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/perf=5Fcounter.h>
+#include <linux/percpu.h>
+#include <linux/uaccess.h>
+#include <linux/mm.h>
+#include <asm/ptrace.h>
+#include <asm/pgtable.h>
+#include <asm/sigcontext.h>
+#include <asm/ucontext.h>
+#include <asm/vdso.h>
+#ifdef CONFIG=5FPPC64
+#include "ppc32.h"
+#endif
+
+/*
+ * Store another value in a callchain=5Fentry.
+ */
+static inline void callchain=5Fstore(struct perf=5Fcallchain=5Fentry *=
entry, u64 ip)
+{
+=09unsigned int nr =3D entry->nr;
+
+=09if (nr < PERF=5FMAX=5FSTACK=5FDEPTH) {
+=09=09entry->ip[nr] =3D ip;
+=09=09entry->nr =3D nr + 1;
+=09}
+}
+
+/*
+ * Is sp valid as the address of the next kernel stack frame after pre=
v=5Fsp=3F
+ * The next frame may be in a different stack area but should not go
+ * back down in the same stack area.
+ */
+static int valid=5Fnext=5Fsp(unsigned long sp, unsigned long prev=5Fsp=
)
+{
+=09if (sp & 0xf)
+=09=09return 0;=09=09/* must be 16-byte aligned */
+=09if (!validate=5Fsp(sp, current, STACK=5FFRAME=5FOVERHEAD))
+=09=09return 0;
+=09if (sp >=3D prev=5Fsp + STACK=5FFRAME=5FOVERHEAD)
+=09=09return 1;
+=09/*
+=09 * sp could decrease when we jump off an interrupt stack
+=09 * back to the regular process stack.
+=09 */
+=09if ((sp & ~(THREAD=5FSIZE - 1)) !=3D (prev=5Fsp & ~(THREAD=5FSIZE -=
 1)))
+=09=09return 1;
+=09return 0;
+}
+
+static void perf=5Fcallchain=5Fkernel(struct pt=5Fregs *regs,
+=09=09=09=09  struct perf=5Fcallchain=5Fentry *entry)
+{
+=09unsigned long sp, next=5Fsp;
+=09unsigned long next=5Fip;
+=09unsigned long lr;
+=09long level =3D 0;
+=09unsigned long *fp;
+
+=09lr =3D regs->link;
+=09sp =3D regs->gpr[1];
+=09callchain=5Fstore(entry, PERF=5FCONTEXT=5FKERNEL);
+=09callchain=5Fstore(entry, regs->nip);
+
+=09if (!validate=5Fsp(sp, current, STACK=5FFRAME=5FOVERHEAD))
+=09=09return;
+
+=09for (;;) {
+=09=09fp =3D (unsigned long *) sp;
+=09=09next=5Fsp =3D fp[0];
+
+=09=09if (next=5Fsp =3D=3D sp + STACK=5FINT=5FFRAME=5FSIZE &&
+=09=09    fp[STACK=5FFRAME=5FMARKER] =3D=3D STACK=5FFRAME=5FREGS=5FMAR=
KER) {
+=09=09=09/*
+=09=09=09 * This looks like an interrupt frame for an
+=09=09=09 * interrupt that occurred in the kernel
+=09=09=09 */
+=09=09=09regs =3D (struct pt=5Fregs *)(sp + STACK=5FFRAME=5FOVERHEAD);=

+=09=09=09next=5Fip =3D regs->nip;
+=09=09=09lr =3D regs->link;
+=09=09=09level =3D 0;
+=09=09=09callchain=5Fstore(entry, PERF=5FCONTEXT=5FKERNEL);
+
+=09=09} else {
+=09=09=09if (level =3D=3D 0)
+=09=09=09=09next=5Fip =3D lr;
+=09=09=09else
+=09=09=09=09next=5Fip =3D fp[STACK=5FFRAME=5FLR=5FSAVE];
+
+=09=09=09/*
+=09=09=09 * We can't tell which of the first two addresses
+=09=09=09 * we get are valid, but we can filter out the
+=09=09=09 * obviously bogus ones here.  We replace them
+=09=09=09 * with 0 rather than removing them entirely so
+=09=09=09 * that userspace can tell which is which.
+=09=09=09 */
+=09=09=09if ((level =3D=3D 1 && next=5Fip =3D=3D lr) ||
+=09=09=09    (level <=3D 1 && !kernel=5Ftext=5Faddress(next=5Fip)))
+=09=09=09=09next=5Fip =3D 0;
+
+=09=09=09++level;
+=09=09}
+
+=09=09callchain=5Fstore(entry, next=5Fip);
+=09=09if (!valid=5Fnext=5Fsp(next=5Fsp, sp))
+=09=09=09return;
+=09=09sp =3D next=5Fsp;
+=09}
+}
+
+#ifdef CONFIG=5FPPC64
+/*
+ * On 64-bit we don't want to invoke hash=5Fpage on user addresses fro=
m
+ * interrupt context, so if the access faults, we read the page tables=

+ * to find which page (if any) is mapped and access it directly.
+ */
+static int read=5Fuser=5Fstack=5Fslow(void =5F=5Fuser *ptr, void *ret,=
 int nb)
+{
+=09pgd=5Ft *pgdir;
+=09pte=5Ft *ptep, pte;
+=09int pagesize;
+=09unsigned long addr =3D (unsigned long) ptr;
+=09unsigned long offset;
+=09unsigned long pfn;
+=09void *kaddr;
+
+=09pgdir =3D current->mm->pgd;
+=09if (!pgdir)
+=09=09return -EFAULT;
+
+=09pagesize =3D get=5Fslice=5Fpsize(current->mm, addr);
+
+=09/* align address to page boundary */
+=09offset =3D addr & ((1ul << mmu=5Fpsize=5Fdefs[pagesize].shift) - 1)=
;
+=09addr -=3D offset;
+
+=09if (HPAGE=5FSHIFT && mmu=5Fhuge=5Fpsizes[pagesize])
+=09=09ptep =3D huge=5Fpte=5Foffset(current->mm, addr);
+=09else
+=09=09ptep =3D find=5Flinux=5Fpte(pgdir, addr);
+
+=09if (ptep =3D=3D NULL)
+=09=09return -EFAULT;
+=09pte =3D *ptep;
+=09if (!pte=5Fpresent(pte) || !(pte=5Fval(pte) & =5FPAGE=5FUSER))
+=09=09return -EFAULT;
+=09pfn =3D pte=5Fpfn(pte);
+=09if (!page=5Fis=5Fram(pfn))
+=09=09return -EFAULT;
+
+=09/* no highmem to worry about here */
+=09kaddr =3D pfn=5Fto=5Fkaddr(pfn);
+=09memcpy(ret, kaddr + offset, nb);
+=09return 0;
+}
+
+static int read=5Fuser=5Fstack=5F64(unsigned long =5F=5Fuser *ptr, uns=
igned long *ret)
+{
+=09if ((unsigned long)ptr > TASK=5FSIZE - sizeof(unsigned long) ||
+=09    ((unsigned long)ptr & 7))
+=09=09return -EFAULT;
+
+=09if (!=5F=5Fget=5Fuser=5Finatomic(*ret, ptr))
+=09=09return 0;
+
+=09return read=5Fuser=5Fstack=5Fslow(ptr, ret, 8);
+}
+
+static int read=5Fuser=5Fstack=5F32(unsigned int =5F=5Fuser *ptr, unsi=
gned int *ret)
+{
+=09if ((unsigned long)ptr > TASK=5FSIZE - sizeof(unsigned int) ||
+=09    ((unsigned long)ptr & 3))
+=09=09return -EFAULT;
+
+=09if (!=5F=5Fget=5Fuser=5Finatomic(*ret, ptr))
+=09=09return 0;
+
+=09return read=5Fuser=5Fstack=5Fslow(ptr, ret, 4);
+}
+
+static inline int valid=5Fuser=5Fsp(unsigned long sp, int is=5F64)
+{
+=09if (!sp || (sp & 7) || sp > (is=5F64 =3F TASK=5FSIZE : 0x100000000U=
L) - 32)
+=09=09return 0;
+=09return 1;
+}
+
+/*
+ * 64-bit user processes use the same stack frame for RT and non-RT si=
gnals.
+ */
+struct signal=5Fframe=5F64 {
+=09char=09=09dummy[=5F=5FSIGNAL=5FFRAMESIZE];
+=09struct ucontext=09uc;
+=09unsigned long=09unused[2];
+=09unsigned int=09tramp[6];
+=09struct siginfo=09*pinfo;
+=09void=09=09*puc;
+=09struct siginfo=09info;
+=09char=09=09abigap[288];
+};
+
+static int is=5Fsigreturn=5F64=5Faddress(unsigned long nip, unsigned l=
ong fp)
+{
+=09if (nip =3D=3D fp + offsetof(struct signal=5Fframe=5F64, tramp))
+=09=09return 1;
+=09if (vdso64=5Frt=5Fsigtramp && current->mm->context.vdso=5Fbase &&
+=09    nip =3D=3D current->mm->context.vdso=5Fbase + vdso64=5Frt=5Fsig=
tramp)
+=09=09return 1;
+=09return 0;
+}
+
+/*
+ * Do some sanity checking on the signal frame pointed to by sp.
+ * We check the pinfo and puc pointers in the frame.
+ */
+static int sane=5Fsignal=5F64=5Fframe(unsigned long sp)
+{
+=09struct signal=5Fframe=5F64 =5F=5Fuser *sf;
+=09unsigned long pinfo, puc;
+
+=09sf =3D (struct signal=5Fframe=5F64 =5F=5Fuser *) sp;
+=09if (read=5Fuser=5Fstack=5F64((unsigned long =5F=5Fuser *) &sf->pinf=
o, &pinfo) ||
+=09    read=5Fuser=5Fstack=5F64((unsigned long =5F=5Fuser *) &sf->puc,=
 &puc))
+=09=09return 0;
+=09return pinfo =3D=3D (unsigned long) &sf->info &&
+=09=09puc =3D=3D (unsigned long) &sf->uc;
+}
+
+static void perf=5Fcallchain=5Fuser=5F64(struct pt=5Fregs *regs,
+=09=09=09=09   struct perf=5Fcallchain=5Fentry *entry)
+{
+=09unsigned long sp, next=5Fsp;
+=09unsigned long next=5Fip;
+=09unsigned long lr;
+=09long level =3D 0;
+=09struct signal=5Fframe=5F64 =5F=5Fuser *sigframe;
+=09unsigned long =5F=5Fuser *fp, *uregs;
+
+=09next=5Fip =3D regs->nip;
+=09lr =3D regs->link;
+=09sp =3D regs->gpr[1];
+=09callchain=5Fstore(entry, PERF=5FCONTEXT=5FUSER);
+=09callchain=5Fstore(entry, next=5Fip);
+
+=09for (;;) {
+=09=09fp =3D (unsigned long =5F=5Fuser *) sp;
+=09=09if (!valid=5Fuser=5Fsp(sp, 1) || read=5Fuser=5Fstack=5F64(fp, &n=
ext=5Fsp))
+=09=09=09return;
+=09=09if (level > 0 && read=5Fuser=5Fstack=5F64(&fp[2], &next=5Fip))
+=09=09=09return;
+
+=09=09/*
+=09=09 * Note: the next=5Fsp - sp >=3D signal frame size check
+=09=09 * is true when next=5Fsp < sp, which can happen when
+=09=09 * transitioning from an alternate signal stack to the
+=09=09 * normal stack.
+=09=09 */
+=09=09if (next=5Fsp - sp >=3D sizeof(struct signal=5Fframe=5F64) &&
+=09=09    (is=5Fsigreturn=5F64=5Faddress(next=5Fip, sp) ||
+=09=09     (level <=3D 1 && is=5Fsigreturn=5F64=5Faddress(lr, sp))) &&=

+=09=09    sane=5Fsignal=5F64=5Fframe(sp)) {
+=09=09=09/*
+=09=09=09 * This looks like an signal frame
+=09=09=09 */
+=09=09=09sigframe =3D (struct signal=5Fframe=5F64 =5F=5Fuser *) sp;
+=09=09=09uregs =3D sigframe->uc.uc=5Fmcontext.gp=5Fregs;
+=09=09=09if (read=5Fuser=5Fstack=5F64(&uregs[PT=5FNIP], &next=5Fip) ||=

+=09=09=09    read=5Fuser=5Fstack=5F64(&uregs[PT=5FLNK], &lr) ||
+=09=09=09    read=5Fuser=5Fstack=5F64(&uregs[PT=5FR1], &sp))
+=09=09=09=09return;
+=09=09=09level =3D 0;
+=09=09=09callchain=5Fstore(entry, PERF=5FCONTEXT=5FUSER);
+=09=09=09callchain=5Fstore(entry, next=5Fip);
+=09=09=09continue;
+=09=09}
+
+=09=09if (level =3D=3D 0)
+=09=09=09next=5Fip =3D lr;
+=09=09callchain=5Fstore(entry, next=5Fip);
+=09=09++level;
+=09=09sp =3D next=5Fsp;
+=09}
+}
+
+static inline int current=5Fis=5F64bit(void)
+{
+=09/*
+=09 * We can't use test=5Fthread=5Fflag() here because we may be on an=

+=09 * interrupt stack, and the thread flags don't get copied over
+=09 * from the thread=5Finfo on the main stack to the interrupt stack.=

+=09 */
+=09return !test=5Fti=5Fthread=5Fflag(task=5Fthread=5Finfo(current), TI=
F=5F32BIT);
+}
+
+#else  /* CONFIG=5FPPC64 */
+/*
+ * On 32-bit we just access the address and let hash=5Fpage create a
+ * HPTE if necessary, so there is no need to fall back to reading
+ * the page tables.  Since this is called at interrupt level,
+ * do=5Fpage=5Ffault() won't treat a DSI as a page fault.
+ */
+static int read=5Fuser=5Fstack=5F32(unsigned int =5F=5Fuser *ptr, unsi=
gned int *ret)
+{
+=09if ((unsigned long)ptr > TASK=5FSIZE - sizeof(unsigned int) ||
+=09    ((unsigned long)ptr & 3))
+=09=09return -EFAULT;
+
+=09return =5F=5Fget=5Fuser=5Finatomic(*ret, ptr);
+}
+
+static inline void perf=5Fcallchain=5Fuser=5F64(struct pt=5Fregs *regs=
,
+=09=09=09=09=09  struct perf=5Fcallchain=5Fentry *entry)
+{
+}
+
+static inline int current=5Fis=5F64bit(void)
+{
+=09return 0;
+}
+
+static inline int valid=5Fuser=5Fsp(unsigned long sp, int is=5F64)
+{
+=09if (!sp || (sp & 7) || sp > TASK=5FSIZE - 32)
+=09=09return 0;
+=09return 1;
+}
+
+#define =5F=5FSIGNAL=5FFRAMESIZE32=09=5F=5FSIGNAL=5FFRAMESIZE
+#define sigcontext32=09=09sigcontext
+#define mcontext32=09=09mcontext
+#define ucontext32=09=09ucontext
+#define compat=5Fsiginfo=5Ft=09struct siginfo
+
+#endif /* CONFIG=5FPPC64 */
+
+/*
+ * Layout for non-RT signal frames
+ */
+struct signal=5Fframe=5F32 {
+=09char=09=09=09dummy[=5F=5FSIGNAL=5FFRAMESIZE32];
+=09struct sigcontext32=09sctx;
+=09struct mcontext32=09mctx;
+=09int=09=09=09abigap[56];
+};
+
+/*
+ * Layout for RT signal frames
+ */
+struct rt=5Fsignal=5Fframe=5F32 {
+=09char=09=09=09dummy[=5F=5FSIGNAL=5FFRAMESIZE32 + 16];
+=09compat=5Fsiginfo=5Ft=09info;
+=09struct ucontext32=09uc;
+=09int=09=09=09abigap[56];
+};
+
+static int is=5Fsigreturn=5F32=5Faddress(unsigned int nip, unsigned in=
t fp)
+{
+=09if (nip =3D=3D fp + offsetof(struct signal=5Fframe=5F32, mctx.mc=5F=
pad))
+=09=09return 1;
+=09if (vdso32=5Fsigtramp && current->mm->context.vdso=5Fbase &&
+=09    nip =3D=3D current->mm->context.vdso=5Fbase + vdso32=5Fsigtramp=
)
+=09=09return 1;
+=09return 0;
+}
+
+static int is=5Frt=5Fsigreturn=5F32=5Faddress(unsigned int nip, unsign=
ed int fp)
+{
+=09if (nip =3D=3D fp + offsetof(struct rt=5Fsignal=5Fframe=5F32,
+=09=09=09=09 uc.uc=5Fmcontext.mc=5Fpad))
+=09=09return 1;
+=09if (vdso32=5Frt=5Fsigtramp && current->mm->context.vdso=5Fbase &&
+=09    nip =3D=3D current->mm->context.vdso=5Fbase + vdso32=5Frt=5Fsig=
tramp)
+=09=09return 1;
+=09return 0;
+}
+
+static int sane=5Fsignal=5F32=5Fframe(unsigned int sp)
+{
+=09struct signal=5Fframe=5F32 =5F=5Fuser *sf;
+=09unsigned int regs;
+
+=09sf =3D (struct signal=5Fframe=5F32 =5F=5Fuser *) (unsigned long) sp=
;
+=09if (read=5Fuser=5Fstack=5F32((unsigned int =5F=5Fuser *) &sf->sctx.=
regs, &regs))
+=09=09return 0;
+=09return regs =3D=3D (unsigned long) &sf->mctx;
+}
+
+static int sane=5Frt=5Fsignal=5F32=5Fframe(unsigned int sp)
+{
+=09struct rt=5Fsignal=5Fframe=5F32 =5F=5Fuser *sf;
+=09unsigned int regs;
+
+=09sf =3D (struct rt=5Fsignal=5Fframe=5F32 =5F=5Fuser *) (unsigned lon=
g) sp;
+=09if (read=5Fuser=5Fstack=5F32((unsigned int =5F=5Fuser *) &sf->uc.uc=
=5Fregs, &regs))
+=09=09return 0;
+=09return regs =3D=3D (unsigned long) &sf->uc.uc=5Fmcontext;
+}
+
+static unsigned int =5F=5Fuser *signal=5Fframe=5F32=5Fregs(unsigned in=
t sp,
+=09=09=09=09unsigned int next=5Fsp, unsigned int next=5Fip)
+{
+=09struct mcontext32 =5F=5Fuser *mctx =3D NULL;
+=09struct signal=5Fframe=5F32 =5F=5Fuser *sf;
+=09struct rt=5Fsignal=5Fframe=5F32 =5F=5Fuser *rt=5Fsf;
+
+=09/*
+=09 * Note: the next=5Fsp - sp >=3D signal frame size check
+=09 * is true when next=5Fsp < sp, for example, when
+=09 * transitioning from an alternate signal stack to the
+=09 * normal stack.
+=09 */
+=09if (next=5Fsp - sp >=3D sizeof(struct signal=5Fframe=5F32) &&
+=09    is=5Fsigreturn=5F32=5Faddress(next=5Fip, sp) &&
+=09    sane=5Fsignal=5F32=5Fframe(sp)) {
+=09=09sf =3D (struct signal=5Fframe=5F32 =5F=5Fuser *) (unsigned long)=
 sp;
+=09=09mctx =3D &sf->mctx;
+=09}
+
+=09if (!mctx && next=5Fsp - sp >=3D sizeof(struct rt=5Fsignal=5Fframe=5F=
32) &&
+=09    is=5Frt=5Fsigreturn=5F32=5Faddress(next=5Fip, sp) &&
+=09    sane=5Frt=5Fsignal=5F32=5Fframe(sp)) {
+=09=09rt=5Fsf =3D (struct rt=5Fsignal=5Fframe=5F32 =5F=5Fuser *) (unsi=
gned long) sp;
+=09=09mctx =3D &rt=5Fsf->uc.uc=5Fmcontext;
+=09}
+
+=09if (!mctx)
+=09=09return NULL;
+=09return mctx->mc=5Fgregs;
+}
+
+static void perf=5Fcallchain=5Fuser=5F32(struct pt=5Fregs *regs,
+=09=09=09=09   struct perf=5Fcallchain=5Fentry *entry)
+{
+=09unsigned int sp, next=5Fsp;
+=09unsigned int next=5Fip;
+=09unsigned int lr;
+=09long level =3D 0;
+=09unsigned int =5F=5Fuser *fp, *uregs;
+
+=09next=5Fip =3D regs->nip;
+=09lr =3D regs->link;
+=09sp =3D regs->gpr[1];
+=09callchain=5Fstore(entry, PERF=5FCONTEXT=5FUSER);
+=09callchain=5Fstore(entry, next=5Fip);
+
+=09while (entry->nr < PERF=5FMAX=5FSTACK=5FDEPTH) {
+=09=09fp =3D (unsigned int =5F=5Fuser *) (unsigned long) sp;
+=09=09if (!valid=5Fuser=5Fsp(sp, 0) || read=5Fuser=5Fstack=5F32(fp, &n=
ext=5Fsp))
+=09=09=09return;
+=09=09if (level > 0 && read=5Fuser=5Fstack=5F32(&fp[1], &next=5Fip))
+=09=09=09return;
+
+=09=09uregs =3D signal=5Fframe=5F32=5Fregs(sp, next=5Fsp, next=5Fip);
+=09=09if (!uregs && level <=3D 1)
+=09=09=09uregs =3D signal=5Fframe=5F32=5Fregs(sp, next=5Fsp, lr);
+=09=09if (uregs) {
+=09=09=09/*
+=09=09=09 * This looks like an signal frame, so restart
+=09=09=09 * the stack trace with the values in it.
+=09=09=09 */
+=09=09=09if (read=5Fuser=5Fstack=5F32(&uregs[PT=5FNIP], &next=5Fip) ||=

+=09=09=09    read=5Fuser=5Fstack=5F32(&uregs[PT=5FLNK], &lr) ||
+=09=09=09    read=5Fuser=5Fstack=5F32(&uregs[PT=5FR1], &sp))
+=09=09=09=09return;
+=09=09=09level =3D 0;
+=09=09=09callchain=5Fstore(entry, PERF=5FCONTEXT=5FUSER);
+=09=09=09callchain=5Fstore(entry, next=5Fip);
+=09=09=09continue;
+=09=09}
+
+=09=09if (level =3D=3D 0)
+=09=09=09next=5Fip =3D lr;
+=09=09callchain=5Fstore(entry, next=5Fip);
+=09=09++level;
+=09=09sp =3D next=5Fsp;
+=09}
+}
+
+/*
+ * Since we can't get PMU interrupts inside a PMU interrupt handler,
+ * we don't need separate irq and nmi entries here.
+ */
+static DEFINE=5FPER=5FCPU(struct perf=5Fcallchain=5Fentry, callchain);=

+
+struct perf=5Fcallchain=5Fentry *perf=5Fcallchain(struct pt=5Fregs *re=
gs)
+{
+=09struct perf=5Fcallchain=5Fentry *entry =3D &=5F=5Fget=5Fcpu=5Fvar(c=
allchain);
+
+=09entry->nr =3D 0;
+
+=09if (current->pid =3D=3D 0)=09=09/* idle task=3F */
+=09=09return entry;
+
+=09if (!user=5Fmode(regs)) {
+=09=09perf=5Fcallchain=5Fkernel(regs, entry);
+=09=09if (current->mm)
+=09=09=09regs =3D task=5Fpt=5Fregs(current);
+=09=09else
+=09=09=09regs =3D NULL;
+=09}
+
+=09if (regs) {
+=09=09if (current=5Fis=5F64bit())
+=09=09=09perf=5Fcallchain=5Fuser=5F64(regs, entry);
+=09=09else
+=09=09=09perf=5Fcallchain=5Fuser=5F32(regs, entry);
+=09}
+
+=09return entry;
+}
--=20
1.5.5.rc3.7.gba13

^ permalink raw reply related

* Re: Next July 29 : Hugetlb test failure (OOPS free_hugepte_range)
From: Sachin Sant @ 2009-08-06  4:40 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: Stephen Rothwell, linux-next, linuxppc-dev
In-Reply-To: <1249530754.18245.71.camel@pasglop>

Benjamin Herrenschmidt wrote:
> Does this patch fixes it ?
>
> [PATCH] powerpc/mm: Fix encoding of page table cache numbers
>
> The mask used to encode the page table cache number in the
> batch when freeing page tables was too small for the new
> possible values of MMU page sizes. This increases it along
> with a comment explaining the constraints.
>
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> ---
>   
Yes this patch fixed the issue for me. Thanks Ben.

Tested-by: Sachin Sant <sachinp@in.ibm.com>

Regards
-Sachin

-- 

---------------------------------
Sachin Sant
IBM Linux Technology Center
India Systems and Technology Labs
Bangalore, India
---------------------------------

^ permalink raw reply

* Re: [PATCH 0/3] cpu: idle state framework for offline CPUs.
From: Vaidyanathan Srinivasan @ 2009-08-06  4:33 UTC (permalink / raw)
  To: Shaohua Li
  Cc: Brown, Len, Peter Zijlstra, Gautham R Shenoy,
	linux-kernel@vger.kernel.org, Pallipadi, Venkatesh, Ingo Molnar,
	linuxppc-dev@lists.ozlabs.org, Darrick J. Wong
In-Reply-To: <20090806015855.GA20596@sli10-desk.sh.intel.com>

* Shaohua Li <shaohua.li@intel.com> [2009-08-06 09:58:55]:

> Hi,
> 
> On Wed, Aug 05, 2009 at 10:25:53PM +0800, Gautham R Shenoy wrote:
> > In this patch-series, we propose to extend the CPU-Hotplug infrastructure
> > and allow the system administrator to choose the desired state the CPU should
> > go to when it is offlined. We think this approach addresses the concerns about
> > determinism as well as transparency, since CPU-Hotplug already provides
> > notification mechanism which the userspace can listen to for any change
> > in the configuration and correspondingly readjust any previously set
> > cpu-affinities.
> Peter dislikes any approach (including cpuhotplug) which breaks userspace policy,
> even userspace can get a notification.

Hi Shaohua,

Notification to userspace and an opportunity to react to the situation
is certainly better to manage as compared to under-the-cover reduction
in capacity.

We are already doing something to this effect in virtualized guests
where VCPU entitlement and assignment can be changed by the hypervisor
based on resource constraints.  This framework with notification and
determinism will help manage cpu capacity better.

I agree with Peter that scheduler approach is better, but it is not
deterministic.  This is simpler and cleaner alternative to keep the
complexity in userspace and provide only framework to control/notify
kernel.
 
> > Also, approaches such as [1] can make use of this
> > extended infrastructure instead of putting the CPU to an arbitrary C-state
> > when it is offlined, thereby providing the system administrator a rope to hang
> > himself with should he feel the need to do so.
> I didn't see the reason why administrator needs to know which state offline cpu
> should stay. Don't know about powerpc side, but in x86 side, it appears deepest
> C-state is already preferred.

Yes that is what we would expect, but the deepest sleep state may be
restricted by BIOS or other system level parameters.  This was the
main objection to Venki's deepest sleep state for offline cpus patch.
There could be higher level policy that restricts the deepest level
C-states for various reasons.  This framework is to provide an
opportunity to adhere to the policy with userspace inputs.  This
framework also helps to choose different states in a virtualized
system.

--Vaidy

^ permalink raw reply

* [PATCH][powerpc/85xx] P2020RDB Platform Support Added
From: Poonam Aggrwal @ 2009-08-06  4:23 UTC (permalink / raw)
  To: linuxppc-release, linuxppc-dev; +Cc: Poonam Aggrwal

Adds P2020RDB basic support in linux.
Overview of P2020RDB platform
	- DDR
	  DDR2 1G
	- NOR Flash
	  16MByte
	- NAND Flash
	  32MByte
	- 3 Ethernet interfaces
	  1) etSEC1
		- RGMII
		- connected to a 5 port Vitesse Switch(VSC7385)
		- Switch is memory mapped through eLBC interface(CS#2)
		- IRQ1
	  2) etSEC2
		- SGMII
		- connected to VSC8221
		- IRQ2
	  3) etSEC3
		- RGMII
		- connected to VSC8641
		- IRQ3
	- 2 1X PCIe interfaces
	- SD/MMC ,USB
	- SPI EEPROM
	- Serial I2C EEPROM

Signed-off-by: Poonam Aggrwal <poonam.aggrwal@freescale.com>
---
based on http://www.kernel.org/pub/scm/linux/kernel/git/galak/powerpc.git
 arch/powerpc/boot/dts/p2020rdb.dts        |  586 +++++++++++++++++++++++++++++
 arch/powerpc/configs/mpc85xx_defconfig    |    1 +
 arch/powerpc/platforms/85xx/Kconfig       |    9 +
 arch/powerpc/platforms/85xx/Makefile      |    3 +-
 arch/powerpc/platforms/85xx/mpc85xx_rdb.c |  141 +++++++
 5 files changed, 739 insertions(+), 1 deletions(-)
 create mode 100644 arch/powerpc/boot/dts/p2020rdb.dts
 create mode 100644 arch/powerpc/platforms/85xx/mpc85xx_rdb.c

diff --git a/arch/powerpc/boot/dts/p2020rdb.dts b/arch/powerpc/boot/dts/p2020rdb.dts
new file mode 100644
index 0000000..d6d8131
--- /dev/null
+++ b/arch/powerpc/boot/dts/p2020rdb.dts
@@ -0,0 +1,586 @@
+/*
+ * P2020 RDB Device Tree Source
+ *
+ * Copyright 2009 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+/dts-v1/;
+/ {
+	model = "fsl,P2020";
+	compatible = "fsl,P2020RDB";
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	aliases {
+		ethernet0 = &enet0;
+		ethernet1 = &enet1;
+		ethernet2 = &enet2;
+		serial0 = &serial0;
+		serial1 = &serial1;
+		pci0 = &pci0;
+		pci1 = &pci1;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		PowerPC,P2020@0 {
+			device_type = "cpu";
+			reg = <0x0>;
+			next-level-cache = <&L2>;
+		};
+
+		PowerPC,P2020@1 {
+			device_type = "cpu";
+			reg = <0x1>;
+			next-level-cache = <&L2>;
+		};
+	};
+
+	memory {
+		device_type = "memory";
+	};
+
+	localbus@ffe05000 {
+		#address-cells = <2>;
+		#size-cells = <1>;
+		compatible = "fsl,p2020-elbc", "fsl,elbc", "simple-bus";
+		reg = <0 0xffe05000 0 0x1000>;
+		interrupts = <19 2>;
+		interrupt-parent = <&mpic>;
+
+		/* NOR and NAND Flashes */
+		ranges = <0x0 0x0 0x0 0xef000000 0x01000000
+			  0x1 0x0 0x0 0xffa00000 0x00040000
+			  0x2 0x0 0x0 0xffb00000 0x08000000>;
+
+		nor@0,0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "cfi-flash";
+			reg = <0x0 0x0 0x1000000>;
+			bank-width = <2>;
+			device-width = <1>;
+
+			vitesse-7385-fw@0 {
+				/* This location must not be altered  */
+				/* 256KB for Vitesse 7385 Switch firmware */
+				reg = <0x0 0x00040000>;
+				label = "NOR (RO) Vitesse-7385 Firmware";
+				read-only;
+			};
+
+			dtb@40000 {
+				/* 256KB for DTB Image */
+				reg = <0x00040000 0x00040000>;
+				label = "NOR (RO) DTB Image";
+				read-only;
+			};
+
+			uImage@80000 {
+				/* 3.5 MB for Linux Kernel Image */
+				reg = <0x00080000 0x00380000>;
+				label = "NOR (RO) Linux Kernel Image";
+				read-only;
+			};
+
+			jffs2@400000 {
+				/* 11MB for JFFS2 based Root file System */
+				reg = <0x00400000 0x00b00000>;
+				label = "NOR (RW) JFFS2 Root File System";
+			};
+
+			u-boot@f00000 {
+				/* This location must not be altered  */
+				/* 512KB for u-boot Bootloader Image */
+				/* 512KB for u-boot Environment Variables */
+				reg = <0x00f00000 0x00100000>;
+				label = "NOR (RO) U-Boot Image";
+				read-only;
+			};
+		};
+
+		nand@1,0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,p2020-fcm-nand",
+				     "fsl,elbc-fcm-nand";
+			reg = <0x1 0x0 0x40000>;
+
+			u-boot@0 {
+				/* This location must not be altered  */
+				/* 1MB for u-boot Bootloader Image */
+				reg = <0x0 0x00100000>;
+				label = "NAND (RO) U-Boot Image";
+				read-only;
+			};
+
+			dtb@100000 {
+				/* 1MB for DTB Image */
+				reg = <0x00100000 0x00100000>;
+				label = "NAND (RO) DTB Image";
+				read-only;
+			};
+
+			uImage@200000 {
+				/* 4MB for Linux Kernel Image */
+				reg = <0x00200000 0x00400000>;
+				label = "NAND (RO) Linux Kernel Image";
+				read-only;
+			};
+
+			rfs@600000 {
+				/* 4MB for Compressed Root file System Image */
+				reg = <0x00600000 0x00400000>;
+				label = "NAND (RO) Compressed RFS Image";
+				read-only;
+			};
+
+			jffs2@a00000 {
+				/* 7MB for JFFS2 based Root file System */
+				reg = <0x00a00000 0x00700000>;
+				label = "NAND (RW) JFFS2 Root File System";
+			};
+
+			user@1100000 {
+				/* 15MB for JFFS2 based Root file System */
+				reg = <0x01100000 0x00f00000>;
+				label = "NAND (RW) Writable User area";
+			};
+		};
+
+		L2switch@2,0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "vitesse-7385";
+			reg = <0x2 0x0 0x20000>;
+		};
+
+	};
+
+	soc@ffe00000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		device_type = "soc";
+		compatible = "fsl,p2020-immr", "simple-bus";
+		ranges = <0x0  0x0 0xffe00000 0x100000>;
+		bus-frequency = <0>;		// Filled out by uboot.
+
+		ecm-law@0 {
+			compatible = "fsl,ecm-law";
+			reg = <0x0 0x1000>;
+			fsl,num-laws = <12>;
+		};
+
+		ecm@1000 {
+			compatible = "fsl,p2020-ecm", "fsl,ecm";
+			reg = <0x1000 0x1000>;
+			interrupts = <17 2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		memory-controller@2000 {
+			compatible = "fsl,p2020-memory-controller";
+			reg = <0x2000 0x1000>;
+			interrupt-parent = <&mpic>;
+			interrupts = <18 2>;
+		};
+
+		i2c@3000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			cell-index = <0>;
+			compatible = "fsl-i2c";
+			reg = <0x3000 0x100>;
+			interrupts = <43 2>;
+			interrupt-parent = <&mpic>;
+			dfsrr;
+			rtc@68 {
+				compatible = "dallas,ds1339";
+				reg = <0x68>;
+			};
+		};
+
+		i2c@3100 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			cell-index = <1>;
+			compatible = "fsl-i2c";
+			reg = <0x3100 0x100>;
+			interrupts = <43 2>;
+			interrupt-parent = <&mpic>;
+			dfsrr;
+		};
+
+		serial0: serial@4500 {
+			cell-index = <0>;
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <0x4500 0x100>;
+			clock-frequency = <0>;
+			interrupts = <42 2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		serial1: serial@4600 {
+			cell-index = <1>;
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <0x4600 0x100>;
+			clock-frequency = <0>;
+			interrupts = <42 2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		spi@7000 {
+			cell-index = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl,espi";
+			reg = <0x7000 0x1000>;
+			interrupts = <59 0x2>;
+			interrupt-parent = <&mpic>;
+			mode = "cpu";
+
+			fsl_m25p80@0 {
+				#address-cells = <1>;
+				#size-cells = <1>;
+				compatible = "fsl,espi-flash";
+				reg = <0>;
+				linux,modalias = "fsl_m25p80";
+				modal = "s25sl128b";
+				spi-max-frequency = <50000000>;
+				mode = <0>;
+
+				u-boot@0 {
+					/* 512KB for u-boot Bootloader Image */
+					reg = <0x0 0x00080000>;
+					label = "SPI (RO) U-Boot Image";
+					read-only;
+				};
+
+				dtb@80000 {
+					/* 512KB for DTB Image */
+					reg = <0x00080000 0x00080000>;
+					label = "SPI (RO) DTB Image";
+					read-only;
+				};
+
+				uImage@100000 {
+					/* 4MB for Linux Kernel Image */
+					reg = <0x00100000 0x00400000>;
+					label = "SPI (RO) Linux Kernel Image";
+					read-only;
+				};
+
+				rfs@500000 {
+					/* 4MB for Compressed RFS Image */
+					reg = <0x00500000 0x00400000>;
+					label = "SPI (RO) Compressed RFS Image";
+					read-only;
+				};
+
+				jffs2@900000 {
+					/* 7MB for JFFS2 based RFS */
+					reg = <0x00900000 0x00700000>;
+					label = "SPI (RW) JFFS2 RFS";
+				};
+			};
+		};
+
+		dma@c300 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,eloplus-dma";
+			reg = <0xc300 0x4>;
+			ranges = <0x0 0xc100 0x200>;
+			cell-index = <1>;
+			dma-channel@0 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x0 0x80>;
+				cell-index = <0>;
+				interrupt-parent = <&mpic>;
+				interrupts = <76 2>;
+			};
+			dma-channel@80 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x80 0x80>;
+				cell-index = <1>;
+				interrupt-parent = <&mpic>;
+				interrupts = <77 2>;
+			};
+			dma-channel@100 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x100 0x80>;
+				cell-index = <2>;
+				interrupt-parent = <&mpic>;
+				interrupts = <78 2>;
+			};
+			dma-channel@180 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x180 0x80>;
+				cell-index = <3>;
+				interrupt-parent = <&mpic>;
+				interrupts = <79 2>;
+			};
+		};
+
+		gpio: gpio-controller@f000 {
+			#gpio-cells = <2>;
+			compatible = "fsl,mpc8572-gpio";
+			reg = <0xf000 0x100>;
+			interrupts = <47 0x2>;
+			interrupt-parent = <&mpic>;
+			gpio-controller;
+		};
+
+		L2: l2-cache-controller@20000 {
+			compatible = "fsl,p2020-l2-cache-controller";
+			reg = <0x20000 0x1000>;
+			cache-line-size = <32>;	// 32 bytes
+			cache-size = <0x80000>; // L2,512K
+			interrupt-parent = <&mpic>;
+			interrupts = <16 2>;
+		};
+
+		dma@21300 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,eloplus-dma";
+			reg = <0x21300 0x4>;
+			ranges = <0x0 0x21100 0x200>;
+			cell-index = <0>;
+			dma-channel@0 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x0 0x80>;
+				cell-index = <0>;
+				interrupt-parent = <&mpic>;
+				interrupts = <20 2>;
+			};
+			dma-channel@80 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x80 0x80>;
+				cell-index = <1>;
+				interrupt-parent = <&mpic>;
+				interrupts = <21 2>;
+			};
+			dma-channel@100 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x100 0x80>;
+				cell-index = <2>;
+				interrupt-parent = <&mpic>;
+				interrupts = <22 2>;
+			};
+			dma-channel@180 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x180 0x80>;
+				cell-index = <3>;
+				interrupt-parent = <&mpic>;
+				interrupts = <23 2>;
+			};
+		};
+
+		usb@22000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl-usb2-dr";
+			reg = <0x22000 0x1000>;
+			interrupt-parent = <&mpic>;
+			interrupts = <28 0x2>;
+			phy_type = "ulpi";
+		};
+
+		enet0: ethernet@24000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			cell-index = <0>;
+			device_type = "network";
+			model = "eTSEC";
+			compatible = "gianfar";
+			reg = <0x24000 0x1000>;
+			ranges = <0x0 0x24000 0x1000>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <29 2 30 2 34 2>;
+			interrupt-parent = <&mpic>;
+			fixed-link = <1 1 1000 0 0>;
+			phy-connection-type = "rgmii-id";
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy0: ethernet-phy@0 {
+					interrupt-parent = <&mpic>;
+					interrupts = <3 1>;
+					reg = <0x0>;
+				};
+				phy1: ethernet-phy@1 {
+					interrupt-parent = <&mpic>;
+					interrupts = <3 1>;
+					reg = <0x1>;
+				};
+			};
+		};
+
+		enet1: ethernet@25000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			cell-index = <1>;
+			device_type = "network";
+			model = "eTSEC";
+			compatible = "gianfar";
+			reg = <0x25000 0x1000>;
+			ranges = <0x0 0x25000 0x1000>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <35 2 36 2 40 2>;
+			interrupt-parent = <&mpic>;
+			tbi-handle = <&tbi0>;
+			phy-handle = <&phy0>;
+			phy-connection-type = "sgmii";
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi0: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
+		};
+
+		enet2: ethernet@26000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			cell-index = <2>;
+			device_type = "network";
+			model = "eTSEC";
+			compatible = "gianfar";
+			reg = <0x26000 0x1000>;
+			ranges = <0x0 0x26000 0x1000>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <31 2 32 2 33 2>;
+			interrupt-parent = <&mpic>;
+			phy-handle = <&phy1>;
+			phy-connection-type = "rgmii-id";
+		};
+
+		sdhci@2e000 {
+			compatible = "fsl,p2020-esdhc", "fsl,esdhc";
+			reg = <0x2e000 0x1000>;
+			interrupts = <72 0x2>;
+			interrupt-parent = <&mpic>;
+			/* Filled in by U-Boot */
+			clock-frequency = <0>;
+		};
+
+		crypto@30000 {
+			compatible = "fsl,sec3.1", "fsl,sec3.0", "fsl,sec2.4",
+				     "fsl,sec2.2", "fsl,sec2.1", "fsl,sec2.0";
+			reg = <0x30000 0x10000>;
+			interrupts = <45 2 58 2>;
+			interrupt-parent = <&mpic>;
+			fsl,num-channels = <4>;
+			fsl,channel-fifo-len = <24>;
+			fsl,exec-units-mask = <0xbfe>;
+			fsl,descriptor-types-mask = <0x3ab0ebf>;
+		};
+
+		mpic: pic@40000 {
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <2>;
+			reg = <0x40000 0x40000>;
+			compatible = "chrp,open-pic";
+			device_type = "open-pic";
+		};
+
+		msi@41600 {
+			compatible = "fsl,p2020-msi", "fsl,mpic-msi";
+			reg = <0x41600 0x80>;
+			msi-available-ranges = <0 0x100>;
+			interrupts = <
+				0xe0 0
+				0xe1 0
+				0xe2 0
+				0xe3 0
+				0xe4 0
+				0xe5 0
+				0xe6 0
+				0xe7 0>;
+			interrupt-parent = <&mpic>;
+		};
+
+		global-utilities@e0000 {	//global utilities block
+			compatible = "fsl,p2020-guts";
+			reg = <0xe0000 0x1000>;
+			fsl,has-rstcr;
+		};
+	};
+
+	pci0: pcie@ffe09000 {
+		compatible = "fsl,mpc8548-pcie";
+		device_type = "pci";
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0 0xffe09000 0 0x1000>;
+		bus-range = <0 255>;
+		ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
+			  0x1000000 0x0 0x00000000 0 0xffc30000 0x0 0x10000>;
+		clock-frequency = <33333333>;
+		interrupt-parent = <&mpic>;
+		interrupts = <25 2>;
+		pcie@0 {
+			reg = <0x0 0x0 0x0 0x0 0x0>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			device_type = "pci";
+			ranges = <0x2000000 0x0 0xa0000000
+				  0x2000000 0x0 0xa0000000
+				  0x0 0x20000000
+
+				  0x1000000 0x0 0x0
+				  0x1000000 0x0 0x0
+				  0x0 0x100000>;
+		};
+	};
+
+	pci1: pcie@ffe0a000 {
+		compatible = "fsl,mpc8548-pcie";
+		device_type = "pci";
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0 0xffe0a000 0 0x1000>;
+		bus-range = <0 255>;
+		ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000
+			  0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>;
+		clock-frequency = <33333333>;
+		interrupt-parent = <&mpic>;
+		interrupts = <26 2>;
+		pcie@0 {
+			reg = <0x0 0x0 0x0 0x0 0x0>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			device_type = "pci";
+			ranges = <0x2000000 0x0 0xc0000000
+				  0x2000000 0x0 0xc0000000
+				  0x0 0x20000000
+
+				  0x1000000 0x0 0x0
+				  0x1000000 0x0 0x0
+				  0x0 0x100000>;
+		};
+	};
+};
diff --git a/arch/powerpc/configs/mpc85xx_defconfig b/arch/powerpc/configs/mpc85xx_defconfig
index c162724..dc4819c 100644
--- a/arch/powerpc/configs/mpc85xx_defconfig
+++ b/arch/powerpc/configs/mpc85xx_defconfig
@@ -189,6 +189,7 @@ CONFIG_MPC85xx_CDS=y
 CONFIG_MPC85xx_MDS=y
 CONFIG_MPC8536_DS=y
 CONFIG_MPC85xx_DS=y
+CONFIG_MPC85xx_RDB=y
 CONFIG_SOCRATES=y
 CONFIG_KSI8560=y
 CONFIG_STX_GP3=y
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
index a9b4166..d3a975e 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -55,6 +55,15 @@ config MPC85xx_DS
 	help
 	  This option enables support for the MPC85xx DS (MPC8544 DS) board
 
+config MPC85xx_RDB
+	bool "Freescale MPC85xx RDB"
+	select PPC_I8259
+	select DEFAULT_UIMAGE
+	select FSL_ULI1575
+	select SWIOTLB
+	help
+	  This option enables support for the MPC85xx RDB (P2020 RDB) board
+
 config SOCRATES
 	bool "Socrates"
 	select DEFAULT_UIMAGE
diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile
index 835733f..4efcc63 100644
--- a/arch/powerpc/platforms/85xx/Makefile
+++ b/arch/powerpc/platforms/85xx/Makefile
@@ -9,10 +9,11 @@ obj-$(CONFIG_MPC85xx_CDS) += mpc85xx_cds.o
 obj-$(CONFIG_MPC8536_DS)  += mpc8536_ds.o
 obj-$(CONFIG_MPC85xx_DS)  += mpc85xx_ds.o
 obj-$(CONFIG_MPC85xx_MDS) += mpc85xx_mds.o
+obj-$(CONFIG_MPC85xx_RDB)  += mpc85xx_rdb.o
 obj-$(CONFIG_STX_GP3)	  += stx_gp3.o
 obj-$(CONFIG_TQM85xx)	  += tqm85xx.o
 obj-$(CONFIG_SBC8560)     += sbc8560.o
 obj-$(CONFIG_SBC8548)     += sbc8548.o
 obj-$(CONFIG_SOCRATES)    += socrates.o socrates_fpga_pic.o
 obj-$(CONFIG_KSI8560)	  += ksi8560.o
-obj-$(CONFIG_XES_MPC85xx) += xes_mpc85xx.o
\ No newline at end of file
+obj-$(CONFIG_XES_MPC85xx) += xes_mpc85xx.o
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_rdb.c b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c
new file mode 100644
index 0000000..c8468de
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c
@@ -0,0 +1,141 @@
+/*
+ * MPC85xx RDB Board Setup
+ *
+ * Copyright 2009 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/kdev_t.h>
+#include <linux/delay.h>
+#include <linux/seq_file.h>
+#include <linux/interrupt.h>
+#include <linux/of_platform.h>
+
+#include <asm/system.h>
+#include <asm/time.h>
+#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
+#include <mm/mmu_decl.h>
+#include <asm/prom.h>
+#include <asm/udbg.h>
+#include <asm/mpic.h>
+
+#include <sysdev/fsl_soc.h>
+#include <sysdev/fsl_pci.h>
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args)
+#else
+#define DBG(fmt, args...)
+#endif
+
+
+void __init mpc85xx_rdb_pic_init(void)
+{
+	struct mpic *mpic;
+	struct resource r;
+	struct device_node *np;
+
+	np = of_find_node_by_type(NULL, "open-pic");
+	if (np == NULL) {
+		printk(KERN_ERR "Could not find open-pic node\n");
+		return;
+	}
+
+	if (of_address_to_resource(np, 0, &r)) {
+		printk(KERN_ERR "Failed to map mpic register space\n");
+		of_node_put(np);
+		return;
+	}
+
+	mpic = mpic_alloc(np, r.start,
+		  MPIC_PRIMARY | MPIC_WANTS_RESET |
+		  MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS |
+		  MPIC_SINGLE_DEST_CPU,
+		  0, 256, " OpenPIC  ");
+
+	BUG_ON(mpic == NULL);
+	of_node_put(np);
+
+	mpic_init(mpic);
+
+}
+
+/*
+ * Setup the architecture
+ */
+#ifdef CONFIG_SMP
+extern void __init mpc85xx_smp_init(void);
+#endif
+static void __init mpc85xx_rdb_setup_arch(void)
+{
+#ifdef CONFIG_PCI
+	struct device_node *np;
+#endif
+
+	if (ppc_md.progress)
+		ppc_md.progress("mpc85xx_rdb_setup_arch()", 0);
+
+#ifdef CONFIG_PCI
+	for_each_node_by_type(np, "pci") {
+		if (of_device_is_compatible(np, "fsl,mpc8548-pcie"))
+			fsl_add_bridge(np, 0);
+	}
+
+#endif
+
+#ifdef CONFIG_SMP
+	mpc85xx_smp_init();
+#endif
+
+	printk(KERN_INFO "MPC85xx RDB board from Freescale Semiconductor\n");
+}
+
+static struct of_device_id __initdata mpc85xxrdb_ids[] = {
+	{ .type = "soc", },
+	{ .compatible = "soc", },
+	{ .compatible = "simple-bus", },
+	{ .compatible = "gianfar", },
+	{},
+};
+
+static int __init mpc85xxrdb_publish_devices(void)
+{
+	return of_platform_bus_probe(NULL, mpc85xxrdb_ids, NULL);
+}
+machine_device_initcall(p2020_rdb, mpc85xxrdb_publish_devices);
+
+/*
+ * Called very early, device-tree isn't unflattened
+ */
+static int __init p2020_rdb_probe(void)
+{
+	unsigned long root = of_get_flat_dt_root();
+
+	if (of_flat_dt_is_compatible(root, "fsl,P2020RDB"))
+		return 1;
+	return 0;
+}
+
+define_machine(p2020_rdb) {
+	.name			= "P2020 RDB",
+	.probe			= p2020_rdb_probe,
+	.setup_arch		= mpc85xx_rdb_setup_arch,
+	.init_IRQ		= mpc85xx_rdb_pic_init,
+#ifdef CONFIG_PCI
+	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+#endif
+	.get_irq		= mpic_get_irq,
+	.restart		= fsl_rstcr_restart,
+	.calibrate_decr		= generic_calibrate_decr,
+	.progress		= udbg_progress,
+};
-- 
1.5.6.5

^ permalink raw reply related

* [PATCH] powerpc/perfctr: Check oprofile_cpu_type for NULL before using it
From: Benjamin Herrenschmidt @ 2009-08-06  4:02 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev list, Ingo Molnar, David Woodhouse

If the current CPU doesn't support performance counters,
cur_cpu_spec->oprofile_cpu_type can be NULL. The current
perfctr modules don't test for that case and would thus
crash.

Bug reported by David Woodhouse

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 arch/powerpc/kernel/mpc7450-pmu.c |    3 ++-
 arch/powerpc/kernel/power4-pmu.c  |    3 ++-
 arch/powerpc/kernel/power5+-pmu.c |    5 +++--
 arch/powerpc/kernel/power5-pmu.c  |    3 ++-
 arch/powerpc/kernel/power6-pmu.c  |    3 ++-
 arch/powerpc/kernel/power7-pmu.c  |    3 ++-
 arch/powerpc/kernel/ppc970-pmu.c  |    5 +++--
 7 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/kernel/mpc7450-pmu.c b/arch/powerpc/kernel/mpc7450-pmu.c
index c244133..cc466d0 100644
--- a/arch/powerpc/kernel/mpc7450-pmu.c
+++ b/arch/powerpc/kernel/mpc7450-pmu.c
@@ -407,7 +407,8 @@ struct power_pmu mpc7450_pmu = {
 
 static int init_mpc7450_pmu(void)
 {
-	if (strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc/7450"))
+	if (!cur_cpu_spec->oprofile_cpu_type ||
+	    strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc/7450"))
 		return -ENODEV;
 
 	return register_power_pmu(&mpc7450_pmu);
diff --git a/arch/powerpc/kernel/power4-pmu.c b/arch/powerpc/kernel/power4-pmu.c
index db90b0c..3c90a3d 100644
--- a/arch/powerpc/kernel/power4-pmu.c
+++ b/arch/powerpc/kernel/power4-pmu.c
@@ -606,7 +606,8 @@ static struct power_pmu power4_pmu = {
 
 static int init_power4_pmu(void)
 {
-	if (strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power4"))
+	if (!cur_cpu_spec->oprofile_cpu_type ||
+	    strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power4"))
 		return -ENODEV;
 
 	return register_power_pmu(&power4_pmu);
diff --git a/arch/powerpc/kernel/power5+-pmu.c b/arch/powerpc/kernel/power5+-pmu.c
index f4adca8..31918af 100644
--- a/arch/powerpc/kernel/power5+-pmu.c
+++ b/arch/powerpc/kernel/power5+-pmu.c
@@ -678,8 +678,9 @@ static struct power_pmu power5p_pmu = {
 
 static int init_power5p_pmu(void)
 {
-	if (strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power5+")
-	    && strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power5++"))
+	if (!cur_cpu_spec->oprofile_cpu_type ||
+	    (strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power5+")
+	     && strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power5++")))
 		return -ENODEV;
 
 	return register_power_pmu(&power5p_pmu);
diff --git a/arch/powerpc/kernel/power5-pmu.c b/arch/powerpc/kernel/power5-pmu.c
index 29b2c6c..867f6f6 100644
--- a/arch/powerpc/kernel/power5-pmu.c
+++ b/arch/powerpc/kernel/power5-pmu.c
@@ -618,7 +618,8 @@ static struct power_pmu power5_pmu = {
 
 static int init_power5_pmu(void)
 {
-	if (strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power5"))
+	if (!cur_cpu_spec->oprofile_cpu_type ||
+	    strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power5"))
 		return -ENODEV;
 
 	return register_power_pmu(&power5_pmu);
diff --git a/arch/powerpc/kernel/power6-pmu.c b/arch/powerpc/kernel/power6-pmu.c
index 09ae5bf..fa21890 100644
--- a/arch/powerpc/kernel/power6-pmu.c
+++ b/arch/powerpc/kernel/power6-pmu.c
@@ -537,7 +537,8 @@ static struct power_pmu power6_pmu = {
 
 static int init_power6_pmu(void)
 {
-	if (strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power6"))
+	if (!cur_cpu_spec->oprofile_cpu_type ||
+	    strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power6"))
 		return -ENODEV;
 
 	return register_power_pmu(&power6_pmu);
diff --git a/arch/powerpc/kernel/power7-pmu.c b/arch/powerpc/kernel/power7-pmu.c
index 5a9f5cb..388cf57 100644
--- a/arch/powerpc/kernel/power7-pmu.c
+++ b/arch/powerpc/kernel/power7-pmu.c
@@ -366,7 +366,8 @@ static struct power_pmu power7_pmu = {
 
 static int init_power7_pmu(void)
 {
-	if (strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power7"))
+	if (!cur_cpu_spec->oprofile_cpu_type ||
+	    strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power7"))
 		return -ENODEV;
 
 	return register_power_pmu(&power7_pmu);
diff --git a/arch/powerpc/kernel/ppc970-pmu.c b/arch/powerpc/kernel/ppc970-pmu.c
index 833097a..75dccb7 100644
--- a/arch/powerpc/kernel/ppc970-pmu.c
+++ b/arch/powerpc/kernel/ppc970-pmu.c
@@ -488,8 +488,9 @@ static struct power_pmu ppc970_pmu = {
 
 static int init_ppc970_pmu(void)
 {
-	if (strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/970")
-	    && strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/970MP"))
+	if (!cur_cpu_spec->oprofile_cpu_type ||
+	    (strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/970")
+	     && strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/970MP")))
 		return -ENODEV;
 
 	return register_power_pmu(&ppc970_pmu);
-- 
1.6.0.4

^ permalink raw reply related

* Re: Next July 29 : Hugetlb test failure (OOPS free_hugepte_range)
From: Benjamin Herrenschmidt @ 2009-08-06  3:52 UTC (permalink / raw)
  To: Sachin Sant; +Cc: Stephen Rothwell, linux-next, linuxppc-dev
In-Reply-To: <4A796237.6070302@in.ibm.com>

On Wed, 2009-08-05 at 16:13 +0530, Sachin Sant wrote:
> Benjamin Herrenschmidt wrote:
> > Thanks. I'll have a look next week. I think when I changed the indices
> > I may have forgotten to update something.
> >   
> Ben,
> 
> I can recreate this issue with today's next.
> Let me know if i can help in any way to fix this issue.

Does this patch fixes it ?

[PATCH] powerpc/mm: Fix encoding of page table cache numbers

The mask used to encode the page table cache number in the
batch when freeing page tables was too small for the new
possible values of MMU page sizes. This increases it along
with a comment explaining the constraints.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 arch/powerpc/include/asm/pgalloc.h |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/include/asm/pgalloc.h b/arch/powerpc/include/asm/pgalloc.h
index 34b0806..f2e812d 100644
--- a/arch/powerpc/include/asm/pgalloc.h
+++ b/arch/powerpc/include/asm/pgalloc.h
@@ -28,7 +28,12 @@ typedef struct pgtable_free {
 	unsigned long val;
 } pgtable_free_t;
 
-#define PGF_CACHENUM_MASK	0x7
+/* This needs to be big enough to allow for MMU_PAGE_COUNT + 2 to be stored
+ * and small enough to fit in the low bits of any naturally aligned page
+ * table cache entry. Arbitrarily set to 0x1f, that should give us some
+ * room to grow
+ */
+#define PGF_CACHENUM_MASK	0x1f
 
 static inline pgtable_free_t pgtable_free_cache(void *p, int cachenum,
 						unsigned long mask)
-- 
1.6.0.4


> Thanks
> -Sachin
> 
> >> : ------------[ cut here ]------------
> >> cpu 0x0: Vector: 700 (Program Check) at [c000000038923560]
> >>     pc: c0000000000486d4: .free_hugepte_range+0x68/0xa0
> >>     lr: c000000000048954: .hugetlb_free_pgd_range+0x248/0x38c
> >>     sp: c0000000389237e0
> >>    msr: 8000000000029032
> >>   current = 0xc00000003b1d7780
> >>   paca    = 0xc000000001002400
> >>     pid   = 2839, comm = readback
> >> kernel BUG at /home/linux-2.6.31-rc4/arch/powerpc/include/asm/pgalloc.h:36!
> >> enter ? for help
> >> [c000000038923880] c000000000048954 .hugetlb_free_pgd_range+0x248/0x38c
> >> [c000000038923970] c000000000165a48 .free_pgtables+0xa0/0x154
> >> [c000000038923a30] c000000000167f78 .exit_mmap+0x13c/0x1cc
> >> [c000000038923ae0] c0000000000997ec .mmput+0x68/0x14c
> >> [c000000038923b70] c00000000009f1d4 .exit_mm+0x190/0x1b8
> >> [c000000038923c20] c0000000000a16e8 .do_exit+0x214/0x784
> >> [c000000038923d00] c0000000000a1d1c .do_group_exit+0xc4/0xf8
> >> [c000000038923da0] c0000000000a1d7c .SyS_exit_group+0x2c/0x48
> >> [c000000038923e30] c0000000000085b4 syscall_exit+0x0/0x40
> >> --- Exception: c01 (System Call) at 000000000fe15038
> >> SP (ffb8e030) is in userspace
> >> 0:mon> e
> >> cpu 0x0: Vector: 700 (Program Check) at [c000000038923560]
> >>     pc: c0000000000486d4: .free_hugepte_range+0x68/0xa0
> >>     lr: c000000000048954: .hugetlb_free_pgd_range+0x248/0x38c
> >>     sp: c0000000389237e0
> >>    msr: 8000000000029032
> >>   current = 0xc00000003b1d7780
> >>   paca    = 0xc000000001002400
> >>     pid   = 2839, comm = readback
> >> kernel BUG at /home/linux-2.6.31-rc4/arch/powerpc/include/asm/pgalloc.h:36!
> >> 0:mon> r
> >> R00 = 0000000000000001   R16 = 0000000000000000
> >> R01 = c0000000389237e0   R17 = 0000000000000001
> >> R02 = c000000000f165a8   R18 = 000000003fffffff
> >> R03 = c0000000014504d0   R19 = 0000000000000000
> >> R04 = c000000039390001   R20 = 0000000000000000
> >> R05 = 0000000000000007   R21 = 0000010000000000
> >> R06 = 0000000000000000   R22 = 0000000040000000
> >> R07 = 0000000040000000   R23 = c0000000014504d0
> >> R08 = c00000003d708188   R24 = 000000003fffffff
> >> R09 = c00000003eb40000   R25 = 0000000000000007
> >> R10 = c00000003d708188   R26 = c00000003ebd41b8
> >> R11 = 0000000000000018   R27 = c0000000014504d0
> >> R12 = 0000000040000448   R28 = c00000003eb40018
> >> R13 = c000000001002400   R29 = 0000000000000008
> >> R14 = 00000000ffffffff   R30 = 0000000040000000
> >> R15 = 00000000ffffffff   R31 = c0000000389237e0
> >> pc  = c0000000000486d4 .free_hugepte_range+0x68/0xa0
> >> lr  = c000000000048954 .hugetlb_free_pgd_range+0x248/0x38c
> >> msr = 8000000000029032   cr  = 20042444
> >> ctr = 800000000000b6f4   xer = 0000000000000001   trap =  700
> >> 0:mon> 
> >>
> >> Line 36 of arch/powerpc/include/asm/pgalloc.h corresponds to
> >>
> >> BUG_ON(cachenum > PGF_CACHENUM_MASK);
> >>
> >> May be something to do with number of elements in huge_pgtable_cache_name ??
> >>
> >> Thanks
> >> -Sachin

^ permalink raw reply related

* Re: ftrace scripts and make V=1
From: Ingo Molnar @ 2009-08-06  3:43 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: Linus Torvalds, Dave Airlie, LKML, Sam Ravnborg, linuxppc-dev
In-Reply-To: <alpine.DEB.2.00.0908052011590.5010@gandalf.stny.rr.com>


* Steven Rostedt <rostedt@goodmis.org> wrote:

> Well we tracked it down and it is powerpc64 specific.
> 
> Seems that in drivers/hwmon/lm93.c there's a function called:
> 
>    LM93_IN_FROM_REG()
> 
> But PPC64 has function descriptors and the real function names (the ones 
> you see in objdump) start with a '.'. Thus this in objdump you have:
> 
>  Disassembly of section .text:
> 
>  0000000000000000 <.LM93_IN_FROM_REG>:
>        0:       7c 08 02 a6     mflr    r0
>        4:       fb 81 ff e0     std     r28,-32(r1)
> 
> 
> The function name used is .LM93_IN_FROM_REG. But gcc considers 
> symbols that start with ".L" as a special symbol that is used 
> inside the assembly stage.
> 
> The nm passed into recordmcount uses the --synthetic option which 
> shows the ".L" symbols (my runs outside of the build did not 
> include the --synthetic option, so my older patch worked). We see 
> the function as a local.
> 
> Now to capture all the locations that use "mcount" we need to have 
> a reference to link into the object file a list of mcount callers. 
> We need a reference that will not disappear. We try to use a 
> global function and if that does not work, we use a local function 
> as a reference. But to relink the section back into the object, we 
> need to make it global. In this case, we run objcopy using 
> --globalize-symbol and --localize-symbol to convert the symbol 
> into a global symbol, link the mcount list, then convert it back 
> to a local symbol.
> 
> This works great except for this case. .L* symbols can not be 
> converted into a global symbol, and the mcount section referencing 
> it will remain unresolved.
> 
> Try this patch and see if it fixes your issue.
> 
> Thanks!
> 
> -- Steve
> 
> diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl
> index d29baa2..4889c44 100755
> --- a/scripts/recordmcount.pl
> +++ b/scripts/recordmcount.pl
> @@ -414,7 +414,10 @@ while (<IN>) {
>  	    $offset = hex $1;
>  	} else {
>  	    # if we already have a function, and this is weak, skip it
> -	    if (!defined($ref_func) && !defined($weak{$text})) {
> +	    if (!defined($ref_func) && !defined($weak{$text}) &&
> +		 # PPC64 can have symbols that start with .L and
> +		 # gcc considers these special. Don't use them!
> +		 $text !~ /^\.L/) {
>  		$ref_func = $text;
>  		$offset = hex $1;
>  	    }

Ah, indeed. I'm wondering whether also emitting a build warning 
would be useful - just in the (admittedly unlikely) case of someone 
wondering about why LM93_IN_FROM_REG does not show up in function 
traces.

	Ingo

^ permalink raw reply

* Re: [PATCH 0/3] cpu: idle state framework for offline CPUs.
From: Shaohua Li @ 2009-08-06  1:58 UTC (permalink / raw)
  To: Gautham R Shenoy
  Cc: Brown, Len, Peter Zijlstra, linux-kernel@vger.kernel.org,
	Pallipadi, Venkatesh, Ingo Molnar, linuxppc-dev@lists.ozlabs.org,
	Darrick J. Wong
In-Reply-To: <20090805142311.553.78286.stgit@sofia.in.ibm.com>

Hi,

On Wed, Aug 05, 2009 at 10:25:53PM +0800, Gautham R Shenoy wrote:
> In this patch-series, we propose to extend the CPU-Hotplug infrastructure
> and allow the system administrator to choose the desired state the CPU should
> go to when it is offlined. We think this approach addresses the concerns about
> determinism as well as transparency, since CPU-Hotplug already provides
> notification mechanism which the userspace can listen to for any change
> in the configuration and correspondingly readjust any previously set
> cpu-affinities.
Peter dislikes any approach (including cpuhotplug) which breaks userspace policy,
even userspace can get a notification.

> Also, approaches such as [1] can make use of this
> extended infrastructure instead of putting the CPU to an arbitrary C-state
> when it is offlined, thereby providing the system administrator a rope to hang
> himself with should he feel the need to do so.
I didn't see the reason why administrator needs to know which state offline cpu
should stay. Don't know about powerpc side, but in x86 side, it appears deepest
C-state is already preferred.

Thanks,
Shaohua

^ permalink raw reply

* Re: ftrace scripts and make V=1
From: Steven Rostedt @ 2009-08-06  2:00 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: Linus Torvalds, Dave Airlie, LKML, Sam Ravnborg, linuxppc-dev
In-Reply-To: <20090805072952.GC19322@elte.hu>


On Wed, 5 Aug 2009, Ingo Molnar wrote:

> 
> * Dave Airlie <airlied@gmail.com> wrote:
> 
> > Hey,
> > 
> > So I spent 3-4 hrs today (I'm stupid yes) tracking down a .o 
> > breakage by blaming rawhide gcc/binutils as I was using make 
> > V=1and seeing only the compiler chain running,
> 
> Hm, is this that powerpc related build bug you just reported?

Well we tracked it down and it is powerpc64 specific.

Seems that in drivers/hwmon/lm93.c there's a function called:

   LM93_IN_FROM_REG()

But PPC64 has function descriptors and the real function names (the ones 
you see in objdump) start with a '.'. Thus this in objdump you have:

 Disassembly of section .text:

 0000000000000000 <.LM93_IN_FROM_REG>:
       0:       7c 08 02 a6     mflr    r0
       4:       fb 81 ff e0     std     r28,-32(r1)


The function name used is .LM93_IN_FROM_REG. But gcc considers symbols 
that start with ".L" as a special symbol that is used inside the assembly 
stage.

The nm passed into recordmcount uses the --synthetic option which shows 
the ".L" symbols (my runs outside of the build did not include the 
--synthetic option, so my older patch worked). We see the function as a 
local.

Now to capture all the locations that use "mcount" we need to have a 
reference to link into the object file a list of mcount callers. We need a 
reference that will not disappear. We try to use a global function and if 
that does not work, we use a local function as a reference. But to relink 
the section back into the object, we need to make it global. In this case, 
we run objcopy using --globalize-symbol and --localize-symbol to convert 
the symbol into a global symbol, link the mcount list, then convert it 
back to a local symbol.

This works great except for this case. .L* symbols can not be converted 
into a global symbol, and the mcount section referencing it will remain 
unresolved.

Try this patch and see if it fixes your issue.

Thanks!

-- Steve

diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl
index d29baa2..4889c44 100755
--- a/scripts/recordmcount.pl
+++ b/scripts/recordmcount.pl
@@ -414,7 +414,10 @@ while (<IN>) {
 	    $offset = hex $1;
 	} else {
 	    # if we already have a function, and this is weak, skip it
-	    if (!defined($ref_func) && !defined($weak{$text})) {
+	    if (!defined($ref_func) && !defined($weak{$text}) &&
+		 # PPC64 can have symbols that start with .L and
+		 # gcc considers these special. Don't use them!
+		 $text !~ /^\.L/) {
 		$ref_func = $text;
 		$offset = hex $1;
 	    }

^ permalink raw reply related

* Re: kexec on e300 core / mpc5121
From: Kenneth Johansson @ 2009-08-06  0:20 UTC (permalink / raw)
  To: Scott Wood; +Cc: linuxppc-dev, Sebastian Andrzej Siewior
In-Reply-To: <20090805234737.GA26183@b07421-ec1.am.freescale.net>

On Wed, 2009-08-05 at 18:47 -0500, Scott Wood wrote:
> On Thu, Aug 06, 2009 at 12:49:45AM +0200, Kenneth Johansson wrote:
> > On Wed, 2009-08-05 at 01:06 +0200, Sebastian Andrzej Siewior wrote:
> > > I've tried kexec on e300 core which should be easy since it is possible
> > > to disable the MMU on that core. However it does not work.
> > 
> > Is it not possible to disable the mmu on all cpu's that have one ?? 
> 
> No, on e500 for example it is always on.  You can use large pages with
> identity maps to make it seem like it's off, though.

why do something like that ? 

> > Before you turn off the cache you need to flush out all dirty data. best
> > done by simply reading in 32kb of crap from somewhere. otherwise you are
> > sure to loose at least the stack and you do not want that.
> 
> 32KiB is usually not sufficient -- depending on the initial state, an
> 8-way 32KiB cache with PLRU (such as in e300) can require up to 52KiB of
> data (13 loads per set) to fully flush if you simply load+dcbf (in
> separate passes) an arbitrary chunk of data which may already be in the
> cache.

if you have 
int crap[1024*32/4] __attribute__((aligned(32)))

What will happen with the cache if you just load data into a register
from that array ?? Wont it force out everything else in the cache to
make room for the crap ? 

 

^ permalink raw reply

* Re: kexec on e300 core / mpc5121
From: Scott Wood @ 2009-08-05 23:47 UTC (permalink / raw)
  To: Kenneth Johansson; +Cc: linuxppc-dev, Sebastian Andrzej Siewior
In-Reply-To: <1249512585.13069.9.camel@localhost>

On Thu, Aug 06, 2009 at 12:49:45AM +0200, Kenneth Johansson wrote:
> On Wed, 2009-08-05 at 01:06 +0200, Sebastian Andrzej Siewior wrote:
> > I've tried kexec on e300 core which should be easy since it is possible
> > to disable the MMU on that core. However it does not work.
> 
> Is it not possible to disable the mmu on all cpu's that have one ?? 

No, on e500 for example it is always on.  You can use large pages with
identity maps to make it seem like it's off, though.

> Before you turn off the cache you need to flush out all dirty data. best
> done by simply reading in 32kb of crap from somewhere. otherwise you are
> sure to loose at least the stack and you do not want that.

32KiB is usually not sufficient -- depending on the initial state, an
8-way 32KiB cache with PLRU (such as in e300) can require up to 52KiB of
data (13 loads per set) to fully flush if you simply load+dcbf (in
separate passes) an arbitrary chunk of data which may already be in the
cache.

If instead you load+dcbf something that you know is not already in the
cache, or if you have a flush-assist mode that does not choose vacant
cache lines when available (instead sticking strictly to the PLRU), the
maximum is 48KiB.

If you have flush-assist *and* you guarantee no hit on the flush data,
then you can get away with only 32KiB.

-Scott

^ permalink raw reply

* Re: kexec on e300 core / mpc5121
From: Kenneth Johansson @ 2009-08-05 22:49 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior; +Cc: linuxppc-dev
In-Reply-To: <20090804230605.GA28753@Chamillionaire.breakpoint.cc>

On Wed, 2009-08-05 at 01:06 +0200, Sebastian Andrzej Siewior wrote:
> I've tried kexec on e300 core which should be easy since it is possible
> to disable the MMU on that core. However it does not work.

Is it not possible to disable the mmu on all cpu's that have one ?? 

> Once I disable the MMU, I can't access my MBAR and print chars on the
> serial port. Is this "normal" or do I have still some caches on?

Yes cache and mmu is separate. the 5121 is not cache coherent and do not
limit cache to only memory regions so serial port or any memory mapped
register is a no no unless you have cache off or cache on and mmu on
with a correct setting for what address range to cache. 

Before you turn off the cache you need to flush out all dirty data. best
done by simply reading in 32kb of crap from somewhere. otherwise you are
sure to loose at least the stack and you do not want that.

^ permalink raw reply

* [PATCH] powerpc: switch to asm-generic/hardirq.h
From: Christoph Hellwig @ 2009-08-05 22:24 UTC (permalink / raw)
  To: linuxppc-dev

hardirq.h on powerpc defines a __last_jiffy_stamp field, but it's not
actually used anywhere.


Signed-off-by: Christoph Hellwig <hch@lst.de>

Index: linux-2.6/arch/powerpc/include/asm/hardirq.h
===================================================================
--- linux-2.6.orig/arch/powerpc/include/asm/hardirq.h	2009-08-05 19:19:57.391342973 -0300
+++ linux-2.6/arch/powerpc/include/asm/hardirq.h	2009-08-05 19:20:38.658365423 -0300
@@ -1,29 +1 @@
-#ifndef _ASM_POWERPC_HARDIRQ_H
-#define _ASM_POWERPC_HARDIRQ_H
-#ifdef __KERNEL__
-
-#include <asm/irq.h>
-#include <asm/bug.h>
-
-/* The __last_jiffy_stamp field is needed to ensure that no decrementer
- * interrupt is lost on SMP machines. Since on most CPUs it is in the same
- * cache line as local_irq_count, it is cheap to access and is also used on UP
- * for uniformity.
- */
-typedef struct {
-	unsigned int __softirq_pending;	/* set_bit is used on this */
-	unsigned int __last_jiffy_stamp;
-} ____cacheline_aligned irq_cpustat_t;
-
-#include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
-
-#define last_jiffy_stamp(cpu) __IRQ_STAT((cpu), __last_jiffy_stamp)
-
-static inline void ack_bad_irq(int irq)
-{
-	printk(KERN_CRIT "illegal vector %d received!\n", irq);
-	BUG();
-}
-
-#endif /* __KERNEL__ */
-#endif /* _ASM_POWERPC_HARDIRQ_H */
+#include <asm-generic/hardirq.h>

^ permalink raw reply

* Re: kexec on e300 core / mpc5121
From: Sebastian Andrzej Siewior @ 2009-08-05 21:33 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <20090804230605.GA28753@Chamillionaire.breakpoint.cc>

* Sebastian Andrzej Siewior | 2009-08-05 01:06:06 [+0200]:
[long mail]
>Does someone have an idea?
Issue fixed, it was the ipic. The missing data while disabling the
caches was my fault because I invalidated the caches before I've flushed
them.

Sebastian

^ permalink raw reply

* Re: [PATCH] powerpc/ipic: unmask all interrupt sources
From: Sebastian Andrzej Siewior @ 2009-08-05 21:29 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <92176A7D-89C7-484F-B4C8-8E510271A512@kernel.crashing.org>

* Kumar Gala | 2009-08-05 15:04:16 [-0500]:
>
> looks good.. I'll pick this up for .32 since it doesn't seem to be a bug 
> until we have kexec.
Well, the code for the non-mmu variant is there and is working. It was
just the ipic thing which was holding me back. However I'm fine with .32
I'm stocked here with .26.
The bigger issue is the user space for ppc32 which is non-working in
current upstream since it is pre-device tree and game cube only.
Once you have time to review the kernel interface (the part where we
jump to the new kernel / kernel wrapper) I could try to rebase my
patches and repost them :)

> - k

Sebastian

^ permalink raw reply

* Re: [PATCH] Fix perfctr oops on ppc32
From: David Woodhouse @ 2009-08-05 21:07 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: Paul Mackerras, linuxppc-dev
In-Reply-To: <1249506153.18245.61.camel@pasglop>

On Thu, 2009-08-06 at 07:02 +1000, Benjamin Herrenschmidt wrote:
> 
> Argh, ignore my Acked-by, I think the patch isn't right...

Hm, good point. Doh.

-- 
David Woodhouse                            Open Source Technology Centre
David.Woodhouse@intel.com                              Intel Corporation

^ permalink raw reply

* Re: [PATCH] Fix perfctr oops on ppc32
From: Benjamin Herrenschmidt @ 2009-08-05 21:02 UTC (permalink / raw)
  To: David Woodhouse; +Cc: Paul Mackerras, linuxppc-dev
In-Reply-To: <1249133370.24204.3.camel@macbook.infradead.org>

On Sat, 2009-08-01 at 14:29 +0100, David Woodhouse wrote:
> This seems to be the reason why the Fedora rawhide 2.6.31-rc kernel
> doesn't boot. With some CPUs, cur_cpu_spec->oprofile_cpu_type can be
> NULL -- which makes strcmp() unhappy.
> 
> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
> ---
> At first glance, it looks like there are a bunch of other places which
> use cur_cpu_spec->oprofile_cpu_type without first checking if it's
> non-NULL, but maybe those are all 64-bit and all 64-bit cpu types have
> it set?

Argh, ignore my Acked-by, I think the patch isn't right...

> diff --git a/arch/powerpc/kernel/mpc7450-pmu.c b/arch/powerpc/kernel/mpc7450-pmu.c
> index 75ff47f..ea383c1 100644
> --- a/arch/powerpc/kernel/mpc7450-pmu.c
> +++ b/arch/powerpc/kernel/mpc7450-pmu.c
> @@ -408,7 +408,8 @@ struct power_pmu mpc7450_pmu = {
>  
>  static int init_mpc7450_pmu(void)
>  {
> -	if (strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc/7450"))
> +	if (cur_cpu_spec->oprofile_cpu_type &&
> +	    strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc/7450"))
>  		return -ENODEV;

That means that if we have oprofile_cpu_type, we will enable the 7450
PMCs which doesn't sound right. Shouldn't it be instead:

	if (!cur_cpu_spec->oprofile_cpu_type ||
	    strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc/7450"))
 		return -ENODEV;

Cheers,
Ben.


>  	return register_power_pmu(&mpc7450_pmu);
> 
> 

^ permalink raw reply

* Re: [PATCH] powerpc/ipic: unmask all interrupt sources
From: Kumar Gala @ 2009-08-05 20:04 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior; +Cc: linuxppc-dev
In-Reply-To: <20090805194112.GA18204@www.tglx.de>


On Aug 5, 2009, at 2:41 PM, Sebastian Andrzej Siewior wrote:

> in case the interrupt controller was used in an earlier life then it  
> is
> possible it is that some of its sources were used and are still  
> unmask.
> If the (unmasked) device is active and is creating interrupts (or one
> interrupts was pending since the interrupts were disabled) then the  
> boot
> process "ends" very soon. Once external interrupts are enabled, we  
> land in
> -> do_IRQ
>  -> call ppc_md.get_irq()
>     -> ipic_read() gets the source number
>     -> irq_linear_revmap(source)
>        -> revmap[source] == NO_IRQ
>           -> irq_find_mapping(source) returns NO_IRQ because no source
>              is registered
>  -> source is NO_IRQ, ppc_spurious_interrupts gets incremented, no
>     further action.
>
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> ---
> This solves my kexec problem I had earlier. I could disable the device
> in ->shutdown path but the device in question could been used in the
> boot loader. Usually one gets the "nobody cared" message for unhandled
> interrupts but in this (rare) case nothing happens and box stands  
> still.
>
> arch/powerpc/sysdev/ipic.c |    3 +++
> 1 files changed, 3 insertions(+), 0 deletions(-)

looks good.. I'll pick this up for .32 since it doesn't seem to be a  
bug until we have kexec.

- k

^ permalink raw reply

* [PATCH] powerpc/ipic: unmask all interrupt sources
From: Sebastian Andrzej Siewior @ 2009-08-05 19:41 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev

in case the interrupt controller was used in an earlier life then it is
possible it is that some of its sources were used and are still unmask.
If the (unmasked) device is active and is creating interrupts (or one
interrupts was pending since the interrupts were disabled) then the boot
process "ends" very soon. Once external interrupts are enabled, we land in
-> do_IRQ
  -> call ppc_md.get_irq()
     -> ipic_read() gets the source number
     -> irq_linear_revmap(source)
        -> revmap[source] == NO_IRQ
           -> irq_find_mapping(source) returns NO_IRQ because no source
              is registered
  -> source is NO_IRQ, ppc_spurious_interrupts gets incremented, no
     further action.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
This solves my kexec problem I had earlier. I could disable the device
in ->shutdown path but the device in question could been used in the
boot loader. Usually one gets the "nobody cared" message for unhandled
interrupts but in this (rare) case nothing happens and box stands still.

 arch/powerpc/sysdev/ipic.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
index 69e2630..ebb7e58 100644
--- a/arch/powerpc/sysdev/ipic.c
+++ b/arch/powerpc/sysdev/ipic.c
@@ -781,6 +781,9 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
 	primary_ipic = ipic;
 	irq_set_default_host(primary_ipic->irqhost);
 
+	ipic_write(ipic->regs, IPIC_SIMSR_H, 0);
+	ipic_write(ipic->regs, IPIC_SIMSR_L, 0);
+
 	printk ("IPIC (%d IRQ sources) at %p\n", NR_IPIC_INTS,
 			primary_ipic->regs);
 
-- 
1.6.2.5

^ permalink raw reply related

* Re: [PATCH] Do not inline putprops function
From: M. Mohan Kumar @ 2009-08-05 16:49 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: linuxppc-dev, Neil Horman, Simon Horman, kexec, miltonm
In-Reply-To: <20090803054919.GA19594@in.ibm.com>

Hi,

When I align the dtstruct variable to 8 bytes, I am able to invoke kdump.

When the line
	static unsigned dtstruct[TREEWORDS], *dt;
changed to 
	static unsigned dtstruct[TREEWORDS] __attribute__ ((aligned (8))), *dt;

kexec-tool works.

Regards,
M. Mohan Kumar

On Mon, Aug 03, 2009 at 11:19:19AM +0530, M. Mohan Kumar wrote:
> On Wed, Jun 24, 2009 at 10:27:43AM +1000, Michael Ellerman wrote:
> > On Tue, 2009-06-23 at 09:56 -0400, Neil Horman wrote:
> > > On Tue, Jun 23, 2009 at 06:25:34PM +0530, M. Mohan Kumar wrote:
> > > > 
> > > Well it definately looks like removing that variable had some code changes.
> > > It'll take some time to match it up to source, but Most interesting I think is
> > > the variance in putprops around address f34.  Looks like its doing some string
> > > maniuplation in a reversed order, using a huge offset.  Might be worthwhile to
> > > check to see if theres any string overruns in this code.
> > 
> > Yeah I still suspect it's just a bug in the code that's being exposed
> > now.
> > 
> Hi,
> 
> The same code works with gcc-3.4.
> 
> > Mohan, can you try running it under valgrind?
> 
> Still I am not able to use valgrind to debug kexec-tools
> 
> Regards,
> M. Mohan Kumar.
> 
> 
> 
> _______________________________________________
> kexec mailing list
> kexec@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply

* Re: Next July 29 : Hugetlb test failure (OOPS free_hugepte_range)
From: Sachin Sant @ 2009-08-05 15:33 UTC (permalink / raw)
  To: Kumar Gala; +Cc: Stephen Rothwell, linux-next, linuxppc-dev
In-Reply-To: <E0A64FA0-C835-4361-A203-E9CB5377599C@kernel.crashing.org>

Kumar Gala wrote:
>
> On Jul 29, 2009, at 10:04 AM, Sachin Sant wrote:
>
>> While executing hugetlb tests against today's Next tree on
>> a Power 6 box came across following OOPS.
>
> out of interest what tests are you running for hugetlb?
The one maintained at : http://libhugetlbfs.ozlabs.org/ which points
to the sourceforge libhugetlbfs project.

Latest release can be downloaded from sourceforge using
http://sourceforge.net/projects/libhugetlbfs/files/

I am using version 2.5

Thanks
-Sachin



-- 

---------------------------------
Sachin Sant
IBM Linux Technology Center
India Systems and Technology Labs
Bangalore, India
---------------------------------

^ permalink raw reply

* RE: Spansion S25FL128-Flash and MTD
From: EXTERNAL Lange Matthias (AA-DGW/ENG1) @ 2009-08-05 14:59 UTC (permalink / raw)
  To: linuxppc-dev@ozlabs.org
In-Reply-To: <44C5CFA72BC0E242A53B64DC1E67DEB80FB989659B@SI-MBX10.de.bosch.com>

I solved part of my problem. The flash now gets detected during boot up. I =
had to change the compatible property from ""amd,s25sl12800", "jedec-flash"=
" to ""amd,m25p80", "jedec-flash"".

What remains is creating the mtd partitions which are specified in the devi=
ce tree as follows

partition@0 {
        label =3D "firmware";
        reg =3D <0x0 0x800000>;
};
partition@800000 {
        label =3D "rootfs";
        reg =3D <0x800000 0x800000>;
};

During boot no partitions are created and "cat /proc/mtd" just gives me

dev:    size   erasesize  name
mtd0: 01000000 00010000 "spi32766.0"

Any ideas?

Regards,
Matthias.

> -----Original Message-----
> From:
> linuxppc-dev-bounces+matthias.lange=3Dbeissbarth.com@lists.ozlab
> s.org
> [mailto:linuxppc-dev-bounces+matthias.lange=3Dbeissbarth.com@lis
ts.ozlabs.org] On Behalf Of EXTERNAL Lange Matthias (AA-DGW/ENG1)
> Sent: Wednesday, August 05, 2009 9:17 AM
> To: linuxppc-dev@ozlabs.org
> Subject: Spansion S25FL128-Flash and MTD
>
> Hi,
>
> I am trying to get a MTD running on my embedded PowerPC
> board. I am using a Xilinx Virtex4 with an embedded PowerPC
> 405. In the FPGA there is a Xilinx SPI controller implemented
> to which a Spansion S25FL128 SPI-flash (16MB) is connected.
>
> The problem is that with my setup the flash chips gets not
> detected and the MTD partitions won't be setup.
>
> In the kernel config I have configured the following options:
>
> In the device drivers section:
> [x] SPI support
>         [x] Xilinx SPI controller
> [x] Memory Technology Device (MTD) support
>         [x] MTD partitioning support
>         [x] Flash partition map based on OF description
>         RAM/ROM/Flash chip drivers
>                 [x] Detect non-CFI AMD/JEDEC-compatible flash chips
>         Self-contained MTD device drivers
>                 [x] Support most SPI Flash chips (AT26DF,
> M25P, W25X, ...)
>
> As filesystem I have configured JFFS2.
>
> In my device tree I have declared the SPI controller and the
> connected flash as follows:
>
> SPI_Flash: xps-spi@83400000 {
>         compatible =3D "xlnx,xps-spi-2.00.b";
>         interrupt-parent =3D <&int_ctrl>;
>         interrupts =3D < 3 2 >;
>         reg =3D < 0x83400000 0x10000 >;
>         xlnx,family =3D "virtex4";
>         xlnx,fifo-exist =3D <0x0>;
>         xlnx,num-offchip-ss-bits =3D <0x1>;
>         xlnx,num-ss-bits =3D <0x1>;
>         xlnx,sck-ratio =3D <0x20>;
>         #address-cells =3D <1>;
>         #size-cells =3D <1>;
>         nor_flash@0,1000000 {
>                 compatible =3D "amd,s25sl12800", "jedec-flash";
>                 reg =3D <0x0 0x1000000>;
>                 spi-max-frequency =3D <25000000>;
>                 bank-width =3D <1>;
>                 device-width =3D <1>;
>                 #address-cells =3D <1>;
>                 #size-cells =3D <1>;
>                 rootfs@800000 {
>                         label =3D "rootfs";
>                         reg =3D <0x800000 0x800000>;
>                 };
>         };
> };
>
> When the kernel boots I can see from the console that the
> drivers for JFFS2 and the SPI controller get successfully loaded:
>
> ...
> JFFS2 version 2.2. (NAND) (c) 2001-2006 Red Hat, Inc.
> ...
> xilinx-xps-spi 83400000.xps-spi: at 0x83400000 mapped to
> 0xC9060000, irq=3D17
> ...
>
> While debugging the boot process I couldn't see any calls to
> jedec_probe() resp. m25p_probe() from m25p80.c which to my
> understanding should be called in result to a successfull
> match of my compatible property (jedec-flash).
>
> The question is: What am I missing? Is there a problem with
> my device tree definition? What else am I doing wrong?
>
> Any help is appreciated. Regards,
> Matthias.
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
>

^ permalink raw reply

* Re: Next July 29 : Hugetlb test failure (OOPS free_hugepte_range)
From: Kumar Gala @ 2009-08-05 14:35 UTC (permalink / raw)
  To: Sachin Sant; +Cc: Stephen Rothwell, linux-next, linuxppc-dev
In-Reply-To: <4A706504.6040704@in.ibm.com>


On Jul 29, 2009, at 10:04 AM, Sachin Sant wrote:

> While executing hugetlb tests against today's Next tree on
> a Power 6 box came across following OOPS.

out of interest what tests are you running for hugetlb?

- k

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox