* [RFC Patch 5/5] PPC64-HWBKPT: Enable proper distinction of per-task and per-cpu breakpoints
From: K.Prasad @ 2010-05-24 4:04 UTC (permalink / raw)
To: linuxppc-dev@ozlabs.org, Paul Mackerras,
Linux Kernel Mailing List
Cc: Michael Neuling, Benjamin Herrenschmidt, shaggy,
Frederic Weisbecker, David Gibson, Alan Stern, K.Prasad,
Roland McGrath
In-Reply-To: <20100524034520.964014525@linux.vnet.ibm.com>
Per-task and per-cpu breakpoints have to be unambiguously identified for
proper restoration of hw-breakpoints. The notion of pure user- and kernel-
space breakpoints is antiquated. Store 'pid' of the process against which
the perf-counter was requested to help proper distinction.
This helps seamless handling of kernel-space breakpoints within the context
of a user-space process and breakpoints for kernel-threads.
Signed-off-by: K.Prasad <prasad@linux.vnet.ibm.com>
---
arch/powerpc/kernel/hw_breakpoint.c | 24 +++++++++++++++++-------
include/linux/perf_event.h | 1 +
kernel/perf_event.c | 9 ++++++---
3 files changed, 24 insertions(+), 10 deletions(-)
Index: linux-2.6.ppc64_test/include/linux/perf_event.h
===================================================================
--- linux-2.6.ppc64_test.orig/include/linux/perf_event.h
+++ linux-2.6.ppc64_test/include/linux/perf_event.h
@@ -698,6 +698,7 @@ struct perf_event {
int oncpu;
int cpu;
+ pid_t pid;
struct list_head owner_entry;
struct task_struct *owner;
Index: linux-2.6.ppc64_test/kernel/perf_event.c
===================================================================
--- linux-2.6.ppc64_test.orig/kernel/perf_event.c
+++ linux-2.6.ppc64_test/kernel/perf_event.c
@@ -4684,6 +4684,7 @@ static const struct pmu *sw_perf_event_i
static struct perf_event *
perf_event_alloc(struct perf_event_attr *attr,
int cpu,
+ pid_t pid,
struct perf_event_context *ctx,
struct perf_event *group_leader,
struct perf_event *parent_event,
@@ -4717,6 +4718,7 @@ perf_event_alloc(struct perf_event_attr
mutex_init(&event->mmap_mutex);
event->cpu = cpu;
+ event->pid = pid;
event->attr = *attr;
event->group_leader = group_leader;
event->pmu = NULL;
@@ -5015,7 +5017,7 @@ SYSCALL_DEFINE5(perf_event_open,
goto err_put_context;
}
- event = perf_event_alloc(&attr, cpu, ctx, group_leader,
+ event = perf_event_alloc(&attr, cpu, pid, ctx, group_leader,
NULL, NULL, GFP_KERNEL);
err = PTR_ERR(event);
if (IS_ERR(event))
@@ -5090,7 +5092,7 @@ perf_event_create_kernel_counter(struct
goto err_exit;
}
- event = perf_event_alloc(attr, cpu, ctx, NULL,
+ event = perf_event_alloc(attr, cpu, pid, ctx, NULL,
NULL, overflow_handler, GFP_KERNEL);
if (IS_ERR(event)) {
err = PTR_ERR(event);
@@ -5142,7 +5144,8 @@ inherit_event(struct perf_event *parent_
parent_event = parent_event->parent;
child_event = perf_event_alloc(&parent_event->attr,
- parent_event->cpu, child_ctx,
+ parent_event->cpu, child->pid,
+ child_ctx,
group_leader, parent_event,
NULL, GFP_KERNEL);
if (IS_ERR(child_event))
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
===================================================================
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/hw_breakpoint.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
@@ -221,7 +221,7 @@ void thread_change_pc(struct task_struct
*/
int __kprobes hw_breakpoint_handler(struct die_args *args)
{
- bool is_kernel, is_ptrace_bp = false;
+ bool is_kernel, is_taskbound_bp, is_ptrace_bp = false;
int rc = NOTIFY_STOP;
struct perf_event *bp;
struct pt_regs *regs = args->regs;
@@ -246,6 +246,7 @@ int __kprobes hw_breakpoint_handler(stru
is_kernel = is_kernel_addr(bp->attr.bp_addr);
is_ptrace_bp = (bp->overflow_handler == ptrace_triggered) ?
true : false;
+ is_taskbound_bp = (bp->pid > 0) ? true : false;
/*
* Verify if dar lies within the address range occupied by the symbol
@@ -288,7 +289,14 @@ int __kprobes hw_breakpoint_handler(stru
/* emulate_step() could not execute it, single-step them */
if (stepped == 0) {
regs->msr |= MSR_SE;
- __get_cpu_var(last_hit_bp) = bp;
+ /*
+ * Kernel-space addresses can also be bound to a task. If so,
+ * store the breakpoint in its 'thread_struct'
+ */
+ if (is_taskbound_bp)
+ bp->ctx->task->thread.last_hit_ubp = bp;
+ else
+ __get_cpu_var(last_hit_bp) = bp;
goto out;
}
/*
@@ -310,17 +318,17 @@ out:
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 perf_event *bp = NULL, *kernel_bp, *per_task_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;
+ per_task_bp = current->thread.last_hit_ubp;
kernel_bp = __get_cpu_var(last_hit_bp);
- if (user_bp) {
- bp = user_bp;
+ if (per_task_bp) {
+ bp = per_task_bp;
current->thread.last_hit_ubp = NULL;
} else if (kernel_bp) {
bp = kernel_bp;
@@ -348,7 +356,9 @@ int __kprobes single_step_dabr_instructi
* 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)))
+ if (!(per_task_bp &&
+ (!is_kernel_addr(bp->attr.bp_addr)) &&
+ test_thread_flag(TIF_SINGLESTEP)))
regs->msr &= ~MSR_SE;
set_dabr(bp_info->address | bp_info->type | DABR_TRANSLATION);
^ permalink raw reply
* [RFC Patch 4/5] PPC64-HWBKPT: Enable hw-breakpoints while handling intervening signals
From: K.Prasad @ 2010-05-24 4:03 UTC (permalink / raw)
To: linuxppc-dev@ozlabs.org, Paul Mackerras
Cc: Michael Neuling, Benjamin Herrenschmidt, shaggy,
Frederic Weisbecker, David Gibson, Alan Stern, K.Prasad,
Roland McGrath
In-Reply-To: <20100524034520.964014525@linux.vnet.ibm.com>
A signal delivered between a hw_breakpoint_handler() and the
single_step_dabr_instruction() will not have the breakpoint active during
signal handling (since breakpoint will not be restored through single-stepping
due to absence of MSR_SE bit on the signal frame). Enable breakpoints before
signal delivery and clear them during sigreturn() syscall.
Limitation: Nested hw-breakpoint exceptions (where second exception is raised
inside signal context) will cause a 'double-hit' i.e. the first breakpoint
exception will be taken twice.
Restore hw-breakpoints if the user-context is altered in the signal handler
(causing loss of MSR_SE).
Side-effect: 'Double-hit' of breakpoint if the instruction pointer is
unaltered in the new context.
Signed-off-by: K.Prasad <prasad@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/hw_breakpoint.h | 3 +++
arch/powerpc/kernel/hw_breakpoint.c | 28 ++++++++++++++++++++++++++++
arch/powerpc/kernel/signal.c | 8 ++++++++
arch/powerpc/kernel/signal_32.c | 10 ++++++++++
arch/powerpc/kernel/signal_64.c | 7 +++++++
5 files changed, 56 insertions(+)
Index: linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
===================================================================
--- linux-2.6.ppc64_test.orig/arch/powerpc/include/asm/hw_breakpoint.h
+++ linux-2.6.ppc64_test/arch/powerpc/include/asm/hw_breakpoint.h
@@ -43,6 +43,9 @@ static inline void hw_breakpoint_disable
{
set_dabr(0);
}
+extern void sighandler_install_bp(struct task_struct *tsk);
+extern void sigreturn_uninstall_bp(struct task_struct *tsk);
+extern void thread_change_pc(struct task_struct *tsk, unsigned long msr);
#endif /* CONFIG_HAVE_HW_BREAKPOINT */
#endif /* __KERNEL__ */
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
===================================================================
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/hw_breakpoint.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/hw_breakpoint.c
@@ -188,6 +188,34 @@ int arch_validate_hwbkpt_settings(struct
return 0;
}
+void sighandler_install_bp(struct task_struct *tsk)
+{
+ struct arch_hw_breakpoint *info;
+
+ if (likely(!tsk->thread.last_hit_ubp))
+ return;
+
+ info = counter_arch_bp(tsk->thread.last_hit_ubp);
+ set_dabr(info->address | info->type | DABR_TRANSLATION);
+}
+
+void sigreturn_uninstall_bp(struct task_struct *tsk)
+{
+ if (unlikely(tsk->thread.last_hit_ubp))
+ set_dabr(0);
+}
+
+void thread_change_pc(struct task_struct *tsk, unsigned long new_msr)
+{
+ /*
+ * Do not bother to restore breakpoints if single-stepping is not
+ * cleared. single_step_dabr_instruction() will handle it if MSR_SE
+ * is set.
+ */
+ if (!(new_msr & MSR_SE))
+ sighandler_install_bp(tsk);
+}
+
/*
* Handle debug exception notifications.
*/
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/signal.c
===================================================================
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/signal.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/signal.c
@@ -11,6 +11,7 @@
#include <linux/tracehook.h>
#include <linux/signal.h>
+#include <asm/hw_breakpoint.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
@@ -149,6 +150,13 @@ static int do_signal_pending(sigset_t *o
if (current->thread.dabr)
set_dabr(current->thread.dabr);
#endif
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+ /*
+ * Re-enable the breakpoints (if it was previously cleared in
+ * hw_breakpoint_handler()) for the signal stack.
+ */
+ sighandler_install_bp(current);
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
if (is32) {
if (ka.sa.sa_flags & SA_SIGINFO)
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/signal_64.c
===================================================================
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/signal_64.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/signal_64.c
@@ -33,6 +33,7 @@
#include <asm/cacheflush.h>
#include <asm/syscalls.h>
#include <asm/vdso.h>
+#include <asm/hw_breakpoint.h>
#include "signal.h"
@@ -312,6 +313,9 @@ int sys_swapcontext(struct ucontext __us
|| __copy_to_user(&old_ctx->uc_sigmask,
¤t->blocked, sizeof(sigset_t)))
return -EFAULT;
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+ thread_change_pc(current, new_msr);
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
}
if (new_ctx == NULL)
return 0;
@@ -364,6 +368,9 @@ int sys_rt_sigreturn(unsigned long r3, u
if (__copy_from_user(&set, &uc->uc_sigmask, sizeof(set)))
goto badframe;
restore_sigmask(&set);
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+ sigreturn_uninstall_bp(current);
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
if (restore_sigcontext(regs, NULL, 1, &uc->uc_mcontext))
goto badframe;
Index: linux-2.6.ppc64_test/arch/powerpc/kernel/signal_32.c
===================================================================
--- linux-2.6.ppc64_test.orig/arch/powerpc/kernel/signal_32.c
+++ linux-2.6.ppc64_test/arch/powerpc/kernel/signal_32.c
@@ -42,6 +42,7 @@
#include <asm/syscalls.h>
#include <asm/sigcontext.h>
#include <asm/vdso.h>
+#include <asm/hw_breakpoint.h>
#ifdef CONFIG_PPC64
#include "ppc32.h"
#include <asm/unistd.h>
@@ -996,6 +997,9 @@ long sys_swapcontext(struct ucontext __u
|| put_sigset_t(&old_ctx->uc_sigmask, ¤t->blocked)
|| __put_user(to_user_ptr(mctx), &old_ctx->uc_regs))
return -EFAULT;
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+ thread_change_pc(current, new_msr);
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
}
if (new_ctx == NULL)
return 0;
@@ -1034,6 +1038,9 @@ long sys_rt_sigreturn(int r3, int r4, in
(regs->gpr[1] + __SIGNAL_FRAMESIZE + 16);
if (!access_ok(VERIFY_READ, rt_sf, sizeof(*rt_sf)))
goto bad;
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+ sigreturn_uninstall_bp(current);
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
if (do_setcontext(&rt_sf->uc, regs, 1))
goto bad;
@@ -1279,6 +1286,9 @@ long sys_sigreturn(int r3, int r4, int r
#endif
restore_sigmask(&set);
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+ sigreturn_uninstall_bp(current);
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
sr = (struct mcontext __user *)from_user_ptr(sigctx.regs);
addr = sr;
if (!access_ok(VERIFY_READ, sr, sizeof(*sr))
^ permalink raw reply
* [RFC Patch 3/5] PPC64-HWBKPT: Handle concurrent alignment interrupts
From: K.Prasad @ 2010-05-24 4:02 UTC (permalink / raw)
To: linuxppc-dev@ozlabs.org, Paul Mackerras
Cc: Michael Neuling, Benjamin Herrenschmidt, shaggy,
Frederic Weisbecker, David Gibson, Alan Stern, K.Prasad,
Roland McGrath
In-Reply-To: <20100524034520.964014525@linux.vnet.ibm.com>
An alignment interrupt may intervene between a DSI/hw-breakpoint exception
and the single-step exception. Enable the alignment interrupt (through
modifications to emulate_single_step()) to notify the single-step exception
handler for proper restoration of hw-breakpoints.
Signed-off-by: K.Prasad <prasad@linux.vnet.ibm.com>
---
arch/powerpc/kernel/traps.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
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
@@ -602,7 +602,7 @@ void RunModeException(struct pt_regs *re
void __kprobes single_step_exception(struct pt_regs *regs)
{
- regs->msr &= ~(MSR_SE | MSR_BE); /* Turn off 'trace' bits */
+ clear_single_step(regs);
if (notify_die(DIE_SSTEP, "single_step", regs, 5,
5, SIGTRAP) == NOTIFY_STOP)
@@ -621,10 +621,7 @@ void __kprobes single_step_exception(str
*/
static void emulate_single_step(struct pt_regs *regs)
{
- if (single_stepping(regs)) {
- clear_single_step(regs);
- _exception(SIGTRAP, regs, TRAP_TRACE, 0);
- }
+ single_step_exception(regs);
}
static inline int __parse_fpscr(unsigned long fpscr)
^ permalink raw reply
* [RFC Patch 2/5] PPC64-HWBKPT: Implement hw-breakpoints for PowerPC Book III S
From: K.Prasad @ 2010-05-24 4:02 UTC (permalink / raw)
To: linuxppc-dev@ozlabs.org, Paul Mackerras
Cc: Michael Neuling, Benjamin Herrenschmidt, shaggy,
Frederic Weisbecker, David Gibson, Alan Stern, K.Prasad,
Roland McGrath
In-Reply-To: <20100524034520.964014525@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 | 49 ++++
arch/powerpc/include/asm/processor.h | 8
arch/powerpc/kernel/Makefile | 1
arch/powerpc/kernel/hw_breakpoint.c | 365 +++++++++++++++++++++++++++++++
arch/powerpc/kernel/machine_kexec_64.c | 3
arch/powerpc/kernel/process.c | 6
arch/powerpc/kernel/ptrace.c | 64 +++++
arch/powerpc/lib/Makefile | 1
include/linux/hw_breakpoint.h | 1
11 files changed, 503 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,49 @@
+#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>
+
+static inline int hw_breakpoint_slots(int type)
+{
+ return HBP_NUM;
+}
+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_check_bp_in_kernelspace(struct perf_event *bp);
+extern int arch_validate_hwbkpt_settings(struct perf_event *bp);
+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,365 @@
+/*
+ * 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 2010 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;
+
+ /*
+ * Do not install DABR values if the instruction must be single-stepped.
+ * If so, DABR will be populated in single_step_dabr_instruction().
+ */
+ if (current->thread.last_hit_ubp != 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();
+}
+
+/*
+ * Check for virtual address in kernel space.
+ */
+int arch_check_bp_in_kernelspace(struct perf_event *bp)
+{
+ struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+
+ return is_kernel_addr(info->address);
+}
+
+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)
+{
+ 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;
+ }
+
+ 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/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>
@@ -866,9 +868,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.
@@ -896,6 +923,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
@@ -462,8 +462,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
@@ -516,6 +516,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>
@@ -165,6 +166,7 @@ static void kexec_smp_down(void *arg)
while(kexec_all_irq_disabled == 0)
cpu_relax();
mb(); /* make sure all irqs are disabled before this */
+ hw_breakpoint_disable();
/*
* Now every CPU has IRQs off, we can clear out any pending
* IPIs and be sure that no more will come in after this.
@@ -180,6 +182,7 @@ static void kexec_prepare_cpus_wait(int
{
int my_cpu, i, notified=-1;
+ hw_breakpoint_disable();
my_cpu = get_cpu();
/* Make sure each CPU has atleast made it to the state we need */
for (i=0; i < NR_CPUS; i++) {
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
@@ -139,6 +139,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/Kconfig
===================================================================
--- linux-2.6.ppc64_test.orig/arch/powerpc/Kconfig
+++ linux-2.6.ppc64_test/arch/powerpc/Kconfig
@@ -141,6 +141,7 @@ config PPC
select GENERIC_ATOMIC64 if PPC32
select HAVE_PERF_EVENTS
select HAVE_REGS_AND_STACK_ACCESS_API
+ select HAVE_HW_BREAKPOINT if PERF_EVENTS && PPC_BOOK3S_64
config EARLY_PRINTK
bool
^ permalink raw reply
* [RFC Patch 1/5] Allow arch-specific cleanup before breakpoint unregistration
From: K.Prasad @ 2010-05-24 4:02 UTC (permalink / raw)
To: linuxppc-dev@ozlabs.org, Paul Mackerras
Cc: Michael Neuling, Benjamin Herrenschmidt, shaggy,
Frederic Weisbecker, David Gibson, Alan Stern, K.Prasad,
Roland McGrath
In-Reply-To: <20100524034520.964014525@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
@@ -242,6 +242,17 @@ toggle_bp_slot(struct perf_event *bp, bo
}
/*
+ * 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)
@@ -339,6 +350,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
* [RFC Patch 0/5] PPC64-HWBKPT: Hardware Breakpoint interfaces - ver XIX
From: K.Prasad @ 2010-05-24 4:01 UTC (permalink / raw)
To: linuxppc-dev@ozlabs.org, Paul Mackerras
Cc: Michael Neuling, Benjamin Herrenschmidt, shaggy,
Frederic Weisbecker, David Gibson, Alan Stern, Roland McGrath
Hi All,
Please find a new version of the patches that implement
hw-breakpoints for PowerPC Book III S. This patchset has some major
additions to hw-breakpoint exception handling that help reliable
restoration of breakpoints + increased coverage of breakpoints for
signal handlers.
The patches have been marked RFC, given that changes through patches
4/5 and 5/5 haven't been tested in particular and that they make
modifications to the generic framework too.
Kindly let me know your comments.
Changelog - ver XIX
--------------------
(Version XVIII: linuxppc-dev ref: 20100512033055.GA6384@in.ibm.com)
- Increased coverage of breakpoints during concurrent alignment_exception
and signal handling (which previously had 'blind-spots').
- Support for kernel-thread breakpoints and kernel-space breakpoints inside the
context of a user-space process.
- Patches re-based to commit f4b87dee923342505e1ddba8d34ce9de33e75050, thereby
necessitating minor changes to arch_validate_hwbkpt_settings().
Thanks,
K.Prasad
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.
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
* [PATCH 081/199] Documentation/powerpc/mpc52xx.txt: Checkpatch cleanup
From: Andrea Gelmini @ 2010-05-23 19:56 UTC (permalink / raw)
To: andrea.gelmini; +Cc: Randy Dunlap, linux-doc, Paul Mackerras, linuxppc-dev
In-Reply-To: <1274644605-25181-1-git-send-email-andrea.gelmini@gelma.net>
Documentation/powerpc/mpc52xx.txt:5: ERROR: trailing whitespace
Documentation/powerpc/mpc52xx.txt:13: ERROR: trailing whitespace
Documentation/powerpc/mpc52xx.txt:18: ERROR: trailing whitespace
Documentation/powerpc/mpc52xx.txt:24: ERROR: trailing whitespace
Documentation/powerpc/mpc52xx.txt:25: ERROR: trailing whitespace
Documentation/powerpc/mpc52xx.txt:29: ERROR: trailing whitespace
Signed-off-by: Andrea Gelmini <andrea.gelmini@gelma.net>
---
Documentation/powerpc/mpc52xx.txt | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/Documentation/powerpc/mpc52xx.txt b/Documentation/powerpc/mpc52xx.txt
index 10dd4ab..0d540a3 100644
--- a/Documentation/powerpc/mpc52xx.txt
+++ b/Documentation/powerpc/mpc52xx.txt
@@ -2,7 +2,7 @@ Linux 2.6.x on MPC52xx family
-----------------------------
For the latest info, go to http://www.246tNt.com/mpc52xx/
-
+
To compile/use :
- U-Boot:
@@ -10,23 +10,23 @@ To compile/use :
if you wish to ).
# make lite5200_defconfig
# make uImage
-
+
then, on U-boot:
=> tftpboot 200000 uImage
=> tftpboot 400000 pRamdisk
=> bootm 200000 400000
-
+
- DBug:
# <edit Makefile to set ARCH=ppc & CROSS_COMPILE=... ( also EXTRAVERSION
if you wish to ).
# make lite5200_defconfig
# cp your_initrd.gz arch/ppc/boot/images/ramdisk.image.gz
- # make zImage.initrd
- # make
+ # make zImage.initrd
+ # make
then in DBug:
DBug> dn -i zImage.initrd.lite5200
-
+
Some remarks :
- The port is named mpc52xxx, and config options are PPC_MPC52xx. The MGT5100
--
1.7.1.251.gf80a2
^ permalink raw reply related
* [PATCH] powerpc/pasemi: update maintainers file
From: Olof Johansson @ 2010-05-22 15:17 UTC (permalink / raw)
To: benh; +Cc: linuxppc-dev
PWRficient platform work is definitely in maintenance mode these
days, update MAINTAINERS file to reflect reality.
Website is long gone as well.
Signed-off-by: Olof Johansson <olof@lixom.net>
diff --git a/MAINTAINERS b/MAINTAINERS
index d329b05..78bb64d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3444,9 +3444,8 @@ F: arch/powerpc/platforms/83xx/
LINUX FOR POWERPC PA SEMI PWRFICIENT
M: Olof Johansson <olof@lixom.net>
-W: http://www.pasemi.com/
L: linuxppc-dev@ozlabs.org
-S: Supported
+S: Maintained
F: arch/powerpc/platforms/pasemi/
F: drivers/*/*pasemi*
F: drivers/*/*/*pasemi*
^ permalink raw reply related
* Re: Problem of PowerPc 82xx when using smc
From: hellohello @ 2010-05-22 6:23 UTC (permalink / raw)
To: hellohello, Scott Wood; +Cc: linuxppc-dev
Pj4gTmV3ZXIga2VybmVscyBzdXBwb3J0IGR5bmFtaWNhbGx5IGFsbG9jYXRpbmcgdGhpcyBwYXJh
bWV0ZXIgUkFNLiAgT2xkZXIgDQo+PiBrZXJuZWxzIHVzZSB3aGF0ZXZlciB1LWJvb3QgY2hvc2Uu
DQoNCkkgc2VlLiAgICBUaGFua3MgLg0KVS1ib290IGluaXRpYWxpemUgU01DMSBmb3IgdGhlIGZp
cnN0IHRpbWUsIGFuZCBoYXMgc2V0IFNNQzFfQkFTRSB0byB0aGUgMHg4N0ZDIG9mZnNldCBvZiB0
aGUgRFBSQU0uDQprZXJuZWwgIDIuNi4yNSBpbml0aWFsaXplIFNNQzEgZm9yIHRoZSBzZWNvbmQg
dGltZSBhcyB3ZWxsIGFzICB3aGljaCBhcmUgZG9uZSBpbiB1LWJvb3QsICBleGNlcHQgdG8gIHNl
dCBTTUMxX0JBU0UgYWdhaW4uDQpTbyBpZiBTTUMxX0JBU0UgaXMgdHJhbnNmZXJyZWQgdG8ga2Vy
bmVsIGJ5IGR0cyBjb3JyZWN0bHksIFNNQzEgc2hvdWxkIHdvcmsgd2VsbC4NClRoZSBwcm9ibGVt
IG11c3QgYmUgbXkgZHRzIGZpbGUgLG5vdCB0aGUgY29kZS4NCg0KDQoNCg0KLS0tLS0gT3JpZ2lu
YWwgTWVzc2FnZSAtLS0tLSANCkZyb206ICJoZWxsb2hlbGxvIiA8aGVsbG9oZWxsbzAwOEAxNjMu
Y29tPg0KVG86ICJTY290dCBXb29kIiA8c2NvdHR3b29kQGZyZWVzY2FsZS5jb20+DQpDYzogPGxp
bnV4cHBjLWRldkBsaXN0cy5vemxhYnMub3JnPg0KU2VudDogU2F0dXJkYXksIE1heSAyMiwgMjAx
MCAxMDo1MSBBTQ0KU3ViamVjdDogUmU6IFByb2JsZW0gb2YgUG93ZXJQYyA4Mnh4IHdoZW4gdXNp
bmcgc21jDQoNCg0KPiANCj4+IE5ld2VyIGtlcm5lbHMgc3VwcG9ydCBkeW5hbWljYWxseSBhbGxv
Y2F0aW5nIHRoaXMgcGFyYW1ldGVyIFJBTS4gIE9sZGVyIA0KPj4ga2VybmVscyB1c2Ugd2hhdGV2
ZXIgdS1ib290IGNob3NlLg0KPj4gDQo+PiBXaHkgZG8geW91IHdhbnQgdG8gc2V0IGl0IHRvIGEg
cGFydGljdWxhciBhZGRyZXNzPw0KPiANCj4gVGhlcmUgc2hvdWxkIGJlIHNvbWUgY29kZSB0byBz
ZXQgU01DMV9CQVNFIHRvIHRoZSAweDg3RkMgb2Zmc2V0IG9mIHRoZSBEUFJBTSwgd2hhdGV2ZXIg
U01DMV9CQVNFIGlzIGZpeGVkIG9yIGR5bmFtaWNhbGx5IGFsbG9jYXRlZCAuDQo+IA0KPiBNeSBr
ZXJuZWwgaXMgMi42LjI1LCB0aGlzIFNNQzFfQkFTRSB2YWx1ZSBjYW4gYmUgdHJhbnNmZXJyZWQg
dG8gIGtlcm5lbCBieSBkdHMgdHJlZSwgYnV0IEkgaGF2ZSBub3QgZmluZCB0aGUgY29kZSB0byBz
ZXQgaXQgdG8gIDB4ODdGQyBvZmZzZXQgb2YgdGhlIERQUkFNLiBPciB0aGVyZSBpcyBhbm90aGVy
IHdheSB0byBzb2x2ZSBpdCA/DQo+IA0KPiANCj4gDQo+IC0tLS0tIE9yaWdpbmFsIE1lc3NhZ2Ug
LS0tLS0gDQo+IEZyb206ICJTY290dCBXb29kIiA8c2NvdHR3b29kQGZyZWVzY2FsZS5jb20+DQo+
IFRvOiAiaGVsbG9oZWxsbyIgPGhlbGxvaGVsbG8wMDhAMTYzLmNvbT4NCj4gQ2M6IDxsaW51eHBw
Yy1kZXZAbGlzdHMub3psYWJzLm9yZz4NCj4gU2VudDogU2F0dXJkYXksIE1heSAyMiwgMjAxMCAx
OjI4IEFNDQo+IFN1YmplY3Q6IFJlOiBQcm9ibGVtIG9mIFBvd2VyUGMgODJ4eCB3aGVuIHVzaW5n
IHNtYw0KPiANCj4gDQo+PiBPbiAwNS8yMC8yMDEwIDEwOjMzIFBNLCBoZWxsb2hlbGxvIHdyb3Rl
Og0KPj4+PiBObywgaXQgc2hvdWxkbid0IC0tIHJ4X2JkX2Jhc2UgaXMgb2YgdHlwZSAiY2JkX3Qg
KiIsIHNvIHRoZSBtdWx0aXBsaWNhdGlvbg0KPj4+PiBhbHJlYWR5IGhhcHBlbnMgYXMgcGFydCBv
ZiBwb2ludGVyIGFyaXRobWV0aWMuDQo+Pj4gLS0tWWVzLCB5b3UgYXJlIHJpZ2h0LiBJIG1hZGUg
YSBiYXNpYyBtaXN0YWtlLg0KPj4+DQo+Pj4gQnV0IG5vdyBJIGhhdmUgYW5vdGhlciBxdWVzdGlv
bi4NCj4+PiBUaGUgU01DMSBwYXJhbXMgY2FuIGJlIHJlbG9jYXRlZCB0byBhbnkgb2Zmc2V0IG9m
IHRoZSBEUFJBTSBvbiBhIDY0IGJ5dGUgYm91bmRhcnksIG5vdCBhcyB0aGUgU0NDMSwgd2hpY2gg
bXVzdCBiZSAgYXQgMHg4MDAwIG9mZnNldCBvZiB0aGUgRFBSQU0uDQo+Pj4gVGhlIFNNQzEgcGFy
YW1zIGJhc2UgaXMgc2V0IGF0IDB4ODdGQyBvZmZzZXQgb2YgdGhlIERQUkFNLg0KPj4+DQo+Pj4g
U28gaWYgIEkgd2FudCBTTUMxIHBhcmFtcyBzdGFydCBhdCAgMHgyMDAgaW4gRFBSQU0gICwgSSBz
aG91bGQgc2V0IDB4MjAwIHRvIHRoZSAweDg3RkMgb2Zmc2V0IG9mIHRoZSBEUFJBTS4NCj4+PiBJ
IGhhdmUgc2VlIHRoaXMgY29kZSBpbiB1LWJvb3QsIGJ1dCBJIGNhbiBub3QgZmluZCB0aGlzIGNv
ZGUgaW4gbmVpdGhlciBjcG1fdWFydF9jcG0yLmMgbm9yIGNwbV91YXJ0X2NvcmUuYy4NCj4+Pg0K
Pj4+IFNob3VsZCBJIGFkZCB0aGVzZSBjb2RlIHRvICBjcG1fdWFydF9jb3JlLmM/DQo+PiANCj4+
IE5ld2VyIGtlcm5lbHMgc3VwcG9ydCBkeW5hbWljYWxseSBhbGxvY2F0aW5nIHRoaXMgcGFyYW1l
dGVyIFJBTS4gIE9sZGVyIA0KPj4ga2VybmVscyB1c2Ugd2hhdGV2ZXIgdS1ib290IGNob3NlLg0K
Pj4gDQo+PiBXaHkgZG8geW91IHdhbnQgdG8gc2V0IGl0IHRvIGEgcGFydGljdWxhciBhZGRyZXNz
Pw0KPj4gDQo+PiAtU2NvdHQNCj4+
^ permalink raw reply
* Re: Problem of PowerPc 82xx when using smc
From: hellohello @ 2010-05-22 3:37 UTC (permalink / raw)
To: Gary Thomas; +Cc: linuxppc-dev
In-Reply-To: <4BF66C8B.10407@mlbassoc.com>
Pj4gU2hvdWxkIEkgYWRkIHRoZXNlIGNvZGUgdG8gIGNwbV91YXJ0X2NvcmUuYz8NCj4+DQo+PiAt
LWRwX21lbSA9IGNwbV9kcHJhbV9hZGRyKDB4ODdmYyk7DQo+PiAtLW91dF9iZTE2KGRwX21lbSwg
U01DMV9CQVNFKTsNCj4gDQo+IFdoeSBhcmUgeW91IG11Y2tpbmcgYWJvdXQgd2l0aCB0aGlzIGNv
ZGUgYXQgYWxsPyAgU01DeCBzZXJpYWwgY2VydGFpbmx5DQo+IHdvcmtzIG9uIGV2ZXJ5IHBsYXRm
b3JtIEkndmUgZXZlciB1c2VkLCA4eHggYW5kIDh4eHggYXMgd2VsbC4NCj4gDQoNCkkgaGF2ZSBu
byBpbnRlcmVzdCBvbiBtdWNraW5nIGFib3V0IGFueSBjb2RlIGF0IGFsbC4gDQpNeSBpbnRlcmVz
dCBpcyAgbXkgc21jMSdzIHByb2JsZW0uDQpTb21lIGRvY3RvciBzYXkgInRvb3RoIG9rLCB5b3Ug
anVzdCBlYXQgdG9vIG11Y2ggY29sZCBmb29kICAuLi4uIg0KU29tZSBkb2N0b3Igc2F5ICJNYXli
ZSB0b290aCBoYXMgYSBsaXR0bGUgaG9sZSwgICB0YWtlIGEgbG9vayAuLi4uIg0KT25lIGRvY3Rv
ciBqdXN0IHNheSwgInRvb3RoYWNoZT8gV2h5IGFyZSB5b3UgbXVja2luZyBhYm91dCB3aXRoIHRo
aXMgdG9vdGggYXQgYWxsPyAsICB0b290aCB3b3JrcyB3ZWxsIG9uIGV2ZXJ5b25lJ3MgbW91dGgs
IGJveXMgYW5kIGdpcmxzIGFzIHdlbGwiDQoNCg0KDQoNCg0KDQoNCg0KDQotLS0tLSBPcmlnaW5h
bCBNZXNzYWdlIC0tLS0tIA0KRnJvbTogIkdhcnkgVGhvbWFzIiA8Z2FyeUBtbGJhc3NvYy5jb20+
DQpUbzogImhlbGxvaGVsbG8iIDxoZWxsb2hlbGxvMDA4QDE2My5jb20+DQpDYzogIlNjb3R0IFdv
b2QiIDxzY290dHdvb2RAZnJlZXNjYWxlLmNvbT47IDxsaW51eHBwYy1kZXZAbGlzdHMub3psYWJz
Lm9yZz4NClNlbnQ6IEZyaWRheSwgTWF5IDIxLCAyMDEwIDc6MjAgUE0NClN1YmplY3Q6IFJlOiBQ
cm9ibGVtIG9mIFBvd2VyUGMgODJ4eCB3aGVuIHVzaW5nIHNtYw0KDQoNCj4gT24gMDUvMjAvMjAx
MCAwOTozMyBQTSwgaGVsbG9oZWxsbyB3cm90ZToNCj4+PiBObywgaXQgc2hvdWxkbid0IC0tIHJ4
X2JkX2Jhc2UgaXMgb2YgdHlwZSAiY2JkX3QgKiIsIHNvIHRoZSBtdWx0aXBsaWNhdGlvbg0KPj4+
IGFscmVhZHkgaGFwcGVucyBhcyBwYXJ0IG9mIHBvaW50ZXIgYXJpdGhtZXRpYy4NCj4+IC0tLVll
cywgeW91IGFyZSByaWdodC4gSSBtYWRlIGEgYmFzaWMgbWlzdGFrZS4NCj4+DQo+PiBCdXQgbm93
IEkgaGF2ZSBhbm90aGVyIHF1ZXN0aW9uLg0KPj4gVGhlIFNNQzEgcGFyYW1zIGNhbiBiZSByZWxv
Y2F0ZWQgdG8gYW55IG9mZnNldCBvZiB0aGUgRFBSQU0gb24gYSA2NCBieXRlIGJvdW5kYXJ5LCBu
b3QgYXMgdGhlIFNDQzEsIHdoaWNoIG11c3QgYmUgIGF0IDB4ODAwMCBvZmZzZXQgb2YgdGhlIERQ
UkFNLg0KPj4gVGhlIFNNQzEgcGFyYW1zIGJhc2UgaXMgc2V0IGF0IDB4ODdGQyBvZmZzZXQgb2Yg
dGhlIERQUkFNLg0KPj4NCj4+IFNvIGlmICBJIHdhbnQgU01DMSBwYXJhbXMgc3RhcnQgYXQgIDB4
MjAwIGluIERQUkFNICAsIEkgc2hvdWxkIHNldCAweDIwMCB0byB0aGUgMHg4N0ZDIG9mZnNldCBv
ZiB0aGUgRFBSQU0uDQo+PiBJIGhhdmUgc2VlIHRoaXMgY29kZSBpbiB1LWJvb3QsIGJ1dCBJIGNh
biBub3QgZmluZCB0aGlzIGNvZGUgaW4gbmVpdGhlciBjcG1fdWFydF9jcG0yLmMgbm9yIGNwbV91
YXJ0X2NvcmUuYy4NCj4+DQo+PiBTaG91bGQgSSBhZGQgdGhlc2UgY29kZSB0byAgY3BtX3VhcnRf
Y29yZS5jPw0KPj4NCj4+IC0tZHBfbWVtID0gY3BtX2RwcmFtX2FkZHIoMHg4N2ZjKTsNCj4+IC0t
b3V0X2JlMTYoZHBfbWVtLCBTTUMxX0JBU0UpOw0KPiANCj4gV2h5IGFyZSB5b3UgbXVja2luZyBh
Ym91dCB3aXRoIHRoaXMgY29kZSBhdCBhbGw/ICBTTUN4IHNlcmlhbCBjZXJ0YWlubHkNCj4gd29y
a3Mgb24gZXZlcnkgcGxhdGZvcm0gSSd2ZSBldmVyIHVzZWQsIDh4eCBhbmQgOHh4eCBhcyB3ZWxs
Lg0KPiANCj4+IC0tLS0tIE9yaWdpbmFsIE1lc3NhZ2UgLS0tLS0NCj4+IEZyb206ICJTY290dCBX
b29kIjxzY290dHdvb2RAZnJlZXNjYWxlLmNvbT4NCj4+IFRvOiAiaGVsbG9oZWxsbyI8aGVsbG9o
ZWxsbzAwOEAxNjMuY29tPg0KPj4gQ2M6PGxpbnV4cHBjLWRldkBsaXN0cy5vemxhYnMub3JnPg0K
Pj4gU2VudDogRnJpZGF5LCBNYXkgMjEsIDIwMTAgMTowNiBBTQ0KPj4gU3ViamVjdDogUmU6IFBy
b2JsZW0gb2YgUG93ZXJQYyA4Mnh4IHdoZW4gdXNpbmcgc21jDQo+Pg0KPj4NCj4+PiBPbiBUaHUs
IE1heSAyMCwgMjAxMCBhdCAwNDo1ODoyN1BNICswODAwLCBoZWxsb2hlbGxvIHdyb3RlOg0KPj4+
Pg0KPj4+PiBJIGZpbmQgYSBwcm9ibGVtIGluDQo+Pj4+IGRyaXZlcnMvc2VyaWFsL2NwbV91YXJ0
L2NwbV91YXJ0X2NwbTIuYzoNCj4+Pj4gaW50IGNwbV91YXJ0X2FsbG9jYnVmKHN0cnVjdCB1YXJ0
X2NwbV9wb3J0ICpwaW5mbywgdW5zaWduZWQgaW50IGlzX2NvbikNCj4+Pj4gew0KPj4+PiAuLi4g
Li4uDQo+Pj4+IHBpbmZvLT50eF9iZF9iYXNlID0gcGluZm8tPnJ4X2JkX2Jhc2UgKyBwaW5mby0+
cnhfbnJmaWZvczsNCj4+Pj4gLypUaGUgYWJvdmUgbGluZSBzaG91bGQgYmUg77yaKi8NCj4+Pj4g
ICBwaW5mby0+dHhfYmRfYmFzZSA9IHBpbmZvLT5yeF9iZF9iYXNlICsgc2l6ZW9mKGNiZF90KSAq
IHBpbmZvLT5yeF9ucmZpZm9zOw0KPj4+DQo+Pj4gTm8sIGl0IHNob3VsZG4ndCAtLSByeF9iZF9i
YXNlIGlzIG9mIHR5cGUgImNiZF90ICoiLCBzbyB0aGUgbXVsdGlwbGljYXRpb24NCj4+PiBhbHJl
YWR5IGhhcHBlbnMgYXMgcGFydCBvZiBwb2ludGVyIGFyaXRobWV0aWMuDQo+Pj4NCj4+Pj4gcmV0
dXJuIDA7DQo+Pj4+IH0NCj4+Pj4NCj4+Pj4gV2hlcmUgdG8gZ2V0IHRoZSBuZXdlc3QgY29kZSBm
b3Iga2VybmVsPw0KPj4+DQo+Pj4gZ2l0Lmtlcm5lbC5vcmcNCj4+Pg0KPj4+PiBIb3cgdG8ga25v
dyB3aGV0aGVyIGl0IGlzIGFscmVhZHkgcGF0Y2hlZCBieSBhbnlvbmUgZWxzZT8gIEp1c3Qgc2Vh
cmNoIGluICB0aGlzIG1haWwgbGlzdD8NCj4+Pg0KPj4+IEFzIHdlbGwgYXMgdGhlIGN1cnJlbnQg
Z2l0IHRyZWUuDQo+Pj4NCj4+PiAtU2NvdHQNCj4+PiBfX19fX19fX19fX19fX19fX19fX19fX19f
X19fX19fX19fX19fX19fX19fX19fXw0KPj4+IExpbnV4cHBjLWRldiBtYWlsaW5nIGxpc3QNCj4+
PiBMaW51eHBwYy1kZXZAbGlzdHMub3psYWJzLm9yZw0KPj4+IGh0dHBzOi8vbGlzdHMub3psYWJz
Lm9yZy9saXN0aW5mby9saW51eHBwYy1kZXYNCj4+IF9fX19fX19fX19fX19fX19fX19fX19fX19f
X19fX19fX19fX19fX19fX19fX19fDQo+PiBMaW51eHBwYy1kZXYgbWFpbGluZyBsaXN0DQo+PiBM
aW51eHBwYy1kZXZAbGlzdHMub3psYWJzLm9yZw0KPj4gaHR0cHM6Ly9saXN0cy5vemxhYnMub3Jn
L2xpc3RpbmZvL2xpbnV4cHBjLWRldg0KPiANCj4gLS0gDQo+IC0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KPiBHYXJ5IFRob21hcyAg
ICAgICAgICAgICAgICAgfCAgQ29uc3VsdGluZyBmb3IgdGhlDQo+IE1MQiBBc3NvY2lhdGVzICAg
ICAgICAgICAgICB8ICAgIEVtYmVkZGVkIHdvcmxkDQo+IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KPiBfX19fX19fX19fX19fX19f
X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXw0KPiBMaW51eHBwYy1kZXYgbWFpbGluZyBs
aXN0DQo+IExpbnV4cHBjLWRldkBsaXN0cy5vemxhYnMub3JnDQo+IGh0dHBzOi8vbGlzdHMub3ps
YWJzLm9yZy9saXN0aW5mby9saW51eHBwYy1kZXY=
^ permalink raw reply
* Re: Problem of PowerPc 82xx when using smc
From: hellohello @ 2010-05-22 2:51 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev
In-Reply-To: <4BF6C2B2.6030705@freescale.com>
DQo+IE5ld2VyIGtlcm5lbHMgc3VwcG9ydCBkeW5hbWljYWxseSBhbGxvY2F0aW5nIHRoaXMgcGFy
YW1ldGVyIFJBTS4gIE9sZGVyIA0KPiBrZXJuZWxzIHVzZSB3aGF0ZXZlciB1LWJvb3QgY2hvc2Uu
DQo+IA0KPiBXaHkgZG8geW91IHdhbnQgdG8gc2V0IGl0IHRvIGEgcGFydGljdWxhciBhZGRyZXNz
Pw0KDQpUaGVyZSBzaG91bGQgYmUgc29tZSBjb2RlIHRvIHNldCBTTUMxX0JBU0UgdG8gdGhlIDB4
ODdGQyBvZmZzZXQgb2YgdGhlIERQUkFNLCB3aGF0ZXZlciBTTUMxX0JBU0UgaXMgZml4ZWQgb3Ig
ZHluYW1pY2FsbHkgYWxsb2NhdGVkIC4NCg0KTXkga2VybmVsIGlzIDIuNi4yNSwgdGhpcyBTTUMx
X0JBU0UgdmFsdWUgY2FuIGJlIHRyYW5zZmVycmVkIHRvICBrZXJuZWwgYnkgZHRzIHRyZWUsIGJ1
dCBJIGhhdmUgbm90IGZpbmQgdGhlIGNvZGUgdG8gc2V0IGl0IHRvICAweDg3RkMgb2Zmc2V0IG9m
IHRoZSBEUFJBTS4gT3IgdGhlcmUgaXMgYW5vdGhlciB3YXkgdG8gc29sdmUgaXQgPw0KDQoNCg0K
LS0tLS0gT3JpZ2luYWwgTWVzc2FnZSAtLS0tLSANCkZyb206ICJTY290dCBXb29kIiA8c2NvdHR3
b29kQGZyZWVzY2FsZS5jb20+DQpUbzogImhlbGxvaGVsbG8iIDxoZWxsb2hlbGxvMDA4QDE2My5j
b20+DQpDYzogPGxpbnV4cHBjLWRldkBsaXN0cy5vemxhYnMub3JnPg0KU2VudDogU2F0dXJkYXks
IE1heSAyMiwgMjAxMCAxOjI4IEFNDQpTdWJqZWN0OiBSZTogUHJvYmxlbSBvZiBQb3dlclBjIDgy
eHggd2hlbiB1c2luZyBzbWMNCg0KDQo+IE9uIDA1LzIwLzIwMTAgMTA6MzMgUE0sIGhlbGxvaGVs
bG8gd3JvdGU6DQo+Pj4gTm8sIGl0IHNob3VsZG4ndCAtLSByeF9iZF9iYXNlIGlzIG9mIHR5cGUg
ImNiZF90ICoiLCBzbyB0aGUgbXVsdGlwbGljYXRpb24NCj4+PiBhbHJlYWR5IGhhcHBlbnMgYXMg
cGFydCBvZiBwb2ludGVyIGFyaXRobWV0aWMuDQo+PiAtLS1ZZXMsIHlvdSBhcmUgcmlnaHQuIEkg
bWFkZSBhIGJhc2ljIG1pc3Rha2UuDQo+Pg0KPj4gQnV0IG5vdyBJIGhhdmUgYW5vdGhlciBxdWVz
dGlvbi4NCj4+IFRoZSBTTUMxIHBhcmFtcyBjYW4gYmUgcmVsb2NhdGVkIHRvIGFueSBvZmZzZXQg
b2YgdGhlIERQUkFNIG9uIGEgNjQgYnl0ZSBib3VuZGFyeSwgbm90IGFzIHRoZSBTQ0MxLCB3aGlj
aCBtdXN0IGJlICBhdCAweDgwMDAgb2Zmc2V0IG9mIHRoZSBEUFJBTS4NCj4+IFRoZSBTTUMxIHBh
cmFtcyBiYXNlIGlzIHNldCBhdCAweDg3RkMgb2Zmc2V0IG9mIHRoZSBEUFJBTS4NCj4+DQo+PiBT
byBpZiAgSSB3YW50IFNNQzEgcGFyYW1zIHN0YXJ0IGF0ICAweDIwMCBpbiBEUFJBTSAgLCBJIHNo
b3VsZCBzZXQgMHgyMDAgdG8gdGhlIDB4ODdGQyBvZmZzZXQgb2YgdGhlIERQUkFNLg0KPj4gSSBo
YXZlIHNlZSB0aGlzIGNvZGUgaW4gdS1ib290LCBidXQgSSBjYW4gbm90IGZpbmQgdGhpcyBjb2Rl
IGluIG5laXRoZXIgY3BtX3VhcnRfY3BtMi5jIG5vciBjcG1fdWFydF9jb3JlLmMuDQo+Pg0KPj4g
U2hvdWxkIEkgYWRkIHRoZXNlIGNvZGUgdG8gIGNwbV91YXJ0X2NvcmUuYz8NCj4gDQo+IE5ld2Vy
IGtlcm5lbHMgc3VwcG9ydCBkeW5hbWljYWxseSBhbGxvY2F0aW5nIHRoaXMgcGFyYW1ldGVyIFJB
TS4gIE9sZGVyIA0KPiBrZXJuZWxzIHVzZSB3aGF0ZXZlciB1LWJvb3QgY2hvc2UuDQo+IA0KPiBX
aHkgZG8geW91IHdhbnQgdG8gc2V0IGl0IHRvIGEgcGFydGljdWxhciBhZGRyZXNzPw0KPiANCj4g
LVNjb3R0DQo+
^ permalink raw reply
* Re: [git pull] Please pull powerpc.git next branch
From: Benjamin Herrenschmidt @ 2010-05-21 22:38 UTC (permalink / raw)
To: Wolfram Sang
Cc: linuxppc-dev list, Andrew Morton, Linus Torvalds,
Linux Kernel list
In-Reply-To: <20100521130417.GB27829@pengutronix.de>
On Fri, 2010-05-21 at 15:04 +0200, Wolfram Sang wrote:
> > Wolfram Sang (4):
> > powerpc/pmac: Fix dangling pointers
> > i2c/mpc: Drop NO_IRQ
> > i2c/cpm: Drop NO_IRQ
> > i2c/ibm-iic: Drop NO_IRQ
>
> Sorry for the confusion, but the other Ben (Dooks) has pushed those
> NO_IRQ-thigies meanwhile.
That shouldn't be a problem. git or Linus should sort it out easily :-)
I did a test merge before sending the pull request and there was nothing
it wouldn't resolve automatically.
Cheers,
Ben.
^ permalink raw reply
* Re: MBX drivers ads5121-rev4-v20090603
From: Andrey Volkov @ 2010-05-21 18:12 UTC (permalink / raw)
To: CTAG / Moisés Domínguez; +Cc: linuxppc-dev
In-Reply-To: <B597D6E3752845929B21C3369FB41730@ctag>
Hello Moisés,
CTAG / Moisés Domínguez wrote:
> Hi all,
>
> I am trying to use MBX 3D engine driver of my ads5121. AFAIK, drivers were
> built against same kernel as mine
i.e. 2.6.24.6 from LTIB? Kernel from Freescale's LTIB != vanilla 2.6.24.6
(number of patches vs vanilla kernel is more than 100)
> but I get problems for testing the demos and for loading the service:
>
I run demos on ADS without problems, except OGLESRenderToTexture (confirmed bug
in ALT's GL driver).
--
Regards
Andrey
> /[root@freescale /]# etc/init.d/rc.pvr start/
>
> /[ 29.526994] dbgdrv: module license 'unspecified' taints kernel./ /[
> 29.721065] _IORemapWrapper: mapping 1048576 bytes uncached from 0x80000000 to
> 0xe5280000/
>
> /… /
>
> * *
>
> I read in previous threads of this list about similar problems:
>
> - MBX on kernel 2.6.31:
> ttp://old.nabble.com/MPC5121ADS-PowerVR-MBX-driver-on-2.6.31-kernel--td26613966.html
>
>
> - MBX on kernel 2.6.24:
> http://lists.ozlabs.org/pipermail/linuxppc-dev/2009-February/067967.html
>
>
> According those posts, I would need to recompile modules against my kernel,
> but, of course, I do not have the sources. Reading ltib doc I read:
>
> /“Proprietary Packages:/
>
> /mbx_build13_binaries: This package provides proprietary binary kernel
> modules, libraries,/
>
> /and test code built from the MBX OpenGL ES DDK.”/
>
> / /
>
> Have anybody tested MBX demos provided with freescale SDK with ltib v20090603
> without having to recompile provided .ko’s?
>
> Regards,
>
> Moises
>
>
>
> /Board ads5121/
>
> /Ltib version 20090603/
>
> /Linux kernel version 2.6.24.6/
>
>
> ------------------------------------------------------------------------
>
> _______________________________________________ Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
^ permalink raw reply
* Re: Problem of PowerPc 82xx when using smc
From: Scott Wood @ 2010-05-21 17:28 UTC (permalink / raw)
To: hellohello; +Cc: linuxppc-dev
In-Reply-To: <051501caf896$5c954630$a51cbcc0@sfdomain.com>
On 05/20/2010 10:33 PM, hellohello wrote:
>> No, it shouldn't -- rx_bd_base is of type "cbd_t *", so the multiplication
>> already happens as part of pointer arithmetic.
> ---Yes, you are right. I made a basic mistake.
>
> But now I have another question.
> The SMC1 params can be relocated to any offset of the DPRAM on a 64 byte boundary, not as the SCC1, which must be at 0x8000 offset of the DPRAM.
> The SMC1 params base is set at 0x87FC offset of the DPRAM.
>
> So if I want SMC1 params start at 0x200 in DPRAM , I should set 0x200 to the 0x87FC offset of the DPRAM.
> I have see this code in u-boot, but I can not find this code in neither cpm_uart_cpm2.c nor cpm_uart_core.c.
>
> Should I add these code to cpm_uart_core.c?
Newer kernels support dynamically allocating this parameter RAM. Older
kernels use whatever u-boot chose.
Why do you want to set it to a particular address?
-Scott
^ permalink raw reply
* [RFC PATCH] powerpc: Emulate most load and store instructions in emulate_step()
From: Milton Miller @ 2010-05-21 16:35 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev, K.Prasad
In-Reply-To: <20100520124955.GA29903@brick.ozlabs.ibm.com>
[resending to hit the list]
> + if (regs->gpr[0] == 0x1ebe &&
> + cpu_has_feature(CPU_FTR_REAL_LE)) {
> + regs->msr ^= MSR_LE;
> + goto instr_done;
> + }
> regs->gpr[9] = regs->gpr[13];
> + regs->gpr[10] = MSR_KERNEL;
>
this hunk didn't seem to be mentioned in the change log
>+ static inline unsigned long xform_ea(unsigned int instr, struct pt_regs *regs)
..
> + if (ra) {
> + ea += regs->gpr[ra];
> + if (instr & 0x40) /* update forms */
> + regs->gpr[ra] = ea;
> + }
if the instruction faults, we shouldn't update ra
> + case 62: /* std[u] */
> + val = regs->gpr[rd];
> + switch (instr & 3) {
> + case 0: /* ld */
> + err = write_mem(val, dsform_ea(instr, regs), 8, regs);
> + goto ldst_done;
> + case 1: /* ldu */
> + err = write_mem(val, dsform_ea(instr, regs), 8, regs);
> + goto ldst_done;
> + }
> + break;
>
comments seem to be copied
milton
^ permalink raw reply
* [PATCH v2] powerpc/85xx: Add P1021MDS board support
From: Haiying Wang @ 2010-05-21 14:16 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1274449867.3003.2.camel@r54964-12.am.freescale.net>
P1021 is a dual e500v2 core based SOC with:
* 3 eTSECs (eTSEC1/3 RGMII, eTSEC2 SGMII on this board)
* 2 PCIe Controller
* 1 USB2.0 controller
* eSDHC, eSPI, I2C, DUART
* eLBC (NAND, BCSR, PMC0/1)
* Security Engine (SEC 3.3.2)
* Quicc Engine (QE)
Signed-off-by: Haiying Wang <Haiying.Wang@freescale.com>
Signed-off-by: Yu Liu <Yu.Liu@freescale.com>
---
v2: address the comments from Kumar.
arch/powerpc/boot/dts/p1021mds.dts | 698 +++++++++++++++++++++++++++++
arch/powerpc/platforms/85xx/mpc85xx_mds.c | 102 ++++-
2 files changed, 797 insertions(+), 3 deletions(-)
create mode 100644 arch/powerpc/boot/dts/p1021mds.dts
diff --git a/arch/powerpc/boot/dts/p1021mds.dts b/arch/powerpc/boot/dts/p1021mds.dts
new file mode 100644
index 0000000..7fad2df
--- /dev/null
+++ b/arch/powerpc/boot/dts/p1021mds.dts
@@ -0,0 +1,698 @@
+/*
+ * P1021 MDS Device Tree Source
+ *
+ * Copyright 2010 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/dts-v1/;
+/ {
+ model = "fsl,P1021";
+ compatible = "fsl,P1021MDS";
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ aliases {
+ serial0 = &serial0;
+ serial1 = &serial1;
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ ethernet2 = &enet2;
+ ethernet3 = &enet3;
+ ethernet4 = &enet4;
+ pci0 = &pci0;
+ pci1 = &pci1;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,P1021@0 {
+ device_type = "cpu";
+ reg = <0x0>;
+ next-level-cache = <&L2>;
+ };
+
+ PowerPC,P1021@1 {
+ device_type = "cpu";
+ reg = <0x1>;
+ next-level-cache = <&L2>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ };
+
+ localbus@ffe05000 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ compatible = "fsl,p1021-elbc", "fsl,elbc", "simple-bus";
+ reg = <0 0xffe05000 0 0x1000>;
+ interrupts = <19 2>;
+ interrupt-parent = <&mpic>;
+
+ /* NAND Flash, BCSR, PMC0/1*/
+ ranges = <0x0 0x0 0x0 0xfc000000 0x02000000
+ 0x1 0x0 0x0 0xf8000000 0x00008000
+ 0x2 0x0 0x0 0xf8010000 0x00020000
+ 0x3 0x0 0x0 0xf8020000 0x00020000>;
+
+ nand@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,p1021-fcm-nand",
+ "fsl,elbc-fcm-nand";
+ reg = <0x0 0x0 0x40000>;
+
+ partition@0 {
+ /* This location must not be altered */
+ /* 1MB for u-boot Bootloader Image */
+ reg = <0x0 0x00100000>;
+ label = "NAND (RO) U-Boot Image";
+ read-only;
+ };
+
+ partition@100000 {
+ /* 1MB for DTB Image */
+ reg = <0x00100000 0x00100000>;
+ label = "NAND (RO) DTB Image";
+ read-only;
+ };
+
+ partition@200000 {
+ /* 4MB for Linux Kernel Image */
+ reg = <0x00200000 0x00400000>;
+ label = "NAND (RO) Linux Kernel Image";
+ read-only;
+ };
+
+ partition@600000 {
+ /* 5MB for Compressed Root file System Image */
+ reg = <0x00600000 0x00500000>;
+ label = "NAND (RO) Compressed RFS Image";
+ read-only;
+ };
+
+ partition@b00000 {
+ /* 6MB for JFFS2 based Root file System */
+ reg = <0x00a00000 0x00600000>;
+ label = "NAND (RW) JFFS2 Root File System";
+ };
+
+ partition@1100000 {
+ /* 14MB for JFFS2 based Root file System */
+ reg = <0x01100000 0x00e00000>;
+ label = "NAND (RW) Writable User area";
+ };
+
+ partition@1f00000 {
+ /* 1MB for microcode */
+ reg = <0x01f00000 0x00100000>;
+ label = "NAND (RO) QE Ucode";
+ read-only;
+ };
+ };
+
+ bcsr@1,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,p1021mds-bcsr";
+ reg = <1 0 0x8000>;
+ ranges = <0 1 0 0x8000>;
+ };
+
+ pib@2,0 {
+ compatible = "fsl,p1021mds-pib";
+ reg = <2 0 0x10000>;
+ };
+
+ pib@3,0 {
+ compatible = "fsl,p1021mds-pib";
+ reg = <3 0 0x10000>;
+ };
+ };
+
+ soc@ffe00000 {
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "soc";
+ compatible = "fsl,p1021-immr", "simple-bus";
+ ranges = <0x0 0x0 0xffe00000 0x100000>;
+ bus-frequency = <0>; // Filled out by uboot.
+
+ ecm-law@0 {
+ compatible = "fsl,ecm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <12>;
+ };
+
+ ecm@1000 {
+ compatible = "fsl,p1021-ecm", "fsl,ecm";
+ reg = <0x1000 0x1000>;
+ interrupts = <16 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ memory-controller@2000 {
+ compatible = "fsl,p1021-memory-controller";
+ reg = <0x2000 0x1000>;
+ interrupt-parent = <&mpic>;
+ interrupts = <16 2>;
+ };
+
+ i2c@3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ compatible = "fsl-i2c";
+ reg = <0x3000 0x100>;
+ interrupts = <43 2>;
+ interrupt-parent = <&mpic>;
+ dfsrr;
+ rtc@68 {
+ compatible = "dallas,ds1374";
+ reg = <0x68>;
+ };
+ };
+
+ i2c@3100 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <1>;
+ compatible = "fsl-i2c";
+ reg = <0x3100 0x100>;
+ interrupts = <43 2>;
+ interrupt-parent = <&mpic>;
+ dfsrr;
+ };
+
+ serial0: serial@4500 {
+ cell-index = <0>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x4500 0x100>;
+ clock-frequency = <0>;
+ interrupts = <42 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ serial1: serial@4600 {
+ cell-index = <1>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x4600 0x100>;
+ clock-frequency = <0>;
+ interrupts = <42 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ spi@7000 {
+ cell-index = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,espi";
+ reg = <0x7000 0x1000>;
+ interrupts = <59 0x2>;
+ interrupt-parent = <&mpic>;
+ espi,num-ss-bits = <4>;
+ mode = "cpu";
+
+ fsl_m25p80@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,espi-flash";
+ reg = <0>;
+ linux,modalias = "fsl_m25p80";
+ spi-max-frequency = <40000000>; /* input clock */
+ partition@u-boot {
+ label = "u-boot-spi";
+ reg = <0x00000000 0x00100000>;
+ read-only;
+ };
+ partition@kernel {
+ label = "kernel-spi";
+ reg = <0x00100000 0x00500000>;
+ read-only;
+ };
+ partition@dtb {
+ label = "dtb-spi";
+ reg = <0x00600000 0x00100000>;
+ read-only;
+ };
+ partition@fs {
+ label = "file system-spi";
+ reg = <0x00700000 0x00900000>;
+ };
+ };
+ };
+
+ gpio: gpio-controller@f000 {
+ #gpio-cells = <2>;
+ compatible = "fsl,mpc8572-gpio";
+ reg = <0xf000 0x100>;
+ interrupts = <47 0x2>;
+ interrupt-parent = <&mpic>;
+ gpio-controller;
+ };
+
+ L2: l2-cache-controller@20000 {
+ compatible = "fsl,p1021-l2-cache-controller";
+ reg = <0x20000 0x1000>;
+ cache-line-size = <32>; // 32 bytes
+ cache-size = <0x40000>; // L2,256K
+ interrupt-parent = <&mpic>;
+ interrupts = <16 2>;
+ };
+
+ dma@21300 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,eloplus-dma";
+ reg = <0x21300 0x4>;
+ ranges = <0x0 0x21100 0x200>;
+ cell-index = <0>;
+ dma-channel@0 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x0 0x80>;
+ cell-index = <0>;
+ interrupt-parent = <&mpic>;
+ interrupts = <20 2>;
+ };
+ dma-channel@80 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x80 0x80>;
+ cell-index = <1>;
+ interrupt-parent = <&mpic>;
+ interrupts = <21 2>;
+ };
+ dma-channel@100 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x100 0x80>;
+ cell-index = <2>;
+ interrupt-parent = <&mpic>;
+ interrupts = <22 2>;
+ };
+ dma-channel@180 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x180 0x80>;
+ cell-index = <3>;
+ interrupt-parent = <&mpic>;
+ interrupts = <23 2>;
+ };
+ };
+
+ usb@22000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl-usb2-dr";
+ reg = <0x22000 0x1000>;
+ interrupt-parent = <&mpic>;
+ interrupts = <28 0x2>;
+ phy_type = "ulpi";
+ };
+
+ mdio@24000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,etsec2-mdio";
+ reg = <0x24000 0x1000 0xb0030 0x4>;
+
+ phy0: ethernet-phy@0 {
+ interrupt-parent = <&mpic>;
+ interrupts = <1 1>;
+ reg = <0x0>;
+ };
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&mpic>;
+ interrupts = <2 1>;
+ reg = <0x1>;
+ };
+ phy4: ethernet-phy@4 {
+ interrupt-parent = <&mpic>;
+ reg = <0x4>;
+ };
+ };
+
+ mdio@25000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,etsec2-tbi";
+ reg = <0x25000 0x1000 0xb1030 0x4>;
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet0: ethernet@B0000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <0>;
+ device_type = "network";
+ model = "eTSEC";
+ compatible = "fsl,etsec2";
+ fsl,num_rx_queues = <0x8>;
+ fsl,num_tx_queues = <0x8>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupt-parent = <&mpic>;
+ phy-handle = <&phy0>;
+ phy-connection-type = "rgmii-id";
+ queue-group@0{
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xB0000 0x1000>;
+ interrupts = <29 2 30 2 34 2>;
+ };
+ queue-group@1{
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xB4000 0x1000>;
+ interrupts = <17 2 18 2 24 2>;
+ };
+ };
+
+ enet1: ethernet@B1000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <0>;
+ device_type = "network";
+ model = "eTSEC";
+ compatible = "fsl,etsec2";
+ fsl,num_rx_queues = <0x8>;
+ fsl,num_tx_queues = <0x8>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupt-parent = <&mpic>;
+ phy-handle = <&phy4>;
+ tbi-handle = <&tbi0>;
+ phy-connection-type = "sgmii";
+ queue-group@0{
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xB1000 0x1000>;
+ interrupts = <35 2 36 2 40 2>;
+ };
+ queue-group@1{
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xB5000 0x1000>;
+ interrupts = <51 2 52 2 67 2>;
+ };
+ };
+
+ enet2: ethernet@B2000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <0>;
+ device_type = "network";
+ model = "eTSEC";
+ compatible = "fsl,etsec2";
+ fsl,num_rx_queues = <0x8>;
+ fsl,num_tx_queues = <0x8>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupt-parent = <&mpic>;
+ phy-handle = <&phy1>;
+ phy-connection-type = "rgmii-id";
+ queue-group@0{
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xB2000 0x1000>;
+ interrupts = <31 2 32 2 33 2>;
+ };
+ queue-group@1{
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xB6000 0x1000>;
+ interrupts = <25 2 26 2 27 2>;
+ };
+ };
+
+ sdhci@2e000 {
+ compatible = "fsl,p1021-esdhc", "fsl,esdhc";
+ reg = <0x2e000 0x1000>;
+ interrupts = <72 0x2>;
+ interrupt-parent = <&mpic>;
+ /* Filled in by U-Boot */
+ clock-frequency = <0>;
+ };
+
+ crypto@30000 {
+ compatible = "fsl,sec3.3", "fsl,sec3.1",
+ "fsl,sec3.0", "fsl,sec2.4",
+ "fsl,sec2.2", "fsl,sec2.1", "fsl,sec2.0";
+ reg = <0x30000 0x10000>;
+ interrupts = <45 2 58 2>;
+ interrupt-parent = <&mpic>;
+ fsl,num-channels = <4>;
+ fsl,channel-fifo-len = <24>;
+ fsl,exec-units-mask = <0x97c>;
+ fsl,descriptor-types-mask = <0x3a30abf>;
+ };
+
+ mpic: pic@40000 {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ reg = <0x40000 0x40000>;
+ compatible = "chrp,open-pic";
+ device_type = "open-pic";
+ };
+
+ msi@41600 {
+ compatible = "fsl,p1021-msi", "fsl,mpic-msi";
+ reg = <0x41600 0x80>;
+ msi-available-ranges = <0 0x100>;
+ interrupts = <
+ 0xe0 0
+ 0xe1 0
+ 0xe2 0
+ 0xe3 0
+ 0xe4 0
+ 0xe5 0
+ 0xe6 0
+ 0xe7 0>;
+ interrupt-parent = <&mpic>;
+ };
+
+ global-utilities@e0000 { //global utilities block
+ compatible = "fsl,p1021-guts";
+ reg = <0xe0000 0x1000>;
+ fsl,has-rstcr;
+ };
+
+ par_io@e0100 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xe0100 0x60>;
+ ranges = <0x0 0xe0100 0x60>;
+ device_type = "par_io";
+ num-ports = <3>;
+ pio1: ucc_pin@01 {
+ pio-map = <
+ /* port pin dir open_drain assignment has_irq */
+ 0x1 0x13 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
+ 0x1 0x14 0x3 0x0 0x1 0x0 /* QE_MUX_MDIO */
+ 0x0 0x17 0x2 0x0 0x2 0x0 /* CLK12 */
+ 0x0 0x18 0x2 0x0 0x1 0x0 /* CLK9
+*/
+ 0x0 0x7 0x1 0x0 0x2 0x0 /* ENET1_TXD0_SER1_TXD0 */
+ 0x0 0x9 0x1 0x0 0x2 0x0 /* ENET1_TXD1_SER1_TXD1 */
+ 0x0 0xb 0x1 0x0 0x2 0x0 /* ENET1_TXD2_SER1_TXD2 */
+ 0x0 0xc 0x1 0x0 0x2 0x0 /* ENET1_TXD3_SER1_TXD3 */
+ 0x0 0x6 0x2 0x0 0x2 0x0 /* ENET1_RXD0_SER1_RXD0 */
+ 0x0 0xa 0x2 0x0 0x2 0x0 /* ENET1_RXD1_SER1_RXD1 */
+ 0x0 0xe 0x2 0x0 0x2 0x0 /* ENET1_RXD2_SER1_RXD2 */
+ 0x0 0xf 0x2 0x0 0x2 0x0 /* ENET1_RXD3_SER1_RXD3 */
+ 0x0 0x5 0x1 0x0 0x2 0x0 /* ENET1_TX_EN_SER1_RTS_B */
+ 0x0 0xd 0x1 0x0 0x2 0x0 /* ENET1_TX_ER */
+ 0x0 0x4 0x2 0x0 0x2 0x0 /* ENET1_RX_DV_SER1_CTS_B */
+ 0x0 0x8 0x2 0x0 0x2 0x0 /* ENET1_RX_ER_SER1_CD_B */
+ 0x0 0x11 0x2 0x0 0x2 0x0 /* ENET1_CRS */
+ 0x0 0x10 0x2 0x0 0x2 0x0>; /* ENET1_COL */
+ };
+
+ pio2: ucc_pin@02 {
+ pio-map = <
+ /* port pin dir open_drain assignment has_irq */
+ 0x1 0x13 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
+ 0x1 0x14 0x3 0x0 0x1 0x0 /* QE_MUX_MDIO */
+ 0x1 0xb 0x2 0x0 0x1 0x0 /* CLK13 */
+ 0x1 0x7 0x1 0x0 0x2 0x0 /* ENET5_TXD0_SER5_TXD0 */
+ 0x1 0xa 0x1 0x0 0x2 0x0 /* ENET5_TXD1_SER5_TXD1 */
+ 0x1 0x6 0x2 0x0 0x2 0x0 /* ENET5_RXD0_SER5_RXD0 */
+ 0x1 0x9 0x2 0x0 0x2 0x0 /* ENET5_RXD1_SER5_RXD1 */
+ 0x1 0x5 0x1 0x0 0x2 0x0 /* ENET5_TX_EN_SER5_RTS_B */
+ 0x1 0x4 0x2 0x0 0x2 0x0 /* ENET5_RX_DV_SER5_CTS_B */
+ 0x1 0x8 0x2 0x0 0x2 0x0>; /* ENET5_RX_ER_SER5_CD_B */
+ };
+ };
+ };
+
+ pci0: pcie@ffe09000 {
+ compatible = "fsl,mpc8548-pcie";
+ device_type = "pci";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <0 0xffe09000 0 0x1000>;
+ bus-range = <0 255>;
+ ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
+ clock-frequency = <33333333>;
+ interrupt-parent = <&mpic>;
+ interrupts = <16 2>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0 0 1 &mpic 4 1
+ 0000 0 0 2 &mpic 5 1
+ 0000 0 0 3 &mpic 6 1
+ 0000 0 0 4 &mpic 7 1
+ >;
+ pcie@0 {
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ ranges = <0x2000000 0x0 0xa0000000
+ 0x2000000 0x0 0xa0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ pci1: pcie@ffe0a000 {
+ compatible = "fsl,mpc8548-pcie";
+ device_type = "pci";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <0 0xffe0a000 0 0x1000>;
+ bus-range = <0 255>;
+ ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>;
+ clock-frequency = <33333333>;
+ interrupt-parent = <&mpic>;
+ interrupts = <16 2>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0 0 1 &mpic 0 1
+ 0000 0 0 2 &mpic 1 1
+ 0000 0 0 3 &mpic 2 1
+ 0000 0 0 4 &mpic 3 1
+ >;
+ pcie@0 {
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ ranges = <0x2000000 0x0 0xc0000000
+ 0x2000000 0x0 0xc0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ qe@ffe80000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "qe";
+ compatible = "fsl,qe";
+ ranges = <0x0 0x0 0xffe80000 0x40000>;
+ reg = <0 0xffe80000 0 0x480>;
+ brg-frequency = <0>;
+ bus-frequency = <0>;
+ fsl,qe-num-riscs = <1>;
+ fsl,qe-num-snums = <28>;
+
+ qeic: interrupt-controller@80 {
+ interrupt-controller;
+ compatible = "fsl,qe-ic";
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ reg = <0x80 0x80>;
+ interrupts = <63 2 60 2>; //high:47 low:44
+ interrupt-parent = <&mpic>;
+ };
+
+ enet3: ucc@2000 {
+ device_type = "network";
+ compatible = "ucc_geth";
+ cell-index = <1>;
+ reg = <0x2000 0x200>;
+ interrupts = <32>;
+ interrupt-parent = <&qeic>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ rx-clock-name = "clk12";
+ tx-clock-name = "clk9";
+ pio-handle = <&pio1>;
+ phy-handle = <&qe_phy0>;
+ phy-connection-type = "mii";
+ };
+
+ mdio@2120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x2120 0x18>;
+ compatible = "fsl,ucc-mdio";
+
+ qe_phy0: ethernet-phy@0 {
+ interrupt-parent = <&mpic>;
+ interrupts = <4 1>;
+ reg = <0x0>;
+ device_type = "ethernet-phy";
+ };
+ qe_phy1: ethernet-phy@03 {
+ interrupt-parent = <&mpic>;
+ interrupts = <5 1>;
+ reg = <0x3>;
+ device_type = "ethernet-phy";
+ };
+ tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet4: ucc@2400 {
+ device_type = "network";
+ compatible = "ucc_geth";
+ cell-index = <5>;
+ reg = <0x2400 0x200>;
+ interrupts = <40>;
+ interrupt-parent = <&qeic>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ rx-clock-name = "none";
+ tx-clock-name = "clk13";
+ pio-handle = <&pio2>;
+ phy-handle = <&qe_phy1>;
+ phy-connection-type = "rmii";
+ };
+
+ muram@10000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,qe-muram", "fsl,cpm-muram";
+ ranges = <0x0 0x10000 0x6000>;
+
+ data-only@0 {
+ compatible = "fsl,qe-muram-data",
+ "fsl,cpm-muram-data";
+ reg = <0x0 0x6000>;
+ };
+ };
+ };
+};
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
index f0684c8..8fe87fc 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) Freescale Semicondutor, Inc. 2006-2007. All rights reserved.
+ * Copyright (C) Freescale Semicondutor, Inc. 2006-2010. All rights reserved.
*
* Author: Andy Fleming <afleming@freescale.com>
*
@@ -154,6 +154,10 @@ static int mpc8568_mds_phy_fixups(struct phy_device *phydev)
* Setup the architecture
*
*/
+#ifdef CONFIG_SMP
+extern void __init mpc85xx_smp_init(void);
+#endif
+
static void __init mpc85xx_mds_setup_arch(void)
{
struct device_node *np;
@@ -194,6 +198,10 @@ static void __init mpc85xx_mds_setup_arch(void)
}
#endif
+#ifdef CONFIG_SMP
+ mpc85xx_smp_init();
+#endif
+
#ifdef CONFIG_QUICC_ENGINE
np = of_find_compatible_node(NULL, NULL, "fsl,qe");
if (!np) {
@@ -271,9 +279,49 @@ static void __init mpc85xx_mds_setup_arch(void)
BCSR_UCC_RGMII, BCSR_UCC_RTBI);
}
+ } else if (machine_is(p1021_mds)) {
+#define BCSR11_ENET_MICRST (0x1 << 5)
+ /* Reset Micrel PHY */
+ clrbits8(&bcsr_regs[11], BCSR11_ENET_MICRST);
+ setbits8(&bcsr_regs[11], BCSR11_ENET_MICRST);
}
+
iounmap(bcsr_regs);
}
+
+ if (machine_is(p1021_mds)) {
+#define MPC85xx_PMUXCR_OFFSET 0x60
+#define MPC85xx_PMUXCR_QE0 0x00008000
+#define MPC85xx_PMUXCR_QE3 0x00001000
+#define MPC85xx_PMUXCR_QE9 0x00000040
+#define MPC85xx_PMUXCR_QE12 0x00000008
+ static __be32 __iomem *pmuxcr;
+
+ np = of_find_node_by_name(NULL, "global-utilities");
+
+ if (np) {
+ pmuxcr = of_iomap(np, 0) + MPC85xx_PMUXCR_OFFSET;
+
+ if (!pmuxcr)
+ printk(KERN_EMERG "Error: Alternate function"
+ " signal multiplex control register not"
+ " mapped!\n");
+ else
+ /* P1021 has pins muxed for QE and other functions. To
+ * enable QE UEC mode, we need to set bit QE0 for UCC1
+ * in Eth mode, QE0 and QE3 for UCC5 in Eth mode, QE9
+ * and QE12 for QE MII management singals in PMUXCR
+ * register.
+ */
+ setbits32(pmuxcr, MPC85xx_PMUXCR_QE0 |
+ MPC85xx_PMUXCR_QE3 |
+ MPC85xx_PMUXCR_QE9 |
+ MPC85xx_PMUXCR_QE12);
+
+ of_node_put(np);
+ }
+
+ }
#endif /* CONFIG_QUICC_ENGINE */
#ifdef CONFIG_SWIOTLB
@@ -330,6 +378,16 @@ static struct of_device_id mpc85xx_ids[] = {
{},
};
+static struct of_device_id p1021_ids[] = {
+ { .type = "soc", },
+ { .compatible = "soc", },
+ { .compatible = "simple-bus", },
+ { .type = "qe", },
+ { .compatible = "fsl,qe", },
+ { .compatible = "gianfar", },
+ {},
+};
+
static int __init mpc85xx_publish_devices(void)
{
if (machine_is(mpc8568_mds))
@@ -342,11 +400,22 @@ static int __init mpc85xx_publish_devices(void)
return 0;
}
+
+static int __init p1021_publish_devices(void)
+{
+ /* Publish the QE devices */
+ of_platform_bus_probe(NULL, p1021_ids, NULL);
+
+ return 0;
+}
+
machine_device_initcall(mpc8568_mds, mpc85xx_publish_devices);
machine_device_initcall(mpc8569_mds, mpc85xx_publish_devices);
+machine_device_initcall(p1021_mds, p1021_publish_devices);
machine_arch_initcall(mpc8568_mds, swiotlb_setup_bus_notifier);
machine_arch_initcall(mpc8569_mds, swiotlb_setup_bus_notifier);
+machine_arch_initcall(p1021_mds, swiotlb_setup_bus_notifier);
static void __init mpc85xx_mds_pic_init(void)
{
@@ -366,7 +435,7 @@ static void __init mpc85xx_mds_pic_init(void)
mpic = mpic_alloc(np, r.start,
MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN |
- MPIC_BROKEN_FRR_NIRQS,
+ MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU,
0, 256, " OpenPIC ");
BUG_ON(mpic == NULL);
of_node_put(np);
@@ -380,7 +449,11 @@ static void __init mpc85xx_mds_pic_init(void)
if (!np)
return;
}
- qe_ic_init(np, 0, qe_ic_cascade_muxed_mpic, NULL);
+ if (machine_is(p1021_mds))
+ qe_ic_init(np, 0, qe_ic_cascade_low_mpic,
+ qe_ic_cascade_high_mpic);
+ else
+ qe_ic_init(np, 0, qe_ic_cascade_muxed_mpic, NULL);
of_node_put(np);
#endif /* CONFIG_QUICC_ENGINE */
}
@@ -426,3 +499,26 @@ define_machine(mpc8569_mds) {
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
#endif
};
+
+static int __init p1021_mds_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+
+ return of_flat_dt_is_compatible(root, "fsl,P1021MDS");
+
+}
+
+define_machine(p1021_mds) {
+ .name = "P1021 MDS",
+ .probe = p1021_mds_probe,
+ .setup_arch = mpc85xx_mds_setup_arch,
+ .init_IRQ = mpc85xx_mds_pic_init,
+ .get_irq = mpic_get_irq,
+ .restart = fsl_rstcr_restart,
+ .calibrate_decr = generic_calibrate_decr,
+ .progress = udbg_progress,
+#ifdef CONFIG_PCI
+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
+#endif
+};
+
--
1.6.0.2
^ permalink raw reply related
* Re: [PATCH] powerpc/85xx: Add P1021MDS board support
From: Kumar Gala @ 2010-05-21 13:59 UTC (permalink / raw)
To: Haiying Wang; +Cc: linuxppc-dev
In-Reply-To: <1274449867.3003.2.camel@r54964-12.am.freescale.net>
>
> +
> + if (machine_is(p1021_mds)) {
> +#define MPC85xx_PMUXCR_OFFSET 0x60
> +#define MPC85xx_PMUXCR_QE0 0x00008000
> +#define MPC85xx_PMUXCR_QE3 0x00001000
> +#define MPC85xx_PMUXCR_QE9 0x00000040
> +#define MPC85xx_PMUXCR_QE12 0x00000008
> + static __be32 __iomem *pmuxcr;
> +
> + np = of_find_node_by_name(NULL, "global-utilities");
> +
> + if (np) {
> + pmuxcr = of_iomap(np, 0) + MPC85xx_PMUXCR_OFFSET;
> + if (!pmuxcr)
> + printk(KERN_EMERG "Error: Alternate function"
> + " signal multiplex control register not"
> + " mapped!\n");
if we error shouldn't we not do the setbit32?
> +
> + /* P1021 has pins muxed for QE and other functions. To
> + * enable QE UEC mode, we need to set bit QE0 for UCC1
> + * in Eth mode, QE0 and QE3 for UCC5 in Eth mode, QE9
> + * and QE12 for QE MII management singals in PMUXCR
> + * register.
> + */
> + setbits32(pmuxcr,
> + MPC85xx_PMUXCR_QE0 | MPC85xx_PMUXCR_QE3 |
> + MPC85xx_PMUXCR_QE9 | MPC85xx_PMUXCR_QE12);
> + }
> +
> + of_node_put(np);
> + }
> #endif /* CONFIG_QUICC_ENGINE */
>
> #ifdef CONFIG_SWIOTLB
> @@ -330,6 +375,16 @@ static struct of_device_id mpc85xx_ids[] = {
> {},
> };
>
> +static struct of_device_id p1021_ids[] = {
> + { .type = "soc", },
> + { .compatible = "soc", },
> + { .compatible = "simple-bus", },
> + { .type = "qe", },
> + { .compatible = "fsl,qe", },
> + { .compatible = "gianfar", },
> + {},
> +};
> +
> static int __init mpc85xx_publish_devices(void)
> {
> if (machine_is(mpc8568_mds))
> @@ -342,11 +397,22 @@ static int __init mpc85xx_publish_devices(void)
>
> return 0;
> }
> +
> +static int __init p1021_publish_devices(void)
> +{
> + /* Publish the QE devices */
> + of_platform_bus_probe(NULL, p1021_ids, NULL);
> +
> + return 0;
> +}
> +
> machine_device_initcall(mpc8568_mds, mpc85xx_publish_devices);
> machine_device_initcall(mpc8569_mds, mpc85xx_publish_devices);
> +machine_device_initcall(p1021_mds, p1021_publish_devices);
>
> machine_arch_initcall(mpc8568_mds, swiotlb_setup_bus_notifier);
> machine_arch_initcall(mpc8569_mds, swiotlb_setup_bus_notifier);
> +machine_arch_initcall(p1021_mds, swiotlb_setup_bus_notifier);
>
> static void __init mpc85xx_mds_pic_init(void)
> {
> @@ -366,7 +432,7 @@ static void __init mpc85xx_mds_pic_init(void)
>
> mpic = mpic_alloc(np, r.start,
> MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN |
> - MPIC_BROKEN_FRR_NIRQS,
> + MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU,
> 0, 256, " OpenPIC ");
> BUG_ON(mpic == NULL);
> of_node_put(np);
> @@ -380,7 +446,11 @@ static void __init mpc85xx_mds_pic_init(void)
> if (!np)
> return;
> }
> - qe_ic_init(np, 0, qe_ic_cascade_muxed_mpic, NULL);
> + if (machine_is(p1021_mds))
> + qe_ic_init(np, 0, qe_ic_cascade_low_mpic,
> + qe_ic_cascade_high_mpic);
> + else
> + qe_ic_init(np, 0, qe_ic_cascade_muxed_mpic, NULL);
> of_node_put(np);
> #endif /* CONFIG_QUICC_ENGINE */
> }
> @@ -426,3 +496,26 @@ define_machine(mpc8569_mds) {
> .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
> #endif
> };
> +
> +static int __init p1021_mds_probe(void)
> +{
> + unsigned long root = of_get_flat_dt_root();
> +
> + return of_flat_dt_is_compatible(root, "fsl,P1021MDS");
> +
> +}
> +
> +define_machine(p1021_mds) {
> + .name = "P1021 MDS",
> + .probe = p1021_mds_probe,
> + .setup_arch = mpc85xx_mds_setup_arch,
> + .init_IRQ = mpc85xx_mds_pic_init,
> + .get_irq = mpic_get_irq,
> + .restart = fsl_rstcr_restart,
> + .calibrate_decr = generic_calibrate_decr,
> + .progress = udbg_progress,
> +#ifdef CONFIG_PCI
> + .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
> +#endif
> +};
> +
> --
> 1.6.0.2
>
>
^ permalink raw reply
* [PATCH] powerpc/85xx: Add P1021MDS board support
From: Haiying Wang @ 2010-05-21 13:51 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <5D3C6BEB-8F69-407B-BE6D-C99D23EB90F4@kernel.crashing.org>
P1021 is a dual e500v2 core based SOC with:
* 3 eTSECs (eTSEC1/3 RGMII, eTSEC2 SGMII on this board)
* 2 PCIe Controller
* 1 USB2.0 controller
* eSDHC, eSPI, I2C, DUART
* eLBC (NAND, BCSR, PMC0/1)
* Security Engine (SEC 3.3.2)
* Quicc Engine (QE)
Signed-off-by: Haiying Wang <Haiying.Wang@freescale.com>
Signed-off-by: Yu Liu <Yu.Liu@freescale.com>
---
arch/powerpc/boot/dts/p1021mds.dts | 698 +++++++++++++++++++++++++++++
arch/powerpc/platforms/85xx/mpc85xx_mds.c | 99 ++++-
2 files changed, 794 insertions(+), 3 deletions(-)
create mode 100644 arch/powerpc/boot/dts/p1021mds.dts
diff --git a/arch/powerpc/boot/dts/p1021mds.dts b/arch/powerpc/boot/dts/p1021mds.dts
new file mode 100644
index 0000000..7fad2df
--- /dev/null
+++ b/arch/powerpc/boot/dts/p1021mds.dts
@@ -0,0 +1,698 @@
+/*
+ * P1021 MDS Device Tree Source
+ *
+ * Copyright 2010 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/dts-v1/;
+/ {
+ model = "fsl,P1021";
+ compatible = "fsl,P1021MDS";
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ aliases {
+ serial0 = &serial0;
+ serial1 = &serial1;
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ ethernet2 = &enet2;
+ ethernet3 = &enet3;
+ ethernet4 = &enet4;
+ pci0 = &pci0;
+ pci1 = &pci1;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,P1021@0 {
+ device_type = "cpu";
+ reg = <0x0>;
+ next-level-cache = <&L2>;
+ };
+
+ PowerPC,P1021@1 {
+ device_type = "cpu";
+ reg = <0x1>;
+ next-level-cache = <&L2>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ };
+
+ localbus@ffe05000 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ compatible = "fsl,p1021-elbc", "fsl,elbc", "simple-bus";
+ reg = <0 0xffe05000 0 0x1000>;
+ interrupts = <19 2>;
+ interrupt-parent = <&mpic>;
+
+ /* NAND Flash, BCSR, PMC0/1*/
+ ranges = <0x0 0x0 0x0 0xfc000000 0x02000000
+ 0x1 0x0 0x0 0xf8000000 0x00008000
+ 0x2 0x0 0x0 0xf8010000 0x00020000
+ 0x3 0x0 0x0 0xf8020000 0x00020000>;
+
+ nand@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,p1021-fcm-nand",
+ "fsl,elbc-fcm-nand";
+ reg = <0x0 0x0 0x40000>;
+
+ partition@0 {
+ /* This location must not be altered */
+ /* 1MB for u-boot Bootloader Image */
+ reg = <0x0 0x00100000>;
+ label = "NAND (RO) U-Boot Image";
+ read-only;
+ };
+
+ partition@100000 {
+ /* 1MB for DTB Image */
+ reg = <0x00100000 0x00100000>;
+ label = "NAND (RO) DTB Image";
+ read-only;
+ };
+
+ partition@200000 {
+ /* 4MB for Linux Kernel Image */
+ reg = <0x00200000 0x00400000>;
+ label = "NAND (RO) Linux Kernel Image";
+ read-only;
+ };
+
+ partition@600000 {
+ /* 5MB for Compressed Root file System Image */
+ reg = <0x00600000 0x00500000>;
+ label = "NAND (RO) Compressed RFS Image";
+ read-only;
+ };
+
+ partition@b00000 {
+ /* 6MB for JFFS2 based Root file System */
+ reg = <0x00a00000 0x00600000>;
+ label = "NAND (RW) JFFS2 Root File System";
+ };
+
+ partition@1100000 {
+ /* 14MB for JFFS2 based Root file System */
+ reg = <0x01100000 0x00e00000>;
+ label = "NAND (RW) Writable User area";
+ };
+
+ partition@1f00000 {
+ /* 1MB for microcode */
+ reg = <0x01f00000 0x00100000>;
+ label = "NAND (RO) QE Ucode";
+ read-only;
+ };
+ };
+
+ bcsr@1,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,p1021mds-bcsr";
+ reg = <1 0 0x8000>;
+ ranges = <0 1 0 0x8000>;
+ };
+
+ pib@2,0 {
+ compatible = "fsl,p1021mds-pib";
+ reg = <2 0 0x10000>;
+ };
+
+ pib@3,0 {
+ compatible = "fsl,p1021mds-pib";
+ reg = <3 0 0x10000>;
+ };
+ };
+
+ soc@ffe00000 {
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "soc";
+ compatible = "fsl,p1021-immr", "simple-bus";
+ ranges = <0x0 0x0 0xffe00000 0x100000>;
+ bus-frequency = <0>; // Filled out by uboot.
+
+ ecm-law@0 {
+ compatible = "fsl,ecm-law";
+ reg = <0x0 0x1000>;
+ fsl,num-laws = <12>;
+ };
+
+ ecm@1000 {
+ compatible = "fsl,p1021-ecm", "fsl,ecm";
+ reg = <0x1000 0x1000>;
+ interrupts = <16 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ memory-controller@2000 {
+ compatible = "fsl,p1021-memory-controller";
+ reg = <0x2000 0x1000>;
+ interrupt-parent = <&mpic>;
+ interrupts = <16 2>;
+ };
+
+ i2c@3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ compatible = "fsl-i2c";
+ reg = <0x3000 0x100>;
+ interrupts = <43 2>;
+ interrupt-parent = <&mpic>;
+ dfsrr;
+ rtc@68 {
+ compatible = "dallas,ds1374";
+ reg = <0x68>;
+ };
+ };
+
+ i2c@3100 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <1>;
+ compatible = "fsl-i2c";
+ reg = <0x3100 0x100>;
+ interrupts = <43 2>;
+ interrupt-parent = <&mpic>;
+ dfsrr;
+ };
+
+ serial0: serial@4500 {
+ cell-index = <0>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x4500 0x100>;
+ clock-frequency = <0>;
+ interrupts = <42 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ serial1: serial@4600 {
+ cell-index = <1>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x4600 0x100>;
+ clock-frequency = <0>;
+ interrupts = <42 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ spi@7000 {
+ cell-index = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,espi";
+ reg = <0x7000 0x1000>;
+ interrupts = <59 0x2>;
+ interrupt-parent = <&mpic>;
+ espi,num-ss-bits = <4>;
+ mode = "cpu";
+
+ fsl_m25p80@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,espi-flash";
+ reg = <0>;
+ linux,modalias = "fsl_m25p80";
+ spi-max-frequency = <40000000>; /* input clock */
+ partition@u-boot {
+ label = "u-boot-spi";
+ reg = <0x00000000 0x00100000>;
+ read-only;
+ };
+ partition@kernel {
+ label = "kernel-spi";
+ reg = <0x00100000 0x00500000>;
+ read-only;
+ };
+ partition@dtb {
+ label = "dtb-spi";
+ reg = <0x00600000 0x00100000>;
+ read-only;
+ };
+ partition@fs {
+ label = "file system-spi";
+ reg = <0x00700000 0x00900000>;
+ };
+ };
+ };
+
+ gpio: gpio-controller@f000 {
+ #gpio-cells = <2>;
+ compatible = "fsl,mpc8572-gpio";
+ reg = <0xf000 0x100>;
+ interrupts = <47 0x2>;
+ interrupt-parent = <&mpic>;
+ gpio-controller;
+ };
+
+ L2: l2-cache-controller@20000 {
+ compatible = "fsl,p1021-l2-cache-controller";
+ reg = <0x20000 0x1000>;
+ cache-line-size = <32>; // 32 bytes
+ cache-size = <0x40000>; // L2,256K
+ interrupt-parent = <&mpic>;
+ interrupts = <16 2>;
+ };
+
+ dma@21300 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,eloplus-dma";
+ reg = <0x21300 0x4>;
+ ranges = <0x0 0x21100 0x200>;
+ cell-index = <0>;
+ dma-channel@0 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x0 0x80>;
+ cell-index = <0>;
+ interrupt-parent = <&mpic>;
+ interrupts = <20 2>;
+ };
+ dma-channel@80 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x80 0x80>;
+ cell-index = <1>;
+ interrupt-parent = <&mpic>;
+ interrupts = <21 2>;
+ };
+ dma-channel@100 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x100 0x80>;
+ cell-index = <2>;
+ interrupt-parent = <&mpic>;
+ interrupts = <22 2>;
+ };
+ dma-channel@180 {
+ compatible = "fsl,eloplus-dma-channel";
+ reg = <0x180 0x80>;
+ cell-index = <3>;
+ interrupt-parent = <&mpic>;
+ interrupts = <23 2>;
+ };
+ };
+
+ usb@22000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl-usb2-dr";
+ reg = <0x22000 0x1000>;
+ interrupt-parent = <&mpic>;
+ interrupts = <28 0x2>;
+ phy_type = "ulpi";
+ };
+
+ mdio@24000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,etsec2-mdio";
+ reg = <0x24000 0x1000 0xb0030 0x4>;
+
+ phy0: ethernet-phy@0 {
+ interrupt-parent = <&mpic>;
+ interrupts = <1 1>;
+ reg = <0x0>;
+ };
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&mpic>;
+ interrupts = <2 1>;
+ reg = <0x1>;
+ };
+ phy4: ethernet-phy@4 {
+ interrupt-parent = <&mpic>;
+ reg = <0x4>;
+ };
+ };
+
+ mdio@25000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,etsec2-tbi";
+ reg = <0x25000 0x1000 0xb1030 0x4>;
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet0: ethernet@B0000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <0>;
+ device_type = "network";
+ model = "eTSEC";
+ compatible = "fsl,etsec2";
+ fsl,num_rx_queues = <0x8>;
+ fsl,num_tx_queues = <0x8>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupt-parent = <&mpic>;
+ phy-handle = <&phy0>;
+ phy-connection-type = "rgmii-id";
+ queue-group@0{
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xB0000 0x1000>;
+ interrupts = <29 2 30 2 34 2>;
+ };
+ queue-group@1{
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xB4000 0x1000>;
+ interrupts = <17 2 18 2 24 2>;
+ };
+ };
+
+ enet1: ethernet@B1000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <0>;
+ device_type = "network";
+ model = "eTSEC";
+ compatible = "fsl,etsec2";
+ fsl,num_rx_queues = <0x8>;
+ fsl,num_tx_queues = <0x8>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupt-parent = <&mpic>;
+ phy-handle = <&phy4>;
+ tbi-handle = <&tbi0>;
+ phy-connection-type = "sgmii";
+ queue-group@0{
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xB1000 0x1000>;
+ interrupts = <35 2 36 2 40 2>;
+ };
+ queue-group@1{
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xB5000 0x1000>;
+ interrupts = <51 2 52 2 67 2>;
+ };
+ };
+
+ enet2: ethernet@B2000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <0>;
+ device_type = "network";
+ model = "eTSEC";
+ compatible = "fsl,etsec2";
+ fsl,num_rx_queues = <0x8>;
+ fsl,num_tx_queues = <0x8>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupt-parent = <&mpic>;
+ phy-handle = <&phy1>;
+ phy-connection-type = "rgmii-id";
+ queue-group@0{
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xB2000 0x1000>;
+ interrupts = <31 2 32 2 33 2>;
+ };
+ queue-group@1{
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xB6000 0x1000>;
+ interrupts = <25 2 26 2 27 2>;
+ };
+ };
+
+ sdhci@2e000 {
+ compatible = "fsl,p1021-esdhc", "fsl,esdhc";
+ reg = <0x2e000 0x1000>;
+ interrupts = <72 0x2>;
+ interrupt-parent = <&mpic>;
+ /* Filled in by U-Boot */
+ clock-frequency = <0>;
+ };
+
+ crypto@30000 {
+ compatible = "fsl,sec3.3", "fsl,sec3.1",
+ "fsl,sec3.0", "fsl,sec2.4",
+ "fsl,sec2.2", "fsl,sec2.1", "fsl,sec2.0";
+ reg = <0x30000 0x10000>;
+ interrupts = <45 2 58 2>;
+ interrupt-parent = <&mpic>;
+ fsl,num-channels = <4>;
+ fsl,channel-fifo-len = <24>;
+ fsl,exec-units-mask = <0x97c>;
+ fsl,descriptor-types-mask = <0x3a30abf>;
+ };
+
+ mpic: pic@40000 {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ reg = <0x40000 0x40000>;
+ compatible = "chrp,open-pic";
+ device_type = "open-pic";
+ };
+
+ msi@41600 {
+ compatible = "fsl,p1021-msi", "fsl,mpic-msi";
+ reg = <0x41600 0x80>;
+ msi-available-ranges = <0 0x100>;
+ interrupts = <
+ 0xe0 0
+ 0xe1 0
+ 0xe2 0
+ 0xe3 0
+ 0xe4 0
+ 0xe5 0
+ 0xe6 0
+ 0xe7 0>;
+ interrupt-parent = <&mpic>;
+ };
+
+ global-utilities@e0000 { //global utilities block
+ compatible = "fsl,p1021-guts";
+ reg = <0xe0000 0x1000>;
+ fsl,has-rstcr;
+ };
+
+ par_io@e0100 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xe0100 0x60>;
+ ranges = <0x0 0xe0100 0x60>;
+ device_type = "par_io";
+ num-ports = <3>;
+ pio1: ucc_pin@01 {
+ pio-map = <
+ /* port pin dir open_drain assignment has_irq */
+ 0x1 0x13 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
+ 0x1 0x14 0x3 0x0 0x1 0x0 /* QE_MUX_MDIO */
+ 0x0 0x17 0x2 0x0 0x2 0x0 /* CLK12 */
+ 0x0 0x18 0x2 0x0 0x1 0x0 /* CLK9
+*/
+ 0x0 0x7 0x1 0x0 0x2 0x0 /* ENET1_TXD0_SER1_TXD0 */
+ 0x0 0x9 0x1 0x0 0x2 0x0 /* ENET1_TXD1_SER1_TXD1 */
+ 0x0 0xb 0x1 0x0 0x2 0x0 /* ENET1_TXD2_SER1_TXD2 */
+ 0x0 0xc 0x1 0x0 0x2 0x0 /* ENET1_TXD3_SER1_TXD3 */
+ 0x0 0x6 0x2 0x0 0x2 0x0 /* ENET1_RXD0_SER1_RXD0 */
+ 0x0 0xa 0x2 0x0 0x2 0x0 /* ENET1_RXD1_SER1_RXD1 */
+ 0x0 0xe 0x2 0x0 0x2 0x0 /* ENET1_RXD2_SER1_RXD2 */
+ 0x0 0xf 0x2 0x0 0x2 0x0 /* ENET1_RXD3_SER1_RXD3 */
+ 0x0 0x5 0x1 0x0 0x2 0x0 /* ENET1_TX_EN_SER1_RTS_B */
+ 0x0 0xd 0x1 0x0 0x2 0x0 /* ENET1_TX_ER */
+ 0x0 0x4 0x2 0x0 0x2 0x0 /* ENET1_RX_DV_SER1_CTS_B */
+ 0x0 0x8 0x2 0x0 0x2 0x0 /* ENET1_RX_ER_SER1_CD_B */
+ 0x0 0x11 0x2 0x0 0x2 0x0 /* ENET1_CRS */
+ 0x0 0x10 0x2 0x0 0x2 0x0>; /* ENET1_COL */
+ };
+
+ pio2: ucc_pin@02 {
+ pio-map = <
+ /* port pin dir open_drain assignment has_irq */
+ 0x1 0x13 0x1 0x0 0x1 0x0 /* QE_MUX_MDC */
+ 0x1 0x14 0x3 0x0 0x1 0x0 /* QE_MUX_MDIO */
+ 0x1 0xb 0x2 0x0 0x1 0x0 /* CLK13 */
+ 0x1 0x7 0x1 0x0 0x2 0x0 /* ENET5_TXD0_SER5_TXD0 */
+ 0x1 0xa 0x1 0x0 0x2 0x0 /* ENET5_TXD1_SER5_TXD1 */
+ 0x1 0x6 0x2 0x0 0x2 0x0 /* ENET5_RXD0_SER5_RXD0 */
+ 0x1 0x9 0x2 0x0 0x2 0x0 /* ENET5_RXD1_SER5_RXD1 */
+ 0x1 0x5 0x1 0x0 0x2 0x0 /* ENET5_TX_EN_SER5_RTS_B */
+ 0x1 0x4 0x2 0x0 0x2 0x0 /* ENET5_RX_DV_SER5_CTS_B */
+ 0x1 0x8 0x2 0x0 0x2 0x0>; /* ENET5_RX_ER_SER5_CD_B */
+ };
+ };
+ };
+
+ pci0: pcie@ffe09000 {
+ compatible = "fsl,mpc8548-pcie";
+ device_type = "pci";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <0 0xffe09000 0 0x1000>;
+ bus-range = <0 255>;
+ ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
+ clock-frequency = <33333333>;
+ interrupt-parent = <&mpic>;
+ interrupts = <16 2>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0 0 1 &mpic 4 1
+ 0000 0 0 2 &mpic 5 1
+ 0000 0 0 3 &mpic 6 1
+ 0000 0 0 4 &mpic 7 1
+ >;
+ pcie@0 {
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ ranges = <0x2000000 0x0 0xa0000000
+ 0x2000000 0x0 0xa0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ pci1: pcie@ffe0a000 {
+ compatible = "fsl,mpc8548-pcie";
+ device_type = "pci";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <0 0xffe0a000 0 0x1000>;
+ bus-range = <0 255>;
+ ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>;
+ clock-frequency = <33333333>;
+ interrupt-parent = <&mpic>;
+ interrupts = <16 2>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0 0 1 &mpic 0 1
+ 0000 0 0 2 &mpic 1 1
+ 0000 0 0 3 &mpic 2 1
+ 0000 0 0 4 &mpic 3 1
+ >;
+ pcie@0 {
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ ranges = <0x2000000 0x0 0xc0000000
+ 0x2000000 0x0 0xc0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x100000>;
+ };
+ };
+
+ qe@ffe80000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "qe";
+ compatible = "fsl,qe";
+ ranges = <0x0 0x0 0xffe80000 0x40000>;
+ reg = <0 0xffe80000 0 0x480>;
+ brg-frequency = <0>;
+ bus-frequency = <0>;
+ fsl,qe-num-riscs = <1>;
+ fsl,qe-num-snums = <28>;
+
+ qeic: interrupt-controller@80 {
+ interrupt-controller;
+ compatible = "fsl,qe-ic";
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ reg = <0x80 0x80>;
+ interrupts = <63 2 60 2>; //high:47 low:44
+ interrupt-parent = <&mpic>;
+ };
+
+ enet3: ucc@2000 {
+ device_type = "network";
+ compatible = "ucc_geth";
+ cell-index = <1>;
+ reg = <0x2000 0x200>;
+ interrupts = <32>;
+ interrupt-parent = <&qeic>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ rx-clock-name = "clk12";
+ tx-clock-name = "clk9";
+ pio-handle = <&pio1>;
+ phy-handle = <&qe_phy0>;
+ phy-connection-type = "mii";
+ };
+
+ mdio@2120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x2120 0x18>;
+ compatible = "fsl,ucc-mdio";
+
+ qe_phy0: ethernet-phy@0 {
+ interrupt-parent = <&mpic>;
+ interrupts = <4 1>;
+ reg = <0x0>;
+ device_type = "ethernet-phy";
+ };
+ qe_phy1: ethernet-phy@03 {
+ interrupt-parent = <&mpic>;
+ interrupts = <5 1>;
+ reg = <0x3>;
+ device_type = "ethernet-phy";
+ };
+ tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+
+ enet4: ucc@2400 {
+ device_type = "network";
+ compatible = "ucc_geth";
+ cell-index = <5>;
+ reg = <0x2400 0x200>;
+ interrupts = <40>;
+ interrupt-parent = <&qeic>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ rx-clock-name = "none";
+ tx-clock-name = "clk13";
+ pio-handle = <&pio2>;
+ phy-handle = <&qe_phy1>;
+ phy-connection-type = "rmii";
+ };
+
+ muram@10000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,qe-muram", "fsl,cpm-muram";
+ ranges = <0x0 0x10000 0x6000>;
+
+ data-only@0 {
+ compatible = "fsl,qe-muram-data",
+ "fsl,cpm-muram-data";
+ reg = <0x0 0x6000>;
+ };
+ };
+ };
+};
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
index f0684c8..f8ec474 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) Freescale Semicondutor, Inc. 2006-2007. All rights reserved.
+ * Copyright (C) Freescale Semicondutor, Inc. 2006-2010. All rights reserved.
*
* Author: Andy Fleming <afleming@freescale.com>
*
@@ -154,6 +154,10 @@ static int mpc8568_mds_phy_fixups(struct phy_device *phydev)
* Setup the architecture
*
*/
+#ifdef CONFIG_SMP
+extern void __init mpc85xx_smp_init(void);
+#endif
+
static void __init mpc85xx_mds_setup_arch(void)
{
struct device_node *np;
@@ -194,6 +198,10 @@ static void __init mpc85xx_mds_setup_arch(void)
}
#endif
+#ifdef CONFIG_SMP
+ mpc85xx_smp_init();
+#endif
+
#ifdef CONFIG_QUICC_ENGINE
np = of_find_compatible_node(NULL, NULL, "fsl,qe");
if (!np) {
@@ -271,9 +279,46 @@ static void __init mpc85xx_mds_setup_arch(void)
BCSR_UCC_RGMII, BCSR_UCC_RTBI);
}
+ } else if (machine_is(p1021_mds)) {
+#define BCSR11_ENET_MICRST (0x1 << 5)
+ /* Reset Micrel PHY */
+ clrbits8(&bcsr_regs[11], BCSR11_ENET_MICRST);
+ setbits8(&bcsr_regs[11], BCSR11_ENET_MICRST);
}
+
iounmap(bcsr_regs);
}
+
+ if (machine_is(p1021_mds)) {
+#define MPC85xx_PMUXCR_OFFSET 0x60
+#define MPC85xx_PMUXCR_QE0 0x00008000
+#define MPC85xx_PMUXCR_QE3 0x00001000
+#define MPC85xx_PMUXCR_QE9 0x00000040
+#define MPC85xx_PMUXCR_QE12 0x00000008
+ static __be32 __iomem *pmuxcr;
+
+ np = of_find_node_by_name(NULL, "global-utilities");
+
+ if (np) {
+ pmuxcr = of_iomap(np, 0) + MPC85xx_PMUXCR_OFFSET;
+ if (!pmuxcr)
+ printk(KERN_EMERG "Error: Alternate function"
+ " signal multiplex control register not"
+ " mapped!\n");
+
+ /* P1021 has pins muxed for QE and other functions. To
+ * enable QE UEC mode, we need to set bit QE0 for UCC1
+ * in Eth mode, QE0 and QE3 for UCC5 in Eth mode, QE9
+ * and QE12 for QE MII management singals in PMUXCR
+ * register.
+ */
+ setbits32(pmuxcr,
+ MPC85xx_PMUXCR_QE0 | MPC85xx_PMUXCR_QE3 |
+ MPC85xx_PMUXCR_QE9 | MPC85xx_PMUXCR_QE12);
+ }
+
+ of_node_put(np);
+ }
#endif /* CONFIG_QUICC_ENGINE */
#ifdef CONFIG_SWIOTLB
@@ -330,6 +375,16 @@ static struct of_device_id mpc85xx_ids[] = {
{},
};
+static struct of_device_id p1021_ids[] = {
+ { .type = "soc", },
+ { .compatible = "soc", },
+ { .compatible = "simple-bus", },
+ { .type = "qe", },
+ { .compatible = "fsl,qe", },
+ { .compatible = "gianfar", },
+ {},
+};
+
static int __init mpc85xx_publish_devices(void)
{
if (machine_is(mpc8568_mds))
@@ -342,11 +397,22 @@ static int __init mpc85xx_publish_devices(void)
return 0;
}
+
+static int __init p1021_publish_devices(void)
+{
+ /* Publish the QE devices */
+ of_platform_bus_probe(NULL, p1021_ids, NULL);
+
+ return 0;
+}
+
machine_device_initcall(mpc8568_mds, mpc85xx_publish_devices);
machine_device_initcall(mpc8569_mds, mpc85xx_publish_devices);
+machine_device_initcall(p1021_mds, p1021_publish_devices);
machine_arch_initcall(mpc8568_mds, swiotlb_setup_bus_notifier);
machine_arch_initcall(mpc8569_mds, swiotlb_setup_bus_notifier);
+machine_arch_initcall(p1021_mds, swiotlb_setup_bus_notifier);
static void __init mpc85xx_mds_pic_init(void)
{
@@ -366,7 +432,7 @@ static void __init mpc85xx_mds_pic_init(void)
mpic = mpic_alloc(np, r.start,
MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN |
- MPIC_BROKEN_FRR_NIRQS,
+ MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU,
0, 256, " OpenPIC ");
BUG_ON(mpic == NULL);
of_node_put(np);
@@ -380,7 +446,11 @@ static void __init mpc85xx_mds_pic_init(void)
if (!np)
return;
}
- qe_ic_init(np, 0, qe_ic_cascade_muxed_mpic, NULL);
+ if (machine_is(p1021_mds))
+ qe_ic_init(np, 0, qe_ic_cascade_low_mpic,
+ qe_ic_cascade_high_mpic);
+ else
+ qe_ic_init(np, 0, qe_ic_cascade_muxed_mpic, NULL);
of_node_put(np);
#endif /* CONFIG_QUICC_ENGINE */
}
@@ -426,3 +496,26 @@ define_machine(mpc8569_mds) {
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
#endif
};
+
+static int __init p1021_mds_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+
+ return of_flat_dt_is_compatible(root, "fsl,P1021MDS");
+
+}
+
+define_machine(p1021_mds) {
+ .name = "P1021 MDS",
+ .probe = p1021_mds_probe,
+ .setup_arch = mpc85xx_mds_setup_arch,
+ .init_IRQ = mpc85xx_mds_pic_init,
+ .get_irq = mpic_get_irq,
+ .restart = fsl_rstcr_restart,
+ .calibrate_decr = generic_calibrate_decr,
+ .progress = udbg_progress,
+#ifdef CONFIG_PCI
+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
+#endif
+};
+
--
1.6.0.2
^ permalink raw reply related
* Re: [git pull] Please pull powerpc.git next branch
From: Wolfram Sang @ 2010-05-21 13:04 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: linuxppc-dev list, Andrew Morton, Linus Torvalds,
Linux Kernel list
In-Reply-To: <1274433088.1931.63.camel@pasglop>
[-- Attachment #1: Type: text/plain, Size: 417 bytes --]
> Wolfram Sang (4):
> powerpc/pmac: Fix dangling pointers
> i2c/mpc: Drop NO_IRQ
> i2c/cpm: Drop NO_IRQ
> i2c/ibm-iic: Drop NO_IRQ
Sorry for the confusion, but the other Ben (Dooks) has pushed those
NO_IRQ-thigies meanwhile.
--
Pengutronix e.K. | Wolfram Sang |
Industrial Linux Solutions | http://www.pengutronix.de/ |
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply
* Re: [git pull] Please pull powerpc.git next branch
From: Benjamin Herrenschmidt @ 2010-05-21 12:42 UTC (permalink / raw)
To: Josh Boyer; +Cc: linuxppc-dev list
In-Reply-To: <20100521102255.GC24511@zod.rchland.ibm.com>
On Fri, 2010-05-21 at 06:22 -0400, Josh Boyer wrote:
> On Fri, May 21, 2010 at 07:11:28PM +1000, Benjamin Herrenschmidt wrote:
> >Hi Linus !
> >
> >Here's the powerpc batch for this merge window.
> >
> >Most of it is in arch/powerpc, a few powerpc specific drivers are hit
> >too, including removing one that has been unused (and unselectable in
> >Kconfig) for a long time (hdpuftrs), probably remains of a long dead
> >platform.
>
> You missed my updated pull request. I still have some patches sitting in my
> -next branch that should go in.
Allright, I'll add them asap. Might have to wait for monday tho.
Cheers,
Ben.
^ permalink raw reply
* Re: Problem of PowerPc 82xx when using smc
From: Gary Thomas @ 2010-05-21 11:20 UTC (permalink / raw)
To: hellohello; +Cc: Scott Wood, linuxppc-dev
In-Reply-To: <051501caf896$5c954630$a51cbcc0@sfdomain.com>
On 05/20/2010 09:33 PM, hellohello wrote:
>> No, it shouldn't -- rx_bd_base is of type "cbd_t *", so the multiplication
>> already happens as part of pointer arithmetic.
> ---Yes, you are right. I made a basic mistake.
>
> But now I have another question.
> The SMC1 params can be relocated to any offset of the DPRAM on a 64 byte boundary, not as the SCC1, which must be at 0x8000 offset of the DPRAM.
> The SMC1 params base is set at 0x87FC offset of the DPRAM.
>
> So if I want SMC1 params start at 0x200 in DPRAM , I should set 0x200 to the 0x87FC offset of the DPRAM.
> I have see this code in u-boot, but I can not find this code in neither cpm_uart_cpm2.c nor cpm_uart_core.c.
>
> Should I add these code to cpm_uart_core.c?
>
> --dp_mem = cpm_dpram_addr(0x87fc);
> --out_be16(dp_mem, SMC1_BASE);
Why are you mucking about with this code at all? SMCx serial certainly
works on every platform I've ever used, 8xx and 8xxx as well.
> ----- Original Message -----
> From: "Scott Wood"<scottwood@freescale.com>
> To: "hellohello"<hellohello008@163.com>
> Cc:<linuxppc-dev@lists.ozlabs.org>
> Sent: Friday, May 21, 2010 1:06 AM
> Subject: Re: Problem of PowerPc 82xx when using smc
>
>
>> On Thu, May 20, 2010 at 04:58:27PM +0800, hellohello wrote:
>>>
>>> I find a problem in
>>> drivers/serial/cpm_uart/cpm_uart_cpm2.c:
>>> int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con)
>>> {
>>> ... ...
>>> pinfo->tx_bd_base = pinfo->rx_bd_base + pinfo->rx_nrfifos;
>>> /*The above line should be :*/
>>> pinfo->tx_bd_base = pinfo->rx_bd_base + sizeof(cbd_t) * pinfo->rx_nrfifos;
>>
>> No, it shouldn't -- rx_bd_base is of type "cbd_t *", so the multiplication
>> already happens as part of pointer arithmetic.
>>
>>> return 0;
>>> }
>>>
>>> Where to get the newest code for kernel?
>>
>> git.kernel.org
>>
>>> How to know whether it is already patched by anyone else? Just search in this mail list?
>>
>> As well as the current git tree.
>>
>> -Scott
>> _______________________________________________
>> Linuxppc-dev mailing list
>> Linuxppc-dev@lists.ozlabs.org
>> https://lists.ozlabs.org/listinfo/linuxppc-dev
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
--
------------------------------------------------------------
Gary Thomas | Consulting for the
MLB Associates | Embedded world
------------------------------------------------------------
^ permalink raw reply
* Re: [git pull] Please pull powerpc.git next branch
From: Anton Vorontsov @ 2010-05-21 10:37 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev list
In-Reply-To: <1274433088.1931.63.camel@pasglop>
On Fri, May 21, 2010 at 07:11:28PM +1000, Benjamin Herrenschmidt wrote:
[...]
> Anton Vorontsov (3):
> powerpc/85xx: Add eTSEC 2.0 support for P1020RDB boards
> powerpc/85xx: Fix P1020RDB boot hang due USB2
> powerpc/83xx: Add MCU LEDs support for MPC837xRDB and MPC8315RDB boards
[...]
> Milton Miller (1):
> powerpc: Use common cpu_die (fixes SMP+SUSPEND build)
Kumar,
As the cpu_die fix is now in, do you mind adding booke
hibernation patch again?
Thanks,
--
Anton Vorontsov
email: cbouatmailru@gmail.com
irc://irc.freenode.net/bd2
^ permalink raw reply
* Re: [git pull] Please pull powerpc.git next branch
From: Josh Boyer @ 2010-05-21 10:22 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev list
In-Reply-To: <1274433088.1931.63.camel@pasglop>
On Fri, May 21, 2010 at 07:11:28PM +1000, Benjamin Herrenschmidt wrote:
>Hi Linus !
>
>Here's the powerpc batch for this merge window.
>
>Most of it is in arch/powerpc, a few powerpc specific drivers are hit
>too, including removing one that has been unused (and unselectable in
>Kconfig) for a long time (hdpuftrs), probably remains of a long dead
>platform.
You missed my updated pull request. I still have some patches sitting in my
-next branch that should go in.
josh
^ permalink raw reply
* Re: [PATCH RT] ehea: make receive irq handler non-threaded (IRQF_NODELAY)
From: Milton Miller @ 2010-05-21 9:02 UTC (permalink / raw)
To: Michael Ellerman
Cc: Darren Hart, Jan-Bernd Themann, dvhltc, linux-kernel,
Milton Miller, Will Schmidt, Brian King, niv, Thomas Gleixner,
Doug Maxey, linuxppc-dev
In-Reply-To: <1274318916.22892.35.camel@concordia>
On Thu May 20 at 11:28:36 EST in 2010, Michael Ellerman wrote:
> On Wed, 2010-05-19 at 07:16 -0700, Darren Hart wrote:
> > On 05/18/2010 06:25 PM, Michael Ellerman wrote:
> > > On Tue, 2010-05-18 at 15:22 -0700, Darren Hart wrote:
> > > > On 05/18/2010 02:52 PM, Brian King wrote:
> > > > > Is IRQF_NODELAY something specific to the RT kernel?
> > > > > I don't see it in mainline...
> > > > Yes, it basically says "don't make this handler threaded".
> > >
> > > That is a good fix for EHEA, but the threaded handling is still broken
> > > for anything else that is edge triggered isn't it?
> >
> > No, I don't believe so. Edge triggered interrupts that are reported as
> > edge triggered interrupts will use the edge handler (which was the
> > approach Sebastien took to make this work back in 2008). Since XICS
> > presents all interrupts as Level Triggered, they use the fasteoi path.
>
> But that's the point, no interrupts on XICS are reported as edge, even
> if they are actually edge somewhere deep in the hardware. I don't think
> we have any reliable way to determine what is what.
>
The platform doesn't tell us this information. The driver might know
but we don't need this information.
> > > The result of the discussion about two years ago on this was that we
> > > needed a custom flow handler for XICS on RT.
> >
> > I'm still not clear on why the ultimate solution wasn't to have XICS
> > report edge triggered as edge triggered. Probably some complexity of the
> > entire power stack that I am ignorant of.
>
> I'm not really sure either, but I think it's a case of a leaky
> abstraction on the part of the hypervisor. Edge interrupts behave as
> level as long as you handle the irq before EOI, but if you mask they
> don't. But Milton's the expert on that.
>
More like the hardware actually converts them. They are all handled
with the same presentation.
The XICS interrupt system is highly scalable and distributed in
implementation, with multiple priority delivery and unlimited nesting.
First, a few features and description:
The hardware has two bits of storage for every LSI interrupt source in the
system to say that interrupt is idle, pending, or was rejected and will
be retried later. The hardware also stores a destination and delivery
priority, settable by software. The destination can be a specific cpu
thread, or a global distribution queue of all (online) threads (in the
partition). While the hardware used to have 256 priority levels available
(255 usable, one for cpu not interrupted), some bits have been stolen
and today we only guarantee 16 levels are avalabile to the OS (15 for
delivery and one for source disabled / cpu not processing any interrupt).
[The current linux kernel delivers all device interrupts at one level
but IPIs at a higher level. To avoid overflowing the irq stack we don't
allow device interrupts while processing any external interrupt.]
The interrupt presentation layer likewise scales, with a seperate instance
for each cpu thread in the system. A single IPI source per thread is
part of this instance; when a cpu wants to interrupt another it writes
the priority of the IPI to that cpus presentation logic.
When an interrupt is signaled, the hardware checks the state of that
interrupt, and if previously idle it sends an interrupt request with its
source number and priority towards the programmed destination, either a
specific cpu thread or the global queue of all processors in the system.
If that cpu is already handling an interrupt of the same or higher (lower
valued) priority either the incoming interrupt will be passed to the next
cpu (if the destnation was global) or it will be rejected and the isu will
update its state and try again later. If the cpu had a prior interrupt
pending at a lower priority then the old interrupt will be rejected back
to its isu instead.
The normal behavior is a load to a presentation logic register causes
the interrupt source number and previous priority of the cpu to be
delivered to the cpu and the cpu priority to be raised to that of the
incoming interrupt. The external interrupt indication to the cpu is
removed. At this point the presentation hardware forgets all history
of this interrupt. A store to the same register resets the priority of
the cpu (which would naturally be the level before it was interrupted
if it stores the value loaded) and sends an EOI (end of interrupt) to
the interrupt source specified in the write. This resets the two bits
from pending to idle.
The software is allowed to reset the cpu priority to allow other
interrupts of equal (or even lower) priority to be presented independently
of creating the EOI for this source. However, until software creates
an EOI for a specific source it will not be presented until the machine
is reset. The only rule is you can't raise your priority (which might
have to reject a pending interrupt) when you send create (write) the EOI.
A cpu can also change its priority to tell the hardware to reject
this interrupt (possibly representing to another cpu) if it was really
working at a higher priority and it just didn't do the MMIO store to the
interrupt controller (which is slow compared to memory). There is also
a polling register that you can see what interrupt would be presented,
but its racy as a new interrupt could come in, displace that one, and
the first one might be represented to another cpu.
To avoid overloading any single cpu, interrupts targeting the global
queue are distributed fairly. Through POWER5 the hardware remembers
the cpu that accepted the previous interrupt and starts considering
the next oneline cpu. Starting with POWER6, the presentation layer
was distributed to the processor chips (for natural scaling) and the
global queue replaced with a forwarding list. The ISU is told (by the
hypervisor) to start its next presentation search with the next cpu in
the list when it accepts the interrupt from the presentation logic.
When MSI interrupts were added, logic was needed to handle reciving the
trigger store, presenting it, and representing the rejected interrupts
the edge when cpus were busy with prior or higher priority interrupts.
So the same state was created for each possible MSI, distributed to the
PCI host bridge logic or other io device like the HEA. These state bits
per MSI convert the incoming store edge trigger into a replayable level,
which will be presented to cpus until one consumes it with the load.
If it gets rejected, it will try again. But unlike an LSI which is still
present from the device, if it gets EOId it waits for a new trigger.
Actually, there is one additional bit in the ISU hardware for MSI sources
that keeps track that an MSI trigger was seen while it is in the pending
state because the path of the EOI from the interrupt presentation logic to
the ISU is not ordered with the MMIOs from the processor to the PCI bus.
However, if the interrupt is disabled, the hardware will not set this bit
or otherwise remember it was triggred. The disable is done by setting
the priority to least favored (FF) as that level could never be higher
than any cpus.
In addition, the OS is not aware where or how the priority, destination,
and enable are are stored. This is hidden via the Run Time Abstraction
Services (RTAS), which is a firmware supplied library for infrequent
calls and is called under a global lock. The platform is not designed
for this to be fast, and the hypwervisor couldn't securely give access
to the registers even if the os knew where they were. (The interrupt
presentation layer is accessed with a fast hypervisor call).
So, with this description, it should be clear that XICS threaded delivery
in the realtime kernel should use the hardware implicit masking per
source and never play games disabling the interrupt at the ISU, which
will be racy for edge sources and pure overhead for true level sources.
This was proposed here: http://lkml.org/lkml/2008/9/24/226 .
The threaded interrupt services in mainline assume the initial interrupt
handler will disable the interrupt at the device and therefore does not
call the irq mask and unmask functions.
> > > Apart from the issue of loosing interrupts there is also the fact that
> > > masking on the XICS requires an RTAS call which takes a global lock.
> >
> > Right, one of may reasons why we felt this was the right fix. The other
> > is that there is no real additional overhead in running this as
> > non-threaded since the receive handler is so short (just napi_schedule()).
>
> True. It's not a fix in general though. I'm worried that we're going to
> see the exact same bug for MSI(-X) interrupts.
>
> cheers
>
>
and hca and ...
milton
^ permalink raw reply
* Re: [PATCH RT] ehea: make receive irq handler non-threaded (IRQF_NODELAY), Re: [PATCH RT] ehea: make receive irq handler non-threaded (IRQF_NODELAY)
From: Milton Miller @ 2010-05-21 9:18 UTC (permalink / raw)
To: Thomas Gleixner, Jan-Bernd Themann
Cc: Darren Hart, dvhltc, linux-kernel, Milton Miller, Will Schmidt,
Brian King, niv, Doug Maxey, linuxppc-dev
In-Reply-To: <alpine.LFD.2.00.1005201014250.3368@localhost.localdomain>
On Thu, 20 May 2010 at 10:21:36 +0200 (CEST) Thomas Gleixner wrote:
> On Thu, 20 May 2010, Michael Ellerman wrote:
> > On Wed, 2010-05-19 at 16:38 +0200, Thomas Gleixner wrote:
> > > On Wed, 19 May 2010, Darren Hart wrote:
> > >
> > > > On 05/18/2010 06:25 PM, Michael Ellerman wrote:
> > > > > On Tue, 2010-05-18 at 15:22 -0700, Darren Hart wrote:
> >
> > > > > The result of the discussion about two years ago on this was that we
> > > > > needed a custom flow handler for XICS on RT.
> > > >
> > > > I'm still not clear on why the ultimate solution wasn't to have XICS report
> > > > edge triggered as edge triggered. Probably some complexity of the entire power
> > > > stack that I am ignorant of.
> > > >
> > > > > Apart from the issue of loosing interrupts there is also the fact that
> > > > > masking on the XICS requires an RTAS call which takes a global lock.
> > >
> > > Right, I'd love to avoid that but with real level interrupts we'd run
> > > into an interrupt storm. Though another solution would be to issue the
> > > EOI after the threaded handler finished, that'd work as well, but
> > > needs testing.
> >
> > Yeah I think that was the idea for the custom flow handler. We'd reset
> > the processor priority so we can take other interrupts (which the EOI
> > usually does for you), then do the actual EOI after the handler
> > finished.
>
> That only works when the card does not issue new interrupts until the
> EOI happens. If the EOI is only relevant for the interrupt controller,
> then you are going to lose any edge which comes in before the EOI as
> well.
Well, the real MSIs have an extra bit to allow the eoi to dally behind
the mmio on another path and that should cover this race when the irq
is left enabled.
Jan-Bernd HEA has that change, right?
milton
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox