LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] [POWERPC] ps3: Fix section mismatch in ps3/setup.c
From: Stephen Rothwell @ 2007-07-31  7:22 UTC (permalink / raw)
  To: paulus; +Cc: ppc-dev

WARNING: vmlinux.o(.text+0x605d4): Section mismatch: reference to .init.text:.__alloc_bootmem (between '.prealloc' and '.ps3_power_save')

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
 arch/powerpc/platforms/ps3/setup.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c
index aa05288..2952b22 100644
--- a/arch/powerpc/platforms/ps3/setup.c
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -109,7 +109,7 @@ static void ps3_panic(char *str)
 
 #if defined(CONFIG_FB_PS3) || defined(CONFIG_FB_PS3_MODULE) || \
     defined(CONFIG_PS3_FLASH) || defined(CONFIG_PS3_FLASH_MODULE)
-static void prealloc(struct ps3_prealloc *p)
+static void __init prealloc(struct ps3_prealloc *p)
 {
 	if (!p->size)
 		return;
-- 
1.5.2.4

^ permalink raw reply related

* [PATCH] [POWERPC] Fix section mismatch references to alloc_bootmem
From: Stephen Rothwell @ 2007-07-31  7:14 UTC (permalink / raw)
  To: paulus; +Cc: ppc-dev

WARNING: vmlinux.o(.text+0x2a9c4): Section mismatch: reference to .init.text:.__alloc_bootmem (between '.update_dn_pci_info' and '.pci_dn_reconfig_notifier')
WARNING: vmlinux.o(.text+0x36430): Section mismatch: reference to .init.text:.__alloc_bootmem (between '.mpic_msi_init_allocator' and '.find_ht_magic_addr')
WARNING: vmlinux.o(.text+0x5e804): Section mismatch: reference to .init.text:.__alloc_bootmem (between '.celleb_setup_phb' and '.celleb_fake_pci_write_config')
WARNING: vmlinux.o(.text+0x5e8e8): Section mismatch: reference to .init.text:.__alloc_bootmem (between '.celleb_setup_phb' and '.celleb_fake_pci_write_config')
WARNING: vmlinux.o(.text+0x5e968): Section mismatch: reference to .init.text:.__alloc_bootmem (between '.celleb_setup_phb' and '.celleb_fake_pci_write_config')
WARNING: vmlinux.o(.text+0x5ec50): Section mismatch: reference to .init.text:.free_bootmem (between '.celleb_setup_phb' and '.celleb_fake_pci_write_config')
WARNING: vmlinux.o(.text+0x5ec70): Section mismatch: reference to .init.text:.free_bootmem (between '.celleb_setup_phb' and '.celleb_fake_pci_write_config')
WARNING: vmlinux.o(.text+0x5eb88): Section mismatch: reference to .init.text:.free_bootmem (between '.celleb_setup_phb' and '.celleb_fake_pci_write_config')
WARNING: vmlinux.o(.text+0x5eba8): Section mismatch: reference to .init.text:.free_bootmem (between '.celleb_setup_phb' and '.celleb_fake_pci_write_config')

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
 arch/powerpc/kernel/pci_dn.c        |    7 +-----
 arch/powerpc/lib/Makefile           |    2 +-
 arch/powerpc/lib/alloc.c            |   22 ++++++++++++++++++
 arch/powerpc/platforms/celleb/pci.c |   41 +++++++---------------------------
 arch/powerpc/sysdev/mpic_msi.c      |    6 +----
 include/asm-powerpc/system.h        |    3 ++
 6 files changed, 37 insertions(+), 44 deletions(-)
 create mode 100644 arch/powerpc/lib/alloc.c

Built for ppc64_defconfig and allmodconfig.  ppc64_defconfig build booted
on iSeries 270.

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c
index d7d36df..b483903 100644
--- a/arch/powerpc/kernel/pci_dn.c
+++ b/arch/powerpc/kernel/pci_dn.c
@@ -23,8 +23,6 @@
 #include <linux/pci.h>
 #include <linux/string.h>
 #include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/bootmem.h>
 
 #include <asm/io.h>
 #include <asm/prom.h>
@@ -45,10 +43,7 @@ static void * __devinit update_dn_pci_info(struct device_node *dn, void *data)
 	const u32 *regs;
 	struct pci_dn *pdn;
 
-	if (mem_init_done)
-		pdn = kmalloc(sizeof(*pdn), GFP_KERNEL);
-	else
-		pdn = alloc_bootmem(sizeof(*pdn));
+	pdn = alloc_maybe_bootmem(sizeof(*pdn), GFP_KERNEL);
 	if (pdn == NULL)
 		return NULL;
 	memset(pdn, 0, sizeof(*pdn));
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index 0a486d4..23bbb1e 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -7,7 +7,7 @@ EXTRA_CFLAGS		+= -mno-minimal-toc
 endif
 
 ifeq ($(CONFIG_PPC_MERGE),y)
-obj-y			:= string.o
+obj-y			:= string.o alloc.o
 obj-$(CONFIG_PPC32)	+= div64.o copy_32.o checksum_32.o
 endif
 
diff --git a/arch/powerpc/lib/alloc.c b/arch/powerpc/lib/alloc.c
new file mode 100644
index 0000000..4a6bc23
--- /dev/null
+++ b/arch/powerpc/lib/alloc.c
@@ -0,0 +1,22 @@
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/bootmem.h>
+
+#include <asm/system.h>
+
+void * __init_refok alloc_maybe_bootmem(size_t size, gfp_t mask)
+{
+	if (mem_init_done)
+		return kmalloc(size, mask);
+	else
+		return alloc_bootmem(size);
+}
+
+void __init_refok free_maybe_bootmem(void *ptr, size_t size)
+{
+	if (mem_init_done)
+		kfree(ptr);
+	else
+		free_bootmem((unsigned long)ptr, size);
+}
diff --git a/arch/powerpc/platforms/celleb/pci.c b/arch/powerpc/platforms/celleb/pci.c
index e9ac19c..72ce335 100644
--- a/arch/powerpc/platforms/celleb/pci.c
+++ b/arch/powerpc/platforms/celleb/pci.c
@@ -29,7 +29,6 @@
 #include <linux/pci.h>
 #include <linux/string.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
 #include <linux/pci_regs.h>
 
 #include <asm/io.h>
@@ -327,10 +326,7 @@ static int __devinit celleb_setup_fake_pci_device(struct device_node *node,
 
 	size = 256;
 	config = &private->fake_config[devno][fn];
-	if (mem_init_done)
-		*config = kzalloc(size, GFP_KERNEL);
-	else
-		*config = alloc_bootmem(size);
+	*config = alloc_maybe_bootmem(size, GFP_KERNEL);
 	if (*config == NULL) {
 		printk(KERN_ERR "PCI: "
 		       "not enough memory for fake configuration space\n");
@@ -341,10 +337,7 @@ static int __devinit celleb_setup_fake_pci_device(struct device_node *node,
 
 	size = sizeof(struct celleb_pci_resource);
 	res = &private->res[devno][fn];
-	if (mem_init_done)
-		*res = kzalloc(size, GFP_KERNEL);
-	else
-		*res = alloc_bootmem(size);
+	*res = alloc_maybe_bootmem(size, GFP_KERNEL);
 	if (*res == NULL) {
 		printk(KERN_ERR
 		       "PCI: not enough memory for resource data space\n");
@@ -398,23 +391,10 @@ static int __devinit celleb_setup_fake_pci_device(struct device_node *node,
 	return 0;
 
 error:
-	if (mem_init_done) {
-		if (config && *config)
-			kfree(*config);
-		if (res && *res)
-			kfree(*res);
-
-	} else {
-		if (config && *config) {
-			size = 256;
-			free_bootmem((unsigned long)(*config), size);
-		}
-		if (res && *res) {
-			size = sizeof(struct celleb_pci_resource);
-			free_bootmem((unsigned long)(*res), size);
-		}
-	}
-
+	if (config && *config)
+		free_maybe_bootmem(*config, 256);
+	if (res && *res)
+		free_maybe_bootmem(*res, sizeof(struct celleb_pci_resource));
 	return 1;
 }
 
@@ -436,12 +416,9 @@ static int __devinit phb_set_bus_ranges(struct device_node *dev,
 
 static void __devinit celleb_alloc_private_mem(struct pci_controller *hose)
 {
-	if (mem_init_done)
-		hose->private_data =
-			kzalloc(sizeof(struct celleb_pci_private), GFP_KERNEL);
-	else
-		hose->private_data =
-			alloc_bootmem(sizeof(struct celleb_pci_private));
+	hose->private_data =
+		alloc_maybe_bootmem(sizeof(struct celleb_pci_private),
+			GFP_KERNEL);
 }
 
 int __devinit celleb_setup_phb(struct pci_controller *phb)
diff --git a/arch/powerpc/sysdev/mpic_msi.c b/arch/powerpc/sysdev/mpic_msi.c
index b076793..53fa9f5 100644
--- a/arch/powerpc/sysdev/mpic_msi.c
+++ b/arch/powerpc/sysdev/mpic_msi.c
@@ -9,7 +9,6 @@
  */
 
 #include <linux/irq.h>
-#include <linux/bootmem.h>
 #include <linux/bitmap.h>
 #include <linux/msi.h>
 #include <asm/mpic.h>
@@ -151,10 +150,7 @@ int mpic_msi_init_allocator(struct mpic *mpic)
 	size = BITS_TO_LONGS(mpic->irq_count) * sizeof(long);
 	pr_debug("mpic: allocator bitmap size is 0x%x bytes\n", size);
 
-	if (mem_init_done)
-		mpic->hwirq_bitmap = kmalloc(size, GFP_KERNEL);
-	else
-		mpic->hwirq_bitmap = alloc_bootmem(size);
+	mpic->hwirq_bitmap = alloc_maybe_bootmem(size, GFP_KERNEL);
 
 	if (!mpic->hwirq_bitmap) {
 		pr_debug("mpic: ENOMEM allocating allocator bitmap!\n");
diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h
index 41520b7..047b740 100644
--- a/include/asm-powerpc/system.h
+++ b/include/asm-powerpc/system.h
@@ -189,6 +189,9 @@ extern int mem_init_done;	/* set on boot once kmalloc can be called */
 extern unsigned long memory_limit;
 extern unsigned long klimit;
 
+extern void *alloc_maybe_bootmem(size_t size, gfp_t mask);
+extern void free_maybe_bootmem(void *ptr, size_t size);
+
 extern int powersave_nap;	/* set if nap mode can be used in idle loop */
 
 /*
-- 
1.5.2.4

^ permalink raw reply related

* Re: Reboot Command Makes kernel to hang (MPC8560)
From: Ansari @ 2007-07-31  7:10 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-embedded
In-Reply-To: <880B302A-742A-4CC1-BB41-E7BD1CE570C6@kernel.crashing.org>

Hi Kumar,

First of all thanks for ur reply .

Even i went through the linux source . And i have observe that the reboot 
command used to hard reset the core . I have few doubts can u please clarify 
me.

1. Is there any way to reset the full chip with out using any external 
signal (MPC8560) ? (like any register that can be used for reseting the 
processor)
2. Even same reboot command works fine for MPC8540 Processor ?.
3. what are the factors that makes ramdisk hangs . When its uncompressing ?

Regards
Haroun Ansari


----- Original Message ----- 
From: "Kumar Gala" <galak@kernel.crashing.org>
To: "Ansari" <ma.harounansari@gdatech.co.in>
Cc: <linuxppc-embedded@ozlabs.org>
Sent: Friday, July 27, 2007 1:21 AM
Subject: Re: Reboot Command Makes kernel to hang (MPC8560)


>
> On Jul 26, 2007, at 1:55 AM, Ansari wrote:
>
>> Hi all,
>>
>> Processor (MPC8560)
>>
>> Whenever reboot command is given in the linux console. The  processor 
>> gets reset and it loads bootloader , kernel and when  uncompressing the 
>> ramdisk it gets hang. The sample log is given  below. Any u please tell 
>> me what are the factors that can makes  this to happen.
>
> This is very board dependant.  The MPC8560 doesn't have a clean way  to 
> request reset, and odds are you're only getting the core reset and  not 
> the full chip.
>
> - k
> 

^ permalink raw reply

* [PATCH] [POWERPC] Fix more section mismatches in head_64.S
From: Stephen Rothwell @ 2007-07-31  6:44 UTC (permalink / raw)
  To: paulus; +Cc: ppc-dev

WARNING: vmlinux.o(.text+0x8174): Section mismatch: reference to .init.text:.prom_init (between '.__boot_from_prom' and '.__after_prom_start')
WARNING: vmlinux.o(.text+0x8498): Section mismatch: reference to .init.text:.early_setup (between '.start_here_multiplatform' and '.start_here_common')
WARNING: vmlinux.o(.text+0x8514): Section mismatch: reference to .init.text:.setup_system (between '.start_here_common' and 'system_call_common')
WARNING: vmlinux.o(.text+0x8530): Section mismatch: reference to .init.text:.start_kernel (between '.start_here_common' and 'system_call_common')

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
 arch/powerpc/kernel/head_64.S |   16 +++++++++-------
 1 files changed, 9 insertions(+), 7 deletions(-)

Booted in POWER5+.
-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 1448af9..1718000 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -1672,8 +1672,9 @@ _GLOBAL(__start_initialization_multiplatform)
 	 * Are we booted from a PROM Of-type client-interface ?
 	 */
 	cmpldi	cr0,r5,0
-	bne	.__boot_from_prom		/* yes -> prom */
-
+	beq	1f
+	b	.__boot_from_prom		/* yes -> prom */
+1:
 	/* Save parameters */
 	mr	r31,r3
 	mr	r30,r4
@@ -1701,7 +1702,7 @@ _GLOBAL(__start_initialization_multiplatform)
 	bl	.__mmu_off
 	b	.__after_prom_start
 
-_STATIC(__boot_from_prom)
+_INIT_STATIC(__boot_from_prom)
 	/* Save parameters */
 	mr	r31,r3
 	mr	r30,r4
@@ -1768,9 +1769,10 @@ _STATIC(__after_prom_start)
 					/*	the source addr		 */
 
 	cmpdi	r4,0			/* In some cases the loader may  */
-	beq	.start_here_multiplatform /* have already put us at zero */
+	bne	1f
+	b	.start_here_multiplatform /* have already put us at zero */
 					/* so we can skip the copy.      */
-	LOAD_REG_IMMEDIATE(r5,copy_to_here) /* # bytes of memory to copy */
+1:	LOAD_REG_IMMEDIATE(r5,copy_to_here) /* # bytes of memory to copy */
 	sub	r5,r5,r27
 
 	li	r6,0x100		/* Start offset, the first 0x100 */
@@ -1957,7 +1959,7 @@ _GLOBAL(enable_64b_mode)
 /*
  * This is where the main kernel code starts.
  */
-_STATIC(start_here_multiplatform)
+_INIT_STATIC(start_here_multiplatform)
 	/* get a new offset, now that the kernel has moved. */
 	bl	.reloc_offset
 	mr	r26,r3
@@ -2019,7 +2021,7 @@ _STATIC(start_here_multiplatform)
 	b	.	/* prevent speculative execution */
 	
 	/* This is where all platforms converge execution */
-_STATIC(start_here_common)
+_INIT_STATIC(start_here_common)
 	/* relocation is on at this point */
 
 	/* The following code sets up the SP and TOC now that we are */
-- 
1.5.2.4

^ permalink raw reply related

* Re: [PATCH 4/6] PowerPC 440EPx: Sequoia bootwrapper
From: Stefan Roese @ 2007-07-31  5:54 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <20070730151445.GA5075@ru.mvista.com>

On Monday 30 July 2007, Valentine Barshak wrote:
> A bootwrapper code for Sequoia.
>
> Signed-off-by: Valentine Barshak <vbarshak@ru.mvista.com>
> ---
>  arch/powerpc/boot/44x.h              |    1
>  arch/powerpc/boot/Makefile           |    6
>  arch/powerpc/boot/cuboot-sequoia.c   |   31 ++++
>  arch/powerpc/boot/sequoia.c          |  234
>  +++++++++++++++++++++++++++++++++++ 
>  arch/powerpc/boot/treeboot-sequoia.c |   27 ++++

Is treeboot-* really needed on Sequoia? From my understanding this is only 
needed for platforms using OpenBIOS as bootloader.

>  5 files changed, 297 insertions(+), 2 deletions(-)
>
> diff -ruN linux.orig/arch/powerpc/boot/44x.h linux/arch/powerpc/boot/44x.h
> --- linux.orig/arch/powerpc/boot/44x.h	2007-07-27 20:37:10.000000000 +0400
> +++ linux/arch/powerpc/boot/44x.h	2007-07-27 20:44:26.000000000 +0400
> @@ -15,5 +15,6 @@
>
>  void ibm44x_dbcr_reset(void);
>  void ebony_init(void *mac0, void *mac1);
> +void sequoia_init(void *mac0, void *mac1);
>
>  #endif /* _PPC_BOOT_44X_H_ */
> diff -ruN linux.orig/arch/powerpc/boot/cuboot-sequoia.c
> linux/arch/powerpc/boot/cuboot-sequoia.c ---
> linux.orig/arch/powerpc/boot/cuboot-sequoia.c	1970-01-01 03:00:00.000000000
> +0300 +++ linux/arch/powerpc/boot/cuboot-sequoia.c	2007-07-27
> 20:44:26.000000000 +0400 @@ -0,0 +1,31 @@
> +/*
> + * Old U-boot compatibility for Sequoia
> + *
> + * Based on Ebony code by David Gibson <david@gibson.dropbear.id.au>
> + *
> + * Copyright 2007 David Gibson, IBM Corporatio.
> + *   Based on cuboot-83xx.c, which is:
> + * Copyright (c) 2007 Freescale Semiconductor, Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License version 2 as
> published + * by the Free Software Foundation.
> + */
> +
> +#include "ops.h"
> +#include "stdio.h"
> +#include "44x.h"
> +#include "cuboot.h"
> +
> +#define TARGET_4xx
> +#define TARGET_44x
> +#include "ppcboot.h"
> +
> +static bd_t bd;
> +
> +void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
> +                   unsigned long r6, unsigned long r7)
> +{
> +	CUBOOT_INIT();
> +	sequoia_init(&bd.bi_enetaddr, &bd.bi_enet1addr);
> +}
> diff -ruN linux.orig/arch/powerpc/boot/Makefile
> linux/arch/powerpc/boot/Makefile ---
> linux.orig/arch/powerpc/boot/Makefile	2007-07-27 20:37:10.000000000 +0400
> +++ linux/arch/powerpc/boot/Makefile	2007-07-27 20:44:26.000000000 +0400 @@
> -44,10 +44,11 @@
>  src-wlib := string.S crt0.S stdio.c main.c flatdevtree.c
> flatdevtree_misc.c \ ns16550.c serial.c simple_alloc.c div64.S util.S \
>  		gunzip_util.c elf_util.c $(zlib) devtree.c oflib.c ofconsole.c \
> -		44x.c ebony.c mv64x60.c mpsc.c mv64x60_i2c.c cuboot.c
> +		44x.c ebony.c mv64x60.c mpsc.c mv64x60_i2c.c cuboot.c \
> +		sequoia.c
>  src-plat := of.c cuboot-83xx.c cuboot-85xx.c holly.c \
>  		cuboot-ebony.c treeboot-ebony.c prpmc2800.c \
> -		ps3-head.S ps3-hvcall.S ps3.c
> +		ps3-head.S ps3-hvcall.S ps3.c treeboot-sequoia.c cuboot-sequoia.c
>  src-boot := $(src-wlib) $(src-plat) empty.c
>
>  src-boot := $(addprefix $(obj)/, $(src-boot))
> @@ -142,6 +143,7 @@
>  image-$(CONFIG_PPC_83xx)		+= cuImage.83xx
>  image-$(CONFIG_PPC_85xx)		+= cuImage.85xx
>  image-$(CONFIG_EBONY)			+= treeImage.ebony cuImage.ebony
> +image-$(CONFIG_SEQUOIA)			+= treeImage.sequoia cuImage.sequoia
>  endif
>
>  # For 32-bit powermacs, build the COFF and miboot images
> diff -ruN linux.orig/arch/powerpc/boot/sequoia.c
> linux/arch/powerpc/boot/sequoia.c ---
> linux.orig/arch/powerpc/boot/sequoia.c	1970-01-01 03:00:00.000000000 +0300
> +++ linux/arch/powerpc/boot/sequoia.c	2007-07-27 20:59:09.000000000 +0400
> @@ -0,0 +1,234 @@
> +/*
> + * Based on Bamboo code by Josh Boyer <jwboyer@linux.vnet.ibm.com>
> + * Copyright IBM Corporation, 2007
> + *
> + * Based on ebony wrapper:
> + * Copyright 2007 David Gibson, IBM Corporation.
> + *
> + * Clocking code based on code by:
> + * Stefan Roese <sr@denx.de>
> + *
> + * 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; version 2 of the License
> + */
> +#include <stdarg.h>
> +#include <stddef.h>
> +#include "types.h"
> +#include "elf.h"
> +#include "string.h"
> +#include "stdio.h"
> +#include "page.h"
> +#include "ops.h"
> +#include "dcr.h"
> +#include "44x.h"
> +
> +extern char _dtb_start[];
> +extern char _dtb_end[];
> +
> +static u8 *sequoia_mac0, *sequoia_mac1;
> +
> +#define SPRN_CCR1 0x378
> +void ibm440ep_fixup_clocks(unsigned int sysclk, unsigned int ser_clk)
> +{
> +	u32 cpu, plb, opb, ebc, tb, uart0, m, vco;
> +	u32 reg;
> +	u32 fwdva, fwdvb, fbdv, lfbdv, opbdv0, perdv0, spcid0, prbdv0, tmp;
> +
> +	mtdcr(DCRN_CPR0_ADDR, CPR0_PLLD0);
> +	reg = mfdcr(DCRN_CPR0_DATA);

How about adding mfcpr functions to access the CPR regs. Makes the source 
better readable:

static inline u32 mfcpr(u32 reg)
{
	mtdcr(DCRN_CPR0_ADDR, reg);
	return mfdcr(DCRN_CPR0_DATA);
}

> +	tmp = (reg & 0x000F0000) >> 16;
> +	fwdva = tmp ? tmp : 16;
> +	tmp = (reg & 0x00000700) >> 8;
> +	fwdvb = tmp ? tmp : 8;
> +	tmp = (reg & 0x1F000000) >> 24;
> +	fbdv = tmp ? tmp : 32;
> +	lfbdv = (reg & 0x0000007F);
> +
> +	mtdcr(DCRN_CPR0_ADDR, CPR0_OPBD0);
> +	reg = mfdcr(DCRN_CPR0_DATA);
> +	tmp = (reg & 0x03000000) >> 24;
> +	opbdv0 = tmp ? tmp : 4;
> +
> +	mtdcr(DCRN_CPR0_ADDR, CPR0_PERD0);
> +	reg = mfdcr(DCRN_CPR0_DATA);
> +	tmp = (reg & 0x07000000) >> 24;
> +	perdv0 = tmp ? tmp : 8;
> +
> +	mtdcr(DCRN_CPR0_ADDR, CPR0_PRIMBD0);
> +	reg = mfdcr(DCRN_CPR0_DATA);
> +	tmp = (reg & 0x07000000) >> 24;
> +	prbdv0 = tmp ? tmp : 8;
> +
> +	mtdcr(DCRN_CPR0_ADDR, CPR0_SCPID);
> +	reg = mfdcr(DCRN_CPR0_DATA);
> +	tmp = (reg & 0x03000000) >> 24;
> +	spcid0 = tmp ? tmp : 4;
> +
> +	/* Calculate M */
> +	mtdcr(DCRN_CPR0_ADDR, CPR0_PLLC0);
> +	reg = mfdcr(DCRN_CPR0_DATA);
> +	tmp = (reg & 0x03000000) >> 24;
> +	if (tmp == 0) { /* PLL output */
> +		tmp = (reg & 0x20000000) >> 29;
> +		if (!tmp) /* PLLOUTA */
> +			m = fbdv * lfbdv * fwdva;
> +		else
> +			m = fbdv * lfbdv * fwdvb;
> +	}
> +	else if (tmp == 1) /* CPU output */
> +		m = fbdv * fwdva;
> +	else
> +		m = perdv0 * opbdv0 * fwdvb;
> +
> +	vco = (m * sysclk) + (m >> 1);
> +	cpu = vco / fwdva;
> +	plb = vco / fwdvb / prbdv0;
> +	opb = plb / opbdv0;
> +	ebc = plb / perdv0;
> +
> +	/* FIXME */
> +	uart0 = ser_clk;
> +
> +	/* Figure out timebase.  Either CPU or default TmrClk */
> +	asm volatile (
> +			"mfspr	%0,%1\n"
> +			:
> +			"=&r"(reg) : "i"(SPRN_CCR1));
> +	if (reg & 0x0080)
> +		tb = 25000000; /* TmrClk is 25MHz */
> +	else
> +		tb = cpu;
> +
> +	dt_fixup_cpu_clocks(cpu, tb, 0);
> +	dt_fixup_clock("/plb", plb);
> +	dt_fixup_clock("/plb/opb", opb);
> +	dt_fixup_clock("/plb/opb/ebc", ebc);
> +	dt_fixup_clock("/plb/opb/serial@ef600300", uart0);
> +	dt_fixup_clock("/plb/opb/serial@ef600400", uart0);
> +	dt_fixup_clock("/plb/opb/serial@ef600500", uart0);
> +	dt_fixup_clock("/plb/opb/serial@ef600600", uart0);
> +}
> +
> +
> +/*
> + * 440EPx DDR1/2 memory controller code
> + * TODO: move to generic 44x code
> + */
> +
> +/* DDR0_02 */
> +#define DDR_START		0x1
> +#define DDR_START_SHIFT		0
> +#define DDR_MAX_CS_REG		0x3
> +#define DDR_MAX_CS_REG_SHIFT	24
> +#define DDR_MAX_COL_REG		0xf
> +#define DDR_MAX_COL_REG_SHIFT	16
> +#define DDR_MAX_ROW_REG		0xf
> +#define DDR_MAX_ROW_REG_SHIFT	8
> +/* DDR0_08 */
> +#define DDR_DDR2_MODE		0x1
> +#define DDR_DDR2_MODE_SHIFT	0
> +/* DDR0_10 */
> +#define DDR_CS_MAP		0x3
> +#define DDR_CS_MAP_SHIFT	8
> +/* DDR0_14 */
> +#define DDR_REDUC		0x1
> +#define DDR_REDUC_SHIFT		16
> +/* DDR0_42 */
> +#define DDR_APIN		0x7
> +#define DDR_APIN_SHIFT		24
> +/* DDR0_43 */
> +#define DDR_COL_SZ		0x7
> +#define DDR_COL_SZ_SHIFT	8
> +#define DDR_BANK8		0x1
> +#define DDR_BANK8_SHIFT		0
> +
> +#define DDR_GET_VAL(val, mask, shift)	(((val) >> (shift)) & (mask))
> +
> +static void ibm440epx_fixup_memsize(void)
> +{
> +	unsigned long val, max_cs, max_col, max_row;
> +	unsigned long cs, col, row, bank, dpath;
> +	unsigned long memsize;
> +
> +	mtdcr(DCRN_SDRAM0_CFGADDR, 2);
> +	val = mfdcr(DCRN_SDRAM0_CFGDATA);

Again, mfsdram() functions would be handy here.

> +	if (!DDR_GET_VAL(val, DDR_START, DDR_START_SHIFT))
> +		fatal("DDR controller is not initialized\n");
> +
> +	/* get maximum cs col and row values */
> +	max_cs  = DDR_GET_VAL(val, DDR_MAX_CS_REG, DDR_MAX_CS_REG_SHIFT);
> +	max_col = DDR_GET_VAL(val, DDR_MAX_COL_REG, DDR_MAX_COL_REG_SHIFT);
> +	max_row = DDR_GET_VAL(val, DDR_MAX_ROW_REG, DDR_MAX_ROW_REG_SHIFT);
> +
> +	/* get CS value */
> +	mtdcr(DCRN_SDRAM0_CFGADDR, 10);
> +	val = mfdcr(DCRN_SDRAM0_CFGDATA);
> +
> +	val = DDR_GET_VAL(val, DDR_CS_MAP, DDR_CS_MAP_SHIFT);
> +	cs = 0;
> +	while (val) {
> +		if (val && 0x1)
> +			cs++;
> +		val = val >> 1;
> +	}
> +
> +	if (!cs)
> +		fatal("No memory installed\n");
> +	if (cs > max_cs)
> +		fatal("DDR wrong CS configuration\n");
> +
> +	/* get data path bytes */
> +	mtdcr(DCRN_SDRAM0_CFGADDR, 14);
> +	val = mfdcr(DCRN_SDRAM0_CFGDATA);
> +
> +	if (DDR_GET_VAL(val, DDR_REDUC, DDR_REDUC_SHIFT))
> +		dpath = 8; /* 64 bits */
> +	else
> +		dpath = 4; /* 32 bits */
> +
> +	/* get adress pins (rows) */
> +	mtdcr(DCRN_SDRAM0_CFGADDR, 42);
> +	val = mfdcr(DCRN_SDRAM0_CFGDATA);
> +
> +	row = DDR_GET_VAL(val, DDR_APIN, DDR_APIN_SHIFT);
> +	if (row > max_row)
> +		fatal("DDR wrong APIN configuration\n");
> +	row = max_row - row;
> +
> +	/* get collomn size and banks */
> +	mtdcr(DCRN_SDRAM0_CFGADDR, 43);
> +	val = mfdcr(DCRN_SDRAM0_CFGDATA);
> +
> +	col = DDR_GET_VAL(val, DDR_COL_SZ, DDR_COL_SZ_SHIFT);
> +	if (col > max_col)
> +		fatal("DDR wrong COL configuration\n");
> +	col = max_col - col;
> +
> +	if (DDR_GET_VAL(val, DDR_BANK8, DDR_BANK8_SHIFT))
> +		bank = 8; /* 8 banks */
> +	else
> +		bank = 4; /* 4 banks */
> +
> +	memsize = cs * (1 << (col+row)) * bank * dpath;
> +	dt_fixup_memory(0, memsize);
> +}
> +
> +static void sequoia_fixups(void)
> +{
> +	unsigned long sysclk = 33333333;

Blank line after variable declaration please.

> +	ibm440ep_fixup_clocks(sysclk, 11059200);
> +	ibm4xx_fixup_ebc_ranges("/plb/opb/ebc");
> +	ibm440epx_fixup_memsize();
> +	dt_fixup_mac_addresses(sequoia_mac0, sequoia_mac1);
> +}
> +
> +void sequoia_init(void *mac0, void *mac1)
> +{
> +	platform_ops.fixups = sequoia_fixups;
> +	platform_ops.exit = ibm44x_dbcr_reset;
> +	sequoia_mac0 = mac0;
> +	sequoia_mac1 = mac1;
> +	ft_init(_dtb_start, 0, 32);
> +	serial_console_init();
> +}
> diff -ruN linux.orig/arch/powerpc/boot/treeboot-sequoia.c
> linux/arch/powerpc/boot/treeboot-sequoia.c ---
> linux.orig/arch/powerpc/boot/treeboot-sequoia.c	1970-01-01
> 03:00:00.000000000 +0300 +++
> linux/arch/powerpc/boot/treeboot-sequoia.c	2007-07-27 20:44:26.000000000
> +0400 @@ -0,0 +1,27 @@
> +/*
> + * Based on Bamboo code by Josh Boyer <jwboyer@linux.vnet.ibm.com>
> + * Copyright IBM Corporation, 2007
> + *
> + * Based on ebony wrapper:
> + * Copyright 2007 David Gibson, IBM Corporation.
> + *
> + * 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; version 2 of the License
> + */
> +#include "ops.h"
> +#include "stdio.h"
> +#include "44x.h"
> +
> +extern char _end[];
> +
> +BSS_STACK(4096);
> +
> +void platform_init(void)
> +{
> +	unsigned long end_of_ram = 0x10000000;
> +	unsigned long avail_ram = end_of_ram - (unsigned long)_end;
> +
> +	simple_alloc_init(_end, avail_ram, 32, 64);
> +	sequoia_init(NULL, NULL);
> +}
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev

Best regards,
Stefan

=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80  Email: office@denx.de
=====================================================================

^ permalink raw reply

* Re: Attempt at addressing head*.S for modpost warnings
From: Kumar Gala @ 2007-07-31  4:29 UTC (permalink / raw)
  To: Stephen Rothwell; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <20070731115047.8b88cb78.sfr@canb.auug.org.au>


On Jul 30, 2007, at 8:50 PM, Stephen Rothwell wrote:

> Hi Kumar,
>
> [sorry for the slow reply]
>
> On Wed, 25 Jul 2007 01:49:04 -0500 (CDT) Kumar Gala  
> <galak@kernel.crashing.org> wrote:
>>
>> Paul said you were looking into this issue as well.  Wanted to  
>> post what I
>> did on ppc32/e500 as a start for you to look at.  I think the  
>> other ppc32
>> head*.S can follow the same pattern if we like this.  However,  
>> wasn't sure
>> how to do _ENTRY() for ppc64.
>
> What I have done so far is to put some peices of the asm code into
> the .text.init.refok section (see the _INIT_STATIC macro in asm/ 
> ppc_asm.h
> in the current kernel).  I was hoping to separate some of the asm  
> into a
> new file (init_64.S) that would contain this and other code in
> the .init.text section.  That is currently not working (ld crashed on
> me :-)).
>
> Even if you create a .text.head, you will need to teach modpost  
> about it.

Modpost is already aware of .text.head.  Its used on x86 and a few  
other archs today.

- k

^ permalink raw reply

* Re: ml403 ac97 driver
From: Qin Lin @ 2007-07-31  4:22 UTC (permalink / raw)
  To: linuxppc-embedded
In-Reply-To: <11859770.post@talk.nabble.com>


HI ALL
I have compile the driver and test it with the help of Joachim.

1.add the lm4550 driver to kernel source
(someboby may can add them as a patch to kernel source)

#cp -r ml403_ac97cr $(KERNEL)/sound/drivers/
#vi $(KERNEL)/sound/drivers/Makefile
=add=
obj-$(CONFIG_SND_ML403_AC97)	+=ml403_ac97cr/
#vi $(KERNEL)/sound/drivers/
=add=
config SND_ML403_AC97
        tristate "ml403 ac97 codec(LM4550)"
        depends on SND
        select SND_AC97_CODEC
        help
          ml403 ac97 codec added by Joachim
          enjoy it !

#vi $(KERNEL)/sound/drivers/ml403_ac97cr/Makefile
obj-$(CONFIG_SND_ML403_AC97) += ml403_ac97cr.o

#make xconfig 
you can see the ml403_ac97cr in SOUND ALSA 

2.cross-compile alsa-lib
I use ELDK4.0 to install cross compile in XILINX ML403.
$echo $CROSS_COMPILE
 ppc_4xx-
$export CC=${CROSS_COMPILE}gcc
$export CPP=${CROSS_COMPILE}cpp
$export CXX=${CROSS_COMPILE}g++
$export LDD=${CROSS_COMPILE}ldd
$export AR=${CROSS_COMPILE}ar
$export LD=${CROSS_COMPILE}ld
$export RANLIB=${CROSS_COMPILE}ranlib
$export STRIP=${CROSS_COMPILE}strip
$cd ${ALSA-LIB-SOURCE}
$./configure --host=ppc-4xx-linux --target=ppc  --prefix=/usr
$make install  DESTDIR=${ALSA}

ps:ALSA lib will be install in path ${ALSA}/usr.Here use prefix=/usr is
important,do not change to another 
path. Otherwise in the target board alsa will not find the config file by
default.You can use DESTDIR to set the lib path .

3.cross-compile alsa-utils
$export CC=${CROSS_COMPILE}gcc
$export CPP=${CROSS_COMPILE}cpp
$export CXX=${CROSS_COMPILE}g++
$export LDD=${CROSS_COMPILE}ldd
$export AR=${CROSS_COMPILE}ar
$export LD=${CROSS_COMPILE}ld
$export RANLIB=${CROSS_COMPILE}ranlib
$export STRIP=${CROSS_COMPILE}strip
$export CFLAGS="-I${ALSA}/usr/include  -L${ALSA}/usr/lib"

$cd ${ALSA-UTILS-SOURCE}
$./configure --host=ppc-4xx-linux --target=ppc  --prefix=/usr --disable-nls 
$make install  DESTDIR=${ALSA}

ps:use --disable-nls,otherwise there is an error about LC_ALL not defined.

3.copy the ${ALSA}/usr/* to the target rootfile /usr/  ,so you can use the
alsa utils.

4.insmod the drive module and create device node ,use 
#aplay music.wav
to test the drive.
-- 
View this message in context: http://www.nabble.com/Re%3A-ml403-ac97-driver-tf4164866.html#a11918008
Sent from the linuxppc-embedded mailing list archive at Nabble.com.

^ permalink raw reply

* RE: [PATCH 0/4][RFC] lro: Generic Large Receive Offload for TCP traffic
From: Leonid Grossman @ 2007-07-31  3:58 UTC (permalink / raw)
  To: Andrew Gallatin, Linas Vepstas
  Cc: Thomas Klein, Jeff Garzik, Jan-Bernd Themann, netdev,
	linux-kernel, Christoph Raisch, linux-ppc, Jan-Bernd Themann,
	Marcus Eder, Stefan Roscher, David Miller
In-Reply-To: <46AE232F.3080409@myri.com>



> -----Original Message-----
> From: netdev-owner@vger.kernel.org [mailto:netdev-
> owner@vger.kernel.org] On Behalf Of Andrew Gallatin
> Sent: Monday, July 30, 2007 10:43 AM
> To: Linas Vepstas
> Cc: Jan-Bernd Themann; netdev; Thomas Klein; Jeff Garzik; Jan-Bernd
> Themann; linux-kernel; linux-ppc; Christoph Raisch; Marcus Eder;
Stefan
> Roscher; David Miller
> Subject: Re: [PATCH 0/4][RFC] lro: Generic Large Receive Offload for
> TCP traffic
>=20
>=20
> Here is a quick reply before something more official can
> be written up:
>=20
> Linas Vepstas wrote:
>=20
>  > -- what is LRO?
>=20
> Large Receive Offload
>=20
>  > -- Basic principles of operation?
>=20
> LRO is analogous to a receive side version of TSO.  The NIC (or
> driver) merges several consecutive segments from the same connection,
> fixing up checksums, etc.  Rather than up to 45 separate 1500 byte
> frames (meaning up to 45 trips through the network stack), the driver
> merges them into one 65212 byte frame.  It currently works only
> with TCP over IPv4.
>=20
> LRO was, AFAIK, first though of by Neterion.  They had a paper about
> it at OLS2005.
> http://www.linuxinsight.com/files/ols2005/grossman-reprint.pdf
>=20
>  > -- Can I use it in my driver?
>=20
> Yes, it can be used in any driver.
>=20
>  > -- Does my hardware have to have some special feature before I can
> use it?
>=20
> No.

Ditto. LRO hw assists (or full LRO offload, meaning that the merge
happens in the ASIC but the merge criteria are set by the host) are
quite beneficial, especially as the number of LRO connections gets very
large (Neterion has IP around fw/hw LRO and will release full hw LRO
offload in the next ASIC), but as Andrew indicated sw-only LRO
implementation can be done for any NIC and provides good results -
especially for non-jumbo workloads.=20

>=20
>  > -- What sort of performance improvement does it provide?
Throughput?
>  >    Latency? CPU usage? How does it affect DMA allocation? Does it
>  >    improve only a certain type of traffic (large/small packets,
> etc.)
>=20
> The benefit is directly proportional to the packet rate.
>=20
> See my reply to the previous RFC for performance information.  The
> executive summary is that for the myri10ge 10GbE driver on low end
> hardware with 1500b frames, I've seen it increase throughput by a
> factor of nearly 2.5x, while at the same time reducing CPU utilization
> by 17%.  The affect for jumbo frames is less dramatic, but still
> impressive (1.10x, 14% CPU reduction)
>=20
> You can achieve better speedups if your driver receives into
> high-order pages.
>=20
>  > -- Example code? What's the API? How should my driver use it?
>=20
> The 3/4 in this patch showed an example of converting a driver
> to use LRO for skb based receive buffers.   I'm working on
> a patch for myri10ge that shows how you would use it in a driver
> which receives into pages.
>=20
> Cheers,
>=20
> Drew
> -
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* RE: [patch][0/5] powerpc V2 : Add support to fully comply with IEEE-754 standard
From: Zhu Ebony-r57400 @ 2007-07-31  3:36 UTC (permalink / raw)
  To: Sergei Shtylyov; +Cc: linuxppc-dev, paulus
In-Reply-To: <46ADFC36.5060709@ru.mvista.com>

 Hi Sergei,

I did some further tests and some development work in past several
months,
but due to project schedule and limited bandwidth, no patches can be
submitted
to the list by now. Anyway, I will keep you and the community updated
once there
is some progress.

Thanks.

B.R.
Ebony

> -----Original Message-----
> From: Sergei Shtylyov [mailto:sshtylyov@ru.mvista.com]=20
> Sent: Monday, July 30, 2007 10:57 PM
> To: Zhu Ebony-r57400
> Cc: Kumar Gala; linuxppc-dev@ozlabs.org; paulus@samba.org
> Subject: Re: [patch][0/5] powerpc V2 : Add support to fully=20
> comply with IEEE-754 standard
>=20
> Hello.
>=20
> Zhu Ebony-r57400 wrote:
>=20
> >>>>>>Did you end up getting testfloat running?  I'd like to see some=20
> >>>>>>testing results before accepting these patches.  I=20
> think estfloat=20
> >>>>>>is our best bet at this point.
>=20
> >>>>>Hi Kumar,
>=20
> >>>>>I looked into the testfloat suit, and found all the=20
> instructions it=20
> >>>>>tests (more than 50)should be implemented based on ASM.
>=20
> >>>>Don't follow?  Can't you build it with the e500 compiler?
>=20
> >>>The TestFloat suite provided the target of 386-Win32-gcc and=20
> >>>SPARC-Solaris-gcc only, and a template for user to porting his own=20
> >>>processor. Some general instructions are implemented in C,=20
> but some=20
> >>>CPU specific instructions like evfsmul need to be implemented=20
> >>>assemblely. To build it with e500 compiler we still Have=20
> some porting=20
> >>>work to do.
>=20
> >>I wouldn't worry too much about the vector forms.  If the scalar=20
> >>single fp and double fp test out ok the vectors are pretty much=20
> >>similar enough.
>=20
> >>Lets just get the scalar versions tested and work out any issues=20
> >>there.
>=20
> > OK, I will focus on scalar SFPF and DPFP versions first.
>=20
>     Any progress with this patchset?
>=20
> WBR, Sergei
>=20

^ permalink raw reply

* Re: Attempt at addressing head*.S for modpost warnings
From: Stephen Rothwell @ 2007-07-31  1:50 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <Pine.LNX.4.64.0707250147150.9086@blarg.am.freescale.net>

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

Hi Kumar,

[sorry for the slow reply]

On Wed, 25 Jul 2007 01:49:04 -0500 (CDT) Kumar Gala <galak@kernel.crashing.org> wrote:
>
> Paul said you were looking into this issue as well.  Wanted to post what I
> did on ppc32/e500 as a start for you to look at.  I think the other ppc32
> head*.S can follow the same pattern if we like this.  However, wasn't sure
> how to do _ENTRY() for ppc64.

What I have done so far is to put some peices of the asm code into
the .text.init.refok section (see the _INIT_STATIC macro in asm/ppc_asm.h
in the current kernel).  I was hoping to separate some of the asm into a
new file (init_64.S) that would contain this and other code in
the .init.text section.  That is currently not working (ld crashed on
me :-)).

Even if you create a .text.head, you will need to teach modpost about it.
-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

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

^ permalink raw reply

* Re: [PATCH 0/4][RFC] lro: Generic Large Receive Offload for TCP traffic
From: Jeff Garzik @ 2007-07-31  0:00 UTC (permalink / raw)
  To: David Miller
  Cc: tklein, themann, netdev, linux-kernel, raisch, linuxppc-dev,
	ossthema, meder, gallatin, stefan.roscher
In-Reply-To: <20070730.154332.72713181.davem@davemloft.net>

David Miller wrote:
> From: Jeff Garzik <jeff@garzik.org>
> Date: Mon, 30 Jul 2007 12:17:58 -0400
> 
>> David, thoughts on merging?  I'm not We could stick this into your tree 
>> or mine.  Whether yours or mine, I would like to keep the driver and 
>> net-core patches together in the same git tree.
> 
> No objections and I'll stick it into my net-2.6.24 tree once I cut
> that, I'll have the NAPI stuff in there too so I'll keep these two
> merge nightmares out of your hair :-)

Works for me.

Thanks,

	Jeff

^ permalink raw reply

* Re: [PATCH 2/2] powerpc: MPC85xx EDAC device driver
From: Dave Jiang @ 2007-07-30 22:58 UTC (permalink / raw)
  To: Linas Vepstas; +Cc: linuxppc-dev, bluesmoke-devel, norsk5
In-Reply-To: <20070730214404.GE4884@austin.ibm.com>

Linas Vepstas wrote:
> On Mon, Jul 30, 2007 at 01:17:40PM -0700, Dave Jiang wrote:
>> Arnd Bergmann wrote:
>>> The best solution may be to look at how it's structured at the
>>> register level. If the PCI EDAC registers are implemented separately
>>> from the regular PCI registers, a device tree entry would be appropriate.
>>> If not, your idea of registering a platform_device from fsl_add_bridge
>>> is probably more sensible.
>>>
>> We can probably do either. From looking at the 8560 and 8548 manuals, the PCI
>> error registers are 0xe00 offset of the start of PCI registers. For example,
>> the PCI registers would start at 0x8000 offset. And the PCI error registers
>> would be at 0xe00 offset from there and would be the very last block of
>> registers. 
> 
> Anywhere I can easily get an overview of these "PCI error registers"?

http://www.freescale.com/files/32bit/doc/ref_manual/MPC8548ERM.pdf?fsrch=1
Page 966. Section 16.3.1.4.
Is this what you mean?

^ permalink raw reply

* Re: [PATCH 2/2] powerpc: MPC85xx EDAC device driver
From: Doug Thompson @ 2007-07-30 22:47 UTC (permalink / raw)
  To: Linas Vepstas, Dave Jiang
  Cc: linuxppc-dev, norsk5, Arnd Bergmann, bluesmoke-devel
In-Reply-To: <20070730214404.GE4884@austin.ibm.com>


--- Linas Vepstas <linas@austin.ibm.com> wrote:

> On Mon, Jul 30, 2007 at 01:17:40PM -0700, Dave Jiang wrote:
> > Arnd Bergmann wrote:
> > > The best solution may be to look at how it's structured at the
> > > register level. If the PCI EDAC registers are implemented separately
> > > from the regular PCI registers, a device tree entry would be appropriate.
> > > If not, your idea of registering a platform_device from fsl_add_bridge
> > > is probably more sensible.
> > > 
> > 
> > We can probably do either. From looking at the 8560 and 8548 manuals, the PCI
> > error registers are 0xe00 offset of the start of PCI registers. For example,
> > the PCI registers would start at 0x8000 offset. And the PCI error registers
> > would be at 0xe00 offset from there and would be the very last block of
> > registers. 
> 
> Anywhere I can easily get an overview of these "PCI error registers"?
> 
> Also: please note that the linux kernel has a pci error recovery
> mechanism built in; its used by pseries and PCI-E. I'm not clear
> on what any of this has to do with EDAC, which I thought was supposed 
> to be for RAM only. (The EDAC project once talked about doing pci error 
> recovery, but that was years ago, and there is a separate system for
> that, now.)

no, edac can/does harvest PCI bus errors, via polling and other hardware error detectors.

The pci error recovery added a couple of NEW device callback functions in the driver interface, 
which the bus layer can call to notify drivers that a PCI bus error occurred. Then the driver can
do some action on the event.

But at the current time, few PCI device drivers initialize those callback functions and
thus errors are lost and some IO transactions fail.

Over time, as drivers get updated (might take some time) then drivers
can take some sort of action FOR THEMSELVES

Yet, there is no tracking of errors - except for a log message in the log file.

There is NO meter on frequency of errors, etc. One must grep the log file and that is not a very
cycle friendly mechanism.

The reason I added PCI parity/error device scanning, was that when I was at Linux Networx, we had
parity errors on the PCI-X bus, but didn't know the cause.  After we discovered that a simple
PCI-X riser card had manufacturing problems (quality) and didn't drive lines properly, it caused
parity errors. This feature allowed us to track nodes that were having parity problems, but we had
no METER to know it.

Recovery is a good thing, BUT how do you know you having LOTS of errors/recovery events? You need
a meter. EDAC provides that METER

I met with Yanmin Zhang of Intel at OLS after his paper presentation on PCI Express Advanced Error
Reporting in the Kernel, and we talked about this same thing. I am talking with him on having the
recovery code present information into EDAC sysfs area. (hopefully, anyway)

The recovery generates log messages BUT having to periodically 'grep' the log file looking for
errors is not a good use of CPU cycles. grep once for a count and then grep later for a count and
then compare the counts for a delta count per unit time. ugly.

The EDAC solution is to be able to have a Listener thread in user space that can be notified (via
poll()) that an event has occurred.

There are more than one consumer (error recover) of error events:

1) driver recovery after a transaction (which is the recovery consumer above)
2) Management agents for health of a node
3) Maintainance agents for predictive component replacement

Rates of change of errors can be gathered as well.

EDAC allows for presentation of error counts via sysfs entries, from which user space
programs can harvest for over-time profiling

We have MEMORY (edac_mc) devices for chipsets now, but via the new edac_device class, such things
as ECC error tracking on DMA error checkers, FABRIC switchs, L1 and L2 cache ECC events, core CPU
data ECC checkers, etc can be done. I have an out of kernel tree MIPS driver do just this. Other
types of harvesters can be generated as well for other and/or new hardware error detectors.

doug thompson

> 
> --linas
> 
> 
> 

^ permalink raw reply

* Re: [PATCH 0/4][RFC] lro: Generic Large Receive Offload for TCP traffic
From: David Miller @ 2007-07-30 22:43 UTC (permalink / raw)
  To: jeff
  Cc: tklein, themann, netdev, linux-kernel, raisch, linuxppc-dev,
	ossthema, meder, gallatin, stefan.roscher
In-Reply-To: <46AE0F36.8030605@garzik.org>

From: Jeff Garzik <jeff@garzik.org>
Date: Mon, 30 Jul 2007 12:17:58 -0400

> David, thoughts on merging?  I'm not We could stick this into your tree 
> or mine.  Whether yours or mine, I would like to keep the driver and 
> net-core patches together in the same git tree.

No objections and I'll stick it into my net-2.6.24 tree once I cut
that, I'll have the NAPI stuff in there too so I'll keep these two
merge nightmares out of your hair :-)

^ permalink raw reply

* Re: [PATCH 2/2] powerpc: MPC85xx EDAC device driver
From: Linas Vepstas @ 2007-07-30 21:44 UTC (permalink / raw)
  To: Dave Jiang; +Cc: linuxppc-dev, norsk5, Arnd Bergmann, bluesmoke-devel
In-Reply-To: <46AE4764.7020101@mvista.com>

On Mon, Jul 30, 2007 at 01:17:40PM -0700, Dave Jiang wrote:
> Arnd Bergmann wrote:
> > The best solution may be to look at how it's structured at the
> > register level. If the PCI EDAC registers are implemented separately
> > from the regular PCI registers, a device tree entry would be appropriate.
> > If not, your idea of registering a platform_device from fsl_add_bridge
> > is probably more sensible.
> > 
> 
> We can probably do either. From looking at the 8560 and 8548 manuals, the PCI
> error registers are 0xe00 offset of the start of PCI registers. For example,
> the PCI registers would start at 0x8000 offset. And the PCI error registers
> would be at 0xe00 offset from there and would be the very last block of
> registers. 

Anywhere I can easily get an overview of these "PCI error registers"?

Also: please note that the linux kernel has a pci error recovery
mechanism built in; its used by pseries and PCI-E. I'm not clear
on what any of this has to do with EDAC, which I thought was supposed 
to be for RAM only. (The EDAC project once talked about doing pci error 
recovery, but that was years ago, and there is a separate system for
that, now.)

--linas

^ permalink raw reply

* Re: [PATCH 0/4][RFC] lro: Generic Large Receive Offload for TCP traffic
From: Andrew Gallatin @ 2007-07-30 20:32 UTC (permalink / raw)
  To: Jan-Bernd Themann
  Cc: Thomas Klein, Jeff Garzik, Jan-Bernd Themann, netdev,
	linux-kernel, linux-ppc, Christoph Raisch, Marcus Eder,
	Stefan Roscher, David Miller
In-Reply-To: <200707301724.33865.ossthema@de.ibm.com>

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

Jan-Bernd Themann wrote:
> Hi,
> 
> this patch set contains the latest generic LRO code, a Kconfig / Makefile
> and an eHEA patch demonstrating how the "aggregate SKB" interface has to
> to be used.
> Drew, could you provide a patch for the myri10ge driver to show how the
> "receive in page" interface works?

Hi,

Thank you for the many fixes, and especially for the counters!

I was working on testing the myri10ge patch, and I ran into a few
problems.  I've attached a patch to inet_lro.c to fix some of them,
and a patch to myri10ge.c to show how to use the page based
interface.  Both patches are signed off by Andrew Gallatin
<gallatin@myri.com>

First, the LRO_MAX_PG_HLEN is still a problem.  Minimally sized 60
byte frames still cause problems in lro_gen_skb due to skb->len
going negative.  Fixed in the attached patch.  It may be simpler
to just drop LRO_MAX_PG_HLEN to ETH_ZLEN, but I'm not sure if
that is enough.  Are there "smart" NICs which might chop off padding
themselves?

Second, you still need to set skb->ip_summed = CHECKSUM_UNNECESSARY
when modified packets are flushed, else the stack will see bad
checksums for packets from CHECKSUM_COMPLETE drivers using the
skb interface.  Fixed in the attached patch.

Third, for some reason I have yet to figure out, this version of the
patch takes a while to "ramp up", but only when the receiver MTU
is 9000 and the sender MTU is 1500.  If the receiver MTU is also
1500, even a 10 second netperf easily shows line rate.  I don't
see this with our LRO, and I'm so far at a loss to explain it.

Here is the first 3 seconds of  output from a simple program
which diffs the interface counters once / sec.
        Ipkts       IBytes        Opkts       Obytes

rx MTU=9000:
            0            0            0            0
           72        99092           14         1102
          105       158970            7          420
       750324   1135987084        17804      1068240
       814427   1233042478        18529      1111740

<....>

rx MTU=1500
            0            0            0            0
       441344    668180168        13132       788182
       815938   1235328656        18716      1122960
       817698   1237994772        18628      1117680
<.....>

Once it has ramped up, the bandwidth is fine, and there
doesn't seem to be much difference between setting the
receiver MTU to 1500 or 9000.  But it takes a very long
netperf run to overcome the ramp up period.

Fourth, I did some traffic sniffing to try to figure out what's going
on above, and saw tcpdump complain about bad checksums.  Have you tried
running tcpdump -s 65535 -vvv?  Have you also seen bad checksums?
I seem to see this for both page- and skb-based versions of the driver.

Last, the pointer to the TCP header in __lro_proc_segment() in the
unaccelerated vlan hdr case needs to also be offset by vlan_hdr_len
from skb->data.   I've fixed this in the attached patch.



Thanks,

Drew

[-- Attachment #2: inet_lro.diff --]
[-- Type: text/plain, Size: 665 bytes --]

--- linux-2.6.23-rc1.orig/net/ipv4/inet_lro.c	2007-07-30 13:10:49.000000000 -0400
+++ linux-2.6.23-rc1/net/ipv4/inet_lro.c	2007-07-30 15:17:51.000000000 -0400
@@ -126,6 +126,7 @@ static void lro_update_tcp_ip_header(str
 					htons(lro_desc->ip_tot_len) -
 					IP_HDR_LEN(iph), IPPROTO_TCP,
 					lro_desc->data_csum);
+	lro_desc->parent->ip_summed = CHECKSUM_UNNECESSARY;
 }
 
 static __wsum lro_tcp_data_csum(struct iphdr *iph, struct tcphdr *tcph, int len)
@@ -396,6 +397,9 @@ static struct sk_buff *lro_gen_skb(struc
 	if (!skb)
 		return NULL;
 
+	if (hlen > len)
+		hlen = len;
+
 	skb->len = len;
 	skb->data_len = len - hlen;
 	skb->truesize += true_size;

[-- Attachment #3: myri10ge_lro.diff --]
[-- Type: text/plain, Size: 6221 bytes --]

diff -urp a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
--- a/drivers/net/myri10ge/myri10ge.c	2007-07-24 15:57:12.000000000 -0400
+++ b/drivers/net/myri10ge/myri10ge.c	2007-07-30 16:12:06.000000000 -0400
@@ -48,6 +48,7 @@
 #include <linux/etherdevice.h>
 #include <linux/if_ether.h>
 #include <linux/if_vlan.h>
+#include <linux/inet_lro.h>
 #include <linux/ip.h>
 #include <linux/inet.h>
 #include <linux/in.h>
@@ -62,6 +63,8 @@
 #include <linux/io.h>
 #include <linux/log2.h>
 #include <net/checksum.h>
+#include <net/ip.h>
+#include <net/tcp.h>
 #include <asm/byteorder.h>
 #include <asm/io.h>
 #include <asm/processor.h>
@@ -89,6 +92,7 @@ MODULE_LICENSE("Dual BSD/GPL");
 
 #define MYRI10GE_EEPROM_STRINGS_SIZE 256
 #define MYRI10GE_MAX_SEND_DESC_TSO ((65536 / 2048) * 2)
+#define MYRI10GE_MAX_LRO_DESCRIPTORS 8
 
 #define MYRI10GE_NO_CONFIRM_DATA htonl(0xffffffff)
 #define MYRI10GE_NO_RESPONSE_RESULT 0xffffffff
@@ -151,6 +155,8 @@ struct myri10ge_rx_done {
 	dma_addr_t bus;
 	int cnt;
 	int idx;
+	struct net_lro_mgr lro_mgr;
+	struct net_lro_desc lro_desc[MYRI10GE_MAX_LRO_DESCRIPTORS];
 };
 
 struct myri10ge_priv {
@@ -276,6 +282,14 @@ static int myri10ge_debug = -1;	/* defau
 module_param(myri10ge_debug, int, 0);
 MODULE_PARM_DESC(myri10ge_debug, "Debug level (0=none,...,16=all)");
 
+static int myri10ge_lro = 1;
+module_param(myri10ge_lro, int, S_IRUGO);
+MODULE_PARM_DESC(myri10ge_lro, "Enable large receive offload\n");
+
+static int myri10ge_lro_max_pkts = MYRI10GE_LRO_MAX_PKTS;
+module_param(myri10ge_lro_max_pkts, int, S_IRUGO);
+MODULE_PARM_DESC(myri10ge_lro, "Number of LRO packets to be aggregated\n");
+
 static int myri10ge_fill_thresh = 256;
 module_param(myri10ge_fill_thresh, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(myri10ge_fill_thresh, "Number of empty rx slots allowed\n");
@@ -1019,6 +1033,16 @@ myri10ge_rx_done(struct myri10ge_priv *m
 		remainder -= MYRI10GE_ALLOC_SIZE;
 	}
 
+	if (mgp->csum_flag && myri10ge_lro) {
+		rx_frags[0].page_offset += MXGEFW_PAD;
+		rx_frags[0].size -= MXGEFW_PAD;
+		len -= MXGEFW_PAD;
+		lro_receive_frags(&mgp->rx_done.lro_mgr, rx_frags,
+				  len, bytes,
+				  (void *)(unsigned long)csum, csum);
+		return 1;
+	}
+
 	hlen = MYRI10GE_HLEN > len ? len : MYRI10GE_HLEN;
 
 	/* allocate an skb to attach the page(s) to. */
@@ -1137,6 +1161,9 @@ static inline void myri10ge_clean_rx_don
 	mgp->stats.rx_packets += rx_packets;
 	mgp->stats.rx_bytes += rx_bytes;
 
+	if (myri10ge_lro)
+		lro_flush_all(&rx_done->lro_mgr);
+
 	/* restock receive rings if needed */
 	if (mgp->rx_small.fill_cnt - mgp->rx_small.cnt < myri10ge_fill_thresh)
 		myri10ge_alloc_rx_pages(mgp, &mgp->rx_small,
@@ -1378,7 +1405,8 @@ static const char myri10ge_gstrings_stat
 	"dropped_pause", "dropped_bad_phy", "dropped_bad_crc32",
 	"dropped_unicast_filtered", "dropped_multicast_filtered",
 	"dropped_runt", "dropped_overrun", "dropped_no_small_buffer",
-	"dropped_no_big_buffer"
+	"dropped_no_big_buffer", "LRO aggregated", "LRO flushed",
+	"LRO avg aggr", "LRO no_desc"
 };
 
 #define MYRI10GE_NET_STATS_LEN      21
@@ -1444,6 +1472,14 @@ myri10ge_get_ethtool_stats(struct net_de
 	data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_overrun);
 	data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_no_small_buffer);
 	data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_no_big_buffer);
+	data[i++] = mgp->rx_done.lro_mgr.stats.aggregated;
+	data[i++] = mgp->rx_done.lro_mgr.stats.flushed;
+	if (mgp->rx_done.lro_mgr.stats.flushed)
+		data[i++] = mgp->rx_done.lro_mgr.stats.aggregated /
+		    mgp->rx_done.lro_mgr.stats.flushed;
+	else
+		data[i++] = 0;
+	data[i++] = mgp->rx_done.lro_mgr.stats.no_desc;
 }
 
 static void myri10ge_set_msglevel(struct net_device *netdev, u32 value)
@@ -1717,10 +1753,69 @@ static void myri10ge_free_irq(struct myr
 		pci_disable_msi(pdev);
 }
 
+static int
+myri10ge_get_frag_header(struct skb_frag_struct *frag, void **mac_hdr,
+			 void **ip_hdr, void **tcpudp_hdr,
+			 u64 * hdr_flags, void *priv)
+{
+	struct ethhdr *eh;
+	struct vlan_ethhdr *veh;
+	struct iphdr *iph;
+	u8 *va = page_address(frag->page) + frag->page_offset;
+	unsigned long ll_hlen;
+	__wsum csum = (__wsum) (unsigned long)priv;
+
+	/* find the mac header, aborting if not IPv4 */
+
+	eh = (struct ethhdr *)va;
+	*mac_hdr = eh;
+	ll_hlen = ETH_HLEN;
+	if (eh->h_proto != htons(ETH_P_IP)) {
+		if (eh->h_proto == htons(ETH_P_8021Q)) {
+			veh = (struct vlan_ethhdr *)va;
+			if (veh->h_vlan_encapsulated_proto != htons(ETH_P_IP))
+				return -1;
+
+			ll_hlen += VLAN_HLEN;
+
+			/*
+			 *  HW checksum starts ETH_HLEN bytes into
+			 *  frame, so we must subtract off the VLAN
+			 *  header's checksum before csum can be used
+			 */
+			csum = csum_sub(csum, csum_partial(va + ETH_HLEN,
+							   VLAN_HLEN, 0));
+		} else {
+			return -1;
+		}
+	}
+	*hdr_flags = LRO_IPV4;
+
+	iph = (struct iphdr *)(va + ll_hlen);
+	*ip_hdr = iph;
+	if (iph->protocol != IPPROTO_TCP)
+		return -1;
+	*hdr_flags |= LRO_TCP;
+	*tcpudp_hdr = (u8 *) (*ip_hdr) + (iph->ihl << 2);
+
+	/* verify the IP checksum */
+	if (unlikely(ip_fast_csum((u8 *) iph, iph->ihl)))
+		return -1;
+
+	/* verify the  checksum */
+	if (unlikely(csum_tcpudp_magic(iph->saddr, iph->daddr,
+				       ntohs(iph->tot_len) - (iph->ihl << 2),
+				       IPPROTO_TCP, csum)))
+		return -1;
+
+	return 0;
+}
+
 static int myri10ge_open(struct net_device *dev)
 {
 	struct myri10ge_priv *mgp;
 	struct myri10ge_cmd cmd;
+	struct net_lro_mgr *lro_mgr;
 	int status, big_pow2;
 
 	mgp = netdev_priv(dev);
@@ -1852,6 +1947,17 @@ static int myri10ge_open(struct net_devi
 	mgp->link_state = htonl(~0U);
 	mgp->rdma_tags_available = 15;
 
+	lro_mgr = &mgp->rx_done.lro_mgr;
+	lro_mgr->dev = dev;
+	lro_mgr->features = LRO_F_NAPI;
+	lro_mgr->ip_summed = CHECKSUM_COMPLETE;
+	lro_mgr->max_desc = MYRI10GE_MAX_LRO_DESCRIPTORS;
+	lro_mgr->lro_arr = mgp->rx_done.lro_desc;
+	lro_mgr->get_frag_header = myri10ge_get_frag_header;
+	lro_mgr->max_aggr = myri10ge_lro_max_pkts;
+	if (lro_mgr->max_aggr > MAX_SKB_FRAGS)
+		lro_mgr->max_aggr = MAX_SKB_FRAGS;
+
 	netif_poll_enable(mgp->dev);	/* must happen prior to any irq */
 
 	status = myri10ge_send_cmd(mgp, MXGEFW_CMD_ETHERNET_UP, &cmd, 0);

^ permalink raw reply

* Re: [PATCH 2/2] powerpc: MPC85xx EDAC device driver
From: Dave Jiang @ 2007-07-30 20:17 UTC (permalink / raw)
  To: Arnd Bergmann, galak; +Cc: linuxppc-dev, bluesmoke-devel, norsk5
In-Reply-To: <200707302158.16530.arnd@arndb.de>

Arnd Bergmann wrote:
> On Monday 30 July 2007, Dave Jiang wrote:
>> Maybe we are just better off adding entries in the DTS to get around this
>> problem....
> 
> The best solution may be to look at how it's structured at the
> register level. If the PCI EDAC registers are implemented separately
> from the regular PCI registers, a device tree entry would be appropriate.
> If not, your idea of registering a platform_device from fsl_add_bridge
> is probably more sensible.
> 

We can probably do either. From looking at the 8560 and 8548 manuals, the PCI
error registers are 0xe00 offset of the start of PCI registers. For example,
the PCI registers would start at 0x8000 offset. And the PCI error registers
would be at 0xe00 offset from there and would be the very last block of
registers. Currently the PCI dts devices seem to claim 0x1000 for size. So the
way to have the least code changes would be to register a platform_device from
fsl_add_bridge() or where appropriate for the 85xx PCI code. Most likely the
83xx and 86xx will have similar code and maybe we can do some reuse out of this.

I can add dts entries instead and pick up of_devices if Kumar prefers it that
way instead....

-- 

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

^ permalink raw reply

* Re: [PATCH 0/4][RFC] lro: Generic Large Receive Offload for TCP traffic
From: Stephen Hemminger @ 2007-07-30 19:57 UTC (permalink / raw)
  To: Andrew Gallatin
  Cc: Thomas Klein, Jeff Garzik, Jan-Bernd Themann, Stefan Roscher,
	netdev, linux-kernel, Christoph Raisch, linux-ppc,
	Jan-Bernd Themann, Marcus Eder, David Miller
In-Reply-To: <46AE232F.3080409@myri.com>

Could someone add this to:
	http://linux-net.osdl.org Wiki?

^ permalink raw reply

* Re: [PATCH 2/2] powerpc: MPC85xx EDAC device driver
From: Arnd Bergmann @ 2007-07-30 19:58 UTC (permalink / raw)
  To: Dave Jiang; +Cc: linuxppc-dev, bluesmoke-devel, norsk5
In-Reply-To: <46AE3C06.5060100@mvista.com>

On Monday 30 July 2007, Dave Jiang wrote:
> I don't believe that EDAC core has been loaded at the time of 85xx PCI
> initialization. Plus, the EDAC driver can be loaded as a kernel module. So that
> probably won't work....

ok, good point.

> Also, instead of having centralized EDAC chip driver, 
> now you have things scattered over various places. One probably needs to add
> 83xx and 86xx code as well and whatever else eventually.
> 
> Maybe we are just better off adding entries in the DTS to get around this
> problem....

The best solution may be to look at how it's structured at the
register level. If the PCI EDAC registers are implemented separately
from the regular PCI registers, a device tree entry would be appropriate.
If not, your idea of registering a platform_device from fsl_add_bridge
is probably more sensible.

	Arnd <><

^ permalink raw reply

* Re: [PATCH] gfar: Fix modpost warning
From: Jeff Garzik @ 2007-07-30 19:48 UTC (permalink / raw)
  To: Kumar Gala; +Cc: netdev, linuxppc-dev
In-Reply-To: <Pine.LNX.4.64.0707260051550.30449@blarg.am.freescale.net>

Kumar Gala wrote:
> Fix the following modpost warning:
> 
> WARNING: vmlinux.o(.init.text+0x1aa6c): Section mismatch: reference to .exit.text:gfar_mdio_exit (between 'gfar_init' and 'gfar_mdio_init')
> 
> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
> ---
>  drivers/net/gianfar_mii.c |    2 +-
>  drivers/net/gianfar_mii.h |    2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)

applied

^ permalink raw reply

* 44x hardware watchpoints support
From: Rodrigo Rubira Branco @ 2007-07-30 19:38 UTC (permalink / raw)
  To: linuxppc-dev


[-- Attachment #1.1: Type: text/plain, Size: 199 bytes --]



-- 
Rodrigo Rubira Branco
Software Engineer 
Advanced Linux Response Team (ALRT) / Linux on Power Toolchain
IBM Linux Technology Center (IBM/LTC)
rrbranco@br.ibm.com

GPG KeyID: 1FCEDEA1

[-- Attachment #1.2: mcp-ppc-hwwatchpoint-latest-27-07-07.diff --]
[-- Type: text/x-patch, Size: 11393 bytes --]

Attached a patch to add Linux PPC 44x Hardware Watchpoints.  It's an updated version of the work done by Michel C. Darneille, also from IBM.

I need to redefine in include/asm-powerpc/reg_booke.h the values of DBCR_D1R and DBCR_D1W to 0x00080000 and 0x00040000.  I can't put ifdef to be CONFIG_4xx since some values are not valid in the 405 systems for example (tks Josh Boyer for spot me that).  What is the best way to do that?

Signed-off-by:  Rodrigo Rubira Branco <rrbranco@br.ibm.com>
---

diff -ruN linux.orig/arch/powerpc/kernel/entry_32.S linux/arch/powerpc/kernel/entry_32.S
--- linux.orig/arch/powerpc/kernel/entry_32.S	2007-07-12 17:04:21.000000000 -0300
+++ linux/arch/powerpc/kernel/entry_32.S	2007-07-27 10:33:46.000000000 -0300
@@ -112,7 +112,7 @@
 	/* Check to see if the dbcr0 register is set up to debug.  Use the
 	   single-step bit to do this. */
 	lwz	r12,THREAD_DBCR0(r12)
-	andis.	r12,r12,DBCR0_IC@h
+	andis.	r12,r12,(DBCR0_IC | DBCR_D1R | DBCR_D1W)@h
 	beq+	3f
 	/* From user and task is ptraced - load up global dbcr0 */
 	li	r12,-1			/* clear all pending debug events */
@@ -238,10 +238,13 @@
 	stw	r11,_CCR(r1)
 syscall_exit_cont:
 #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
-	/* If the process has its own DBCR0 value, load it up.  The single
-	   step bit tells us that dbcr0 should be loaded. */
+	/*
+	* If the process has its own DBCR0 value, load it up.  The single
+	* step bit tells us that dbcr0 should be loaded. GDB hw watchpoints
+	* may also be set
+	*/
 	lwz	r0,THREAD+THREAD_DBCR0(r2)
-	andis.	r10,r0,DBCR0_IC@h
+	andis.	r10,r0,(DBCR0_IC | DBCR_D1R | DBCR_D1W)@h
 	bnel-	load_dbcr0
 #endif
 	stwcx.	r0,0,r1			/* to clear the reservation */
@@ -646,10 +649,13 @@
 
 restore_user:
 #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
-	/* Check whether this process has its own DBCR0 value.  The single
-	   step bit tells us that dbcr0 should be loaded. */
+	/*
+	* Check whether this process has its own DBCR0 value.  The single
+	* step bit tells us that dbcr0 should be loaded. GDB hw watchpoints
+	* may also be set
+	*/
 	lwz	r0,THREAD+THREAD_DBCR0(r2)
-	andis.	r10,r0,DBCR0_IC@h
+	andis.	r10,r0,(DBCR0_IC | DBCR_D1R | DBCR_D1W)@h
 	bnel-	load_dbcr0
 #endif
 
diff -ruN linux.orig/arch/powerpc/kernel/process.c linux/arch/powerpc/kernel/process.c
--- linux.orig/arch/powerpc/kernel/process.c	2007-07-12 17:04:21.000000000 -0300
+++ linux/arch/powerpc/kernel/process.c	2007-07-27 10:14:04.000000000 -0300
@@ -197,6 +197,20 @@
 }
 #endif /* CONFIG_SPE */
 
+/* Add support for HW Debug breakpoint.   Use DAC register */
+void set_dac(unsigned long dac)
+{
+       mtspr(SPRN_DAC1, dac);
+}
+unsigned int get_dac()
+{
+       return mfspr(SPRN_DAC1);
+}
+void set_dbcr0(unsigned long dbcr)
+{
+       mtspr(SPRN_DBCR0, dbcr);
+}
+
 #ifndef CONFIG_SMP
 /*
  * If we are doing lazy switching of CPU state (FP, altivec or SPE),
@@ -308,6 +322,10 @@
 		__get_cpu_var(current_dabr) = new->thread.dabr;
 	}
 
+	/* If new thread dac (hw bp) is the same then leave it. */
+	if (new->thread.dac)
+		set_dac(new->thread.dac);
+
 	new_thread = &new->thread;
 	old_thread = &current->thread;
 
@@ -475,6 +493,13 @@
 
 	discard_lazy_cpu_state();
 
+	if (current->thread.dac) {
+		current->thread.dac = 0;
+		current->thread.dbcr0 &= ~(DBCR_D1R | DBCR_D1W);  /* clear
+								debug control */
+		set_dac(0);
+	}
+
 	if (current->thread.dabr) {
 		current->thread.dabr = 0;
 		set_dabr(0);
diff -ruN linux.orig/arch/powerpc/kernel/ptrace.c linux/arch/powerpc/kernel/ptrace.c
--- linux.orig/arch/powerpc/kernel/ptrace.c	2007-07-12 17:04:21.000000000 -0300
+++ linux/arch/powerpc/kernel/ptrace.c	2007-07-27 10:37:03.000000000 -0300
@@ -273,11 +273,14 @@
 
 static void clear_single_step(struct task_struct *task)
 {
+	if (task->thread.dac)   /* if dac then not single step, skip */
+		return;
+
 	struct pt_regs *regs = task->thread.regs;
 
 	if (regs != NULL) {
 #if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
-		task->thread.dbcr0 = 0;
+		task->thread.dbcr0 &= ~(DBCR0_IC | DBCR0_IDM);
 		regs->msr &= ~MSR_DE;
 #else
 		regs->msr &= ~MSR_SE;
@@ -286,22 +289,48 @@
 	clear_tsk_thread_flag(task, TIF_SINGLESTEP);
 }
 
-static int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
+static int ptrace_get_debugreg(struct task_struct *task, unsigned long data)
+{
+	#ifdef CONFIG_PPC64
+		ret = put_user(child->thread.dabr,
+				(unsigned long __user *)data);
+	#else
+		ret = put_user(child->thread.dac,
+				(unsigned long __user *)data);
+	#endif
+
+	return ret;
+}
+
+int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
 			       unsigned long data)
 {
-	/* We only support one DABR and no IABRS at the moment */
+	/* We only support one DAC and no IABRS at the moment */
 	if (addr > 0)
 		return -EINVAL;
 
-	/* The bottom 3 bits are flags */
-	if ((data & ~0x7UL) >= TASK_SIZE)
-		return -EIO;
-
-	/* Ensure translation is on */
-	if (data && !(data & DABR_TRANSLATION))
-		return -EIO;
+	task->thread.dac = data & ~0x3UL;
+
+	if (task->thread.dac == 0) {
+		task->thread.dbcr0 &= ~(DBCR_D1R | DBCR_D1W | DBCR_IDM);
+		task->thread.regs->msr &= ~MSR_DE;
+		return 0;
+	}
+
+	if (!(data & 0x3UL))            /* R or W must be set */
+		return -EINVAL;
+
+	/* Check data lsb for r/w flag:   1 = r   2 = w   then mask lower 2 bits
+	keeping watchpoint addr aligned to 32 bits. */
+	task->thread.dbcr0 = DBCR_IDM;
+
+	if (data & 1)
+		task->thread.dbcr0 |= DBCR_D1R;
+	if (data & 2)
+		task->thread.dbcr0 |= DBCR_D1W;
+
+	task->thread.regs->msr |= MSR_DE;
 
-	task->thread.dabr = data;
 	return 0;
 }
 
@@ -503,11 +532,10 @@
 
 	case PTRACE_GET_DEBUGREG: {
 		ret = -EINVAL;
-		/* We only support one DABR and no IABRS at the moment */
+		/* We only support one DAC at the moment */
 		if (addr > 0)
 			break;
-		ret = put_user(child->thread.dabr,
-			       (unsigned long __user *)data);
+		ret = ptrace_get_debugreg(child, data);
 		break;
 	}
 
diff -ruN linux.orig/arch/powerpc/kernel/signal.c linux/arch/powerpc/kernel/signal.c
--- linux.orig/arch/powerpc/kernel/signal.c	2007-07-12 17:04:21.000000000 -0300
+++ linux/arch/powerpc/kernel/signal.c	2007-07-27 10:30:47.000000000 -0300
@@ -142,6 +142,16 @@
 		set_dabr(current->thread.dabr);
 
 	if (is32) {
+		/*
+		* Reenable the DAC before delivering the signal to
+		* user space. The DAC will have been cleared if it
+		* triggered inside the kernel.
+		*/
+		if (current->thread.dac) {
+			set_dac(current->thread.dac);
+			set_dbcr0(current->thread.dbcr0);
+		}
+
         	if (ka.sa.sa_flags & SA_SIGINFO)
 			ret = handle_rt_signal32(signr, &ka, &info, oldset,
 					regs);
diff -ruN linux.orig/arch/powerpc/kernel/traps.c linux/arch/powerpc/kernel/traps.c
--- linux.orig/arch/powerpc/kernel/traps.c	2007-07-12 17:04:21.000000000 -0300
+++ linux/arch/powerpc/kernel/traps.c	2007-07-27 11:01:31.000000000 -0300
@@ -54,6 +54,10 @@
 #endif
 #include <asm/kexec.h>
 
+extern int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
+							unsigned long data);
+extern int get_dac();
+
 #ifdef CONFIG_DEBUGGER
 int (*__debugger)(struct pt_regs *regs);
 int (*__debugger_ipi)(struct pt_regs *regs);
@@ -61,6 +65,7 @@
 int (*__debugger_sstep)(struct pt_regs *regs);
 int (*__debugger_iabr_match)(struct pt_regs *regs);
 int (*__debugger_dabr_match)(struct pt_regs *regs);
+int (*__debugger_dac_match)(struct pt_regs *regs);
 int (*__debugger_fault_handler)(struct pt_regs *regs);
 
 EXPORT_SYMBOL(__debugger);
@@ -69,6 +74,7 @@
 EXPORT_SYMBOL(__debugger_sstep);
 EXPORT_SYMBOL(__debugger_iabr_match);
 EXPORT_SYMBOL(__debugger_dabr_match);
+EXPORT_SYMBOL(__debugger_dac_match);
 EXPORT_SYMBOL(__debugger_fault_handler);
 #endif
 
@@ -242,6 +248,25 @@
 }
 #endif
 
+static void do_dac(struct pt_regs *regs, unsigned long address,
+						unsigned long error_code)
+{
+	siginfo_t info;
+
+	/* Clear the DAC and struct entries.  One shot trigger */
+	mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) & ~(DBCR_D1R | DBCR_D1W
+							| DBCR_IDM));
+	set_dac(0);
+	ptrace_set_debugreg(current, 0, 0);
+
+	/* Deliver the signal to userspace */
+	info.si_signo = SIGTRAP;
+	info.si_errno = 0;
+	info.si_code = TRAP_HWBKPT;
+	info.si_addr = (void __user *)address;
+	force_sig_info(SIGTRAP, &info, current);
+}
+
 /*
  * I/O accesses can cause machine checks on powermacs.
  * Check if the NIP corresponds to the address of a sync
@@ -978,6 +1003,20 @@
 				return;
 		}
 		_exception(SIGTRAP, regs, TRAP_TRACE, 0);
+	} else if (debug_status & (DBSR_DAC1R | DBSR_DAC1W)) {
+		regs->msr &= ~MSR_DE;
+		if (user_mode(regs)) {
+			current->thread.dbcr0 &= ~(DBCR_D1R | DBCR_D1W |
+								DBCR_IDM);
+		} else {
+			/* Disable dac interupts */
+			mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) & ~(DBCR_D1R |
+							DBCR_D1W | DBCR_IDM));
+			/* Clear the dac event */
+			mtspr(SPRN_DBSR, (DBSR_DAC1R | DBSR_DAC1W));
+		}
+		/* Setup and send the trap to the handler */
+		do_dac(regs, get_dac(), debug_status);
 	}
 }
 #endif /* CONFIG_4xx || CONFIG_BOOKE */
diff -ruN linux.orig/include/asm-powerpc/processor.h linux/include/asm-powerpc/processor.h
--- linux.orig/include/asm-powerpc/processor.h	2007-07-12 17:04:56.000000000 -0300
+++ linux/include/asm-powerpc/processor.h	2007-07-27 10:47:34.000000000 -0300
@@ -129,6 +129,7 @@
 #if defined(CONFIG_4xx) || defined (CONFIG_BOOKE)
 	unsigned long	dbcr0;		/* debug control register values */
 	unsigned long	dbcr1;
+	unsigned long   dac;            /* Data Address Compare register */
 #endif
 	double		fpr[32];	/* Complete floating point set */
 	struct {			/* fpr ... fpscr must be contiguous */
diff -ruN linux.orig/include/asm-powerpc/system.h linux/include/asm-powerpc/system.h
--- linux.orig/include/asm-powerpc/system.h	2007-07-12 17:04:56.000000000 -0300
+++ linux/include/asm-powerpc/system.h	2007-07-27 11:05:14.000000000 -0300
@@ -72,6 +72,7 @@
 extern int (*__debugger_sstep)(struct pt_regs *regs);
 extern int (*__debugger_iabr_match)(struct pt_regs *regs);
 extern int (*__debugger_dabr_match)(struct pt_regs *regs);
+extern int (*__debugger_dac_match)(struct pt_regs *regs);
 extern int (*__debugger_fault_handler)(struct pt_regs *regs);
 
 #define DEBUGGER_BOILERPLATE(__NAME) \
@@ -88,6 +89,7 @@
 DEBUGGER_BOILERPLATE(debugger_sstep)
 DEBUGGER_BOILERPLATE(debugger_iabr_match)
 DEBUGGER_BOILERPLATE(debugger_dabr_match)
+DEBUGGER_BOILERPLATE(debugger_dac_match)
 DEBUGGER_BOILERPLATE(debugger_fault_handler)
 
 #else
@@ -97,10 +99,13 @@
 static inline int debugger_sstep(struct pt_regs *regs) { return 0; }
 static inline int debugger_iabr_match(struct pt_regs *regs) { return 0; }
 static inline int debugger_dabr_match(struct pt_regs *regs) { return 0; }
+static inline int debugger_dac_match(struct pt_regs *regs) { return 0; }
 static inline int debugger_fault_handler(struct pt_regs *regs) { return 0; }
 #endif
 
 extern int set_dabr(unsigned long dabr);
+extern void set_dac(unsigned long dac);
+extern void set_dbcr0(unsigned long dbcr);
 extern void print_backtrace(unsigned long *);
 extern void show_regs(struct pt_regs * regs);
 extern void flush_instruction_cache(void);

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

^ permalink raw reply

* Re: [PATCH 2/2] powerpc: MPC85xx EDAC device driver
From: Dave Jiang @ 2007-07-30 19:29 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: linuxppc-dev, bluesmoke-devel, norsk5
In-Reply-To: <200707302046.10010.arnd@arndb.de>

Arnd Bergmann wrote:
> On Monday 30 July 2007, Dave Jiang wrote:
>>> What about the other option I mentioned, handling the EDAC stuff from the
>>> fsl_add_bridge() function?
>> I'm not sure I follow your thought on this quite yet. Do you mean the setup of
>> either of_device or platform_device or do you mean the actual pci err driver?
>> I'm not understanding how doing the setup code in fsl_add_bridge() would allow
>> us to prevent the of_device being monopolized by the EDAC driver or the future
>> PCI code.... The EDAC driver still needs some sort of "device" to claim one way
>> or another right?
> 
> What I meant is calling the edac_pci_alloc_ctl_info() function directly
> from fsl_add_bridge() where appropriate, with all the 85xx PCI EDAC
> code moved into fsl_pci.c.

I don't believe that EDAC core has been loaded at the time of 85xx PCI
initialization. Plus, the EDAC driver can be loaded as a kernel module. So that
probably won't work.... Also, instead of having centralized EDAC chip driver,
now you have things scattered over various places. One probably needs to add
83xx and 86xx code as well and whatever else eventually.

Maybe we are just better off adding entries in the DTS to get around this
problem....

-- 

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

^ permalink raw reply

* Re: [PATCH 2/2] powerpc: MPC85xx EDAC device driver
From: Arnd Bergmann @ 2007-07-30 18:46 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: norsk5, bluesmoke-devel
In-Reply-To: <46AE2487.7060103@mvista.com>

On Monday 30 July 2007, Dave Jiang wrote:
> 
> > What about the other option I mentioned, handling the EDAC stuff from the
> > fsl_add_bridge() function?
> 
> I'm not sure I follow your thought on this quite yet. Do you mean the setup of
> either of_device or platform_device or do you mean the actual pci err driver?
> I'm not understanding how doing the setup code in fsl_add_bridge() would allow
> us to prevent the of_device being monopolized by the EDAC driver or the future
> PCI code.... The EDAC driver still needs some sort of "device" to claim one way
> or another right?

What I meant is calling the edac_pci_alloc_ctl_info() function directly
from fsl_add_bridge() where appropriate, with all the 85xx PCI EDAC
code moved into fsl_pci.c.

	Arnd <><

^ permalink raw reply

* Re: [PATCH 0/4][RFC] lro: Generic Large Receive Offload for TCP traffic
From: Andrew Gallatin @ 2007-07-30 17:43 UTC (permalink / raw)
  To: Linas Vepstas
  Cc: Thomas Klein, Jeff Garzik, Jan-Bernd Themann, netdev,
	linux-kernel, Christoph Raisch, linux-ppc, Jan-Bernd Themann,
	Marcus Eder, Stefan Roscher, David Miller
In-Reply-To: <20070730170038.GA4884@austin.ibm.com>


Here is a quick reply before something more official can
be written up:

Linas Vepstas wrote:

 > -- what is LRO?

Large Receive Offload

 > -- Basic principles of operation?

LRO is analogous to a receive side version of TSO.  The NIC (or
driver) merges several consecutive segments from the same connection,
fixing up checksums, etc.  Rather than up to 45 separate 1500 byte
frames (meaning up to 45 trips through the network stack), the driver
merges them into one 65212 byte frame.  It currently works only
with TCP over IPv4.

LRO was, AFAIK, first though of by Neterion.  They had a paper about
it at OLS2005.
http://www.linuxinsight.com/files/ols2005/grossman-reprint.pdf

 > -- Can I use it in my driver?

Yes, it can be used in any driver.

 > -- Does my hardware have to have some special feature before I can 
use it?

No.

 > -- What sort of performance improvement does it provide? Throughput?
 >    Latency? CPU usage? How does it affect DMA allocation? Does it
 >    improve only a certain type of traffic (large/small packets, etc.)

The benefit is directly proportional to the packet rate.

See my reply to the previous RFC for performance information.  The
executive summary is that for the myri10ge 10GbE driver on low end
hardware with 1500b frames, I've seen it increase throughput by a
factor of nearly 2.5x, while at the same time reducing CPU utilization
by 17%.  The affect for jumbo frames is less dramatic, but still
impressive (1.10x, 14% CPU reduction)

You can achieve better speedups if your driver receives into
high-order pages.

 > -- Example code? What's the API? How should my driver use it?

The 3/4 in this patch showed an example of converting a driver
to use LRO for skb based receive buffers.   I'm working on
a patch for myri10ge that shows how you would use it in a driver
which receives into pages.

Cheers,

Drew

^ permalink raw reply

* Re: [PATCH 2/2] powerpc: MPC85xx EDAC device driver
From: Dave Jiang @ 2007-07-30 17:48 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: linuxppc-dev, norsk5, bluesmoke-devel
In-Reply-To: <200707301928.51253.arnd@arndb.de>

Arnd Bergmann wrote:
> On Monday 30 July 2007, Dave Jiang wrote:
>> Arnd Bergmann wrote:
> 
>>> I'd suggest either to integrate EDAC into the 85xx specific PCI code,
>>> or to have an extra device in the device tree for this.
>> How about I create a platform device just for EDAC and leave the PCI of_device
>> to the 85xx PCI code? That would be a lot less modification than adding a
>> device for every PCI hose per DTS file.... Just a thought....
> 
> Hmm, I can see your point about not having to change all the device trees,
> but if you really want to have a device for each of them, an of_device seems
> more natural to me than a platform_device.
> 
> What about the other option I mentioned, handling the EDAC stuff from the
> fsl_add_bridge() function?

I'm not sure I follow your thought on this quite yet. Do you mean the setup of
either of_device or platform_device or do you mean the actual pci err driver?
I'm not understanding how doing the setup code in fsl_add_bridge() would allow
us to prevent the of_device being monopolized by the EDAC driver or the future
PCI code.... The EDAC driver still needs some sort of "device" to claim one way
or another right?

Of course I can go ahead and add the PCI err device in the DTS files for all
85xx if Kumar is okay with that idea....

-- 

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

^ 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