LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [RFC:PATCH 02/03] powerpc: Add definitions for Debug Registers on BookE Platforms
From: Josh Boyer @ 2009-12-10 17:07 UTC (permalink / raw)
  To: Dave Kleikamp
  Cc: linuxppc-dev list, Sergio Durigan Junior, Torez Smith,
	Thiago Jung Bauermann, David Gibson
In-Reply-To: <20091210155721.6697.40863.sendpatchset@norville.austin.ibm.com>

On Thu, Dec 10, 2009 at 01:57:21PM -0200, Dave Kleikamp wrote:
>diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
>index 9eed29e..1393307 100644
>--- a/arch/powerpc/include/asm/processor.h
>+++ b/arch/powerpc/include/asm/processor.h
>@@ -161,9 +161,35 @@ struct thread_struct {
> #ifdef CONFIG_PPC32
> 	void		*pgdir;		/* root of page-table tree */
> #endif
>-#if defined(CONFIG_4xx) || defined (CONFIG_BOOKE)
>-	unsigned long	dbcr0;		/* debug control register values */
>+#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
>+	/*
>+	 * The following help to manage the use of Debug Control Registers
>+	 * om the BookE platforms.
>+	 */
>+	unsigned long	dbcr0;
> 	unsigned long	dbcr1;
>+	unsigned long	dbcr2;

This is wrong for 405.  405 only has dbcr0 and dbcr1.  I don't see why you'd
change the #define values to be more explicit and then include things that
don't make sense.

>+	/*
>+	 * The stored value of the DBSR register will be the value at the
>+	 * last debug interrupt. This register can only be read from the
>+	 * user (will never be written to) and has value while helping to
>+	 * describe the reason for the last debug trap.  Torez
>+	 */
>+	unsigned long	dbsr;
>+	/*
>+	 * The following will contain addresses used by debug applications
>+	 * to help trace and trap on particular address locations.
>+	 * The bits in the Debug Control Registers above help define which
>+	 * of the following registers will contain valid data and/or addresses.
>+	 */
>+	unsigned long	iac1;
>+	unsigned long	iac2;
>+	unsigned long	iac3;
>+	unsigned long	iac4;
>+	unsigned long	dac1;
>+	unsigned long	dac2;
>+	unsigned long	dvc1;
>+	unsigned long	dvc2;
> #endif

Without digging much, I'm wondering if we could just use a pointer to a debug
register structure here instead of growing struct thread more.

> 	/* FP and VSX 0-31 register set */
> 	double		fpr[32][TS_FPRWIDTH];
>diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h
>index 3bf7835..7f8c71f 100644
>--- a/arch/powerpc/include/asm/reg_booke.h
>+++ b/arch/powerpc/include/asm/reg_booke.h
>@@ -248,6 +248,8 @@
> #define DBSR_RET	0x00008000	/* Return Debug Event */
> #define DBSR_CIRPT	0x00000040	/* Critical Interrupt Taken Event */
> #define DBSR_CRET	0x00000020	/* Critical Return Debug Event */
>+#define DBSR_IAC12ATS	0x00000002	/* Instr Address Compare 1/2 Toggle */
>+#define DBSR_IAC34ATS	0x00000001	/* Instr Address Compare 3/4 Toggle */
> #endif
> #ifdef CONFIG_40x
> #define DBSR_IC		0x80000000	/* Instruction Completion */
>@@ -294,25 +296,68 @@
> #define DBCR0_IC	0x08000000	/* Instruction Completion */
> #define DBCR0_ICMP	DBCR0_IC
> #define DBCR0_BT	0x04000000	/* Branch Taken */
>-#define DBCR0_BRT	DBCR0_BT
> #define DBCR0_EDE	0x02000000	/* Exception Debug Event */
> #define DBCR0_IRPT	DBCR0_EDE
> #define DBCR0_TDE	0x01000000	/* TRAP Debug Event */
>-#define DBCR0_IA1	0x00800000	/* Instr Addr compare 1 enable */
>-#define DBCR0_IAC1	DBCR0_IA1
>-#define DBCR0_IA2	0x00400000	/* Instr Addr compare 2 enable */
>-#define DBCR0_IAC2	DBCR0_IA2
>-#define DBCR0_IA12	0x00200000	/* Instr Addr 1-2 range enable */
>-#define DBCR0_IA12X	0x00100000	/* Instr Addr 1-2 range eXclusive */
>-#define DBCR0_IA3	0x00080000	/* Instr Addr compare 3 enable */
>-#define DBCR0_IAC3	DBCR0_IA3
>-#define DBCR0_IA4	0x00040000	/* Instr Addr compare 4 enable */
>-#define DBCR0_IAC4	DBCR0_IA4
>-#define DBCR0_IA34	0x00020000	/* Instr Addr 3-4 range Enable */
>-#define DBCR0_IA34X	0x00010000	/* Instr Addr 3-4 range eXclusive */
>-#define DBCR0_IA12T	0x00008000	/* Instr Addr 1-2 range Toggle */
>-#define DBCR0_IA34T	0x00004000	/* Instr Addr 3-4 range Toggle */
>+#define DBCR0_IAC1	0x00800000	/* Instr Addr compare 1 enable */
>+#define DBCR0_IAC2	0x00400000	/* Instr Addr compare 2 enable */
>+#define DBCR0_IAC12M	0x00300000	/* Instr Addr 1-2 range enable */
>+#define DBCR0_IAC12M_R	0x00100000	/* Instr Addr 1-2 Reserved state */
>+#define DBCR0_IAC12M_I	0x00200000	/* Instr Addr 1-2 range Inclusive */
>+#define DBCR0_IAC12M_X	0x00300000	/* Instr Addr 1-2 range eXclusive */
>+#define DBCR0_IAC3	0x00080000	/* Instr Addr compare 3 enable */
>+#define DBCR0_IAC4	0x00040000	/* Instr Addr compare 4 enable */
>+#define DBCR0_IAC34	0x00020000	/* Instr Addr 3-4 range Enable */
>+#define DBCR0_IAC34X	0x00010000	/* Instr Addr 3-4 range eXclusive */
>+#define DBCR0_IAC12T	0x00008000	/* Instr Addr 1-2 range Toggle */
>+#define DBCR0_IAC34T	0x00004000	/* Instr Addr 3-4 range Toggle */

A lot of this seems to just be cleanup... would it be possible to factor out
the cleanup parts so that the additions are easier to review?

> #define DBCR0_FT	0x00000001	/* Freeze Timers on debug event */
>+
>+#define DBCR0_USER_DEBUG	(DBCR0_IDM | DBCR0_ICMP | DBCR0_IAC1 | \
>+				 DBCR0_IAC2 | DBCR0_IAC3 | DBCR0_IAC4)
>+#define DBCR0_BASE_REG_VALUE	0
>+
>+#define dbcr_iac_range(task)	((task)->thread.dbcr0)
>+#define DBCR_IAC12M	DBCR0_IAC12M
>+#define DBCR_IAC12M_I	DBCR0_IAC12M_I
>+#define DBCR_IAC12M_X	DBCR0_IAC12M_X
>+#define DBCR_IAC34M	DBCR0_IAC34M
>+#define DBCR_IAC34M_I	DBCR0_IAC34M_I
>+#define DBCR_IAC34M_X	DBCR0_IAC34M_X
>+
>+/* Bit definitions related to the DBCR1. */
>+#define DBCR1_D1R	0x80000000	/* DAC1 Read Debug Event */
>+#define DBCR1_DAC1R	DBCR1_D1R
>+#define DBCR1_D2R	0x40000000	/* DAC2 Read Debug Event */
>+#define DBCR1_DAC2R	DBCR1_D2R
>+#define DBCR1_D1W	0x20000000	/* DAC1 Write Debug Event */
>+#define DBCR1_DAC1W	DBCR1_D1W
>+#define DBCR1_D2W	0x10000000	/* DAC2 Write Debug Event */
>+#define DBCR1_DAC2W	DBCR1_D2W
>+
>+#define DBCR1_USER_DEBUG	(DBCR1_DAC1R | DBCR1_DAC2R | DBCR1_DAC1W | \
>+				 DBCR1_DAC2W)
>+#define DBCR1_BASE_REG_VALUE	0
>+
>+#define dbcr_dac(task)	((task)->thread.dbcr1)
>+#define DBCR_DAC1R	DBCR1_DAC1R
>+#define DBCR_DAC1W	DBCR1_DAC1W
>+#define DBCR_DAC2R	DBCR1_DAC2R
>+#define DBCR_DAC2W	DBCR1_DAC2W
>+
>+#define DBCR2_USER_DEBUG	0
>+#define DBCR2_BASE_REG_VALUE	0

Why are these defined for 405?

>+/*
>+ * Are there any active Debug Events represented in the
>+ * Debug Control Registers?
>+ */
>+#define DBCR0_ACTIVE_EVENTS	(DBCR0_ICMP | DBCR0_IAC1 | DBCR0_IAC2 | \
>+				 DBCR0_IAC3 | DBCR0_IAC4)
>+#define DBCR1_ACTIVE_EVENTS	(DBCR1_D1R | DBCR1_D2R | DBCR1_D1W | DBCR1_D2W)
>+#define DBCR_ACTIVE_EVENTS(dbcr0, dbcr1)  (((dbcr0) & DBCR0_ACTIVE_EVENTS) || \
>+					   ((dbcr1) & DBCR1_ACTIVE_EVENTS))
>+
> #elif defined(CONFIG_BOOKE)
> #define DBCR0_EDM	0x80000000	/* External Debug Mode */
> #define DBCR0_IDM	0x40000000	/* Internal Debug Mode */
>@@ -324,8 +369,7 @@
> #define DBCR0_RST_NONE	0x00000000	/* No Reset */
> #define DBCR0_ICMP	0x08000000	/* Instruction Completion */
> #define DBCR0_IC	DBCR0_ICMP
>-#define DBCR0_BRT	0x04000000	/* Branch Taken */
>-#define DBCR0_BT	DBCR0_BRT
>+#define DBCR0_BT	0x04000000	/* Branch Taken */

This seems like just cleanup of DBCR0_BRT?

> #define DBCR0_IRPT	0x02000000	/* Exception Debug Event */
> #define DBCR0_TDE	0x01000000	/* TRAP Debug Event */
> #define DBCR0_TIE	DBCR0_TDE
>@@ -342,19 +386,99 @@
> #define DBCR0_CRET	0x00000020	/* Critical Return Debug Event */
> #define DBCR0_FT	0x00000001	/* Freeze Timers on debug event */
>
>+#define DBCR0_USER_DEBUG	(DBCR0_IDM | DBCR0_ICMP | DBCR0_IAC1 | \
>+				 DBCR0_IAC2 | DBCR0_IAC3 | DBCR0_IAC4 | \
>+				 DBCR0_DAC1R | DBCR0_DAC1W  | DBCR0_DAC2R | \
>+				 DBCR0_DAC2W)
>+#define DBCR0_BASE_REG_VALUE	0
>+
>+#define dbcr_dac(task)	((task)->thread.dbcr0)
>+#define DBCR_DAC1R	DBCR0_DAC1R
>+#define DBCR_DAC1W	DBCR0_DAC1W
>+#define DBCR_DAC2R	DBCR0_DAC2R
>+#define DBCR_DAC2W	DBCR0_DAC2W
>+
> /* Bit definitions related to the DBCR1. */

I'll try to review these a bit later.  Changing #defines makes for hard patch
review :)

josh

^ permalink raw reply

* Re: [PATCH] [SCSI] mpt fusion: Fix 32 bit platforms with 64 bit resources.
From: Anatolij Gustschin @ 2009-12-10 16:36 UTC (permalink / raw)
  To: James Bottomley; +Cc: linuxppc-dev, Eric.Moore, Pravin Bathija, linux-scsi
In-Reply-To: <1260459818.2457.77.camel@mulgrave.site>

On Thu, 10 Dec 2009 09:43:38 -0600
James Bottomley <James.Bottomley@suse.de> wrote:

> On Wed, 2009-12-02 at 17:51 -0800, Pravin Bathija wrote:
> > Powerpc 44x uses 36 bit real address while the real address defined
> >     in MPT Fusion driver is of type 32 bit. This causes ioremap to fail and driver
> >     fails to initialize. This fix changes the data types representing the real
> >     address from unsigned long 32-bit types to resource_size_t which is 64-bit. The
> >     driver has been tested, the disks get discovered correctly and can do IO.
> > 
> > Signed-off-by: Pravin Bathija <pbathija@amcc.com>
> > Acked-by: Feng Kan <fkan@amcc.com>
> > Acked-by: Fushen Chen <fchen@amcc.com>
> > Acked-by: Loc Ho <lho@amcc.com>
> > Acked-by: Tirumala Reddy Marri <tmarri@amcc.com>
> > Acked-by: Victor Gallardo <vgallardo@amcc.com>
> > ---
> >  drivers/message/fusion/mptbase.c |    2 +-
> >  1 files changed, 1 insertions(+), 1 deletions(-)
> > 
> > diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
> > index 5d496a9..9f14a60 100644
> > --- a/drivers/message/fusion/mptbase.c
> > +++ b/drivers/message/fusion/mptbase.c
> > @@ -1511,7 +1511,7 @@ mpt_mapresources(MPT_ADAPTER *ioc)
> >  {
> >  	u8		__iomem *mem;
> >  	int		 ii;
> > -	unsigned long	 mem_phys;
> > +	resource_size_t	 mem_phys;
> 
> You never actually compiled this, did you?
> 
> drivers/message/fusion/mptbase.c: In function 'mpt_mapresources':
> drivers/message/fusion/mptbase.c:1680: warning: format '%lx' expects type 'long unsigned int', but argument 4 has type 'resource_size_t'
> 
> I'll just fold the fix in

another patch (inlined below) should probably also go in as 'mem_phys' is
assigned to ioc->mem_phys which is 'u32'. ioc->mem_phys is never used in
the driver, however.

Some time ago I posted a patch which enables using second LSI SAS HBA on
PPC440SPe based katmai board again:

http://thread.gmane.org/gmane.linux.scsi/54839

Could someone comment on this patch, please. Thanks!

Anatolij

---

diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index 8dd4d21..8dc58e3 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -605,7 +605,7 @@ typedef struct _MPT_ADAPTER
 	SYSIF_REGS __iomem	*chip;		/* == c8817000 (mmap) */
 	SYSIF_REGS __iomem	*pio_chip;	/* Programmed IO (downloadboot) */
 	u8			 bus_type;
-	u32			 mem_phys;	/* == f4020000 (mmap) */
+	resource_size_t		 mem_phys;	/* == f4020000 (mmap) */
 	u32			 pio_mem_phys;	/* Programmed IO (downloadboot) */
 	int			 mem_size;	/* mmap memory size */
 	int			 number_of_buses;

^ permalink raw reply related

* [RFC:PATCH 03/03] powerpc: Add support for BookE Debug Reg. traps, exceptions and ptrace
From: Dave Kleikamp @ 2009-12-10 15:57 UTC (permalink / raw)
  To: linuxppc-dev list
  Cc: Sergio Durigan Junior, Thiago Jung Bauermann, Torez Smith,
	David Gibson
In-Reply-To: <20091210155709.6697.4635.sendpatchset@norville.austin.ibm.com>

powerpc: Add support for BookE Debug Reg. traps, exceptions and ptrace

From: Torez Smith <lnxtorez@linux.vnet.ibm.com>

This patch defines context switch and trap related functionality
for BookE specific Debug Registers. It adds support to ptrace()
for setting and getting BookE related Debug Registers

Signed-off-by: Torez Smith  <lnxtorez@linux.vnet.ibm.com>
Signed-off-by: Dave Kleikamp <shaggy@linux.vnet.ibm.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Thiago Jung Bauermann <bauerman@br.ibm.com>
Cc: Sergio Durigan Junior <sergiodj@br.ibm.com>
Cc: David Gibson <dwg@au1.ibm.com>
Cc: linuxppc-dev list <Linuxppc-dev@ozlabs.org>
---

 arch/powerpc/include/asm/system.h |    2 
 arch/powerpc/kernel/process.c     |  109 ++++++++-
 arch/powerpc/kernel/ptrace.c      |  435 ++++++++++++++++++++++++++++++++++---
 arch/powerpc/kernel/signal.c      |    6 -
 arch/powerpc/kernel/signal_32.c   |    8 +
 arch/powerpc/kernel/traps.c       |   86 ++++++-
 6 files changed, 564 insertions(+), 82 deletions(-)


diff --git a/arch/powerpc/include/asm/system.h b/arch/powerpc/include/asm/system.h
index bb8e006..474bf23 100644
--- a/arch/powerpc/include/asm/system.h
+++ b/arch/powerpc/include/asm/system.h
@@ -114,6 +114,8 @@ static inline int debugger_fault_handler(struct pt_regs *regs) { return 0; }
 extern int set_dabr(unsigned long dabr);
 extern void do_dabr(struct pt_regs *regs, unsigned long address,
 		    unsigned long error_code);
+extern void do_send_trap(struct pt_regs *regs, unsigned long address,
+			 unsigned long error_code, int signal_code, int errno);
 extern void print_backtrace(unsigned long *);
 extern void show_regs(struct pt_regs * regs);
 extern void flush_instruction_cache(void);
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index c930ac3..a0dbb09 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -245,6 +245,24 @@ void discard_lazy_cpu_state(void)
 }
 #endif /* CONFIG_SMP */
 
+void do_send_trap(struct pt_regs *regs, unsigned long address,
+		  unsigned long error_code, int signal_code, int errno)
+{
+	siginfo_t info;
+
+	if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, error_code,
+			11, SIGSEGV) == NOTIFY_STOP)
+		return;
+
+	/* Deliver the signal to userspace */
+	info.si_signo = SIGTRAP;
+	info.si_errno = errno;
+	info.si_code = signal_code;
+	info.si_addr = (void __user *)address;
+	force_sig_info(SIGTRAP, &info, current);
+}
+
+#if !(defined(CONFIG_40x) || defined(CONFIG_BOOKE))
 void do_dabr(struct pt_regs *regs, unsigned long address,
 		    unsigned long error_code)
 {
@@ -257,12 +275,6 @@ void do_dabr(struct pt_regs *regs, unsigned long address,
 	if (debugger_dabr_match(regs))
 		return;
 
-	/* Clear the DAC and struct entries.  One shot trigger */
-#if defined(CONFIG_BOOKE)
-	mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) & ~(DBSR_DAC1R | DBSR_DAC1W
-							| DBCR0_IDM));
-#endif
-
 	/* Clear the DABR */
 	set_dabr(0);
 
@@ -273,9 +285,71 @@ void do_dabr(struct pt_regs *regs, unsigned long address,
 	info.si_addr = (void __user *)address;
 	force_sig_info(SIGTRAP, &info, current);
 }
+#endif
 
 static DEFINE_PER_CPU(unsigned long, current_dabr);
 
+#if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
+/*
+ * Set the debug registers back to their default "safe" values.
+ */
+static void set_debug_reg_defaults(struct thread_struct *thread)
+{
+	thread->iac1 = thread->iac2 = thread->iac3 = thread->iac4 = 0;
+	thread->dac1 = thread->dac2 = 0;
+	thread->dvc1 = thread->dvc2 = 0;
+	/*
+	 * reset the DBCR0, DBCR1 and DBCR2 registers. All bits with
+	 * the exception of the reserved bits should be cleared out
+	 * and set to 0.
+	 *
+	 * For the DBCR0 register, the reserved bits are bits 17:30.
+	 * Reserved bits for DBCR1 are bits 10:14 and bits 26:30.
+	 * And, bits 10:11 for DBCR2.
+	 */
+	thread->dbcr0 = DBCR0_BASE_REG_VALUE;
+	/*
+	 * First clear all "non reserved" bits from DBCR1 then initialize reg
+	 * to force User/Supervisor bits to b11 (user-only MSR[PR]=1) and
+	 * Effective/Real * bits to b10 (trap only if IS==0)
+	 */
+	thread->dbcr1 = DBCR1_BASE_REG_VALUE;
+	/*
+	 * Force Data Address Compare User/Supervisor bits to be User-only
+	 * (0b11 MSR[PR]=1) and set all other bits in DBCR2 register to be 0.
+	 * This sets the Data Address Compare Effective/Real bits to be 0b00
+	 * (Effective, MSR[DS]=don't care).
+	 */
+	thread->dbcr2 = DBCR2_BASE_REG_VALUE;
+}
+
+static void prime_debug_regs(struct thread_struct *thread)
+{
+	mtspr(SPRN_IAC1, thread->iac1);
+	mtspr(SPRN_IAC2, thread->iac2);
+	mtspr(SPRN_IAC3, thread->iac3);
+	mtspr(SPRN_IAC4, thread->iac4);
+	mtspr(SPRN_DAC1, thread->dac1);
+	mtspr(SPRN_DAC2, thread->dac2);
+	mtspr(SPRN_DVC1, thread->dvc1);
+	mtspr(SPRN_DVC2, thread->dvc2);
+	mtspr(SPRN_DBCR0, thread->dbcr0);
+	mtspr(SPRN_DBCR1, thread->dbcr1);
+	mtspr(SPRN_DBCR2, thread->dbcr2);
+}
+/*
+ * Unless neither the old or new thread are making use of the
+ * debug registers, set the debug registers from the values
+ * stored in the new thread.
+ */
+static void switch_booke_debug_regs(struct thread_struct *new_thread)
+{
+	if ((current->thread.dbcr0 & DBCR0_IDM)
+		|| (new_thread->dbcr0 & DBCR0_IDM))
+			prime_debug_regs(new_thread);
+}
+#endif
+
 int set_dabr(unsigned long dabr)
 {
 	__get_cpu_var(current_dabr) = dabr;
@@ -284,7 +358,7 @@ int set_dabr(unsigned long dabr)
 		return ppc_md.set_dabr(dabr);
 
 	/* XXX should we have a CPU_FTR_HAS_DABR ? */
-#if defined(CONFIG_BOOKE)
+#if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
 	mtspr(SPRN_DAC1, dabr);
 #elif defined(CONFIG_PPC_BOOK3S)
 	mtspr(SPRN_DABR, dabr);
@@ -371,10 +445,8 @@ struct task_struct *__switch_to(struct task_struct *prev,
 
 #endif /* CONFIG_SMP */
 
-#if defined(CONFIG_BOOKE)
-	/* If new thread DAC (HW breakpoint) is the same then leave it */
-	if (new->thread.dabr)
-		set_dabr(new->thread.dabr);
+#if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
+	switch_booke_debug_regs(&new->thread);
 #else
 	if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr))
 		set_dabr(new->thread.dabr);
@@ -514,7 +586,7 @@ void show_regs(struct pt_regs * regs)
 	printk("  CR: %08lx  XER: %08lx\n", regs->ccr, regs->xer);
 	trap = TRAP(regs);
 	if (trap == 0x300 || trap == 0x600)
-#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+#if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
 		printk("DEAR: "REG", ESR: "REG"\n", regs->dar, regs->dsisr);
 #else
 		printk("DAR: "REG", DSISR: "REG"\n", regs->dar, regs->dsisr);
@@ -568,14 +640,19 @@ void flush_thread(void)
 
 	discard_lazy_cpu_state();
 
+#if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
+	/*
+	 * flush_thread() is called on exec() to reset the
+	 * thread's status. Set all debug regs back to their
+	 * default values....Torez
+	 */
+	set_debug_reg_defaults(&current->thread);
+#else
 	if (current->thread.dabr) {
 		current->thread.dabr = 0;
 		set_dabr(0);
-
-#if defined(CONFIG_BOOKE)
-		current->thread.dbcr0 &= ~(DBSR_DAC1R | DBSR_DAC1W);
-#endif
 	}
+#endif
 }
 
 void
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 6be2ce0..6710a69 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -737,17 +737,25 @@ void user_disable_single_step(struct task_struct *task)
 	struct pt_regs *regs = task->thread.regs;
 
 	if (regs != NULL) {
-#if defined(CONFIG_BOOKE)
-		/* If DAC don't clear DBCRO_IDM or MSR_DE */
-		if (task->thread.dabr)
-			task->thread.dbcr0 &= ~(DBCR0_IC | DBCR0_BT);
-		else {
-			task->thread.dbcr0 &= ~(DBCR0_IC | DBCR0_BT | DBCR0_IDM);
+#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
+		/*
+		 * The logic to disable single stepping should be as
+		 * simple as turning off the Instruction Complete flag.
+		 * And, after doing so, if all debug flags are off, turn
+		 * off DBCR0(IDM) and MSR(DE) .... Torez
+		 */
+		task->thread.dbcr0 &= ~DBCR0_IC;
+		/*
+		 * Test to see if any of the DBCR_ACTIVE_EVENTS bits are set.
+		 */
+		if (!DBCR_ACTIVE_EVENTS(task->thread.dbcr0,
+					task->thread.dbcr1)) {
+			/*
+			 * All debug events were off.....
+			 */
+			task->thread.dbcr0 &= ~DBCR0_IDM;
 			regs->msr &= ~MSR_DE;
 		}
-#elif defined(CONFIG_40x)
-		task->thread.dbcr0 &= ~(DBCR0_IC | DBCR0_BT | DBCR0_IDM);
-		regs->msr &= ~MSR_DE;
 #else
 		regs->msr &= ~(MSR_SE | MSR_BE);
 #endif
@@ -769,8 +777,7 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
 	if ((data & ~0x7UL) >= TASK_SIZE)
 		return -EIO;
 
-#ifndef CONFIG_BOOKE
-
+#if !(defined(CONFIG_40x) || defined(CONFIG_BOOKE))
 	/* For processors using DABR (i.e. 970), the bottom 3 bits are flags.
 	 *  It was assumed, on previous implementations, that 3 bits were
 	 *  passed together with the data address, fitting the design of the
@@ -789,21 +796,22 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
 
 	/* Move contents to the DABR register */
 	task->thread.dabr = data;
-
-#endif
-#if defined(CONFIG_BOOKE)
-
+#else
 	/* As described above, it was assumed 3 bits were passed with the data
 	 *  address, but we will assume only the mode bits will be passed
 	 *  as to not cause alignment restrictions for DAC-based processors.
 	 */
 
 	/* DAC's hold the whole address without any mode flags */
-	task->thread.dabr = data & ~0x3UL;
-
-	if (task->thread.dabr == 0) {
-		task->thread.dbcr0 &= ~(DBSR_DAC1R | DBSR_DAC1W | DBCR0_IDM);
-		task->thread.regs->msr &= ~MSR_DE;
+	task->thread.dac1 = data & ~0x3UL;
+
+	if (task->thread.dac1 == 0) {
+		dbcr_dac(task) &= ~(DBCR_DAC1R | DBCR_DAC1W);
+		if (!DBCR_ACTIVE_EVENTS(task->thread.dbcr0,
+					task->thread.dbcr1)) {
+			task->thread.regs->msr &= ~MSR_DE;
+			task->thread.dbcr0 &= ~DBCR0_IDM;
+		}
 		return 0;
 	}
 
@@ -814,15 +822,15 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
 
 	/* Set the Internal Debugging flag (IDM bit 1) for the DBCR0
 	   register */
-	task->thread.dbcr0 = DBCR0_IDM;
+	task->thread.dbcr0 |= DBCR0_IDM;
 
 	/* Check for write and read flags and set DBCR0
 	   accordingly */
+	dbcr_dac(task) &= ~(DBCR_DAC1R|DBCR_DAC1W);
 	if (data & 0x1UL)
-		task->thread.dbcr0 |= DBSR_DAC1R;
+		dbcr_dac(task) |= DBCR_DAC1R;
 	if (data & 0x2UL)
-		task->thread.dbcr0 |= DBSR_DAC1W;
-
+		dbcr_dac(task) |= DBCR_DAC1W;
 	task->thread.regs->msr |= MSR_DE;
 #endif
 	return 0;
@@ -839,11 +847,324 @@ void ptrace_disable(struct task_struct *child)
 	user_disable_single_step(child);
 }
 
+#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
+static long set_intruction_bp(struct task_struct *child,
+			      struct ppc_hw_breakpoint *bp_info)
+{
+	int slots_needed;
+	int slot;
+	int free_slot = 0;
+
+	/*
+	 * Find an avalailable slot for the breakpoint.
+	 * If possible, reserve consecutive slots, 1 & 2, for a range
+	 * breakpoint.  (Can this be done simpler?)
+	 */
+	if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_EXACT)
+		slots_needed = 1;
+	else
+		slots_needed = 2;
+
+	if ((child->thread.dbcr0 & DBCR0_IAC1) == 0) {
+		if (slots_needed == 1) {
+			if (child->thread.dbcr0 & DBCR0_IAC2) {
+				slot = 1;
+				goto found;
+			}
+			/* Try to save slots 1 & 2 for range */
+			free_slot = 1;
+		} else
+			if ((child->thread.dbcr0 & DBCR0_IAC2) == 0) {
+				slot = 1;
+				goto found;
+			}
+	} else if ((slots_needed == 1) &&
+		   ((child->thread.dbcr0 & DBCR0_IAC2) == 0)) {
+		slot = 2;
+		goto found;
+	}
+	if ((child->thread.dbcr0 & DBCR0_IAC3) == 0) {
+		if (slots_needed == 1) {
+			slot = 3;
+			goto found;
+		}
+		if ((child->thread.dbcr0 & DBCR0_IAC4) == 0) {
+			slot = 3;
+			goto found;
+		}
+		return -ENOSPC;
+	} else if (slots_needed == 2)
+		return -ENOSPC;
+	if ((child->thread.dbcr0 & DBCR0_IAC4) == 0) {
+		slot = 4;
+	} else if (free_slot)
+		slot = free_slot;
+	else
+		return -ENOSPC;
+found:
+	if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_EXACT) {
+		switch (slot) {
+			case 1:
+				child->thread.iac1 = bp_info->addr;
+				child->thread.dbcr0 |= DBCR0_IAC1;
+				break;
+			case 2:
+				child->thread.iac2 = bp_info->addr;
+				child->thread.dbcr0 |= DBCR0_IAC2;
+				break;
+			case 3:
+				child->thread.iac3 = bp_info->addr;
+				child->thread.dbcr0 |= DBCR0_IAC3;
+				break;
+			case 4:
+				child->thread.iac4 = bp_info->addr;
+				child->thread.dbcr0 |= DBCR0_IAC4;
+				break;
+		}
+	} else if (slot == 1) {
+		child->thread.iac1 = bp_info->addr;
+		child->thread.iac2 = bp_info->addr2;
+		child->thread.dbcr0 |= (DBCR0_IAC1 | DBCR0_IAC2);
+		if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE)
+			dbcr_iac_range(child) |= DBCR_IAC12M_X;
+		else
+			dbcr_iac_range(child) |= DBCR_IAC12M_I;
+	} else { /* slot == 3 */
+		child->thread.iac3 = bp_info->addr;
+		child->thread.iac4 = bp_info->addr2;
+		child->thread.dbcr0 |= (DBCR0_IAC3 | DBCR0_IAC4);
+		if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE)
+			dbcr_iac_range(child) |= DBCR_IAC34M_X;
+		else
+			dbcr_iac_range(child) |= DBCR_IAC34M_I;
+	}
+	child->thread.dbcr0 |= DBCR0_IDM;
+	child->thread.regs->msr |= MSR_DE;
+
+	return slot;
+}
+
+static int del_instruction_bp(struct task_struct *child, int slot)
+{
+	switch (slot) {
+	case 1:
+		if (dbcr_iac_range(child) & DBCR_IAC12M) {
+			/* address range - clear slots 1 & 2 */
+			child->thread.iac2 = 0;
+			child->thread.dbcr0 &= ~DBCR0_IAC2;
+			dbcr_iac_range(child) &= ~DBCR_IAC12M;
+		}
+		child->thread.iac1 = 0;
+		child->thread.dbcr0 &= ~DBCR0_IAC1;
+		break;
+	case 2:
+		if (dbcr_iac_range(child) & DBCR_IAC12M)
+			/* used in a range */
+			return -EINVAL;
+		child->thread.iac2 = 0;
+		child->thread.dbcr0 &= ~DBCR0_IAC2;
+		break;
+	case 3:
+		if (dbcr_iac_range(child) & DBCR_IAC34M) {
+			/* address range - clear slots 3 & 4 */
+			child->thread.iac4 = 0;
+			child->thread.dbcr0 &= ~DBCR0_IAC4;
+			dbcr_iac_range(child) &= ~DBCR_IAC34M;
+		}
+		child->thread.iac3 = 0;
+		child->thread.dbcr0 &= ~DBCR0_IAC3;
+		break;
+	case 4:
+		if (dbcr_iac_range(child) & DBCR_IAC34M)
+			/* Used in a range */
+			return -EINVAL;
+		child->thread.iac4 = 0;
+		child->thread.dbcr0 &= ~DBCR0_IAC4;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int set_dac(struct task_struct *child, struct ppc_hw_breakpoint *bp_info)
+{
+	int byte_enable =
+		(bp_info->condition_mode >> PPC_BREAKPOINT_CONDITION_BE_SHIFT)
+		& 0xf;
+	int condition_mode =
+		bp_info->condition_mode & PPC_BREAKPOINT_CONDITION_AND_OR;
+	int slot;
+
+	if (byte_enable && (condition_mode == 0))
+		return -EINVAL;
+
+	if (bp_info->addr >= TASK_SIZE)
+		return -EIO;
+
+	if ((dbcr_dac(child) & (DBCR_DAC1R | DBCR_DAC1W)) == 0) {
+		if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ)
+			dbcr_dac(child) |= DBCR_DAC1R;
+		if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
+			dbcr_dac(child) |= DBCR_DAC1W;
+		child->thread.dac1 = (unsigned long)bp_info->addr;
+#ifdef CONFIG_BOOKE
+		if (byte_enable) {
+			child->thread.dvc1 =
+				(unsigned long)bp_info->condition_value;
+			child->thread.dbcr2 |=
+				((byte_enable << DBCR2_DVC1BE_SHIFT) |
+				 (condition_mode << DBCR2_DVC1M_SHIFT));
+		}
+#endif
+		slot = 1;
+	} else if ((dbcr_dac(child) & (DBCR_DAC2R | DBCR_DAC2W)) == 0) {
+		if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ)
+			dbcr_dac(child) |= DBCR_DAC2R;
+		if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
+			dbcr_dac(child) |= DBCR_DAC2W;
+		child->thread.dac2 = (unsigned long)bp_info->addr;
+#ifdef CONFIG_BOOKE
+		if (byte_enable) {
+			child->thread.dvc2 =
+				(unsigned long)bp_info->condition_value;
+			child->thread.dbcr2 |=
+				((byte_enable << DBCR2_DVC2BE_SHIFT) |
+				 (condition_mode << DBCR2_DVC2M_SHIFT));
+		}
+#endif
+		slot = 2;
+	} else
+		return -ENOSPC;
+	child->thread.dbcr0 |= DBCR0_IDM;
+	child->thread.regs->msr |= MSR_DE;
+
+	return slot + 4;
+}
+
+static int del_dac(struct task_struct *child, int slot)
+{
+	if (slot == 1) {
+#ifdef CONFIG_BOOKE
+		if (child->thread.dbcr2 & DBCR2_DAC12MODE) {
+			child->thread.dac1 = 0;
+			child->thread.dac2 = 0;
+			child->thread.dbcr0 &= ~(DBCR0_DAC1R | DBCR0_DAC1W |
+						 DBCR0_DAC2R | DBCR0_DAC2W);
+			child->thread.dbcr2 &= ~DBCR2_DAC12MODE;
+			return 0;
+		}
+		child->thread.dbcr2 &= ~(DBCR2_DVC1M | DBCR2_DVC1BE);
+		child->thread.dvc1 = 0;
+#endif
+		child->thread.dac1 = 0;
+		dbcr_dac(child) &= ~(DBCR_DAC1R | DBCR_DAC1W);
+	} else if (slot == 2) {
+#ifdef CONFIG_BOOKE
+		if (child->thread.dbcr2 & DBCR2_DAC12MODE)
+			/* Part of a range */
+			return -EINVAL;
+		child->thread.dbcr2 &= ~(DBCR2_DVC2M | DBCR2_DVC2BE);
+		child->thread.dvc2 = 0;
+#endif
+		child->thread.dac2 = 0;
+		dbcr_dac(child) &= ~(DBCR_DAC2R | DBCR_DAC2W);
+	} else
+		return -EINVAL;
+
+	return 0;
+}
+#endif /* CONFIG_40x || CONFIG_BOOKE */
+
+#ifdef CONFIG_BOOKE
+static int set_dac_range(struct task_struct *child,
+			 struct ppc_hw_breakpoint *bp_info)
+{
+	int mode = bp_info->addr_mode & PPC_BREAKPOINT_MODE_MASK;
+
+	/* We don't allow range watchpoints to be used with DVC */
+	if (bp_info->condition_mode && PPC_BREAKPOINT_CONDITION_BE_ALL)
+		return -EINVAL;
+
+	if (bp_info->addr >= TASK_SIZE)
+		return -EIO;
+
+	if (child->thread.dbcr0 &
+	    (DBCR0_DAC1R | DBCR0_DAC1W | DBCR0_DAC2R | DBCR0_DAC2W))
+		return -ENOSPC;
+
+	if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ)
+		child->thread.dbcr0 |= (DBCR0_DAC1R | DBCR0_DAC2R | DBCR0_IDM);
+	if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
+		child->thread.dbcr0 |= (DBCR0_DAC1W | DBCR0_DAC2W | DBCR0_IDM);
+	child->thread.dac1 = bp_info->addr;
+	child->thread.dac2 = bp_info->addr2;
+	if (mode == PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE)
+		child->thread.dbcr2  |= DBCR2_DAC12R;
+	else if (mode == PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE)
+		child->thread.dbcr2  |= DBCR2_DAC12RX;
+	else	/* PPC_BREAKPOINT_MODE_MASK */
+		child->thread.dbcr2  |= DBCR2_DAC12MASK;
+	child->thread.regs->msr |= MSR_DE;
+
+	return 5;
+}
+#endif /* CONFIG_BOOKE */
+
 static long ppc_set_hwdebug(struct task_struct *child,
 		     struct ppc_hw_breakpoint *bp_info)
 {
+	if (bp_info->version != 1)
+		return -ENOTSUPP;
+
+#ifdef CONFIG_BOOKE
+	/*
+	 * Check for invalid flags and combinations
+	 */
+	if ((bp_info->trigger_type == 0) ||
+	    (bp_info->trigger_type & ~(PPC_BREAKPOINT_TRIGGER_EXECUTE |
+				       PPC_BREAKPOINT_TRIGGER_RW)) ||
+	    (bp_info->addr_mode & ~PPC_BREAKPOINT_MODE_MASK) ||
+	    (bp_info->condition_mode &
+	     ~(PPC_BREAKPOINT_CONDITION_AND_OR |
+	       PPC_BREAKPOINT_CONDITION_BE_ALL)))
+		return -EINVAL;
+
+	if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_EXECUTE) {
+		if (bp_info->trigger_type != PPC_BREAKPOINT_TRIGGER_EXECUTE)
+			/* At least another bit was set */
+			return -EINVAL;
+		return set_intruction_bp(child, bp_info);
+	}
+
+	if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_EXACT)
+		return set_dac(child, bp_info);
+
+	return set_dac_range(child, bp_info);
+#elif defined(CONFIG_40x)
+	/*
+	 * Check for invalid flags and combinations
+	 */
+	if ((bp_info->trigger_type == 0) ||
+	    (bp_info->trigger_type & ~(PPC_BREAKPOINT_TRIGGER_EXECUTE |
+				       PPC_BREAKPOINT_TRIGGER_RW)) ||
+	    (bp_info->addr_mode & ~PPC_BREAKPOINT_MODE_MASK) ||
+	    (bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE))
+		return -EINVAL;
+
+	if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_EXECUTE) {
+		if (bp_info->trigger_type != PPC_BREAKPOINT_TRIGGER_EXECUTE)
+			/* At least another bit was set */
+			return -EINVAL;
+		return set_intruction_bp(child, bp_info);
+	}
+	if (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT)
+		return -EINVAL;
+
+	return set_dac(child, bp_info);
+#else
 	/*
-	 * We currently support one data breakpoint
+	 * We only support one data breakpoint
 	 */
 	if (((bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_RW) == 0) ||
 	    ((bp_info->trigger_type & ~PPC_BREAKPOINT_TRIGGER_RW) != 0) ||
@@ -859,28 +1180,35 @@ static long ppc_set_hwdebug(struct task_struct *child,
 		return -EIO;
 
 	child->thread.dabr = (unsigned long)bp_info->addr;
-#ifdef CONFIG_BOOKE
-	child->thread.dbcr0 = DBCR0_IDM;
-	if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ)
-		child->thread.dbcr0 |= DBSR_DAC1R;
-	if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
-		child->thread.dbcr0 |= DBSR_DAC1W;
-	child->thread.regs->msr |= MSR_DE;
-#endif
 	return 1;
+#endif
 }
 
 static long ppc_del_hwdebug(struct task_struct *child, long addr, long data)
 {
+#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
+	int rc;
+
+	if (data <= 4)
+		rc = del_instruction_bp(child, (int)data);
+	else
+		rc = del_dac(child, (int)data - 4);
+
+	if (!rc) {
+		if (!DBCR_ACTIVE_EVENTS(child->thread.dbcr0,
+					child->thread.dbcr1)) {
+			child->thread.dbcr0 &= ~DBCR0_IDM;
+			child->thread.regs->msr &= ~MSR_DE;
+		}
+	}
+	return rc;
+#else
 	if ((data != 1) || (child->thread.dabr == 0))
 		return -EINVAL;
 
 	child->thread.dabr = 0;
-#ifdef CONFIG_BOOKE
-	child->thread.dbcr0 &= ~(DBSR_DAC1R | DBSR_DAC1W | DBCR0_IDM);
-	child->thread.regs->msr &= ~MSR_DE;
-#endif
 	return 0;
+#endif
 }
 
 /*
@@ -980,16 +1308,36 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 		struct ppc_debug_info dbginfo;
 
 		dbginfo.version = 1;
+#ifdef CONFIG_BOOKE
+		dbginfo.num_instruction_bps = 4;
+		dbginfo.num_data_bps = 2;
+		dbginfo.num_condition_regs = 2;
+		dbginfo.data_bp_alignment = 0;
+		dbginfo.sizeof_condition = 4;
+		dbginfo.features = PPC_DEBUG_FEATURE_INSN_BP_RANGE |
+				   PPC_DEBUG_FEATURE_INSN_BP_MASK |
+				   PPC_DEBUG_FEATURE_DATA_BP_RANGE |
+				   PPC_DEBUG_FEATURE_DATA_BP_MASK;
+#elif defined(CONFIG_40x)
+		/*
+		 * I don't know how the DVCs work on 40x, I'm not going
+		 * to support it now. -- Shaggy
+		 */
+		dbginfo.num_instruction_bps = 4;
+		dbginfo.num_data_bps = 2;
+		dbginfo.num_condition_regs = 0;
+		dbginfo.data_bp_alignment = 0;
+		dbginfo.sizeof_condition = 0;
+		dbginfo.features = PPC_DEBUG_FEATURE_INSN_BP_RANGE |
+				   PPC_DEBUG_FEATURE_INSN_BP_MASK;
+#else
 		dbginfo.num_instruction_bps = 0;
 		dbginfo.num_data_bps = 1;
 		dbginfo.num_condition_regs = 0;
-#ifdef CONFIG_PPC64
 		dbginfo.data_bp_alignment = 8;
-#else
-		dbginfo.data_bp_alignment = 0;
-#endif
 		dbginfo.sizeof_condition = 0;
 		dbginfo.features = 0;
+#endif
 
 		if (!access_ok(VERIFY_WRITE, data,
 			       sizeof(struct ppc_debug_info)))
@@ -1025,8 +1373,13 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 		/* We only support one DABR and no IABRS at the moment */
 		if (addr > 0)
 			break;
+#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
+		ret = put_user(child->thread.dac1,
+			       (unsigned long __user *)data);
+#else
 		ret = put_user(child->thread.dabr,
 			       (unsigned long __user *)data);
+#endif
 		break;
 	}
 
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index 00b5078..94df779 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -140,17 +140,15 @@ static int do_signal_pending(sigset_t *oldset, struct pt_regs *regs)
 		return 0;               /* no signals delivered */
 	}
 
+#if !(defined(CONFIG_BOOKE) || defined(CONFIG_40x))
         /*
 	 * Reenable the DABR before delivering the signal to
 	 * user space. The DABR will have been cleared if it
 	 * triggered inside the kernel.
 	 */
-	if (current->thread.dabr) {
+	if (current->thread.dabr)
 		set_dabr(current->thread.dabr);
-#if defined(CONFIG_BOOKE)
-		mtspr(SPRN_DBCR0, current->thread.dbcr0);
 #endif
-	}
 
 	if (is32) {
         	if (ka.sa.sa_flags & SA_SIGINFO)
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index d670429..6cc6e81 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -1092,8 +1092,12 @@ int sys_debug_setcontext(struct ucontext __user *ctx,
 				new_msr |= MSR_DE;
 				new_dbcr0 |= (DBCR0_IDM | DBCR0_IC);
 			} else {
-				new_msr &= ~MSR_DE;
-				new_dbcr0 &= ~(DBCR0_IDM | DBCR0_IC);
+				new_dbcr0 &= ~DBCR0_IC;
+				if (!DBCR_ACTIVE_EVENTS(new_dbcr0,
+						current->thread.dbcr1)) {
+					new_msr &= ~MSR_DE;
+					new_dbcr0 &= ~DBCR0_IDM;
+				}
 			}
 #else
 			if (op.dbg_value)
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index a81c743..d919571 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -1016,9 +1016,63 @@ void SoftwareEmulation(struct pt_regs *regs)
 #endif /* CONFIG_8xx */
 
 #if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
+static void handle_debug(struct pt_regs *regs, unsigned long debug_status)
+{
+	int changed = 0;
+	/*
+	 * Determine the cause of the debug event, clear the
+	 * event flags and send a trap to the handler. Torez
+	 */
+	if (debug_status & (DBSR_DAC1R | DBSR_DAC1W)) {
+		dbcr_dac(current) &= ~(DBCR_DAC1R | DBCR_DAC1W);
+		do_send_trap(regs, mfspr(SPRN_DAC1), debug_status, TRAP_HWBKPT,
+			     5);
+		changed |= 0x01;
+	}  else if (debug_status & (DBSR_DAC2R | DBSR_DAC2W)) {
+		dbcr_dac(current) &= ~(DBCR_DAC2R | DBCR_DAC2W);
+		do_send_trap(regs, mfspr(SPRN_DAC2), debug_status, TRAP_HWBKPT,
+			     6);
+		changed |= 0x01;
+	}  else if (debug_status & DBSR_IAC1) {
+		current->thread.dbcr0 &= ~DBCR0_IAC1;
+		do_send_trap(regs, mfspr(SPRN_IAC1), debug_status, TRAP_HWBKPT,
+			     1);
+		changed |= 0x01;
+	}  else if (debug_status & DBSR_IAC2) {
+		current->thread.dbcr0 &= ~DBCR0_IAC2;
+		do_send_trap(regs, mfspr(SPRN_IAC2), debug_status, TRAP_HWBKPT,
+			     2);
+		changed |= 0x01;
+	}  else if (debug_status & DBSR_IAC3) {
+		current->thread.dbcr0 &= ~DBCR0_IAC3;
+		do_send_trap(regs, mfspr(SPRN_IAC3), debug_status, TRAP_HWBKPT,
+			     3);
+		changed |= 0x01;
+	}  else if (debug_status & DBSR_IAC4) {
+		current->thread.dbcr0 &= ~DBCR0_IAC4;
+		do_send_trap(regs, mfspr(SPRN_IAC4), debug_status, TRAP_HWBKPT,
+			     4);
+		changed |= 0x01;
+	}
+	/*
+	 * At the point this routine was called, the MSR(DE) was turned off.
+	 * Check all other debug flags and see if that bit needs to be turned
+	 * back on or not.
+	 */
+	if (DBCR_ACTIVE_EVENTS(current->thread.dbcr0, current->thread.dbcr1))
+		regs->msr |= MSR_DE;
+	else
+		/* Make sure the IDM flag is off */
+		current->thread.dbcr0 &= ~DBCR0_IDM;
+
+	if (changed & 0x01)
+		mtspr(SPRN_DBCR0, current->thread.dbcr0);
+}
 
 void __kprobes DebugException(struct pt_regs *regs, unsigned long debug_status)
 {
+	current->thread.dbsr = debug_status;
+
 	/* Hack alert: On BookE, Branch Taken stops on the branch itself, while
 	 * on server, it stops on the target of the branch. In order to simulate
 	 * the server behaviour, we thus restart right away with a single step
@@ -1062,27 +1116,21 @@ void __kprobes DebugException(struct pt_regs *regs, unsigned long debug_status)
 		if (debugger_sstep(regs))
 			return;
 
-		if (user_mode(regs))
-			current->thread.dbcr0 &= ~(DBCR0_IC);
-
-		_exception(SIGTRAP, regs, TRAP_TRACE, regs->nip);
-	} else if (debug_status & (DBSR_DAC1R | DBSR_DAC1W)) {
-		regs->msr &= ~MSR_DE;
-
 		if (user_mode(regs)) {
-			current->thread.dbcr0 &= ~(DBSR_DAC1R | DBSR_DAC1W |
-								DBCR0_IDM);
-		} else {
-			/* Disable DAC interupts */
-			mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) & ~(DBSR_DAC1R |
-						DBSR_DAC1W | DBCR0_IDM));
-
-			/* Clear the DAC event */
-			mtspr(SPRN_DBSR, (DBSR_DAC1R | DBSR_DAC1W));
+			current->thread.dbcr0 &= ~DBCR0_IC;
+#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
+			if (DBCR_ACTIVE_EVENTS(current->thread.dbcr0,
+					       current->thread.dbcr1))
+				regs->msr |= MSR_DE;
+			else
+				/* Make sure the IDM bit is off */
+				current->thread.dbcr0 &= ~DBCR0_IDM;
+#endif
 		}
-		/* Setup and send the trap to the handler */
-		do_dabr(regs, mfspr(SPRN_DAC1), debug_status);
-	}
+
+		_exception(SIGTRAP, regs, TRAP_TRACE, regs->nip);
+	} else
+		handle_debug(regs, debug_status);
 }
 #endif /* CONFIG_4xx || CONFIG_BOOKE */
 

-- 
Dave Kleikamp
IBM Linux Technology Center

^ permalink raw reply related

* [RFC:PATCH 02/03] powerpc: Add definitions for Debug Registers on BookE Platforms
From: Dave Kleikamp @ 2009-12-10 15:57 UTC (permalink / raw)
  To: linuxppc-dev list
  Cc: Sergio Durigan Junior, Torez Smith, David Gibson,
	Thiago Jung Bauermann
In-Reply-To: <20091210155709.6697.4635.sendpatchset@norville.austin.ibm.com>

powerpc: Add definitions for Debug Registers on BookE Platforms

From: Torez Smith <lnxtorez@linux.vnet.ibm.com>

This patch adds additional definitions for BookE Debug Registers
to the reg_booke.h header file.

Signed-off-by: Torez Smith  <lnxtorez@linux.vnet.ibm.com>
Signed-off-by: Dave Kleikamp <shaggy@linux.vnet.ibm.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Thiago Jung Bauermann <bauerman@br.ibm.com>
Cc: Sergio Durigan Junior <sergiodj@br.ibm.com>
Cc: David Gibson <dwg@au1.ibm.com>
Cc: linuxppc-dev list <Linuxppc-dev@ozlabs.org>
---

 arch/powerpc/include/asm/processor.h |   30 +++++-
 arch/powerpc/include/asm/reg_booke.h |  176 +++++++++++++++++++++++++++++-----
 2 files changed, 178 insertions(+), 28 deletions(-)


diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index 9eed29e..1393307 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -161,9 +161,35 @@ struct thread_struct {
 #ifdef CONFIG_PPC32
 	void		*pgdir;		/* root of page-table tree */
 #endif
-#if defined(CONFIG_4xx) || defined (CONFIG_BOOKE)
-	unsigned long	dbcr0;		/* debug control register values */
+#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
+	/*
+	 * The following help to manage the use of Debug Control Registers
+	 * om the BookE platforms.
+	 */
+	unsigned long	dbcr0;
 	unsigned long	dbcr1;
+	unsigned long	dbcr2;
+	/*
+	 * The stored value of the DBSR register will be the value at the
+	 * last debug interrupt. This register can only be read from the
+	 * user (will never be written to) and has value while helping to
+	 * describe the reason for the last debug trap.  Torez
+	 */
+	unsigned long	dbsr;
+	/*
+	 * The following will contain addresses used by debug applications
+	 * to help trace and trap on particular address locations.
+	 * The bits in the Debug Control Registers above help define which
+	 * of the following registers will contain valid data and/or addresses.
+	 */
+	unsigned long	iac1;
+	unsigned long	iac2;
+	unsigned long	iac3;
+	unsigned long	iac4;
+	unsigned long	dac1;
+	unsigned long	dac2;
+	unsigned long	dvc1;
+	unsigned long	dvc2;
 #endif
 	/* FP and VSX 0-31 register set */
 	double		fpr[32][TS_FPRWIDTH];
diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h
index 3bf7835..7f8c71f 100644
--- a/arch/powerpc/include/asm/reg_booke.h
+++ b/arch/powerpc/include/asm/reg_booke.h
@@ -248,6 +248,8 @@
 #define DBSR_RET	0x00008000	/* Return Debug Event */
 #define DBSR_CIRPT	0x00000040	/* Critical Interrupt Taken Event */
 #define DBSR_CRET	0x00000020	/* Critical Return Debug Event */
+#define DBSR_IAC12ATS	0x00000002	/* Instr Address Compare 1/2 Toggle */
+#define DBSR_IAC34ATS	0x00000001	/* Instr Address Compare 3/4 Toggle */
 #endif
 #ifdef CONFIG_40x
 #define DBSR_IC		0x80000000	/* Instruction Completion */
@@ -294,25 +296,68 @@
 #define DBCR0_IC	0x08000000	/* Instruction Completion */
 #define DBCR0_ICMP	DBCR0_IC
 #define DBCR0_BT	0x04000000	/* Branch Taken */
-#define DBCR0_BRT	DBCR0_BT
 #define DBCR0_EDE	0x02000000	/* Exception Debug Event */
 #define DBCR0_IRPT	DBCR0_EDE
 #define DBCR0_TDE	0x01000000	/* TRAP Debug Event */
-#define DBCR0_IA1	0x00800000	/* Instr Addr compare 1 enable */
-#define DBCR0_IAC1	DBCR0_IA1
-#define DBCR0_IA2	0x00400000	/* Instr Addr compare 2 enable */
-#define DBCR0_IAC2	DBCR0_IA2
-#define DBCR0_IA12	0x00200000	/* Instr Addr 1-2 range enable */
-#define DBCR0_IA12X	0x00100000	/* Instr Addr 1-2 range eXclusive */
-#define DBCR0_IA3	0x00080000	/* Instr Addr compare 3 enable */
-#define DBCR0_IAC3	DBCR0_IA3
-#define DBCR0_IA4	0x00040000	/* Instr Addr compare 4 enable */
-#define DBCR0_IAC4	DBCR0_IA4
-#define DBCR0_IA34	0x00020000	/* Instr Addr 3-4 range Enable */
-#define DBCR0_IA34X	0x00010000	/* Instr Addr 3-4 range eXclusive */
-#define DBCR0_IA12T	0x00008000	/* Instr Addr 1-2 range Toggle */
-#define DBCR0_IA34T	0x00004000	/* Instr Addr 3-4 range Toggle */
+#define DBCR0_IAC1	0x00800000	/* Instr Addr compare 1 enable */
+#define DBCR0_IAC2	0x00400000	/* Instr Addr compare 2 enable */
+#define DBCR0_IAC12M	0x00300000	/* Instr Addr 1-2 range enable */
+#define DBCR0_IAC12M_R	0x00100000	/* Instr Addr 1-2 Reserved state */
+#define DBCR0_IAC12M_I	0x00200000	/* Instr Addr 1-2 range Inclusive */
+#define DBCR0_IAC12M_X	0x00300000	/* Instr Addr 1-2 range eXclusive */
+#define DBCR0_IAC3	0x00080000	/* Instr Addr compare 3 enable */
+#define DBCR0_IAC4	0x00040000	/* Instr Addr compare 4 enable */
+#define DBCR0_IAC34	0x00020000	/* Instr Addr 3-4 range Enable */
+#define DBCR0_IAC34X	0x00010000	/* Instr Addr 3-4 range eXclusive */
+#define DBCR0_IAC12T	0x00008000	/* Instr Addr 1-2 range Toggle */
+#define DBCR0_IAC34T	0x00004000	/* Instr Addr 3-4 range Toggle */
 #define DBCR0_FT	0x00000001	/* Freeze Timers on debug event */
+
+#define DBCR0_USER_DEBUG	(DBCR0_IDM | DBCR0_ICMP | DBCR0_IAC1 | \
+				 DBCR0_IAC2 | DBCR0_IAC3 | DBCR0_IAC4)
+#define DBCR0_BASE_REG_VALUE	0
+
+#define dbcr_iac_range(task)	((task)->thread.dbcr0)
+#define DBCR_IAC12M	DBCR0_IAC12M
+#define DBCR_IAC12M_I	DBCR0_IAC12M_I
+#define DBCR_IAC12M_X	DBCR0_IAC12M_X
+#define DBCR_IAC34M	DBCR0_IAC34M
+#define DBCR_IAC34M_I	DBCR0_IAC34M_I
+#define DBCR_IAC34M_X	DBCR0_IAC34M_X
+
+/* Bit definitions related to the DBCR1. */
+#define DBCR1_D1R	0x80000000	/* DAC1 Read Debug Event */
+#define DBCR1_DAC1R	DBCR1_D1R
+#define DBCR1_D2R	0x40000000	/* DAC2 Read Debug Event */
+#define DBCR1_DAC2R	DBCR1_D2R
+#define DBCR1_D1W	0x20000000	/* DAC1 Write Debug Event */
+#define DBCR1_DAC1W	DBCR1_D1W
+#define DBCR1_D2W	0x10000000	/* DAC2 Write Debug Event */
+#define DBCR1_DAC2W	DBCR1_D2W
+
+#define DBCR1_USER_DEBUG	(DBCR1_DAC1R | DBCR1_DAC2R | DBCR1_DAC1W | \
+				 DBCR1_DAC2W)
+#define DBCR1_BASE_REG_VALUE	0
+
+#define dbcr_dac(task)	((task)->thread.dbcr1)
+#define DBCR_DAC1R	DBCR1_DAC1R
+#define DBCR_DAC1W	DBCR1_DAC1W
+#define DBCR_DAC2R	DBCR1_DAC2R
+#define DBCR_DAC2W	DBCR1_DAC2W
+
+#define DBCR2_USER_DEBUG	0
+#define DBCR2_BASE_REG_VALUE	0
+
+/*
+ * Are there any active Debug Events represented in the
+ * Debug Control Registers?
+ */
+#define DBCR0_ACTIVE_EVENTS	(DBCR0_ICMP | DBCR0_IAC1 | DBCR0_IAC2 | \
+				 DBCR0_IAC3 | DBCR0_IAC4)
+#define DBCR1_ACTIVE_EVENTS	(DBCR1_D1R | DBCR1_D2R | DBCR1_D1W | DBCR1_D2W)
+#define DBCR_ACTIVE_EVENTS(dbcr0, dbcr1)  (((dbcr0) & DBCR0_ACTIVE_EVENTS) || \
+					   ((dbcr1) & DBCR1_ACTIVE_EVENTS))
+
 #elif defined(CONFIG_BOOKE)
 #define DBCR0_EDM	0x80000000	/* External Debug Mode */
 #define DBCR0_IDM	0x40000000	/* Internal Debug Mode */
@@ -324,8 +369,7 @@
 #define DBCR0_RST_NONE	0x00000000	/* No Reset */
 #define DBCR0_ICMP	0x08000000	/* Instruction Completion */
 #define DBCR0_IC	DBCR0_ICMP
-#define DBCR0_BRT	0x04000000	/* Branch Taken */
-#define DBCR0_BT	DBCR0_BRT
+#define DBCR0_BT	0x04000000	/* Branch Taken */
 #define DBCR0_IRPT	0x02000000	/* Exception Debug Event */
 #define DBCR0_TDE	0x01000000	/* TRAP Debug Event */
 #define DBCR0_TIE	DBCR0_TDE
@@ -342,19 +386,99 @@
 #define DBCR0_CRET	0x00000020	/* Critical Return Debug Event */
 #define DBCR0_FT	0x00000001	/* Freeze Timers on debug event */
 
+#define DBCR0_USER_DEBUG	(DBCR0_IDM | DBCR0_ICMP | DBCR0_IAC1 | \
+				 DBCR0_IAC2 | DBCR0_IAC3 | DBCR0_IAC4 | \
+				 DBCR0_DAC1R | DBCR0_DAC1W  | DBCR0_DAC2R | \
+				 DBCR0_DAC2W)
+#define DBCR0_BASE_REG_VALUE	0
+
+#define dbcr_dac(task)	((task)->thread.dbcr0)
+#define DBCR_DAC1R	DBCR0_DAC1R
+#define DBCR_DAC1W	DBCR0_DAC1W
+#define DBCR_DAC2R	DBCR0_DAC2R
+#define DBCR_DAC2W	DBCR0_DAC2W
+
 /* Bit definitions related to the DBCR1. */
-#define DBCR1_IAC12M	0x00800000	/* Instr Addr 1-2 range enable */
-#define DBCR1_IAC12MX	0x00C00000	/* Instr Addr 1-2 range eXclusive */
-#define DBCR1_IAC12AT	0x00010000	/* Instr Addr 1-2 range Toggle */
-#define DBCR1_IAC34M	0x00000080	/* Instr Addr 3-4 range enable */
-#define DBCR1_IAC34MX	0x000000C0	/* Instr Addr 3-4 range eXclusive */
-#define DBCR1_IAC34AT	0x00000001	/* Instr Addr 3-4 range Toggle */
+#define DBCR1_IAC1US	0xC0000000	/* Instr Addr Cmp 1 Sup/User   */
+#define DBCR1_IAC1ER	0x30000000	/* Instr Addr Cmp 1 Eff/Real */
+#define DBCR1_IAC1ER_01	0x10000000	/* reserved */
+#define DBCR1_IAC1ER_10	0x20000000	/* Instr Addr Cmp 1 Eff/Real MSR[IS]=0 */
+#define DBCR1_IAC1ER_11	0x30000000	/* Instr Addr Cmp 1 Eff/Real MSR[IS]=1 */
+#define DBCR1_IAC2US	0x0C000000	/* Instr Addr Cmp 2 Sup/User   */
+#define DBCR1_IAC2ER	0x03000000	/* Instr Addr Cmp 2 Eff/Real */
+#define DBCR1_IAC2ER_01	0x01000000	/* reserved */
+#define DBCR1_IAC2ER_10	0x02000000	/* Instr Addr Cmp 2 Eff/Real MSR[IS]=0 */
+#define DBCR1_IAC2ER_11	0x03000000	/* Instr Addr Cmp 2 Eff/Real MSR[IS]=1 */
+#define DBCR1_IAC12M	0x00C00000	/* Instr Addr 1-2 range enable */
+#define DBCR1_IAC12M_R	0x00400000	/* Instr Addr 1-2 reserved state */
+#define DBCR1_IAC12M_I	0x00800000	/* Instr Addr 1-2 range inclusive */
+#define DBCR1_IAC12M_X	0x00C00000	/* Instr Addr 1-2 range eXclusive */
+#define DBCR1_IAC12A_T	0x00010000	/* Instr Addr 1-2 range Toggle */
+#define DBCR1_IAC3US	0x0000C000	/* Instr Addr Cmp 3 Sup/User   */
+#define DBCR1_IAC3ER	0x00003000	/* Instr Addr Cmp 3 Eff/Real */
+#define DBCR1_IAC3ER_01	0x00001000	/* reserved */
+#define DBCR1_IAC3ER_10	0x00002000	/* Instr Addr Cmp 3 Eff/Real MSR[IS]=0 */
+#define DBCR1_IAC3ER_11	0x00003000	/* Instr Addr Cmp 3 Eff/Real MSR[IS]=1 */
+#define DBCR1_IAC4US	0x00000C00	/* Instr Addr Cmp 4 Sup/User   */
+#define DBCR1_IAC4ER	0x00000300	/* Instr Addr Cmp 4 Eff/Real */
+#define DBCR1_IAC4ER_01	0x00000100	/* Instr Addr Cmp 4 Eff/Real MSR[IS]=0 */
+#define DBCR1_IAC4ER_10	0x00000200	/* Instr Addr Cmp 4 Eff/Real MSR[IS]=0 */
+#define DBCR1_IAC4ER_11	0x00000300	/* Instr Addr Cmp 4 Eff/Real MSR[IS]=1 */
+#define DBCR1_IAC34M	0x000000C0	/* Instr Addr 3-4 range enable */
+#define DBCR1_IAC34M_R	0x00000040	/* Instr Addr 3-4 reserved state */
+#define DBCR1_IAC34M_I	0x00000080	/* Instr Addr 3-4 range inclusive */
+#define DBCR1_IAC34M_X	0x000000C0	/* Instr Addr 3-4 range eXclusive */
+#define DBCR1_IAC34A_T	0x00000001	/* Instr Addr 3-4 range Toggle */
+
+#define DBCR1_USER_DEBUG	(DBCR1_IAC12M | DBCR1_IAC34M)
+#define DBCR1_BASE_REG_VALUE	(DBCR1_IAC1US | DBCR1_IAC1ER_10 | \
+				 DBCR1_IAC2US | DBCR1_IAC2ER_10 | \
+				 DBCR1_IAC3US | DBCR1_IAC3ER_10 | \
+				 DBCR1_IAC4US | DBCR1_IAC4ER_10)
+
+#define dbcr_iac_range(task)	((task)->thread.dbcr1)
+#define DBCR_IAC12M	DBCR1_IAC12M
+#define DBCR_IAC12M_I	DBCR1_IAC12M_I
+#define DBCR_IAC12M_X	DBCR1_IAC12M_X
+#define DBCR_IAC34M	DBCR1_IAC34M
+#define DBCR_IAC34M_I	DBCR1_IAC34M_I
+#define DBCR_IAC34M_X	DBCR1_IAC34M_X
 
 /* Bit definitions related to the DBCR2. */
-#define DBCR2_DAC12M	0x00800000	/* DAC 1-2 range enable */
-#define DBCR2_DAC12MX	0x00C00000	/* DAC 1-2 range eXclusive */
+#define DBCR2_DAC1US	0xC0000000	/* Data Addr Cmp 1 Sup/User   */
+#define DBCR2_DAC1ER	0x30000000	/* Data Addr Cmp 1 Eff/Real */
+#define DBCR2_DAC2US	0x00000000	/* Data Addr Cmp 2 Sup/User   */
+#define DBCR2_DAC2ER	0x00000000	/* Data Addr Cmp 2 Eff/Real */
+#define DBCR2_DAC12MODE	0x00C00000	/* DAC 1-2 Mode Bits */
+#define DBCR2_DAC12MASK	0x00400000	/* DAC 1-2 Mask mode*/
+#define DBCR2_DAC12R	0x00800000	/* DAC 1-2 range enable */
+#define DBCR2_DAC12RX	0x00C00000	/* DAC 1-2 range eXclusive */
 #define DBCR2_DAC12A	0x00200000	/* DAC 1-2 Asynchronous */
-#endif
+#define DBCR2_DVC1M	0x000C0000	/* Data Value Comp 1 Mode */
+#define DBCR2_DVC1M_SHIFT	18	/* # of bits to shift DBCR2_DVC1M */
+#define DBCR2_DVC2M	0x00030000	/* Data Value Comp 2 Mode */
+#define DBCR2_DVC2M_SHIFT	16	/* # of bits to shift DBCR2_DVC2M */
+#define DBCR2_DVC1BE	0x00000F00	/* Data Value Comp 1 Byte */
+#define DBCR2_DVC1BE_SHIFT	8	/* # of bits to shift DBCR2_DVC1BE */
+#define DBCR2_DVC2BE	0x0000000F	/* Data Value Comp 2 Byte */
+#define DBCR2_DVC2BE_SHIFT	0	/* # of bits to shift DBCR2_DVC2BE */
+
+#define DBCR2_USER_DEBUG	(DBCR2_DAC12MODE | DBCR2_DVC1M | DBCR2_DVC2M | \
+				 DBCR2_DVC1BE | DBCR2_DVC2BE)
+#define DBCR2_BASE_REG_VALUE	(DBCR2_DAC1US | DBCR2_DAC2US)
+
+/*
+ * Are there any active Debug Events represented in the
+ * Debug Control Registers?
+ */
+#define DBCR0_ACTIVE_EVENTS  (DBCR0_ICMP | DBCR0_IAC1 | DBCR0_IAC2 | \
+			      DBCR0_IAC3 | DBCR0_IAC4 | DBCR0_DAC1R | \
+			      DBCR0_DAC1W  | DBCR0_DAC2R | DBCR0_DAC2W)
+#define DBCR1_ACTIVE_EVENTS	0
+
+#define DBCR_ACTIVE_EVENTS(dbcr0, dbcr1)  (((dbcr0) & DBCR0_ACTIVE_EVENTS) || \
+					   ((dbcr1) & DBCR1_ACTIVE_EVENTS))
+#endif /* #elif defined(CONFIG_BOOKE) */
 
 /* Bit definitions related to the TCR. */
 #define TCR_WP(x)	(((x)&0x3)<<30)	/* WDT Period */

-- 
Dave Kleikamp
IBM Linux Technology Center

^ permalink raw reply related

* [RFC:PATCH 01/03] powerpc: Extended ptrace interface
From: Dave Kleikamp @ 2009-12-10 15:57 UTC (permalink / raw)
  To: linuxppc-dev list
  Cc: Sergio Durigan Junior, Thiago Jung Bauermann, Torez Smith,
	David Gibson
In-Reply-To: <20091210155709.6697.4635.sendpatchset@norville.austin.ibm.com>

powerpc: Extended ptrace interface

From: Torez Smith <lnxtorez@linux.vnet.ibm.com>

Add a new extended ptrace interface so that user-space has a single
interface for powerpc, without having to know the specific layout
of the debug registers.

Implement:
PPC_PTRACE_GETHWDEBUGINFO
PPC_PTRACE_SETHWDEBUG
PPC_PTRACE_DELHWDEBUG

Signed-off-by: Dave Kleikamp <shaggy@linux.vnet.ibm.com>
Signed-off-by: Torez Smith  <lnxtorez@linux.vnet.ibm.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Thiago Jung Bauermann <bauerman@br.ibm.com>
Cc: Sergio Durigan Junior <sergiodj@br.ibm.com>
Cc: David Gibson <dwg@au1.ibm.com>
Cc: linuxppc-dev list <Linuxppc-dev@ozlabs.org>
---

 arch/powerpc/include/asm/ptrace.h |   75 ++++++++++++++++++++++++++++++++
 arch/powerpc/kernel/ptrace.c      |   88 +++++++++++++++++++++++++++++++++++++
 2 files changed, 163 insertions(+), 0 deletions(-)


diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h
index 8c34149..7ae887b 100644
--- a/arch/powerpc/include/asm/ptrace.h
+++ b/arch/powerpc/include/asm/ptrace.h
@@ -24,6 +24,12 @@
  * 2 of the License, or (at your option) any later version.
  */
 
+#ifdef __KERNEL__
+#include <linux/types.h>
+#else
+#include <stdint.h>
+#endif
+
 #ifndef __ASSEMBLY__
 
 struct pt_regs {
@@ -292,4 +298,73 @@ extern void user_disable_single_step(struct task_struct *);
 
 #define PTRACE_SINGLEBLOCK	0x100	/* resume execution until next branch */
 
+#define PPC_PTRACE_GETHWDBGINFO	0x89
+#define PPC_PTRACE_SETHWDEBUG	0x88
+#define PPC_PTRACE_DELHWDEBUG	0x87
+
+#ifndef __ASSEMBLY__
+
+struct ppc_debug_info {
+	uint32_t version;		/* Only version 1 exists to date */
+	uint32_t num_instruction_bps;
+	uint32_t num_data_bps;
+	uint32_t num_condition_regs;
+	uint32_t data_bp_alignment;
+	uint32_t sizeof_condition;	/* size of the DVC register */
+	uint64_t features;
+};
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * features will have bits indication whether there is support for:
+ */
+#define PPC_DEBUG_FEATURE_INSN_BP_RANGE		0x1
+#define PPC_DEBUG_FEATURE_INSN_BP_MASK		0x2
+#define PPC_DEBUG_FEATURE_DATA_BP_RANGE		0x4
+#define PPC_DEBUG_FEATURE_DATA_BP_MASK		0x8
+
+#ifndef __ASSEMBLY__
+
+struct ppc_hw_breakpoint {
+	uint32_t version;		/* currently, version must be 1 */
+	uint32_t trigger_type;		/* only some combinations allowed */
+	uint32_t addr_mode;		/* address match mode */
+	uint32_t condition_mode;	/* break/watchpoint condition flags */
+	uint64_t addr;			/* break/watchpoint address */
+	uint64_t addr2;			/* range end or mask */
+	uint64_t condition_value;	/* contents of the DVC register */
+};
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * Trigger Type
+ */
+#define PPC_BREAKPOINT_TRIGGER_EXECUTE	0x1
+#define PPC_BREAKPOINT_TRIGGER_READ	0x2
+#define PPC_BREAKPOINT_TRIGGER_WRITE	0x4
+#define PPC_BREAKPOINT_TRIGGER_RW	0x6
+
+/*
+ * Address Mode
+ */
+#define PPC_BREAKPOINT_MODE_EXACT		0x0
+#define PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE	0x1
+#define PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE	0x2
+#define PPC_BREAKPOINT_MODE_MASK		0x3
+
+/*
+ * Condition Mode
+ */
+#define PPC_BREAKPOINT_CONDITION_NONE	0x0
+#define PPC_BREAKPOINT_CONDITION_AND	0x1
+#define PPC_BREAKPOINT_CONDITION_EXACT	0x1
+#define PPC_BREAKPOINT_CONDITION_OR	0x2
+#define PPC_BREAKPOINT_CONDITION_AND_OR	0x3
+#define PPC_BREAKPOINT_CONDITION_BE_ALL	0x00ff0000
+#define PPC_BREAKPOINT_CONDITION_BE_SHIFT	16
+#define PPC_BREAKPOINT_CONDITION_BE(n)	\
+	(1<<((n)+PPC_BREAKPOINT_CONDITION_BE_SHIFT))
+
 #endif /* _ASM_POWERPC_PTRACE_H */
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index ef14988..6be2ce0 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -839,6 +839,50 @@ void ptrace_disable(struct task_struct *child)
 	user_disable_single_step(child);
 }
 
+static long ppc_set_hwdebug(struct task_struct *child,
+		     struct ppc_hw_breakpoint *bp_info)
+{
+	/*
+	 * We currently support one data breakpoint
+	 */
+	if (((bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_RW) == 0) ||
+	    ((bp_info->trigger_type & ~PPC_BREAKPOINT_TRIGGER_RW) != 0) ||
+	    (bp_info->trigger_type != PPC_BREAKPOINT_TRIGGER_WRITE) ||
+	    (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT) ||
+	    (bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE))
+		return -EINVAL;
+
+	if (child->thread.dabr)
+		return -ENOSPC;
+
+	if ((unsigned long)bp_info->addr >= TASK_SIZE)
+		return -EIO;
+
+	child->thread.dabr = (unsigned long)bp_info->addr;
+#ifdef CONFIG_BOOKE
+	child->thread.dbcr0 = DBCR0_IDM;
+	if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ)
+		child->thread.dbcr0 |= DBSR_DAC1R;
+	if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
+		child->thread.dbcr0 |= DBSR_DAC1W;
+	child->thread.regs->msr |= MSR_DE;
+#endif
+	return 1;
+}
+
+static long ppc_del_hwdebug(struct task_struct *child, long addr, long data)
+{
+	if ((data != 1) || (child->thread.dabr == 0))
+		return -EINVAL;
+
+	child->thread.dabr = 0;
+#ifdef CONFIG_BOOKE
+	child->thread.dbcr0 &= ~(DBSR_DAC1R | DBSR_DAC1W | DBCR0_IDM);
+	child->thread.regs->msr &= ~MSR_DE;
+#endif
+	return 0;
+}
+
 /*
  * Here are the old "legacy" powerpc specific getregs/setregs ptrace calls,
  * we mark them as obsolete now, they will be removed in a future version
@@ -932,6 +976,50 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 		break;
 	}
 
+	case PPC_PTRACE_GETHWDBGINFO: {
+		struct ppc_debug_info dbginfo;
+
+		dbginfo.version = 1;
+		dbginfo.num_instruction_bps = 0;
+		dbginfo.num_data_bps = 1;
+		dbginfo.num_condition_regs = 0;
+#ifdef CONFIG_PPC64
+		dbginfo.data_bp_alignment = 8;
+#else
+		dbginfo.data_bp_alignment = 0;
+#endif
+		dbginfo.sizeof_condition = 0;
+		dbginfo.features = 0;
+
+		if (!access_ok(VERIFY_WRITE, data,
+			       sizeof(struct ppc_debug_info)))
+			return -EFAULT;
+		ret = __copy_to_user((struct ppc_debug_info __user *)data,
+				     &dbginfo, sizeof(struct ppc_debug_info)) ?
+		      -EFAULT : 0;
+		break;
+	}
+
+	case PPC_PTRACE_SETHWDEBUG: {
+		struct ppc_hw_breakpoint bp_info;
+
+		if (!access_ok(VERIFY_READ, data,
+			       sizeof(struct ppc_hw_breakpoint)))
+			return -EFAULT;
+		ret = __copy_from_user(&bp_info,
+				       (struct ppc_hw_breakpoint __user *)data,
+				       sizeof(struct ppc_hw_breakpoint)) ?
+		      -EFAULT : 0;
+		if (!ret)
+			ret = ppc_set_hwdebug(child, &bp_info);
+		break;
+	}
+
+	case PPC_PTRACE_DELHWDEBUG: {
+		ret = ppc_del_hwdebug(child, addr, data);
+		break;
+	}
+
 	case PTRACE_GET_DEBUGREG: {
 		ret = -EINVAL;
 		/* We only support one DABR and no IABRS at the moment */

-- 
Dave Kleikamp
IBM Linux Technology Center

^ permalink raw reply related

* [RFC:PATCH 00/03] powerpc: Expose BookE debug registers through extended ptrace interface
From: Dave Kleikamp @ 2009-12-10 15:57 UTC (permalink / raw)
  To: linuxppc-dev list
  Cc: Sergio Durigan Junior, Torez Smith, David Gibson,
	Thiago Jung Bauermann

These patches implement an extention to the ptrace interface proposed by
Thiago Bauermann and the the PowerPC gdb team.

GDB intends to support the following hardware debug features of BookE
processors:

4 hardware breakpoints (IAC)
2 hardware watchpoints (read, write and read-write) (DAC)
2 value conditions for the hardware watchpoints (DVC)

For that, we need to extend ptrace so that GDB can query and set these
resources. Since we're extending, we're trying to create an interface
that's extendable and that covers both BookE and server processors, so
that GDB doesn't need to special-case each of them. We propose the
following 3 new ptrace requests described below.

There have been discussions of a generic hardware debug interface for the
kernel which would hopefully contemplate all the functionality below and
supersede it.  But we need something that works now, and which enables GDB
to be simpler and work with both Server and Embedded processors without
special cases.

1. PTRACE_PPC_GETHWDEBUGINFO

Query for GDB to discover the hardware debug features. The main info to
be returned here is the minimum alignment for the hardware watchpoints.
BookE processors don't have restrictions here, but server processors have
an 8-byte alignment restriction for hardware watchpoints. We'd like to avoid
adding special cases to GDB based on what it sees in AUXV.

Since we're at it, we added other useful info that the kernel can return to
GDB: this query will return the number of hardware breakpoints, hardware
watchpoints and whether it supports a range of addresses and a condition.
The query will fill the following structure provided by the requesting process:

struct ppc_debug_info {
       unit32_t version;
       unit32_t num_instruction_bps;
       unit32_t num_data_bps;
       unit32_t num_condition_regs;
       unit32_t data_bp_alignment;
       unit32_t sizeof_condition; /* size of the DVC register */
       uint64_t features; /* bitmask of the individual flags */
};

features will have bits indicating whether there is support for:

#define PPC_DEBUG_FEATURE_INSN_BP_RANGE		0x1
#define PPC_DEBUG_FEATURE_INSN_BP_MASK		0x2
#define PPC_DEBUG_FEATURE_DATA_BP_RANGE		0x4
#define PPC_DEBUG_FEATURE_DATA_BP_MASK		0x8

2. PTRACE_SETHWDEBUG

Sets a hardware breakpoint or watchpoint, according to the provided structure:

struct ppc_hw_breakpoint {
        uint32_t version;
#define PPC_BREAKPOINT_TRIGGER_EXECUTE  0x1
#define PPC_BREAKPOINT_TRIGGER_READ     0x2
#define PPC_BREAKPOINT_TRIGGER_WRITE    0x4
        uint32_t trigger_type;       /* only some combinations allowed */
#define PPC_BREAKPOINT_MODE_EXACT               0x0
#define PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE     0x1
#define PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE     0x2
#define PPC_BREAKPOINT_MODE_MASK                0x3
        uint32_t addr_mode;          /* address match mode */

#define PPC_BREAKPOINT_CONDITION_NONE   0x0
#define PPC_BREAKPOINT_CONDITION_AND    0x1
#define PPC_BREAKPOINT_CONDITION_EXACT  0x1	/* different name for the same thing as above */
#define PPC_BREAKPOINT_CONDITION_OR     0x2
#define PPC_BREAKPOINT_CONDITION_AND_OR 0x3
#define PPC_BREAKPOINT_CONDITION_BE_ALL 0x00ff0000	/* byte enable bits */
#define PPC_BREAKPOINT_CONDITION_BE(n)  (1<<((n)+16))
        uint32_t condition_mode;     /* break/watchpoint condition flags */

        uint64_t addr;
        uint64_t addr2;
        uint64_t condition_value;
};

A request specifies one event, not necessarily just one register to be set.
For instance, if the request is for a watchpoint with a condition, both the
DAC and DVC registers will be set in the same request.

With this GDB can ask for all kinds of hardware breakpoints and watchpoints
that the BookE supports. COMEFROM breakpoints available in server processors
are not contemplated, but that is out of the scope of this work.

ptrace will return an integer (handle) uniquely identifying the breakpoint or
watchpoint just created. This integer will be used in the PTRACE_DELHWDEBUG
request to ask for its removal. Return -ENOSPC if the requested breakpoint
can't be allocated on the registers.

Some examples of using the structure to:

- set a breakpoint in the first breakpoint register

  p.version         = PPC_DEBUG_CURRENT_VERSION;
  p.trigger_type    = PPC_BREAKPOINT_TRIGGER_EXECUTE;
  p.addr_mode       = PPC_BREAKPOINT_MODE_EXACT;
  p.condition_mode  = PPC_BREAKPOINT_CONDITION_NONE;
  p.addr            = (uint64_t) address;
  p.addr2           = 0;
  p.condition_value = 0;

- set a watchpoint which triggers on reads in the second watchpoint register

  p.version         = PPC_DEBUG_CURRENT_VERSION;
  p.trigger_type    = PPC_BREAKPOINT_TRIGGER_READ;
  p.addr_mode       = PPC_BREAKPOINT_MODE_EXACT;
  p.condition_mode  = PPC_BREAKPOINT_CONDITION_NONE;
  p.addr            = (uint64_t) address;
  p.addr2           = 0;
  p.condition_value = 0;

- set a watchpoint which triggers only with a specific value

  p.version         = PPC_DEBUG_CURRENT_VERSION;
  p.trigger_type    = PPC_BREAKPOINT_TRIGGER_READ;
  p.addr_mode       = PPC_BREAKPOINT_MODE_EXACT;
  p.condition_mode  = PPC_BREAKPOINT_CONDITION_AND | PPC_BREAKPOINT_CONDITION_BE_ALL;
  p.addr            = (uint64_t) address;
  p.addr2           = 0;
  p.condition_value = (uint64_t) condition;

- set a ranged hardware breakpoint

  p.version         = PPC_DEBUG_CURRENT_VERSION;
  p.trigger_type    = PPC_BREAKPOINT_TRIGGER_EXECUTE;
  p.addr_mode       = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE;
  p.condition_mode  = PPC_BREAKPOINT_CONDITION_NONE;
  p.addr            = (uint64_t) begin_range;
  p.addr2           = (uint64_t) end_range;
  p.condition_value = 0;

3. PTRACE_DELHWDEBUG

Takes an integer which identifies an existing breakpoint or watchpoint
(i.e., the value returned from PTRACE_SETHWDEBUG), and deletes the
corresponding breakpoint or watchpoint..

-- 
Dave Kleikamp
IBM Linux Technology Center

^ permalink raw reply

* Re: [PATCH] [SCSI] mpt fusion: Fix 32 bit platforms with 64 bit resources.
From: James Bottomley @ 2009-12-10 15:43 UTC (permalink / raw)
  To: Pravin Bathija; +Cc: linuxppc-dev, Eric.Moore, linux-scsi
In-Reply-To: <1259805106-23636-1-git-send-email-pbathija@amcc.com>

On Wed, 2009-12-02 at 17:51 -0800, Pravin Bathija wrote:
> Powerpc 44x uses 36 bit real address while the real address defined
>     in MPT Fusion driver is of type 32 bit. This causes ioremap to fail and driver
>     fails to initialize. This fix changes the data types representing the real
>     address from unsigned long 32-bit types to resource_size_t which is 64-bit. The
>     driver has been tested, the disks get discovered correctly and can do IO.
> 
> Signed-off-by: Pravin Bathija <pbathija@amcc.com>
> Acked-by: Feng Kan <fkan@amcc.com>
> Acked-by: Fushen Chen <fchen@amcc.com>
> Acked-by: Loc Ho <lho@amcc.com>
> Acked-by: Tirumala Reddy Marri <tmarri@amcc.com>
> Acked-by: Victor Gallardo <vgallardo@amcc.com>
> ---
>  drivers/message/fusion/mptbase.c |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
> index 5d496a9..9f14a60 100644
> --- a/drivers/message/fusion/mptbase.c
> +++ b/drivers/message/fusion/mptbase.c
> @@ -1511,7 +1511,7 @@ mpt_mapresources(MPT_ADAPTER *ioc)
>  {
>  	u8		__iomem *mem;
>  	int		 ii;
> -	unsigned long	 mem_phys;
> +	resource_size_t	 mem_phys;

You never actually compiled this, did you?

drivers/message/fusion/mptbase.c: In function 'mpt_mapresources':
drivers/message/fusion/mptbase.c:1680: warning: format '%lx' expects type 'long unsigned int', but argument 4 has type 'resource_size_t'

I'll just fold the fix in

James

---

diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 162923f..85bc6a6 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -1677,8 +1677,8 @@ mpt_mapresources(MPT_ADAPTER *ioc)
 		return -EINVAL;
 	}
 	ioc->memmap = mem;
-	dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %lx\n",
-	    ioc->name, mem, mem_phys));
+	dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %llx\n",
+	    ioc->name, mem, (unsigned long long)mem_phys));
 
 	ioc->mem_phys = mem_phys;
 	ioc->chip = (SYSIF_REGS __iomem *)mem;

^ permalink raw reply related

* Re: [PATCH v3] cpm2_pic: Allow correct flow_types for port C interrupts
From: Anton Vorontsov @ 2009-12-10 14:58 UTC (permalink / raw)
  To: Kumar Gala; +Cc: Scott Wood, Linuxppc-dev Development, Mark Ware
In-Reply-To: <9DDC31C7-6AEE-498C-BE18-C286C950BB51@kernel.crashing.org>

On Thu, Dec 10, 2009 at 08:52:01AM -0600, Kumar Gala wrote:
> 
> On Dec 10, 2009, at 5:14 AM, Mark Ware wrote:
> 
> > Port C interrupts can be either falling edge, or either edge.
> > Other external interrupts are either falling edge or active low.
> > Tested on a custom 8280 based board.
> > 
> > Signed-off-by: Mark Ware <mware@elphinstone.net>
> > ---
> > Changed in v3:
> > - Cosmetic improvements as suggested by Anton and Scott
> > - Added tested note to changelog
> > 
> > arch/powerpc/sysdev/cpm2_pic.c |   28 +++++++++++++++++++++-------
> > 1 files changed, 21 insertions(+), 7 deletions(-)
> 
> Scott, Anton do you want to add an Ack to this version?

Acked-by: Anton Vorontsov <avorontsov@ru.mvista.com>

Thanks!

-- 
Anton Vorontsov
email: cbouatmailru@gmail.com
irc://irc.freenode.net/bd2

^ permalink raw reply

* Re: [PATCH v3] cpm2_pic: Allow correct flow_types for port C interrupts
From: Kumar Gala @ 2009-12-10 14:52 UTC (permalink / raw)
  To: Scott Wood, Mark Ware; +Cc: Linuxppc-dev Development, Anton Vorontsov
In-Reply-To: <4B20D81A.7010503@elphinstone.net>


On Dec 10, 2009, at 5:14 AM, Mark Ware wrote:

> Port C interrupts can be either falling edge, or either edge.
> Other external interrupts are either falling edge or active low.
> Tested on a custom 8280 based board.
> 
> Signed-off-by: Mark Ware <mware@elphinstone.net>
> ---
> Changed in v3:
> - Cosmetic improvements as suggested by Anton and Scott
> - Added tested note to changelog
> 
> arch/powerpc/sysdev/cpm2_pic.c |   28 +++++++++++++++++++++-------
> 1 files changed, 21 insertions(+), 7 deletions(-)

Scott, Anton do you want to add an Ack to this version?

- k

^ permalink raw reply

* Re: Ping does not work on my MPC8544 board, using linux2.6.23
From: 林志平 @ 2009-12-10 13:05 UTC (permalink / raw)
  To: Scott Wood; +Cc: linuxppc-dev
In-Reply-To: <4B2001A3.9010002@freescale.com>

[-- Attachment #1: Type: text/plain, Size: 1719 bytes --]

2009/12/10 Scott Wood <scottwood@freescale.com>

>  林志平 wrote:
>
>>     > Another question is that I found linux2.6.31 does not support
>>     > board mpc8544ds,
>>
>>    It should.  What problems do you see?
>>
>> => bootm 0x1000000 0x1800000 0x800000
>> ## Booting kernel from Legacy Image at 01000000 ...
>>   Image Name:   Linux-2.6.31
>>   Image Type:   PowerPC Linux Kernel Image (gzip compressed)
>>   Data Size:    2185099 Bytes =  2.1 MB
>>   Load Address: 00000000
>>   Entry Point:  00000000
>>   Verifying Checksum ... OK
>> ## Loading init Ramdisk from Legacy Image at 01800000 ...
>>   Image Name:   Simple Embedded Linux Framework
>>   Image Type:   PowerPC Linux RAMDisk Image (gzip compressed)
>>   Data Size:    1859256 Bytes =  1.8 MB
>>   Load Address: 00000000
>>   Entry Point:  00000000
>>   Verifying Checksum ... OK
>> ## Flattened Device Tree blob at 00800000
>>   Booting using the fdt blob at 0x800000
>>   Uncompressing Kernel Image ... OK
>>   Loading Ramdisk to 1fca7000, end 1fe6ceb8 ... OK
>> booting kernel using flat tree
>> It then stops and never print any more,  I use mpc85xx_defconfig, I select
>> mpc85xxds in the menuconfig and deselect other options like mpc8540ads etc.
>>
>
> Are you using the mpc8544ds device tree from 2.6.31, unchanged?  Try
> turning on CONFIG_PPC_EARLY_DEBUG.
>
> No need to deselect the others, BTW.


>    Does mpc85xx_defconfig not work?
>>
>> Yes mcp85xx_defconfig does not work, I can see mpc8540ads in the
>> menuconfig, but no mpc8544ds.
>>
>
> mpc8544ds is supported by CONFIG_MPC85xx_DS.
> CONFIG_MPC85XX_DS does not exist. Only mpc85xx_defconfig in
> arch/powerpc/configs



> -Scott
>

[-- Attachment #2: Type: text/html, Size: 2750 bytes --]

^ permalink raw reply

* [ibm_emac] rx_dropped_stack
From: Bross Stephan (LWE) @ 2009-12-10 12:36 UTC (permalink / raw)
  To: linuxppc-dev

Hi all,

I am using linux version 2.6.25.20 on
cpu             : 440GRX
revision        : 24.212 (pvr 2162 18d4)
bogomips        : 995.32
vendor          : AMCC
machine         : PPC440EPx LWMON5

I am using ethtool to read out NIC statistics. On every tested board I =
saw the counter increasing for 'rx_dropped_stack', on some boards also =
for 'rx_bd_errors', 'rx_bd_bad_fcs' and on few boards for 'tx_underrun' =
or 'tx_dropped'. Can you help me interpret those values? Which values =
are nice for information, which are really bad?

thanks in advance,
Stephan

Liebherr-Werk Ehingen GmbH
Dr.-Hans-Liebherr-Str. 1
89584 Ehingen
E-Mail:		Stephan.Bross@liebherr.com
Internet:	http://www.liebherr.com


Vorsitzender des Aufsichtsrats: Dipl.-Volksw. Henning Rapp
Gesch=E4ftsf=FChrer: Dr.-Ing. Ulrich Hamme, Dr.-Ing. Hubert Hummel, =
Dipl.-Ing. (FH) Christoph Kleiner, Dipl.-Kfm. Mario Trunzer
Sitz: 89584 Ehingen/Donau, Amtsgericht Ulm/Donau, HRB 490123, Ust-Id. =
Nr.: DE 811120093
LIEBHERRB2B4EM@IL

^ permalink raw reply

* [PATCH 2/2] pseries: Make declarations of cpu_hotplug_driver_lock() ANSI compatible.
From: Gautham R Shenoy @ 2009-12-10 11:19 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Benjamin Herrenschmidt
In-Reply-To: <20091210111937.18281.5146.stgit@sofia.in.ibm.com>

And add the __acquires() and __releases() annotations, while at it.

Signed-off-by: Gautham R Shenoy <ego@in.ibm.com>
---
 arch/powerpc/platforms/pseries/dlpar.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c
index 12df9e8..67b7a10 100644
--- a/arch/powerpc/platforms/pseries/dlpar.c
+++ b/arch/powerpc/platforms/pseries/dlpar.c
@@ -346,12 +346,14 @@ int dlpar_release_drc(u32 drc_index)
 
 static DEFINE_MUTEX(pseries_cpu_hotplug_mutex);
 
-void cpu_hotplug_driver_lock()
+void cpu_hotplug_driver_lock(void)
+__acquires(pseries_cpu_hotplug_mutex)
 {
 	mutex_lock(&pseries_cpu_hotplug_mutex);
 }
 
-void cpu_hotplug_driver_unlock()
+void cpu_hotplug_driver_unlock(void)
+__releases(pseries_cpu_hotplug_mutex)
 {
 	mutex_unlock(&pseries_cpu_hotplug_mutex);
 }

^ permalink raw reply related

* [PATCH 1/2] pseries: Don't panic when H_PROD fails during cpu-online.
From: Gautham R Shenoy @ 2009-12-10 11:19 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Benjamin Herrenschmidt

If an online-attempt on a CPU which has been offlined using H_CEDE
with an appropriate cede latency hint fails, don't panic.

Instead print the error message and let the __cpu_up() code notify the
CPU Hotplug framework of the failure, which in turn can notify the
other subsystem through CPU_UP_CANCELED.

Signed-off-by: Gautham R Shenoy <ego@in.ibm.com>
---
 arch/powerpc/platforms/pseries/smp.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c
index 8868c01..b488663 100644
--- a/arch/powerpc/platforms/pseries/smp.c
+++ b/arch/powerpc/platforms/pseries/smp.c
@@ -144,8 +144,8 @@ static void __devinit smp_pSeries_kick_cpu(int nr)
 		hcpuid = get_hard_smp_processor_id(nr);
 		rc = plpar_hcall_norets(H_PROD, hcpuid);
 		if (rc != H_SUCCESS)
-			panic("Error: Prod to wake up processor %d Ret= %ld\n",
-				nr, rc);
+			printk(KERN_ERR "Error: Prod to wake up processor %d\
+						Ret= %ld\n", nr, rc);
 	}
 }
 

^ permalink raw reply related

* [PATCH v3] cpm2_pic: Allow correct flow_types for port C interrupts
From: Mark Ware @ 2009-12-10 11:14 UTC (permalink / raw)
  To: Linuxppc-dev Development; +Cc: Scott Wood, avorontsov

Port C interrupts can be either falling edge, or either edge.
Other external interrupts are either falling edge or active low.
Tested on a custom 8280 based board.

Signed-off-by: Mark Ware <mware@elphinstone.net>
---
Changed in v3:
- Cosmetic improvements as suggested by Anton and Scott
- Added tested note to changelog

 arch/powerpc/sysdev/cpm2_pic.c |   28 +++++++++++++++++++++-------
 1 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c
index 78f1f7c..b1e9206 100644
--- a/arch/powerpc/sysdev/cpm2_pic.c
+++ b/arch/powerpc/sysdev/cpm2_pic.c
@@ -141,13 +141,23 @@ static int cpm2_set_irq_type(unsigned int virq, unsigned int flow_type)
 	struct irq_desc *desc = get_irq_desc(virq);
 	unsigned int vold, vnew, edibit;
 
-	if (flow_type == IRQ_TYPE_NONE)
-		flow_type = IRQ_TYPE_LEVEL_LOW;
-
-	if (flow_type & IRQ_TYPE_EDGE_RISING) {
-		printk(KERN_ERR "CPM2 PIC: sense type 0x%x not supported\n",
-			flow_type);
-		return -EINVAL;
+	/* Port C interrupts are either IRQ_TYPE_EDGE_FALLING or
+	 * IRQ_TYPE_EDGE_BOTH (default).  All others are IRQ_TYPE_EDGE_FALLING
+	 * or IRQ_TYPE_LEVEL_LOW (default)
+	 */
+	if (src >= CPM2_IRQ_PORTC15 && src <= CPM2_IRQ_PORTC0) {
+		if (flow_type == IRQ_TYPE_NONE)
+			flow_type = IRQ_TYPE_EDGE_BOTH;
+
+		if (flow_type != IRQ_TYPE_EDGE_BOTH &&
+		    flow_type != IRQ_TYPE_EDGE_FALLING)
+			goto err_sense;
+	} else {
+		if (flow_type == IRQ_TYPE_NONE)
+			flow_type = IRQ_TYPE_LEVEL_LOW;
+
+		if (flow_type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_LEVEL_HIGH))
+			goto err_sense;
 	}
 
 	desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
@@ -179,6 +189,10 @@ static int cpm2_set_irq_type(unsigned int virq, unsigned int flow_type)
 	if (vold != vnew)
 		out_be32(&cpm2_intctl->ic_siexr, vnew);
 	return 0;
+
+err_sense:
+	pr_err("CPM2 PIC: sense type 0x%x not supported\n", flow_type);
+	return -EINVAL;
 }
 
 static struct irq_chip cpm2_pic = {
-- 
1.5.6.5

^ permalink raw reply related

* Re: [PATCH v2] cpm2_pic: Allow correct flow_types for port C interrupts
From: Mark Ware @ 2009-12-10 11:10 UTC (permalink / raw)
  To: Scott Wood; +Cc: Linuxppc-dev Development, avorontsov
In-Reply-To: <4B201D67.4070802@freescale.com>

Scott Wood wrote:
> Anton Vorontsov wrote:
>>> +        if ((flow_type != IRQ_TYPE_EDGE_BOTH) && +           
>>> (flow_type != IRQ_TYPE_EDGE_FALLING)) {
>>
>> I'd place one more tab here.
> 
> Or better, align one "flow_type" with the other.
> 
> -Scott
> 

Thanks Anton and Scott.

Scott's suggestion is also my preferred style, but a (brief) search through the source didn't reveal much support.

I'll send a new version shortly including you suggestions.

- Mark

^ permalink raw reply

* Re: MPC5200B XLB Configuration Issues, FEC RFIFO Events, ATA Crashes
From: Roman Fietze @ 2009-12-10  6:09 UTC (permalink / raw)
  To: Wolfram Sang; +Cc: linuxppc-dev
In-Reply-To: <20091209145748.GB3112@pengutronix.de>

Hello Wolfram,

On Wednesday 09 December 2009 15:57:48 Wolfram Sang wrote:

> Do you have a way to measure performance penalties?

Yes, I do. I am using an SCLPC test driver derived from a driver
written or posted by Grant Likely named mpc5200-localplus-test. This
gives me some useful output about the SCLPC BestComm FIFO read
throughput.

Additional to that I'm running I relatively dumb ATA stress test
writing large files to an ext3 that gives me the data rate, as well as
an NFS mount where I read data from.

I will now run all three tests in a few combinations, those that do
not crash my system with the old setup, adding NFS writes and ATA
reads.

I will post the numbers here as soon as I'm done, please give me 2 or
3 days, and as soon as I have the confidence they reflect the reality
at least somewhat.

> I know that stability comes before performance, still I am wondering
> as it looks to me that the most interesting features are simply
> switched off.

We are seeing the same problem in our device, but having a return rate
of almost 100% due to corrupt file systems that can not be repaired in
the field is no alternative.

But, something that never happened before, the system is now running
SCLPC read, ATA write and NFS read for more that 20 hours without any
crash. That's an argument.

Probably the XLB setup has to be done in the U-Boot anyway, and here
the configuration can be flexible enough to enable those positive
features on boards that use only component that do not conflict. The
only thing left is the the cache coherency switch in the kernel
config.


Roman

=2D-=20
Roman Fietze                Telemotive AG B=FCro M=FChlhausen
Breitwiesen                              73347 M=FChlhausen
Tel.: +49(0)7335/18493-45        http://www.telemotive.de

^ permalink raw reply

* Re: [PATCH] cardbus: Add a fixup hook and fix powerpc
From: Benjamin Herrenschmidt @ 2009-12-10  3:53 UTC (permalink / raw)
  To: Dominik Brodowski
  Cc: linux-pci, linux-kernel@vger.kernel.org, Jesse Barnes, blofeldus,
	Olof Johansson, linuxppc-dev
In-Reply-To: <20091209213736.GA25968@comet.dominikbrodowski.net>

On Wed, 2009-12-09 at 22:37 +0100, Dominik Brodowski wrote:
> Acked-by: Dominik Brodowski <linux@dominikbrodowski.net> (for PCMCIA)
> 
> > Note: In the long run we might want to streamline the hooks for fixing
> > up new devices vs. new busses and make some stuff common between cardbus
> > and PCI hotplug which is actually a mess.
> 
> ... though I'd prefer such a generic approach. 

Thanks. Yes that would be better. I don't have the bandwidth right now
to look at that though, maybe early next year.

Cheers,
Ben.

^ permalink raw reply

* [PATCH] of: merge of_find_node_by_phandle
From: Jeremy Kerr @ 2009-12-10  2:47 UTC (permalink / raw)
  To: devicetree-discuss; +Cc: sparclinux, microblaze-uclinux, linuxppc-dev

Merge common function between powerpc, sparc and microblaze. Code is
identical for powerpc and microblaze, but adds a lock (and release) of
the devtree_lock on sparc.

Currently untested.

Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>

---
v2: update iterator, fix subject, post to arch lists

---
 arch/microblaze/kernel/prom.c   |   21 ---------------------
 arch/powerpc/kernel/prom.c      |   21 ---------------------
 arch/sparc/kernel/prom_common.c |   12 ------------
 drivers/of/base.c               |   21 +++++++++++++++++++++
 4 files changed, 21 insertions(+), 54 deletions(-)

diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c
index 9b4a20b..3fac1e2 100644
--- a/arch/microblaze/kernel/prom.c
+++ b/arch/microblaze/kernel/prom.c
@@ -238,27 +238,6 @@ void __init early_init_devtree_arch(void)
  *
  *******/
 
-/**
- *	of_find_node_by_phandle - Find a node given a phandle
- *	@handle:	phandle of the node to find
- *
- *	Returns a node pointer with refcount incremented, use
- *	of_node_put() on it when done.
- */
-struct device_node *of_find_node_by_phandle(phandle handle)
-{
-	struct device_node *np;
-
-	read_lock(&devtree_lock);
-	for (np = allnodes; np != NULL; np = np->allnext)
-		if (np->phandle == handle)
-			break;
-	of_node_get(np);
-	read_unlock(&devtree_lock);
-	return np;
-}
-EXPORT_SYMBOL(of_find_node_by_phandle);
-
 #if defined(CONFIG_DEBUG_FS) && defined(DEBUG)
 static struct debugfs_blob_wrapper flat_dt_blob;
 
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index d3ce311..83161d0 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -689,27 +689,6 @@ void __init early_init_devtree_arch(void)
  *******/
 
 /**
- *	of_find_node_by_phandle - Find a node given a phandle
- *	@handle:	phandle of the node to find
- *
- *	Returns a node pointer with refcount incremented, use
- *	of_node_put() on it when done.
- */
-struct device_node *of_find_node_by_phandle(phandle handle)
-{
-	struct device_node *np;
-
-	read_lock(&devtree_lock);
-	for (np = allnodes; np != 0; np = np->allnext)
-		if (np->phandle == handle)
-			break;
-	of_node_get(np);
-	read_unlock(&devtree_lock);
-	return np;
-}
-EXPORT_SYMBOL(of_find_node_by_phandle);
-
-/**
  *	of_find_next_cache_node - Find a node's subsidiary cache
  *	@np:	node of type "cpu" or "cache"
  *
diff --git a/arch/sparc/kernel/prom_common.c b/arch/sparc/kernel/prom_common.c
index 5832e13..57ac9e2 100644
--- a/arch/sparc/kernel/prom_common.c
+++ b/arch/sparc/kernel/prom_common.c
@@ -37,18 +37,6 @@ EXPORT_SYMBOL(of_console_path);
 char *of_console_options;
 EXPORT_SYMBOL(of_console_options);
 
-struct device_node *of_find_node_by_phandle(phandle handle)
-{
-	struct device_node *np;
-
-	for (np = allnodes; np; np = np->allnext)
-		if (np->phandle == handle)
-			break;
-
-	return np;
-}
-EXPORT_SYMBOL(of_find_node_by_phandle);
-
 int of_getintprop_default(struct device_node *np, const char *name, int def)
 {
 	struct property *prop;
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 9212b87..7432011 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -672,6 +672,27 @@ int of_modalias_node(struct device_node *node, char *modalias, int len)
 EXPORT_SYMBOL_GPL(of_modalias_node);
 
 /**
+ * of_find_node_by_phandle - Find a node given a phandle
+ * @handle:	phandle of the node to find
+ *
+ * Returns a node pointer with refcount incremented, use
+ * of_node_put() on it when done.
+ */
+struct device_node *of_find_node_by_phandle(phandle handle)
+{
+	struct device_node *np;
+
+	read_lock(&devtree_lock);
+	for (np = allnodes; np; np = np->allnext)
+		if (np->phandle == handle)
+			break;
+	of_node_get(np);
+	read_unlock(&devtree_lock);
+	return np;
+}
+EXPORT_SYMBOL(of_find_node_by_phandle);
+
+/**
  * of_parse_phandle - Resolve a phandle property to a device_node pointer
  * @np: Pointer to device node holding phandle property
  * @phandle_name: Name of property holding a phandle value

^ permalink raw reply related

* RE: [PATCH] Adding PCI-E support for 460SX based redwood board.
From: Tirumala Reddy Marri @ 2009-12-10  2:22 UTC (permalink / raw)
  To: tmarr, benh; +Cc: linuxppc-dev
In-Reply-To: <1259615732-20272-1-git-send-email-tmarr@amcc.com>


Testing  and other information for this patch.

1. Kernel version: 2.6.32-rc6=20
2. Board:  AMCC redwood validation board.
3. tests
   a. Configured redwood boards PCI-E ports as root ports. And plugged
in 2 HBA sas cards with 8 drives each. XDD and IO  =20
      meter tests were ran. No issues found.
   b. Configured redwood board PCI-E port as Endpoint and configured
second board as root complex.  Boards were interconnected using PCI-E
cable. Then did lspci on root complex configured redwood board to see if
the endpoint can be scanned. Also using BDI I was able to do read and
writes to & from root complex as well as endpoint.


Regards,
Marri

-----Original Message-----
From: tmarr@amcc.com [mailto:tmarr@amcc.com]=20
Sent: Monday, November 30, 2009 1:16 PM
To: benh@kernel.crashing.org
Cc: linuxppc-dev@ozlabs.org; Tirumala Reddy Marri
Subject: [PATCH] Adding PCI-E support for 460SX based redwood board.

From: Tirumala Marri <tmarri@amcc.com>

This patch would add PCI-E support for AMCC 460SX processor based=20
redwood board.

Signed-off-by: Tirumala Marri <tmarri@amcc.com>

---
 arch/powerpc/boot/dts/redwood.dts |  122
+++++++++++++++++++++++++++++++++++++
 arch/powerpc/sysdev/ppc4xx_pci.c  |  119
++++++++++++++++++++++++++++++++++++
 arch/powerpc/sysdev/ppc4xx_pci.h  |   58 +++++++++++++++++
 3 files changed, 299 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/boot/dts/redwood.dts
b/arch/powerpc/boot/dts/redwood.dts
index ad402c4..9eeec28 100644
--- a/arch/powerpc/boot/dts/redwood.dts
+++ b/arch/powerpc/boot/dts/redwood.dts
@@ -233,6 +233,128 @@
 				has-inverted-stacr-oc;
 				has-new-stacr-staopc;
 			};
+			PCIE0: pciex@d00000000 {
+				device_type =3D "pci";
+				#interrupt-cells =3D <1>;
+				#size-cells =3D <2>;
+				#address-cells =3D <3>;
+				compatible =3D "ibm,plb-pciex-460sx",
"ibm,plb-pciex";
+				primary;
+				port =3D <0x0>; /* port number */
+				reg =3D <0x0000000d 0x00000000 0x20000000
/* Config space access */
+				       0x0000000c 0x10000000
0x00001000>;	/* Registers */
+				dcr-reg =3D <0x100 0x020>;
+				sdr-base =3D <0x300>;
+
+				/* Outbound ranges, one memory and one
IO,
+				 * later cannot be changed
+				 */
+				ranges =3D <0x02000000 0x00000000
0x80000000 0x0000000e 0x00000000 0x00000000 0x80000000
+					  0x01000000 0x00000000
0x00000000 0x0000000f 0x80000000 0x00000000 0x00010000>;
+
+				/* Inbound 2GB range starting at 0 */
+				dma-ranges =3D <0x42000000 0x0 0x0 0x0 0x0
0x0 0x80000000>;
+
+				/* This drives busses 10 to 0x1f */
+				bus-range =3D <0x10 0x1f>;
+
+				/* Legacy interrupts (note the weird
polarity, the bridge seems
+				 * to invert PCIe legacy interrupts).
+				 * We are de-swizzling here because the
numbers are actually for
+				 * port of the root complex virtual P2P
bridge. But I want
+				 * to avoid putting a node for it in the
tree, so the numbers
+				 * below are basically de-swizzled
numbers.
+				 * The real slot is on idsel 0, so the
swizzling is 1:1
+				 */
+				interrupt-map-mask =3D <0x0 0x0 0x0 0x7>;
+				interrupt-map =3D <
+					0x0 0x0 0x0 0x1 &UIC3 0x0 0x4 /*
swizzled int A */
+					0x0 0x0 0x0 0x2 &UIC3 0x1 0x4 /*
swizzled int B */
+					0x0 0x0 0x0 0x3 &UIC3 0x2 0x4 /*
swizzled int C */
+					0x0 0x0 0x0 0x4 &UIC3 0x3 0x4 /*
swizzled int D */>;
+			};
+
+			PCIE1: pciex@d20000000 {
+				device_type =3D "pci";
+				#interrupt-cells =3D <1>;
+				#size-cells =3D <2>;
+				#address-cells =3D <3>;
+				compatible =3D "ibm,plb-pciex-460sx",
"ibm,plb-pciex";
+				primary;
+				port =3D <0x1>; /* port number */
+				reg =3D <0x0000000d 0x20000000 0x20000000
/* Config space access */
+				       0x0000000c 0x10001000
0x00001000>;	/* Registers */
+				dcr-reg =3D <0x120 0x020>;
+				sdr-base =3D <0x340>;
+
+				/* Outbound ranges, one memory and one
IO,
+				 * later cannot be changed
+				 */
+				ranges =3D <0x02000000 0x00000000
0x80000000 0x0000000e 0x80000000 0x00000000 0x80000000
+					  0x01000000 0x00000000
0x00000000 0x0000000f 0x80010000 0x00000000 0x00010000>;
+
+				/* Inbound 2GB range starting at 0 */
+				dma-ranges =3D <0x42000000 0x0 0x0 0x0 0x0
0x0 0x80000000>;
+
+				/* This drives busses 10 to 0x1f */
+				bus-range =3D <0x20 0x2f>;
+
+				/* Legacy interrupts (note the weird
polarity, the bridge seems
+				 * to invert PCIe legacy interrupts).
+				 * We are de-swizzling here because the
numbers are actually for
+				 * port of the root complex virtual P2P
bridge. But I want
+				 * to avoid putting a node for it in the
tree, so the numbers
+				 * below are basically de-swizzled
numbers.
+				 * The real slot is on idsel 0, so the
swizzling is 1:1
+				 */
+				interrupt-map-mask =3D <0x0 0x0 0x0 0x7>;
+				interrupt-map =3D <
+					0x0 0x0 0x0 0x1 &UIC3 0x4 0x4 /*
swizzled int A */
+					0x0 0x0 0x0 0x2 &UIC3 0x5 0x4 /*
swizzled int B */
+					0x0 0x0 0x0 0x3 &UIC3 0x6 0x4 /*
swizzled int C */
+					0x0 0x0 0x0 0x4 &UIC3 0x7 0x4 /*
swizzled int D */>;
+			};
+
+			PCIE2: pciex@d40000000 {
+				device_type =3D "pci";
+				#interrupt-cells =3D <1>;
+				#size-cells =3D <2>;
+				#address-cells =3D <3>;
+				compatible =3D "ibm,plb-pciex-460sx",
"ibm,plb-pciex";
+				primary;
+				port =3D <0x2>; /* port number */
+				reg =3D <0x0000000d 0x40000000 0x20000000
/* Config space access */
+				       0x0000000c 0x10002000
0x00001000>;	/* Registers */
+				dcr-reg =3D <0x140 0x020>;
+				sdr-base =3D <0x370>;
+
+				/* Outbound ranges, one memory and one
IO,
+				 * later cannot be changed
+				 */
+				ranges =3D <0x02000000 0x00000000
0x80000000 0x0000000f 0x00000000 0x00000000 0x80000000
+					  0x01000000 0x00000000
0x00000000 0x0000000f 0x80020000 0x00000000 0x00010000>;
+
+				/* Inbound 2GB range starting at 0 */
+				dma-ranges =3D <0x42000000 0x0 0x0 0x0 0x0
0x0 0x80000000>;
+
+				/* This drives busses 10 to 0x1f */
+				bus-range =3D <0x30 0x3f>;
+
+				/* Legacy interrupts (note the weird
polarity, the bridge seems
+				 * to invert PCIe legacy interrupts).
+				 * We are de-swizzling here because the
numbers are actually for
+				 * port of the root complex virtual P2P
bridge. But I want
+				 * to avoid putting a node for it in the
tree, so the numbers
+				 * below are basically de-swizzled
numbers.
+				 * The real slot is on idsel 0, so the
swizzling is 1:1
+				 */
+				interrupt-map-mask =3D <0x0 0x0 0x0 0x7>;
+				interrupt-map =3D <
+					0x0 0x0 0x0 0x1 &UIC3 0x8 0x4 /*
swizzled int A */
+					0x0 0x0 0x0 0x2 &UIC3 0x9 0x4 /*
swizzled int B */
+					0x0 0x0 0x0 0x3 &UIC3 0xa 0x4 /*
swizzled int C */
+					0x0 0x0 0x0 0x4 &UIC3 0xb 0x4 /*
swizzled int D */>;
+			};
=20
 		};
=20
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c
b/arch/powerpc/sysdev/ppc4xx_pci.c
index 6ff9d71..64cd020 100644
--- a/arch/powerpc/sysdev/ppc4xx_pci.c
+++ b/arch/powerpc/sysdev/ppc4xx_pci.c
@@ -972,6 +972,123 @@ static struct ppc4xx_pciex_hwops
ppc460ex_pcie_hwops __initdata =3D
 	.setup_utl	=3D ppc460ex_pciex_init_utl,
 };
=20
+static int __init ppc460sx_pciex_core_init(struct device_node *np)
+{
+	/* HSS drive amplitude */
+	mtdcri(SDR0, PESDR0_460SX_HSSL0DAMP, 0xB9843211);
+	mtdcri(SDR0, PESDR0_460SX_HSSL1DAMP, 0xB9843211);
+	mtdcri(SDR0, PESDR0_460SX_HSSL2DAMP, 0xB9843211);
+	mtdcri(SDR0, PESDR0_460SX_HSSL3DAMP, 0xB9843211);
+	mtdcri(SDR0, PESDR0_460SX_HSSL4DAMP, 0xB9843211);
+	mtdcri(SDR0, PESDR0_460SX_HSSL5DAMP, 0xB9843211);
+	mtdcri(SDR0, PESDR0_460SX_HSSL6DAMP, 0xB9843211);
+	mtdcri(SDR0, PESDR0_460SX_HSSL7DAMP, 0xB9843211);
+
+	mtdcri(SDR0, PESDR1_460SX_HSSL0DAMP, 0xB9843211);
+	mtdcri(SDR0, PESDR1_460SX_HSSL1DAMP, 0xB9843211);
+	mtdcri(SDR0, PESDR1_460SX_HSSL2DAMP, 0xB9843211);
+	mtdcri(SDR0, PESDR1_460SX_HSSL3DAMP, 0xB9843211);
+
+	mtdcri(SDR0, PESDR2_460SX_HSSL0DAMP, 0xB9843211);
+	mtdcri(SDR0, PESDR2_460SX_HSSL1DAMP, 0xB9843211);
+	mtdcri(SDR0, PESDR2_460SX_HSSL2DAMP, 0xB9843211);
+	mtdcri(SDR0, PESDR2_460SX_HSSL3DAMP, 0xB9843211);
+
+	/* HSS TX pre-emphasis */
+	mtdcri(SDR0, PESDR0_460SX_HSSL0COEFA, 0xDCB98987);
+	mtdcri(SDR0, PESDR0_460SX_HSSL1COEFA, 0xDCB98987);
+	mtdcri(SDR0, PESDR0_460SX_HSSL2COEFA, 0xDCB98987);
+	mtdcri(SDR0, PESDR0_460SX_HSSL3COEFA, 0xDCB98987);
+	mtdcri(SDR0, PESDR0_460SX_HSSL4COEFA, 0xDCB98987);
+	mtdcri(SDR0, PESDR0_460SX_HSSL5COEFA, 0xDCB98987);
+	mtdcri(SDR0, PESDR0_460SX_HSSL6COEFA, 0xDCB98987);
+	mtdcri(SDR0, PESDR0_460SX_HSSL7COEFA, 0xDCB98987);
+
+	mtdcri(SDR0, PESDR1_460SX_HSSL0COEFA, 0xDCB98987);
+	mtdcri(SDR0, PESDR1_460SX_HSSL1COEFA, 0xDCB98987);
+	mtdcri(SDR0, PESDR1_460SX_HSSL2COEFA, 0xDCB98987);
+	mtdcri(SDR0, PESDR1_460SX_HSSL3COEFA, 0xDCB98987);
+
+	mtdcri(SDR0, PESDR2_460SX_HSSL0COEFA, 0xDCB98987);
+	mtdcri(SDR0, PESDR2_460SX_HSSL1COEFA, 0xDCB98987);
+	mtdcri(SDR0, PESDR2_460SX_HSSL2COEFA, 0xDCB98987);
+	mtdcri(SDR0, PESDR2_460SX_HSSL3COEFA, 0xDCB98987);
+
+	/* HSS TX calibration control */
+	mtdcri(SDR0, PESDR0_460SX_HSSL1CALDRV, 0x22222222);
+	mtdcri(SDR0, PESDR1_460SX_HSSL1CALDRV, 0x22220000);
+	mtdcri(SDR0, PESDR2_460SX_HSSL1CALDRV, 0x22220000);
+
+	/* HSS TX slew control */
+	mtdcri(SDR0, PESDR0_460SX_HSSSLEW, 0xFFFFFFFF);
+	mtdcri(SDR0, PESDR1_460SX_HSSSLEW, 0xFFFF0000);
+	mtdcri(SDR0, PESDR2_460SX_HSSSLEW, 0xFFFF0000);
+
+	udelay(100);
+
+	/* De-assert PLLRESET */
+	dcri_clrset(SDR0, PESDR0_PLLLCT2, 0x00000100, 0);
+
+	/* Reset DL, UTL, GPL before configuration */
+	mtdcri(SDR0, PESDR0_460SX_RCSSET,
+			PESDRx_RCSSET_RSTDL | PESDRx_RCSSET_RSTGU);
+	mtdcri(SDR0, PESDR1_460SX_RCSSET,
+			PESDRx_RCSSET_RSTDL | PESDRx_RCSSET_RSTGU);
+	mtdcri(SDR0, PESDR2_460SX_RCSSET,
+			PESDRx_RCSSET_RSTDL | PESDRx_RCSSET_RSTGU);
+
+	udelay(100);
+
+	/*
+	 * If bifurcation is not enabled, u-boot would have disabled the
+	 * third PCIe port
+	 */
+	if (((mfdcri(SDR0, PESDR1_460SX_HSSCTLSET) & 0x00000001) =3D=3D
+				0x00000001)) {
+		printk(KERN_INFO "PCI: PCIE bifurcation setup
successfully.\n");
+		printk(KERN_INFO "PCI: Total 3 PCIE ports are
present\n");
+		return 3;
+	}
+
+	printk(KERN_INFO "PCI: Total 2 PCIE ports are present\n");
+	return 2;
+}
+
+static int ppc460sx_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
+{
+
+	if (port->endpoint)
+		dcri_clrset(SDR0, port->sdr_base + PESDRn_UTLSET2,
+				0x01000000, 0);
+	else
+		dcri_clrset(SDR0, port->sdr_base + PESDRn_UTLSET2,
+				0, 0x01000000);
+
+	/*Gen-1*/
+	mtdcri(SDR0, port->sdr_base + PESDRn_460SX_RCEI, 0x08000000);
+
+	dcri_clrset(SDR0, port->sdr_base + PESDRn_RCSSET,
+			(PESDRx_RCSSET_RSTGU | PESDRx_RCSSET_RSTDL),
+			PESDRx_RCSSET_RSTPYN);
+
+	port->has_ibpre =3D 1;
+
+	return 0;
+}
+
+static int ppc460sx_pciex_init_utl(struct ppc4xx_pciex_port *port)
+{
+	/* Max 128 Bytes */
+	out_be32 (port->utl_base + PEUTL_PBBSZ,   0x00000000);
+	return 0;
+}
+
+static struct ppc4xx_pciex_hwops ppc460sx_pcie_hwops __initdata =3D {
+	.core_init	=3D ppc460sx_pciex_core_init,
+	.port_init_hw	=3D ppc460sx_pciex_init_port_hw,
+	.setup_utl	=3D ppc460sx_pciex_init_utl,
+};
+
 #endif /* CONFIG_44x */
=20
 #ifdef CONFIG_40x
@@ -1087,6 +1204,8 @@ static int __init
ppc4xx_pciex_check_core_init(struct device_node *np)
 	}
 	if (of_device_is_compatible(np, "ibm,plb-pciex-460ex"))
 		ppc4xx_pciex_hwops =3D &ppc460ex_pcie_hwops;
+	if (of_device_is_compatible(np, "ibm,plb-pciex-460sx"))
+		ppc4xx_pciex_hwops =3D &ppc460sx_pcie_hwops;
 #endif /* CONFIG_44x    */
 #ifdef CONFIG_40x
 	if (of_device_is_compatible(np, "ibm,plb-pciex-405ex"))
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.h
b/arch/powerpc/sysdev/ppc4xx_pci.h
index d04e40b..56d9e5d 100644
--- a/arch/powerpc/sysdev/ppc4xx_pci.h
+++ b/arch/powerpc/sysdev/ppc4xx_pci.h
@@ -324,6 +324,64 @@
 #define PESDR0_460EX_IHS2		0x036D
=20
 /*
+ * 460SX addtional DCRs
+ */
+#define PESDRn_460SX_RCEI		0x02
+
+#define PESDR0_460SX_HSSL0DAMP		0x320
+#define PESDR0_460SX_HSSL1DAMP		0x321
+#define PESDR0_460SX_HSSL2DAMP		0x322
+#define PESDR0_460SX_HSSL3DAMP		0x323
+#define PESDR0_460SX_HSSL4DAMP		0x324
+#define PESDR0_460SX_HSSL5DAMP		0x325
+#define PESDR0_460SX_HSSL6DAMP		0x326
+#define PESDR0_460SX_HSSL7DAMP		0x327
+
+#define PESDR1_460SX_HSSL0DAMP		0x354
+#define PESDR1_460SX_HSSL1DAMP		0x355
+#define PESDR1_460SX_HSSL2DAMP		0x356
+#define PESDR1_460SX_HSSL3DAMP		0x357
+
+#define PESDR2_460SX_HSSL0DAMP		0x384
+#define PESDR2_460SX_HSSL1DAMP		0x385
+#define PESDR2_460SX_HSSL2DAMP		0x386
+#define PESDR2_460SX_HSSL3DAMP		0x387
+
+#define PESDR0_460SX_HSSL0COEFA		0x328
+#define PESDR0_460SX_HSSL1COEFA		0x329
+#define PESDR0_460SX_HSSL2COEFA		0x32A
+#define PESDR0_460SX_HSSL3COEFA		0x32B
+#define PESDR0_460SX_HSSL4COEFA		0x32C
+#define PESDR0_460SX_HSSL5COEFA		0x32D
+#define PESDR0_460SX_HSSL6COEFA		0x32E
+#define PESDR0_460SX_HSSL7COEFA		0x32F
+
+#define PESDR1_460SX_HSSL0COEFA		0x358
+#define PESDR1_460SX_HSSL1COEFA		0x359
+#define PESDR1_460SX_HSSL2COEFA		0x35A
+#define PESDR1_460SX_HSSL3COEFA		0x35B
+
+#define PESDR2_460SX_HSSL0COEFA		0x388
+#define PESDR2_460SX_HSSL1COEFA		0x389
+#define PESDR2_460SX_HSSL2COEFA		0x38A
+#define PESDR2_460SX_HSSL3COEFA		0x38B
+
+#define PESDR0_460SX_HSSL1CALDRV	0x339
+#define PESDR1_460SX_HSSL1CALDRV	0x361
+#define PESDR2_460SX_HSSL1CALDRV	0x391
+
+#define PESDR0_460SX_HSSSLEW		0x338
+#define PESDR1_460SX_HSSSLEW		0x360
+#define PESDR2_460SX_HSSSLEW		0x390
+
+#define PESDR0_460SX_HSSCTLSET		0x31E
+#define PESDR1_460SX_HSSCTLSET		0x352
+#define PESDR2_460SX_HSSCTLSET		0x382
+
+#define PESDR0_460SX_RCSSET		0x304
+#define PESDR1_460SX_RCSSET		0x344
+#define PESDR2_460SX_RCSSET		0x374
+/*
  * Of the above, some are common offsets from the base
  */
 #define PESDRn_UTLSET1			0x00
--=20
1.6.3.3

^ permalink raw reply related

* Re: Deprecating of_platform, the path from here...
From: Benjamin Herrenschmidt @ 2009-12-10  1:45 UTC (permalink / raw)
  To: David Miller; +Cc: devicetree-discuss, linuxppc-dev, paulus, jk
In-Reply-To: <20091209.161550.168794100.davem@davemloft.net>

On Wed, 2009-12-09 at 16:15 -0800, David Miller wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
> Date: Wed, 9 Dec 2009 15:06:29 -0700
> 
> > 1) of_platform will be deprecated in preference of the platform bus.
> 
> What a shame, it's one of the cleanest driver probing models
> in the tree.

It is indeed. However, I'm not 100% convinced it requires keeping a
separate bus & device type, if we can make the base platform_device
benefit from it transparently.

So here's a (long) email summarizing my thoughts in those matters. I
would really appreciate if you took the time to read it through, think
it through and then speak your mind. As you will notice, I'm not myself
completely sold on the way to go there myself and some of your ideas do
tempt me very much indeed :-)

First let's clearly separate the two different aspects of this
discussion for the sake of lurkers :-) One is the probing & matching
mechanism.  The other one is how the driver retrieves it's various
parameters, either from a device node, or from pdata. From our IRC
discussion you have valid points on both aspect of the argument so I'll
try to discuss this here separately and we'll see what others think too.

First the probing because that's the real important issue, I believe the
other one is mostly academic and can be dealt on a per driver basis
(I'll discuss it later too).

I'm not totally sold on the idea of the table that Grant proposed. I
think I proposed it initially in a discussion we had on IRC as one
possible option and in fact it was suggested by Paulus so don't
completely blame Grant for it though. It does mean that either platform
code or core code will have some kind of big table that associates a
whole pile of of_device_id with a platform device name. It somewhat
sucks when I think more about it and it does feel like a step backward
from of_platform_device.

If we could make platform_driver grow an of_device_id match list it
would be indeed nicer. Of course you'll reply to that "let's just use
of_platform" instead :-)

I would then argue that I don't like having two different bus types,
platform and of_platform for "generic platform" devices that aren't
typed on a bus type. There's a lot of existing "platform device" and it
would be quite hard to convert them all. Especially since a lot of them
are used today on archs that don't have device trees and may never grow
one.

IE. I believe it's going to be an easier path to grow platform_device
into something that has the of_device probing functionality rather than
turn everything into of_platform. (I'm not talking here about the pdata
and retrieval of informations from the tree, this is the second part of
the discussion, discussed below).

The main problem with moving existing platform_device to of_platform is
how do we deal with archs that don't have the device-tree infrastructure
and use those drivers today ?

We could I suppose create a helper that looks a lot like the current
platform device creation one, which would create an of_platform device
instead, along with a struct device_node attached (which isn't part of a
tree) to it, and create a single "compatible" property whose content is
the platform data name.

But that means that for every driver we want to be able to use a
device-tree probing for, we would have to convert all archs & platforms
that may instanciate it to use the new helpers, in addition to replacing
whatever pdata they have statically stored into a device node (see the
second part of the discussion).

It's possible I suppose. I just feel that it's going to be a tougher
sell to the rest of the world.

There's one nit to be careful of. Some drivers (sadly) have the fact
that they appear under /sys/bus/platform/ as a userspace ABI thingy. Sad
but a fact. This is one of the reasons why rather than actually
converting to of_platform I'd rather find a way to add the of_device_id
match mechanism to the existing platform_device and deprecate the pdata
over time. 

It will also provide with an easier transition. Basically transform
platform_device into of_platform_device by first adding the missing bits
and -then- trimming the crufty remains.

Now let's move to the second part of the discussion which is the
retrieval of various configuration informations by the driver.

Here too, our model is better, I think there's little argument there. A
named list of properties is just so much more flexible than a statically
data structure that has to be in sync between the driver and all
platforms using it leaves little room for improvement or adding platform
specific attributes which some drivers might need, etc...

Grant proposal is to have drivers create the pdata from the device-tree.
This is something I believe we both disagree with, though you more
vehemently than me I suppose :-)

There are various things at play here:

First, let me make it clear that imho, the device type
(of_platform_device vs. platform_device) is irrelevant to that aspect of
the problem since nowadays we have the ability to carry a device node
pointer in any descendant of struct device (and we use that heavily for
devices using specific bus types already).

If you take an existing platform driver that you want to use on a
device-tree enabled platform (other than just creating it and pdata from
arch code which we all agree sucks), the two choices have different
consequences:

In one case, converting to of_platform_device, you pretty much _have_ to
get rid of pdata, and convert the driver into using of_get_property()
instead. This is probably not a bad thing in the long run, except that
this means you also -have- to convert all platforms in all archs that
use that specific platform driver to also generate a device node
(possibly statically in many cases).

This can be a lot of code churn deep into platform code for things like
ARM which can be pretty nasty, for which none of us have any way to test
on the relevant hardware. Other arch people will (maybe rightfully so)
protest especially if they have no intent to use the device-tree stuff
in their architecture or not yet anyways. And that for each platform
driver involved.

On the other case, converting to platform_device, adding the device
node, we have the ability to do an easier transition and easier to sell.
yes, we do take the risk of getting in that limbo land where drivers end
up forever in the "transition" state though. That's a con of this
approach, I do admit.

I don't agree with grant idea however that just converting the content
of the device node into properties is the way to go.

I do prefer your proposed approach (from our IRC discussion) which is
instead to allocate a struct device-node, convert pdata into properties,
and modify the drier to use these properties.

The main difference thus between the two type of conversions (convert to
of_platform vs convert to platform) is that in the first case, you have
to convert the driver to use properties -and- convert all platforms in
all archs including gory ARM cell phone stuff you really don't want to
go anywhere near. In the second case, you still convert the driver to
use properties natively, but you keep a "wart" to turn pdata into a
device-node -inside the driver-, protected by a CONFIG option maybe, so
that those archs can be left alone until it becomes so obvious to
everybody what approach is better that they'll end up being converted
too and the wart can go.

I believe the second approach, while less "clean" in the absolute is a
more realistic path to take.

Now, orthogonally to that, I do believe it's still nice to provide a way
to statically lay out a device node in platform code, to allow archs
that don't otherwise have the device-tree to replace pdata with
something nicer and get rid of the wart quicker.

We could either find a way with macros to layout an actual struct
device_node statically along with all the properties etc... but that
sounds a tad hard.

We could have something that convert an entirely ASCII representation
into a struct device_node, but that would be akin of having dtc in the
kernel, might be a bit bloated no ? Though it could be made simpler and
more restrictive.

Or we could find an in-between .. .A different struct type that is more
suitable for being laid out statically (a name, a type, and an enum of
structs for various property "types", ie, strings, words, bytes, ...)
with a little helper function that conver that into a device node at
runtime ?

What do you think ?

Cheers,
Ben.

^ permalink raw reply

* Re: Deprecating of_platform, the path from here...
From: David Miller @ 2009-12-10  0:21 UTC (permalink / raw)
  To: grant.likely; +Cc: devicetree-discuss, linuxppc-dev, paulus, jk
In-Reply-To: <20091209.161550.168794100.davem@davemloft.net>

From: David Miller <davem@davemloft.net>
Date: Wed, 09 Dec 2009 16:15:50 -0800 (PST)

> From: Grant Likely <grant.likely@secretlab.ca>
> Date: Wed, 9 Dec 2009 15:06:29 -0700
> 
>> 1) of_platform will be deprecated in preference of the platform bus.
> 
> What a shame, it's one of the cleanest driver probing models
> in the tree.

And BTW, have you folks who "decided" this considered at all the fact
that it is much easier to describe represent platform devices using
of OF devices rather than the other way around?

The platform device pdata mechanism requires data structure changes
and is not dynamically extensible, whereas OF devices are
fundamentally so.

I don't like the idea to get rid of of_platform devices at all.

OF devices are really clean, much like netlink messages, where
arbitrary named attributes can be added or removed without any data
structure changes at all.

^ permalink raw reply

* Re: Deprecating of_platform, the path from here...
From: David Miller @ 2009-12-10  0:15 UTC (permalink / raw)
  To: grant.likely; +Cc: devicetree-discuss, linuxppc-dev, paulus, jk
In-Reply-To: <fa686aa40912091406i2ef4e1b2u25c9f46b20786245@mail.gmail.com>

From: Grant Likely <grant.likely@secretlab.ca>
Date: Wed, 9 Dec 2009 15:06:29 -0700

> 1) of_platform will be deprecated in preference of the platform bus.

What a shame, it's one of the cleanest driver probing models
in the tree.

^ permalink raw reply

* Re: ucc_geth: Fix the wrong the Rx/Tx FIFO size
From: Anton Vorontsov @ 2009-12-09 23:00 UTC (permalink / raw)
  To: Dave Liu; +Cc: linuxppc-dev, David Miller, netdev
In-Reply-To: <1259309803-5474-1-git-send-email-daveliu@freescale.com>

On Fri, Nov 27, 2009 at 04:16:43PM +0800, Dave Liu wrote:
> current the Rx/Tx FIFO size settings cause problem
> when four UEC ethernets work simultaneously.
> 
> eg: GETH1, UEM-J15, GETH2, UEC-J5 on 8569MDS board
> 
>  $ ifconfig eth0 10.193.20.166
>  $ ifconfig eth1 10.193.20.167
>  $ ifconfig eth2 10.193.20.168
>  then
>  $ ifconfig eth3 10.193.20.169
> 
> The fourth ethernet will cause all of interface broken,
> you cann't ping successfully any more.
> The patch fix this issue for MPC8569 Rev1.0 and Rev2.0
> 
> Signed-off-by: Dave Liu <daveliu@freescale.com>

Acked-by: Anton Vorontsov <avorontsov@ru.mvista.com>

Thanks Dave! I see that the new values actually match the QEIWRM
spec (except UTFS... spec recommends 2048, but it also says that
it might differ for different memory setups, though that's a
separate issue).

And FWIW, I did some quick netperf tests on MPC8360, and the
patch doesn't cause any problems.

-- 
Anton Vorontsov
email: cbouatmailru@gmail.com
irc://irc.freenode.net/bd2

^ permalink raw reply

* Re: [PATCH 6/8] Use proper types for do_div
From: Mark Wielaard @ 2009-12-09 22:47 UTC (permalink / raw)
  To: avorontsov; +Cc: linuxppc-dev, systemtap
In-Reply-To: <20091209160941.GA8539@oksana.dev.rtsoft.ru>

Hi Anton,

On Wed, 2009-12-09 at 19:09 +0300, Anton Vorontsov wrote:
> I think this should be fixed by this patch:
> 
> http://sourceware.org/ml/systemtap/2009-q4/msg00800.html
> 
> Can you try it? With this patch I see no new regressions on x86_64.

Yes, that fixes everything. Sorry I didn't see that patch earlier. I see
Wenji also tested it already. I have pushed it for you.

Thanks,

Mark

^ permalink raw reply

* Re: dts file for MPC8343EA - cuImage doesn't boot , but uImage with DTS shows serial output
From: Junita Ajith @ 2009-12-09 22:08 UTC (permalink / raw)
  To: Lee, Eric; +Cc: Linuxppc-dev@lists.ozlabs.org
In-Reply-To: <507B57E36B7C3A48BD1B90EFA80A782E5372EE795D@GVW0433EXB.americas.hpqcorp.net>

[-- Attachment #1: Type: text/plain, Size: 19528 bytes --]

Eric,

1. I did try building with MDS configuration.
2. Removed BCSR section
3. Set u-boot environment variable.

The code boots up in the MPC8349 reference platform and not in the custom
board.
Also I am wondering why the cuImage would not give out any serial output
even, whereas I do see serial out with DTB file passed from u-boot?!!


Screen-shot:
==========
Bytes transferred = 12288 (3000 hex)
SC3000> bootm 0x2000000 - 0x3000000
## Booting image at 02000000 ...
   Image Name:   Linux-2.6.27.18
   Created:      2009-12-09  21:57:32 UTC
   Image Type:   PowerPC Linux Kernel Image (gzip compressed)
   Data Size:    1464261 Bytes =  1.4 MB
   Load Address: 00000000
   Entry Point:  00000000
   Verifying Checksum ... OK
   Uncompressing Kernel Image ... OK
## Current stack ends at 0x0FF9BD48 => set upper limit to 0x00800000
## cmdline at 0x007FFF00 ... 0x007FFF25
bd address  = 0x0FF9BFC4
memstart    = 0x00000000
memsize     = 0x10000000
flashstart  = 0xFE000000
flashsize   = 0x00080000
flashoffset = 0x00034000
sramstart   = 0x00000000
sramsize    = 0x00000000
bootflags   = 0x00000001
intfreq     = 399.999 MHz
busfreq     = 266.666 MHz
ethaddr     = 00:E0:0C:00:8C:01
IP addr     = 192.168.201.199
baudrate    = 115200 bps
Skipping initrd
   Booting using the fdt at 0x3000000
No initrd
## device tree at 0x03000000 ... 0x03002FFF (len=12288=0x3000)
   Loading Device Tree to 007fc000, end 007fefff ... OK
Updating property '/soc8349@e0000000/ethernet@24000/mac-address' =  00 e0 0c
00 81Updating property '/soc8349@e0000000/ethernet@24000/local-mac-address'
=  00 e0 01Updating property 'timebase-frequency' =  03 f9 40 aa
Updating property 'bus-frequency' =  0f e5 02 a8
Updating property 'clock-frequency' =  17 d7 83 fc
Updating property 'bus-frequency' =  0f e5 02 a8
Updating property 'clock-frequency' =  0f e5 02 a8
## Transferring control to Linux (at address 00000000) ...
Using MPC834x MDS machine description
Linux version 2.6.27.18 (root@localhost.localdomain) (gcc version 4.1.2) #4
Wed D9Found legacy serial port 0 for /soc8349@e0000000/serial@4500
  mem=e0004500, taddr=e0004500, irq=0, clk=266666664, speed=0
Found legacy serial port 1 for /soc8349@e0000000/serial@4600
  mem=e0004600, taddr=e0004600, irq=0, clk=266666664, speed=0
console [udbg0] enabled
setup_arch: bootmem
mpc834x_mds_setup_arch()
Found MPC83xx PCI host bridge at 0x00000000e0008500. Firmware bus number:
0->0
PCI host bridge /pci@e0008500 (primary) ranges:
 MEM 0x0000000090000000..0x000000009fffffff -> 0x0000000090000000
 MEM 0x0000000080000000..0x000000008fffffff -> 0x0000000080000000 Prefetch
  IO 0x00000000e2000000..0x00000000e20fffff -> 0x0000000000000000
Found MPC83xx PCI host bridge at 0x00000000e0008600. Firmware bus number:
0->0
PCI host bridge /pci@e0008600  ranges:
 MEM 0x00000000b0000000..0x00000000bfffffff -> 0x00000000b0000000
 MEM 0x00000000a0000000..0x00000000afffffff -> 0x00000000a0000000 Prefetch
  IO 0x00000000e2100000..0x00000000e21fffff -> 0x0000000000000000
arch: exit
Top of RAM: 0x10000000, Total RAM: 0x10000000
Memory hole size: 0MB
Zone PFN ranges:
  DMA      0x00000000 -> 0x00010000
  Normal   0x00010000 -> 0x00010000
Movable zone start PFN for each node
early_node_map[1] active PFN ranges
    0: 0x00000000 -> 0x00010000
On node 0 totalpages: 65536
free_area_init_node: node 0, pgdat c02ed470, node_mem_map c030f180
  DMA zone: 65024 pages, LIFO batch:15
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 65024
Kernel command line: root=/dev/ram rw console=ttyS0,115200
IPIC (128 IRQ sources) at fddfa700
PID hash table entries: 1024 (order: 10, 4096 bytes)
time_init: decrementer frequency = 66.666666 MHz
time_init: processor frequency   = 399.999996 MHz
clocksource: timebase mult[3c00001] shift[22] registered
clockevent: decrementer mult[1111] shift[16] cpu[0]
Dentry cache hash table entries: 32768 (order: 5, 131072 bytes)



On 12/9/09, Lee, Eric <eric.lee@hp.com> wrote:
>
>  two things; I had better luck with the mpc8349mds (? don’t remember exact
> file name) dts as opposed to the itx.  I had to remove the bcsr section or
> else the kernel hung during initialization .  also, your u-boot is not
> passing the correct kernel commandline:
>
>
>
> “Kernel command line: root=/dev/nfs rw nfsroot=192.168.200.230:/nfsroot/rootfs
> i0IPIC (128 IRQ sources) at fdffc700”
>
>
>
> you’re trying to run a ramdisk and with tty I expect:
>
>
>
> “root=/dev/ram rw console=ttyS0,115200  “
>
>
>
> check your environment variable bootargs in u-boot
>
>
>
>
>
>
>
> *From:* Junita Ajith [mailto:ajijuni@gmail.com]
> *Sent:* Wednesday, December 09, 2009 10:58 AM
> *To:* Lee, Eric
> *Cc:* Linuxppc-dev@lists.ozlabs.org
> *Subject:* dts file for MPC8343EA - cuImage doesn't boot , but uImage with
> DTS shows serial output
>
>
>
> Hi Eric,
>
> I am building the linux kernel V-2.6.27  based on MPC8349miTXGP dts file.
> I am still not able to boot the cuImage.
>
> But, I see serial outuput from kernel when I try to boot with <kernel>
> <ramdisk> <dtb file>
>
> Still the kernel hangs after "Dentry cache hash table entries: 32768
> (order: 5, 131072 bytes)".
>
> Any clues ..?? We have DDR2 in this board and we are initializing it in
> U-Boot.
>
> Please find the screen dump below:
>
> Thanks,
> Junita
>
> Screen shot:
> ===========
> u-boot> bootm 0x2000000 0x3000000 0x4000000
> ## Booting image at 02000000 ...
>    Image Name:   Linux-2.6.27.18-svn52-dirty8
>    Created:      2009-12-08  23:49:28 UTC
>    Image Type:   PowerPC Linux Kernel Image (gzip compressed)
>    Data Size:    1416039 Bytes =  1.4 MB
>    Load Address: 00000000
>    Entry Point:  00000000
>    Verifying Checksum ... OK
>    Uncompressing Kernel Image ... OK
> ## Current stack ends at 0x0FF9BD48 => set upper limit to 0x00800000
> ## cmdline at 0x007FFF00 ... 0x007FFFA6
> bd address  = 0x0FF9BFC4
> memstart    = 0x00000000
> memsize     = 0x10000000
> flashstart  = 0xFE000000
> flashsize   = 0x00080000
> flashoffset = 0x00034000
> sramstart   = 0x00000000
> sramsize    = 0x00000000
> bootflags   = 0x00000001
> intfreq     = 399.999 MHz
> busfreq     = 266.666 MHz
> ethaddr     = 00:E0:0C:00:8C:01
> IP addr     = 192.168.201.199
> baudrate    = 115200 bps
> Not skipping initrd
> ## Loading RAMDisk Image at 03000000 ...
>    Image Name:   uboot ext2 ramdisk rootfs
>    Created:      2009-10-30  20:15:22 UTC
>    Image Type:   PowerPC Linux RAMDisk Image (gzip compressed)
>    Data Size:    3889103 Bytes =  3.7 MB
>    Load Address: 00000000
>    Entry Point:  00000000
>    Verifying Checksum ... OK
>    Booting using the fdt at 0x4000000
> ## initrd at 0x03000040 ... 0x033B580E (len=3889103=0x3B57CF)
>    Loading Ramdisk to 0fbe5000, end 0ff9a7cf ... OK
> ## device tree at 0x04000000 ... 0x04002FFF (len=12288=0x3000)
>    Loading Device Tree to 007fc000, end 007fefff ... OK
> Updating property '/soc8349@e0000000/ethernet@24000/mac-address' =  00 e0
> 0c 001Updating property '/soc8349@e0000000/ethernet@24000/local-mac-address'
> =  00 e01Updating property 'timebase-frequency' =  03 f9 40 aa
> Updating property 'bus-frequency' =  0f e5 02 a8
> Updating property 'clock-frequency' =  17 d7 83 fc
> Updating property 'bus-frequency' =  0f e5 02 a8
> Updating property 'clock-frequency' =  0f e5 02 a8
> ## Transferring control to Linux (at address 00000000) ...
> Using MPC834x ITX machine description
> Linux version 2.6.27.18-svn52-dirty8 (root@localhost.localdomain) (gcc
> version 9Found initrd at 0xcfbe5000:0xcff9a7cf
> console [udbg0] enabled
> setup_arch: bootmem
> mpc834x_itx_setup_arch()
> arch: exit
> Zone PFN ranges:
>   DMA      0x00000000 -> 0x00010000
>   Normal   0x00010000 -> 0x00010000
> Movable zone start PFN for each node
> early_node_map[1] active PFN ranges
>     0: 0x00000000 -> 0x00010000
> Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 65024
> Kernel command line: root=/dev/nfs rw nfsroot=192.168.200.230:/nfsroot/rootfs
> i0IPIC (128 IRQ sources) at fdffc700
> PID hash table entries: 1024 (order: 10, 4096 bytes)
> clocksource: timebase mult[3c00001] shift[22] registered
> Dentry cache hash table entries: 32768 (order: 5, 131072 bytes)
>
>
>
>
>  On 12/9/09, *Lee, Eric* <eric.lee@hp.com> wrote:
>
> I would probably remove the bcsr region.  this was some cpld I believe on a
> reference board.  with this dts it'll try to write to some hardware
> registers that do not exist or are not mapped to the same area.
>
>
>
>
> -----Original Message-----
> From: linuxppc-dev-bounces+eric.lee=hp.com@lists.ozlabs.org [mailto:
> linuxppc-dev-bounces+eric.lee <linuxppc-dev-bounces%2Beric.lee>=hp.com@
> lists.ozlabs.org] On Behalf Of ajijuni@gmail.com
> Sent: Sunday, December 06, 2009 11:41 PM
> To: Linuxppc-dev@lists.ozlabs.org
> Subject: dts file for MPC8343EA
>
> Hi
>
> We have an MPC8343EA based custom board.
>
> I am not able to get Linux up and running in this. No serial output to
> debug further.
>   U-boot shows correct 'bdinfo' & 'clocks' output.
> inux hangs at machine_probe.
>
>
> I doubt the DTS file in Linux. anyone has DTS file for MPC8343??
>
> u-boot version - 1.3.2
> linux-2.6.27
> The board base files are drived from MPC8349Imtx-GP since we have the
> reference board in which we tested the linux image.
>
> My current DTS file
> /dts-v1/;
>
> / {
>         model = "MPC8343";
>         compatible = "MPC8349EMDS", "MPC834xMDS", "MPC83xxMDS";
>         linux,phandle = <0x100>;
>         #size-cells = <0x1>;
>         #address-cells = <0x1>;
>
>         aliases {
>                 ethernet0 = &enet0;
>                 ethernet1 = &enet1;
>                 serial0 = &serial0;
>                 serial1 = &serial1;
>                 pci0 = &pci0;
>                 pci1 = &pci1;
>         };
>          cpus {
>                 linux,phandle = <0x200>;
>                 #cpus = <0x1>;
>                 #address-cells = <1>;
>                 #size-cells = <0>;
>
>   PowerPC,8343EA@0 {
>                         device_type = "cpu";
>                         reg = <0x0>;
>                         d-cache-line-size = <20>;
>                         i-cache-line-size = <20>;
>                         d-cache-size = <8000>;
>                         i-cache-size = <8000>;
>                         timebase-frequency = <0>;       // from bootloader
>                         bus-frequency = <0>;            // from bootloader
>                         clock-frequency = <0>;          // from bootloader
>                         32-bit;
>                 };
>         };
>
>
>         memory {
>                 device_type = "memory";
>                 reg = <0x00000000 0x10000000>;  // 256MB at 0
>         };
>
>         bcsr@e2400000 {
>                 device_type = "board-control";
>                 reg = <0xe2400000 0x8000>;
>         };
>         soc8343@e0000000 {
>                 bus-frequency = <0x1>;
>                 reg = <0xe0000000 0x200>;
>                 ranges = <0x0 0xe0000000 0x100000>;
>                 device_type = "soc";
>                 #interrupt-cells = <0x2>;
>                 #size-cells = <0x1>;
>                 #address-cells = <0x1>;
>
>                 wdt@200 {
>                         device_type = "watchdog";
>                         compatible = "mpc83xx_wdt";
>                         reg = <0x200 0x100>;
>                 };
>
> i2c@3000 {
>                         #address-cells = <1>;
>                         #size-cells = <0>;
>                         cell-index = <0>;
>                         compatible = "fsl-i2c";
>                         reg = <0x3000 0x100>;
>                         interrupts = <14 0x8>;
>                         interrupt-parent = <&ipic>;
>                         dfsrr;
>
>                         rtc@68 {
>                                 compatible = "dallas,ds1374";
>                                 reg = <0x68>;
>                         };
>                 };
>
>                 i2c@3100 {
>                         #address-cells = <1>;
>                         #size-cells = <0>;
>                         cell-index = <1>;
>                         compatible = "fsl-i2c";
>                         reg = <0x3100 0x100>;
>                         interrupts = <15 0x8>;
>                         interrupt-parent = <&ipic>;
>                         dfsrr;
>                 };
>
>                 spi@7000 {
>                         cell-index = <0>;
>                         compatible = "fsl,spi";
>                         reg = <0x7000 0x1000>;
>                         interrupts = <16 0x8>;
>                         interrupt-parent = <&ipic>;
>                         mode = "cpu";
>                 };
>
> dma@82a8 {
>                         #address-cells = <1>;
>                         #size-cells = <1>;
>                         compatible = "fsl,mpc8349-dma", "fsl,elo-dma";
>                         reg = <0x82a8 4>;
>                         ranges = <0 0x8100 0x1a8>;
>                         interrupt-parent = <&ipic>;
>                         interrupts = <71 8>;
>                         cell-index = <0>;
>                         dma-channel@0 {
>                                 compatible = "fsl,mpc8349-dma-channel",
> "fsl,elo-dma-channel";
>                                 reg = <0 0x80>;
>                                 interrupt-parent = <&ipic>;
>                                 interrupts = <71 8>;
>                         };
>                         dma-channel@80 {
>                                 compatible = "fsl,mpc8349-dma-channel",
> "fsl,elo-dma-channel";
>                                 reg = <0x80 0x80>;
>                                 interrupt-parent = <&ipic>;
>                                 interrupts = <71 8>;
>                         };
>                         dma-channel@100 {
>                                 compatible = "fsl,mpc8349-dma-channel",
> "fsl,elo-dma-channel";
>                                 reg = <0x100 0x80>;
>                                 interrupt-parent = <&ipic>;
>                                 interrupts = <71 8>;
>                         };
>                         dma-channel@180 {
>                                 compatible = "fsl,mpc8349-dma-channel",
> "fsl,elo-dma-channel";
>                                 reg = <0x180 0x28>;
>                                 interrupt-parent = <&ipic>;
>                                 interrupts = <71 8>;
>                         };
>                 };
> /* phy type (ULPI or SERIAL) are only types supported for MPH */
>                 /* port = 0 or 1 */
>                 usb@22000 {
>                         compatible = "fsl-usb2-mph";
>                         reg = <0x22000 0x1000>;
>                         #address-cells = <1>;
>                         #size-cells = <0>;
>                         interrupt-parent = <&ipic>;
>                         interrupts = <39 0x8>;
>                         phy_type = "ulpi";
>                         port1;
>                 };
>                 /* phy type (ULPI, UTMI, UTMI_WIDE, SERIAL) */
>                 usb@23000 {
>                         compatible = "fsl-usb2-dr";
>                         reg = <0x23000 0x1000>;
>                         #address-cells = <1>;
>                         #size-cells = <0>;
>                         interrupt-parent = <&ipic>;
>                         interrupts = <38 0x8>;
>                         dr_mode = "otg";
>                         phy_type = "ulpi";
>                 };
>
>                 mdio@24520 {
>                         #address-cells = <1>;
>                         #size-cells = <0>;
>                         compatible = "fsl,gianfar-mdio";
>                         reg = <0x24520 0x20>;
>
>                         phy0: ethernet-phy@0 {
>                                 interrupt-parent = <&ipic>;
>                                 interrupts = <17 0x8>;
>                                 reg = <0x0>;
>                                 device_type = "ethernet-phy";
>                         };
>                         phy1: ethernet-phy@1 {
>                                 interrupt-parent = <&ipic>;
>                                 interrupts = <18 0x8>;
>                                 reg = <0x1>;
>                                 device_type = "ethernet-phy";
>                         };
> enet0: ethernet@24000 {
>                         cell-index = <0>;
>                         device_type = "network";
>                         model = "TSEC";
>                         compatible = "gianfar";
>                         reg = <0x24000 0x1000>;
>                         local-mac-address = [ 00 00 00 00 00 00 ];
>                         interrupts = <32 0x8 33 0x8 34 0x8>;
>                         interrupt-parent = <&ipic>;
>                         phy-handle = <&phy0>;
>                         linux,network-index = <0>;
>                 };
>
>                 enet1: ethernet@25000 {
>                         cell-index = <1>;
>                         device_type = "network";
>                         model = "TSEC";
>                         compatible = "gianfar";
>                         reg = <0x25000 0x1000>;
>                         local-mac-address = [ 00 00 00 00 00 00 ];
>                         interrupts = <35 0x8 36 0x8 37 0x8>;
>                         interrupt-parent = <&ipic>;
>                         phy-handle = <&phy1>;
>                         linux,network-index = <1>;
>                 };
>
> serial0: serial@4500 {
>                         cell-index = <0>;
>                         device_type = "serial";
>                         compatible = "ns16550";
>                         reg = <0x4500 0x100>;
>                         clock-frequency = <0>;
>                         interrupts = <9 0x8>;
>                         interrupt-parent = <&ipic>;
>                 };
>
>                 serial1: serial@4600 {
>                         cell-index = <1>;
>                         device_type = "serial";
>                         compatible = "ns16550";
>                         reg = <0x4600 0x100>;
>                         clock-frequency = <0>;
>                         interrupts = <10 0x8>;
>                         interrupt-parent = <&ipic>;
>                 };
>
>                 crypto@30000 {
>                         compatible = "fsl,sec2.0";
>                         reg = <0x30000 0x10000>;
>                         interrupts = <11 0x8>;
>                         interrupt-parent = <&ipic>;
>                         fsl,num-channels = <4>;
>                         fsl,channel-fifo-len = <24>;
>                         fsl,exec-units-mask = <0x7e>;
>                         fsl,descriptor-types-mask = <0x01010ebf>;
>                 };
>
> Thanks,
> agnel
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
>
>
>

[-- Attachment #2: Type: text/html, Size: 24569 bytes --]

^ 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