LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [Patch 2/2] PPC64-HWBKPT: Implement hw-breakpoints for PPC64
From: K.Prasad @ 2010-05-12  3:34 UTC (permalink / raw)
  To: Paul Mackerras
  Cc: Michael Neuling, Benjamin Herrenschmidt, shaggy,
	Frederic Weisbecker, David Gibson, linuxppc-dev@ozlabs.org,
	Alan Stern, Roland McGrath
In-Reply-To: <20100504203302.GA3894@in.ibm.com>

On Wed, May 05, 2010 at 02:03:03AM +0530, K.Prasad wrote:
> On Mon, May 03, 2010 at 04:23:30PM +1000, Paul Mackerras wrote:
> > On Wed, Apr 14, 2010 at 09:18:27AM +0530, K.Prasad wrote:
> > 
[snipped]
> 
> It has been pointed out to me before (Roland's mail Ref:linuxppc-dev
> message-id: 20100119100335.3EB621DE@magilla.sf.frob.com) that there will
> be too many corner cases that will be difficult to foresee, however your
> above list appears to be exhaustive. While the alternatives to this being
> a fallback to one-shot breakpoints (thereby leading to confusing
> hw-breakpoint interface semantics), this is an attempt to generate
> continuous and 'trigger-after-execute' (for non-ptrace requests)
> breakpoint exceptions. I believe that, with the addressal of concerns
> cited above, the resultant patchset would be one that achieves the
> stated design goals with no loss to existing functionality.
> 

Hi Paul,

> I intend to send out another version of this patchset with fixes as
> described in my replies above (unless I hear objections to it :-)).
> 

Meanwhile, a little sickness had kept me away from working on this
patchset. I have now posted a new version of the same here () which
contains changes as described above.

A few more changes to the patch is impending post merger
of Frederic's patches (which are now in -tip) into mainline (ref: commit
73266fc1df2f94cf72b3beba3eee3b88ed0b0664 to
777d0411cd1e384115985dac5ccd42031e3eee2b);
mainly due to the new ability for a per-task breakpoint to request
kernel-space breakpoints (the notion of kernel- vs user-bp would also
become obsolete, it is better to call them per-cpu vs per-task
breakpoints).

Also, I find that possibility of a kernel-thread specific breakpoint
(which can migrate across CPUs) has not been thought and implemented well
in this patch (will be much easier after merger of Frederic's patch). I
would prefer to have atleast some version of the patch included in
mainline before bringing in support for the same.

Thanks,
K.Prasad

^ permalink raw reply

* [Patch 3/3] PPC64-HWBKPT: Implement hw-breakpoints for PowerPC Book III S
From: K.Prasad @ 2010-05-12  3:33 UTC (permalink / raw)
  To: linuxppc-dev@ozlabs.org
  Cc: Michael Neuling, Benjamin Herrenschmidt, shaggy,
	Frederic Weisbecker, David Gibson, paulus, Alan Stern, K.Prasad,
	Roland McGrath
In-Reply-To: <20100512022527.857904312@linux.vnet.ibm.com>

Implement perf-events based hw-breakpoint interfaces for PowerPC Book III S
processors. These interfaces help arbitrate requests from various users and
schedules them as appropriate.

Signed-off-by: K.Prasad <prasad@linux.vnet.ibm.com>
---
 arch/powerpc/Kconfig                     |    1 
 arch/powerpc/include/asm/cputable.h      |    4 
 arch/powerpc/include/asm/hw_breakpoint.h |   45 +++
 arch/powerpc/include/asm/processor.h     |    8 
 arch/powerpc/kernel/Makefile             |    1 
 arch/powerpc/kernel/hw_breakpoint.c      |  354 +++++++++++++++++++++++++++++++
 arch/powerpc/kernel/machine_kexec_64.c   |    3 
 arch/powerpc/kernel/process.c            |    6 
 arch/powerpc/kernel/ptrace.c             |   64 +++++
 arch/powerpc/kernel/traps.c              |    3 
 arch/powerpc/lib/Makefile                |    1 
 include/linux/hw_breakpoint.h            |    1 
 12 files changed, 491 insertions(+)

Index: linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
===================================================================
--- /dev/null
+++ linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
@@ -0,0 +1,45 @@
+#ifndef _PPC_BOOK3S_64_HW_BREAKPOINT_H
+#define _PPC_BOOK3S_64_HW_BREAKPOINT_H
+
+#ifdef	__KERNEL__
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+
+struct arch_hw_breakpoint {
+	u8		len; /* length of the target data symbol */
+	int		type;
+	unsigned long	address;
+};
+
+#include <linux/kdebug.h>
+#include <asm/reg.h>
+#include <asm/system.h>
+
+struct perf_event;
+struct pmu;
+struct perf_sample_data;
+
+#define HW_BREAKPOINT_ALIGN 0x7
+/* Maximum permissible length of any HW Breakpoint */
+#define HW_BREAKPOINT_LEN 0x8
+
+extern int arch_bp_generic_fields(int type, int *gen_bp_type);
+extern int arch_validate_hwbkpt_settings(struct perf_event *bp,
+						struct task_struct *tsk);
+extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
+						unsigned long val, void *data);
+int arch_install_hw_breakpoint(struct perf_event *bp);
+void arch_uninstall_hw_breakpoint(struct perf_event *bp);
+void hw_breakpoint_pmu_read(struct perf_event *bp);
+extern void flush_ptrace_hw_breakpoint(struct task_struct *tsk);
+
+extern struct pmu perf_ops_bp;
+extern void ptrace_triggered(struct perf_event *bp, int nmi,
+			struct perf_sample_data *data, struct pt_regs *regs);
+static inline void hw_breakpoint_disable(void)
+{
+	set_dabr(0);
+}
+
+#endif	/* CONFIG_HAVE_HW_BREAKPOINT */
+#endif	/* __KERNEL__ */
+#endif	/* _PPC_BOOK3S_64_HW_BREAKPOINT_H */
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
===================================================================
--- /dev/null
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
@@ -0,0 +1,354 @@
+/*
+ * HW_breakpoint: a unified kernel/user-space hardware breakpoint facility,
+ * using the CPU's debug registers. Derived from
+ * "arch/x86/kernel/hw_breakpoint.c"
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright 2009 IBM Corporation
+ * Author: K.Prasad <prasad@linux.vnet.ibm.com>
+ *
+ */
+
+#include <linux/hw_breakpoint.h>
+#include <linux/notifier.h>
+#include <linux/kprobes.h>
+#include <linux/percpu.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+
+#include <asm/hw_breakpoint.h>
+#include <asm/processor.h>
+#include <asm/sstep.h>
+
+/*
+ * Store the 'bp' that caused the hw-breakpoint exception just before we
+ * single-step. Use it to distinguish a single-step exception (due to a
+ * previous hw-breakpoint exception) from a normal one
+ */
+static DEFINE_PER_CPU(struct perf_event *, last_hit_bp);
+
+/*
+ * Stores the breakpoints currently in use on each breakpoint address
+ * register for every cpu
+ */
+static DEFINE_PER_CPU(struct perf_event *, bp_per_reg);
+
+/*
+ * Install a perf counter breakpoint.
+ *
+ * We seek a free debug address register and use it for this
+ * breakpoint.
+ *
+ * Atomic: we hold the counter->ctx->lock and we only handle variables
+ * and registers local to this cpu.
+ */
+int arch_install_hw_breakpoint(struct perf_event *bp)
+{
+	struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+	struct perf_event **slot = &__get_cpu_var(bp_per_reg);
+
+	*slot = bp;
+	set_dabr(info->address | info->type | DABR_TRANSLATION);
+	return 0;
+}
+
+/*
+ * Uninstall the breakpoint contained in the given counter.
+ *
+ * First we search the debug address register it uses and then we disable
+ * it.
+ *
+ * Atomic: we hold the counter->ctx->lock and we only handle variables
+ * and registers local to this cpu.
+ */
+void arch_uninstall_hw_breakpoint(struct perf_event *bp)
+{
+	struct perf_event **slot = &__get_cpu_var(bp_per_reg);
+
+	if (*slot != bp) {
+		WARN_ONCE(1, "Can't find the breakpoint");
+		return;
+	}
+
+	*slot = NULL;
+	set_dabr(0);
+}
+
+/*
+ * Perform cleanup of arch-specific counters during unregistration
+ * of the perf-event
+ */
+void arch_unregister_hw_breakpoint(struct perf_event *bp)
+{
+	int cpu = get_cpu();
+
+	/*
+	 * If the breakpoint is unregistered between a hw_breakpoint_handler()
+	 * and the single_step_dabr_instruction(), then cleanup the breakpoint
+	 * restoration variables to prevent dangling pointers.
+	 */
+	if (per_cpu(last_hit_bp, cpu) == bp) {
+			per_cpu(last_hit_bp, cpu) = NULL;
+		return;
+	}
+	if (bp->ctx->task)
+		bp->ctx->task->thread.last_hit_ubp = NULL;
+
+	put_cpu();
+}
+
+int arch_bp_generic_fields(int type, int *gen_bp_type)
+{
+	switch (type) {
+	case DABR_DATA_READ:
+		*gen_bp_type = HW_BREAKPOINT_R;
+		break;
+	case DABR_DATA_WRITE:
+		*gen_bp_type = HW_BREAKPOINT_W;
+		break;
+	case (DABR_DATA_WRITE | DABR_DATA_READ):
+		*gen_bp_type = (HW_BREAKPOINT_W | HW_BREAKPOINT_R);
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/*
+ * Validate the arch-specific HW Breakpoint register settings
+ */
+int arch_validate_hwbkpt_settings(struct perf_event *bp,
+						struct task_struct *tsk)
+{
+	bool is_kernel;
+	int ret = -EINVAL;
+	struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+
+	if (!bp)
+		return ret;
+
+	switch (bp->attr.bp_type) {
+	case HW_BREAKPOINT_R:
+		info->type = DABR_DATA_READ;
+		break;
+	case HW_BREAKPOINT_W:
+		info->type = DABR_DATA_WRITE;
+		break;
+	case HW_BREAKPOINT_R | HW_BREAKPOINT_W:
+		info->type = (DABR_DATA_READ | DABR_DATA_WRITE);
+		break;
+	default:
+		return ret;
+	}
+
+	is_kernel = is_kernel_addr(bp->attr.bp_addr);
+	if ((tsk && is_kernel) || (!tsk && !is_kernel))
+		return -EINVAL;
+
+	info->address = bp->attr.bp_addr;
+	info->len = bp->attr.bp_len;
+
+	/*
+	 * Since breakpoint length can be a maximum of HW_BREAKPOINT_LEN(8)
+	 * and breakpoint addresses are aligned to nearest double-word
+	 * HW_BREAKPOINT_ALIGN by rounding off to the lower address, the
+	 * 'symbolsize' should satisfy the check below.
+	 */
+	if (info->len >
+	    (HW_BREAKPOINT_LEN - (info->address & HW_BREAKPOINT_ALIGN)))
+		return -EINVAL;
+	return 0;
+}
+
+/*
+ * Handle debug exception notifications.
+ */
+int __kprobes hw_breakpoint_handler(struct die_args *args)
+{
+	bool is_kernel, is_ptrace_bp = false;
+	int rc = NOTIFY_STOP;
+	struct perf_event *bp;
+	struct pt_regs *regs = args->regs;
+	unsigned long dar = regs->dar;
+	int stepped = 1;
+	struct arch_hw_breakpoint *info;
+
+	/* Disable breakpoints during exception handling */
+	set_dabr(0);
+	/*
+	 * The counter may be concurrently released but that can only
+	 * occur from a call_rcu() path. We can then safely fetch
+	 * the breakpoint, use its callback, touch its counter
+	 * while we are in an rcu_read_lock() path.
+	 */
+	rcu_read_lock();
+
+	bp = __get_cpu_var(bp_per_reg);
+	if (!bp)
+		goto out;
+	info = counter_arch_bp(bp);
+	is_kernel = is_kernel_addr(bp->attr.bp_addr);
+	is_ptrace_bp = (bp->overflow_handler == ptrace_triggered) ?
+			true : false;
+
+	/*
+	 * Verify if dar lies within the address range occupied by the symbol
+	 * being watched to filter extraneous exceptions.
+	 */
+	if (!((bp->attr.bp_addr <= dar) &&
+	    (dar <= (bp->attr.bp_addr + bp->attr.bp_len))) &&
+	    (!is_ptrace_bp))
+		/*
+		 * This exception is triggered not because of a memory access on
+		 * the monitored variable but in the double-word address range
+		 * in which it is contained. We will consume this exception,
+		 * considering it as 'noise'.
+		 */
+		goto restore_bp;
+
+	/*
+	 * Return early after invoking user-callback function without restoring
+	 * DABR if the breakpoint is from ptrace which always operates in
+	 * one-shot mode. The ptrace-ed process will receive the SIGTRAP signal
+	 * generated in do_dabr().
+	 */
+	if (is_ptrace_bp) {
+		perf_bp_event(bp, regs);
+		rc = NOTIFY_DONE;
+		goto out;
+	}
+
+	/*
+	 * Do not emulate user-space instructions from kernel-space,
+	 * instead single-step them.
+	 */
+	if (!is_kernel) {
+		bp->ctx->task->thread.last_hit_ubp = bp;
+		regs->msr |= MSR_SE;
+		goto out;
+	}
+
+	stepped = emulate_step(regs, regs->nip);
+	/* emulate_step() could not execute it, single-step them */
+	if (stepped == 0) {
+		regs->msr |= MSR_SE;
+		__get_cpu_var(last_hit_bp) = bp;
+		goto out;
+	}
+	/*
+	 * As a policy, the callback is invoked in a 'trigger-after-execute'
+	 * fashion
+	 */
+	perf_bp_event(bp, regs);
+
+restore_bp:
+	set_dabr(info->address | info->type | DABR_TRANSLATION);
+out:
+	rcu_read_unlock();
+	return rc;
+}
+
+/*
+ * Handle single-step exceptions following a DABR hit.
+ */
+int __kprobes single_step_dabr_instruction(struct die_args *args)
+{
+	struct pt_regs *regs = args->regs;
+	struct perf_event *bp = NULL, *kernel_bp, *user_bp;
+	struct arch_hw_breakpoint *bp_info;
+
+	/*
+	 * Identify the cause of single-stepping and find the corresponding
+	 * breakpoint structure
+	 */
+	user_bp = current->thread.last_hit_ubp;
+	kernel_bp = __get_cpu_var(last_hit_bp);
+	if (user_bp) {
+		bp = user_bp;
+		current->thread.last_hit_ubp = NULL;
+	} else if (kernel_bp) {
+		bp = kernel_bp;
+		__get_cpu_var(last_hit_bp) = NULL;
+	}
+
+	/*
+	 * Check if we are single-stepping as a result of a
+	 * previous HW Breakpoint exception
+	 */
+	if (!bp)
+		return NOTIFY_DONE;
+
+	bp_info = counter_arch_bp(bp);
+
+	/*
+	 * We shall invoke the user-defined callback function in the single
+	 * stepping handler to confirm to 'trigger-after-execute' semantics
+	 */
+	perf_bp_event(bp, regs);
+
+	/*
+	 * Do not disable MSR_SE if the process was already in
+	 * single-stepping mode. We cannot reliable detect single-step mode
+	 * for kernel-space breakpoints, so this cannot work along with other
+	 * debuggers (like KGDB, xmon) which may be single-stepping kernel code.
+	 */
+	if (!(user_bp && test_thread_flag(TIF_SINGLESTEP)))
+		regs->msr &= ~MSR_SE;
+
+	set_dabr(bp_info->address | bp_info->type | DABR_TRANSLATION);
+	return NOTIFY_STOP;
+}
+
+/*
+ * Handle debug exception notifications.
+ */
+int __kprobes hw_breakpoint_exceptions_notify(
+		struct notifier_block *unused, unsigned long val, void *data)
+{
+	int ret = NOTIFY_DONE;
+
+	switch (val) {
+	case DIE_DABR_MATCH:
+		ret = hw_breakpoint_handler(data);
+		break;
+	case DIE_SSTEP:
+		ret = single_step_dabr_instruction(data);
+		break;
+	}
+
+	return ret;
+}
+
+/*
+ * Release the user breakpoints used by ptrace
+ */
+void flush_ptrace_hw_breakpoint(struct task_struct *tsk)
+{
+	struct thread_struct *t = &tsk->thread;
+
+	unregister_hw_breakpoint(t->ptrace_bps[0]);
+	t->ptrace_bps[0] = NULL;
+}
+
+void hw_breakpoint_pmu_read(struct perf_event *bp)
+{
+	/* TODO */
+}
+
Index: linux-2.6.ppc64_test/arch/powerpc/Kconfig
===================================================================
--- linux-2.6.ppc64_test.orig/arch/powerpc/Kconfig
+++ linux-2.6.ppc64_test/arch/powerpc/Kconfig
@@ -140,6 +140,7 @@ config PPC
 	select HAVE_SYSCALL_WRAPPERS if PPC64
 	select GENERIC_ATOMIC64 if PPC32
 	select HAVE_PERF_EVENTS
+	select HAVE_HW_BREAKPOINT if PERF_EVENTS && PPC_BOOK3S_64
 
 config EARLY_PRINTK
 	bool
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/Makefile
===================================================================
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/Makefile
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/Makefile
@@ -34,6 +34,7 @@ obj-y				+= vdso32/
 obj-$(CONFIG_PPC64)		+= setup_64.o sys_ppc32.o \
 				   signal_64.o ptrace32.o \
 				   paca.o nvram_64.o firmware.o
+obj-$(CONFIG_HAVE_HW_BREAKPOINT)	+= hw_breakpoint.o
 obj-$(CONFIG_PPC_BOOK3S_64)	+= cpu_setup_ppc970.o cpu_setup_pa6t.o
 obj64-$(CONFIG_RELOCATABLE)	+= reloc_64.o
 obj-$(CONFIG_PPC_BOOK3E_64)	+= exceptions-64e.o
Index: linux-2.6.ppc64_test/arch/powerpc/include/asm/processor.h
===================================================================
--- linux-2.6.ppc64_test.orig/arch/powerpc/include/asm/processor.h
+++ linux-2.6.ppc64_test/arch/powerpc/include/asm/processor.h
@@ -209,6 +209,14 @@ struct thread_struct {
 #ifdef CONFIG_PPC64
 	unsigned long	start_tb;	/* Start purr when proc switched in */
 	unsigned long	accum_tb;	/* Total accumilated purr for process */
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+	struct perf_event *ptrace_bps[HBP_NUM];
+	/*
+	 * Helps identify source of single-step exception and subsequent
+	 * hw-breakpoint enablement
+	 */
+	struct perf_event *last_hit_ubp;
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
 #endif
 	unsigned long	dabr;		/* Data address breakpoint register */
 #ifdef CONFIG_ALTIVEC
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/ptrace.c
===================================================================
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/ptrace.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/ptrace.c
@@ -32,6 +32,8 @@
 #ifdef CONFIG_PPC32
 #include <linux/module.h>
 #endif
+#include <linux/hw_breakpoint.h>
+#include <linux/perf_event.h>
 
 #include <asm/uaccess.h>
 #include <asm/page.h>
@@ -763,9 +765,34 @@ void user_disable_single_step(struct tas
 	clear_tsk_thread_flag(task, TIF_SINGLESTEP);
 }
 
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+void ptrace_triggered(struct perf_event *bp, int nmi,
+		      struct perf_sample_data *data, struct pt_regs *regs)
+{
+	struct perf_event_attr attr;
+
+	/*
+	 * Disable the breakpoint request here since ptrace has defined a
+	 * one-shot behaviour for breakpoint exceptions in PPC64.
+	 * The SIGTRAP signal is generated automatically for us in do_dabr().
+	 * We don't have to do anything about that here
+	 */
+	attr = bp->attr;
+	attr.disabled = true;
+	modify_user_hw_breakpoint(bp, &attr);
+}
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
+
 int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
 			       unsigned long data)
 {
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+	int ret;
+	struct thread_struct *thread = &(task->thread);
+	struct perf_event *bp;
+	struct perf_event_attr attr;
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
+
 	/* For ppc64 we support one DABR and no IABR's at the moment (ppc64).
 	 *  For embedded processors we support one DAC and no IAC's at the
 	 *  moment.
@@ -793,6 +820,43 @@ int ptrace_set_debugreg(struct task_stru
 	/* Ensure breakpoint translation bit is set */
 	if (data && !(data & DABR_TRANSLATION))
 		return -EIO;
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+	bp = thread->ptrace_bps[0];
+	if ((!data) || !(data & (DABR_DATA_WRITE | DABR_DATA_READ))) {
+		if (bp) {
+			unregister_hw_breakpoint(bp);
+			thread->ptrace_bps[0] = NULL;
+		}
+		return 0;
+	}
+	if (bp) {
+		attr = bp->attr;
+		attr.bp_addr = data & ~HW_BREAKPOINT_ALIGN;
+		arch_bp_generic_fields(data &
+					(DABR_DATA_WRITE | DABR_DATA_READ),
+							&attr.bp_type);
+		ret =  modify_user_hw_breakpoint(bp, &attr);
+		if (ret)
+			return ret;
+		thread->ptrace_bps[0] = bp;
+		thread->dabr = data;
+		return 0;
+	}
+
+	/* Create a new breakpoint request if one doesn't exist already */
+	hw_breakpoint_init(&attr);
+	attr.bp_addr = data & ~HW_BREAKPOINT_ALIGN;
+	arch_bp_generic_fields(data & (DABR_DATA_WRITE | DABR_DATA_READ),
+								&attr.bp_type);
+
+	thread->ptrace_bps[0] = bp = register_user_hw_breakpoint(&attr,
+							ptrace_triggered, task);
+	if (IS_ERR(bp)) {
+		thread->ptrace_bps[0] = NULL;
+		return PTR_ERR(bp);
+	}
+
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
 
 	/* Move contents to the DABR register */
 	task->thread.dabr = data;
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/process.c
===================================================================
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/process.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/process.c
@@ -459,8 +459,14 @@ struct task_struct *__switch_to(struct t
 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
 	switch_booke_debug_regs(&new->thread);
 #else
+/*
+ * For PPC_BOOK3S_64, we use the hw-breakpoint interfaces that would
+ * schedule DABR
+ */
+#ifndef CONFIG_HAVE_HW_BREAKPOINT
 	if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr))
 		set_dabr(new->thread.dabr);
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
 #endif
 
 
Index: linux-2.6.ppc64_test/arch/powerpc/include/asm/cputable.h
===================================================================
--- linux-2.6.ppc64_test.orig/arch/powerpc/include/asm/cputable.h
+++ linux-2.6.ppc64_test/arch/powerpc/include/asm/cputable.h
@@ -511,6 +511,10 @@ static inline int cpu_has_feature(unsign
 		& feature);
 }
 
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+#define HBP_NUM 1
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* __KERNEL__ */
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/machine_kexec_64.c
===================================================================
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/machine_kexec_64.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/machine_kexec_64.c
@@ -15,6 +15,7 @@
 #include <linux/thread_info.h>
 #include <linux/init_task.h>
 #include <linux/errno.h>
+#include <linux/hw_breakpoint.h>
 
 #include <asm/page.h>
 #include <asm/current.h>
@@ -161,6 +162,7 @@ void kexec_copy_flush(struct kimage *ima
  */
 static void kexec_smp_down(void *arg)
 {
+	hw_breakpoint_disable();
 	if (ppc_md.kexec_cpu_down)
 		ppc_md.kexec_cpu_down(0, 1);
 
@@ -174,6 +176,7 @@ static void kexec_prepare_cpus(void)
 	int my_cpu, i, notified=-1;
 
 	smp_call_function(kexec_smp_down, NULL, /* wait */0);
+	hw_breakpoint_disable();
 	my_cpu = get_cpu();
 
 	/* check the others cpus are now down (via paca hw cpu id == -1) */
Index: linux-2.6.ppc64_test/arch/powerpc/lib/Makefile
===================================================================
--- linux-2.6.ppc64_test.orig/arch/powerpc/lib/Makefile
+++ linux-2.6.ppc64_test/arch/powerpc/lib/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_PPC64)	+= copypage_64.o cop
 			   memcpy_64.o usercopy_64.o mem_64.o string.o
 obj-$(CONFIG_XMON)	+= sstep.o
 obj-$(CONFIG_KPROBES)	+= sstep.o
+obj-$(CONFIG_HAVE_HW_BREAKPOINT)	+= sstep.o
 
 ifeq ($(CONFIG_PPC64),y)
 obj-$(CONFIG_SMP)	+= locks.o
Index: linux-2.6.ppc64_test/include/linux/hw_breakpoint.h
===================================================================
--- linux-2.6.ppc64_test.orig/include/linux/hw_breakpoint.h
+++ linux-2.6.ppc64_test/include/linux/hw_breakpoint.h
@@ -120,6 +120,7 @@ static inline struct arch_hw_breakpoint 
 {
 	return NULL;
 }
+static inline void hw_breakpoint_disable(void) { }
 
 #endif /* CONFIG_HAVE_HW_BREAKPOINT */
 #endif /* __KERNEL__ */
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/traps.c
===================================================================
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/traps.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/traps.c
@@ -581,6 +581,9 @@ void __kprobes single_step_exception(str
  */
 static void emulate_single_step(struct pt_regs *regs)
 {
+	if (notify_die(DIE_SSTEP, "single_step", regs, 5,
+		       5, SIGTRAP) == NOTIFY_STOP)
+		return;
 	if (single_stepping(regs)) {
 		clear_single_step(regs);
 		_exception(SIGTRAP, regs, TRAP_TRACE, 0);

^ permalink raw reply

* [Patch 2/3] Allow arch-specific cleanup before breakpoint unregistration
From: K.Prasad @ 2010-05-12  3:33 UTC (permalink / raw)
  To: linuxppc-dev@ozlabs.org
  Cc: Michael Neuling, Benjamin Herrenschmidt, shaggy,
	Frederic Weisbecker, Linux Kernel Mailing List, David Gibson,
	paulus, Alan Stern, Ingo Molnar, K.Prasad, Roland McGrath
In-Reply-To: <20100512022527.857904312@linux.vnet.ibm.com>

Certain architectures (such as PowerPC Book III S) have a need to cleanup
data-structures before the breakpoint is unregistered. This patch introduces
an arch-specific hook in release_bp_slot() along with a weak definition in
the form of a stub funciton.

Signed-off-by: K.Prasad <prasad@linux.vnet.ibm.com>
---
 kernel/hw_breakpoint.c |   12 ++++++++++++
 1 file changed, 12 insertions(+)

Index: linux-2.6.ppc64_test/kernel/hw_breakpoint.c
===================================================================
--- linux-2.6.ppc64_test.orig/kernel/hw_breakpoint.c
+++ linux-2.6.ppc64_test/kernel/hw_breakpoint.c
@@ -203,6 +203,17 @@ static void toggle_bp_slot(struct perf_e
 }
 
 /*
+ * Function to perform processor-specific cleanup during unregistration
+ */
+__weak void arch_unregister_hw_breakpoint(struct perf_event *bp)
+{
+	/*
+	 * A weak stub function here for those archs that don't define
+	 * it inside arch/.../kernel/hw_breakpoint.c
+	 */
+}
+
+/*
  * Contraints to check before allowing this new breakpoint counter:
  *
  *  == Non-pinned counter == (Considered as pinned for now)
@@ -280,6 +291,7 @@ void release_bp_slot(struct perf_event *
 {
 	mutex_lock(&nr_bp_mutex);
 
+	arch_unregister_hw_breakpoint(bp);
 	__release_bp_slot(bp);
 
 	mutex_unlock(&nr_bp_mutex);

^ permalink raw reply

* [Patch 1/3] PPC64-HWBKPT: Disable interrupts for data breakpoint exceptions
From: K.Prasad @ 2010-05-12  3:32 UTC (permalink / raw)
  To: linuxppc-dev@ozlabs.org
  Cc: Michael Neuling, Benjamin Herrenschmidt, shaggy,
	Frederic Weisbecker, David Gibson, paulus, Alan Stern, K.Prasad,
	Roland McGrath
In-Reply-To: <20100512022527.857904312@linux.vnet.ibm.com>

Data address breakpoint exceptions are currently handled along with page-faults
which require interrupts to remain in enabled state. Since exception handling
for data breakpoints aren't pre-empt safe, we handle them separately.

Signed-off-by: K.Prasad <prasad@linux.vnet.ibm.com>
Acked-by: Paul Mackerras <paulus@samba.org>
---
 arch/powerpc/kernel/exceptions-64s.S |   13 ++++++++++++-
 arch/powerpc/mm/fault.c              |    5 +++--
 2 files changed, 15 insertions(+), 3 deletions(-)

Index: linux-2.6.ppc64_test/arch/powerpc/kernel/exceptions-64s.S
===================================================================
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/exceptions-64s.S
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/exceptions-64s.S
@@ -735,8 +735,11 @@ _STATIC(do_hash_page)
 	std	r3,_DAR(r1)
 	std	r4,_DSISR(r1)
 
-	andis.	r0,r4,0xa450		/* weird error? */
+	andis.	r0,r4,0xa410		/* weird error? */
 	bne-	handle_page_fault	/* if not, try to insert a HPTE */
+	andis.  r0,r4,DSISR_DABRMATCH@h
+	bne-    handle_dabr_fault
+
 BEGIN_FTR_SECTION
 	andis.	r0,r4,0x0020		/* Is it a segment table fault? */
 	bne-	do_ste_alloc		/* If so handle it */
@@ -823,6 +826,14 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISER
 	bl	.raw_local_irq_restore
 	b	11f
 
+/* We have a data breakpoint exception - handle it */
+handle_dabr_fault:
+	ld      r4,_DAR(r1)
+	ld      r5,_DSISR(r1)
+	addi    r3,r1,STACK_FRAME_OVERHEAD
+	bl      .do_dabr
+	b       .ret_from_except_lite
+
 /* Here we have a page fault that hash_page can't handle. */
 handle_page_fault:
 	ENABLE_INTS
Index: linux-2.6.ppc64_test/arch/powerpc/mm/fault.c
===================================================================
--- linux-2.6.ppc64_test.orig/arch/powerpc/mm/fault.c
+++ linux-2.6.ppc64_test/arch/powerpc/mm/fault.c
@@ -151,13 +151,14 @@ int __kprobes do_page_fault(struct pt_re
 	if (!user_mode(regs) && (address >= TASK_SIZE))
 		return SIGSEGV;
 
-#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
+#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE) || \
+			     defined(CONFIG_PPC_BOOK3S_64))
   	if (error_code & DSISR_DABRMATCH) {
 		/* DABR match */
 		do_dabr(regs, address, error_code);
 		return 0;
 	}
-#endif /* !(CONFIG_4xx || CONFIG_BOOKE)*/
+#endif
 
 	if (in_atomic() || mm == NULL) {
 		if (!user_mode(regs))

^ permalink raw reply

* [Patch 0/3] PPC64-HWBKPT: Hardware Breakpoint interfaces - ver XVIII
From: K.Prasad @ 2010-05-12  3:30 UTC (permalink / raw)
  To: linuxppc-dev@ozlabs.org
  Cc: Michael Neuling, Benjamin Herrenschmidt, shaggy,
	Frederic Weisbecker, David Gibson, paulus, Alan Stern,
	Roland McGrath

Hi Ben/Paul,
	Please find a new version of the patchset that implements hw-breakpoint
interfaces for PowerPC Book III S. The changes in this version over the previous
version are as listed below, and are the result of addressing comments 
received for the previous version.

Changelog - ver XVIII
--------------------
(Version XVII: linuxppc-dev ref: 20100414034340.GA6571@in.ibm.com)
- hw-breakpoint restoration variables are cleaned-up before unregistration
  through a new function hook arch_unregister_hw_breakpoint().
- emulate_single_step() now notifies DIE_SSTEP to registered handlers;
  causes single_step_dabr_instruction() to be invoked after alignment_exception.
- SIGTRAP is no longer generated for non-ptrace user-space breakpoints.
- Slight code restructuring for brevity and style corrections.

Kindly accept them to be a part of -next tree.

Thanks,
K.Prasad

Changelog - ver XVII
--------------------
(Version XVI: linuxppc-dev ref: 20100330095809.GA14403@in.ibm.com)
- CONFIG_HAVE_HW_BREAKPOINT is now used to define the scope of the new code
  (in lieu of CONFIG_PPC_BOOK3S_64).
- CONFIG_HAVE_HW_BREAKPOINT is now dependant upon CONFIG_PERF_EVENTS and
  CONFIG_PPC_BOOK3S_64 (to overcome build failures under certain configs).
- Included a target in arch/powerpc/lib/Makefile to build sstep.o when
  HAVE_HW_BREAKPOINT.
- Added a dummy definition for hw_breakpoint_disable() when !HAVE_HW_BREAKPOINT.
- Tested builds under defconfigs for ppc64, cell and g5 (found no patch induced
  failures).

Changelog - ver XVI
--------------------
(Version XV: linuxppc-dev ref: 20100323140639.GA21836@in.ibm.com)
- Used a new config option CONFIG_PPC_BOOK3S_64 (in lieu of
  CONFIG_PPC64/CPU_FTR_HAS_DABR) to limit the scope of the new code.
- Disabled breakpoints before kexec of the machine using hw_breakpoint_disable().
- Minor optimisation in exception-64s.S to check for data breakpoint exceptions
  in DSISR finally (after check for other causes) + changes in code comments and 
  representation of DSISR_DABRMATCH constant.
- Rebased to commit ae6be51ed01d6c4aaf249a207b4434bc7785853b of linux-2.6.

Changelog - ver XV
--------------------
(Version XIV: linuxppc-dev ref: 20100308181232.GA3406@in.ibm.com)

- Additional patch to disable interrupts during data breakpoint exception
  handling.
- Moved HBP_NUM definition to cputable.h under a new CPU_FTR definition
  (CPU_FTR_HAS_DABR).
- Filtering of extraneous exceptions (due to accesses outside symbol length) is
  by-passed for ptrace requests.
- Removed flush_ptrace_hw_breakpoint() from __switch_to() due to incorrect
  coding placement.
- Changes to code comments as per community reviews for previous version.
- Minor coding-style changes in hw_breakpoint.c as per review comments.
- Re-based to commit ae6be51ed01d6c4aaf249a207b4434bc7785853b of linux-2.6

Changelog - ver XIV
--------------------
(Version XIII: linuxppc-dev ref: 20100215055605.GB3670@in.ibm.com)

- Removed the 'name' field from 'struct arch_hw_breakpoint'.
- All callback invocations through bp->overflow_handler() are replaced with
  perf_bp_event().
- Removed the check for pre-existing single-stepping mode in
  hw_breakpoint_handler() as this check is unreliable while in kernel-space.
  Side effect of this change is the non-triggering of hw-breakpoints while
  single-stepping kernel through KGDB or Xmon.
- Minor code-cleanups and addition of comments in hw_breakpoint_handler() and
  single_step_dabr_instruction().
- Re-based to commit 25cf84cf377c0aae5dbcf937ea89bc7893db5176 of linux-2.6

Changelog - ver XIII
--------------------
(Version XII: linuxppc-dev ref: 20100121084640.GA3252@in.ibm.com)

- Fixed a bug for user-space breakpoints (triggered following the failure of a
  breakpoint request).
- Re-based on commit 724e6d3fe8003c3f60bf404bf22e4e331327c596 of linux-2.6
  
Changelog - ver XII
--------------------
(Version XI: linuxppc-dev ref: 20100119091234.GA9971@in.ibm.com)

- Unset MSR_SE only if kernel was not previously in single-step mode.
- Pre-emption is now enabled before returning from the hw-breakpoint exception
  handler.
- Variables to track the source of single-step exception (breakpoint from kernel,
  user-space vs single-stepping due to other requests) are added.
- Extraneous hw-breakpoint exceptions (due to memory accesses lying outside
  monitored symbol length) is now done for both kernel and user-space
  (previously only user-space).
- single_step_dabr_instruction() now returns NOTIFY_DONE if kernel was in
  single-step mode even before the hw-breakpoint. This enables other users of
  single-step mode to be notified of the exception.
- User-space instructions are not emulated from kernel-space, they are instead
  single-stepped.
  
Changelog - ver XI
------------------
(Version X: linuxppc-dev ref: 20091211160144.GA23156@in.ibm.com)
- Conditionally unset MSR_SE in the single-step handler
- Added comments to explain the duration and need for pre-emption
disable following hw-breakpoint exception.

Changelog - ver X
------------------
- Re-write the PPC64 patches for the new implementation of hw-breakpoints that
  uses the perf-layer.
- Rebased to commit 7622fc234190a37d4e9fe3ed944a2b61a63fca03 of -tip.

Changelog - ver IX
-------------------
- Invocation of user-defined callback will be 'trigger-after-execute' (except
  for ptrace).
- Creation of a new global per-CPU breakpoint structure to help invocation of
  user-defined callback from single-step handler.
(Changes made now)
- Validation before registration will fail only if the address does not match
  the kernel symbol's (if specified) resolved address
  (through kallsyms_lookup_name()).
- 'symbolsize' value is expected to within the range contained by the symbol's
  starting address and the end of a double-word boundary (8 Bytes).
- PPC64's arch-dependant code is now aware of 'cpumask' in 'struct hw_breakpoint'
  and can accomodate requests for a subset of CPUs in the system.
- Introduced arch_disable_hw_breakpoint() required for
  <enable><disable>_hw_breakpoint() APIs.

Changelog - ver VIII
-------------------
- Reverting changes to allow one-shot breakpoints only for ptrace requests.
- Minor changes in sanity checking in arch_validate_hwbkpt_settings().
- put_cpu_no_resched() is no longer available. Converted to put_cpu().

Changelog - ver VII
-------------------
- Allow the one-shot behaviour for exception handlers to be defined by the user.
  A new 'is_one_shot' flag is added to 'struct arch_hw_breakpoint'.

Changelog - ver VI
------------------
The task of identifying 'genuine' breakpoint exceptions from those caused by
'out-of-range' accesses turned out to be more tricky than originally thought.
Some changes to this effect were made in version IV of this patchset, but they
were not sufficient for user-space. Basically the breakpoint address received
through ptrace is always aligned to 8-bytes since ptrace receives an encoded
'data' (consisting of address | translation_enable | bkpt_type), and the size of
the symbol is not known. However for kernel-space addresses, the symbol-size can
be determined using kallsyms_lookup_size_offset() and this is used to check if
DAR (in the exception context) is
'bkpt_address <= DAR <= (bkpt_address + symbol_size)', failing which we conclude
it as a stray exception.

The following changes are made to enable check:
- Addition of a symbolsize field in 'struct arch_hw_breakpoint' field.
- Store the size of the 'watched' kernel symbol into 'symbolsize' field in
  arch_store_info(0 routine.
- Verify if the above described condition is true when is_one_shot is FALSE in
  hw_breakpoint_handler().

Changelog - ver V
------------------
- Breakpoint requests from ptrace (for user-space) are designed to be one-shot
in PPC64. The patch contains changes to retain this behaviour by returning early
in hw_breakpoint_handler() [without re-initialising DABR] and unregistering the
user-space request in ptrace_triggered(). It is safe to make a
unregister_user_hw_breakpoint() call from the breakpoint exception context
[through ptrace_triggered()] without giving rise to circular locking-dependancy.
This is because there can be no kernel code running on the CPU (which received
the exception) with the same spinlock held.

- Minor change in 'type' member of 'struct arch_hw_breakpoint' from u8 to 'int'.

Changelog - ver IV
------------------
- While DABR register requires double-word (8 bytes) aligned addresses, i.e.
the breakpoint is active over a range of 8 bytes, PPC64 allows byte-level
addressability. This may lead to stray exceptions which have to be ignored in
hw_breakpoint_handler(), when DAR != (Breakpoint request address). However DABR
will be populated with the requested breakpoint address aligned to the previous
double-word address. The code is now modified to store user-requested address
in 'bp->info.address' but update the DABR with a double-word aligned address.

- Please note that the Data Breakpoint facility in Xmon is broken as of 2.6.29
and the same has not been integrated into this facility as described in Ver I.

Changelog - ver III
------------------
- Patches are based on commit 08f16e060bf54bdc34f800ed8b5362cdeda75d8b of -tip
tree.

- The declarations in arch/powerpc/include/asm/hw_breakpoint.h are done only if
CONFIG_PPC64 is defined. This eliminates the need to conditionally include this
header file.

- load_debug_registers() is done in start_secondary() i.e. during CPU
initialisation.

- arch_check_va_<> routines in hw_breakpoint.c are now replaced with a much
simpler is_kernel_addr() check in arch_validate_hwbkpt_settings()

- Return code of hw_breakpoint_handler() when triggered due to Lazy debug
register switching is now changed to NOTIFY_STOP.

- The ptrace code no longer sets the TIF_DEBUG task flag as it is proposed to
be done in register_user_hw_breakpoint() routine.

- hw_breakpoint_handler() is now modified to use hbp_kernel_pos value to
  determine if the trigger was a user/kernel space address. The DAR register
  value is checked with the address stored in 'struct hw_breakpoint' to avoid
  handling of exceptions that belong to kprobe/Xmon.


Changelog - ver II
------------------
- Split the monolithic patch into six logical patches

- Changed the signature of arch_check_va_in_<user><kernel>space functions. They
  are now marked static.

- HB_NUM is now called as HBP_NUM (to preserve a consistent short-name
  convention)

- Introduced hw_breakpoint_disable() and changes to kexec code to disable
  breakpoints before a reboot.
  
- Minor changes in ptrace code to use macro-defined constants instead of
  numbers.

- Introduced a new constant definition INSTRUCTION_LEN in reg.h

^ permalink raw reply

* Re: 440SPe/Katmai PCIe problems
From: Benjamin Herrenschmidt @ 2010-05-12  3:02 UTC (permalink / raw)
  To: Stefan Roese; +Cc: linuxppc-dev, Pravin Bathija
In-Reply-To: <1273632013.21352.88.camel@pasglop>

On Wed, 2010-05-12 at 12:40 +1000, Benjamin Herrenschmidt wrote:
> Hi Stefan !
> 
> (Or somebody from AMCC)
> 
> I noticed we still have this old problem on PCIe where some cards don't
> seem to work. The link trains but they don't respond on config space.
> This is the case for example of that Sunix quad USB card. It seems to be
> related to the kind of TI PCIe <-> PCI bridge on these though.
> 
> Have anybody tracked down the root cause of the problem ? Some say that
> it could be that the bridge doesn't cope with the double reset (uboot
> then kernel). Would it be possible to tell uboot to avoid touching the
> PCIe interface completely so the kernel is the first one to get in ?

Actually... the card works in the Canyonlands using the latest u-boot
from ftp.denx.de (u-boot-nand.bin-2009.11.1), though interestingly
enough, this u-boot fails to detect an XGI Z11 video card that I have,
whichever slot I put it in.

in fact, the kernel itself detects the card and times out trying to get
a link. It works with whatever u-boot I used to have in there (and no
longer do ... oops :-)

Cheers,
Ben.

^ permalink raw reply

* Re: [PATCH] kexec-tools, ppc64: Fix segfault parsing DR memory property
From: Michael Neuling @ 2010-05-12  2:50 UTC (permalink / raw)
  To: Matt Evans; +Cc: linuxppc-dev, horms, kexec
In-Reply-To: <4BE9102C.6040404@axio.ms>



In message <4BE9102C.6040404@axio.ms> you wrote:
> 
> add_dyn_reconf_usable_mem_property() iterates over memory spans
> in /ibm,dynamic-reconfiguration-memory/ibm,dynamic-memory and intersects
> these with usablemem_rgns ranges.  Not only did it seem to write
> null properties for every range that didn't match, but it used an unchecked
> fixed-size array which will overrun on machines with lots of LMBs.
> 
> This patch stops add_dyn_reconf_usable_mem_property() from adding null ranges
> to the linux,drconf-usable-memory property and removes its fixed-size array,
> as well as the array in add_usable_mem_property, in lieu of malloc/realloc/fr
ee.
> 

Thanks matt!

Acked-by: Michael Neuling <mikey@neuling.org>


> Signed-off-by: Matt Evans <matt@ozlabs.org>
> ---
>  kexec/arch/ppc64/fs2dt.c |   66 +++++++++++++++++++++++++++++++++++++-------
-
>  1 files changed, 54 insertions(+), 12 deletions(-)
> 
> diff --git a/kexec/arch/ppc64/fs2dt.c b/kexec/arch/ppc64/fs2dt.c
> index 762bf04..7470132 100644
> --- a/kexec/arch/ppc64/fs2dt.c
> +++ b/kexec/arch/ppc64/fs2dt.c
> @@ -37,7 +37,7 @@
>  #define NAMESPACE 16384		/* max bytes for property names */
>  #define INIT_TREE_WORDS 65536	/* Initial num words for prop values */
>  #define MEMRESERVE 256		/* max number of reserved memory blocks
 */
> -#define MAX_MEMORY_RANGES 1024
> +#define MEM_RANGE_CHUNK_SZ 2048 /* Initial num dwords for mem ranges */
>  
>  static char pathname[MAXPATH], *pathstart;
>  static char propnames[NAMESPACE] = { 0 };
> @@ -148,7 +148,8 @@ static void add_dyn_reconf_usable_mem_property(int fd)
>  {
>  	char fname[MAXPATH], *bname;
>  	uint64_t buf[32];
> -	uint64_t ranges[2*MAX_MEMORY_RANGES];
> +	uint64_t *ranges;
> +	int ranges_size = MEM_RANGE_CHUNK_SZ;
>  	uint64_t base, end, loc_base, loc_end;
>  	size_t i, rngs_cnt, range;
>  	int rlen = 0;
> @@ -165,6 +166,11 @@ static void add_dyn_reconf_usable_mem_property(int fd)
>  		die("unrecoverable error: error seeking in \"%s\": %s\n",
>  			pathname, strerror(errno));
>  
> +	ranges = malloc(ranges_size*8);
> +	if (!ranges)
> +		die("unrecoverable error: can't alloc %d bytes for ranges.\n",
> +		    ranges_size*8);
> +
>  	rlen = 0;
>  	for (i = 0; i < num_of_lmbs; i++) {
>  		if (read(fd, buf, 24) < 0)
> @@ -180,24 +186,41 @@ static void add_dyn_reconf_usable_mem_property(int fd)
>  
>  		rngs_cnt = 0;
>  		for (range = 0; range < usablemem_rgns.size; range++) {
> +			int add = 0;
>  			loc_base = usablemem_rgns.ranges[range].start;
>  			loc_end = usablemem_rgns.ranges[range].end;
>  			if (loc_base >= base && loc_end <= end) {
> -				ranges[rlen++] = loc_base;
> -				ranges[rlen++] = loc_end - loc_base;
> -				rngs_cnt++;
> +				add = 1;
>  			} else if (base < loc_end && end > loc_base) {
>  				if (loc_base < base)
>  					loc_base = base;
>  				if (loc_end > end)
>  					loc_end = end;
> +				add = 1;
> +			}
> +
> +			if (add) {
> +				if (rlen >= (ranges_size-2)) {
> +					ranges_size += MEM_RANGE_CHUNK_SZ;
> +					ranges = realloc(ranges, ranges_size*8)
;
> +					if (!ranges)
> +						die("unrecoverable error: can't
"
> +						    " realloc %d bytes for"
> +						    " ranges.\n",
> +						    ranges_size*8);
> +				}
>  				ranges[rlen++] = loc_base;
>  				ranges[rlen++] = loc_end - loc_base;
>  				rngs_cnt++;
>  			}
>  		}
> -		/* Store the count of (base, size) duple */
> -		ranges[tmp_indx] = rngs_cnt;
> +		if (rngs_cnt == 0) {
> +			/* Don't store anything for unwritten iterations! */
> +			rlen = tmp_indx;
> +		} else {
> +			/* Store the count of (base, size) duple */
> +			ranges[tmp_indx] = rngs_cnt;
> +		}
>  	}
>  		
>  	rlen = rlen * sizeof(uint64_t);
> @@ -210,7 +233,8 @@ static void add_dyn_reconf_usable_mem_property(int fd)
>  	*dt++ = propnum("linux,drconf-usable-memory");
>  	if ((rlen >= 8) && ((unsigned long)dt & 0x4))
>  		dt++;
> -	memcpy(dt, &ranges, rlen);
> +	memcpy(dt, ranges, rlen);
> +	free(ranges);
>  	dt += (rlen + 3)/4;
>  }
>  
> @@ -218,7 +242,8 @@ static void add_usable_mem_property(int fd, size_t len)
>  {
>  	char fname[MAXPATH], *bname;
>  	uint64_t buf[2];
> -	uint64_t ranges[2*MAX_MEMORY_RANGES];
> +	uint64_t *ranges;
> +	int ranges_size = MEM_RANGE_CHUNK_SZ;
>  	uint64_t base, end, loc_base, loc_end;
>  	size_t range;
>  	int rlen = 0;
> @@ -247,17 +272,33 @@ static void add_usable_mem_property(int fd, size_t len)
>  	base = buf[0];
>  	end = base + buf[1];
>  
> +	ranges = malloc(ranges_size*8);
> +	if (!ranges)
> +		die("unrecoverable error: can't alloc %d bytes for ranges.\n",
> +		    ranges_size*8);
> +
>  	for (range = 0; range < usablemem_rgns.size; range++) {
> +		int add = 0;
>  		loc_base = usablemem_rgns.ranges[range].start;
>  		loc_end = usablemem_rgns.ranges[range].end;
>  		if (loc_base >= base && loc_end <= end) {
> -			ranges[rlen++] = loc_base;
> -			ranges[rlen++] = loc_end - loc_base;
> +			add = 1;
>  		} else if (base < loc_end && end > loc_base) {
>  			if (loc_base < base)
>  				loc_base = base;
>  			if (loc_end > end)
>  				loc_end = end;
> +			add = 1;
> +		}
> +		if (add) {
> +			if (rlen >= (ranges_size-2)) {
> +				ranges_size += MEM_RANGE_CHUNK_SZ;
> +				ranges = realloc(ranges, ranges_size*8);
> +				if (!ranges) 
> +					die("unrecoverable error: can't realloc
"
> +					    "%d bytes for ranges.\n",
> +					    ranges_size*8);
> +			}
>  			ranges[rlen++] = loc_base;
>  			ranges[rlen++] = loc_end - loc_base;
>  		}
> @@ -283,7 +324,8 @@ static void add_usable_mem_property(int fd, size_t len)
>  	*dt++ = propnum("linux,usable-memory");
>  	if ((rlen >= 8) && ((unsigned long)dt & 0x4))
>  		dt++;
> -	memcpy(dt,&ranges,rlen);
> +	memcpy(dt, ranges, rlen);
> +	free(ranges);
>  	dt += (rlen + 3)/4;
>  }
>  
> -- 
> 1.6.3.3
> 
> 
> _______________________________________________
> kexec mailing list
> kexec@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec
> 

^ permalink raw reply

* 440SPe/Katmai PCIe problems
From: Benjamin Herrenschmidt @ 2010-05-12  2:40 UTC (permalink / raw)
  To: Stefan Roese; +Cc: linuxppc-dev, Pravin Bathija

Hi Stefan !

(Or somebody from AMCC)

I noticed we still have this old problem on PCIe where some cards don't
seem to work. The link trains but they don't respond on config space.
This is the case for example of that Sunix quad USB card. It seems to be
related to the kind of TI PCIe <-> PCI bridge on these though.

Have anybody tracked down the root cause of the problem ? Some say that
it could be that the bridge doesn't cope with the double reset (uboot
then kernel). Would it be possible to tell uboot to avoid touching the
PCIe interface completely so the kernel is the first one to get in ?

Cheers,
Ben.

^ permalink raw reply

* [PATCH] Fix UART clocks on 440SPe
From: Benjamin Herrenschmidt @ 2010-05-12  2:22 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Stefan Roese

The code to fixup the serial ports on 440SPe uses the incorrect
addresses for these. This fixes it.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

I'm surprised nobody noticed, serial is pretty busted for me without
that patch :-)

diff --git a/arch/powerpc/boot/4xx.c b/arch/powerpc/boot/4xx.c
index 27db893..627de25 100644
--- a/arch/powerpc/boot/4xx.c
+++ b/arch/powerpc/boot/4xx.c
@@ -544,9 +544,9 @@ void ibm440spe_fixup_clocks(unsigned int sys_clk,
 	unsigned int plb_clk = __ibm440eplike_fixup_clocks(sys_clk, tmr_clk, 1);
 
 	/* serial clocks beed fixup based on int/ext */
-	eplike_fixup_uart_clk(0, "/plb/opb/serial@10000200", ser_clk, plb_clk);
-	eplike_fixup_uart_clk(1, "/plb/opb/serial@10000300", ser_clk, plb_clk);
-	eplike_fixup_uart_clk(2, "/plb/opb/serial@10000600", ser_clk, plb_clk);
+	eplike_fixup_uart_clk(0, "/plb/opb/serial@f0000200", ser_clk, plb_clk);
+	eplike_fixup_uart_clk(1, "/plb/opb/serial@f0000300", ser_clk, plb_clk);
+	eplike_fixup_uart_clk(2, "/plb/opb/serial@f0000600", ser_clk, plb_clk);
 }
 
 void ibm405gp_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk)

^ permalink raw reply related

* Re: [PATCH 2/2] powerpc,kexec: Speedup kexec hpte tear down
From: Michael Ellerman @ 2010-05-12  1:36 UTC (permalink / raw)
  To: Michael Neuling; +Cc: kexec, Paul Mackerras, Anton Blanchard, linuxppc-dev
In-Reply-To: <9537.1273626418@neuling.org>

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

On Wed, 2010-05-12 at 11:06 +1000, Michael Neuling wrote:
> > > We probably only do the remove on < 1% of the hptes now.  So I doubt we
> > > would get a speedup since most of the time we aren't do the remove
> > > anymore.
> > 
> > It would be nice to have some actual numbers.  Could you add some
> > counters and print the results at the end?  (Or don't you have any
> > way to print things at that stage?)
> 
> Printing is hard at that point but I think we can do it.  I'll try to
> when I get some time.

A version of udbg_putcLP() that uses a raw hcall should work, or there
was code added to purgatory recently to print to the HV console which
you could nick.

> A heavily loaded system which kdumps will need a lot more hptes removes
> than kexec, so stats for both these cases might be useful also.

Yeah, or even a system that is kexec'ed while lots of stuff is still
running.

cheers



[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply

* Re: [PATCH 2/2] powerpc,kexec: Speedup kexec hpte tear down
From: Michael Neuling @ 2010-05-12  1:06 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev, kexec, Anton Blanchard
In-Reply-To: <20100512010003.GB3548@drongo>

> > We probably only do the remove on < 1% of the hptes now.  So I doubt we
> > would get a speedup since most of the time we aren't do the remove
> > anymore.
> 
> It would be nice to have some actual numbers.  Could you add some
> counters and print the results at the end?  (Or don't you have any
> way to print things at that stage?)

Printing is hard at that point but I think we can do it.  I'll try to
when I get some time.

A heavily loaded system which kdumps will need a lot more hptes removes
than kexec, so stats for both these cases might be useful also.

Mikey

^ permalink raw reply

* Re: [PATCH 2/2] powerpc,kexec: Speedup kexec hpte tear down
From: Paul Mackerras @ 2010-05-12  1:00 UTC (permalink / raw)
  To: Michael Neuling; +Cc: linuxppc-dev, kexec, Anton Blanchard
In-Reply-To: <7247.1273624988@neuling.org>

On Wed, May 12, 2010 at 10:43:08AM +1000, Michael Neuling wrote:

> We probably only do the remove on < 1% of the hptes now.  So I doubt we
> would get a speedup since most of the time we aren't do the remove
> anymore.

It would be nice to have some actual numbers.  Could you add some
counters and print the results at the end?  (Or don't you have any
way to print things at that stage?)

Paul.

^ permalink raw reply

* Re: [PATCH 2/2] powerpc,kexec: Speedup kexec hpte tear down
From: Michael Neuling @ 2010-05-12  0:43 UTC (permalink / raw)
  To: michael; +Cc: kexec, Anton Blanchard, linuxppc-dev
In-Reply-To: <1273624565.5738.8.camel@concordia>



In message <1273624565.5738.8.camel@concordia> you wrote:
> 
> --=-wnrJa93KBardFtse2eHB
> Content-Type: text/plain; charset="UTF-8"
> Content-Transfer-Encoding: quoted-printable
> 
> On Wed, 2010-05-12 at 09:29 +1000, Michael Neuling wrote:
> >=20
> > In message <1273561463.9209.138.camel@concordia> you wrote:
> > >=20
> > > --=3D-S056dRzmrEHDBzKyyTOs
> > > Content-Type: text/plain; charset=3D"UTF-8"
> > > Content-Transfer-Encoding: quoted-printable
> > >=20
> > > On Tue, 2010-05-11 at 16:28 +1000, Michael Neuling wrote:
> > > > Currently for kexec the PTE tear down on 1TB segment systems normally
> > > > requires 3 hcalls for each PTE removal. On a machine with 32GB of
> > > > memory it can take around a minute to remove all the PTEs.
> > > >=3D20
> > > ..
> > > > -	/* TODO: Use bulk call */
> > >=20
> > > ...
> > > > +	/* Read in batches of 4,
> > > > +	 * invalidate only valid entries not in the VRMA
> > > > +	 * hpte_count will be a multiple of 4
> > > > +         */
> > > > +	for (i =3D3D 0; i < hpte_count; i +=3D3D 4) {
> > > > +		lpar_rc =3D3D plpar_pte_read_4_raw(0, i, (void *)ptes);
> > > > +		if (lpar_rc !=3D3D H_SUCCESS)
> > > > +			continue;
> > > > +		for (j =3D3D 0; j < 4; j++){
> > > > +			if ((ptes[j].pteh & HPTE_V_VRMA_MASK) =3D3D=3D3
D
> > > > +				HPTE_V_VRMA_MASK)
> > > > +				continue;
> > > > +			if (ptes[j].pteh & HPTE_V_VALID)
> > > > +				plpar_pte_remove_raw(0, i + j, 0,
> > > > +					&(ptes[j].pteh), &(ptes[j].ptel
));
> > > >  		}
> > >=20
> > > Have you tried using the bulk remove call, if none of the HPTEs are for
> > > the VRMA? Rumour was it was slower/the-same, but that may have been
> > > apocryphal.
> >=20
> > No, I didn't try it.
> >=20
> > I think the real solution is to ask FW for a new call to do it all for
> > us.
> 
> Sure, you could theoretically still get a 4x speedup though by using the
> bulk remove.

We probably only do the remove on < 1% of the hptes now.  So I doubt we
would get a speedup since most of the time we aren't do the remove
anymore.

Mikey

^ permalink raw reply

* Re: [PATCH 2/2] powerpc,kexec: Speedup kexec hpte tear down
From: Michael Ellerman @ 2010-05-12  0:36 UTC (permalink / raw)
  To: Michael Neuling; +Cc: kexec, Anton Blanchard, linuxppc-dev
In-Reply-To: <30983.1273620594@neuling.org>

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

On Wed, 2010-05-12 at 09:29 +1000, Michael Neuling wrote:
> 
> In message <1273561463.9209.138.camel@concordia> you wrote:
> > 
> > --=-S056dRzmrEHDBzKyyTOs
> > Content-Type: text/plain; charset="UTF-8"
> > Content-Transfer-Encoding: quoted-printable
> > 
> > On Tue, 2010-05-11 at 16:28 +1000, Michael Neuling wrote:
> > > Currently for kexec the PTE tear down on 1TB segment systems normally
> > > requires 3 hcalls for each PTE removal. On a machine with 32GB of
> > > memory it can take around a minute to remove all the PTEs.
> > >=20
> > ..
> > > -	/* TODO: Use bulk call */
> > 
> > ...
> > > +	/* Read in batches of 4,
> > > +	 * invalidate only valid entries not in the VRMA
> > > +	 * hpte_count will be a multiple of 4
> > > +         */
> > > +	for (i =3D 0; i < hpte_count; i +=3D 4) {
> > > +		lpar_rc =3D plpar_pte_read_4_raw(0, i, (void *)ptes);
> > > +		if (lpar_rc !=3D H_SUCCESS)
> > > +			continue;
> > > +		for (j =3D 0; j < 4; j++){
> > > +			if ((ptes[j].pteh & HPTE_V_VRMA_MASK) =3D=3D
> > > +				HPTE_V_VRMA_MASK)
> > > +				continue;
> > > +			if (ptes[j].pteh & HPTE_V_VALID)
> > > +				plpar_pte_remove_raw(0, i + j, 0,
> > > +					&(ptes[j].pteh), &(ptes[j].ptel));
> > >  		}
> > 
> > Have you tried using the bulk remove call, if none of the HPTEs are for
> > the VRMA? Rumour was it was slower/the-same, but that may have been
> > apocryphal.
> 
> No, I didn't try it.
> 
> I think the real solution is to ask FW for a new call to do it all for
> us.

Sure, you could theoretically still get a 4x speedup though by using the
bulk remove.

cheers

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply

* Re: [PATCH 2/2] powerpc,kexec: Speedup kexec hpte tear down
From: Michael Neuling @ 2010-05-11 23:29 UTC (permalink / raw)
  To: michael; +Cc: kexec, Anton Blanchard, linuxppc-dev
In-Reply-To: <1273561463.9209.138.camel@concordia>



In message <1273561463.9209.138.camel@concordia> you wrote:
> 
> --=-S056dRzmrEHDBzKyyTOs
> Content-Type: text/plain; charset="UTF-8"
> Content-Transfer-Encoding: quoted-printable
> 
> On Tue, 2010-05-11 at 16:28 +1000, Michael Neuling wrote:
> > Currently for kexec the PTE tear down on 1TB segment systems normally
> > requires 3 hcalls for each PTE removal. On a machine with 32GB of
> > memory it can take around a minute to remove all the PTEs.
> >=20
> ..
> > -	/* TODO: Use bulk call */
> 
> ...
> > +	/* Read in batches of 4,
> > +	 * invalidate only valid entries not in the VRMA
> > +	 * hpte_count will be a multiple of 4
> > +         */
> > +	for (i =3D 0; i < hpte_count; i +=3D 4) {
> > +		lpar_rc =3D plpar_pte_read_4_raw(0, i, (void *)ptes);
> > +		if (lpar_rc !=3D H_SUCCESS)
> > +			continue;
> > +		for (j =3D 0; j < 4; j++){
> > +			if ((ptes[j].pteh & HPTE_V_VRMA_MASK) =3D=3D
> > +				HPTE_V_VRMA_MASK)
> > +				continue;
> > +			if (ptes[j].pteh & HPTE_V_VALID)
> > +				plpar_pte_remove_raw(0, i + j, 0,
> > +					&(ptes[j].pteh), &(ptes[j].ptel));
> >  		}
> 
> Have you tried using the bulk remove call, if none of the HPTEs are for
> the VRMA? Rumour was it was slower/the-same, but that may have been
> apocryphal.

No, I didn't try it.

I think the real solution is to ask FW for a new call to do it all for
us.

Mikey

^ permalink raw reply

* Problem setting link_address too high on PowerPC 40x
From: David Baird @ 2010-05-11 22:48 UTC (permalink / raw)
  To: linuxppc-dev

Hi,

I am working with the PowerPC 405 in the Virtex-II Pro FPGA.  I've
come across a possible problem where the device tree is located in at
an address that the kernel cannot access if link_address (the location
where zImage executes from, set in the "wrapper" script) is set too
high (somewhere in the ballpark of 16 MB).  Here is a summary of the
problem:

In arch/powerpc/boot/main.c, ft_addr (a pointer to the flat? device
tree) is computed and then passed on to "kentry" to the kernel startup
code.  At startup, the kernel only has access via the TLB to the first
16 MB of memory which is initialized by "initial_imu" in
arch/powerpc/kernel/head_40x.S.  The problem is that ft_addr is
located relative to link_address / zImage, but this address might be
outside of the bounds of the 16MB initially mapped by the TLB.

A symptom of this problem is that the kernel ceases to print any
messages to the console because it could not read information about
the console from the flat device tree.  The last thing the user will
see is this:

zImage starting: loaded at 0x04000000 (sp: 0x0430beb0)
Allocating 0x6f11b0 bytes for kernel ...
gunzipping (0x00000000 <- 0x0400c000:0x0430a31a)...done 0x657000 bytes

Linux/PowerPC load: console=ttyUL0 root=/dev/ram
Finalizing device tree... flat tree at 0x4318300

...and then the screen goes completely blank...  And it seems that the
kernel also eventually crashes (but I couldn't tell exactly what
happened because __log_buf repeatedly gets corrupted with zeros
whenever I try this particular experiment).

Maybe there is also more to this problem too than just the ft_addr.

-David

^ permalink raw reply

* Re: [PATCH] powerpc: eeh: Fix oops when probing in early boot
From: Brian King @ 2010-05-11 19:39 UTC (permalink / raw)
  To: linasvepstas; +Cc: mikey, linuxppc-dev, Anton Blanchard, mmlnx, leitao
In-Reply-To: <AANLkTinvdNU48u9RcNznXYQJQqTRlBuV4DmJVTwxSqaI@mail.gmail.com>

The needs_freset bit went in since the last time I touched
all this code, so I don't think this will affect ipr at least.
The way this works for the ipr adapters we needed a warm reset
for was, we would get the hot reset in the generic EEH code, the
the ipr driver would come along after that and issue a warm
reset to get the adapter in a usable state. Now that the needs_freset
feature is there, we could set that in ipr for the adapters we need
a warm reset for and get rid of the useless hot reset.

A quick grep through the code shows that qlogic is the one user of this
feature. 

How early is this? I assume this is pre driver load time, in which
case even if we could check the flag it wouldn't be set yet...

Thanks,

Brian


On 05/11/2010 01:59 PM, Linas Vepstas wrote:
> On 10 May 2010 20:38, Anton Blanchard <anton@samba.org> wrote:
>>
>> If we take an EEH early enough, we oops:
>>
>> 
>> Call Trace:
>> [c000000010483770] [c000000000013ee4] .show_stack+0xd8/0x218 (unreliable)
>> [c000000010483850] [c000000000658940] .dump_stack+0x28/0x3c
>> [c0000000104838d0] [c000000000057a68] .eeh_dn_check_failure+0x2b8/0x304
>> [c000000010483990] [c0000000000259c8] .rtas_read_config+0x120/0x168
>> [c000000010483a40] [c000000000025af4] .rtas_pci_read_config+0xe4/0x124
>> [c000000010483af0] [c00000000037af18] .pci_bus_read_config_word+0xac/0x104
>> [c000000010483bc0] [c0000000008fec98] .pcibios_allocate_resources+0x7c/0x220
>> [c000000010483c90] [c0000000008feed8] .pcibios_resource_survey+0x9c/0x418
>> [c000000010483d80] [c0000000008fea10] .pcibios_init+0xbc/0xf4
>> [c000000010483e20] [c000000000009844] .do_one_initcall+0x98/0x1d8
>> [c000000010483ed0] [c0000000008f0560] .kernel_init+0x228/0x2e8
>> [c000000010483f90] [c000000000031a08] .kernel_thread+0x54/0x70
>> EEH: Detected PCI bus error on device <null>
>> EEH: This PCI device has failed 1 times in the last hour:
>> EEH: location=U78A5.001.WIH8464-P1 driver= pci addr=0001:00:01.0
>> EEH: of node=/pci@800000020000209/usb@1
>> EEH: PCI device/vendor: 00351033
>> EEH: PCI cmd/status register: 12100146
>>
>> Unable to handle kernel paging request for data at address 0x00000468
>> Oops: Kernel access of bad area, sig: 11 [#1]
>> ....
>> NIP [c000000000057610] .rtas_set_slot_reset+0x38/0x10c
>> LR [c000000000058724] .eeh_reset_device+0x5c/0x124
>> Call Trace: 
>> [c00000000bc6bd00] [c00000000005a0e0] .pcibios_remove_pci_devices+0x7c/0xb0 (unreliable)
>> [c00000000bc6bd90] [c000000000058724] .eeh_reset_device+0x5c/0x124
>> [c00000000bc6be40] [c0000000000589c0] .handle_eeh_events+0x1d4/0x39c
>> [c00000000bc6bf00] [c000000000059124] .eeh_event_handler+0xf0/0x188
>> [c00000000bc6bf90] [c000000000031a08] .kernel_thread+0x54/0x70
>>
>>
>> We called rtas_set_slot_reset while scanning the bus and before the pci_dn
>> to pcidev mapping has been created. Since we only need the pcidev to work
>> out the type of reset and that only gets set after the module for the
>> device loads, lets just do a hot reset if the pcidev is NULL.
>>
>> Signed-off-by: Anton Blanchard <anton@samba.org>
>> ---
> 
> 
> Acked-by: Linas Vepstas <linasvepstas@gmail.com>
> 
> I'm cc'ing Brian King, he's the one who figured out the proper fix
> for a hot-reset/fundamental-reset hardware "feature" that added
> this line of code.
> 
> The question is -- when the system finishes booting, and the
> module finally loads, will the device be found in a usable state
> and/or will it automatically reset to a usable state?
> 
> --linas
> 
>>
>> Index: linux-2.6/arch/powerpc/platforms/pseries/eeh.c
>> ===================================================================
>> --- linux-2.6.orig/arch/powerpc/platforms/pseries/eeh.c 2010-05-10 17:25:10.703453565 +1000
>> +++ linux-2.6/arch/powerpc/platforms/pseries/eeh.c      2010-05-10 17:25:24.034323030 +1000
>> @@ -749,7 +749,7 @@ static void __rtas_set_slot_reset(struct
>>        /* Determine type of EEH reset required by device,
>>         * default hot reset or fundamental reset
>>         */
>> -       if (dev->needs_freset)
>> +       if (dev && dev->needs_freset)
>>                rtas_pci_slot_reset(pdn, 3);
>>        else
>>                rtas_pci_slot_reset(pdn, 1);
>>
>>


-- 
Brian King
Linux on Power Virtualization
IBM Linux Technology Center
(507) 253-8636 | t/l 553-8636

^ permalink raw reply

* Re: [PATCH] hwmon: (tmp421) Add nfactor support.
From: Jeff Angielski @ 2010-05-11 19:34 UTC (permalink / raw)
  To: Andre Prendel; +Cc: Jean Delvare, Linuxppc-dev, lm-sensors
In-Reply-To: <20100511190327.GA2031@andre-laptop>

On 05/11/2010 03:03 PM, Andre Prendel wrote:
> On Mon, May 10, 2010 at 10:43:07AM -0400, Jeff Angielski wrote:
>
> Hi Jeff,
>
> A few comments below.
>
>> Add support for reading and writing the n-factor correction
>> registers.  This is needed to compensate for the characteristics
>> of a particular sensor hanging off of the remote channels.
>>
>> Signed-off-by: Jeff Angielski<jeff@theptrgroup.com>
>> ---
>>   drivers/hwmon/tmp421.c |   42 ++++++++++++++++++++++++++++++++++++++++++
>>   1 files changed, 42 insertions(+), 0 deletions(-)
>>
>> diff --git a/drivers/hwmon/tmp421.c b/drivers/hwmon/tmp421.c
>> index 738c472..c9e9855 100644
>> --- a/drivers/hwmon/tmp421.c
>> +++ b/drivers/hwmon/tmp421.c
>> @@ -49,6 +49,7 @@ enum chips { tmp421, tmp422, tmp423 };
>>
>>   static const u8 TMP421_TEMP_MSB[4]		= { 0x00, 0x01, 0x02, 0x03 };
>>   static const u8 TMP421_TEMP_LSB[4]		= { 0x10, 0x11, 0x12, 0x13 };
>> +static const u8 TMP421_NFACTOR[3]		= { 0x21, 0x22, 0x23 };
>>
>>   /* Flags */
>>   #define TMP421_CONFIG_SHUTDOWN			0x40
>> @@ -157,6 +158,38 @@ static ssize_t show_fault(struct device *dev,
>>   		return sprintf(buf, "0\n");
>>   }
>>
>> +static ssize_t show_nfactor(struct device *dev,
>> +			  struct device_attribute *devattr, char *buf)
>> +{
>> +	struct i2c_client *client = to_i2c_client(dev);
>> +	struct tmp421_data *data = i2c_get_clientdata(client);
>> +	int index = to_sensor_dev_attr(devattr)->index;
>> +	s8 nfactor;
>> +
>> +	mutex_lock(&data->update_lock);
>> +	nfactor = i2c_smbus_read_byte_data(client, TMP421_NFACTOR[index-1]);
>
> There should be spaces within the array index, [index - 1].

Ok.

>
>> +	mutex_unlock(&data->update_lock);
>> +
>> +	return sprintf(buf, "%d\n", nfactor);
>> +}
>
> I'de prefer implementing the sysfs access methods in a consistent way (see other functions). That means adding the nfactor register to the tmp421_data structure and using tmp421_update_device() to update the structure.

I did this on purpose since the nfactor typically only changes once at 
runtime when you program it for your sensor.  It seemed like a waste of 
processing power and i2c bandwidth to read a "pseudo static" register 
over and over again.

It can easily be changed if that's what will help the community the best.

>> +static ssize_t set_nfactor(struct device *dev,
>> +		struct device_attribute *devattr,
>> +		const char *buf, size_t count)
>> +{
>> +	struct i2c_client *client = to_i2c_client(dev);
>> +	struct tmp421_data *data = i2c_get_clientdata(client);
>> +	int index = to_sensor_dev_attr(devattr)->index;
>> +	int nfactor = simple_strtol(buf, NULL, 10);
>> +
>> +	mutex_lock(&data->update_lock);
>> +	i2c_smbus_write_byte_data(client, TMP421_NFACTOR[index-1],
>
> Missing spaces in array index again.

Ok.




-- 
Jeff Angielski
The PTR Group
www.theptrgroup.com

^ permalink raw reply

* Re: [PATCH] hwmon: (tmp421) Add nfactor support.
From: Jean Delvare @ 2010-05-11 19:12 UTC (permalink / raw)
  To: Andre Prendel; +Cc: Linuxppc-dev, lm-sensors
In-Reply-To: <20100511190327.GA2031@andre-laptop>

On Tue, 11 May 2010 21:03:27 +0200, Andre Prendel wrote:
> On Mon, May 10, 2010 at 10:43:07AM -0400, Jeff Angielski wrote:
> 
> Hi Jeff,
> 
> A few comments below.
>  
> > Add support for reading and writing the n-factor correction
> > registers.  This is needed to compensate for the characteristics
> > of a particular sensor hanging off of the remote channels.
> > 
> > Signed-off-by: Jeff Angielski <jeff@theptrgroup.com>
> > ---
> >  drivers/hwmon/tmp421.c |   42 ++++++++++++++++++++++++++++++++++++++++++
> >  1 files changed, 42 insertions(+), 0 deletions(-)
> > 
> > diff --git a/drivers/hwmon/tmp421.c b/drivers/hwmon/tmp421.c
> > index 738c472..c9e9855 100644
> > --- a/drivers/hwmon/tmp421.c
> > +++ b/drivers/hwmon/tmp421.c
> > @@ -49,6 +49,7 @@ enum chips { tmp421, tmp422, tmp423 };
> > 
> >  static const u8 TMP421_TEMP_MSB[4]		= { 0x00, 0x01, 0x02, 0x03 };
> >  static const u8 TMP421_TEMP_LSB[4]		= { 0x10, 0x11, 0x12, 0x13 };
> > +static const u8 TMP421_NFACTOR[3]		= { 0x21, 0x22, 0x23 };
> > 
> >  /* Flags */
> >  #define TMP421_CONFIG_SHUTDOWN			0x40
> > @@ -157,6 +158,38 @@ static ssize_t show_fault(struct device *dev,
> >  		return sprintf(buf, "0\n");
> >  }
> > 
> > +static ssize_t show_nfactor(struct device *dev,
> > +			  struct device_attribute *devattr, char *buf)
> > +{
> > +	struct i2c_client *client = to_i2c_client(dev);
> > +	struct tmp421_data *data = i2c_get_clientdata(client);
> > +	int index = to_sensor_dev_attr(devattr)->index;
> > +	s8 nfactor;
> > +
> > +	mutex_lock(&data->update_lock);
> > +	nfactor = i2c_smbus_read_byte_data(client, TMP421_NFACTOR[index-1]);
> 
> There should be spaces within the array index, [index - 1].
> 
> > +	mutex_unlock(&data->update_lock);
> > +
> > +	return sprintf(buf, "%d\n", nfactor);
> > +}
> 
> I'de prefer implementing the sysfs access methods in a consistent way (see other functions). That means adding the nfactor register to the tmp421_data structure and using tmp421_update_device() to update the structure.
> 
> > +static ssize_t set_nfactor(struct device *dev,
> > +		struct device_attribute *devattr,
> > +		const char *buf, size_t count)
> > +{
> > +	struct i2c_client *client = to_i2c_client(dev);
> > +	struct tmp421_data *data = i2c_get_clientdata(client);
> > +	int index = to_sensor_dev_attr(devattr)->index;
> > +	int nfactor = simple_strtol(buf, NULL, 10);
> > +
> > +	mutex_lock(&data->update_lock);
> > +	i2c_smbus_write_byte_data(client, TMP421_NFACTOR[index-1],
> 
> Missing spaces in array index again.
> 
> > +			SENSORS_LIMIT(nfactor, -128, 127));
> > +	mutex_unlock(&data->update_lock);
> > +
> > +	return count;
> > +}
> > +
> >  static mode_t tmp421_is_visible(struct kobject *kobj, struct attribute *a,
> >  				int n)
> >  {
> > @@ -177,19 +210,28 @@ static mode_t tmp421_is_visible(struct kobject
> > *kobj, struct attribute *a,
> >  static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_value, NULL, 0);
> >  static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp_value, NULL, 1);
> >  static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_fault, NULL, 1);
> > +static SENSOR_DEVICE_ATTR(temp2_nfactor, S_IRUGO | S_IWUSR,
> > +		show_nfactor, set_nfactor, 1);
> >  static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp_value, NULL, 2);
> >  static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_fault, NULL, 2);
> > +static SENSOR_DEVICE_ATTR(temp3_nfactor, S_IRUGO | S_IWUSR,
> > +		show_nfactor, set_nfactor, 2);
> >  static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp_value, NULL, 3);
> >  static SENSOR_DEVICE_ATTR(temp4_fault, S_IRUGO, show_fault, NULL, 3);
> > +static SENSOR_DEVICE_ATTR(temp4_nfactor, S_IRUGO | S_IWUSR,
> > +		show_nfactor, set_nfactor, 3);
> > 
> >  static struct attribute *tmp421_attr[] = {
> >  	&sensor_dev_attr_temp1_input.dev_attr.attr,
> >  	&sensor_dev_attr_temp2_input.dev_attr.attr,
> >  	&sensor_dev_attr_temp2_fault.dev_attr.attr,
> > +	&sensor_dev_attr_temp2_nfactor.dev_attr.attr,
> >  	&sensor_dev_attr_temp3_input.dev_attr.attr,
> >  	&sensor_dev_attr_temp3_fault.dev_attr.attr,
> > +	&sensor_dev_attr_temp3_nfactor.dev_attr.attr,
> >  	&sensor_dev_attr_temp4_input.dev_attr.attr,
> >  	&sensor_dev_attr_temp4_fault.dev_attr.attr,
> > +	&sensor_dev_attr_temp4_nfactor.dev_attr.attr,
> >  	NULL
> >  };

Any hope to standardize on the sysfs attribute files and units? So that
other drivers can implement the same interface.

-- 
Jean Delvare

^ permalink raw reply

* Re: [PATCH] 85xx: Fix PCI-E interrupt mapping for slot 0 of P2020DS
From: Felix Radensky @ 2010-05-11 19:10 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <1CA6B1BA-FBD1-4ECF-87DC-D3E50835E781@kernel.crashing.org>

Hi Kumar,

On 5/11/2010 3:36 PM, Kumar Gala wrote:
> On May 10, 2010, at 2:15 PM, Felix Radensky wrote:
>
>   
>> Fix legacy PCI-E interrupt mapping for PCI-E slot 0 of
>> P2020DS evaluation board. The patch is based on P2020DS
>> device tree from Freescale BSP for this board.
>>
>> Signed-off-by: Felix Radensky <felix@embedded-sol.com>
>> ---
>> arch/powerpc/boot/dts/p2020ds.dts |    8 ++++----
>> 1 files changed, 4 insertions(+), 4 deletions(-)
>>     
> I don't understand why this is needed?
>
> -k
>
>   

With 2.6.34-rc7 I get this nice dump when loading ath9k for PCI-E card
in slot 0:

irq 17: nobody cared (try booting with the "irqpoll" option)
Call Trace:
[ef0d59d0] [c00070b0] show_stack+0x3c/0x17c (unreliable)
[ef0d5a10] [c00740f8] __report_bad_irq+0x38/0xcc
[ef0d5a30] [c0074344] note_interrupt+0x1b8/0x228
[ef0d5a60] [c007539c] handle_fasteoi_irq+0xac/0x138
[ef0d5a80] [c0004a68] do_IRQ+0xd8/0x104
[ef0d5aa0] [c00102b0] ret_from_except+0x0/0x18
[ef0d5b60] [00029000] 0x29000
[ef0d5bb0] [c000498c] do_softirq+0x6c/0x70
[ef0d5bc0] [c0043bb4] irq_exit+0xb0/0xb4
[ef0d5bd0] [c0004a6c] do_IRQ+0xdc/0x104
[ef0d5bf0] [c00102b0] ret_from_except+0x0/0x18
[ef0d5cb0] [c00735c4] __setup_irq+0x374/0x3ac
[ef0d5ce0] [c00736d4] request_threaded_irq+0xd8/0x150
[ef0d5d10] [f11e8c34] ath_pci_probe+0x28c/0x3f8 [ath9k]
[ef0d5d90] [c0186334] local_pci_probe+0x24/0x34
[ef0d5da0] [c0186688] pci_device_probe+0x84/0xc4
[ef0d5dd0] [c01b7f84] driver_probe_device+0xa4/0x198
[ef0d5df0] [c01b8328] __driver_attach+0xa4/0xa8
[ef0d5e10] [c01b71b8] bus_for_each_dev+0x60/0x9c
[ef0d5e40] [c01b7d98] driver_attach+0x24/0x34
[ef0d5e50] [c01b7b20] bus_add_driver+0x1bc/0x280
[ef0d5e80] [c01b85b4] driver_register+0x70/0x168
[ef0d5ea0] [c01869a0] __pci_register_driver+0x5c/0xe4
[ef0d5ed0] [f11e88cc] ath_pci_init+0x28/0x38 [ath9k]
[ef0d5ee0] [f11f104c] ath9k_init+0x4c/0xb0 [ath9k]
[ef0d5ef0] [c0001cfc] do_one_initcall+0x40/0x1dc
[ef0d5f20] [c0070a7c] sys_init_module+0xf4/0x21c
[ef0d5f40] [c000fc58] ret_from_syscall+0x0/0x3c
handlers:
[<f11e16ac>] (ath_isr+0x0/0x1b4 [ath9k])
Disabling IRQ #17

The ath9k driver does not support MSI interrupts, so it has to use 
legacy ones.
If MSI interrupts are disabled in the kernel configuration I get similar 
dump
with e1000e driver.

The patch I've sent fixes the problem with legacy interrupts.

Felix.

^ permalink raw reply

* Re: [PATCH] hwmon: (tmp421) Add nfactor support.
From: Andre Prendel @ 2010-05-11 19:03 UTC (permalink / raw)
  To: Jeff Angielski; +Cc: Jean Delvare, Linuxppc-dev, lm-sensors
In-Reply-To: <4BE81B7B.7010804@theptrgroup.com>

On Mon, May 10, 2010 at 10:43:07AM -0400, Jeff Angielski wrote:

Hi Jeff,

A few comments below.
 
> Add support for reading and writing the n-factor correction
> registers.  This is needed to compensate for the characteristics
> of a particular sensor hanging off of the remote channels.
> 
> Signed-off-by: Jeff Angielski <jeff@theptrgroup.com>
> ---
>  drivers/hwmon/tmp421.c |   42 ++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 42 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/hwmon/tmp421.c b/drivers/hwmon/tmp421.c
> index 738c472..c9e9855 100644
> --- a/drivers/hwmon/tmp421.c
> +++ b/drivers/hwmon/tmp421.c
> @@ -49,6 +49,7 @@ enum chips { tmp421, tmp422, tmp423 };
> 
>  static const u8 TMP421_TEMP_MSB[4]		= { 0x00, 0x01, 0x02, 0x03 };
>  static const u8 TMP421_TEMP_LSB[4]		= { 0x10, 0x11, 0x12, 0x13 };
> +static const u8 TMP421_NFACTOR[3]		= { 0x21, 0x22, 0x23 };
> 
>  /* Flags */
>  #define TMP421_CONFIG_SHUTDOWN			0x40
> @@ -157,6 +158,38 @@ static ssize_t show_fault(struct device *dev,
>  		return sprintf(buf, "0\n");
>  }
> 
> +static ssize_t show_nfactor(struct device *dev,
> +			  struct device_attribute *devattr, char *buf)
> +{
> +	struct i2c_client *client = to_i2c_client(dev);
> +	struct tmp421_data *data = i2c_get_clientdata(client);
> +	int index = to_sensor_dev_attr(devattr)->index;
> +	s8 nfactor;
> +
> +	mutex_lock(&data->update_lock);
> +	nfactor = i2c_smbus_read_byte_data(client, TMP421_NFACTOR[index-1]);

There should be spaces within the array index, [index - 1].

> +	mutex_unlock(&data->update_lock);
> +
> +	return sprintf(buf, "%d\n", nfactor);
> +}

I'de prefer implementing the sysfs access methods in a consistent way (see other functions). That means adding the nfactor register to the tmp421_data structure and using tmp421_update_device() to update the structure.

> +static ssize_t set_nfactor(struct device *dev,
> +		struct device_attribute *devattr,
> +		const char *buf, size_t count)
> +{
> +	struct i2c_client *client = to_i2c_client(dev);
> +	struct tmp421_data *data = i2c_get_clientdata(client);
> +	int index = to_sensor_dev_attr(devattr)->index;
> +	int nfactor = simple_strtol(buf, NULL, 10);
> +
> +	mutex_lock(&data->update_lock);
> +	i2c_smbus_write_byte_data(client, TMP421_NFACTOR[index-1],

Missing spaces in array index again.

> +			SENSORS_LIMIT(nfactor, -128, 127));
> +	mutex_unlock(&data->update_lock);
> +
> +	return count;
> +}
> +
>  static mode_t tmp421_is_visible(struct kobject *kobj, struct attribute *a,
>  				int n)
>  {
> @@ -177,19 +210,28 @@ static mode_t tmp421_is_visible(struct kobject
> *kobj, struct attribute *a,
>  static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_value, NULL, 0);
>  static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp_value, NULL, 1);
>  static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_fault, NULL, 1);
> +static SENSOR_DEVICE_ATTR(temp2_nfactor, S_IRUGO | S_IWUSR,
> +		show_nfactor, set_nfactor, 1);
>  static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp_value, NULL, 2);
>  static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_fault, NULL, 2);
> +static SENSOR_DEVICE_ATTR(temp3_nfactor, S_IRUGO | S_IWUSR,
> +		show_nfactor, set_nfactor, 2);
>  static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp_value, NULL, 3);
>  static SENSOR_DEVICE_ATTR(temp4_fault, S_IRUGO, show_fault, NULL, 3);
> +static SENSOR_DEVICE_ATTR(temp4_nfactor, S_IRUGO | S_IWUSR,
> +		show_nfactor, set_nfactor, 3);
> 
>  static struct attribute *tmp421_attr[] = {
>  	&sensor_dev_attr_temp1_input.dev_attr.attr,
>  	&sensor_dev_attr_temp2_input.dev_attr.attr,
>  	&sensor_dev_attr_temp2_fault.dev_attr.attr,
> +	&sensor_dev_attr_temp2_nfactor.dev_attr.attr,
>  	&sensor_dev_attr_temp3_input.dev_attr.attr,
>  	&sensor_dev_attr_temp3_fault.dev_attr.attr,
> +	&sensor_dev_attr_temp3_nfactor.dev_attr.attr,
>  	&sensor_dev_attr_temp4_input.dev_attr.attr,
>  	&sensor_dev_attr_temp4_fault.dev_attr.attr,
> +	&sensor_dev_attr_temp4_nfactor.dev_attr.attr,
>  	NULL
>  };
> 

Regards,
Andre

PS: CC'ed lm-sensors list

^ permalink raw reply

* Re: [PATCH] powerpc: eeh: Fix oops when probing in early boot
From: Linas Vepstas @ 2010-05-11 18:59 UTC (permalink / raw)
  To: Anton Blanchard, Brian King; +Cc: linuxppc-dev, mikey, leitao, mmlnx
In-Reply-To: <20100511013855.GD12203@kryten>

On 10 May 2010 20:38, Anton Blanchard <anton@samba.org> wrote:
>
> If we take an EEH early enough, we oops:
>
>
> Call Trace:
> [c000000010483770] [c000000000013ee4] .show_stack+0xd8/0x218 (unreliable)
> [c000000010483850] [c000000000658940] .dump_stack+0x28/0x3c
> [c0000000104838d0] [c000000000057a68] .eeh_dn_check_failure+0x2b8/0x304
> [c000000010483990] [c0000000000259c8] .rtas_read_config+0x120/0x168
> [c000000010483a40] [c000000000025af4] .rtas_pci_read_config+0xe4/0x124
> [c000000010483af0] [c00000000037af18] .pci_bus_read_config_word+0xac/0x10=
4
> [c000000010483bc0] [c0000000008fec98] .pcibios_allocate_resources+0x7c/0x=
220
> [c000000010483c90] [c0000000008feed8] .pcibios_resource_survey+0x9c/0x418
> [c000000010483d80] [c0000000008fea10] .pcibios_init+0xbc/0xf4
> [c000000010483e20] [c000000000009844] .do_one_initcall+0x98/0x1d8
> [c000000010483ed0] [c0000000008f0560] .kernel_init+0x228/0x2e8
> [c000000010483f90] [c000000000031a08] .kernel_thread+0x54/0x70
> EEH: Detected PCI bus error on device <null>
> EEH: This PCI device has failed 1 times in the last hour:
> EEH: location=3DU78A5.001.WIH8464-P1 driver=3D pci addr=3D0001:00:01.0
> EEH: of node=3D/pci@800000020000209/usb@1
> EEH: PCI device/vendor: 00351033
> EEH: PCI cmd/status register: 12100146
>
> Unable to handle kernel paging request for data at address 0x00000468
> Oops: Kernel access of bad area, sig: 11 [#1]
> ....
> NIP [c000000000057610] .rtas_set_slot_reset+0x38/0x10c
> LR [c000000000058724] .eeh_reset_device+0x5c/0x124
> Call Trace:
> [c00000000bc6bd00] [c00000000005a0e0] .pcibios_remove_pci_devices+0x7c/0x=
b0 (unreliable)
> [c00000000bc6bd90] [c000000000058724] .eeh_reset_device+0x5c/0x124
> [c00000000bc6be40] [c0000000000589c0] .handle_eeh_events+0x1d4/0x39c
> [c00000000bc6bf00] [c000000000059124] .eeh_event_handler+0xf0/0x188
> [c00000000bc6bf90] [c000000000031a08] .kernel_thread+0x54/0x70
>
>
> We called rtas_set_slot_reset while scanning the bus and before the pci_d=
n
> to pcidev mapping has been created. Since we only need the pcidev to work
> out the type of reset and that only gets set after the module for the
> device loads, lets just do a hot reset if the pcidev is NULL.
>
> Signed-off-by: Anton Blanchard <anton@samba.org>
> ---


Acked-by: Linas Vepstas <linasvepstas@gmail.com>

I'm cc'ing Brian King, he's the one who figured out the proper fix
for a hot-reset/fundamental-reset hardware "feature" that added
this line of code.

The question is -- when the system finishes booting, and the
module finally loads, will the device be found in a usable state
and/or will it automatically reset to a usable state?

--linas

>
> Index: linux-2.6/arch/powerpc/platforms/pseries/eeh.c
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> --- linux-2.6.orig/arch/powerpc/platforms/pseries/eeh.c 2010-05-10 17:25:=
10.703453565 +1000
> +++ linux-2.6/arch/powerpc/platforms/pseries/eeh.c =C2=A0 =C2=A0 =C2=A020=
10-05-10 17:25:24.034323030 +1000
> @@ -749,7 +749,7 @@ static void __rtas_set_slot_reset(struct
> =C2=A0 =C2=A0 =C2=A0 =C2=A0/* Determine type of EEH reset required by dev=
ice,
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 * default hot reset or fundamental reset
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 */
> - =C2=A0 =C2=A0 =C2=A0 if (dev->needs_freset)
> + =C2=A0 =C2=A0 =C2=A0 if (dev && dev->needs_freset)
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0rtas_pci_slot_rese=
t(pdn, 3);
> =C2=A0 =C2=A0 =C2=A0 =C2=A0else
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0rtas_pci_slot_rese=
t(pdn, 1);
>
>

^ permalink raw reply

* Re: [PATCH] media/IR: Add missing include file to rc-map.c
From: Peter Hüwe @ 2010-05-11 18:42 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: linux-mips, linux-sh, linux-kernel, David Härdeman,
	linuxppc-dev, linux-m68k, linux-media
In-Reply-To: <201005051720.22617.PeterHuewe@gmx.de>

Am Mittwoch 05 Mai 2010 17:20:21 schrieb Peter H=FCwe:
> From: Peter Huewe <peterhuewe@gmx.de>
>=20
> This patch adds a missing include linux/delay.h to prevent
> build failures[1-5]
>=20
> Signed-off-by: Peter Huewe <peterhuewe@gmx.de>
> ---
Any updates on this patch?
Issue still exists with today's linux-next tree

Thanks,
Peter

^ permalink raw reply

* Re: [PATCH 1/2] Fix kexec on powerpc32
From: Christian Kujau @ 2010-05-11 17:57 UTC (permalink / raw)
  To: Maxim Uvarov; +Cc: kexec, uvarov, linuxppc-dev, horms
In-Reply-To: <20100511174749.19309.44615.stgit@muvarov>

On Tue, 11 May 2010 at 21:47, Maxim Uvarov wrote:
> This patch is required in case if you are using new toolchains.

Ah, thanks I was missing (and looking for) crashdump-powerpc.h
already :-)

Christian
-- 
make bzImage, not war

^ permalink raw reply

* [PATCH] powerpc new toolchains fix (crt.S)
From: Maxim Uvarov @ 2010-05-11 17:55 UTC (permalink / raw)
  To: linuxppc-dev, kexec; +Cc: lists, horms

Forgot to add purgatory/arch/ppc/crt.S to the patch. Resending...

--
This patch is required in case if you are using new toolchains.

Best regards,
Maxim Uvarov.

From: Maxim Uvarov <muvarov@gmail.com>

Linker does not provide some vital functions when building freestanding
applications with a new toolchain, so we have to provide our own CRT.

p.s.
Without the CRT we won't see any build errors (since the purgatory is
linked with --no-undefined), but the purgatory code won't work,
'kexec -e' will just hang the board.


I added option to configure to keep code buildable for old toolchais.
But there should be way to do this automatically.

Author: Anton Vorontsov <avorontsov@ru.mvista.com>
Signed-off-by: Maxim Uvarov <muvarov@gmail.com>
---

 configure.ac                |    9 +
 purgatory/arch/ppc/Makefile |    3 
 purgatory/arch/ppc/crt.S    |  262 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 274 insertions(+), 0 deletions(-)
 create mode 100644 purgatory/arch/ppc/crt.S

diff --git a/configure.ac b/configure.ac
index fcf50e4..63606bc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -159,6 +159,15 @@ if test "$with_xen" = yes ; then
 		AC_MSG_NOTICE([Xen support disabled])))
 fi
 
+dnl new toolchains
+if test "$ARCH" = ppc; then
+AC_ARG_WITH([oldtoolchain],
+		AC_HELP_STRING([--with-oldtoolchain],[compile without crt.S
+			required for new toolchains]),
+		AC_DEFINE(PPC_OLDTOOLCHAIN, 1,
+			[Define to compile with old toolchains]))
+fi
+
 dnl ---Sanity checks
 if test "$CC"      = "no"; then AC_MSG_ERROR([cc not found]); fi
 if test "$CPP"     = "no"; then AC_MSG_ERROR([cpp not found]); fi
diff --git a/purgatory/arch/ppc/Makefile b/purgatory/arch/ppc/Makefile
index 72289a0..d11ec3e 100644
--- a/purgatory/arch/ppc/Makefile
+++ b/purgatory/arch/ppc/Makefile
@@ -6,6 +6,9 @@ ppc_PURGATORY_SRCS += purgatory/arch/ppc/v2wrap_32.S
 ppc_PURGATORY_SRCS += purgatory/arch/ppc/misc.S
 ppc_PURGATORY_SRCS += purgatory/arch/ppc/purgatory-ppc.c
 ppc_PURGATORY_SRCS += purgatory/arch/ppc/console-ppc.c
+ifndef PPC_OLDTOOLCHAIN
+	ppc_PURGATORY_SRCS += purgatory/arch/ppc/crt.S
+endif
 
 dist += purgatory/arch/ppc/Makefile $(ppc_PURGATORY_SRCS)		\
 	purgatory/arch/ppc/purgatory-ppc.h purgatory/arch/ppc/ppc_asm.h
diff --git a/purgatory/arch/ppc/crt.S b/purgatory/arch/ppc/crt.S
new file mode 100644
index 0000000..d7a44bd
--- /dev/null
+++ b/purgatory/arch/ppc/crt.S
@@ -0,0 +1,262 @@
+/* This is from linux-2.6/arch/powerpc/lib/crtsavres.S:
+ *
+ * Special support for eabi and SVR4
+ *
+ *   Copyright (C) 1995, 1996, 1998, 2000, 2001 Free Software Foundation, Inc.
+ *   Copyright 2008 Freescale Semiconductor, Inc.
+ *   Written By Michael Meissner
+ *
+ * Based on gcc/config/rs6000/crtsavres.asm from gcc
+ *
+ * This file is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * In addition to the permissions in the GNU General Public License, the
+ * Free Software Foundation gives you unlimited permission to link the
+ * compiled version of this file with other programs, and to distribute
+ * those programs without any restriction coming from the use of this
+ * file.  (The General Public License restrictions do apply in other
+ * respects; for example, they cover modification of the file, and
+ * distribution when not linked into another program.)
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ *    As a special exception, if you link this library with files
+ *    compiled with GCC to produce an executable, this does not cause
+ *    the resulting executable to be covered by the GNU General Public License.
+ *    This exception does not however invalidate any other reasons why
+ *    the executable file might be covered by the GNU General Public License.
+ */
+
+/* On PowerPC64 Linux, these functions are provided by the linker.  */
+#ifndef __powerpc64__
+
+#define _GLOBAL(name) \
+	.type name,@function; \
+	.globl name; \
+name:
+
+/* Routines for saving integer registers, called by the compiler.  */
+/* Called with r11 pointing to the stack header word of the caller of the */
+/* function, just beyond the end of the integer save area.  */
+
+_GLOBAL(_savegpr_14)
+_GLOBAL(_save32gpr_14)
+	stw	14,-72(11)	/* save gp registers */
+_GLOBAL(_savegpr_15)
+_GLOBAL(_save32gpr_15)
+	stw	15,-68(11)
+_GLOBAL(_savegpr_16)
+_GLOBAL(_save32gpr_16)
+	stw	16,-64(11)
+_GLOBAL(_savegpr_17)
+_GLOBAL(_save32gpr_17)
+	stw	17,-60(11)
+_GLOBAL(_savegpr_18)
+_GLOBAL(_save32gpr_18)
+	stw	18,-56(11)
+_GLOBAL(_savegpr_19)
+_GLOBAL(_save32gpr_19)
+	stw	19,-52(11)
+_GLOBAL(_savegpr_20)
+_GLOBAL(_save32gpr_20)
+	stw	20,-48(11)
+_GLOBAL(_savegpr_21)
+_GLOBAL(_save32gpr_21)
+	stw	21,-44(11)
+_GLOBAL(_savegpr_22)
+_GLOBAL(_save32gpr_22)
+	stw	22,-40(11)
+_GLOBAL(_savegpr_23)
+_GLOBAL(_save32gpr_23)
+	stw	23,-36(11)
+_GLOBAL(_savegpr_24)
+_GLOBAL(_save32gpr_24)
+	stw	24,-32(11)
+_GLOBAL(_savegpr_25)
+_GLOBAL(_save32gpr_25)
+	stw	25,-28(11)
+_GLOBAL(_savegpr_26)
+_GLOBAL(_save32gpr_26)
+	stw	26,-24(11)
+_GLOBAL(_savegpr_27)
+_GLOBAL(_save32gpr_27)
+	stw	27,-20(11)
+_GLOBAL(_savegpr_28)
+_GLOBAL(_save32gpr_28)
+	stw	28,-16(11)
+_GLOBAL(_savegpr_29)
+_GLOBAL(_save32gpr_29)
+	stw	29,-12(11)
+_GLOBAL(_savegpr_30)
+_GLOBAL(_save32gpr_30)
+	stw	30,-8(11)
+_GLOBAL(_savegpr_31)
+_GLOBAL(_save32gpr_31)
+	stw	31,-4(11)
+	blr
+
+/* Routines for restoring integer registers, called by the compiler.  */
+/* Called with r11 pointing to the stack header word of the caller of the */
+/* function, just beyond the end of the integer restore area.  */
+
+_GLOBAL(_restgpr_14)
+_GLOBAL(_rest32gpr_14)
+	lwz	14,-72(11)	/* restore gp registers */
+_GLOBAL(_restgpr_15)
+_GLOBAL(_rest32gpr_15)
+	lwz	15,-68(11)
+_GLOBAL(_restgpr_16)
+_GLOBAL(_rest32gpr_16)
+	lwz	16,-64(11)
+_GLOBAL(_restgpr_17)
+_GLOBAL(_rest32gpr_17)
+	lwz	17,-60(11)
+_GLOBAL(_restgpr_18)
+_GLOBAL(_rest32gpr_18)
+	lwz	18,-56(11)
+_GLOBAL(_restgpr_19)
+_GLOBAL(_rest32gpr_19)
+	lwz	19,-52(11)
+_GLOBAL(_restgpr_20)
+_GLOBAL(_rest32gpr_20)
+	lwz	20,-48(11)
+_GLOBAL(_restgpr_21)
+_GLOBAL(_rest32gpr_21)
+	lwz	21,-44(11)
+_GLOBAL(_restgpr_22)
+_GLOBAL(_rest32gpr_22)
+	lwz	22,-40(11)
+_GLOBAL(_restgpr_23)
+_GLOBAL(_rest32gpr_23)
+	lwz	23,-36(11)
+_GLOBAL(_restgpr_24)
+_GLOBAL(_rest32gpr_24)
+	lwz	24,-32(11)
+_GLOBAL(_restgpr_25)
+_GLOBAL(_rest32gpr_25)
+	lwz	25,-28(11)
+_GLOBAL(_restgpr_26)
+_GLOBAL(_rest32gpr_26)
+	lwz	26,-24(11)
+_GLOBAL(_restgpr_27)
+_GLOBAL(_rest32gpr_27)
+	lwz	27,-20(11)
+_GLOBAL(_restgpr_28)
+_GLOBAL(_rest32gpr_28)
+	lwz	28,-16(11)
+_GLOBAL(_restgpr_29)
+_GLOBAL(_rest32gpr_29)
+	lwz	29,-12(11)
+_GLOBAL(_restgpr_30)
+_GLOBAL(_rest32gpr_30)
+	lwz	30,-8(11)
+_GLOBAL(_restgpr_31)
+_GLOBAL(_rest32gpr_31)
+	lwz	31,-4(11)
+	blr
+
+/* Routines for restoring integer registers, called by the compiler.  */
+/* Called with r11 pointing to the stack header word of the caller of the */
+/* function, just beyond the end of the integer restore area.  */
+
+_GLOBAL(_restgpr_14_x)
+_GLOBAL(_rest32gpr_14_x)
+	lwz	14,-72(11)	/* restore gp registers */
+_GLOBAL(_restgpr_15_x)
+_GLOBAL(_rest32gpr_15_x)
+	lwz	15,-68(11)
+_GLOBAL(_restgpr_16_x)
+_GLOBAL(_rest32gpr_16_x)
+	lwz	16,-64(11)
+_GLOBAL(_restgpr_17_x)
+_GLOBAL(_rest32gpr_17_x)
+	lwz	17,-60(11)
+_GLOBAL(_restgpr_18_x)
+_GLOBAL(_rest32gpr_18_x)
+	lwz	18,-56(11)
+_GLOBAL(_restgpr_19_x)
+_GLOBAL(_rest32gpr_19_x)
+	lwz	19,-52(11)
+_GLOBAL(_restgpr_20_x)
+_GLOBAL(_rest32gpr_20_x)
+	lwz	20,-48(11)
+_GLOBAL(_restgpr_21_x)
+_GLOBAL(_rest32gpr_21_x)
+	lwz	21,-44(11)
+_GLOBAL(_restgpr_22_x)
+_GLOBAL(_rest32gpr_22_x)
+	lwz	22,-40(11)
+_GLOBAL(_restgpr_23_x)
+_GLOBAL(_rest32gpr_23_x)
+	lwz	23,-36(11)
+_GLOBAL(_restgpr_24_x)
+_GLOBAL(_rest32gpr_24_x)
+	lwz	24,-32(11)
+_GLOBAL(_restgpr_25_x)
+_GLOBAL(_rest32gpr_25_x)
+	lwz	25,-28(11)
+_GLOBAL(_restgpr_26_x)
+_GLOBAL(_rest32gpr_26_x)
+	lwz	26,-24(11)
+_GLOBAL(_restgpr_27_x)
+_GLOBAL(_rest32gpr_27_x)
+	lwz	27,-20(11)
+_GLOBAL(_restgpr_28_x)
+_GLOBAL(_rest32gpr_28_x)
+	lwz	28,-16(11)
+_GLOBAL(_restgpr_29_x)
+_GLOBAL(_rest32gpr_29_x)
+	lwz	29,-12(11)
+_GLOBAL(_restgpr_30_x)
+_GLOBAL(_rest32gpr_30_x)
+	lwz	30,-8(11)
+_GLOBAL(_restgpr_31_x)
+_GLOBAL(_rest32gpr_31_x)
+	lwz	0,4(11)
+	lwz	31,-4(11)
+	mtlr	0
+	mr	1,11
+	blr
+
+/* This is from linux-2.6/arch/powerpc/kernel/misc_32.S
+ * 
+ * This file contains miscellaneous low-level functions.
+ *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
+ * and Paul Mackerras.
+ *
+ * kexec bits:
+ * Copyright (C) 2002-2003 Eric Biederman  <ebiederm@xmission.com>
+ * GameCube/ppc32 port Copyright (C) 2004 Albert Herranz
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+_GLOBAL(__lshrdi3)
+	subfic	6,5,32
+	srw	4,4,5	# LSW = count > 31 ? 0 : LSW >> count
+	addi	7,5,32	# could be xori, or addi with -32
+	slw	6,3,6	# t1 = count > 31 ? 0 : MSW << (32-count)
+	srw	7,3,7	# t2 = count < 32 ? 0 : MSW >> (count-32)
+	or	4,4,6	# LSW |= t1
+	srw	3,3,5	# MSW = MSW >> count
+	or	4,4,7	# LSW |= t2
+	blr
+
+#endif

^ permalink raw reply related


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