* [PATCH] Add Freescale CodeWarrior debug support for kernel
From: Roy Zang @ 2010-10-28 8:50 UTC (permalink / raw)
To: linuxppc-dev; +Cc: adrian.bogdan
CodeWarrior is popular embedded tools to support debugging Powerpc.
This patch adds Freescale CodeWarrior debug support for Linux kernel on
85xx/QorIQ platform.
Signed-off-by: Bogdan Adrin <drian.bogdan@freescale.com>
Signed-off-by: Roy Zang <tie-fei.zang@freescale.com>
---
arch/powerpc/Kconfig.debug | 8 ++++++++
arch/powerpc/Makefile | 5 +++++
arch/powerpc/include/asm/reg_booke.h | 4 ++++
arch/powerpc/kernel/fsl_booke_entry_mapping.S | 3 +++
arch/powerpc/kernel/head_fsl_booke.S | 11 +++++++++--
arch/powerpc/kernel/idle.c | 5 ++++-
6 files changed, 33 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index 2d38a50..eedd2ac 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -153,6 +153,14 @@ config BDI_SWITCH
Unless you are intending to debug the kernel with one of these
machines, say N here.
+config DEBUG_CODEWARRIOR
+ bool "Include CodeWarrior kernel debugging"
+ depends on DEBUG_KERNEL && PPC32
+ help
+ Say Y here to include CodeWarrior kernel debugging option
+ Unless you are intending to debug the kernel with one of these
+ machines, say N here.
+
config BOOTX_TEXT
bool "Support for early boot text console (BootX or OpenFirmware only)"
depends on PPC_OF && PPC_BOOK3S
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index b7212b6..d3050e6 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -121,6 +121,11 @@ KBUILD_CFLAGS += $(call cc-option,-fno-dwarf2-cfi-asm)
# often slow when they are implemented at all
KBUILD_CFLAGS += -mno-string
+ifeq ($(CONFIG_DEBUG_CODEWARRIOR),y)
+CFLAGS += -g2 -gdwarf-2
+AFLAGS_KERNEL += -Wa,-gdwarf2
+endif
+
ifeq ($(CONFIG_6xx),y)
KBUILD_CFLAGS += -mcpu=powerpc
endif
diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h
index 667a498..ac65fcd 100644
--- a/arch/powerpc/include/asm/reg_booke.h
+++ b/arch/powerpc/include/asm/reg_booke.h
@@ -35,7 +35,11 @@
#define MSR_KERNEL (MSR_ME|MSR_RI|MSR_IR|MSR_DR|MSR_CE)
#define MSR_USER (MSR_KERNEL|MSR_PR|MSR_EE)
#else
+#if defined(CONFIG_DEBUG_CODEWARRIOR)
+#define MSR_KERNEL (MSR_ME|MSR_RI|MSR_CE|MSR_DE)
+#else
#define MSR_KERNEL (MSR_ME|MSR_RI|MSR_CE)
+#endif
#define MSR_USER (MSR_KERNEL|MSR_PR|MSR_EE)
#endif
diff --git a/arch/powerpc/kernel/fsl_booke_entry_mapping.S b/arch/powerpc/kernel/fsl_booke_entry_mapping.S
index a92c79b..9102aa7 100644
--- a/arch/powerpc/kernel/fsl_booke_entry_mapping.S
+++ b/arch/powerpc/kernel/fsl_booke_entry_mapping.S
@@ -116,6 +116,9 @@ skpinv: addi r6,r6,1 /* Increment */
xori r6,r4,1
slwi r6,r6,5 /* setup new context with other address space */
+#if defined(CONFIG_DEBUG_CODEWARRIOR)
+ ori r6, r6, 0x200 /* enable DE bit for MSR */
+#endif
bl 1f /* Find our address */
1: mflr r9
rlwimi r7,r9,0,20,31
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
index 529b817..9962d09 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -21,7 +21,7 @@
* debbie_chu@mvista.com
* Copyright 2002-2004 MontaVista Software, Inc.
* PowerPC 44x support, Matt Porter <mporter@kernel.crashing.org>
- * Copyright 2004 Freescale Semiconductor, Inc
+ * Copyright 2004,2010 Freescale Semiconductor, Inc
* PowerPC e500 modifications, Kumar Gala <galak@kernel.crashing.org>
*
* This program is free software; you can redistribute it and/or modify it
@@ -135,7 +135,7 @@ _ENTRY(__early_start)
mtspr SPRN_HID0, r2
#endif
-#if !defined(CONFIG_BDI_SWITCH)
+#if !defined(CONFIG_BDI_SWITCH) && !defined(CONFIG_DEBUG_CODEWARRIOR)
/*
* The Abatron BDI JTAG debugger does not tolerate others
* mucking with the debug registers.
@@ -197,6 +197,13 @@ _ENTRY(__early_start)
/*
* Decide what sort of machine this is and initialize the MMU.
*/
+#if defined(CONFIG_DEBUG_CODEWARRIOR)
+ lis r10, 0x1008 /* clear the V bit from the L2MMU_CAM8 register */
+ mtspr SPRN_MAS0, r10
+ lis r10, 0x0
+ mtspr SPRN_MAS1, r10
+ tlbwe
+#endif
mr r3,r31
mr r4,r30
mr r5,r29
diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c
index 39a2baa..83fb019 100644
--- a/arch/powerpc/kernel/idle.c
+++ b/arch/powerpc/kernel/idle.c
@@ -73,8 +73,11 @@ void cpu_idle(void)
stop_critical_timings();
/* check again after disabling irqs */
- if (!need_resched() && !cpu_should_die())
+ if (!need_resched() && !cpu_should_die()) {
+#if !defined(CONFIG_DEBUG_CODEWARRIOR)
ppc_md.power_save();
+#endif
+ }
start_critical_timings();
--
1.5.6.5
^ permalink raw reply related
* mpc52xx_gpt breaks on linux-2.6.26
From: nello martuscielli @ 2010-10-28 15:18 UTC (permalink / raw)
To: linuxppc-dev
If i try to enable watchdog it breaks linux kernel build when enabled.
I'm using an Efika MPC5200B with CRUX PPC 2.6 32bit.
CONFIG_WATCHDOG=y
CONFIG_MPC5200_WDT=y
That's compiling linux-2.6.36:
[..]
LD arch/powerpc/lib/built-in.o
CC arch/powerpc/sysdev/simple_gpio.o
CC arch/powerpc/sysdev/bestcomm/ata.o
CC arch/powerpc/sysdev/bestcomm/bcom_ata_task.o
CC arch/powerpc/sysdev/bestcomm/bestcomm.o
CC arch/powerpc/sysdev/bestcomm/sram.o
LD arch/powerpc/sysdev/bestcomm/bestcomm-core.o
LD arch/powerpc/sysdev/bestcomm/bestcomm-ata.o
LD arch/powerpc/sysdev/bestcomm/built-in.o
CC [M] arch/powerpc/sysdev/bestcomm/fec.o
CC [M] arch/powerpc/sysdev/bestcomm/bcom_fec_rx_task.o
CC [M] arch/powerpc/sysdev/bestcomm/bcom_fec_tx_task.o
CC [M] arch/powerpc/sysdev/bestcomm/gen_bd.o
CC [M] arch/powerpc/sysdev/bestcomm/bcom_gen_bd_rx_task.o
CC [M] arch/powerpc/sysdev/bestcomm/bcom_gen_bd_tx_task.o
LD [M] arch/powerpc/sysdev/bestcomm/bestcomm-fec.o
LD [M] arch/powerpc/sysdev/bestcomm/bestcomm-gen-bd.o
CC arch/powerpc/sysdev/mpc5xxx_clocks.o
AS arch/powerpc/sysdev/6xx-suspend.o
LD arch/powerpc/sysdev/built-in.o
CC arch/powerpc/platforms/52xx/mpc52xx_pic.o
CC arch/powerpc/platforms/52xx/mpc52xx_common.o
CC arch/powerpc/platforms/52xx/mpc52xx_gpt.o
arch/powerpc/platforms/52xx/mpc52xx_gpt.c: In function 'mpc52xx_wdt_write':
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:549: error: dereferencing
pointer to incomplete type
arch/powerpc/platforms/52xx/mpc52xx_gpt.c: In function 'mpc52xx_wdt_ioctl':
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:562: error: dereferencing
pointer to incomplete type
arch/powerpc/platforms/52xx/mpc52xx_gpt.c: In function 'mpc52xx_wdt_open':
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:635: error: dereferencing
pointer to incomplete type
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:636: error: implicit
declaration of function 'nonseekable_open'
arch/powerpc/platforms/52xx/mpc52xx_gpt.c: In function 'mpc52xx_wdt_release':
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:643: error: dereferencing
pointer to incomplete type
arch/powerpc/platforms/52xx/mpc52xx_gpt.c: At top level:
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:657: error: variable
'mpc52xx_wdt_fops' has initializer but incomplete type
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:658: error: unknown field
'owner' specified in initializer
cc1: warnings being treated as errors
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:658: error: excess elements
in struct initializer
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:658: error: (near
initialization for 'mpc52xx_wdt_fops')
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:659: error: unknown field
'llseek' specified in initializer
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:659: error: 'no_llseek'
undeclared here (not in a function)
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:659: error: excess elements
in struct initializer
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:659: error: (near
initialization for 'mpc52xx_wdt_fops')
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:660: error: unknown field
'write' specified in initializer
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:660: error: excess elements
in struct initializer
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:660: error: (near
initialization for 'mpc52xx_wdt_fops')
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:661: error: unknown field
'unlocked_ioctl' specified in initializer
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:661: error: excess elements
in struct initializer
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:661: error: (near
initialization for 'mpc52xx_wdt_fops')
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:662: error: unknown field
'open' specified in initializer
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:662: error: excess elements
in struct initializer
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:662: error: (near
initialization for 'mpc52xx_wdt_fops')
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:663: error: unknown field
'release' specified in initializer
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:663: error: excess elements
in struct initializer
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:663: error: (near
initialization for 'mpc52xx_wdt_fops')
make[2]: *** [arch/powerpc/platforms/52xx/mpc52xx_gpt.o] Error 1
make[1]: *** [arch/powerpc/platforms/52xx] Error 2
make: *** [arch/powerpc/platforms] Error 2
thanks for any advice.
Nello Martuscielli
^ permalink raw reply
* mpc52xx_gpt breaks on linux-2.6.26
From: nello martuscielli @ 2010-10-28 16:21 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <AANLkTikf=ztL+wL7WvaUW4-4uvfeJUUaqMJWqdjwSzQK@mail.gmail.com>
If i try to enable watchdog =A0it breaks linux kernel build when enabled.
I'm using an Efika MPC5200B with CRUX PPC 2.6 32bit.
CONFIG_WATCHDOG=3Dy
CONFIG_MPC5200_WDT=3Dy
That's compiling linux-2.6.36:
[..]
=A0LD =A0 =A0 =A0arch/powerpc/lib/built-in.o
=A0CC =A0 =A0 =A0arch/powerpc/sysdev/simple_gpio.o
=A0CC =A0 =A0 =A0arch/powerpc/sysdev/bestcomm/ata.o
=A0CC =A0 =A0 =A0arch/powerpc/sysdev/bestcomm/bcom_ata_task.o
=A0CC =A0 =A0 =A0arch/powerpc/sysdev/bestcomm/bestcomm.o
=A0CC =A0 =A0 =A0arch/powerpc/sysdev/bestcomm/sram.o
=A0LD =A0 =A0 =A0arch/powerpc/sysdev/bestcomm/bestcomm-core.o
=A0LD =A0 =A0 =A0arch/powerpc/sysdev/bestcomm/bestcomm-ata.o
=A0LD =A0 =A0 =A0arch/powerpc/sysdev/bestcomm/built-in.o
=A0CC [M] =A0arch/powerpc/sysdev/bestcomm/fec.o
=A0CC [M] =A0arch/powerpc/sysdev/bestcomm/bcom_fec_rx_task.o
=A0CC [M] =A0arch/powerpc/sysdev/bestcomm/bcom_fec_tx_task.o
=A0CC [M] =A0arch/powerpc/sysdev/bestcomm/gen_bd.o
=A0CC [M] =A0arch/powerpc/sysdev/bestcomm/bcom_gen_bd_rx_task.o
=A0CC [M] =A0arch/powerpc/sysdev/bestcomm/bcom_gen_bd_tx_task.o
=A0LD [M] =A0arch/powerpc/sysdev/bestcomm/bestcomm-fec.o
=A0LD [M] =A0arch/powerpc/sysdev/bestcomm/bestcomm-gen-bd.o
=A0CC =A0 =A0 =A0arch/powerpc/sysdev/mpc5xxx_clocks.o
=A0AS =A0 =A0 =A0arch/powerpc/sysdev/6xx-suspend.o
=A0LD =A0 =A0 =A0arch/powerpc/sysdev/built-in.o
=A0CC =A0 =A0 =A0arch/powerpc/platforms/52xx/mpc52xx_pic.o
=A0CC =A0 =A0 =A0arch/powerpc/platforms/52xx/mpc52xx_common.o
=A0CC =A0 =A0 =A0arch/powerpc/platforms/52xx/mpc52xx_gpt.o
arch/powerpc/platforms/52xx/mpc52xx_gpt.c: In function 'mpc52xx_wdt_write':
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:549: error: dereferencing
pointer to incomplete type
arch/powerpc/platforms/52xx/mpc52xx_gpt.c: In function 'mpc52xx_wdt_ioctl':
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:562: error: dereferencing
pointer to incomplete type
arch/powerpc/platforms/52xx/mpc52xx_gpt.c: In function 'mpc52xx_wdt_open':
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:635: error: dereferencing
pointer to incomplete type
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:636: error: implicit
declaration of function 'nonseekable_open'
arch/powerpc/platforms/52xx/mpc52xx_gpt.c: In function 'mpc52xx_wdt_release=
':
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:643: error: dereferencing
pointer to incomplete type
arch/powerpc/platforms/52xx/mpc52xx_gpt.c: At top level:
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:657: error: variable
'mpc52xx_wdt_fops' has initializer but incomplete type
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:658: error: unknown field
'owner' specified in initializer
cc1: warnings being treated as errors
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:658: error: excess elements
in struct initializer
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:658: error: (near
initialization for 'mpc52xx_wdt_fops')
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:659: error: unknown field
'llseek' specified in initializer
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:659: error: 'no_llseek'
undeclared here (not in a function)
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:659: error: excess elements
in struct initializer
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:659: error: (near
initialization for 'mpc52xx_wdt_fops')
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:660: error: unknown field
'write' specified in initializer
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:660: error: excess elements
in struct initializer
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:660: error: (near
initialization for 'mpc52xx_wdt_fops')
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:661: error: unknown field
'unlocked_ioctl' specified in initializer
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:661: error: excess elements
in struct initializer
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:661: error: (near
initialization for 'mpc52xx_wdt_fops')
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:662: error: unknown field
'open' specified in initializer
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:662: error: excess elements
in struct initializer
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:662: error: (near
initialization for 'mpc52xx_wdt_fops')
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:663: error: unknown field
'release' specified in initializer
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:663: error: excess elements
in struct initializer
arch/powerpc/platforms/52xx/mpc52xx_gpt.c:663: error: (near
initialization for 'mpc52xx_wdt_fops')
make[2]: *** [arch/powerpc/platforms/52xx/mpc52xx_gpt.o] Error 1
make[1]: *** [arch/powerpc/platforms/52xx] Error 2
make: *** [arch/powerpc/platforms] Error 2
thanks for any advice.
Nello Martuscielli
^ permalink raw reply
* Re: PowerMac G5 config
From: kevin diggs @ 2010-10-28 19:40 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <AANLkTinaYPUwX+YOJh1pCKmSWS_JmG8+eHQ3QvJgG3KA@mail.gmail.com>
Hi,
Apparently, for some reason, you can't use -depth in your find
command when rebuilding your initrd???
Machine is now running 2.6.36. Glad to be rid of that awful cpufreq driver ...
kevin
On Mon, Oct 25, 2010 at 1:45 PM, kevin diggs <diggskevin38@gmail.com> wrote:
> Hi,
>
> I have a G5 (dual 970FX, june 2004?) running YDL 6.0. After fighting
> to get a compiler that will build 2.6.29+ (4.2.1 -> 4.2.2) I can't get
> it to boot. It spits out a bunch of message about devices (I think the
> last ones are USB related) and then says:
>
> Restarting System
>
> and then reboots. I've attached a diff of the 2.6.28 config that will boot.
>
> Any suggestions would be greatly appreciated. Thanks!
>
> kevin
>
^ permalink raw reply
* Re: Pegasos OHCI bug (was Re: PROBLEM: memory corrupting bug,
From: Segher Boessenkool @ 2010-10-28 19:50 UTC (permalink / raw)
To: pacman; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <20101028011147.26254.qmail@kosh.dhis.org>
> So is it wrong to leave the host controller enabled when the OS is booted?
Yes. Or, rather, there should be some way for the client to turn off
all dma and interrupt activity; if the client closes the ihandles in
"/chosen", and perhaps calls "quiesce", that should be enough.
> If
> not, then the error must be in the communication of which memory addresses
> are in use by OF. I've got a node /memory@0 whose "available" property
> looks
> like this:
> 00000000 00400000
> 00584000 0007c000
> 0092a1d8 00004e28
> 00a2f000 005d1000
> 01800000 0e3fd000
> 0fbffab4 0000054c
>>From that list, it looks to me like OF is telling the kernel that it
>> should
> not attempt to use any address above 0xfbffab4+0x54c == 0xfc00000.
The client is allowed to "take over" all memory, if it doesn't call OF
after doing so. This won't work if some device scribbles on it, as
you have seen.
> Later, when the kernel decides it's done using OF, what's supposed to
> happen?
> It closes stdin, but that doesn't help here since the offending device is
> a
> bus node, not an input node. It looks to me like the kernel makes the
> assumption that all devices other than stdin and stdout will have been
> deactivated already when the kernel starts, and that this assumption has
> been violated. Who is wrong, from the perspective of the OF standard, the
> assumer or the violator?
The violator.
>> Lovely, incorrect data (it should start with 82002810, i.e.,
>> not relocatable -- it is already an assigned address!).
>
> Now you see how I have trouble relating the docs to the reality...
Yeah :-(
>> This means: 32-bit MMIO address space for bus 0 dev 5 fn 0,
>> first BAR; assigned to address 80000000; size is 1000.
>
> But "address 80000000" is a physical address (I think), so do I need to do
> a
> map-in on it before using it?
Yes.
>> You could try a boot script like this:
>>
>>
>> dev /pci
>> 0 ffff04 DO 0 i config-w! -100 +LOOP
>> device-end
>>
>>
>> which should disable all PCI devices on all busses, on that
>
> Almost all of my devices are under that PCI node. What will I prove by
> disabling them?
You should put it after "load", and before "go".
It should give you a working system; it's a sledgehammer workaround.
Segher
^ permalink raw reply
* Re: Pegasos OHCI bug (was Re: PROBLEM: memory corrupting bug,
From: pacman @ 2010-10-28 21:07 UTC (permalink / raw)
To: Segher Boessenkool; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <52441.84.105.60.153.1288295412.squirrel@gate.crashing.org>
Segher Boessenkool writes:
>
> > So is it wrong to leave the host controller enabled when the OS is booted?
>
> Yes. Or, rather, there should be some way for the client to turn off
> all dma and interrupt activity; if the client closes the ihandles in
> "/chosen", and perhaps calls "quiesce", that should be enough.
Sounds good to me, I only wish someone had written down what "quiesce" means.
> >
> > Almost all of my devices are under that PCI node. What will I prove by
> > disabling them?
>
> You should put it after "load", and before "go".
>
> It should give you a working system; it's a sledgehammer workaround.
I can do it a little more gracefully than that. This works to deactivate the
problem devices manually:
1 lbflip 80000000 8 + rl!
1 lbflip 80001000 8 + rl!
where 80000000 and 80001000 have been obtained from
/pci@80000000/usb@5/assigned-addresses and
/pci@80000000/usb@5,1/assigned-addresses; 8 is the offset of the
HcCommandStatus register; and the 1 bit is HostControllerReset (HCR).
Now I'm just trying to find the more correct way of doing it, without
hardcoded addresses. That'll be something like this:
search the device tree for OHCI nodes
for each OHCI node
get assigned-addresses
map-in
set HCR
wait for acknowledgement
map-out
which can be done any time before the quiesce call, since that marks the
point where the kernel assumes that there are no devices writing to memory.
Sound good?
--
Alan Curry
^ permalink raw reply
* [PATHC v1] PPC4xx: Adding PCI(E) MSI support
From: tmarri @ 2010-10-28 22:55 UTC (permalink / raw)
To: linuxppc-dev; +Cc: tmarri
From: Tirumala Marri <tmarri@apm.com>
This patch adds MSI support for 440SPe, 460Ex, 460Sx and 405Ex.
Signed-off-by: Tirumala R Marri <tmarri@apm.com>
---
v1:
* Get rid of bitmap functions.
* Remove irq mapping as each MSI is tied to UIC.
* Cleaning up of prints.
---
arch/powerpc/boot/dts/canyonlands.dts | 18 +++
arch/powerpc/boot/dts/katmai.dts | 18 +++
arch/powerpc/boot/dts/kilauea.dts | 28 ++++
arch/powerpc/boot/dts/redwood.dts | 20 +++
arch/powerpc/platforms/40x/Kconfig | 2 +
arch/powerpc/platforms/44x/Kconfig | 6 +
arch/powerpc/sysdev/Kconfig | 6 +
arch/powerpc/sysdev/Makefile | 1 +
arch/powerpc/sysdev/ppc4xx_msi.c | 251 +++++++++++++++++++++++++++++++++
9 files changed, 350 insertions(+), 0 deletions(-)
create mode 100644 arch/powerpc/sysdev/ppc4xx_msi.c
diff --git a/arch/powerpc/boot/dts/canyonlands.dts b/arch/powerpc/boot/dts/canyonlands.dts
index a303703..5a8e04e 100644
--- a/arch/powerpc/boot/dts/canyonlands.dts
+++ b/arch/powerpc/boot/dts/canyonlands.dts
@@ -519,5 +519,23 @@
0x0 0x0 0x0 0x3 &UIC3 0x12 0x4 /* swizzled int C */
0x0 0x0 0x0 0x4 &UIC3 0x13 0x4 /* swizzled int D */>;
};
+
+ MSI: ppc4xx-msi@C10000000 {
+ compatible = "amcc,ppc4xx-msi", "ppc4xx-msi";
+ reg = < 0xC 0x10000000 0x100>;
+ sdr-base = <0x36C>;
+ msi-data = <0x00000000>;
+ msi-mask = <0x44440000>;
+ interrupt-count = <3>;
+ interrupts = <0 1 2 3>;
+ interrupt-parent = <&UIC3>;
+ #interrupt-cells = <1>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ interrupt-map = <0 &UIC3 0x18 1
+ 1 &UIC3 0x19 1
+ 2 &UIC3 0x1A 1
+ 3 &UIC3 0x1B 1>;
+ };
};
};
diff --git a/arch/powerpc/boot/dts/katmai.dts b/arch/powerpc/boot/dts/katmai.dts
index 7c3be5e..f913dbe 100644
--- a/arch/powerpc/boot/dts/katmai.dts
+++ b/arch/powerpc/boot/dts/katmai.dts
@@ -442,6 +442,24 @@
0x0 0x0 0x0 0x4 &UIC3 0xb 0x4 /* swizzled int D */>;
};
+ MSI: ppc4xx-msi@400300000 {
+ compatible = "amcc,ppc4xx-msi", "ppc4xx-msi";
+ reg = < 0x4 0x00300000 0x100>;
+ sdr-base = <0x3B0>;
+ msi-data = <0x00000000>;
+ msi-mask = <0x44440000>;
+ interrupt-count = <3>;
+ interrupts =<0 1 2 3>;
+ interrupt-parent = <&UIC0>;
+ #interrupt-cells = <1>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ interrupt-map = <0 &UIC0 0xC 1
+ 1 &UIC0 0x0D 1
+ 2 &UIC0 0x0E 1
+ 3 &UIC0 0x0F 1>;
+ };
+
I2O: i2o@400100000 {
compatible = "ibm,i2o-440spe";
reg = <0x00000004 0x00100000 0x100>;
diff --git a/arch/powerpc/boot/dts/kilauea.dts b/arch/powerpc/boot/dts/kilauea.dts
index 083e68e..21e88f5 100644
--- a/arch/powerpc/boot/dts/kilauea.dts
+++ b/arch/powerpc/boot/dts/kilauea.dts
@@ -394,5 +394,33 @@
0x0 0x0 0x0 0x3 &UIC2 0xd 0x4 /* swizzled int C */
0x0 0x0 0x0 0x4 &UIC2 0xe 0x4 /* swizzled int D */>;
};
+
+ MSI: ppc4xx-msi@C10000000 {
+ compatible = "amcc,ppc4xx-msi", "ppc4xx-msi";
+ reg = < 0x0 0xEF620000 0x100>;
+ sdr-base = <0x4B0>;
+ msi-data = <0x00000000>;
+ msi-mask = <0x44440000>;
+ interrupt-count = <12>;
+ interrupts = <0 1 2 3 4 5 6 7 8 9 0xA 0xB 0xC 0xD>;
+ interrupt-parent = <&UIC2>;
+ #interrupt-cells = <1>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ interrupt-map = <0 &UIC2 0x10 1
+ 1 &UIC2 0x11 1
+ 2 &UIC2 0x12 1
+ 2 &UIC2 0x13 1
+ 2 &UIC2 0x14 1
+ 2 &UIC2 0x15 1
+ 2 &UIC2 0x16 1
+ 2 &UIC2 0x17 1
+ 2 &UIC2 0x18 1
+ 2 &UIC2 0x19 1
+ 2 &UIC2 0x1A 1
+ 2 &UIC2 0x1B 1
+ 2 &UIC2 0x1C 1
+ 3 &UIC2 0x1D 1>;
+ };
};
};
diff --git a/arch/powerpc/boot/dts/redwood.dts b/arch/powerpc/boot/dts/redwood.dts
index 81636c0..d86a3a4 100644
--- a/arch/powerpc/boot/dts/redwood.dts
+++ b/arch/powerpc/boot/dts/redwood.dts
@@ -358,8 +358,28 @@
0x0 0x0 0x0 0x4 &UIC3 0xb 0x4 /* swizzled int D */>;
};
+ MSI: ppc4xx-msi@400300000 {
+ compatible = "amcc,ppc4xx-msi", "ppc4xx-msi";
+ reg = < 0x4 0x00300000 0x100
+ 0x4 0x00300000 0x100>;
+ sdr-base = <0x3B0>;
+ msi-data = <0x00000000>;
+ msi-mask = <0x44440000>;
+ interrupt-count = <3>;
+ interrupts =<0 1 2 3>;
+ interrupt-parent = <&UIC0>;
+ #interrupt-cells = <1>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ interrupt-map = <0 &UIC0 0xC 1
+ 1 &UIC0 0x0D 1
+ 2 &UIC0 0x0E 1
+ 3 &UIC0 0x0F 1>;
+ };
+
};
+
chosen {
linux,stdout-path = "/plb/opb/serial@ef600200";
};
diff --git a/arch/powerpc/platforms/40x/Kconfig b/arch/powerpc/platforms/40x/Kconfig
index b721764..92aeee6 100644
--- a/arch/powerpc/platforms/40x/Kconfig
+++ b/arch/powerpc/platforms/40x/Kconfig
@@ -57,6 +57,8 @@ config KILAUEA
select 405EX
select PPC40x_SIMPLE
select PPC4xx_PCI_EXPRESS
+ select PCI_MSI
+ select 4xx_MSI
help
This option enables support for the AMCC PPC405EX evaluation board.
diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig
index 0f979c5..3836353 100644
--- a/arch/powerpc/platforms/44x/Kconfig
+++ b/arch/powerpc/platforms/44x/Kconfig
@@ -74,6 +74,8 @@ config KATMAI
select 440SPe
select PCI
select PPC4xx_PCI_EXPRESS
+ select PCI_MSI
+ select 4xx_MSI
help
This option enables support for the AMCC PPC440SPe evaluation board.
@@ -119,6 +121,8 @@ config CANYONLANDS
select 460EX
select PCI
select PPC4xx_PCI_EXPRESS
+ select PCI_MSI
+ select 4xx_MSI
select IBM_NEW_EMAC_RGMII
select IBM_NEW_EMAC_ZMII
help
@@ -145,6 +149,8 @@ config REDWOOD
select 460SX
select PCI
select PPC4xx_PCI_EXPRESS
+ select PCI_MSI
+ select 4xx_MSI
help
This option enables support for the AMCC PPC460SX Redwood board.
diff --git a/arch/powerpc/sysdev/Kconfig b/arch/powerpc/sysdev/Kconfig
index 3965828..ec86000 100644
--- a/arch/powerpc/sysdev/Kconfig
+++ b/arch/powerpc/sysdev/Kconfig
@@ -7,6 +7,12 @@ config PPC4xx_PCI_EXPRESS
depends on PCI && 4xx
default n
+config 4xx_MSI
+ bool
+ depends on PCI_MSI
+ depends on PCI && 4xx
+ default n
+
config PPC_MSI_BITMAP
bool
depends on PCI_MSI
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index 0bef9da..30f4da4 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -40,6 +40,7 @@ obj-$(CONFIG_XILINX_PCI) += xilinx_pci.o
obj-$(CONFIG_OF_RTC) += of_rtc.o
ifeq ($(CONFIG_PCI),y)
obj-$(CONFIG_4xx) += ppc4xx_pci.o
+obj-$(CONFIG_4xx_MSI) += ppc4xx_msi.o
endif
obj-$(CONFIG_PPC4xx_GPIO) += ppc4xx_gpio.o
diff --git a/arch/powerpc/sysdev/ppc4xx_msi.c b/arch/powerpc/sysdev/ppc4xx_msi.c
new file mode 100644
index 0000000..9d5e0c9
--- /dev/null
+++ b/arch/powerpc/sysdev/ppc4xx_msi.c
@@ -0,0 +1,251 @@
+/*
+ * Adding PCI-E MSI support for PPC4XX SoCs.
+ *
+ * Copyright (c) 2010, Applied Micro Circuits Corporation
+ * Authors: Tirumala R Marri <tmarri@apm.com>
+ * Feng Kan <fkan@apm.com>
+ *
+ * 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
+ */
+#include <linux/irq.h>
+#include <linux/bootmem.h>
+#include <linux/pci.h>
+#include <linux/msi.h>
+#include <linux/of_platform.h>
+#include <linux/interrupt.h>
+#include <asm/prom.h>
+#include <asm/hw_irq.h>
+#include <asm/ppc-pci.h>
+#include <boot/dcr.h>
+#include <asm/dcr-regs.h>
+#include <asm/msi_bitmap.h>
+
+#define PEIH_TERMADH 0x00
+#define PEIH_TERMADL 0x08
+#define PEIH_MSIED 0x10
+#define PEIH_MSIMK 0x18
+#define PEIH_MSIASS 0x20
+#define PEIH_FLUSH0 0x30
+#define PEIH_FLUSH1 0x38
+#define PEIH_CNTRST 0x48
+
+#define UPPER_4BITS_OF36BIT 32
+#define LOWER_32BITS_OF36BIT 0xFFFFFFFF
+
+struct ppc4xx_msi {
+ u32 msi_addr_lo;
+ u32 msi_addr_hi;
+ void __iomem *msi_regs;
+ u32 feature;
+};
+
+static struct ppc4xx_msi *ppc4xx_msi;
+struct ppc4xx_msi_feature {
+ u32 ppc4xx_pic_ip;
+ u32 msiir_offset;
+};
+
+static int ppc4xx_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+{
+ struct msi_desc *entry;
+ unsigned int virq = 0;
+ struct msi_msg msg;
+ struct ppc4xx_msi *msi_data = ppc4xx_msi;
+ static int int_no = 0; /* To remember last used interrupt */
+ struct device_node *msi_dev = NULL;
+ const u32 *count;
+
+ msi_dev = of_find_node_by_name(NULL, "ppc4xx-msi");
+ if (msi_dev)
+ return -ENODEV;
+
+ count = of_get_property(msi_dev, "interrupt-count", NULL);
+ if (!count) {
+ dev_err(&dev->dev, "no interrupts property found \n");
+ return -ENODEV;
+ }
+
+ if (int_no > *count)
+ return -EINVAL;
+
+ list_for_each_entry(entry, &dev->msi_list, list) {
+ virq = irq_of_parse_and_map(msi_dev, int_no);
+ printk("virq = 0x%x\n", virq);
+ if (virq == NO_IRQ) {
+ dev_err(&dev->dev, "%s: fail mapping irq\n", __func__);
+ return -EINVAL;
+ } else
+ set_irq_data(virq, (void *)int_no);
+
+ dev_dbg(&dev->dev, "%s: virq = %d \n", __func__, virq);
+
+ /* Setup msi address space */
+ msg.address_hi = msi_data->msi_addr_hi;
+ msg.address_lo = msi_data->msi_addr_lo;
+
+ set_irq_msi(virq, entry);
+ msg.data = int_no;
+ int_no++;
+ write_msi_msg(virq, &msg);
+ }
+
+ return 0;
+}
+
+void ppc4xx_teardown_msi_irqs(struct pci_dev *dev)
+{
+ struct msi_desc *entry;
+
+ dev_dbg(&dev->dev, "PCIE-MSI: tearing down msi irqs\n");
+
+ list_for_each_entry(entry, &dev->msi_list, list) {
+ if (entry->irq == NO_IRQ)
+ continue;
+ set_irq_msi(entry->irq, NULL);
+ irq_dispose_mapping(entry->irq);
+ }
+
+ return;
+}
+
+static int ppc4xx_msi_check_device(struct pci_dev *pdev, int nvec, int type)
+{
+ dev_dbg(&pdev->dev, "PCIE-MSI:%s called. vec %x type %d\n",
+ __func__, nvec, type);
+ return 0;
+}
+
+static int ppc4xx_setup_pcieh_hw(struct platform_device *dev,
+ struct resource res, struct ppc4xx_msi *msi)
+{
+ const u32 *msi_data;
+ const u32 *msi_mask;
+ const u32 *sdr_addr;
+ int rc = 0;
+ dma_addr_t msi_phys;
+ void *msi_virt;
+
+ sdr_addr = of_get_property(dev->dev.of_node, "sdr-base", NULL);
+ if (!sdr_addr)
+ return -1;
+
+ SDR0_WRITE(sdr_addr, (u64)res.start >> UPPER_4BITS_OF36BIT); /*HIGH addr */
+ SDR0_WRITE(sdr_addr + 1, res.start & LOWER_32BITS_OF36BIT); /* Low addr */
+
+ msi->msi_regs = ioremap((u64) res.start, res.end - res.start + 1);
+ if (!msi->msi_regs) {
+ dev_err(&dev->dev, "ioremap problem failed\n");
+ return ENOMEM;
+ }
+ dev_dbg(&dev->dev, "PCIE-MSI: msi register mapped 0x%x 0x%x\n",
+ (u32) (msi->msi_regs + PEIH_TERMADH), (u32) (msi->msi_regs));
+
+ msi_virt = dma_alloc_coherent(&dev->dev, 64, &msi_phys, GFP_KERNEL);
+ msi->msi_addr_hi = 0x0;
+ msi->msi_addr_lo = (u32) msi_phys;
+ dev_dbg(&dev->dev, "PCIE-MSI: msi address 0x%x \n", msi->msi_addr_lo);
+
+ /* Progam the Interrupt handler Termination addr registers */
+ out_be32(msi->msi_regs + PEIH_TERMADH, msi->msi_addr_hi);
+ out_be32(msi->msi_regs + PEIH_TERMADL, msi->msi_addr_lo);
+
+ msi_data = of_get_property(dev->dev.of_node, "msi-data", NULL);
+ if (!msi_data) {
+ rc = -1;
+ goto error_out;
+ }
+
+ msi_mask = of_get_property(dev->dev.of_node, "msi-mask", NULL);
+ if (!msi_mask) {
+ rc = -1;
+ goto error_out;
+ }
+
+ /* Program MSI Expected data and Mask bits */
+ out_be32(msi->msi_regs + PEIH_MSIED, 0);
+ out_be32(msi->msi_regs + PEIH_MSIMK, *msi_mask);
+
+ return 0;
+ error_out:
+ iounmap(msi->msi_regs);
+ return rc;
+}
+static int __devinit ppc4xx_msi_probe(struct platform_device *dev,
+ const struct of_device_id *match)
+{
+ struct ppc4xx_msi *msi;
+ struct resource res;
+ int err = 0;
+
+ dev_dbg(&dev->dev, "PCIE-MSI: Setting up MSI support...\n");
+
+ msi = kzalloc(sizeof(struct ppc4xx_msi), GFP_KERNEL);
+ if (!msi) {
+ dev_err(&dev->dev, "No memory for MSI structure\n");
+ err = -ENOMEM;
+ goto error_out;
+ }
+ /* Get MSI ranges */
+ err = of_address_to_resource(dev->dev.of_node, 0, &res);
+ if (err) {
+ dev_err(&dev->dev, "%s resource error!\n",
+ dev->dev.of_node->full_name);
+ goto error_out;
+ }
+
+ if (ppc4xx_setup_pcieh_hw(dev, res, msi))
+ goto error_out;
+
+ ppc4xx_msi = msi;
+
+ WARN_ON(ppc_md.setup_msi_irqs);
+ ppc_md.setup_msi_irqs = ppc4xx_setup_msi_irqs;
+ ppc_md.teardown_msi_irqs = ppc4xx_teardown_msi_irqs;
+ ppc_md.msi_check_device = ppc4xx_msi_check_device;
+ return 0;
+
+ error_out:
+ kfree(msi);
+ return err;
+}
+static const struct ppc4xx_msi_feature ppc4xx_msi_feature = {
+ .ppc4xx_pic_ip = 0,
+ .msiir_offset = 0x140,
+};
+
+static const struct of_device_id ppc4xx_msi_ids[] = {
+ {
+ .compatible = "amcc,ppc4xx-msi",
+ .data = (void *)&ppc4xx_msi_feature,
+ },
+ {}
+};
+
+static struct of_platform_driver ppc4xx_msi_driver = {
+ .driver = {
+ .name = "ppc4xx-msi",
+ .owner = THIS_MODULE,
+ .of_match_table = ppc4xx_msi_ids,
+ },
+ .probe = ppc4xx_msi_probe,
+};
+
+static __init int ppc4xx_msi_init(void)
+{
+ return of_register_platform_driver(&ppc4xx_msi_driver);
+}
+
+subsys_initcall(ppc4xx_msi_init);
--
1.6.1.rc3
^ permalink raw reply related
* Re: Pegasos OHCI bug (was Re: PROBLEM: memory corrupting bug,
From: Segher Boessenkool @ 2010-10-29 0:16 UTC (permalink / raw)
To: pacman; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <20101028210753.22240.qmail@kosh.dhis.org>
>> > Almost all of my devices are under that PCI node. What will I prove by
>> > disabling them?
>>
>> You should put it after "load", and before "go".
>>
>> It should give you a working system; it's a sledgehammer workaround.
>
> I can do it a little more gracefully than that. This works to deactivate
> the
> problem devices manually:
>
> 1 lbflip 80000000 8 + rl!
> 1 lbflip 80001000 8 + rl!
>
> where 80000000 and 80001000 have been obtained from
> /pci@80000000/usb@5/assigned-addresses and
> /pci@80000000/usb@5,1/assigned-addresses; 8 is the offset of the
> HcCommandStatus register; and the 1 bit is HostControllerReset (HCR).
>
> Now I'm just trying to find the more correct way of doing it, without
> hardcoded addresses. That'll be something like this:
>
> search the device tree for OHCI nodes
> for each OHCI node
> get assigned-addresses
> map-in
> set HCR
> wait for acknowledgement
> map-out
As you noted, your firmware does not show which usb host controllers
are OHCI and which are not. It has a lot of other problems as well.
Also, it's a lot of code to do things this way. Which is why I suggested
the "heavy handed" workaround: it is simple and should work on even the
most broken OF implementations.
To figure out which host controllers are OHCI, you'll need to look
at the PCI class code (0c0310 for OHCI), since your OF doesn't want
to tell you.
> Sound good?
Sounds like it should work, yes.
Segher
^ permalink raw reply
* [PATCH 0/3][RFC][REPOST] Add Support for Virtual Processor Home Node (VPHN)
From: Jesse Larrew @ 2010-10-29 0:27 UTC (permalink / raw)
To: linuxppc-dev; +Cc: markn, pmac, tbreeds, lkessler, Jesse Larrew, mjwolf
From: Jesse Larrew <jlarrew@linux.vnet.ibm.com>
The SPLPAR option allows the platform to dispatch virtual processors on
physical processors that, due to the variable nature of work loads, are
temporarily free, thus improving the utilization of computing resources.
However, SPLPAR implies inconsistent mapping of virtual to physical
processors, thus defeating resource allocation software that attempts to
optimize performance on platforms that implement the NUMA option.
To bridge the gap between these two options, the VPHN option maintains a
substantially consistent mapping of a given virtual processor to a physical
processor or set of processors within a given associativity domain. When
allocating computing resources, the kernel can take advantage of this
statistically consistent mapping to improve processing performance.
VPHN mappings are substantially consistent but not static. For any given
dispatch cycle, a best effort is made by the hypervisor to dispatch the
virtual processor on a physical processor within a targeted associativity
domain (the virtual processor's home node). However, if processing capacity
within the home node is not available, some other physical processor is
assigned to meet the processing capacity entitlement. From time to time,
to optimize the total platform performance, it may be necessary for the
platform to change the home node of a given virtual processor.
The Virtual Processor Home Node feature addresses this by adding the
H_HOME_NODE_ASSOCIATIVITY hcall to retrieve the current associativity
domain information directly from the hypervisor for a given virtual
processor's home node. It also exposes a set of associativity change
counters in the Virtual Processor Area (VPA) of each processor to indicate
when associativity changes occur.
This patch set sets a timer during boot that will periodically poll the
associativity change counters. When a change in associativity is detected,
it retrieves the new associativity domain information via the
H_HOME_NODE_ASSOCIATIVITY hcall and updates the NUMA node maps and sysfs
entries accordingly. The polling mechanism is also tied into the
ibm,suspend-me rtas call to stop/restart polling before/after a suspend,
hibernate, migrate, or checkpoint restart operation.
This patch set applies to v2.6.36 and includes the following:
[PATCH 1/3] powerpc: Add VPHN firmware feature
[PATCH 2/3] powerpc: Poll VPA for topology changes and update NUMA maps
[PATCH 3/3] powerpc: Disable VPHN polling during a suspend operation
Signed-off-by: Jesse Larrew <jlarrew@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/firmware.h | 3 +-
arch/powerpc/include/asm/hvcall.h | 3 +-
arch/powerpc/include/asm/lppaca.h | 5 +-
arch/powerpc/include/asm/topology.h | 6 +-
arch/powerpc/kernel/rtas.c | 15 ++
arch/powerpc/mm/numa.c | 274 +++++++++++++++++++++++++++-
arch/powerpc/platforms/pseries/firmware.c | 1 +
7 files changed, 293 insertions(+), 14 deletions(-)
^ permalink raw reply
* [PATCH 1/3] powerpc: Add VPHN firmware feature
From: Jesse Larrew @ 2010-10-29 0:28 UTC (permalink / raw)
To: linuxppc-dev; +Cc: markn, pmac, tbreeds, lkessler, Jesse Larrew, mjwolf
In-Reply-To: <20101029002628.17835.37125.sendpatchset@manic8ball.ltc.austin.ibm.com>
From: Jesse Larrew <jlarrew@linux.vnet.ibm.com>
This simple patch adds the firmware feature for VPHN to the firmware
features bitmask.
Signed-off-by: Jesse Larrew <jlarrew@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/firmware.h | 3 ++-
arch/powerpc/include/asm/hvcall.h | 3 ++-
arch/powerpc/platforms/pseries/firmware.c | 1 +
3 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/include/asm/firmware.h b/arch/powerpc/include/asm/firmware.h
index 20778a4..4ef662e 100644
--- a/arch/powerpc/include/asm/firmware.h
+++ b/arch/powerpc/include/asm/firmware.h
@@ -46,6 +46,7 @@
#define FW_FEATURE_PS3_LV1 ASM_CONST(0x0000000000800000)
#define FW_FEATURE_BEAT ASM_CONST(0x0000000001000000)
#define FW_FEATURE_CMO ASM_CONST(0x0000000002000000)
+#define FW_FEATURE_VPHN ASM_CONST(0x0000000004000000)
#ifndef __ASSEMBLY__
@@ -59,7 +60,7 @@ enum {
FW_FEATURE_VIO | FW_FEATURE_RDMA | FW_FEATURE_LLAN |
FW_FEATURE_BULK_REMOVE | FW_FEATURE_XDABR |
FW_FEATURE_MULTITCE | FW_FEATURE_SPLPAR | FW_FEATURE_LPAR |
- FW_FEATURE_CMO,
+ FW_FEATURE_CMO | FW_FEATURE_VPHN,
FW_FEATURE_PSERIES_ALWAYS = 0,
FW_FEATURE_ISERIES_POSSIBLE = FW_FEATURE_ISERIES | FW_FEATURE_LPAR,
FW_FEATURE_ISERIES_ALWAYS = FW_FEATURE_ISERIES | FW_FEATURE_LPAR,
diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h
index de03ca5..6de1e5f 100644
--- a/arch/powerpc/include/asm/hvcall.h
+++ b/arch/powerpc/include/asm/hvcall.h
@@ -232,7 +232,8 @@
#define H_GET_EM_PARMS 0x2B8
#define H_SET_MPP 0x2D0
#define H_GET_MPP 0x2D4
-#define MAX_HCALL_OPCODE H_GET_MPP
+#define H_HOME_NODE_ASSOCIATIVITY 0x2EC
+#define MAX_HCALL_OPCODE H_HOME_NODE_ASSOCIATIVITY
#ifndef __ASSEMBLY__
diff --git a/arch/powerpc/platforms/pseries/firmware.c b/arch/powerpc/platforms/pseries/firmware.c
index 0a14d8c..0b0eff0 100644
--- a/arch/powerpc/platforms/pseries/firmware.c
+++ b/arch/powerpc/platforms/pseries/firmware.c
@@ -55,6 +55,7 @@ firmware_features_table[FIRMWARE_MAX_FEATURES] = {
{FW_FEATURE_XDABR, "hcall-xdabr"},
{FW_FEATURE_MULTITCE, "hcall-multi-tce"},
{FW_FEATURE_SPLPAR, "hcall-splpar"},
+ {FW_FEATURE_VPHN, "hcall-vphn"},
};
/* Build up the firmware features bitmask using the contents of
--
1.7.2.3
^ permalink raw reply related
* [PATCH 2/3] powerpc: Poll VPA for topology changes and update NUMA maps
From: Jesse Larrew @ 2010-10-29 0:33 UTC (permalink / raw)
To: linuxppc-dev; +Cc: markn, pmac, tbreeds, lkessler, Jesse Larrew, mjwolf
In-Reply-To: <20101029002628.17835.37125.sendpatchset@manic8ball.ltc.austin.ibm.com>
From: Jesse Larrew <jlarrew@linux.vnet.ibm.com>
This patch sets a timer during boot that will periodically poll the
associativity change counters in the VPA. When a change in
associativity is detected, it retrieves the new associativity domain
information via the H_HOME_NODE_ASSOCIATIVITY hcall and updates the
NUMA node maps and sysfs entries accordingly. Note that since the
ibm,associativity device tree property does not exist on configurations
with both NUMA and SPLPAR enabled, no device tree updates are necessary.
Signed-off-by: Jesse Larrew <jlarrew@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/lppaca.h | 5 +-
arch/powerpc/mm/numa.c | 274 +++++++++++++++++++++++++++++++++++--
2 files changed, 268 insertions(+), 11 deletions(-)
diff --git a/arch/powerpc/include/asm/lppaca.h b/arch/powerpc/include/asm/lppaca.h
index 7f5e0fe..380d48b 100644
--- a/arch/powerpc/include/asm/lppaca.h
+++ b/arch/powerpc/include/asm/lppaca.h
@@ -62,7 +62,10 @@ struct lppaca {
volatile u32 dyn_pir; // Dynamic ProcIdReg value x20-x23
u32 dsei_data; // DSEI data x24-x27
u64 sprg3; // SPRG3 value x28-x2F
- u8 reserved3[80]; // Reserved x30-x7F
+ u8 reserved3[40]; // Reserved x30-x57
+ volatile u8 vphn_assoc_counts[8]; // Virtual processor home node
+ // associativity change counters x58-x5F
+ u8 reserved4[32]; // Reserved x60-x7F
//=============================================================================
// CACHE_LINE_2 0x0080 - 0x00FF Contains local read-write data
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index 74505b2..3150c32 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -20,10 +20,14 @@
#include <linux/memblock.h>
#include <linux/of.h>
#include <linux/pfn.h>
+#include <linux/cpuset.h>
+#include <linux/node.h>
#include <asm/sparsemem.h>
#include <asm/prom.h>
#include <asm/system.h>
#include <asm/smp.h>
+#include <asm/firmware.h>
+#include <asm/paca.h>
static int numa_enabled = 1;
@@ -246,32 +250,41 @@ static void initialize_distance_lookup_table(int nid,
/* Returns nid in the range [0..MAX_NUMNODES-1], or -1 if no useful numa
* info is found.
*/
-static int of_node_to_nid_single(struct device_node *device)
+static int associativity_to_nid(const unsigned int *associativity)
{
int nid = -1;
- const unsigned int *tmp;
if (min_common_depth == -1)
goto out;
- tmp = of_get_associativity(device);
- if (!tmp)
- goto out;
-
- if (tmp[0] >= min_common_depth)
- nid = tmp[min_common_depth];
+ if (associativity[0] >= min_common_depth)
+ nid = associativity[min_common_depth];
/* POWER4 LPAR uses 0xffff as invalid node */
if (nid == 0xffff || nid >= MAX_NUMNODES)
nid = -1;
- if (nid > 0 && tmp[0] >= distance_ref_points_depth)
- initialize_distance_lookup_table(nid, tmp);
+ if (nid > 0 && associativity[0] >= distance_ref_points_depth)
+ initialize_distance_lookup_table(nid, associativity);
out:
return nid;
}
+/* Returns the nid associated with the given device tree node,
+ * or -1 if not found.
+ */
+static int of_node_to_nid_single(struct device_node *device)
+{
+ int nid = -1;
+ const unsigned int *tmp;
+
+ tmp = of_get_associativity(device);
+ if (tmp)
+ nid = associativity_to_nid(tmp);
+ return nid;
+}
+
/* Walk the device tree upwards, looking for an associativity id */
int of_node_to_nid(struct device_node *device)
{
@@ -1248,3 +1261,244 @@ int hot_add_scn_to_nid(unsigned long scn_addr)
}
#endif /* CONFIG_MEMORY_HOTPLUG */
+
+/* Vrtual Processor Home Node (VPHN) support */
+#define VPHN_NR_CHANGE_CTRS (8)
+static u8 vphn_cpu_change_counts[NR_CPUS][VPHN_NR_CHANGE_CTRS];
+static cpumask_t cpu_associativity_changes_mask;
+static void topology_work_fn(struct work_struct *work);
+static DECLARE_WORK(topology_work, topology_work_fn);
+static void topology_timer_fn(unsigned long ignored);
+static struct timer_list topology_timer =
+ TIMER_INITIALIZER(topology_timer_fn, 0, 0);
+
+static void set_topology_timer(void);
+int stop_topology_update(void);
+
+/*
+ * Store the current values of the associativity change counters in the
+ * hypervisor.
+ */
+static void setup_cpu_associativity_change_counters(void)
+{
+ int cpu = 0;
+
+ for_each_possible_cpu(cpu) {
+ int i = 0;
+ u8 *counts = vphn_cpu_change_counts[cpu];
+ volatile u8 *hypervisor_counts = lppaca[cpu].vphn_assoc_counts;
+
+ for (i = 0; i < VPHN_NR_CHANGE_CTRS; i++) {
+ counts[i] = hypervisor_counts[i];
+ }
+ }
+
+ return;
+}
+
+/*
+ * The hypervisor maintains a set of 8 associativity change counters in
+ * the VPA of each cpu that correspond to the associativity levels in the
+ * ibm,associativity-reference-points property. When an associativity
+ * level changes, the corresponding counter is incremented.
+ *
+ * Set a bit in cpu_associativity_changes_mask for each cpu whose home
+ * node associativity levels have changed.
+ */
+static void update_cpu_associativity_changes_mask(void)
+{
+ int cpu = 0;
+ cpumask_t *changes = &cpu_associativity_changes_mask;
+
+ cpumask_clear(changes);
+
+ for_each_possible_cpu(cpu) {
+ int i;
+ u8 *counts = vphn_cpu_change_counts[cpu];
+ volatile u8 *hypervisor_counts = lppaca[cpu].vphn_assoc_counts;
+
+ for (i = 0; i < VPHN_NR_CHANGE_CTRS; i++) {
+ if (hypervisor_counts[i] > counts[i]) {
+ counts[i] = hypervisor_counts[i];
+
+ if (!(cpumask_test_cpu(cpu, changes)))
+ cpumask_set_cpu(cpu, changes);
+ }
+ }
+ }
+
+ return;
+}
+
+/* 6 64-bit registers unpacked into 12 32-bit associativity values */
+#define VPHN_ASSOC_BUFSIZE (6*sizeof(u64)/sizeof(u32))
+
+/*
+ * Convert the associativity domain numbers returned from the hypervisor
+ * to the sequence they would appear in the ibm,associativity property.
+ */
+static int vphn_unpack_associativity(const long *packed, unsigned int *unpacked)
+{
+ int i = 0;
+ int nr_assoc_doms = 0;
+ const u16 *field = (const u16*) packed;
+
+#define VPHN_FIELD_UNUSED (0xffff)
+#define VPHN_FIELD_MSB (0x8000)
+#define VPHN_FIELD_MASK (~VPHN_FIELD_MSB)
+
+ for (i = 0; i < VPHN_ASSOC_BUFSIZE; i++) {
+ if (*field == VPHN_FIELD_UNUSED) {
+ /* All significant fields processed, and remaining
+ * fields contain the reserved value of all 1's.
+ * Just store them.
+ */
+ unpacked[i] = *((u32*)field);
+ field += 2;
+ }
+ else if (*field & VPHN_FIELD_MSB) {
+ /* Data is in the lower 15 bits of this field */
+ unpacked[i] = *field & VPHN_FIELD_MASK;
+ field++;
+ nr_assoc_doms++;
+ }
+ else {
+ /* Data is in the lower 15 bits of this field
+ * concatenated with the next 16 bit field
+ */
+ unpacked[i] = *((u32*)field);
+ field += 2;
+ nr_assoc_doms++;
+ }
+ }
+
+ return nr_assoc_doms;
+}
+
+/*
+ * Retrieve the new associativity information for a virtual processor's
+ * home node.
+ */
+static long hcall_vphn(unsigned long cpu, unsigned int *associativity)
+{
+ long rc = 0;
+ long retbuf[PLPAR_HCALL9_BUFSIZE] = {0};
+ u64 flags = 1;
+ int hwcpu = get_hard_smp_processor_id(cpu);
+
+ rc = plpar_hcall9(H_HOME_NODE_ASSOCIATIVITY, retbuf, flags, hwcpu);
+ vphn_unpack_associativity(retbuf, associativity);
+
+ return rc;
+}
+
+static long
+vphn_get_associativity(unsigned long cpu, unsigned int *associativity)
+{
+ long rc = 0;
+
+ rc = hcall_vphn(cpu, associativity);
+
+ switch (rc) {
+ case H_FUNCTION:
+ printk(KERN_INFO
+ "VPHN is not supported. Disabling polling...\n");
+ stop_topology_update();
+ break;
+ case H_HARDWARE:
+ printk(KERN_ERR
+ "hcall_vphn() experienced a hardware fault "
+ "preventing VPHN. Disabling polling...\n");
+ stop_topology_update();
+ }
+
+ return rc;
+}
+
+/*
+ * Update the node maps and sysfs entries for each cpu whose home node
+ * has changed.
+ */
+int arch_update_cpu_topology(void)
+{
+ int cpu = 0, nid = 0, old_nid = 0;
+ unsigned int associativity[VPHN_ASSOC_BUFSIZE] = {0};
+ struct sys_device *sysdev = NULL;
+
+ for_each_cpu_mask(cpu, cpu_associativity_changes_mask) {
+ vphn_get_associativity(cpu, associativity);
+ nid = associativity_to_nid(associativity);
+
+ if (nid < 0 || !node_online(nid))
+ nid = first_online_node;
+
+ old_nid = numa_cpu_lookup_table[cpu];
+
+ /* Disable hotplug while we update the cpu
+ * masks and sysfs.
+ */
+ get_online_cpus();
+ unregister_cpu_under_node(cpu, old_nid);
+ unmap_cpu_from_node(cpu);
+ map_cpu_to_node(cpu, nid);
+ register_cpu_under_node(cpu, nid);
+ put_online_cpus();
+
+ sysdev = get_cpu_sysdev(cpu);
+ if (sysdev)
+ kobject_uevent(&sysdev->kobj, KOBJ_CHANGE);
+ }
+
+ return 1;
+}
+
+static void topology_work_fn(struct work_struct *work)
+{
+ rebuild_sched_domains();
+}
+
+void topology_schedule_update(void)
+{
+ schedule_work(&topology_work);
+}
+
+static void topology_timer_fn(unsigned long ignored)
+{
+ update_cpu_associativity_changes_mask();
+ if (!cpumask_empty(&cpu_associativity_changes_mask))
+ topology_schedule_update();
+ set_topology_timer();
+}
+
+static void set_topology_timer(void)
+{
+ topology_timer.data = 0;
+ topology_timer.expires = jiffies + 60 * HZ;
+ add_timer(&topology_timer);
+}
+
+/*
+ * Start polling for VPHN associativity changes.
+ */
+int __init init_topology_update(void)
+{
+ int rc = 0;
+
+ if (firmware_has_feature(FW_FEATURE_VPHN)) {
+ setup_cpu_associativity_change_counters();
+ init_timer_deferrable(&topology_timer);
+ set_topology_timer();
+ rc = 1;
+ }
+
+ return rc;
+}
+__initcall(init_topology_update);
+
+/*
+ * Disable polling for VPHN associativity changes.
+ */
+int stop_topology_update(void)
+{
+ return del_timer(&topology_timer);
+}
--
1.7.2.3
^ permalink raw reply related
* [PATCH 3/3] powerpc: Disable VPHN polling during a suspend operation
From: Jesse Larrew @ 2010-10-29 0:30 UTC (permalink / raw)
To: linuxppc-dev; +Cc: markn, pmac, tbreeds, lkessler, Jesse Larrew, mjwolf
In-Reply-To: <20101029002628.17835.37125.sendpatchset@manic8ball.ltc.austin.ibm.com>
From: Jesse Larrew <jlarrew@linux.vnet.ibm.com>
Tie the polling mechanism into the ibm,suspend-me rtas call to
stop/restart polling before/after a suspend, hibernate, migrate,
or checkpoint restart operation. This ensures that the system has a
chance to disable the polling if the partition is migrated to a system
that does not support VPHN (and vice versa).
Signed-off-by: Jesse Larrew <jlarrew@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/topology.h | 6 +++++-
arch/powerpc/kernel/rtas.c | 15 +++++++++++++++
2 files changed, 20 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h
index afe4aaa..1747d27 100644
--- a/arch/powerpc/include/asm/topology.h
+++ b/arch/powerpc/include/asm/topology.h
@@ -49,7 +49,7 @@ static inline int pcibus_to_node(struct pci_bus *bus)
{
return -1;
}
-#endif
+#endif /* CONFIG_PCI */
#define cpumask_of_pcibus(bus) (pcibus_to_node(bus) == -1 ? \
cpu_all_mask : \
@@ -93,6 +93,8 @@ extern void __init dump_numa_cpu_topology(void);
extern int sysfs_add_device_to_node(struct sys_device *dev, int nid);
extern void sysfs_remove_device_from_node(struct sys_device *dev, int nid);
+extern int __init init_topology_update(void);
+extern int stop_topology_update(void);
#else
static inline void dump_numa_cpu_topology(void) {}
@@ -107,6 +109,8 @@ static inline void sysfs_remove_device_from_node(struct sys_device *dev,
{
}
+static int __init init_topology_update(void) {}
+static int stop_topology_update(void) {}
#endif /* CONFIG_NUMA */
#include <asm-generic/topology.h>
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 8fe8bc6..317ff2f 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -41,6 +41,7 @@
#include <asm/atomic.h>
#include <asm/time.h>
#include <asm/mmu.h>
+#include <asm/topology.h>
struct rtas_t rtas = {
.lock = __ARCH_SPIN_LOCK_UNLOCKED
@@ -706,6 +707,18 @@ void rtas_os_term(char *str)
static int ibm_suspend_me_token = RTAS_UNKNOWN_SERVICE;
#ifdef CONFIG_PPC_PSERIES
+static void pre_suspend_work(void)
+{
+ stop_topology_update();
+ return;
+}
+
+static void post_suspend_work(void)
+{
+ init_topology_update();
+ return;
+}
+
static int __rtas_suspend_last_cpu(struct rtas_suspend_me_data *data, int wake_when_done)
{
u16 slb_size = mmu_slb_size;
@@ -713,6 +726,7 @@ static int __rtas_suspend_last_cpu(struct rtas_suspend_me_data *data, int wake_w
int cpu;
slb_set_size(SLB_MIN_SIZE);
+ pre_suspend_work();
printk(KERN_DEBUG "calling ibm,suspend-me on cpu %i\n", smp_processor_id());
while (rc == H_MULTI_THREADS_ACTIVE && !atomic_read(&data->done) &&
@@ -728,6 +742,7 @@ static int __rtas_suspend_last_cpu(struct rtas_suspend_me_data *data, int wake_w
rc = atomic_read(&data->error);
atomic_set(&data->error, rc);
+ post_suspend_work();
if (wake_when_done) {
atomic_set(&data->done, 1);
--
1.7.2.3
^ permalink raw reply related
* [PATCH 2/4][v2] fsl_rio: fix non-standard HID1 register access
From: Shaohui Xie @ 2010-10-29 7:13 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Alexandre Bounine, Kumar Gala, Shaohui Xie
Signed-off-by: Shaohui Xie <b21989@freescale.com>
Cc: Li Yang <leoli@freescale.com>
Cc: Kumar Gala <kumar.gala@freescale.com>
Cc: Roy Zang <tie-fei.zang@freescale.com>
Cc: Alexandre Bounine <alexandre.bounine@idt.com>
---
arch/powerpc/kernel/cpu_setup_fsl_booke.S | 6 ++++++
arch/powerpc/sysdev/fsl_rio.c | 2 --
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/kernel/cpu_setup_fsl_booke.S b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
index 0adb50a..8fd5bc6 100644
--- a/arch/powerpc/kernel/cpu_setup_fsl_booke.S
+++ b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
@@ -63,6 +63,12 @@ _GLOBAL(__setup_cpu_e500v2)
bl __e500_icache_setup
bl __e500_dcache_setup
bl __setup_e500_ivors
+#ifdef CONFIG_RAPIDIO
+ /* Ensure that RFXE is set */
+ mfspr r3,SPRN_HID1
+ oris r3,r3,HID1_RFXE@h
+ mtspr SPRN_HID1,r3
+#endif
mtlr r4
blr
_GLOBAL(__setup_cpu_e500mc)
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index 4127636..1143c93 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -1538,8 +1538,6 @@ int fsl_rio_setup(struct platform_device *dev)
saved_mcheck_exception = ppc_md.machine_check_exception;
ppc_md.machine_check_exception = fsl_rio_mcheck_exception;
#endif
- /* Ensure that RFXE is set */
- mtspr(SPRN_HID1, (mfspr(SPRN_HID1) | 0x20000));
return 0;
err:
--
1.6.4
^ permalink raw reply related
* [PATCH 3/4][v2] fsl_rio: move machine_check handler into machine_check_e500 & machine_check_e500mc
From: Shaohui Xie @ 2010-10-29 7:14 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Alexandre Bounine, Kumar Gala, Shaohui Xie
Signed-off-by: Shaohui Xie <b21989@freescale.com>
Cc: Li Yang <leoli@freescale.com>
Cc: Kumar Gala <kumar.gala@freescale.com>
Cc: Roy Zang <tie-fei.zang@freescale.com>
Cc: Alexandre Bounine <alexandre.bounine@idt.com>
---
arch/powerpc/kernel/traps.c | 14 +++++++++++++-
arch/powerpc/sysdev/fsl_rio.c | 15 +++------------
include/linux/rio.h | 1 +
3 files changed, 17 insertions(+), 13 deletions(-)
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index a45a63c..2a5fb9d 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -55,6 +55,7 @@
#endif
#include <asm/kexec.h>
#include <asm/ppc-opcode.h>
+#include <linux/rio.h>
#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
int (*__debugger)(struct pt_regs *regs) __read_mostly;
@@ -500,6 +501,13 @@ int machine_check_e500mc(struct pt_regs *regs)
reason & MCSR_MEA ? "Effective" : "Physical", addr);
}
+ if (reason & MCSR_BUS_RBERR) {
+ printk("Bus - Read Data Bus Error\n");
+#ifdef CONFIG_RAPIDIO
+ recoverable = fsl_rio_mcheck_exception(regs);
+#endif
+ }
+
mtspr(SPRN_MCSR, mcsr);
return mfspr(SPRN_MCSR) == 0 && recoverable;
}
@@ -527,8 +535,12 @@ int machine_check_e500(struct pt_regs *regs)
printk("Bus - Write Address Error\n");
if (reason & MCSR_BUS_IBERR)
printk("Bus - Instruction Data Error\n");
- if (reason & MCSR_BUS_RBERR)
+ if (reason & MCSR_BUS_RBERR) {
printk("Bus - Read Data Bus Error\n");
+#ifdef CONFIG_RAPIDIO
+ fsl_rio_mcheck_exception(regs);
+#endif
+ }
if (reason & MCSR_BUS_WBERR)
printk("Bus - Read Data Bus Error\n");
if (reason & MCSR_BUS_IPERR)
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index 1143c93..a9bc1e8 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -256,9 +256,7 @@ struct rio_priv {
static void __iomem *rio_regs_win;
#ifdef CONFIG_E500
-static int (*saved_mcheck_exception)(struct pt_regs *regs);
-
-static int fsl_rio_mcheck_exception(struct pt_regs *regs)
+int fsl_rio_mcheck_exception(struct pt_regs *regs)
{
const struct exception_table_entry *entry = NULL;
unsigned long reason = mfspr(SPRN_MCSR);
@@ -280,11 +278,9 @@ static int fsl_rio_mcheck_exception(struct pt_regs *regs)
}
}
- if (saved_mcheck_exception)
- return saved_mcheck_exception(regs);
- else
- return cur_cpu_spec->machine_check(regs);
+ return 0;
}
+EXPORT_SYMBOL_GPL(fsl_rio_mcheck_exception);
#endif
/**
@@ -1534,11 +1530,6 @@ int fsl_rio_setup(struct platform_device *dev)
fsl_rio_doorbell_init(port);
fsl_rio_port_write_init(port);
-#ifdef CONFIG_E500
- saved_mcheck_exception = ppc_md.machine_check_exception;
- ppc_md.machine_check_exception = fsl_rio_mcheck_exception;
-#endif
-
return 0;
err:
iounmap(priv->regs_win);
diff --git a/include/linux/rio.h b/include/linux/rio.h
index bd6eb0e..685b18f 100644
--- a/include/linux/rio.h
+++ b/include/linux/rio.h
@@ -365,5 +365,6 @@ extern int rio_open_inb_mbox(struct rio_mport *, void *, int, int);
extern void rio_close_inb_mbox(struct rio_mport *, int);
extern int rio_open_outb_mbox(struct rio_mport *, void *, int, int);
extern void rio_close_outb_mbox(struct rio_mport *, int);
+extern int fsl_rio_mcheck_exception(struct pt_regs *);
#endif /* LINUX_RIO_H */
--
1.6.4
^ permalink raw reply related
* [PATCH 1/4][v2] powerpc: add e500 HID1 bit definition
From: Shaohui Xie @ 2010-10-29 7:13 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Alexandre Bounine, Kumar Gala, Shaohui Xie
From: Li Yang <leoli@freescale.com>
Also make 74xx HID1 definition conditional.
Signed-off-by: Li Yang <leoli@freescale.com>
Signed-off-by: Shaohui Xie <b21989@freescale.com>
Cc: Li Yang <leoli@freescale.com>
Cc: Kumar Gala <kumar.gala@freescale.com>
Cc: Roy Zang <tie-fei.zang@freescale.com>
Cc: Alexandre Bounine <alexandre.bounine@idt.com>
---
arch/powerpc/include/asm/reg.h | 2 ++
arch/powerpc/include/asm/reg_booke.h | 14 ++++++++++++++
2 files changed, 16 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index ff0005e..125fc1a 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -283,6 +283,7 @@
#define HID0_NOPTI (1<<0) /* No-op dcbt and dcbst instr. */
#define SPRN_HID1 0x3F1 /* Hardware Implementation Register 1 */
+#ifdef CONFIG_6xx
#define HID1_EMCP (1<<31) /* 7450 Machine Check Pin Enable */
#define HID1_DFS (1<<22) /* 7447A Dynamic Frequency Scaling */
#define HID1_PC0 (1<<16) /* 7450 PLL_CFG[0] */
@@ -292,6 +293,7 @@
#define HID1_SYNCBE (1<<11) /* 7450 ABE for sync, eieio */
#define HID1_ABE (1<<10) /* 7450 Address Broadcast Enable */
#define HID1_PS (1<<16) /* 750FX PLL selection */
+#endif
#define SPRN_HID2 0x3F8 /* Hardware Implementation Register 2 */
#define SPRN_HID2_GEKKO 0x398 /* Gekko HID2 Register */
#define SPRN_IABR 0x3F2 /* Instruction Address Breakpoint Register */
diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h
index 667a498..dc6adff 100644
--- a/arch/powerpc/include/asm/reg_booke.h
+++ b/arch/powerpc/include/asm/reg_booke.h
@@ -246,6 +246,20 @@
store or cache line push */
#endif
+/* Bit definitions for the HID1 */
+#ifdef CONFIG_E500
+/* e500v1/v2 */
+#define HID1_PLL_CFG_MASK 0xfc000000 /* PLL_CFG input pins */
+#define HID1_RFXE 0x00020000 /* Read fault exception enable */
+#define HID1_R1DPE 0x00008000 /* R1 data bus parity enable */
+#define HID1_R2DPE 0x00004000 /* R2 data bus parity enable */
+#define HID1_ASTME 0x00002000 /* Address bus streaming mode enable */
+#define HID1_ABE 0x00001000 /* Address broadcast enable */
+#define HID1_MPXTT 0x00000400 /* MPX re-map transfer type */
+#define HID1_ATS 0x00000080 /* Atomic status */
+#define HID1_MID_MASK 0x0000000f /* MID input pins */
+#endif
+
/* Bit definitions for the DBSR. */
/*
* DBSR bits which have conflicting definitions on true Book E versus IBM 40x.
--
1.6.4
^ permalink raw reply related
* [PATCH 4/4][v2] rapidio, powerpc/85xx: Error interrupt handler for sRIO.
From: Shaohui Xie @ 2010-10-29 7:14 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Alexandre Bounine, Kumar Gala, Shaohui Xie
The sRIO controller reports errors to the core with one signal, it uses
register EPWISR to provides the core quick access to where the error occurred.
The EPWISR indicates that there are 4 interrupts sources, port1, port2, message
unit and port write receive, but the sRIO driver does not support port2
for now, still the handler takes care of port2.
Currently the handler only clear error status without any recovery.
Signed-off-by: Shaohui Xie <b21989@freescale.com>
Cc: Li Yang <leoli@freescale.com>
Cc: Kumar Gala <kumar.gala@freescale.com>
Cc: Roy Zang <tie-fei.zang@freescale.com>
Cc: Alexandre Bounine <alexandre.bounine@idt.com>
---
arch/powerpc/sysdev/fsl_rio.c | 86 +++++++++++++++++++++++++++++++++++++---
1 files changed, 79 insertions(+), 7 deletions(-)
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index a9bc1e8..8de86a8 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -10,7 +10,7 @@
* - Added Port-Write message handling
* - Added Machine Check exception handling
*
- * Copyright (C) 2007, 2008 Freescale Semiconductor, Inc.
+ * Copyright (C) 2007, 2008, 2010 Freescale Semiconductor, Inc.
* Zhang Wei <wei.zhang@freescale.com>
*
* Copyright 2005 MontaVista Software, Inc.
@@ -47,10 +47,36 @@
#define IRQ_RIO_RX(m) (((struct rio_priv *)(m->priv))->rxirq)
#define IRQ_RIO_PW(m) (((struct rio_priv *)(m->priv))->pwirq)
+/* EPWISR Error match value */
+#define EPWISR_ERR_PINT1 0x80000000
+#define EPWISR_ERR_PINT2 0x40000000
+#define EPWISR_ERR_MU 0x2
+#define EPWISR_ERR_PW 0x1
+
+#define IPWMR_CLEAR_QUEUE 0x00000002
+#define IPWSR_CLEAR 0x98
+#define OMSR_CLEAR 0x1cb3
+#define IMSR_CLEAR 0x491
+#define IDSR_CLEAR 0x91
+#define ODSR_CLEAR 0x1c00
+#define LTLEECSR_ENABLE_ALL 0xFFC000FC
+#define ESCSR_CLEAR 0x07120204
+
+#define RIO_EDCSR 0x0640
+#define PORT2_RIO_EDCSR 0x0680
+#define RIO_IECSR 0x10130
+#define PORT2_RIO_IECSR 0x101B0
+#define RIO_IM0SR 0x13064
+#define RIO_IM1SR 0x13164
+#define RIO_OM0SR 0x13004
+#define RIO_OM1SR 0x13104
+
+#define RIO_EPWISR_OFFSET 0x10010
#define RIO_ATMU_REGS_OFFSET 0x10c00
#define RIO_P_MSG_REGS_OFFSET 0x11000
#define RIO_S_MSG_REGS_OFFSET 0x13000
#define RIO_ESCSR 0x158
+#define PORT2_RIO_ESCSR 0x178
#define RIO_CCSR 0x15c
#define RIO_LTLEDCSR 0x0608
#define RIO_LTLEDCSR_IER 0x80000000
@@ -1003,6 +1029,40 @@ fsl_rio_dbell_handler(int irq, void *dev_instance)
return IRQ_HANDLED;
}
+static void port_error_handler(struct rio_mport *port, int offset)
+{
+ /*XXX: Error recovery is not implemented, we just clear errors */
+ out_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR), 0);
+
+ if (offset == 0) {
+ out_be32((u32 *)(rio_regs_win + RIO_EDCSR), 0);
+ out_be32((u32 *)(rio_regs_win + RIO_IECSR), 0);
+ out_be32((u32 *)(rio_regs_win + RIO_ESCSR), ESCSR_CLEAR);
+ } else {
+ out_be32((u32 *)(rio_regs_win + PORT2_RIO_EDCSR), 0);
+ out_be32((u32 *)(rio_regs_win + PORT2_RIO_IECSR), 0);
+ out_be32((u32 *)(rio_regs_win + PORT2_RIO_ESCSR), ESCSR_CLEAR);
+ }
+}
+
+static void msg_unit_error_handler(struct rio_mport *port)
+{
+ struct rio_priv *priv = port->priv;
+
+ /*XXX: Error recovery is not implemented, we just clear errors */
+ out_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR), 0);
+
+ out_be32((u32 *)(rio_regs_win + RIO_IM0SR), IMSR_CLEAR);
+ out_be32((u32 *)(rio_regs_win + RIO_IM1SR), IMSR_CLEAR);
+ out_be32((u32 *)(rio_regs_win + RIO_OM0SR), OMSR_CLEAR);
+ out_be32((u32 *)(rio_regs_win + RIO_OM1SR), OMSR_CLEAR);
+
+ out_be32(&priv->msg_regs->odsr, ODSR_CLEAR);
+ out_be32(&priv->msg_regs->dsr, IDSR_CLEAR);
+
+ out_be32(&priv->msg_regs->pwsr, IPWSR_CLEAR);
+}
+
/**
* fsl_rio_doorbell_init - MPC85xx doorbell interface init
* @mport: Master port implementing the inbound doorbell unit
@@ -1082,14 +1142,24 @@ fsl_rio_port_write_handler(int irq, void *dev_instance)
ipwsr = in_be32(&priv->msg_regs->pwsr);
epwisr = in_be32(priv->regs_win + RIO_EPWISR);
- if (epwisr & 0x80000000) {
+ if (epwisr & EPWISR_ERR_PINT1) {
tmp = in_be32(priv->regs_win + RIO_LTLEDCSR);
pr_info("RIO_LTLEDCSR = 0x%x\n", tmp);
- out_be32(priv->regs_win + RIO_LTLEDCSR, 0);
+ port_error_handler(port, 0);
+ }
+
+ if (epwisr & EPWISR_ERR_PINT2) {
+ pr_info("RIO: port2 error\n");
+ port_error_handler(port, 1);
+ }
+
+ if (epwisr & EPWISR_ERR_MU) {
+ pr_info("RIO: message unit error\n");
+ msg_unit_error_handler(port);
}
- if (!(epwisr & 0x00000001))
- return IRQ_HANDLED;
+ if (!(epwisr & EPWISR_ERR_PW))
+ return IRQ_NONE;
#ifdef DEBUG_PW
pr_debug("PW Int->IPWMR: 0x%08x IPWSR: 0x%08x (", ipwmr, ipwsr);
@@ -1249,12 +1319,14 @@ static int fsl_rio_port_write_init(struct rio_mport *mport)
/* Hook up port-write handler */
- rc = request_irq(IRQ_RIO_PW(mport), fsl_rio_port_write_handler, 0,
- "port-write", (void *)mport);
+ rc = request_irq(IRQ_RIO_PW(mport), fsl_rio_port_write_handler,
+ IRQF_SHARED, "port-write", (void *)mport);
if (rc < 0) {
pr_err("MPC85xx RIO: unable to request inbound doorbell irq");
goto err_out;
}
+ /* Enable Error Interrupt */
+ out_be32((u32 *)(rio_regs_win + RIO_LTLEECSR), LTLEECSR_ENABLE_ALL);
INIT_WORK(&priv->pw_work, fsl_pw_dpc);
spin_lock_init(&priv->pw_fifo_lock);
--
1.6.4
^ permalink raw reply related
* [MPC5200B] strange data loss on uart reception
From: Albrecht Dreß @ 2010-10-29 8:54 UTC (permalink / raw)
To: linuxppc-dev
Hi all,
I'm not sure if this is the right list, so please excuse me if I'm totally
wrong here, or if my question is really dumb...
My platform is a MPC5200B (roughly Icecube) based board with kernel 2.6.32.
>From a PC I try to send data through the MPC5200B's serial port, using the
standard mpc52xx_uart driver. The reading process is rather slow in
processing the incoming data. Thus, the uart is configured to use rts/cts
handshaking. The port is opened in (O_EXCL | O_RDWR) mode.
Sending large data blocks to the 5200, I noticed that complete chunks of
data are missing in the output read in user space. This is apparently *not*
a problem on the uart layer; the result of the TIOCGICOUNT ioctl does not
report any errors from the uart, and the serial_icounter_struct.rx field
contains *exactly* the correct number of data bytes I transmitted. The
data loss seems to occur only if the block is larger than 64 kByte, but I
didn't find a scheme of the actually missing number of bytes. However, it's
always a larger chunk of several hundred bytes to kBytes.
Am I simply too dumb to use the uart correctly, or is there some issue in
the kernel causing this effect? I noticed that the function
mpc52xx_uart_int_rx_chars() does not check the return value of
tty_insert_flip_char(). If the system runs out of space (actually, the
maximum buffer size used should be limited, in particular on embedded
systems!), might this be undetected? This might explain the bigger
"chunks", as the '5200's uart has a rather big fifo.
Any insight would be really appreciated!
Thanks in advance,
Albrecht.
^ permalink raw reply
* Re: RapidIO: MC Exception when enumerating peer to peer connection
From: Micha Nelissen @ 2010-10-29 9:21 UTC (permalink / raw)
To: Thomas Taranowski; +Cc: linuxppc-dev
In-Reply-To: <AANLkTimS-sfqONuSJNPJy7OxO_U81qtDHe2JeioLDNVs@mail.gmail.com>
Thomas Taranowski wrote:
> use my trusty jtag to issue a Port Link Maintenance Request and
> request status, I get back unrecoverable ackID error for port 1, and
> error-stopped port_status for port 2.
Did you try rebooting all devices together?
Micha
^ permalink raw reply
* [MPC8272ADS] porting a custom patch from 2.6.21.7 to 2.6.35.7 for a custom board
From: Alexandru Ionut Grama @ 2010-10-29 14:09 UTC (permalink / raw)
To: linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 16713 bytes --]
Hello linuxppc-dev community!
First of all, I want to introduce myself and my project. I'm working at the
Technical University of Madrid in a project for porting Linux to an embedded
system, a router. This project is my final degree thesis. This machine has a
MPC8272VRMIBA processor and a custom platform and seems to be based on
MPC8272ADS. The company that subsidizes us provides us a patch for making
the router compatible with Linux, but it only works for Linux-2.6.21.
I've achieve some aims, but for now I want to make openssl compatible with
SEC1.0. I want to use the Cryptographic-API with talitos to get the
advantage of using crypto-processor. I've decided to use Linux-2.6.35.7
because is the latest stable version of Linux, and adds new features to
"talitos". So, for now, my aim is to port the original patch to
Linux-2.6.35.7 to get CPM and serial port compatibility. After that I can do
kernel debugging for making Ethernet cards compatible, and finally make some
benchmark for the crypto system. The bad point is that the architecture of
kernel's code changes a lot and I don't know if the changes that I'm doing
are in the good way.
I'll try to explain my best what I'm doing.
Here is the original change:
diff -rcNP linux-2.6.21/arch/powerpc/mm/init_32.c
atlas_kernel/arch/powerpc/mm/init_32.c
*** linux-2.6.21/arch/powerpc/mm/init_32.c 2007-04-26 05:08:32.000000000
+0200
--- atlas_kernel/arch/powerpc/mm/init_32.c 2008-04-24 08:43:51.000000000
+0200
***************
*** 172,178 ****
#ifdef CONFIG_HIGHMEM
ioremap_base = PKMAP_BASE;
#else
! ioremap_base = 0xfe000000UL; /* for now, could be 0xfffff000 */
#endif /* CONFIG_HIGHMEM */
ioremap_bot = ioremap_base;
--- 172,178 ----
#ifdef CONFIG_HIGHMEM
ioremap_base = PKMAP_BASE;
#else
! ioremap_base = 0xff000000UL; /* for now, could be 0xfffff000 */ /*
gonza */
#endif /* CONFIG_HIGHMEM */
ioremap_bot = ioremap_base;
I reproduce this change with this:
diff -rc linux-2.6.35.7/arch/powerpc/include/asm/pgtable-ppc32.h
linux-agrama/arch/powerpc/include/asm/pgtable-ppc32.h
*** linux-2.6.35.7/arch/powerpc/include/asm/pgtable-ppc32.h 2010-09-29
03:09:08.000000000 +0200
--- linux-agrama/arch/powerpc/include/asm/pgtable-ppc32.h 2010-10-26
18:47:28.000000000 +0200
***************pq2ads
*** 63,69 ****
#ifdef CONFIG_HIGHMEM
#define KVIRT_TOP PKMAP_BASE
#else
! #define KVIRT_TOP (0xfe000000UL) /* for now, could be FIXMAP_BASE ? */
#endif
/*
--- 63,69 ----
#ifdef CONFIG_HIGHMEM
#define KVIRT_TOP PKMAP_BASE
#else
! #define KVIRT_TOP (0xff000000UL) /* for now, could be FIXMAP_BASE ? */ /*
agrama, antes KVIRT_TOP era 0xfe000000UL */
#endif
/*
Also, I've add the next line:
diff -rc linux-2.6.35.7/arch/powerpc/mm/init_32.c
linux-agrama/arch/powerpc/mm/init_32.c
*** linux-2.6.35.7/arch/powerpc/mm/init_32.c 2010-09-29
03:09:08.000000000 +0200
--- linux-agrama/arch/powerpc/mm/init_32.c 2010-10-29 10:28:43.000000000
+0200
***************
*** 178,184 ****
/* Initialize early top-down ioremap allocator */
ioremap_bot = IOREMAP_TOP;
!
/* Map in I/O resources */
if (ppc_md.progress)
ppc_md.progress("MMU:setio", 0x302);
--- 178,184 ----
/* Initialize early top-down ioremap allocator */
ioremap_bot = IOREMAP_TOP;
! ioremap_base = ioremap_bot; /*agrama*/
/* Map in I/O resources */
if (ppc_md.progress)
ppc_md.progress("MMU:setio", 0x302);
¿It's correct to add the line ioremap_base=ioremap_bot or ioremap_base it
not used anymore?
The next change it's about a jam on pci's kref. This line has been deleted
on 2.6.21:
diff -rcNP linux-2.6.21/arch/powerpc/platforms/82xx/mpc82xx_ads.c
atlas_kernel/arch/powerpc/platforms/82xx/mpc82xx_ads.c
*** linux-2.6.21/arch/powerpc/platforms/82xx/mpc82xx_ads.c 2007-04-26
05:08:32.000000000 +0200
--- atlas_kernel/arch/powerpc/platforms/82xx/mpc82xx_ads.c 2008-04-24
08:43:51.000000000 +0200
***************
*** 533,539 ****
return;
}
pci_clk_frq = *(uint *) ptr;
- of_node_put(np);
bus_range = get_property(np, "bus-range", &len);
if (bus_range == NULL || len < 2 * sizeof(int)) {
printk(KERN_WARNING "Can't get bus-range for %s, assume"
I didn't find an equivalent operation on 2.6.35 because the code has been
changed completly. ¿Where it's included this operation about the bus?
Here there's a change of the macro CPM_BASE_ADDR :
diff -rcNP linux-2.6.21/arch/powerpc/platforms/82xx/pq2ads.h
atlas_kernel/arch/powerpc/platforms/82xx/pq2ads.h
*** linux-2.6.21/arch/powerpc/platforms/82xx/pq2ads.h 2007-04-26
05:08:32.000000000 +0200
--- atlas_kernel/arch/powerpc/platforms/82xx/pq2ads.h 2008-04-24
08:43:51.000000000 +0200
***************
*** 30,36 ****
#define CPUINFO_MACHINE "PQ2 ADS PowerPC"
/* Backword-compatibility stuff for the drivers */
! #define CPM_MAP_ADDR ((uint)0xf0000000)
#define CPM_IRQ_OFFSET 0
/* The ADS8260 has 16, 32-bit wide control/status registers, accessed
--- 30,36 ----
#define CPUINFO_MACHINE "PQ2 ADS PowerPC"
/* Backword-compatibility stuff for the drivers */
! #define CPM_MAP_ADDR ((uint)0xff000000) /*gonza*/
#define CPM_IRQ_OFFSET 0
It's seems that it has to be 0xff000000, but in 2.6.35 this symbol it's not
used anymore. ¿Where it's defined right now, or how I can handle this
address? I need it for the next part, that it's the hardest one to modify.
Here comes the hardest part at the file
arch/powerpc/platforms/82xx/mpc82xx_ads.c:
***************
*** 632,637 ****
--- 632,643 ----
while (1) ;
}
+ static void __init m82xx_map_io(void) /* gonza */
+ {
+ io_block_mapping(CPM_MAP_ADDR, CPM_MAP_ADDR, ((uint)(4 * 64 * 1024)),
_PAGE_IO);
+ }
+
+
define_machine(mpc82xx_ads)
{
.name = "MPC82xx ADS",
***************
*** 642,645 ****
--- 648,652 ----
.get_irq = cpm2_get_irq,
.calibrate_decr = m82xx_calibrate_decr,
.restart = m82xx_restart,.halt = m82xx_halt,
+ .setup_io_mappings = m82xx_map_io, /* gonza */
};
Here it's a modification that sets the base address for CPM with
io_block_mapping. I've seen in another discussion that io_block_mapping it's
became deprecated and it's out or kernel code. Does ioremap() function
became smarter and you can use it instead of io_block_mapping? I've found
some part of the code that I think do the same stuff, but it's not seems
working. Also, I've tried with setbat() changing the addresses for
0xff000000, but it doesn't work. Also, I've removed the original setbat line
and let only mine. So it doesn't work with the both lines or letting only
mine (being ioremap() or setbat()).
*** linux-2.6.35.7/arch/powerpc/sysdev/cpm_common.c 2010-09-29
03:09:08.000000000 +0200
--- linux-agrama/arch/powerpc/sysdev/cpm_common.c 2010-10-29
13:20:35.000000000 +0200
***************
*** 58,63 ****
--- 58,64 ----
if (cpm_udbg_txdesc) {
#ifdef CONFIG_CPM2
setbat(1, 0xf0000000, 0xf0000000, 1024*1024, PAGE_KERNEL_NCG);
+ ioremap(((uint)0xff000000UL),(uint)1024*64*4);
#endif
udbg_putc = udbg_putc_cpm;
}
I've seen that .setup_io_mappings was removed from kernel code. It has beed
called in version 2.6.21.7 from arch/powerpc/mm/init_32.c. It's has the same
effect make this operation at arch/powerpc/sysdev/cpm_common.c ? Which
operation should I do, ioremap(),setbat() or another one?
The last part of the modification it's about the serial port. At the version
2.6.21.7 you can choose where it's connected the serial port
(SCC1,SCC2,SCC3,SCC4,SMC1 or SMC2). Our serial port it's connected over
SMC1. We define it with the var SERIAL_CPM_SMC1 at menuconfig. At the
2.6.35.7 there's no option for do that. How should i do to force the serial
on SMC1? Also, there's a change when you init the serial port:
diff -rcNP linux-2.6.21/drivers/serial/cpm_uart/cpm_uart_cpm2.c
atlas_kernel/drivers/serial/cpm_uart/cpm_uart_cpm2.c
*** linux-2.6.21/drivers/serial/cpm_uart/cpm_uart_cpm2.c 2007-04-26
05:08:32.000000000 +0200
--- atlas_kernel/drivers/serial/cpm_uart/cpm_uart_cpm2.c 2008-04-24
08:43:52.000000000 +0200
***************
*** 95,105 ****
volatile iop_cpm2_t *io = cpm2_map(im_ioport);
volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
! /* SMC1 is only on port D */
! io->iop_ppard |= 0x00c00000;
! io->iop_pdird |= 0x00400000;
! io->iop_pdird &= ~0x00800000;
! io->iop_psord &= ~0x00c00000;
/* Wire BRG1 to SMC1 */
cpmux->cmx_smr &= 0x0f;
--- 95,105 ----
volatile iop_cpm2_t *io = cpm2_map(im_ioport);
volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
! /* gonza, se cambia ppard por pparc*/
! io->iop_pparc |= 0x0c000000;
! io->iop_pdirc |= 0x04000000;
! io->iop_pdirc &= ~0x08000000;
! io->iop_psorc &= ~0x0c000000;
/* Wire BRG1 to SMC1 */
cpmux->cmx_smr &= 0x0f;
The change consists on use port c instead of port d. Also, the values that
are written are multiplied of 0x10. In version 2.6.35.7 I've made the next
change that I believe that makes the same stuff:
diff -rc linux-2.6.35.7/arch/powerpc/platforms/82xx/mpc8272_ads.c
linux-agrama/arch/powerpc/platforms/82xx/mpc8272_ads.c
*** linux-2.6.35.7/arch/powerpc/platforms/82xx/mpc8272_ads.c 2010-09-29
03:09:08.000000000 +0200
--- linux-agrama/arch/powerpc/platforms/82xx/mpc8272_ads.c 2010-10-28
15:05:49.000000000 +0200
***************
*** 108,113 ****
--- 108,127 ----
{3, 23, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
{3, 24, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
{3, 25, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
+
+ #if 0 /* agrama */
+ /* En linux-2.6.21.7 (atlas):*/
+ /* gonza, se cambia ppard por pparc*/
+ io->iop_pparc |= 0x0c 00 00 00;
+ 1100
+ io->iop_pdirc |= 0x04000000;
+ io->iop_pdirc &= ~0x08000000;
+ io->iop_psorc &= ~0x0c000000;
+ #endif
+
+ /* SMC1 */ /* agrama */
+ {2, 26, (0*CPM_PIN_GPIO) | CPM_PIN_OUTPUT | CPM_PIN_SECONDARY}, /*
agrama */
+ {2, 27, (0*CPM_PIN_GPIO) | CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /*
agrama */
};
There's another modification in version 2.6.21.7 about Ethernet, but I
believe that doesn't affect to serial port.
diff -rcNP linux-2.6.21/arch/powerpc/sysdev/fsl_soc.c
atlas_kernel/arch/powerpc/sysdev/fsl_soc.c
*** linux-2.6.21/arch/powerpc/sysdev/fsl_soc.c 2007-04-26
05:08:32.000000000 +0200
--- atlas_kernel/arch/powerpc/sysdev/fsl_soc.c 2008-04-24
08:43:51.000000000 +0200
***************
*** 679,685 ****
fs_enet_data.rx_ring = 32;
fs_enet_data.tx_ring = 32;
fs_enet_data.rx_copybreak = 240;
! fs_enet_data.use_napi = 0;
fs_enet_data.napi_weight = 17;
fs_enet_data.mem_offset = FCC_MEM_OFFSET(fcc_index);
fs_enet_data.cp_page = CPM_CR_FCC_PAGE(fcc_index);
--- 680,686 ----
fs_enet_data.rx_ring = 32;
fs_enet_data.tx_ring = 32;
fs_enet_data.rx_copybreak = 240;
! fs_enet_data.use_napi = 1;
fs_enet_data.napi_weight = 17;
fs_enet_data.mem_offset = FCC_MEM_OFFSET(fcc_index);
fs_enet_data.cp_page = CPM_CR_FCC_PAGE(fcc_index);
***************
*** 713,731 ****
fs_enet_mdio_bb_data.delay =
mdio_bb_prop[5];
fs_enet_mdio_bb_data.irq[0] = phy_irq[0];
fs_enet_mdio_bb_data.irq[1] = -1;
fs_enet_mdio_bb_data.irq[2] = -1;
fs_enet_mdio_bb_data.irq[3] = phy_irq[0];
fs_enet_mdio_bb_data.irq[31] = -1;
fs_enet_mdio_bb_data.mdio_dat.offset =
(u32)&cpm2_immr->im_ioport.iop_pdatc;
fs_enet_mdio_bb_data.mdio_dir.offset =
(u32)&cpm2_immr->im_ioport.iop_pdirc;
fs_enet_mdio_bb_data.mdc_dat.offset =
(u32)&cpm2_immr->im_ioport.iop_pdatc;
!
ret = platform_device_add_data(
fs_enet_mdio_bb_dev,
&fs_enet_mdio_bb_data,
--- 714,747 ----
fs_enet_mdio_bb_data.delay =
mdio_bb_prop[5];
+ /*gonza: Creo que aqui se esta suponiendo que hay phy con direccion 0 y
3*/
+ /*igual que en mii-bitbang.c*/
fs_enet_mdio_bb_data.irq[0] = phy_irq[0];
fs_enet_mdio_bb_data.irq[1] = -1;
fs_enet_mdio_bb_data.irq[2] = -1;
fs_enet_mdio_bb_data.irq[3] = phy_irq[0];
fs_enet_mdio_bb_data.irq[31] = -1;
+ /*gonza: uso los campos mdio_port y mdc_port que son
0=PORTA..3=PORTD*/
+ offset_port_port = (u32)&cpm2_immr->im_ioport.iop_pdirb -
(u32)&cpm2_immr->im_ioport.iop_pdira;
+
+ fs_enet_mdio_bb_data.mdio_dat.offset =
+ (u32)&cpm2_immr->im_ioport.iop_pdata +
+ (offset_port_port * fs_enet_mdio_bb_data.mdio_port);
+ fs_enet_mdio_bb_data.mdio_dir.offset =
+ (u32)&cpm2_immr->im_ioport.iop_pdira +
+ (offset_port_port * fs_enet_mdio_bb_data.mdio_port);
+ fs_enet_mdio_bb_data.mdc_dat.offset =
+ (u32)&cpm2_immr->im_ioport.iop_pdata +
+ (offset_port_port * fs_enet_mdio_bb_data.mdc_port);
+ #if 0
fs_enet_mdio_bb_data.mdio_dat.offset =
(u32)&cpm2_immr->im_ioport.iop_pdatc;
fs_enet_mdio_bb_data.mdio_dir.offset =
(u32)&cpm2_immr->im_ioport.iop_pdirc;
fs_enet_mdio_bb_data.mdc_dat.offset =
(u32)&cpm2_immr->im_ioport.iop_pdatc;
! #endif
ret = platform_device_add_data(
fs_enet_mdio_bb_dev,
&fs_enet_mdio_bb_data,
***************
*** 733,739 ****
if (ret)
goto unreg;
}
!
of_node_put(phy);
of_node_put(mdio);
--- 749,755 ----
if (ret)
goto unreg;
}
!
of_node_put(phy);
of_node_put(mdio);
***************
*** 754,759 ****
--- 770,777 ----
arch_initcall(fs_enet_of_init);
+ #if 0 /* gonza */
+
static const char scc_regs[] = "regs";
static const char scc_pram[] = "pram";
***************
*** 828,833 ****
--- 846,853 ----
}
arch_initcall(cpm_uart_of_init);
+ #endif
+
#endif /* CONFIG_CPM2 */
#ifdef CONFIG_8xx
***************
*** 1022,1027 ****
--- 1042,1050 ----
arch_initcall(fs_enet_of_init);
+ #endif /* CONFIG_8xx */
+
+ #if defined(CONFIG_CPM2) || defined(CONFIG_8xx)
static const char *smc_regs = "regs";
static const char *smc_pram = "pram";
***************
*** 1096,1099 ****
arch_initcall(cpm_smc_uart_of_init);
! #endif /* CONFIG_8xx */
--- 1119,1122 ----
arch_initcall(cpm_smc_uart_of_init);
! #endif /* CONFIG_CPM2 || CONFIG_8xx */
So, the questions are the next:
- linux-2.6.21/arch/powerpc/mm/init_32.c
linux-2.6.35.7/arch/powerpc/mm/pgtable_32.h
- It's ok what I'm doing changing here KVIRT_TOP?
- ioremap_base = ioremap_bot at linux-2.6.35.7/arch/powerpc/mm/init_32.c?
- linux-2.6.21/arch/powerpc/platforms/82xx/pq2ads.h
- Where and how can I define CMP_MAP_ADDR, that all the controllers can
use it?
- Changing the CMP_MAP_ADDR in 2.6.21.7 involves that I should use a
configuration for 2.6.35 based on PQ2ADS?
-linux-2.6.35.7/arch/powerpc/platforms/82xx/mpc8272_ads.c
- How shall I the same stuff asociated to the operation
.setup_io_mappings, that uses block_io_mapping?
-linux-2.6.35.7/drivers/serial/cpm_uart/cpm_uart_cpm2.c
- How shall I force the uart driver to work on SMC1?
- What shall I change to make the same operation at recognizing the uart,
(I mean, asingn control sequences to iop_pparc,iop_pdirc and iop_psorc), in
the new "style" of kernel architecture?
-linux-2.6.21/arch/powerpc/sysdev/fsl_soc.c
-This code it's necesary for making the UART works properly?
I really appreciate the work that you're doing adding features to the new
kernel, but it's very obscure for me to make the changes that I need, so
I'll apreciate very much your help with my issue. Also I think that it's a
very good way to show to the begginers (as me) how to make the proper
changes with the new style of the code.
King regards,
Alexandru
[-- Attachment #2: Type: text/html, Size: 18130 bytes --]
^ permalink raw reply
* [PATCH 7/7] kgdb,ppc: Individual register get/set for ppc
From: Jason Wessel @ 2010-10-29 18:43 UTC (permalink / raw)
To: torvalds
Cc: kgdb-bugreport, linuxppc-dev, Dongdong Deng, linux-kernel,
Jason Wessel
In-Reply-To: <1288377821-24520-1-git-send-email-jason.wessel@windriver.com>
From: Dongdong Deng <dongdong.deng@windriver.com>
commit 534af1082329392bc29f6badf815e69ae2ae0f4c(kgdb,kdb: individual
register set and and get API) introduce dbg_get_reg/dbg_set_reg API
for individual register get and set.
This patch implement those APIs for ppc.
Signed-off-by: Dongdong Deng <dongdong.deng@windriver.com>
Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
CC: linuxppc-dev@lists.ozlabs.org
---
arch/powerpc/include/asm/kgdb.h | 1 +
arch/powerpc/kernel/kgdb.c | 188 ++++++++++++++++++++++++++-------------
2 files changed, 126 insertions(+), 63 deletions(-)
diff --git a/arch/powerpc/include/asm/kgdb.h b/arch/powerpc/include/asm/kgdb.h
index edd2170..9db24e7 100644
--- a/arch/powerpc/include/asm/kgdb.h
+++ b/arch/powerpc/include/asm/kgdb.h
@@ -31,6 +31,7 @@ static inline void arch_kgdb_breakpoint(void)
asm(".long 0x7d821008"); /* twge r2, r2 */
}
#define CACHE_FLUSH_IS_SAFE 1
+#define DBG_MAX_REG_NUM 70
/* The number bytes of registers we have to save depends on a few
* things. For 64bit we default to not including vector registers and
diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c
index 7f61a3a..7a9db64 100644
--- a/arch/powerpc/kernel/kgdb.c
+++ b/arch/powerpc/kernel/kgdb.c
@@ -194,40 +194,6 @@ static int kgdb_dabr_match(struct pt_regs *regs)
ptr = (unsigned long *)ptr32; \
} while (0)
-
-void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
-{
- unsigned long *ptr = gdb_regs;
- int reg;
-
- memset(gdb_regs, 0, NUMREGBYTES);
-
- for (reg = 0; reg < 32; reg++)
- PACK64(ptr, regs->gpr[reg]);
-
-#ifdef CONFIG_FSL_BOOKE
-#ifdef CONFIG_SPE
- for (reg = 0; reg < 32; reg++)
- PACK64(ptr, current->thread.evr[reg]);
-#else
- ptr += 32;
-#endif
-#else
- /* fp registers not used by kernel, leave zero */
- ptr += 32 * 8 / sizeof(long);
-#endif
-
- PACK64(ptr, regs->nip);
- PACK64(ptr, regs->msr);
- PACK32(ptr, regs->ccr);
- PACK64(ptr, regs->link);
- PACK64(ptr, regs->ctr);
- PACK32(ptr, regs->xer);
-
- BUG_ON((unsigned long)ptr >
- (unsigned long)(((void *)gdb_regs) + NUMREGBYTES));
-}
-
void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
{
struct pt_regs *regs = (struct pt_regs *)(p->thread.ksp +
@@ -271,44 +237,140 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
(unsigned long)(((void *)gdb_regs) + NUMREGBYTES));
}
-#define UNPACK64(dest, ptr) do { dest = *(ptr++); } while (0)
+#define GDB_SIZEOF_REG sizeof(unsigned long)
+#define GDB_SIZEOF_REG_U32 sizeof(u32)
-#define UNPACK32(dest, ptr) do { \
- u32 *ptr32; \
- ptr32 = (u32 *)ptr; \
- dest = *(ptr32++); \
- ptr = (unsigned long *)ptr32; \
- } while (0)
+#ifdef CONFIG_FSL_BOOKE
+#define GDB_SIZEOF_FLOAT_REG sizeof(unsigned long)
+#else
+#define GDB_SIZEOF_FLOAT_REG sizeof(u64)
+#endif
-void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
+struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] =
{
- unsigned long *ptr = gdb_regs;
- int reg;
-
- for (reg = 0; reg < 32; reg++)
- UNPACK64(regs->gpr[reg], ptr);
+ { "r0", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[0]) },
+ { "r1", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[1]) },
+ { "r2", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[2]) },
+ { "r3", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[3]) },
+ { "r4", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[4]) },
+ { "r5", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[5]) },
+ { "r6", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[6]) },
+ { "r7", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[7]) },
+ { "r8", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[8]) },
+ { "r9", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[9]) },
+ { "r10", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[10]) },
+ { "r11", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[11]) },
+ { "r12", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[12]) },
+ { "r13", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[13]) },
+ { "r14", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[14]) },
+ { "r15", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[15]) },
+ { "r16", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[16]) },
+ { "r17", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[17]) },
+ { "r18", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[18]) },
+ { "r19", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[19]) },
+ { "r20", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[20]) },
+ { "r21", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[21]) },
+ { "r22", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[22]) },
+ { "r23", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[23]) },
+ { "r24", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[24]) },
+ { "r25", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[25]) },
+ { "r26", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[26]) },
+ { "r27", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[27]) },
+ { "r28", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[28]) },
+ { "r29", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[29]) },
+ { "r30", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[30]) },
+ { "r31", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[31]) },
+
+ { "f0", GDB_SIZEOF_FLOAT_REG, 0 },
+ { "f1", GDB_SIZEOF_FLOAT_REG, 1 },
+ { "f2", GDB_SIZEOF_FLOAT_REG, 2 },
+ { "f3", GDB_SIZEOF_FLOAT_REG, 3 },
+ { "f4", GDB_SIZEOF_FLOAT_REG, 4 },
+ { "f5", GDB_SIZEOF_FLOAT_REG, 5 },
+ { "f6", GDB_SIZEOF_FLOAT_REG, 6 },
+ { "f7", GDB_SIZEOF_FLOAT_REG, 7 },
+ { "f8", GDB_SIZEOF_FLOAT_REG, 8 },
+ { "f9", GDB_SIZEOF_FLOAT_REG, 9 },
+ { "f10", GDB_SIZEOF_FLOAT_REG, 10 },
+ { "f11", GDB_SIZEOF_FLOAT_REG, 11 },
+ { "f12", GDB_SIZEOF_FLOAT_REG, 12 },
+ { "f13", GDB_SIZEOF_FLOAT_REG, 13 },
+ { "f14", GDB_SIZEOF_FLOAT_REG, 14 },
+ { "f15", GDB_SIZEOF_FLOAT_REG, 15 },
+ { "f16", GDB_SIZEOF_FLOAT_REG, 16 },
+ { "f17", GDB_SIZEOF_FLOAT_REG, 17 },
+ { "f18", GDB_SIZEOF_FLOAT_REG, 18 },
+ { "f19", GDB_SIZEOF_FLOAT_REG, 19 },
+ { "f20", GDB_SIZEOF_FLOAT_REG, 20 },
+ { "f21", GDB_SIZEOF_FLOAT_REG, 21 },
+ { "f22", GDB_SIZEOF_FLOAT_REG, 22 },
+ { "f23", GDB_SIZEOF_FLOAT_REG, 23 },
+ { "f24", GDB_SIZEOF_FLOAT_REG, 24 },
+ { "f25", GDB_SIZEOF_FLOAT_REG, 25 },
+ { "f26", GDB_SIZEOF_FLOAT_REG, 26 },
+ { "f27", GDB_SIZEOF_FLOAT_REG, 27 },
+ { "f28", GDB_SIZEOF_FLOAT_REG, 28 },
+ { "f29", GDB_SIZEOF_FLOAT_REG, 29 },
+ { "f30", GDB_SIZEOF_FLOAT_REG, 30 },
+ { "f31", GDB_SIZEOF_FLOAT_REG, 31 },
+
+ { "pc", GDB_SIZEOF_REG, offsetof(struct pt_regs, nip) },
+ { "msr", GDB_SIZEOF_REG, offsetof(struct pt_regs, msr) },
+ { "cr", GDB_SIZEOF_REG_U32, offsetof(struct pt_regs, ccr) },
+ { "lr", GDB_SIZEOF_REG, offsetof(struct pt_regs, link) },
+ { "ctr", GDB_SIZEOF_REG_U32, offsetof(struct pt_regs, ctr) },
+ { "xer", GDB_SIZEOF_REG, offsetof(struct pt_regs, xer) },
+};
-#ifdef CONFIG_FSL_BOOKE
-#ifdef CONFIG_SPE
- for (reg = 0; reg < 32; reg++)
- UNPACK64(current->thread.evr[reg], ptr);
+char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs)
+{
+ if (regno >= DBG_MAX_REG_NUM || regno < 0)
+ return NULL;
+
+ if (regno < 32 || regno >= 64)
+ /* First 0 -> 31 gpr registers*/
+ /* pc, msr, ls... registers 64 -> 69 */
+ memcpy(mem, (void *)regs + dbg_reg_def[regno].offset,
+ dbg_reg_def[regno].size);
+
+ if (regno >= 32 && regno < 64) {
+ /* FP registers 32 -> 63 */
+#if defined(CONFIG_FSL_BOOKE) && defined(CONFIG_SPE)
+ if (current)
+ memcpy(mem, current->thread.evr[regno-32],
+ dbg_reg_def[regno].size);
#else
- ptr += 32;
+ /* fp registers not used by kernel, leave zero */
+ memset(mem, 0, dbg_reg_def[regno].size);
#endif
+ }
+
+ return dbg_reg_def[regno].name;
+}
+
+int dbg_set_reg(int regno, void *mem, struct pt_regs *regs)
+{
+ if (regno >= DBG_MAX_REG_NUM || regno < 0)
+ return -EINVAL;
+
+ if (regno < 32 || regno >= 64)
+ /* First 0 -> 31 gpr registers*/
+ /* pc, msr, ls... registers 64 -> 69 */
+ memcpy((void *)regs + dbg_reg_def[regno].offset, mem,
+ dbg_reg_def[regno].size);
+
+ if (regno >= 32 && regno < 64) {
+ /* FP registers 32 -> 63 */
+#if defined(CONFIG_FSL_BOOKE) && defined(CONFIG_SPE)
+ memcpy(current->thread.evr[regno-32], mem,
+ dbg_reg_def[regno].size);
#else
- /* fp registers not used by kernel, leave zero */
- ptr += 32 * 8 / sizeof(int);
+ /* fp registers not used by kernel, leave zero */
+ return 0;
#endif
+ }
- UNPACK64(regs->nip, ptr);
- UNPACK64(regs->msr, ptr);
- UNPACK32(regs->ccr, ptr);
- UNPACK64(regs->link, ptr);
- UNPACK64(regs->ctr, ptr);
- UNPACK32(regs->xer, ptr);
-
- BUG_ON((unsigned long)ptr >
- (unsigned long)(((void *)gdb_regs) + NUMREGBYTES));
+ return 0;
}
void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
--
1.6.3.3
^ permalink raw reply related
* Re: RapidIO: MC Exception when enumerating peer to peer connection
From: Thomas Taranowski @ 2010-10-29 20:11 UTC (permalink / raw)
To: Micha Nelissen; +Cc: linuxppc-dev
In-Reply-To: <4CCA9207.8050506@neli.hopto.org>
Yes, I tried pretty much all combinations of boot order, but I believe
the preferred approach is to boot the agents first, then the host
according to my freescale documentation. My problem was that all
three devices had the same device id. Once I programmed them with
different device id's via the alternate device id register I could
finally get doorbell messages across with the jtag.
Thanks
On Fri, Oct 29, 2010 at 2:21 AM, Micha Nelissen <micha@neli.hopto.org> wrote:
> Thomas Taranowski wrote:
>>
>> use my trusty jtag to issue a Port Link Maintenance Request and
>> request status, I get back unrecoverable ackID error for port 1, and
>> error-stopped port_status for port 2.
>
> Did you try rebooting all devices together?
>
> Micha
>
^ permalink raw reply
* Support for multiple port's
From: Thomas Taranowski @ 2010-10-29 23:09 UTC (permalink / raw)
To: linuxppc-dev
Going through the code, it looks like the rapidio driver assumes
there's only going to be a single Port implemented.
Snapshot of code assumes a single port atmu configuration block, which
is wrong for the p2020, and probably other QorIQ processors.
<snip>
priv->atmu_regs = (struct rio_atmu_regs *)(priv->regs_win
+ RIO_ATMU_REGS_OFFSET);
priv->maint_atmu_regs = priv->atmu_regs + 1;
priv->dbell_atmu_regs = priv->atmu_regs + 2;
priv->msg_regs = (struct rio_msg_regs *)(priv->regs_win +
((port->phy_type == RIO_PHY_SERIAL) ?
RIO_S_MSG_REGS_OFFSET : RIO_P_MSG_REGS_OFFSET));
<snip>
On the newer QorIQ P2020 processors there are 2 sets of port
registers, so the current code lays the dbell_atmu_regs structure on
top of the second set of atmu_regs. There are probably other issues
as well.
Are there any patch sets available that support the newer processors,
and multi-port ( multi-homed? ) RapidIO configurations?
Thanks!
^ permalink raw reply
* [PATCH] powerpc: kvm: fix information leak to userland
From: Vasiliy Kulikov @ 2010-10-30 9:04 UTC (permalink / raw)
To: kernel-janitors
Cc: kvm, Marcelo Tosatti, Alexander Graf, kvm-ppc, linux-kernel,
Paul Mackerras, Avi Kivity, linuxppc-dev
Structure kvm_ppc_pvinfo is copied to userland with flags and
pad fields unitialized. It leads to leaking of contents of
kernel stack memory.
Signed-off-by: Vasiliy Kulikov <segooon@gmail.com>
---
I cannot compile this driver, so it is not tested at all.
arch/powerpc/kvm/powerpc.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 2f87a16..38f756f 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -617,6 +617,7 @@ long kvm_arch_vm_ioctl(struct file *filp,
switch (ioctl) {
case KVM_PPC_GET_PVINFO: {
struct kvm_ppc_pvinfo pvinfo;
+ memset(&pvinfo, 0, sizeof(pvinfo));
r = kvm_vm_ioctl_get_pvinfo(&pvinfo);
if (copy_to_user(argp, &pvinfo, sizeof(pvinfo))) {
r = -EFAULT;
--
1.7.0.4
^ permalink raw reply related
* [MPC8xx] Initial MMU too low
From: LEROY christophe @ 2010-10-30 11:52 UTC (permalink / raw)
To: linuxppc-dev
Hello,
When I build a kernel with DEBUG_LOCK_ALLOC set, I get a kernel which
has __bss_stop above the C0800000 limit, and then I get a bad page
exception during the zeroize of the __bss at startup, because the
initial MMU only maps the first 8Mbytes.
What can I do to fix that ?
Regards
C. Leroy
^ permalink raw reply
* [PATCH] iSeries: Don't leak if allocations fail in mf_getSrcHistory
From: Jesper Juhl @ 2010-10-30 17:20 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras, linux-kernel
Hi,
If memory is tight and a dynamic allocation fails there's no reason to
make a bad situation worse by leaking memory.
mf_getSrcHistory potentially leaks pages[0-3]. I believe the right thing
to do is to free that memory again before returning -ENOMEM - which is
what this patch does.
I realize that the function is under '#if 0' so this probably doesn't
matter much, but I assume that the function is still there for a reason
(but I could be wrong, I don't know the powerpc code).
Anyway, I suggest we remove the leak.
Please keep me on CC when replying.
Signed-off-by: Jesper Juhl <jj@chaosbits.net>
---
mf.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c
index 42d0a88..f67522a 100644
--- a/arch/powerpc/platforms/iseries/mf.c
+++ b/arch/powerpc/platforms/iseries/mf.c
@@ -1058,8 +1058,13 @@ static void mf_getSrcHistory(char *buffer, int size)
pages[2] = kmalloc(4096, GFP_ATOMIC);
pages[3] = kmalloc(4096, GFP_ATOMIC);
if ((ev == NULL) || (pages[0] == NULL) || (pages[1] == NULL)
- || (pages[2] == NULL) || (pages[3] == NULL))
+ || (pages[2] == NULL) || (pages[3] == NULL)) {
+ kfree(pages[3]);
+ kfree(pages[2]);
+ kfree(pages[1]);
+ kfree(pages[0]);
return -ENOMEM;
+ }
return_stuff.xType = 0;
return_stuff.xRc = 0;
--
Jesper Juhl <jj@chaosbits.net> http://www.chaosbits.net/
Plain text mails only, please http://www.expita.com/nomime.html
Don't top-post http://www.catb.org/~esr/jargon/html/T/top-post.html
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox