LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH 2/2] powerpc: create mpc85xx pci err platform device for EDAC
From: Dave Jiang @ 2008-02-13 21:41 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <27AAC964-D9EE-435A-84FD-8A45FF27D448@kernel.crashing.org>

Kumar Gala wrote:
> On Feb 11, 2008, at 2:34 PM, Dave Jiang wrote:
> 
>> Creating a platform device for the PCI error registers in order for  
>> the
>> mpc85xx EDAC driver to pick up proper resources. This is to prevent  
>> the
>> EDAC driver from monopolizing the of_device and thus preventing  
>> future PCI
>> code from using the PCI of_device(s).
>>
>> Signed-off-by: Dave Jiang <djiang@mvista.com>
> 
> I'd rather we didn't add new platform devices, but do this via  
> of_platform in the driver itself.

Kumar,
  Here's the thread of discussion between Arnd Bergmann and I why platform
device is used. The original patch was of_device based....

http://ozlabs.org/pipermail/linuxppc-dev/2007-July/thread.html

Does it still make sense or do I need to go back to of_device?

> 
> Also, we need to 'rename' the compatible field for some of these  
> devices.
> 
> - k
> 


-- 

------------------------------------------------------
Dave Jiang
Software Engineer
MontaVista Software, Inc.
http://www.mvista.com
------------------------------------------------------

^ permalink raw reply

* [2.6 patch] powerpc: free_property() mustn't be __init
From: Adrian Bunk @ 2008-02-13 21:30 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev, linux-kernel, Stephen Rothwell

This patch fixes the following section mismatch:

<--  snip  -->

...
WARNING: vmlinux.o(.text+0x55648): Section mismatch in reference from the function .free_node() to the function .init.text:.free_property()
...

<--  snip  -->

Signed-off-by: Adrian Bunk <bunk@kernel.org>
Acked-by: Stephen Rothwell <sfr@canb.auug.org.au>

---

This patch has been sent on:
- 30 Jan 2008

99e9b48d8f5aba059916540fc69815db2b60b08d 
diff --git a/arch/powerpc/platforms/iseries/vio.c b/arch/powerpc/platforms/iseries/vio.c
index be06cfd..657b72f 100644
--- a/arch/powerpc/platforms/iseries/vio.c
+++ b/arch/powerpc/platforms/iseries/vio.c
@@ -75,7 +75,7 @@ static struct property *new_property(const char *name, int length,
 	return np;
 }
 
-static void __init free_property(struct property *np)
+static void free_property(struct property *np)
 {
 	kfree(np);
 }

^ permalink raw reply related

* [2.6 patch] hvc_rtas_init() must be __init
From: Adrian Bunk @ 2008-02-13 21:30 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev, linux-kernel

This patch fixes the following section mismatch:

<--  snip  -->

...
WARNING: vmlinux.o(.text+0x2fbca8): Section mismatch in reference from the function .hvc_rtas_init() to the function .devinit.text:.hvc_alloc()
...

<--  snip  -->

Signed-off-by: Adrian Bunk <bunk@kernel.org>

---

This patch has been sent on:
- 30 Jan 2008

1cc00c4ad5c881db2fc256ced43f3b5ce5c76e1c 
diff --git a/drivers/char/hvc_rtas.c b/drivers/char/hvc_rtas.c
index bb09413..88590d0 100644
--- a/drivers/char/hvc_rtas.c
+++ b/drivers/char/hvc_rtas.c
@@ -76,7 +76,7 @@ static struct hv_ops hvc_rtas_get_put_ops = {
 	.put_chars = hvc_rtas_write_console,
 };
 
-static int hvc_rtas_init(void)
+static int __init hvc_rtas_init(void)
 {
 	struct hvc_struct *hp;
 

^ permalink raw reply related

* [2.6 patch] powerpc: vdso_do_func_patch{32,64}() must be __init
From: Adrian Bunk @ 2008-02-13 21:30 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev, linux-kernel

This patch fixes the following section mismatches:

<--  snip  -->

...
WARNING: vmlinux.o(.text+0xe49c): Section mismatch in reference from the function .vdso_do_func_patch64() to the function .init.text:.find_symbol64()
WARNING: vmlinux.o(.text+0xe4d0): Section mismatch in reference from the function .vdso_do_func_patch64() to the function .init.text:.find_symbol64()
WARNING: vmlinux.o(.text+0xe56c): Section mismatch in reference from the function .vdso_do_func_patch32() to the function .init.text:.find_symbol32()
WARNING: vmlinux.o(.text+0xe5a0): Section mismatch in reference from the function .vdso_do_func_patch32() to the function .init.text:.find_symbol32()
...

<--  snip  -->

Signed-off-by: Adrian Bunk <bunk@kernel.org>

---

This patch has been sent on:
- 30 Jan 2008

 arch/powerpc/kernel/vdso.c |   12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

1c52ed2049b82e8458d03e50633b01ac5e1dfa40 
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index 3702df7..d3437c4 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -336,9 +336,9 @@ static unsigned long __init find_function32(struct lib32_elfinfo *lib,
 	return sym->st_value - VDSO32_LBASE;
 }
 
-static int vdso_do_func_patch32(struct lib32_elfinfo *v32,
-				struct lib64_elfinfo *v64,
-				const char *orig, const char *fix)
+static int __init vdso_do_func_patch32(struct lib32_elfinfo *v32,
+				       struct lib64_elfinfo *v64,
+				       const char *orig, const char *fix)
 {
 	Elf32_Sym *sym32_gen, *sym32_fix;
 
@@ -433,9 +433,9 @@ static unsigned long __init find_function64(struct lib64_elfinfo *lib,
 #endif
 }
 
-static int vdso_do_func_patch64(struct lib32_elfinfo *v32,
-				struct lib64_elfinfo *v64,
-				const char *orig, const char *fix)
+static int __init vdso_do_func_patch64(struct lib32_elfinfo *v32,
+				       struct lib64_elfinfo *v64,
+				       const char *orig, const char *fix)
 {
 	Elf64_Sym *sym64_gen, *sym64_fix;
 

^ permalink raw reply related

* [PATCH] [POWERPC] Enable correct operation of serial ports with nonzero regshift.
From: Pavel Kiryukhin @ 2008-02-13 21:19 UTC (permalink / raw)
  To: linuxppc-dev

Add regshift reading to serial drivers.
This enables correct operation of serial ports with nonzero regshift.

Signed-off-by: Pavel Kiryukhin <pkiryukhin@ru.mvista.com>
---
 arch/powerpc/kernel/legacy_serial.c |    6 +++++-
 drivers/serial/of_serial.c          |    6 ++++--
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c
index 61dd174..74bd1f3 100644
--- a/arch/powerpc/kernel/legacy_serial.c
+++ b/arch/powerpc/kernel/legacy_serial.c
@@ -50,7 +50,7 @@ static int __init add_legacy_port(struct device_node *np, int want_index,
 				  phys_addr_t taddr, unsigned long irq,
 				  upf_t flags, int irq_check_parent)
 {
-	const u32 *clk, *spd;
+	const u32 *clk, *spd, *regshift;
 	u32 clock = BASE_BAUD * 16;
 	int index;
 
@@ -62,6 +62,9 @@ static int __init add_legacy_port(struct device_node *np, int want_index,
 	/* get default speed if present */
 	spd = of_get_property(np, "current-speed", NULL);
 
+	/* get regshift if present*/
+	regshift = get_property(np, "reg-shift", NULL);
+
 	/* If we have a location index, then try to use it */
 	if (want_index >= 0 && want_index < MAX_LEGACY_SERIAL_PORTS)
 		index = want_index;
@@ -104,6 +107,7 @@ static int __init add_legacy_port(struct device_node *np, int want_index,
 	legacy_serial_ports[index].uartclk = clock;
 	legacy_serial_ports[index].irq = irq;
 	legacy_serial_ports[index].flags = flags;
+	legacy_serial_ports[index].regshift = regshift ? (u8)*regshift : 0;
 	legacy_serial_infos[index].taddr = taddr;
 	legacy_serial_infos[index].np = of_node_get(np);
 	legacy_serial_infos[index].clock = clock;
diff --git a/drivers/serial/of_serial.c b/drivers/serial/of_serial.c
index a64d858..ea9f1e4 100644
--- a/drivers/serial/of_serial.c
+++ b/drivers/serial/of_serial.c
@@ -30,7 +30,7 @@ static int __devinit of_platform_serial_setup(struct of_device *ofdev,
 {
 	struct resource resource;
 	struct device_node *np = ofdev->node;
-	const unsigned int *clk, *spd;
+	const unsigned int *clk, *spd, *regshift;
 	int ret;
 
 	memset(port, 0, sizeof *port);
@@ -40,7 +40,7 @@ static int __devinit of_platform_serial_setup(struct of_device *ofdev,
 		dev_warn(&ofdev->dev, "no clock-frequency property set\n");
 		return -ENODEV;
 	}
-
+	regshift = get_property(np, "reg-shift", NULL);
 	ret = of_address_to_resource(np, 0, &resource);
 	if (ret) {
 		dev_warn(&ofdev->dev, "invalid address\n");
@@ -57,6 +57,8 @@ static int __devinit of_platform_serial_setup(struct of_device *ofdev,
 		| UPF_FIXED_PORT;
 	port->dev = &ofdev->dev;
 	port->custom_divisor = *clk / (16 * (*spd));
+	if (regshift)
+		port->regshift = *regshift;
 
 	return 0;
 }
-- 
1.5.4.1

^ permalink raw reply related

* [PATCH 1/2 rev2] powerpc: publish 85xx cds soc dts entries as of_device
From: Dave Jiang @ 2008-02-13 21:08 UTC (permalink / raw)
  To: galak, linuxppc-dev
In-Reply-To: <20080211203243.GA5331@blade.az.mvista.com>

Publish the devices listed in dts under SOC as of_device for mpc85xx_cds
platforms.

The memory controller, L2 cache-controller, and the PCI controller(s) are
published as of_device so the mpc85xx EDAC driver can claim them for usage.

Signed-off-by: Dave Jiang <djiang@mvista.com>

---
commit 4be72413410c560fe7ad5ef9156d43159003dad3
tree 8890093ee1cff0ec0cc9ce0b9367e134f528eed2
parent 19af35546de68c872dcb687613e0902a602cb20e
author Dave Jiang <djiang@mvista.com> Wed, 13 Feb 2008 14:03:33 -0700
committer Dave Jiang <djiang@blade.(none)> Wed, 13 Feb 2008 14:03:33 -0700

 arch/powerpc/platforms/85xx/mpc85xx_cds.c |   14 ++++++++++++++
 1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
index 8b1de78..374c9d5 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
@@ -26,6 +26,7 @@
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/fsl_devices.h>
+#include <linux/of_platform.h>
 
 #include <asm/system.h>
 #include <asm/pgtable.h>
@@ -324,6 +325,19 @@ static void mpc85xx_cds_show_cpuinfo(struct seq_file *m)
 	seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
 }
 
+static struct of_device_id __initdata of_bus_ids[] = {
+	{ .name = "soc", },
+	{ .type = "soc", },
+	{},
+};
+
+static int __init declare_of_platform_devices(void)
+{
+	of_platform_bus_probe(NULL, of_bus_ids, NULL);
+
+	return 0;
+}
+machine_device_initcall(mpc85xx_cds, declare_of_platform_devices);
 
 /*
  * Called very early, device-tree isn't unflattened

^ permalink raw reply related

* RE: V4 FX12 and PLB TEMAC: no space for user logic?
From: Mohammad Sadegh Sadri @ 2008-02-13 21:00 UTC (permalink / raw)
  To: llandre; +Cc: linuxppc-embedded
In-Reply-To: <47B2B94A.6090600@dave-tech.it>

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


llandre,

Our tests show that V4 FX 12 is really a small device. The FPGA was completely full with these set of modules:

1- CPU core and related circuits, 2- PLB TEMAC , 3- DDR SDRAM Controller , 4- PLB BRAM IF , 5- Bridges , 6- OPB UART and 7- OPB EMC controller (Used for interfacing to flash chips )

The synthesis tool we used during our tests was : XST
it seems that there are some solutions to have a more optimized implementation on FX-12, personally i visited one of the members here who claimed that he has two PLB TEMACs enabled on one FX-12 FPGA. I believe that this is not possible. may be if one use better synthesis tools such as Synplify he may get slightly better results.

any how, in my idea FX-12 is not suitable for serious projects, it is suitable only for beginning phases of a project and the research phase. 
We are now focusing on ML410, a great board by Xiling, featuring on FX-60 FPGA while keeps costs low.

any questions are welcom,
thanks,
Mohammad.


> Date: Wed, 13 Feb 2008 10:32:58 +0100
> From: r&d2@dave-tech.it
> To: mamsadegh@hotmail.com
> CC: linuxppc-embedded@ozlabs.org
> Subject: V4 FX12 and PLB TEMAC: no space for user logic?
> 
> Hi Mohammad,
> 
> I've just had a look at the messages you generously posted in the ml 
> about your experience with linux on V4 FX12 FPGA.
> I'd like to ask your opinion about FX12 practical usability in this 
> context (gigabit PLB TEMAC/linux).
> In this message
> 
> http://article.gmane.org/gmane.linux.ports.ppc.embedded/16816
> 
> you say the device is completely full. If I understand correctly your 
> system provides just the devices required to run the bandwidth test so 
> it seems there is no room for user logic (I think you did not even add 
> the memory controller required to access the NOR Flash containing 
> bootloader, kernel image and root fs that is clearly mandatory for 
> standalone product). Is that true? If it is, this limits a lot the 
> flexibility of this architecture in this configuration. What do you think?
> 
> 
> 
> Regards,
> llandre
> 
> DAVE Electronics System House - R&D Department
> web:   http://www.dave.eu
> email: r&d2@dave-tech.it

_________________________________________________________________


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

^ permalink raw reply

* Re: [Patch 0/2] powerpc: avoid userspace poking to legacy ioports
From: Benjamin Herrenschmidt @ 2008-02-13 20:42 UTC (permalink / raw)
  To: Christian Krafft; +Cc: parabelboi, linuxppc-dev, linux-kernel
In-Reply-To: <20080213183506.7f3e3145@de.ibm.com>


On Wed, 2008-02-13 at 18:35 +0100, Christian Krafft wrote:
> sensors_detect crashes kernel on PowerPC, as it pokes directly to memory.
> This patch adds a check_legacy_ioports to read_port and write_port.
> It will now return ENXIO, instead of oopsing.
> 
> Signed-off-by: Christian Krafft <krafft@de.ibm.com>

The problem is that this prevents using /proc/ioports to access PCI
IO space, which might be useful.

I hate that sensors_detect.. or for that matter any other userland code
that pokes random ports like that. It should die.

Ben.

> Index: linux.git/drivers/char/mem.c
> ===================================================================
> --- linux.git.orig/drivers/char/mem.c
> +++ linux.git/drivers/char/mem.c
> @@ -566,8 +566,13 @@ static ssize_t read_port(struct file * f
>  	char __user *tmp = buf;
>  
>  	if (!access_ok(VERIFY_WRITE, buf, count))
> -		return -EFAULT; 
> +		return -EFAULT;
> +
>  	while (count-- > 0 && i < 65536) {
> +#ifdef CONFIG_PPC_MERGE
> +		if (check_legacy_ioport(i))
> +			return -ENXIO;
> +#endif
>  		if (__put_user(inb(i),tmp) < 0) 
>  			return -EFAULT;  
>  		i++;
> @@ -585,6 +590,7 @@ static ssize_t write_port(struct file * 
>  
>  	if (!access_ok(VERIFY_READ,buf,count))
>  		return -EFAULT;
> +
>  	while (count-- > 0 && i < 65536) {
>  		char c;
>  		if (__get_user(c, tmp)) {
> @@ -592,6 +598,10 @@ static ssize_t write_port(struct file * 
>  				break;
>  			return -EFAULT; 
>  		}
> +#ifdef CONFIG_PPC_MERGE
> +		if (check_legacy_ioport(i))
> +			return -ENXIO;
> +#endif
>  		outb(c,i);
>  		i++;
>  		tmp++;
> 
> 
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev

^ permalink raw reply

* Re: TLB Miss booting linux kernel on ppc 405
From: David Baird @ 2008-02-13 19:02 UTC (permalink / raw)
  To: linuxppc-embedded
In-Reply-To: <5ee408090802131049u652ef867wff034b4ccb1067f1@mail.gmail.com>

On Feb 13, 2008 11:49 AM, Ricardo Ayres Severo <severo.ricardo@gmail.com> wrote:
> Executing without single step the exception doesn't occurs. But at
> __log_buf I get only trash, even after reseting the processor.
> How can I send some characters to uartlite on asm code?

Great.  This confirms that I am not crazy.  You are having similar
results as I did.  But I still don't yet know why single-step and
memory read can't be used in virtual mode...

To use UARTLite, there are some patches you need.  First thing, you
have to setup your TLBs so that uartlite can be accessed in virtual
mode.  I did something like this:

#define MY_UART_LITE_BASE 0x40000000

 lis r3,MY_UART_LITE_BASE@h
 ori r3,r3,MY_UART_LITE_BASE@l
 mr  r4,r3
 clrrwi  r4,r4,12
 ori r4,r4,(TLB_WR|TLB_I|TLB_M|TLB_G)

 clrrwi  r3,r3,12
 ori r3,r3,(TLB_VALID | TLB_PAGESZ(PAGESZ_16M))

 li  r0,0      /* TLB slot 0 */
 tlbwe r4,r0,TLB_DATA
 tlbwe r3,r0,TLB_TAG

Then, you need to add some C code somewhere.  I chose "setup.c" (in
same directory as head_4xx.S) for this purpose:

// Try to get value for XPAR_RS232_UART_BASEADDR:
#include <platforms/4xx/xparameters/xparameters.h>
#include <platforms/4xx/xparameters/xparameters_ml403.h>

void
serial_putc(unsigned char c)
{
 while (((*(volatile uint32_t*)(XPAR_RS232_UART_BASEADDR + 0x8)) & 0x08) != 0);
 *(volatile uint32_t*)(XPAR_RS232_UART_BASEADDR + 0x4) = c;
}

void
print_A()
{
 serial_putc('A');
}

void
print_B()
{
 serial_putc('B');
}


Now, from assembly, things are easy.  Just do this, I think:

 blr print_A
 blr print_B

If this gives you any trouble, try it first from real mode so that you
can easily debug it.

-David

^ permalink raw reply

* Re: TLB Miss booting linux kernel on ppc 405
From: Ricardo Ayres Severo @ 2008-02-13 18:49 UTC (permalink / raw)
  To: David Baird; +Cc: linuxppc-embedded
In-Reply-To: <440abda90802131032l6e11eef7gbd7eb57352c2ce4@mail.gmail.com>

Executing without single step the exception doesn't occurs. But at
__log_buf I get only trash, even after reseting the processor.
How can I send some characters to uartlite on asm code?

Thanks,

On Feb 13, 2008 4:32 PM, David Baird <dhbaird@gmail.com> wrote:
> On Feb 13, 2008 11:03 AM, Ricardo Ayres Severo <severo.ricardo@gmail.com> wrote:
> > Here are the srr dump:
> >   srr0: c0002218
> >   srr1: 00021030
> >   srr2: 00001154
> >   srr3: 00000000
>
> Okay, SRR0 tells us that you did in fact have an exception at
> 0xc0002218.  And I am willing to bet that is the line you mentioned
> (line 826 of start_here).  You can match this up with your System.map
> or an objdump -d of vmlinux.
>
> Someone who knows more than I do can correct me on this, but I have a
> suspicion.  As soon virtual (translation) mode is entered, I have had
> a hard time using the normal debugging functions (e.g. single
> instruction stepping and reading memory regions).  While in virtual
> mode, it seemed like I had to resort to these techniques:
>
> - Blinking some LEDs
> - Spitting characters out of a uartlite
> - When an exception occurs, the processor switches back into real mode
> and therefore I can set breakpoints on the beginnings of various
> exception handlers and be able to use normal debugging tools again
>
> So, I have another question.  Can you set a breakpoint on 0x1100 (in
> XMD: bps 0x1100 hw), then just let it run (i.e. do not single step!)
> all the way until an exception happens.  When the exception happens,
> can you then paste the SRR0, SRR1, and the ESR (exception syndrome
> register)?
>
> I hope I am not giving you a run-around here....
>
> -David
>
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>



-- 
Ricardo Ayres Severo <severo.ricardo@gmail.com>

^ permalink raw reply

* Re: TLB Miss booting linux kernel on ppc 405
From: David Baird @ 2008-02-13 18:32 UTC (permalink / raw)
  To: linuxppc-embedded
In-Reply-To: <5ee408090802131003m4b8e632cu931769bc77f9b439@mail.gmail.com>

On Feb 13, 2008 11:03 AM, Ricardo Ayres Severo <severo.ricardo@gmail.com> wrote:
> Here are the srr dump:
>   srr0: c0002218
>   srr1: 00021030
>   srr2: 00001154
>   srr3: 00000000

Okay, SRR0 tells us that you did in fact have an exception at
0xc0002218.  And I am willing to bet that is the line you mentioned
(line 826 of start_here).  You can match this up with your System.map
or an objdump -d of vmlinux.

Someone who knows more than I do can correct me on this, but I have a
suspicion.  As soon virtual (translation) mode is entered, I have had
a hard time using the normal debugging functions (e.g. single
instruction stepping and reading memory regions).  While in virtual
mode, it seemed like I had to resort to these techniques:

- Blinking some LEDs
- Spitting characters out of a uartlite
- When an exception occurs, the processor switches back into real mode
and therefore I can set breakpoints on the beginnings of various
exception handlers and be able to use normal debugging tools again

So, I have another question.  Can you set a breakpoint on 0x1100 (in
XMD: bps 0x1100 hw), then just let it run (i.e. do not single step!)
all the way until an exception happens.  When the exception happens,
can you then paste the SRR0, SRR1, and the ESR (exception syndrome
register)?

I hope I am not giving you a run-around here....

-David

^ permalink raw reply

* Re: TLB Miss booting linux kernel on ppc 405
From: Ricardo Ayres Severo @ 2008-02-13 18:03 UTC (permalink / raw)
  Cc: linuxppc-embedded
In-Reply-To: <440abda90802130951h7a23743asc85454bf089c7e55@mail.gmail.com>

Here are the srr dump:
  srr0: c0002218
  srr1: 00021030
  srr2: 00001154
  srr3: 00000000

On Feb 13, 2008 3:51 PM, David Baird <dhbaird@gmail.com> wrote:
> On Feb 13, 2008 10:38 AM, Ricardo Ayres Severo <severo.ricardo@gmail.com> wrote:
> > I tracked the kernel execution using step one instruction (si) on gdb
> > and matching the jumps with the System.map.
> > It is a Data TLB Miss and this is the register dump after the miss occurs:
> >
> >     r1: 00502090
> >     r2: 0000000f
> >     r3: c00003c0
> >     r4: c0000000
> >     r5: 00000000
> >     r6: 00000000
> >     r7: 74747955
> >     r8: 4c302c39
> >     r9: 00000000
> >     pc: 00001100
> >     lr: 00000018
>
> Can you also past the special registers (srrd in XMD)?  I am very
> curious about SRR0 and SRR1 and maybe some of the others.
>
> > Now I'm checking the PPC cache configurations on XPS, because when
> > treating the DTLB Miss Exception a Machine Check Exception occurs when
> > it works with L1. Does this makes sense or am I confusing things?
>
> Too soon for me to tell :-)
>
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>



-- 
Ricardo Ayres Severo <severo.ricardo@gmail.com>

^ permalink raw reply

* Re: TLB Miss booting linux kernel on ppc 405
From: David Baird @ 2008-02-13 17:51 UTC (permalink / raw)
  To: linuxppc-embedded
In-Reply-To: <5ee408090802130938u7d069636g42a496e489fe5b80@mail.gmail.com>

On Feb 13, 2008 10:38 AM, Ricardo Ayres Severo <severo.ricardo@gmail.com> wrote:
> I tracked the kernel execution using step one instruction (si) on gdb
> and matching the jumps with the System.map.
> It is a Data TLB Miss and this is the register dump after the miss occurs:
>
>     r1: 00502090
>     r2: 0000000f
>     r3: c00003c0
>     r4: c0000000
>     r5: 00000000
>     r6: 00000000
>     r7: 74747955
>     r8: 4c302c39
>     r9: 00000000
>     pc: 00001100
>     lr: 00000018

Can you also past the special registers (srrd in XMD)?  I am very
curious about SRR0 and SRR1 and maybe some of the others.

> Now I'm checking the PPC cache configurations on XPS, because when
> treating the DTLB Miss Exception a Machine Check Exception occurs when
> it works with L1. Does this makes sense or am I confusing things?

Too soon for me to tell :-)

^ permalink raw reply

* Re: TLB Miss booting linux kernel on ppc 405
From: Ricardo Ayres Severo @ 2008-02-13 17:38 UTC (permalink / raw)
  To: David Baird; +Cc: linuxppc-embedded
In-Reply-To: <440abda90802130917x79c3c990j6a1fc7c12ba05ed7@mail.gmail.com>

I tracked the kernel execution using step one instruction (si) on gdb
and matching the jumps with the System.map.
It is a Data TLB Miss and this is the register dump after the miss occurs:

    r1: 00502090
    r2: 0000000f
    r3: c00003c0
    r4: c0000000
    r5: 00000000
    r6: 00000000
    r7: 74747955
    r8: 4c302c39
    r9: 00000000
    pc: 00001100
    lr: 00000018

Now I'm checking the PPC cache configurations on XPS, because when
treating the DTLB Miss Exception a Machine Check Exception occurs when
it works with L1. Does this makes sense or am I confusing things?

Thanks,

On Feb 13, 2008 3:17 PM, David Baird <dhbaird@gmail.com> wrote:
> On Feb 13, 2008 9:50 AM, Ricardo Ayres Severo <severo.ricardo@gmail.com> wrote:
> > Hi All,
> >
> > I'm using kernel 2.6.24 and when it comes to line 826 on the file
> > arch/ppc/kernel/head_4xx.S it gives a TLB Miss.
> >
> > arch/ppc/kernel/head_4xx.S
> > 823 start_here:
> > 824
> > 825         /* ptr to current */
> > 826         lis    r2,init_task@h
> > 827         ori    r2,r2,init_task@l
>
> I am just curious: how did you find that you have TLB miss on that
> line?  Is it an Instruction TLB miss or a Data TLB miss?
>
> Can you paste a dump of your registers (in XMD, rrd and srrd)?
>
> I was having TLB misses awhile back due to some other problems, but
> never had any on that line though.
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>



-- 
Ricardo Ayres Severo <severo.ricardo@gmail.com>

^ permalink raw reply

* Re: [Patch 2/2] powerpc: i2c-isa: add access check to legacy ioports
From: Christian Krafft @ 2008-02-13 17:37 UTC (permalink / raw)
  To: linux-kernel; +Cc: parabelboi, linuxppc-dev
In-Reply-To: <20080213182800.5c6940a8@de.ibm.com>

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

when probing i2c-pca-isa writes to legacy ioports, which crashes the kernel
if there is no device at that port.
This patch adds a check_legacy_ioport call, so probe failes gracefully
and thus prevents the oops.

Signed-off-by: Christian Krafft <krafft@de.ibm.com>

Index: linux.git/drivers/i2c/busses/i2c-pca-isa.c
===================================================================
--- linux.git.orig/drivers/i2c/busses/i2c-pca-isa.c
+++ linux.git/drivers/i2c/busses/i2c-pca-isa.c
@@ -125,6 +125,13 @@ static int __devinit pca_isa_probe(struc
 
 	dev_info(dev, "i/o base %#08lx. irq %d\n", base, irq);
 
+#ifdef CONFIG_PPC_MERGE
+	if (check_legacy_ioport(base)) {
+		dev_err(dev, "I/O address %#08lx is not available\n", base);
+		goto out;
+	}
+#endif
+
 	if (!request_region(base, IO_SIZE, "i2c-pca-isa")) {
 		dev_err(dev, "I/O address %#08lx is in use\n", base);
 		goto out;


-- 
Mit freundlichen Gruessen,
kind regards,

Christian Krafft
IBM Systems & Technology Group,
Linux Kernel Development
IT Specialist


Vorsitzender des Aufsichtsrats:	Martin Jetter
Geschaeftsfuehrung:		Herbert Kircher
Sitz der Gesellschaft:		Boeblingen
Registriergericht:		Amtsgericht Stuttgart, HRB 243294

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: [Patch 0/2] powerpc: avoid userspace poking to legacy ioports
From: Christian Krafft @ 2008-02-13 17:35 UTC (permalink / raw)
  To: linux-kernel; +Cc: parabelboi, linuxppc-dev
In-Reply-To: <20080213182800.5c6940a8@de.ibm.com>

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

sensors_detect crashes kernel on PowerPC, as it pokes directly to memory.
This patch adds a check_legacy_ioports to read_port and write_port.
It will now return ENXIO, instead of oopsing.

Signed-off-by: Christian Krafft <krafft@de.ibm.com>

Index: linux.git/drivers/char/mem.c
===================================================================
--- linux.git.orig/drivers/char/mem.c
+++ linux.git/drivers/char/mem.c
@@ -566,8 +566,13 @@ static ssize_t read_port(struct file * f
 	char __user *tmp = buf;
 
 	if (!access_ok(VERIFY_WRITE, buf, count))
-		return -EFAULT; 
+		return -EFAULT;
+
 	while (count-- > 0 && i < 65536) {
+#ifdef CONFIG_PPC_MERGE
+		if (check_legacy_ioport(i))
+			return -ENXIO;
+#endif
 		if (__put_user(inb(i),tmp) < 0) 
 			return -EFAULT;  
 		i++;
@@ -585,6 +590,7 @@ static ssize_t write_port(struct file * 
 
 	if (!access_ok(VERIFY_READ,buf,count))
 		return -EFAULT;
+
 	while (count-- > 0 && i < 65536) {
 		char c;
 		if (__get_user(c, tmp)) {
@@ -592,6 +598,10 @@ static ssize_t write_port(struct file * 
 				break;
 			return -EFAULT; 
 		}
+#ifdef CONFIG_PPC_MERGE
+		if (check_legacy_ioport(i))
+			return -ENXIO;
+#endif
 		outb(c,i);
 		i++;
 		tmp++;


-- 
Mit freundlichen Gruessen,
kind regards,

Christian Krafft
IBM Systems & Technology Group,
Linux Kernel Development
IT Specialist


Vorsitzender des Aufsichtsrats:	Martin Jetter
Geschaeftsfuehrung:		Herbert Kircher
Sitz der Gesellschaft:		Boeblingen
Registriergericht:		Amtsgericht Stuttgart, HRB 243294

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* [Patch 0/2] add check_legacy_ioport calls to prevent oops
From: Christian Krafft @ 2008-02-13 17:28 UTC (permalink / raw)
  To: linux-kernel; +Cc: parabelboi, linuxppc-dev

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

Hi,

the following two patches prevent kernel from crashing on powerpc.
The surrounding ifdefs will be obsolete, if check_legacy_ioport becomes
generic code.


-- 
Mit freundlichen Gruessen,
kind regards,

Christian Krafft
IBM Systems & Technology Group,
Linux Kernel Development
IT Specialist


Vorsitzender des Aufsichtsrats:	Martin Jetter
Geschaeftsfuehrung:		Herbert Kircher
Sitz der Gesellschaft:		Boeblingen
Registriergericht:		Amtsgericht Stuttgart, HRB 243294

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: TLB Miss booting linux kernel on ppc 405
From: David Baird @ 2008-02-13 17:17 UTC (permalink / raw)
  To: linuxppc-embedded
In-Reply-To: <5ee408090802130850w130ce09an507ca5c4d41cc5a8@mail.gmail.com>

On Feb 13, 2008 9:50 AM, Ricardo Ayres Severo <severo.ricardo@gmail.com> wrote:
> Hi All,
>
> I'm using kernel 2.6.24 and when it comes to line 826 on the file
> arch/ppc/kernel/head_4xx.S it gives a TLB Miss.
>
> arch/ppc/kernel/head_4xx.S
> 823 start_here:
> 824
> 825         /* ptr to current */
> 826         lis    r2,init_task@h
> 827         ori    r2,r2,init_task@l

I am just curious: how did you find that you have TLB miss on that
line?  Is it an Instruction TLB miss or a Data TLB miss?

Can you paste a dump of your registers (in XMD, rrd and srrd)?

I was having TLB misses awhile back due to some other problems, but
never had any on that line though.

^ permalink raw reply

* Re: [PATCH] drivers/base: export gpl (un)register_memory_notifier
From: Dave Hansen @ 2008-02-13 17:05 UTC (permalink / raw)
  To: Jan-Bernd Themann
  Cc: Thomas Klein, Themann, Jan-Bernd, netdev, apw, linux-kernel,
	linuxppc-dev, Christoph Raisch, Badari Pulavarty, Greg KH,
	Thomas Klein
In-Reply-To: <200802131617.58646.ossthema@de.ibm.com>

On Wed, 2008-02-13 at 16:17 +0100, Jan-Bernd Themann wrote:
> Constraints imposed by HW / FW:
> - eHEA has own MMU
> - eHEA  Memory Regions (MRs) are used by the eHEA MMU  to translate virtual
>   addresses to absolute addresses (like DMA mapped memory on a PCI bus)
> - The number of MRs is limited (not enough to have one MR per packet)

Are there enough to have one per 16MB section?

> Our current understanding about the current Memory Hotplug System are
> (please correct me if I'm wrong):
> 
> - depends on sparse mem

You're wrong ;).  In mainline, this is true.  There was a version of the
SUSE kernel that did otherwise.  But you can not and should not depend
on this never changing.  But, someone is perfectly free to go out an
implement something better than sparsemem for memory hotplug.  If they
go and do this, your driver may get left behind. 

> - only whole memory sections are added / removed
> - for each section a memory resource is registered

True, and true. (There might be exceptions to the whole sections one,
but that's blatant abuse and should be fixed. :)

> From the driver side we need:
> - some kind of memory notification mechanism.
>   For memory add we can live without any external memory notification
>   event. For memory remove we do need an external trigger (see explanation
>   above).

You can export and use (un)register_memory_notifier.  You just need to
do it in a reasonable way that compiles for randconfig on your
architecture.  Believe me, we don't want to start teaching drivers about
sparsemem.  

> - a way to iterate over all kernel pages and a way to detect holes in the
>   kernel memory layout in order to build up our own ehea_bmap.

Look at kernel/resource.c

But, I'm really not convinced that you can actually keep this map
yourselves.  It's not as simple as you think.  What happens if you get
on an LPAR with two sections, one 256MB@0x0 and another
16MB@0x1000000000000000.  That's quite possible.  I think your vmalloc'd
array will eat all of memory.  

That's why we have SPARSEMEM_EXTREME and SPARSEMEM_VMEMMAP implemented
in the core, so that we can deal with these kinds of problems, once and
*NOT* in every single little driver out there.  

> Functions to use while building ehea_bmap + MRs:
> - Use either the functions that are used by the memory hotplug system as
>   well, that means using the section defines + functions (section_nr_to_pfn,
>   pfn_valid)

Basically, you can't use anything related to sections outside of the
core code.  You can use things like pfn_valid(), or you can create new
interfaces that are properly abstracted.  

> - Use currently other not exported functions in kernel/resource.c, like
>   walk_memory_resource (where we would still need the maximum possible number
>   of pages NR_MEM_SECTIONS)

It isn't the act of exporting that's the problem.  It's making sure that
the exports won't be prone to abuse and that people are using them
properly.  You should assume that you can export and use
walk_memory_resource().

Do you know what other operating systems do with this hardware?

In the future, please make an effort to get review from knowledgeable
people about these kinds of things before using them in your driver.
Your company has many, many resources available, and all you need to do
is ask.  All that you have to do is look to the tops of the files of the
functions you are calling.

-- Dave

^ permalink raw reply

* TLB Miss booting linux kernel on ppc 405
From: Ricardo Ayres Severo @ 2008-02-13 16:50 UTC (permalink / raw)
  To: linuxppc-embedded

Hi All,

I'm using kernel 2.6.24 and when it comes to line 826 on the file
arch/ppc/kernel/head_4xx.S it gives a TLB Miss.

arch/ppc/kernel/head_4xx.S
823 start_here:
824
825         /* ptr to current */
826         lis    r2,init_task@h
827         ori    r2,r2,init_task@l

It seems to have a problem initializing the MMU.

What I could do to solve this?

Thanks,

-- 
Ricardo Ayres Severo <severo.ricardo@gmail.com>

^ permalink raw reply

* Re: V4 FX12 and PLB TEMAC: no space for user logic?
From: A. Nolson @ 2008-02-13 16:33 UTC (permalink / raw)
  Cc: linuxppc-embedded
In-Reply-To: <47B2B94A.6090600@dave-tech.it>

Hi ,

I am now developing my own IPs and when I try to synthesize normally I 
get an error because the router finds no place to fit everything. I have 
resynthesized using the option:

XIL_PAR_ENABLE_LEGALIZER=1 ( loading the program with that variable on > 
XIL_PAR_ENABLE_LEGALIZER=1 xps). It took so much time because it uses a 
much more consuming algorithm but I managed to build it correctly.

Regards,
 
/A


llandre wrote:
> Hi Mohammad,
>
> I've just had a look at the messages you generously posted in the ml 
> about your experience with linux on V4 FX12 FPGA.
> I'd like to ask your opinion about FX12 practical usability in this 
> context (gigabit PLB TEMAC/linux).
> In this message
>
> http://article.gmane.org/gmane.linux.ports.ppc.embedded/16816
>
> you say the device is completely full. If I understand correctly your 
> system provides just the devices required to run the bandwidth test so 
> it seems there is no room for user logic (I think you did not even add 
> the memory controller required to access the NOR Flash containing 
> bootloader, kernel image and root fs that is clearly mandatory for 
> standalone product). Is that true? If it is, this limits a lot the 
> flexibility of this architecture in this configuration. What do you think?
>
>
>
> Regards,
> llandre
>
> DAVE Electronics System House - R&D Department
> web:   http://www.dave.eu
> email: r&d2@dave-tech.it
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>
>   

^ permalink raw reply

* Re: [PATCH] [POWERPC] Fix initial lmb add region with a non-zero base
From: Kumar Gala @ 2008-02-13 15:37 UTC (permalink / raw)
  To: Jon Loeliger; +Cc: sparclinux, linuxppc-dev, davem, linux-kernel
In-Reply-To: <E1JPIT1-0001ke-GR@jdl.com>


On Feb 13, 2008, at 8:20 AM, Jon Loeliger wrote:

> So, like, the other day Kumar Gala mumbled:
>> If we add to an empty lmb region with a non-zero base we will not  
>> coalesce
>> the number of regions done to one.  This causes problems on ppc32  
>> for the
>
> s/done/down

will fix.

>> memory region as its assumed to only have one region.
>>
>> We can fix this be easily specially casing the initial add to just  
>> replace
>> the dummy region.
>>
>> ---
>>
>> Posting this since Dave's looking a pulling the lmb code out into  
>> lib/ and
>> sharing it between powerpc and sparc.
>
> Did you want to S-o-b: this patch?  Or was this just informational?

this was info/for review, the git tree has a s-o-b.

- k

^ permalink raw reply

* [PATCH] ehea: add kdump support
From: Thomas Klein @ 2008-02-13 15:18 UTC (permalink / raw)
  To: Jeff Garzik
  Cc: Thomas Klein, Jan-Bernd Themann, netdev, linux-kernel, linux-ppc,
	Christoph Raisch, Marcus Eder

This patch adds kdump support to the ehea driver. As the firmware doesn't free
resource handles automatically, the driver has to run an as simple as possible
free resource function in case of a crash shutdown. The function iterates over
two arrays freeing all resource handles which are stored there. The arrays are
kept up-to-date during normal runtime. The crash handler fn is triggered by the
recently introduced PPC crash shutdown reg/unreg functions.


Signed-off-by: Thomas Klein <tklein@de.ibm.com>

---
 drivers/net/ehea/ehea.h      |   34 +++++-
 drivers/net/ehea/ehea_main.c |  281 ++++++++++++++++++++++++++++++++++++++----
 2 files changed, 290 insertions(+), 25 deletions(-)

diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index 88fb53e..7c4ead3 100644
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -40,7 +40,7 @@
 #include <asm/io.h>

 #define DRV_NAME	"ehea"
-#define DRV_VERSION	"EHEA_0083"
+#define DRV_VERSION	"EHEA_0087"

 /* eHEA capability flags */
 #define DLPAR_PORT_ADD_REM 1
@@ -386,6 +386,13 @@ struct ehea_port_res {


 #define EHEA_MAX_PORTS 16
+
+#define EHEA_NUM_PORTRES_FW_HANDLES    6  /* QP handle, SendCQ handle,
+					     RecvCQ handle, EQ handle,
+					     SendMR handle, RecvMR handle */
+#define EHEA_NUM_PORT_FW_HANDLES       1  /* EQ handle */
+#define EHEA_NUM_ADAPTER_FW_HANDLES    2  /* MR handle, NEQ handle */
+
 struct ehea_adapter {
 	u64 handle;
 	struct of_device *ofdev;
@@ -405,6 +412,31 @@ struct ehea_mc_list {
 	u64 macaddr;
 };

+/* kdump support */
+struct ehea_fw_handle_entry {
+	u64 adh;               /* Adapter Handle */
+	u64 fwh;               /* Firmware Handle */
+};
+
+struct ehea_fw_handle_array {
+	struct ehea_fw_handle_entry *arr;
+	int num_entries;
+	struct semaphore lock;
+};
+
+struct ehea_bcmc_reg_entry {
+	u64 adh;               /* Adapter Handle */
+	u32 port_id;           /* Logical Port Id */
+	u8 reg_type;           /* Registration Type */
+	u64 macaddr;
+};
+
+struct ehea_bcmc_reg_array {
+	struct ehea_bcmc_reg_entry *arr;
+	int num_entries;
+	struct semaphore lock;
+};
+
 #define EHEA_PORT_UP 1
 #define EHEA_PORT_DOWN 0
 #define EHEA_PHY_LINK_UP 1
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index c051c7e..21af674 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -35,6 +35,7 @@
 #include <linux/if_ether.h>
 #include <linux/notifier.h>
 #include <linux/reboot.h>
+#include <asm/kexec.h>

 #include <net/ip.h>

@@ -98,8 +99,10 @@ static int port_name_cnt;
 static LIST_HEAD(adapter_list);
 u64 ehea_driver_flags;
 struct work_struct ehea_rereg_mr_task;
-
 struct semaphore dlpar_mem_lock;
+struct ehea_fw_handle_array ehea_fw_handles;
+struct ehea_bcmc_reg_array ehea_bcmc_regs;
+

 static int __devinit ehea_probe_adapter(struct of_device *dev,
 					const struct of_device_id *id);
@@ -132,6 +135,160 @@ void ehea_dump(void *adr, int len, char *msg)
 	}
 }

+static void ehea_update_firmware_handles(void)
+{
+	struct ehea_fw_handle_entry *arr = NULL;
+	struct ehea_adapter *adapter;
+	int num_adapters = 0;
+	int num_ports = 0;
+	int num_portres = 0;
+	int i = 0;
+	int num_fw_handles, k, l;
+
+	/* Determine number of handles */
+	list_for_each_entry(adapter, &adapter_list, list) {
+		num_adapters++;
+
+		for (k = 0; k < EHEA_MAX_PORTS; k++) {
+			struct ehea_port *port = adapter->port[k];
+
+			if (!port || (port->state != EHEA_PORT_UP))
+				continue;
+
+			num_ports++;
+			num_portres += port->num_def_qps + port->num_add_tx_qps;
+		}
+	}
+
+	num_fw_handles = num_adapters * EHEA_NUM_ADAPTER_FW_HANDLES +
+			 num_ports * EHEA_NUM_PORT_FW_HANDLES +
+			 num_portres * EHEA_NUM_PORTRES_FW_HANDLES;
+
+	if (num_fw_handles) {
+		arr = kzalloc(num_fw_handles * sizeof(*arr), GFP_KERNEL);
+		if (!arr)
+			return;  /* Keep the existing array */
+	} else
+		goto out_update;
+
+	list_for_each_entry(adapter, &adapter_list, list) {
+		for (k = 0; k < EHEA_MAX_PORTS; k++) {
+			struct ehea_port *port = adapter->port[k];
+
+			if (!port || (port->state != EHEA_PORT_UP))
+				continue;
+
+			for (l = 0;
+			     l < port->num_def_qps + port->num_add_tx_qps;
+			     l++) {
+				struct ehea_port_res *pr = &port->port_res[l];
+
+				arr[i].adh = adapter->handle;
+				arr[i++].fwh = pr->qp->fw_handle;
+				arr[i].adh = adapter->handle;
+				arr[i++].fwh = pr->send_cq->fw_handle;
+				arr[i].adh = adapter->handle;
+				arr[i++].fwh = pr->recv_cq->fw_handle;
+				arr[i].adh = adapter->handle;
+				arr[i++].fwh = pr->eq->fw_handle;
+				arr[i].adh = adapter->handle;
+				arr[i++].fwh = pr->send_mr.handle;
+				arr[i].adh = adapter->handle;
+				arr[i++].fwh = pr->recv_mr.handle;
+			}
+			arr[i].adh = adapter->handle;
+			arr[i++].fwh = port->qp_eq->fw_handle;
+		}
+
+		arr[i].adh = adapter->handle;
+		arr[i++].fwh = adapter->neq->fw_handle;
+
+		if (adapter->mr.handle) {
+			arr[i].adh = adapter->handle;
+			arr[i++].fwh = adapter->mr.handle;
+		}
+	}
+
+out_update:
+	kfree(ehea_fw_handles.arr);
+	ehea_fw_handles.arr = arr;
+	ehea_fw_handles.num_entries = i;
+}
+
+static void ehea_update_bcmc_registrations(void)
+{
+	struct ehea_bcmc_reg_entry *arr = NULL;
+	struct ehea_adapter *adapter;
+	struct ehea_mc_list *mc_entry;
+	int num_registrations = 0;
+	int i = 0;
+	int k;
+
+	/* Determine number of registrations */
+	list_for_each_entry(adapter, &adapter_list, list)
+		for (k = 0; k < EHEA_MAX_PORTS; k++) {
+			struct ehea_port *port = adapter->port[k];
+
+			if (!port || (port->state != EHEA_PORT_UP))
+				continue;
+
+			num_registrations += 2;	/* Broadcast registrations */
+
+			list_for_each_entry(mc_entry, &port->mc_list->list,list)
+				num_registrations += 2;
+		}
+
+	if (num_registrations) {
+		arr = kzalloc(num_registrations * sizeof(*arr), GFP_KERNEL);
+		if (!arr)
+			return;  /* Keep the existing array */
+	} else
+		goto out_update;
+
+	list_for_each_entry(adapter, &adapter_list, list) {
+		for (k = 0; k < EHEA_MAX_PORTS; k++) {
+			struct ehea_port *port = adapter->port[k];
+
+			if (!port || (port->state != EHEA_PORT_UP))
+				continue;
+
+			arr[i].adh = adapter->handle;
+			arr[i].port_id = port->logical_port_id;
+			arr[i].reg_type = EHEA_BCMC_BROADCAST |
+					  EHEA_BCMC_UNTAGGED;
+			arr[i++].macaddr = port->mac_addr;
+
+			arr[i].adh = adapter->handle;
+			arr[i].port_id = port->logical_port_id;
+			arr[i].reg_type = EHEA_BCMC_BROADCAST |
+					  EHEA_BCMC_VLANID_ALL;
+			arr[i++].macaddr = port->mac_addr;
+
+			list_for_each_entry(mc_entry,
+					    &port->mc_list->list, list) {
+				arr[i].adh = adapter->handle;
+				arr[i].port_id = port->logical_port_id;
+				arr[i].reg_type = EHEA_BCMC_SCOPE_ALL |
+						  EHEA_BCMC_MULTICAST |
+						  EHEA_BCMC_UNTAGGED;
+				arr[i++].macaddr = mc_entry->macaddr;
+
+				arr[i].adh = adapter->handle;
+				arr[i].port_id = port->logical_port_id;
+				arr[i].reg_type = EHEA_BCMC_SCOPE_ALL |
+						  EHEA_BCMC_MULTICAST |
+						  EHEA_BCMC_VLANID_ALL;
+				arr[i++].macaddr = mc_entry->macaddr;
+			}
+		}
+	}
+
+out_update:
+	kfree(ehea_bcmc_regs.arr);
+	ehea_bcmc_regs.arr = arr;
+	ehea_bcmc_regs.num_entries = i;
+}
+
 static struct net_device_stats *ehea_get_stats(struct net_device *dev)
 {
 	struct ehea_port *port = netdev_priv(dev);
@@ -1601,19 +1758,25 @@ static int ehea_set_mac_addr(struct net_device *dev, void *sa)

 	memcpy(dev->dev_addr, mac_addr->sa_data, dev->addr_len);

+	down(&ehea_bcmc_regs.lock);
+
 	/* Deregister old MAC in pHYP */
 	ret = ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
 	if (ret)
-		goto out_free;
+		goto out_upregs;

 	port->mac_addr = cb0->port_mac_addr << 16;

 	/* Register new MAC in pHYP */
 	ret = ehea_broadcast_reg_helper(port, H_REG_BCMC);
 	if (ret)
-		goto out_free;
+		goto out_upregs;

 	ret = 0;
+
+out_upregs:
+	ehea_update_bcmc_registrations();
+	up(&ehea_bcmc_regs.lock);
 out_free:
 	kfree(cb0);
 out:
@@ -1775,9 +1938,11 @@ static void ehea_set_multicast_list(struct net_device *dev)
 	}
 	ehea_promiscuous(dev, 0);

+	down(&ehea_bcmc_regs.lock);
+
 	if (dev->flags & IFF_ALLMULTI) {
 		ehea_allmulti(dev, 1);
-		return;
+		goto out;
 	}
 	ehea_allmulti(dev, 0);

@@ -1803,6 +1968,8 @@ static void ehea_set_multicast_list(struct net_device *dev)

 	}
 out:
+	ehea_update_bcmc_registrations();
+	up(&ehea_bcmc_regs.lock);
 	return;
 }

@@ -2285,6 +2452,8 @@ static int ehea_up(struct net_device *dev)
 	if (port->state == EHEA_PORT_UP)
 		return 0;

+	down(&ehea_fw_handles.lock);
+
 	ret = ehea_port_res_setup(port, port->num_def_qps,
 				  port->num_add_tx_qps);
 	if (ret) {
@@ -2321,8 +2490,17 @@ static int ehea_up(struct net_device *dev)
 		}
 	}

-	ret = 0;
+	down(&ehea_bcmc_regs.lock);
+
+	ret = ehea_broadcast_reg_helper(port, H_REG_BCMC);
+	if (ret) {
+		ret = -EIO;
+		goto out_free_irqs;
+	}
+
 	port->state = EHEA_PORT_UP;
+
+	ret = 0;
 	goto out;

 out_free_irqs:
@@ -2334,6 +2512,12 @@ out:
 	if (ret)
 		ehea_info("Failed starting %s. ret=%i", dev->name, ret);

+	ehea_update_bcmc_registrations();
+	up(&ehea_bcmc_regs.lock);
+
+	ehea_update_firmware_handles();
+	up(&ehea_fw_handles.lock);
+
 	return ret;
 }

@@ -2382,16 +2566,27 @@ static int ehea_down(struct net_device *dev)
 	if (port->state == EHEA_PORT_DOWN)
 		return 0;

+	down(&ehea_bcmc_regs.lock);
 	ehea_drop_multicast_list(dev);
+	ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
+
 	ehea_free_interrupts(dev);

+	down(&ehea_fw_handles.lock);
+
 	port->state = EHEA_PORT_DOWN;

+	ehea_update_bcmc_registrations();
+	up(&ehea_bcmc_regs.lock);
+
 	ret = ehea_clean_all_portres(port);
 	if (ret)
 		ehea_info("Failed freeing resources for %s. ret=%i",
 			  dev->name, ret);

+	ehea_update_firmware_handles();
+	up(&ehea_fw_handles.lock);
+
 	return ret;
 }

@@ -2920,19 +3115,12 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
 	dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT;

 	INIT_WORK(&port->reset_task, ehea_reset_port);
-
-	ret = ehea_broadcast_reg_helper(port, H_REG_BCMC);
-	if (ret) {
-		ret = -EIO;
-		goto out_unreg_port;
-	}
-
 	ehea_set_ethtool_ops(dev);

 	ret = register_netdev(dev);
 	if (ret) {
 		ehea_error("register_netdev failed. ret=%d", ret);
-		goto out_dereg_bc;
+		goto out_unreg_port;
 	}

 	port->lro_max_aggr = lro_max_aggr;
@@ -2949,9 +3137,6 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,

 	return port;

-out_dereg_bc:
-	ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
-
 out_unreg_port:
 	ehea_unregister_port(port);

@@ -2971,7 +3156,6 @@ static void ehea_shutdown_single_port(struct ehea_port *port)
 {
 	unregister_netdev(port->netdev);
 	ehea_unregister_port(port);
-	ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
 	kfree(port->mc_list);
 	free_netdev(port->netdev);
 	port->adapter->active_ports--;
@@ -3014,7 +3198,6 @@ static int ehea_setup_ports(struct ehea_adapter *adapter)

 		i++;
 	};
-
 	return 0;
 }

@@ -3159,6 +3342,7 @@ static int __devinit ehea_probe_adapter(struct of_device *dev,
 		ehea_error("Invalid ibmebus device probed");
 		return -EINVAL;
 	}
+	down(&ehea_fw_handles.lock);

 	adapter = kzalloc(sizeof(*adapter), GFP_KERNEL);
 	if (!adapter) {
@@ -3239,7 +3423,10 @@ out_kill_eq:

 out_free_ad:
 	kfree(adapter);
+
 out:
+	ehea_update_firmware_handles();
+	up(&ehea_fw_handles.lock);
 	return ret;
 }

@@ -3258,18 +3445,41 @@ static int __devexit ehea_remove(struct of_device *dev)

 	flush_scheduled_work();

+	down(&ehea_fw_handles.lock);
+
 	ibmebus_free_irq(adapter->neq->attr.ist1, adapter);
 	tasklet_kill(&adapter->neq_tasklet);

 	ehea_destroy_eq(adapter->neq);
 	ehea_remove_adapter_mr(adapter);
 	list_del(&adapter->list);
-
 	kfree(adapter);

+	ehea_update_firmware_handles();
+	up(&ehea_fw_handles.lock);
+
 	return 0;
 }

+void ehea_crash_handler(void)
+{
+	int i;
+
+	if (ehea_fw_handles.arr)
+		for (i = 0; i < ehea_fw_handles.num_entries; i++)
+			ehea_h_free_resource(ehea_fw_handles.arr[i].adh,
+					     ehea_fw_handles.arr[i].fwh,
+					     FORCE_FREE);
+
+	if (ehea_bcmc_regs.arr)
+		for (i = 0; i < ehea_bcmc_regs.num_entries; i++)
+			ehea_h_reg_dereg_bcmc(ehea_bcmc_regs.arr[i].adh,
+					      ehea_bcmc_regs.arr[i].port_id,
+					      ehea_bcmc_regs.arr[i].reg_type,
+					      ehea_bcmc_regs.arr[i].macaddr,
+					      0, H_DEREG_BCMC);
+}
+
 static int ehea_reboot_notifier(struct notifier_block *nb,
 				unsigned long action, void *unused)
 {
@@ -3330,7 +3540,12 @@ int __init ehea_module_init(void)


 	INIT_WORK(&ehea_rereg_mr_task, ehea_rereg_mrs);
+	memset(&ehea_fw_handles, 0, sizeof(ehea_fw_handles));
+	memset(&ehea_bcmc_regs, 0, sizeof(ehea_bcmc_regs));
+
 	sema_init(&dlpar_mem_lock, 1);
+	sema_init(&ehea_fw_handles.lock, 1);
+	sema_init(&ehea_bcmc_regs.lock, 1);

 	ret = check_module_parm();
 	if (ret)
@@ -3340,12 +3555,18 @@ int __init ehea_module_init(void)
 	if (ret)
 		goto out;

-	register_reboot_notifier(&ehea_reboot_nb);
+	ret = register_reboot_notifier(&ehea_reboot_nb);
+	if (ret)
+		ehea_info("failed registering reboot notifier");
+
+	ret = crash_shutdown_register(&ehea_crash_handler);
+	if (ret)
+		ehea_info("failed registering crash handler");

 	ret = ibmebus_register_driver(&ehea_driver);
 	if (ret) {
 		ehea_error("failed registering eHEA device driver on ebus");
-		goto out;
+		goto out2;
 	}

 	ret = driver_create_file(&ehea_driver.driver,
@@ -3353,21 +3574,33 @@ int __init ehea_module_init(void)
 	if (ret) {
 		ehea_error("failed to register capabilities attribute, ret=%d",
 			   ret);
-		unregister_reboot_notifier(&ehea_reboot_nb);
-		ibmebus_unregister_driver(&ehea_driver);
-		goto out;
+		goto out3;
 	}

+	return ret;
+
+out3:
+	ibmebus_unregister_driver(&ehea_driver);
+out2:
+	unregister_reboot_notifier(&ehea_reboot_nb);
+	crash_shutdown_unregister(&ehea_crash_handler);
 out:
 	return ret;
 }

 static void __exit ehea_module_exit(void)
 {
+	int ret;
+
 	flush_scheduled_work();
 	driver_remove_file(&ehea_driver.driver, &driver_attr_capabilities);
 	ibmebus_unregister_driver(&ehea_driver);
 	unregister_reboot_notifier(&ehea_reboot_nb);
+	ret = crash_shutdown_unregister(&ehea_crash_handler);
+	if (ret)
+		ehea_info("failed unregistering crash handler");
+	kfree(ehea_fw_handles.arr);
+	kfree(ehea_bcmc_regs.arr);
 	ehea_destroy_busmap();
 }

-- 
1.5.2

^ permalink raw reply related

* Re: [PATCH] drivers/base: export gpl (un)register_memory_notifier
From: Jan-Bernd Themann @ 2008-02-13 15:17 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: Thomas Klein, Themann, Jan-Bernd, netdev, Dave Hansen, apw,
	linux-kernel, Christoph Raisch, Badari Pulavarty, Greg KH,
	Thomas Klein
In-Reply-To: <1202748429.8276.21.camel@nimitz.home.sr71.net>

Hi Dave,

On Monday 11 February 2008 17:47, Dave Hansen wrote:
> Also, just ripping down and completely re-doing the entire mass of cards
> every time a 16MB area of memory is added or removed seems like an
> awfully big sledgehammer to me.  I would *HATE* to see anybody else
> using this driver as an example to work off of?  Can't you just keep
> track of which areas the driver is actually *USING* and only worry about
> changing mappings if that intersects with an area having hotplug done on
> it?


to form a base for the eHEA memory add / remove concept discussion:

Explanation of the current eHEA memory add / remove concept:

Constraints imposed by HW / FW:
=2D eHEA has own MMU
=2D eHEA =A0Memory Regions (MRs) are used by the eHEA MMU =A0to translate v=
irtual
=A0 addresses to absolute addresses (like DMA mapped memory on a PCI bus)
=2D The number of MRs is limited (not enough to have one MR per packet)
=2D Registration of MRs is comparativley slow as done via slow firmware call
(H_CALL)
=2D MRs can have a maximum size of the memory available under linux
=2D MRs cover a contiguous virtual memory block (no holes)

Because of this there is just one big MR that covers entire kernel memory.
We also need a mapping table from kernel addresses to this
contiguous "virtual memory IO space" (here called ehea_bmap).

=2D When memory is added / removed to LPAR (and linux), the MR has to be up=
dated.
=A0 This can only be done by destroying and recreating the MR. There is no =
H_CALL
=A0 to modify MR size. To find holes in the linux kernel memory layout we h=
ave to
=A0 iterate over the memory sections for recreating a ehea_bmap
  (otherwise MR would be bigger then available memory causing the
  registration to fail)

=2D DLPAR userspace tools, kernel, driver, firmware and HMC are involved in=
 that
=A0 process on System p

Memory add: version without a external memory notifier call
=2D new memory used in a transfer_xmit will result in a "ehea_bmap
  translation miss", which triggers a rebuild and reregistration
=A0 of the ehea_bmap based on the current kernel memory setup.
=2D advantage: the number of MR rebuilds is reduced significantly compared =
to
  a rebuild for each 16MB chunk of memory added.

Memory add: version with external notifier call:
=2D We still need a ehea_bmap (whatever structure it has)

Memory remove with notifier:
=2D We have to rebuild the ehea_bmap instantly to remove the pages that are
  no longer available. Without doing that, the firmware (pHYP) cannot remove
  that memory from the LPAR. As we don't know if or how many additional=20
  sections are to be removed before the DLPAR user space tool tells the=20
  firmware to remove the memory, we can't wait with the rebuild.


Our current understanding about the current Memory Hotplug System are
(please correct me
if I'm wrong):

=2D depends on sparse mem
=2D only whole memory sections are added / removed
=2D for each section a memory resource is registered


=46rom the driver side we need:
=2D some kind of memory notification mechanism.
=A0 For memory add we can live without any external memory notification
  event. For memory remove we do need an external trigger (see explanation
  above).
=2D a way to iterate over all kernel pages and a way to detect holes in the
  kernel memory layout in order to build up our own ehea_bmap.


Memory notification trigger:
=2D These triggers exist, an exported "register_memory_notifier" /
=A0 "unregister_memory_notifier" would work in this scheme

=46unctions to use while building ehea_bmap + MRs:
=2D Use either the functions that are used by the memory hotplug system as
  well, that means using the section defines + functions (section_nr_to_pfn,
=A0 pfn_valid)
=2D Use currently other not exported functions in kernel/resource.c, like
  walk_memory_resource (where we would still need the maximum possible numb=
er
  of pages NR_MEM_SECTIONS)
=2D Maybe some kind of new interface?

What would you suggest?

Regards,
Jan-Bernd & Christoph

^ permalink raw reply

* Re: [PATCH] [POWERPC] Fix initial lmb add region with a non-zero base
From: Jon Loeliger @ 2008-02-13 14:20 UTC (permalink / raw)
  To: Kumar Gala; +Cc: sparclinux, linuxppc-dev, davem, linux-kernel
In-Reply-To: <Pine.LNX.4.64.0802130719330.14428@blarg.am.freescale.net>

So, like, the other day Kumar Gala mumbled:
> If we add to an empty lmb region with a non-zero base we will not coalesce
> the number of regions done to one.  This causes problems on ppc32 for the

s/done/down

> memory region as its assumed to only have one region.
> 
> We can fix this be easily specially casing the initial add to just replace
> the dummy region.
> 
> ---
>
> Posting this since Dave's looking a pulling the lmb code out into lib/ and
> sharing it between powerpc and sparc.

Did you want to S-o-b: this patch?  Or was this just informational?

Thanks,
jdl

^ permalink raw reply


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