LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [RFC 1/2] powerpc: copy_4K_page tweaked for Cell
From: Mark Nelson @ 2008-08-14  6:18 UTC (permalink / raw)
  To: linuxppc-dev, cbe-oss-dev

/*
 * Copyright (C) 2008 Mark Nelson, IBM Corp.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 */
#include <asm/processor.h>
#include <asm/ppc_asm.h>
#include <asm/asm-offsets.h>

        .section        ".toc","aw"
PPC64_CACHES:
        .tc             ppc64_caches[TC],ppc64_caches
        .section        ".text"


_GLOBAL(copy_4K_page)
	li	r5,4096		/* 4K page size */
	ld      r10,PPC64_CACHES@toc(r2)
	lwz	r11,DCACHEL1LOGLINESIZE(r10)	/* log2 of cache line size */
	lwz     r12,DCACHEL1LINESIZE(r10)	/* Get cache line size */
	li	r9,0
	srd	r8,r5,r11

	mtctr	r8
setup:
	dcbt	r9,r4
	dcbz	r9,r3
	add	r9,r9,r12
	bdnz	setup

	addi	r3,r3,-8
	srdi    r8,r5,7		/* page is copied in 128 byte strides */
	addi	r8,r8,-1	/* one stride copied outside loop */

	mtctr	r8

	ld	r5,0(r4)
	ld	r6,8(r4)
	ld	r7,16(r4)
	ldu	r8,24(r4)
1:	std	r5,8(r3)
	ld	r9,8(r4)
	std	r6,16(r3)
	ld	r10,16(r4)
	std	r7,24(r3)
	ld	r11,24(r4)
	std	r8,32(r3)
	ld	r12,32(r4)
	std	r9,40(r3)
	ld	r5,40(r4)
	std	r10,48(r3)
	ld	r6,48(r4)
	std	r11,56(r3)
	ld	r7,56(r4)
	std	r12,64(r3)
	ld	r8,64(r4)
	std	r5,72(r3)
	ld	r9,72(r4)
	std	r6,80(r3)
	ld	r10,80(r4)
	std	r7,88(r3)
	ld	r11,88(r4)
	std	r8,96(r3)
	ld	r12,96(r4)
	std	r9,104(r3)
	ld	r5,104(r4)
	std	r10,112(r3)
	ld	r6,112(r4)
	std	r11,120(r3)
	ld	r7,120(r4)
	stdu	r12,128(r3)
	ldu	r8,128(r4)
	bdnz	1b

	std	r5,8(r3)
	ld	r9,8(r4)
	std	r6,16(r3)
	ld	r10,16(r4)
	std	r7,24(r3)
	ld	r11,24(r4)
	std	r8,32(r3)
	ld	r12,32(r4)
	std	r9,40(r3)
	ld	r5,40(r4)
	std	r10,48(r3)
	ld	r6,48(r4)
	std	r11,56(r3)
	ld	r7,56(r4)
	std	r12,64(r3)
	ld	r8,64(r4)
	std	r5,72(r3)
	ld	r9,72(r4)
	std	r6,80(r3)
	ld	r10,80(r4)
	std	r7,88(r3)
	ld	r11,88(r4)
	std	r8,96(r3)
	ld	r12,96(r4)
	std	r9,104(r3)
	std	r10,112(r3)
	std	r11,120(r3)
	std	r12,128(r3)
	blr

^ permalink raw reply

* [RFC 2/2] powerpc: copy_4K_page tweaked for Cell - add CPU feature
From: Mark Nelson @ 2008-08-14  6:18 UTC (permalink / raw)
  To: linuxppc-dev, cbe-oss-dev

Add a new CPU feature, CPU_FTR_CP_USE_DCBTZ, to be added to the CPUs that benefit
from having dcbt and dcbz instructions used in copy_4K_page(). So far Cell, PPC970
and Power4 benefit.

This way all the other 64bit powerpc chips will have the whole prefetching loop
nop'ed out.

Signed-off-by: Mark Nelson <markn@au1.ibm.com>
---
 arch/powerpc/include/asm/cputable.h |    9 ++++++---
 arch/powerpc/lib/copypage_64.S      |    3 ++-
 2 files changed, 8 insertions(+), 4 deletions(-)

Index: upstream/arch/powerpc/include/asm/cputable.h
===================================================================
--- upstream.orig/arch/powerpc/include/asm/cputable.h
+++ upstream/arch/powerpc/include/asm/cputable.h
@@ -192,6 +192,7 @@ extern const char *powerpc_base_platform
 #define CPU_FTR_NO_SLBIE_B		LONG_ASM_CONST(0x0008000000000000)
 #define CPU_FTR_VSX			LONG_ASM_CONST(0x0010000000000000)
 #define CPU_FTR_SAO			LONG_ASM_CONST(0x0020000000000000)
+#define CPU_FTR_CP_USE_DCBTZ		LONG_ASM_CONST(0x0040000000000000)
 
 #ifndef __ASSEMBLY__
 
@@ -387,10 +388,11 @@ extern const char *powerpc_base_platform
 	    CPU_FTR_MMCRA | CPU_FTR_CTRL)
 #define CPU_FTRS_POWER4	(CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
 	    CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
-	    CPU_FTR_MMCRA)
+	    CPU_FTR_MMCRA | CPU_FTR_CP_USE_DCBTZ)
 #define CPU_FTRS_PPC970	(CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
 	    CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
-	    CPU_FTR_ALTIVEC_COMP | CPU_FTR_CAN_NAP | CPU_FTR_MMCRA)
+	    CPU_FTR_ALTIVEC_COMP | CPU_FTR_CAN_NAP | CPU_FTR_MMCRA | \
+	    CPU_FTR_CP_USE_DCBTZ)
 #define CPU_FTRS_POWER5	(CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
 	    CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
 	    CPU_FTR_MMCRA | CPU_FTR_SMT | \
@@ -411,7 +413,8 @@ extern const char *powerpc_base_platform
 #define CPU_FTRS_CELL	(CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
 	    CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
 	    CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
-	    CPU_FTR_PAUSE_ZERO | CPU_FTR_CI_LARGE_PAGE | CPU_FTR_CELL_TB_BUG)
+	    CPU_FTR_PAUSE_ZERO | CPU_FTR_CI_LARGE_PAGE | \
+	    CPU_FTR_CELL_TB_BUG | CPU_FTR_CP_USE_DCBTZ)
 #define CPU_FTRS_PA6T (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
 	    CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \
 	    CPU_FTR_ALTIVEC_COMP | CPU_FTR_CI_LARGE_PAGE | \
Index: upstream/arch/powerpc/lib/copypage_64.S
===================================================================
--- upstream.orig/arch/powerpc/lib/copypage_64.S
+++ upstream/arch/powerpc/lib/copypage_64.S
@@ -18,6 +18,7 @@ PPC64_CACHES:
 
 _GLOBAL(copy_4K_page)
 	li	r5,4096		/* 4K page size */
+BEGIN_FTR_SECTION
 	ld      r10,PPC64_CACHES@toc(r2)
 	lwz	r11,DCACHEL1LOGLINESIZE(r10)	/* log2 of cache line size */
 	lwz     r12,DCACHEL1LINESIZE(r10)	/* Get cache line size */
@@ -30,7 +31,7 @@ setup:
 	dcbz	r9,r3
 	add	r9,r9,r12
 	bdnz	setup
-
+END_FTR_SECTION_IFSET(CPU_FTR_CP_USE_DCBTZ)
 	addi	r3,r3,-8
 	srdi    r8,r5,7		/* page is copied in 128 byte strides */
 	addi	r8,r8,-1	/* one stride copied outside loop */

^ permalink raw reply

* Re: How to use ramdisk on the ml300?
From: Jens Wirth @ 2008-08-14  7:04 UTC (permalink / raw)
  To: linuxppc-embedded, killyouatonce
In-Reply-To: <931ae8260808132008i1cac2e91kc76c099ecc574cd0@mail.gmail.com>

Hi Yanlong,

On Thu, Aug 14, 2008 at 5:08 AM, yanlong wang <killyouatonce@gmail.com> wrote:
>      If i want use ramdisk on the ml300 , i must use u-boot in my system ?
>     many thanks

I suppose you want to use an initial ram filesystem as
rootfs to boot your system?

You have to point CONFIG_INITRAMFS_SOURCE="" to a cpio
archive or a directory which contains your rootfs. If
you use a directory structure then you should set your
uid/gid to make the build process convert the owner
to root:

# if your uid/gid is 500:
CONFIG_INITRAMFS_ROOT_UID=500
CONFIG_INITRAMFS_ROOT_GID=500

Don't forget to set CONFIG_BLK_DEV_RAM=y to be able
to use a ramdisk at all.

I'm also using the ml300 board and I create my kernel
with: make simpleImage.virtex405-ml300

My dts is arch/powerpc/boot/dts/virtex405-ml300.dts.
There is no kernel boot command line needed to use
the initramfs in my case (I only set up my console
to the uart). Just download the image
arch/powerpc/boot/simpleImage.virtex405-ml300.elf
with xmd to your ml300 and run it.

I hope this works for you.

Regards
Jens

^ permalink raw reply

* Re: [PATCH / RFC] net: fix locking in ibm_newemac
From: Sebastian Siewior @ 2008-08-14  7:33 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: netdev, Sebastian Siewior, linuxppc-dev
In-Reply-To: <1218685554.8041.172.camel@pasglop>

* Benjamin Herrenschmidt | 2008-08-14 13:45:54 [+1000]:

>> The fix is to defer phy init until netdevice is registered / initialized.
>
>I think it's better instead to take the dev_mc_add() statement
>out of emac_configure().
I looked yesterday into that code and I saw that dev_mc_add() was called
by the network core itself. Now I'm sure it was definitly too late for
writing patches :)

>What about this patch instead, does it fix it for you ?
yep it does.

Sebastian

^ permalink raw reply

* bug in lmb_enforce_memory_limit()
From: David Miller @ 2008-08-14  8:20 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: linux-kernel


I just mentioned this to Ben H. on IRC and promised I would report it
here. :-)

The first loop over lmb.memory in this function interprets the
memory_limit as a raw size limit, and that's fine so far.

But the second loop over lmb.reserved interprets this value
instead as an "address limit."

I haven't cobbled together a fix myself, but probably the way to do
this is, when we're about break out of the first loop over lmb.memory,
walk through the now-trimmed memory blobs and trim those from
lmb.reserved, one by one.

This bug got introduced by:

   commit 2babf5c2ec2f2d5de3e38d20f7df7fd815fd10c9
   Author: Michael Ellerman <michael@ellerman.id.au>
   Date:   Wed May 17 18:00:46 2006 +1000

       [PATCH] powerpc: Unify mem= handling

back when LMB was still a powerpc local item. :-)

This led me to another bug which probably a lot of platforms are
effected by.

If you do this command line memory limiting, and the kernel was placed
by the boot loader into physical ram (say at the end of the available
physical memory) that gets trimmed out by the command line option, we
hang or crash right as we boot into userspace because freeing up
initmem ends up freeing invalid page structs.

I think, on sparc64, instead of adding all kinds of complicated logic
to free_initmem() I'm simply going to only poison the pages and
not free them at all if cmdline_memory_size has been set.

^ permalink raw reply

* Re: [PATCH] gianfar: Call gfar_halt_nodisable() from gfar_halt().
From: Jeff Garzik @ 2008-08-14  8:28 UTC (permalink / raw)
  To: Scott Wood; +Cc: netdev, linuxppc-dev
In-Reply-To: <20080812201046.GC27956@loki.buserror.net>

Scott Wood wrote:
> gfar_halt() was factored out into halting and disabling by commit
> d87eb12785c14de1586e3bad86ca2c0991300339, as the suspend() method
> only wants to do the former.  However, the call to gfar_halt_nodisable()
> from gfar_halt() apparently got lost during the patch respin process.
> 
> This adds it back.
> 
> Signed-off-by: Scott Wood <scottwood@freescale.com>
> ---
>  drivers/net/gianfar.c |    6 ++----
>  1 files changed, 2 insertions(+), 4 deletions(-)

applied

^ permalink raw reply

* mpc52xx_uart and rs485
From: Sinisa Denic @ 2008-08-14  9:23 UTC (permalink / raw)
  To: linuxppc-dev

>From bf050adbc092043c1ba6e43373563bb761bb2e40 Mon Sep 17 00:00:00 2001
From: Sinisa Denic <sinisa.denic@abs-cs.com>
Date: Wed, 13 Aug 2008 15:57:52 +0200
Subject: [PATCH] mpc52xx_uart RS485 support added

Hi Wolfgang and others, 
below is patch for mpc52xx_usrt.c which add software rs485 support to 
this driver.
It has worked for me and if you think it is good enough it might be 
useful for someone else.
Regards, 
Sinisa Denic
System and software  engineer
tel: +381(0)112016142
ABS Control Systems
bul.Zorana Djindjica 8a
Belgrade,Serbia
---
 drivers/serial/mpc52xx_uart.c |   47 +++++++++++++++++++++++++++++++++
+-------
 1 files changed, 39 insertions(+), 8 deletions(-)

diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index 7a3625f..38b2751 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -62,7 +62,7 @@
  * by the bootloader or in the platform init code.
  */
 
-#undef DEBUG
+//#undef DEBUG
 
 #include <linux/device.h>
 #include <linux/module.h>
@@ -142,11 +142,13 @@ struct psc_ops {
 	int		(*rx_rdy)(struct uart_port *port);
 	int		(*tx_rdy)(struct uart_port *port);
 	int		(*tx_empty)(struct uart_port *port);
+	int		(*tx_empty_enabled)(struct uart_port *port);
 	void		(*stop_rx)(struct uart_port *port);
 	void		(*start_tx)(struct uart_port *port);
 	void		(*stop_tx)(struct uart_port *port);
 	void		(*rx_clr_irq)(struct uart_port *port);
 	void		(*tx_clr_irq)(struct uart_port *port);
+	void		(*tx_empty_clr_irq)(struct uart_port *port);
 	void		(*write_char)(struct uart_port *port, unsigned 
char c);
 	unsigned char	(*read_char)(struct uart_port *port);
 	void		(*cw_disable_ints)(struct uart_port *port);
@@ -169,7 +171,7 @@ static void mpc52xx_psc_fifo_init(struct uart_port 
*port)
 	out_8(&fifo->tfcntl, 0x07);
 	out_be16(&fifo->tfalarm, 0x80);
 
-	port->read_status_mask |= MPC52xx_PSC_IMR_RXRDY | 
MPC52xx_PSC_IMR_TXRDY;
+	port->read_status_mask |= MPC52xx_PSC_IMR_RXRDY | 
MPC52xx_PSC_IMR_TXRDY | MPC52xx_PSC_IMR_TXEMP; 
 	out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask);
 }
 
@@ -200,6 +202,13 @@ static int mpc52xx_psc_tx_rdy(struct uart_port *port)
 	    & MPC52xx_PSC_IMR_TXRDY;
 }
 
+static int mpc52xx_psc_tx_empty_enabled(struct uart_port *port)
+{
+	return in_be16(&PSC(port)->mpc52xx_psc_isr)
+	    & port->read_status_mask
+	    & MPC52xx_PSC_IMR_TXEMP;
+}
+
 static int mpc52xx_psc_tx_empty(struct uart_port *port)
 {
 	return in_be16(&PSC(port)->mpc52xx_psc_status)
@@ -209,6 +218,7 @@ static int mpc52xx_psc_tx_empty(struct uart_port 
*port)
 static void mpc52xx_psc_start_tx(struct uart_port *port)
 {
 	port->read_status_mask |= MPC52xx_PSC_IMR_TXRDY;
+	port->read_status_mask |= MPC52xx_PSC_IMR_TXEMP;
 	out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask);
 }
 
@@ -232,6 +242,11 @@ static void mpc52xx_psc_tx_clr_irq(struct uart_port 
*port)
 {
 }
 
+static void mpc52xx_psc_tx_empty_clr_irq(struct uart_port *port)
+{
+	port->read_status_mask &= ~MPC52xx_PSC_IMR_TXEMP;
+	out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask);
+}
 static void mpc52xx_psc_write_char(struct uart_port *port, unsigned char 
c)
 {
 	out_8(&PSC(port)->mpc52xx_psc_buffer_8, c);
@@ -275,11 +290,13 @@ static struct psc_ops mpc52xx_psc_ops = {
 	.rx_rdy = mpc52xx_psc_rx_rdy,
 	.tx_rdy = mpc52xx_psc_tx_rdy,
 	.tx_empty = mpc52xx_psc_tx_empty,
+	.tx_empty_enabled = mpc52xx_psc_tx_empty_enabled,
 	.stop_rx = mpc52xx_psc_stop_rx,
 	.start_tx = mpc52xx_psc_start_tx,
 	.stop_tx = mpc52xx_psc_stop_tx,
 	.rx_clr_irq = mpc52xx_psc_rx_clr_irq,
 	.tx_clr_irq = mpc52xx_psc_tx_clr_irq,
+	.tx_empty_clr_irq = mpc52xx_psc_tx_empty_clr_irq,
 	.write_char = mpc52xx_psc_write_char,
 	.read_char = mpc52xx_psc_read_char,
 	.cw_disable_ints = mpc52xx_psc_cw_disable_ints,
@@ -583,7 +600,7 @@ mpc52xx_uart_set_termios(struct uart_port *port, 
struct ktermios *new,
 
 
 	mr2 = 0;
-
+	
 	if (new->c_cflag & CSTOPB)
 		mr2 |= MPC52xx_PSC_MODE_TWO_STOP;
 	else
@@ -591,7 +608,6 @@ mpc52xx_uart_set_termios(struct uart_port *port, 
struct ktermios *new,
 			MPC52xx_PSC_MODE_ONE_STOP_5_BITS :
 			MPC52xx_PSC_MODE_ONE_STOP;
 
-
 	baud = uart_get_baud_rate(port, new, old, 0, port->uartclk/16);
 	quot = uart_get_divisor(port, baud);
 	ctr = quot & 0xffff;
@@ -735,7 +751,7 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port)
 	struct tty_struct *tty = port->info->tty;
 	unsigned char ch, flag;
 	unsigned short status;
-
+	//printk("Int. citanje...\n");
 	/* While we can read, do so ! */
 	while (psc_ops->raw_rx_rdy(port)) {
 		/* Get the char */
@@ -792,7 +808,9 @@ static inline int
 mpc52xx_uart_int_tx_chars(struct uart_port *port)
 {
 	struct circ_buf *xmit = &port->info->xmit;
+	out_8(&PSC(port)->op1,1);
 
+//	printk("Int. slanje...\n");
 	/* Process out of band chars */
 	if (port->x_char) {
 		psc_ops->write_char(port, port->x_char);
@@ -812,8 +830,10 @@ mpc52xx_uart_int_tx_chars(struct uart_port *port)
 		psc_ops->write_char(port, xmit->buf[xmit->tail]);
 		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
 		port->icount.tx++;
-		if (uart_circ_empty(xmit))
+		if (uart_circ_empty(xmit)){
+//		printk("Uart circular buffer is empty!!\n");
 			break;
+			}
 	}
 
 	/* Wake up */
@@ -828,7 +848,15 @@ mpc52xx_uart_int_tx_chars(struct uart_port *port)
 
 	return 1;
 }
-
+static inline int
+mpc52xx_uart_int_tx_empty(struct uart_port *port)
+{
+	out_8(&PSC(port)->op0,1);
+	port->read_status_mask &= ~MPC52xx_PSC_IMR_TXEMP;
+	out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask);
+//printk("tx_empty_interrupt!\n");
+	return 0;
+}
 static irqreturn_t
 mpc52xx_uart_int(int irq, void *dev_id)
 {
@@ -850,7 +878,10 @@ mpc52xx_uart_int(int irq, void *dev_id)
 		psc_ops->tx_clr_irq(port);
 		if (psc_ops->tx_rdy(port))
 			keepgoing |= mpc52xx_uart_int_tx_chars(port);
-
+		if (psc_ops->tx_empty_enabled(port)){
+			keepgoing |= mpc52xx_uart_int_tx_empty(port);
+//			psc_ops->tx_empty_clr_irq(port);
+		}
 		/* Limit number of iteration */
 		if (!(--pass))
 			keepgoing = 0;
-- 
1.5.4.5

^ permalink raw reply related

* [PATCH 1/2][V3] powerpc: add support for dynamic reconfiguration memory in kexec/kdump kernels
From: Chandru @ 2008-08-14  9:47 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Stephen Rothwell, Michael Neuling, Paul Mackerras

kdump kernel needs to use only those memory regions that it is allowed to use (crashkernel, rtas, tce ..etc ). Each of these regions have their own sizes and are currently added under  'linux,usable-memory' property under each memory@ node of the device tree.  ibm,dynamic-memory property of ibm,dynamic-reconfiguration-memory node now stores in it the representation for most of the logical memory blocks with the size of each memory block being a constant (lmb_size).  If one or more or part of the above mentioned regions lie under one of the lmb from ibm,dynamic-memory property, there is a need to identify those regions within the given lmb. Following patch recognizes a new property 'linux,drconf-usable-memory' property added by kexec-tools. Each entry in this property is of the form 'a counter'  followed by those many (base, size) duple for the above mentioned regions.

Signed-off-by: Chandru Siddalingappa <chandru@in.ibm.com>
---

These patches were sent earlier but these are V3 of the patches. Pls let me know your thoughts. Thanks. 

 arch/powerpc/kernel/prom.c |   40 +++++++++++++++--
 arch/powerpc/mm/numa.c     |   79 +++++++++++++++++++++++++++--------
 2 files changed, 96 insertions(+), 23 deletions(-)

diff -Naurp powerpc-orig/arch/powerpc/kernel/prom.c powerpc/arch/powerpc/kernel/prom.c
--- powerpc-orig/arch/powerpc/kernel/prom.c	2008-08-14 08:23:25.000000000 +0530
+++ powerpc/arch/powerpc/kernel/prom.c	2008-08-14 14:35:24.000000000 +0530
@@ -888,9 +888,10 @@ static u64 __init dt_mem_next_cell(int s
  */
 static int __init early_init_dt_scan_drconf_memory(unsigned long node)
 {
-	cell_t *dm, *ls;
+	cell_t *dm, *ls, *usm;
 	unsigned long l, n, flags;
 	u64 base, size, lmb_size;
+	unsigned int is_kexec_kdump = 0, rngs;
 
 	ls = (cell_t *)of_get_flat_dt_prop(node, "ibm,lmb-size", &l);
 	if (ls == NULL || l < dt_root_size_cells * sizeof(cell_t))
@@ -905,6 +906,12 @@ static int __init early_init_dt_scan_drc
 	if (l < (n * (dt_root_addr_cells + 4) + 1) * sizeof(cell_t))
 		return 0;
 
+	/* check if this is a kexec/kdump kernel. */
+	usm = (cell_t *)of_get_flat_dt_prop(node, "linux,drconf-usable-memory",
+						 &l);
+	if (usm != NULL)
+		is_kexec_kdump = 1;
+
 	for (; n != 0; --n) {
 		base = dt_mem_next_cell(dt_root_addr_cells, &dm);
 		flags = dm[3];
@@ -915,13 +922,34 @@ static int __init early_init_dt_scan_drc
 		if ((flags & 0x80) || !(flags & 0x8))
 			continue;
 		size = lmb_size;
-		if (iommu_is_off) {
-			if (base >= 0x80000000ul)
+		rngs = 1;
+		if (is_kexec_kdump) {
+			/*
+			 * For each lmb in ibm,dynamic-memory, a corresponding
+			 * entry in linux,drconf-usable-memory property contains
+			 * a counter 'p' followed by 'p' (base, size) duple.
+			 * Now read the counter from
+			 * linux,drconf-usable-memory property
+			 */
+			rngs = dt_mem_next_cell(dt_root_size_cells, &usm);
+			if (!rngs) /* there are no (base, size) duple */
 				continue;
-			if ((base + size) > 0x80000000ul)
-				size = 0x80000000ul - base;
 		}
-		lmb_add(base, size);
+		do {
+			if (is_kexec_kdump) {
+				base = dt_mem_next_cell(dt_root_addr_cells,
+							 &usm);
+				size = dt_mem_next_cell(dt_root_size_cells,
+							 &usm);
+			}
+			if (iommu_is_off) {
+				if (base >= 0x80000000ul)
+					continue;
+				if ((base + size) > 0x80000000ul)
+					size = 0x80000000ul - base;
+			}
+			lmb_add(base, size);
+		} while (--rngs);
 	}
 	lmb_dump_all();
 	return 0;
diff -Naurp powerpc-orig/arch/powerpc/mm/numa.c powerpc/arch/powerpc/mm/numa.c
--- powerpc-orig/arch/powerpc/mm/numa.c	2008-08-14 08:23:25.000000000 +0530
+++ powerpc/arch/powerpc/mm/numa.c	2008-08-14 14:35:42.000000000 +0530
@@ -150,6 +150,21 @@ static const int *of_get_associativity(s
 	return of_get_property(dev, "ibm,associativity", NULL);
 }
 
+/*
+ * Returns the property linux,drconf-usable-memory if
+ * it exists (the property exists only in kexec/kdump kernels,
+ * added by kexec-tools)
+ */
+static const u32 *of_get_usable_memory(struct device_node *memory)
+{
+	const u32 *prop;
+	u32 len;
+	prop = of_get_property(memory, "linux,drconf-usable-memory", &len);
+	if (!prop || len < sizeof(unsigned int))
+		return 0;
+	return prop;
+}
+
 /* Returns nid in the range [0..MAX_NUMNODES-1], or -1 if no useful numa
  * info is found.
  */
@@ -487,14 +502,29 @@ static unsigned long __init numa_enforce
 }
 
 /*
+ * Reads the counter for a given entry in
+ * linux,drconf-usable-memory property
+ */
+static inline int __init read_usm_ranges(const u32 **usm)
+{
+	/*
+	 * For each lmb in ibm,dynamic-memory a corresponding
+	 * entry in linux,drconf-usable-memory property contains
+	 * a counter followed by that many (base, size) duple.
+	 * read the counter from linux,drconf-usable-memory
+	 */
+	return read_n_cells(n_mem_size_cells, usm);
+}
+
+/*
  * Extract NUMA information from the ibm,dynamic-reconfiguration-memory
  * node.  This assumes n_mem_{addr,size}_cells have been set.
  */
 static void __init parse_drconf_memory(struct device_node *memory)
 {
-	const u32 *dm;
-	unsigned int n, rc;
-	unsigned long lmb_size, size;
+	const u32 *dm, *usm;
+	unsigned int n, rc, ranges, is_kexec_kdump = 0;
+	unsigned long lmb_size, base, size, sz;
 	int nid;
 	struct assoc_arrays aa;
 
@@ -510,6 +540,11 @@ static void __init parse_drconf_memory(s
 	if (rc)
 		return;
 
+	/* check if this is a kexec/kdump kernel */
+	usm = of_get_usable_memory(memory);
+	if (usm != NULL)
+		is_kexec_kdump = 1;
+
 	for (; n != 0; --n) {
 		struct of_drconf_cell drmem;
 
@@ -521,21 +556,31 @@ static void __init parse_drconf_memory(s
 		    || !(drmem.flags & DRCONF_MEM_ASSIGNED))
 			continue;
 
-		nid = of_drconf_to_nid_single(&drmem, &aa);
-
-		fake_numa_create_new_node(
-				((drmem.base_addr + lmb_size) >> PAGE_SHIFT),
+		base = drmem.base_addr;
+		size = lmb_size;
+		ranges = 1;
+
+		if (is_kexec_kdump) {
+			ranges = read_usm_ranges(&usm);
+			if (!ranges) /* there are no (base, size) duple */
+				continue;
+		}
+		do {
+			if (is_kexec_kdump) {
+				base = read_n_cells(n_mem_addr_cells, &usm);
+				size = read_n_cells(n_mem_size_cells, &usm);
+			}
+			nid = of_drconf_to_nid_single(&drmem, &aa);
+			fake_numa_create_new_node(
+				((base + size) >> PAGE_SHIFT),
 					   &nid);
-
-		node_set_online(nid);
-
-		size = numa_enforce_memory_limit(drmem.base_addr, lmb_size);
-		if (!size)
-			continue;
-
-		add_active_range(nid, drmem.base_addr >> PAGE_SHIFT,
-				 (drmem.base_addr >> PAGE_SHIFT)
-				 + (size >> PAGE_SHIFT));
+			node_set_online(nid);
+			sz = numa_enforce_memory_limit(base, size);
+			if (sz)
+				add_active_range(nid, base >> PAGE_SHIFT,
+						 (base >> PAGE_SHIFT)
+						 + (sz >> PAGE_SHIFT));
+		} while (--ranges);
 	}
 }
 

^ permalink raw reply

* [PATCH 2/2][V3] kexec-tools: create a new linux, drconf-usable-memory property
From: Chandru @ 2008-08-14  9:50 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Stephen Rothwell, Michael Neuling, Paul Mackerras

Add a new linux,drconf-usable-memory property to the device tree. This property stores the usable memory regions for kexec/kdump kernel. The other changes to kexec-tools which do not affect the kernel are not attached here.  These are the changes to kexec-tools. Patch 1/2 are the changes in kernel. 

Signed-off-by: Chandru Siddalingappa <chandru@in.ibm.com>
---

 kexec/arch/ppc64/fs2dt.c |   72 +++++++++++++++++++++++++++++++++++++
 1 file changed, 72 insertions(+)

--- kexec-tools-testing-orig/kexec/arch/ppc64/fs2dt.c	2008-08-14 14:41:52.000000000 +0530
+++ kexec-tools-testing/kexec/arch/ppc64/fs2dt.c	2008-08-14 14:46:15.000000000 +0530
@@ -122,6 +122,74 @@ static unsigned propnum(const char *name
 	return offset;
 }
 
+static void add_dyn_reconf_usable_mem_property(int fd)
+{
+	char fname[MAXPATH], *bname;
+	uint64_t buf[32];
+	uint64_t ranges[2*MAX_MEMORY_RANGES];
+	uint64_t base, end, loc_base, loc_end;
+	int range, rlen = 0, i;
+	int rngs_cnt, tmp_indx;
+
+	strcpy(fname, pathname);
+	bname = strrchr(fname, '/');
+	bname[0] = '\0';
+	bname = strrchr(fname, '/');
+	if (strncmp(bname, "/ibm,dynamic-reconfiguration-memory", 36))
+		return;
+
+	if (lseek(fd, 4, SEEK_SET) < 0)
+		die("unrecoverable error: error seeking in \"%s\": %s\n",
+			pathname, strerror(errno));
+
+	rlen = 0;
+	for (i = 0; i < num_of_lmbs; i++) {
+		if (read(fd, buf, 24) < 0)
+			die("unrecoverable error: error reading \"%s\": %s\n",
+				pathname, strerror(errno));
+
+		base = (uint64_t) buf[0];
+		end = base + lmb_size;
+		if (~0ULL - base < end)
+			die("unrecoverable error: mem property overflow\n");
+
+		tmp_indx = rlen++;
+
+		rngs_cnt = 0;
+		for (range = 0; range < usablemem_rgns.size; range++) {
+			loc_base = usablemem_rgns.ranges[range].start;
+			loc_end = usablemem_rgns.ranges[range].end;
+			if (loc_base >= base && loc_end <= end) {
+				ranges[rlen++] = loc_base;
+				ranges[rlen++] = loc_end - loc_base;
+				rngs_cnt++;
+			} else if (base < loc_end && end > loc_base) {
+				if (loc_base < base)
+					loc_base = base;
+				if (loc_end > end)
+					loc_end = end;
+				ranges[rlen++] = loc_base;
+				ranges[rlen++] = loc_end - loc_base;
+				rngs_cnt++;
+			}
+		}
+		/* Store the count of (base, size) duple */
+		ranges[tmp_indx] = rngs_cnt;
+	}
+		
+	rlen = rlen * sizeof(uint64_t);
+	/*
+	 * Add linux,drconf-usable-memory property.
+	 */
+	*dt++ = 3;
+	*dt++ = rlen;
+	*dt++ = propnum("linux,drconf-usable-memory");
+	if ((rlen >= 8) && ((unsigned long)dt & 0x4))
+		dt++;
+	memcpy(dt, &ranges, rlen);
+	dt += (rlen + 3)/4;
+}
+
 static void add_usable_mem_property(int fd, int len)
 {
 	char fname[MAXPATH], *bname;
@@ -267,6 +335,10 @@ static void putprops(char *fn, struct di
 		dt += (len + 3)/4;
 		if (!strcmp(dp->d_name, "reg") && usablemem_rgns.size)
 			add_usable_mem_property(fd, len);
+		if (!strcmp(dp->d_name, "ibm,dynamic-memory") &&
+					usablemem_rgns.size)
+			add_dyn_reconf_usable_mem_property(fd);
+
 		close(fd);
 	}
 

^ permalink raw reply

* Re: [PATCH 1/2] port ndfc driver to of platform
From: Arnd Bergmann @ 2008-08-14  9:53 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: dwmw2, Sean MacLennan
In-Reply-To: <20080813173629.32ec73ee@lappy.seanm.ca>

On Wednesday 13 August 2008, Sean MacLennan wrote:
> Port of the ndfc driver to an of platform driver.

Look good overall, thanks for following up on this.

> +struct ndfc_ctrl {
> +	struct device *dev;
> +	void __iomem *ndfcbase;
> +	struct mtd_info mtd;
> +	struct nand_chip chip;
> +	int chip_select;
> +	struct nand_hw_control ndfc_control;
>  };

conceptually, I would lint to the ofdev, not the dev, even if you
don't need the extra information.

>  static void ndfc_select_chip(struct mtd_info *mtd, int chip)
>  {
>  	uint32_t ccr;
> -	struct ndfc_controller *ndfc = &ndfc_ctrl;
> -	struct nand_chip *nandchip = mtd->priv;
> -	struct ndfc_nand_mtd *nandmtd = nandchip->priv;
> -	struct platform_nand_chip *pchip = nandmtd->pl_chip;
> +	struct ndfc_ctrl *ndfc = &ndfc_ctrl;
>  
>  	ccr = __raw_readl(ndfc->ndfcbase + NDFC_CCR);

This already exists, but I noticed it now: device drivers should
not user __raw_readl/__raw_writel for accessing ioremapped storage.
Instead, you should use ioread32_be or in_be32.

> @@ -83,7 +79,7 @@ static int ndfc_ready(struct mtd_info *mtd)
>  static void ndfc_enable_hwecc(struct mtd_info *mtd, int mode)
>  {
>  	uint32_t ccr;
> -	struct ndfc_controller *ndfc = &ndfc_ctrl;
> +	struct ndfc_ctrl *ndfc = &ndfc_ctrl;
>  
>  	ccr = __raw_readl(ndfc->ndfcbase + NDFC_CCR);
>  	ccr |= NDFC_CCR_RESET_ECC;

You have lots of these changes, which do not appear necessary -- if you
just keep the struct ndfc_controller name, your patch will be a lot
smaller.

> -static int ndfc_nand_probe(struct platform_device *pdev)
> -{
> -	struct platform_nand_ctrl *nc = pdev->dev.platform_data;
> -	struct ndfc_controller_settings *settings = nc->priv;
> -	struct resource *res = pdev->resource;
> -	struct ndfc_controller *ndfc = &ndfc_ctrl;
> -	unsigned long long phys = settings->ndfc_erpn | res->start;
> +	spin_lock_init(&ndfc->ndfc_control.lock);
> +	init_waitqueue_head(&ndfc->ndfc_control.wq);
> +	ndfc->dev = &ofdev->dev;
> +	dev_set_drvdata(&ofdev->dev, ndfc);
> +
> +	/* Read the reg property to get the chip select */
> +	reg = of_get_property(ofdev->node, "reg", &len);
> +	if (reg == NULL || len != 12) {
> +		dev_err(&ofdev->dev, "unable read reg property (%d)\n", len);
> +		return -ENOENT;
> +	}
> +	ndfc->chip_select = *reg;
>  
> -	ndfc->ndfcbase = ioremap((phys_addr_t)phys, res->end - res->start + 1);
> +	ndfc->ndfcbase = ioremap(reg[1], reg[2]);

This could be better expressed as of_iomap().

> -	platform_set_drvdata(pdev, ndfc);
> +	__raw_writel(ccr, ndfc->ndfcbase + NDFC_CCR);
>  
> -	printk("NDFC NAND Driver initialized. Chip-Rev: 0x%08x\n",
> -	       __raw_readl(ndfc->ndfcbase + NDFC_REVID));
> +	/* Set the bank settings */
> +	reg = of_get_property(ofdev->node, "bank_settings", NULL);
> +	bank_settings = reg ? *reg : 0x80002222;

Your device tree does have a bank_setting, so why not assume that
all others will have it as well? I would remove the default.

	Arnd <><

^ permalink raw reply

* mpc52xx localplus bus and dm9000
From: Sinisa Denic @ 2008-08-14  9:52 UTC (permalink / raw)
  To: linuxppc-dev

Hi,I have mpc52xx based board very similar to lite5200b.
There is Davicom DM9000 connected to Local Plus Bus CS0.
Does anybody have idea how should DTS part look like in order to add this 
resource in system.
I've written something like this:

lpb {
                        device_type = "network";
                        compatible = "fsl,lpb";
                        ranges = <0 0 ff000000 1000000>;

                        dm9000@0,0 {
                                compatible = "dm9000";
                                reg = <0 0 100000>;
                                #size-cells = <1>;
                                #address-cells = <1>;
                        };
                };

but it's not working.
Is it enough to have right dts record for default dm9000 driver working
or I have to change something more?
Thank you in andvance.

Sinisa Denic
System and software  engineer
tel: +381(0)112016142
ABS Control Systems
bul.Zorana Djindjica 8a
Belgrade,Serbia

^ permalink raw reply

* Re: [PATCH 2/2] port ndfc driver to of platform
From: Arnd Bergmann @ 2008-08-14 10:08 UTC (permalink / raw)
  To: Sean MacLennan; +Cc: linuxppc-dev, devicetree-discuss
In-Reply-To: <20080813174536.677187f5@lappy.seanm.ca>

On Wednesday 13 August 2008, Sean MacLennan wrote:
> Changes to the warp platform with the ndfc as an of platform device.
> The main changes are:
> 
> * moving the NAND information to the DTS
> * removing warp-nand.c
> * moving the NAND fixups to cuboot-warp.c

The device tree stuff looks good, but the significant fixups you still
need to for the old hw do look like an indication that we should really
have a different way of producing almost-identical dts files.
The cleanest solution for now would be to have two dts files for warp,
but I can understand that you don't want to do that.

Did we ever come to a conclusion on how this could be done, e.g. with
preprocessed dts files or simpler dynamic patching of binary device
trees?

	Arnd <><

^ permalink raw reply

* Re: How to use ramdisk on the ml300?
From: wangyanlong @ 2008-08-14 10:44 UTC (permalink / raw)
  To: linuxppc-embedded
In-Reply-To: <f944af2a0808140004w70948283nde0978d34d1db261@mail.gmail.com>


Hi JensWirth,
    Thanks  for your reply :). I have some questions here.
    (1)You told me "make simpleImage.virtex405-ml300",i only know "make
zImage" and "make zImage.initrd" ,what it is this command mean???
    (2)What is dts ? I don't know what is this :(
Regards,
YanLong:)

  

Jens Wirth wrote:
> 
> Hi Yanlong,
> 
> On Thu, Aug 14, 2008 at 5:08 AM, yanlong wang <killyouatonce@gmail.com>
> wrote:
>>      If i want use ramdisk on the ml300 , i must use u-boot in my system
>> ?
>>     many thanks
> 
> I suppose you want to use an initial ram filesystem as
> rootfs to boot your system?
> 
> You have to point CONFIG_INITRAMFS_SOURCE="" to a cpio
> archive or a directory which contains your rootfs. If
> you use a directory structure then you should set your
> uid/gid to make the build process convert the owner
> to root:
> 
> # if your uid/gid is 500:
> CONFIG_INITRAMFS_ROOT_UID=500
> CONFIG_INITRAMFS_ROOT_GID=500
> 
> Don't forget to set CONFIG_BLK_DEV_RAM=y to be able
> to use a ramdisk at all.
> 
> I'm also using the ml300 board and I create my kernel
> with: make simpleImage.virtex405-ml300
> 
> My dts is arch/powerpc/boot/dts/virtex405-ml300.dts.
> There is no kernel boot command line needed to use
> the initramfs in my case (I only set up my console
> to the uart). Just download the image
> arch/powerpc/boot/simpleImage.virtex405-ml300.elf
> with xmd to your ml300 and run it.
> 
> I hope this works for you.
> 
> Regards
> Jens
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
> 
> 

-- 
View this message in context: http://www.nabble.com/How-to-use-ramdisk-on-the-ml300--tp18975066p18979320.html
Sent from the linuxppc-embedded mailing list archive at Nabble.com.

^ permalink raw reply

* Re: [RFC 2/2] powerpc: copy_4K_page tweaked for Cell - add CPU feature
From: Michael Ellerman @ 2008-08-14 10:51 UTC (permalink / raw)
  To: Mark Nelson; +Cc: linuxppc-dev, cbe-oss-dev
In-Reply-To: <200808141618.23818.markn@au1.ibm.com>

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

On Thu, 2008-08-14 at 16:18 +1000, Mark Nelson wrote:
> Add a new CPU feature, CPU_FTR_CP_USE_DCBTZ, to be added to the CPUs that benefit
> from having dcbt and dcbz instructions used in copy_4K_page(). So far Cell, PPC970
> and Power4 benefit.
> 
> This way all the other 64bit powerpc chips will have the whole prefetching loop
> nop'ed out.

> Index: upstream/arch/powerpc/lib/copypage_64.S
> ===================================================================
> --- upstream.orig/arch/powerpc/lib/copypage_64.S
> +++ upstream/arch/powerpc/lib/copypage_64.S
> @@ -18,6 +18,7 @@ PPC64_CACHES:
>  
>  _GLOBAL(copy_4K_page)
>  	li	r5,4096		/* 4K page size */
> +BEGIN_FTR_SECTION
>  	ld      r10,PPC64_CACHES@toc(r2)
>  	lwz	r11,DCACHEL1LOGLINESIZE(r10)	/* log2 of cache line size */
>  	lwz     r12,DCACHEL1LINESIZE(r10)	/* Get cache line size */
> @@ -30,7 +31,7 @@ setup:
>  	dcbz	r9,r3
>  	add	r9,r9,r12
>  	bdnz	setup
> -
> +END_FTR_SECTION_IFSET(CPU_FTR_CP_USE_DCBTZ)
>  	addi	r3,r3,-8
>  	srdi    r8,r5,7		/* page is copied in 128 byte strides */
>  	addi	r8,r8,-1	/* one stride copied outside loop */

Instead of nop'ing it out, we could use an alternative feature section
to either run it or jump over it. It would look something like:


_GLOBAL(copy_4K_page)
BEGIN_FTR_SECTION
        li      r5,4096         /* 4K page size */
        ld      r10,PPC64_CACHES@toc(r2)
        lwz     r11,DCACHEL1LOGLINESIZE(r10)    /* log2 of cache line size */
        lwz     r12,DCACHEL1LINESIZE(r10)       /* Get cache line size */
        li      r9,0
        srd     r8,r5,r11

        mtctr   r8
setup:
        dcbt    r9,r4
        dcbz    r9,r3
        add     r9,r9,r12
        bdnz    setup
FTR_SECTION_ELSE
	b	1f
ALT_FTR_SECTION_END_IFSET(CPU_FTR_CP_USE_DCBTZ)
1:
        addi    r3,r3,-8

So in the no-dcbtz case you'd get a branch instead of 11 nops.

Of course you'd need to benchmark it to see if skipping the nops is
better than executing them ;P

cheers

-- 
Michael Ellerman
OzLabs, IBM Australia Development Lab

wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)

We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person

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

^ permalink raw reply

* Re: bug in lmb_enforce_memory_limit()
From: Michael Ellerman @ 2008-08-14 11:26 UTC (permalink / raw)
  To: David Miller; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <20080814.012004.193702132.davem@davemloft.net>

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

On Thu, 2008-08-14 at 01:20 -0700, David Miller wrote:
> I just mentioned this to Ben H. on IRC and promised I would report it
> here. :-)
> 
> The first loop over lmb.memory in this function interprets the
> memory_limit as a raw size limit, and that's fine so far.
> 
> But the second loop over lmb.reserved interprets this value
> instead as an "address limit."
>
> I haven't cobbled together a fix myself, but probably the way to do
> this is, when we're about break out of the first loop over lmb.memory,
> walk through the now-trimmed memory blobs and trim those from
> lmb.reserved, one by one.

Perhaps after the first loop we should set memory_limit to equal
lmb_end_of_DRAM(), then the second loop should work as it is.

I think that actually makes memory_limit (the variable) more useful, and
avoids more code like we have in numa_enforce_memory_limit(), which
doesn't use memory_limit exactly because it isn't the value we're
actually interested in (because of holes).


> This bug got introduced by:
> 
>    commit 2babf5c2ec2f2d5de3e38d20f7df7fd815fd10c9
>    Author: Michael Ellerman <michael@ellerman.id.au>
>    Date:   Wed May 17 18:00:46 2006 +1000
> 
>        [PATCH] powerpc: Unify mem= handling
> 
> back when LMB was still a powerpc local item. :-)

Guilty as charged. I have some tests for that code, but clearly not
enough - and it gets very little exercise otherwise.

> This led me to another bug which probably a lot of platforms are
> effected by.
> 
> If you do this command line memory limiting, and the kernel was placed
> by the boot loader into physical ram (say at the end of the available
> physical memory) that gets trimmed out by the command line option, we
> hang or crash right as we boot into userspace because freeing up
> initmem ends up freeing invalid page structs.
> 
> I think, on sparc64, instead of adding all kinds of complicated logic
> to free_initmem() I'm simply going to only poison the pages and
> not free them at all if cmdline_memory_size has been set.

Would it be that much extra logic to check that the address is less than
the limit? Especially if we changed memory_limit to incorporate holes.

cheers

-- 
Michael Ellerman
OzLabs, IBM Australia Development Lab

wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)

We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person

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

^ permalink raw reply

* Re: [RFC 2/2] powerpc: copy_4K_page tweaked for Cell - add CPU feature
From: Mark Nelson @ 2008-08-14 11:48 UTC (permalink / raw)
  To: michael; +Cc: linuxppc-dev, cbe-oss-dev
In-Reply-To: <1218711095.10673.4.camel@localhost>

Hi Michael,

On Thu, 14 Aug 2008 08:51:35 pm Michael Ellerman wrote:
> On Thu, 2008-08-14 at 16:18 +1000, Mark Nelson wrote:
> > Add a new CPU feature, CPU_FTR_CP_USE_DCBTZ, to be added to the CPUs that benefit
> > from having dcbt and dcbz instructions used in copy_4K_page(). So far Cell, PPC970
> > and Power4 benefit.
> > 
> > This way all the other 64bit powerpc chips will have the whole prefetching loop
> > nop'ed out.
> 
> > Index: upstream/arch/powerpc/lib/copypage_64.S
> > ===================================================================
> > --- upstream.orig/arch/powerpc/lib/copypage_64.S
> > +++ upstream/arch/powerpc/lib/copypage_64.S
> > @@ -18,6 +18,7 @@ PPC64_CACHES:
> >  
> >  _GLOBAL(copy_4K_page)
> >  	li	r5,4096		/* 4K page size */
> > +BEGIN_FTR_SECTION
> >  	ld      r10,PPC64_CACHES@toc(r2)
> >  	lwz	r11,DCACHEL1LOGLINESIZE(r10)	/* log2 of cache line size */
> >  	lwz     r12,DCACHEL1LINESIZE(r10)	/* Get cache line size */
> > @@ -30,7 +31,7 @@ setup:
> >  	dcbz	r9,r3
> >  	add	r9,r9,r12
> >  	bdnz	setup
> > -
> > +END_FTR_SECTION_IFSET(CPU_FTR_CP_USE_DCBTZ)
> >  	addi	r3,r3,-8
> >  	srdi    r8,r5,7		/* page is copied in 128 byte strides */
> >  	addi	r8,r8,-1	/* one stride copied outside loop */
> 
> Instead of nop'ing it out, we could use an alternative feature section
> to either run it or jump over it. It would look something like:
> 
> 
> _GLOBAL(copy_4K_page)
> BEGIN_FTR_SECTION
>         li      r5,4096         /* 4K page size */
>         ld      r10,PPC64_CACHES@toc(r2)
>         lwz     r11,DCACHEL1LOGLINESIZE(r10)    /* log2 of cache line size */
>         lwz     r12,DCACHEL1LINESIZE(r10)       /* Get cache line size */
>         li      r9,0
>         srd     r8,r5,r11
> 
>         mtctr   r8
> setup:
>         dcbt    r9,r4
>         dcbz    r9,r3
>         add     r9,r9,r12
>         bdnz    setup
> FTR_SECTION_ELSE
> 	b	1f
> ALT_FTR_SECTION_END_IFSET(CPU_FTR_CP_USE_DCBTZ)
> 1:
>         addi    r3,r3,-8
> 
> So in the no-dcbtz case you'd get a branch instead of 11 nops.
> 
> Of course you'd need to benchmark it to see if skipping the nops is
> better than executing them ;P

Thanks for looking through this.

That does look a lot better. In the first version there wasn't quite
as much to nop out (the cache line size was hardcoded to 128
bytes) so I wasn't so worried but I'll definitely try this with an
alternative section like you describe.

The jump probably will turn out to be better because I'd imagine
that the same chips that don't need the dcbt and dcbz because
they've got beefy enough hardware prefetchers also won't be
disturbed by the jump (but benchmarks tomorrow will confirm;
or prove me wrong :) )

Thanks!

Mark

^ permalink raw reply

* Re: [PATCH] libfdt: Add support for using aliases in fdt_path_offset()
From: Kumar Gala @ 2008-08-14 12:02 UTC (permalink / raw)
  To: David Gibson; +Cc: linuxppc-dev, Jon Loeliger, devicetree-discuss
In-Reply-To: <20080814041557.GE18344@yookeroo.seuss>


On Aug 13, 2008, at 11:15 PM, David Gibson wrote:

> On Wed, Aug 13, 2008 at 10:52:26PM -0500, Kumar Gala wrote:
>> If the path doesn't start with '/' check to see if it matches some  
>> alias
>> under "/aliases" and substitute the matching alias value in the path
>> and retry the lookup.
>
> Kumar, this is broken.  If you match an alias you only follow the path
> one level down from there.  i.e. you will correctly resolve
> 'somealias' and 'somealias/foo', but not 'somealias/foo/bar'.

I'm not clear on what cases you are suggesting fail.

- k

^ permalink raw reply

* Re: [RFC 2/2] powerpc: copy_4K_page tweaked for Cell - add CPU feature
From: Michael Ellerman @ 2008-08-14 12:10 UTC (permalink / raw)
  To: Mark Nelson; +Cc: linuxppc-dev, cbe-oss-dev
In-Reply-To: <200808142148.57218.markn@au1.ibm.com>

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

On Thu, 2008-08-14 at 21:48 +1000, Mark Nelson wrote:
> Hi Michael,
> 
> On Thu, 14 Aug 2008 08:51:35 pm Michael Ellerman wrote:
> > On Thu, 2008-08-14 at 16:18 +1000, Mark Nelson wrote:
> > > Add a new CPU feature, CPU_FTR_CP_USE_DCBTZ, to be added to the CPUs that benefit
> > > from having dcbt and dcbz instructions used in copy_4K_page(). So far Cell, PPC970
> > > and Power4 benefit.
> > > 
> > > This way all the other 64bit powerpc chips will have the whole prefetching loop
> > > nop'ed out.
> > 
> > > Index: upstream/arch/powerpc/lib/copypage_64.S
> > > ===================================================================
> > > --- upstream.orig/arch/powerpc/lib/copypage_64.S
> > > +++ upstream/arch/powerpc/lib/copypage_64.S
> > > @@ -18,6 +18,7 @@ PPC64_CACHES:
> > >  
> > >  _GLOBAL(copy_4K_page)
> > >  	li	r5,4096		/* 4K page size */
> > > +BEGIN_FTR_SECTION
> > >  	ld      r10,PPC64_CACHES@toc(r2)
> > >  	lwz	r11,DCACHEL1LOGLINESIZE(r10)	/* log2 of cache line size */
> > >  	lwz     r12,DCACHEL1LINESIZE(r10)	/* Get cache line size */
> > > @@ -30,7 +31,7 @@ setup:
> > >  	dcbz	r9,r3
> > >  	add	r9,r9,r12
> > >  	bdnz	setup
> > > -
> > > +END_FTR_SECTION_IFSET(CPU_FTR_CP_USE_DCBTZ)
> > >  	addi	r3,r3,-8
> > >  	srdi    r8,r5,7		/* page is copied in 128 byte strides */
> > >  	addi	r8,r8,-1	/* one stride copied outside loop */
> > 
> > Instead of nop'ing it out, we could use an alternative feature section
> > to either run it or jump over it. It would look something like:
> > 
> > 
> > _GLOBAL(copy_4K_page)
> > BEGIN_FTR_SECTION
> >         li      r5,4096         /* 4K page size */
> >         ld      r10,PPC64_CACHES@toc(r2)
> >         lwz     r11,DCACHEL1LOGLINESIZE(r10)    /* log2 of cache line size */
> >         lwz     r12,DCACHEL1LINESIZE(r10)       /* Get cache line size */
> >         li      r9,0
> >         srd     r8,r5,r11
> > 
> >         mtctr   r8
> > setup:
> >         dcbt    r9,r4
> >         dcbz    r9,r3
> >         add     r9,r9,r12
> >         bdnz    setup
> > FTR_SECTION_ELSE
> > 	b	1f
> > ALT_FTR_SECTION_END_IFSET(CPU_FTR_CP_USE_DCBTZ)
> > 1:
> >         addi    r3,r3,-8
> > 
> > So in the no-dcbtz case you'd get a branch instead of 11 nops.
> > 
> > Of course you'd need to benchmark it to see if skipping the nops is
> > better than executing them ;P
> 
> Thanks for looking through this.
> 
> That does look a lot better. In the first version there wasn't quite
> as much to nop out (the cache line size was hardcoded to 128
> bytes) so I wasn't so worried but I'll definitely try this with an
> alternative section like you describe.
> 
> The jump probably will turn out to be better because I'd imagine
> that the same chips that don't need the dcbt and dcbz because
> they've got beefy enough hardware prefetchers also won't be
> disturbed by the jump (but benchmarks tomorrow will confirm;
> or prove me wrong :) )

Yeah, that would make sense. But you never know :)

cheers

-- 
Michael Ellerman
OzLabs, IBM Australia Development Lab

wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)

We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person

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

^ permalink raw reply

* Re: [PATCH 0/3] Patches to support QE USB Host Controller
From: Laurent Pinchart @ 2008-08-14 12:15 UTC (permalink / raw)
  To: linuxppc-dev, avorontsov
  Cc: David Brownell, Greg Kroah-Hartman, linux-usb, linux-kernel,
	Li Yang, Timur Tabi
In-Reply-To: <20080808161717.GA19095@polina.dev.rtsoft.ru>

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

On Friday 08 August 2008, Anton Vorontsov wrote:
> Hi all,
> 
> Most patches that were needed to support QE USB Host were merged during
> 2.6.27 merge window, and only three more patches left over. Here they
> are.
> 
> David, could you bear with gpio_to_chip() exported function, just as
> a stopgap for a proper api?

I need gpio_to_chip() (or another 'proper API') as well for RTS/CTS based flow control in the CPM/CPM2 UART driver.

Best regards,

-- 
Laurent Pinchart
CSE Semaphore Belgium

Chaussee de Bruxelles, 732A
B-1410 Waterloo
Belgium

T +32 (2) 387 42 59
F +32 (2) 387 42 75

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

^ permalink raw reply

* [PATCH] RE: Some memory (DDR2 ECC Dual Rank) just doesn't work! Can anyone pointme to how to debug this hang?
From: Fillod Stephane @ 2008-08-14 12:05 UTC (permalink / raw)
  To: Vince Asbridge, linuxppc-embedded; +Cc: u-boot

Vince Asbridge wrote:
> We have an 8548 design, which implements a DDR2 on a SODIMM=20
> We have an issue with dual rank memory (specific part number Viking =
VR5DR287218EBSS1), which is a 1G ECC Registered SODIMM part, with two =
ranks.
> Our platform wires CS0 and CS1 to the SODIMM slot.=20
> At uBoot, all is well.=A0 Memory is discovered as ECC 533, 1G DDR2 =
64Bit 4 beat bursts, and mtest can read and write all 1G of the SODIMM.
[...]
> Other DDR2s (identical except for vendor and # of ranks), work =
perfectly!=20
> Anyone got a clue what I could look at to try to figure this out?=20
> We've tried enable / disable ECC at uboot=20
> We've tried enable / disable Interleaving at uboot=20
> uboot always works (and can read/write entire DDR), Linux always hangs =
on boot!=20

U-Boot is too gentle when testing SDRAM. Make sure the caches are =
enabled
under U-Boot, and put on heavy stress with DMA, pipelined prefetch's, =
etc.
This is what your CPU is enduring under Linux.=20

Your question is definitely a question for the U-Boot mailing list.
BTW, what is the version of U-Boot in use? U-Boot is still missing
the following patch:

MPC85xx BA bits not set for 3-bit bank address DIMM of CS1

The current implementation set the number of bank address bits
(BA) in the processor for CS0 but not for CS1.=20

Signed-off-by: Stephane Fillod <stephane.fillod@thomson.net>

--- u-boot/cpu/mpc85xx/spd_sdram.c
+++ u-boot/cpu/mpc85xx/spd_sdram.c
@@ -365,6 +365,7 @@
                ddr->cs1_config =3D ( 1<<31
                                    | (odt_rd_cfg << 20)
                                    | (odt_wr_cfg << 16)
+                                   | (ba_bits << 14)
                                    | (spd.nrow_addr - 12) << 8
                                    | (spd.ncol_addr - 8) );
                debug("DDR: cs1_bnds   =3D 0x%08x\n", ddr->cs1_bnds);



Otherwise, recompile with -DDEBUG and CFG_CMD_SDRAM, grab the Viking =
datasheet=20
and a scope, and a full cup of coffee/tea much needed during =
cross-checking :-)

Cheers
--=20
Stephane

^ permalink raw reply

* [PATCH v2] libfdt: Add support for using aliases in fdt_path_offset()
From: Kumar Gala @ 2008-08-14 12:51 UTC (permalink / raw)
  To: jdl, devicetree-discuss; +Cc: linuxppc-dev, David Gibson

If the path doesn't start with '/' check to see if it matches some alias
under "/aliases" and substitute the matching alias value in the path
and retry the lookup.

Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---

Fixed the bug pointed out by David Gibson and added tests.

- k

 libfdt/fdt_ro.c             |   21 ++++++++++++++-
 tests/Makefile.tests        |    2 +-
 tests/aliases.dts           |   31 ++++++++++++++++++++++
 tests/path_offset_aliases.c |   59 +++++++++++++++++++++++++++++++++++++++++++
 tests/run_tests.sh          |    4 +++
 5 files changed, 114 insertions(+), 3 deletions(-)
 create mode 100644 tests/aliases.dts
 create mode 100644 tests/path_offset_aliases.c

diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c
index ebd1260..2f3ff48 100644
--- a/libfdt/fdt_ro.c
+++ b/libfdt/fdt_ro.c
@@ -139,8 +139,25 @@ int fdt_path_offset(const void *fdt, const char *path)

 	FDT_CHECK_HEADER(fdt);

-	if (*path != '/')
-		return -FDT_ERR_BADPATH;
+	/* see if we have an alias */
+	if (*path != '/') {
+		const char *q;
+		int aliasoffset = fdt_path_offset(fdt, "/aliases");
+
+		if (aliasoffset < 0)
+			return -FDT_ERR_BADPATH;
+
+		q = strchr(path, '/');
+		if (!q)
+			q = end;
+
+		p = fdt_getprop_namelen(fdt, aliasoffset, path, q - p, NULL);
+		if (!p)
+			return -FDT_ERR_BADPATH;
+		offset = fdt_path_offset(fdt, p);
+
+		p = q;
+	}

 	while (*p) {
 		const char *q;
diff --git a/tests/Makefile.tests b/tests/Makefile.tests
index 704c95d..44021b0 100644
--- a/tests/Makefile.tests
+++ b/tests/Makefile.tests
@@ -11,7 +11,7 @@ LIB_TESTS_L = get_mem_rsv \
 	open_pack rw_tree1 set_name setprop del_property del_node \
 	string_escapes references path-references boot-cpuid incbin \
 	dtbs_equal_ordered \
-	add_subnode_with_nops
+	add_subnode_with_nops path_offset_aliases
 LIB_TESTS = $(LIB_TESTS_L:%=$(TESTS_PREFIX)%)

 LIBTREE_TESTS_L = truncated_property
diff --git a/tests/aliases.dts b/tests/aliases.dts
new file mode 100644
index 0000000..bd0e6bf
--- /dev/null
+++ b/tests/aliases.dts
@@ -0,0 +1,31 @@
+/dts-v1/;
+
+/memreserve/ 0xdeadbeef00000000 0x100000;
+/memreserve/ 123456789 010000;
+
+/ {
+	compatible = "test_tree1";
+	prop-int = <0xdeadbeef>;
+	prop-str = "hello world";
+
+	aliases {
+		s1 = &sub1;
+		ss1 = &subsub1;
+		sss1 = &subsubsub1;
+	};
+
+	sub1: subnode@1 {
+		compatible = "subnode1";
+		prop-int = [deadbeef];
+
+		subsub1: subsubnode {
+			compatible = "subsubnode1", "subsubnode";
+			prop-int = <0xdeadbeef>;
+
+			subsubsub1: subsubsubnode {
+				compatible = "subsubsubnode1", "subsubsubnode";
+				prop-int = <0xdeadbeef>;
+			};
+		};
+	};
+};
diff --git a/tests/path_offset_aliases.c b/tests/path_offset_aliases.c
new file mode 100644
index 0000000..191edd2
--- /dev/null
+++ b/tests/path_offset_aliases.c
@@ -0,0 +1,59 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ *	Testcase for fdt_path_offset()
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ * Copyright 2008 Kumar Gala, Freescale Semiconductor, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+void check_alias(void *fdt, const char *full_path, const char *alias_path)
+{
+	int offset, offset_a;
+
+	offset = fdt_path_offset(fdt, full_path);
+	offset_a = fdt_path_offset(fdt, alias_path);
+
+	if (offset != offset_a)
+		FAIL("Mismatch between %s path_offset (%d) and %s path_offset alias (%d)",
+		     full_path, offset, alias_path, offset_a);
+}
+
+int main(int argc, char *argv[])
+{
+	void *fdt;
+
+	test_init(argc, argv);
+	fdt = load_blob_arg(argc, argv);
+
+	check_alias(fdt, "/subnode@1", "s1");
+	check_alias(fdt, "/subnode@1/subsubnode", "ss1");
+	check_alias(fdt, "/subnode@1/subsubnode", "s1/subsubnode");
+	check_alias(fdt, "/subnode@1/subsubnode/subsubsubnode", "sss1");
+	check_alias(fdt, "/subnode@1/subsubnode/subsubsubnode", "ss1/subsubsubnode");
+	check_alias(fdt, "/subnode@1/subsubnode/subsubsubnode", "s1/subsubnode/subsubsubnode");
+
+	PASS();
+}
diff --git a/tests/run_tests.sh b/tests/run_tests.sh
index 7bfc399..eb29462 100755
--- a/tests/run_tests.sh
+++ b/tests/run_tests.sh
@@ -214,6 +214,10 @@ dtc_tests () {
     run_dtc_test -I dts -O dtb -o dtc_comments-cmp.test.dtb comments-cmp.dts
     run_test dtbs_equal_ordered dtc_comments.test.dtb dtc_comments-cmp.test.dtb

+    # Check aliases support in fdt_path_offset
+    run_dtc_test -I dts -O dtb -o aliases.dtb aliases.dts
+    run_test path_offset_aliases aliases.dtb
+
     # Check /include/ directive
     run_dtc_test -I dts -O dtb -o includes.test.dtb include0.dts
     run_test dtbs_equal_ordered includes.test.dtb test_tree1.dtb
-- 
1.5.5.1

^ permalink raw reply related

* Re: [RFC/PATCH v2] powerpc: add ioremap_early() function for mapping IO regions before MMU_init()
From: Kumar Gala @ 2008-08-14 13:00 UTC (permalink / raw)
  To: Grant Likely; +Cc: miltonm, linuxppc-dev, paulus, scottwood
In-Reply-To: <20080813025726.26033.29519.stgit@trillian.secretlab.ca>


On Aug 12, 2008, at 10:03 PM, Grant Likely wrote:

> +/**
> + * ioremap_early - Allow large persistant IO regions to be mapped  
> early.
> + * @addr: physical address of region
> + * @size: size of region
> + *
> + * This routine uses setbat() to set up IO ranges before the MMU is
> + * fully configured.
> + *
> + * This routine can be called really early, before MMU_init() is  
> called.  It
> + * is useful for setting up early debug output consoles and  
> frequently
> + * accessed IO regions, like the internally memory mapped registers  
> (IMMR)
> + * in an SoC.  Ranges mapped with this function persist even after  
> MMU_init()
> + * is called and the MMU is turned on 'for real.'
> + *
> + * The region mapped is large (minimum size of 128k) and virtual  
> mapping must
> + * be aligned against this boundary.  Therefore, to avoid  
> fragmentation all
> + * calls to ioremap_early() are best made before any calls to ioremap
> + * for smaller regions.
> + */
> +void __iomem * __init
> +ioremap_early(phys_addr_t addr, unsigned long size)
> +{
> +	unsigned long v, p;
> +	int i;
> +
> +	/* Be loud and annoying if someone calls this too late.
> +	 * No need to crash the kernel though */
> +	WARN_ON(mem_init_done);
> +	if (mem_init_done)
> +		return NULL;
> +
> +	/* Make sure request is sane */
> +	if (size == 0)
> +		return NULL;
> +
> +	/* If the region is already block mapped, then there is nothing
> +	 * to do; just return the mapped address */
> +	v = p_mapped_by_bats(addr);
> +	if (v)
> +		return (void __iomem *)v;
> +
> +	/* Adjust size to reflect aligned region */
> +	p = _ALIGN_DOWN(addr, 128 << 10); /* BATs align on 128k boundaries  
> */
> +	size = ALIGN(addr - p + size, 128 << 10);
> +
> +	/* Allocate the aligned virtual base address.  ALIGN_DOWN is used
> +	 * to ensure no overlaps occur with normal 4k ioremaps. */
> +	v = ioremap_bot = _ALIGN_DOWN(ioremap_bot, 128 << 10) - size;
> +
> +	/* Set up a BAT for this IO region */
> +	i = loadbat(v, p, size, _PAGE_IO);

what happens if we run out of bats?


does this actually build on any non-BAT based ppc32 system?

>
> +	if (i < 0)
> +		return NULL;
> +
> +	return (void __iomem *) (v + (addr - p));
> +}
> +

^ permalink raw reply

* [PATCH 2.6.27] [POWERPC] Invalidate all TLB entries in a specified range
From: Rocky Craig @ 2008-08-14 13:11 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: paulus, Linux Kernel

From: Rocky Craig <rocky.craig@hp.com>

The apparent intent of "flush_tlbs" is to invalidate TLB entries that
might match in the address range 0 to 0x00400000.  A loop counter is 
set up at the high value and decremented by page size.  However, the 
loop is only done once as the sense of the conditional branch at the
loop end does not match the setup/decrement.

Signed-off-by: Rocky Craig <rocky.craig@hp.com>
---

Source is from 2.6.27 development, but the bug appears as far back as 2.4.0.
The small user-space program below demonstrates the loop behavior.  It was
compiled via crosstool gcc 3.4.5 / glibc 2.3.6 for an MPC8347 target.

int main()
{
	long endval;				// 16(r31)

	__asm__ __volatile__(
		"	lis 10,0x40\n"
		"1:	addic. 10,10,-0x1000\n"
		"	bgt 1b\n"
		"	stw 10,16(31)\n");	// endval

	printf("end value = 0x%08lx\n", endval);
}

This might win the prize for "Smallest actual code patch ever".

--- a/arch/powerpc/kernel/head_32.S.orig	2008-07-24 19:25:09.000000000 -0600
+++ a/arch/powerpc/kernel/head_32.S	2008-07-24 19:25:22.000000000 -0600
@@ -1155,7 +1155,7 @@ flush_tlbs:
 	lis	r10, 0x40
 1:	addic.	r10, r10, -0x1000
 	tlbie	r10
-	blt	1b
+	bgt	1b
 	sync
 	blr
 

^ permalink raw reply

* Re: [PATCH v2] libfdt: Add support for using aliases in fdt_path_offset()
From: David Gibson @ 2008-08-14 13:21 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev, devicetree-discuss
In-Reply-To: <Pine.LNX.4.64.0808140750550.22943@blarg.am.freescale.net>

On Thu, Aug 14, 2008 at 07:51:47AM -0500, Kumar Gala wrote:
> If the path doesn't start with '/' check to see if it matches some alias
> under "/aliases" and substitute the matching alias value in the path
> and retry the lookup.
> 
> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
> ---
> 
> Fixed the bug pointed out by David Gibson and added tests.

Glad you spotted it in the end :)

[snip[]
> diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c
> index ebd1260..2f3ff48 100644
> --- a/libfdt/fdt_ro.c
> +++ b/libfdt/fdt_ro.c
> @@ -139,8 +139,25 @@ int fdt_path_offset(const void *fdt, const char *path)
> 
>  	FDT_CHECK_HEADER(fdt);
> 
> -	if (*path != '/')
> -		return -FDT_ERR_BADPATH;
> +	/* see if we have an alias */
> +	if (*path != '/') {
> +		const char *q;
> +		int aliasoffset = fdt_path_offset(fdt, "/aliases");
> +
> +		if (aliasoffset < 0)
> +			return -FDT_ERR_BADPATH;
> +
> +		q = strchr(path, '/');
> +		if (!q)
> +			q = end;
> +
> +		p = fdt_getprop_namelen(fdt, aliasoffset, path, q - p, NULL);
> +		if (!p)
> +			return -FDT_ERR_BADPATH;
> +		offset = fdt_path_offset(fdt, p);
> +
> +		p = q;
> +	}

Much better.  It would be quite nice to have an explicit way of
retreiving the aliases too, but I can factor that out easily enough in
a later patch.

[snip]
> --- /dev/null
> +++ b/tests/aliases.dts
> @@ -0,0 +1,31 @@
> +/dts-v1/;
> +
> +/memreserve/ 0xdeadbeef00000000 0x100000;
> +/memreserve/ 123456789 010000;

I'd drop these /memreserve/s, they're not relevant to the test.

> +
> +/ {
> +	compatible = "test_tree1";
> +	prop-int = <0xdeadbeef>;
> +	prop-str = "hello world";

Likewise the various prop-int and prop-str properties.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

^ permalink raw reply

* [PATCH v3] libfdt: Add support for using aliases in fdt_path_offset()
From: Kumar Gala @ 2008-08-14 13:28 UTC (permalink / raw)
  To: jdl, devicetree-discuss; +Cc: linuxppc-dev, David Gibson

If the path doesn't start with '/' check to see if it matches some alias
under "/aliases" and substitute the matching alias value in the path
and retry the lookup.

Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---

Simplify down the aliases.dts to only whats needed for the test.

- k

 libfdt/fdt_ro.c             |   21 ++++++++++++++-
 tests/Makefile.tests        |    2 +-
 tests/aliases.dts           |   21 +++++++++++++++
 tests/path_offset_aliases.c |   59 +++++++++++++++++++++++++++++++++++++++++++
 tests/run_tests.sh          |    4 +++
 5 files changed, 104 insertions(+), 3 deletions(-)
 create mode 100644 tests/aliases.dts
 create mode 100644 tests/path_offset_aliases.c

diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c
index ebd1260..2f3ff48 100644
--- a/libfdt/fdt_ro.c
+++ b/libfdt/fdt_ro.c
@@ -139,8 +139,25 @@ int fdt_path_offset(const void *fdt, const char *path)

 	FDT_CHECK_HEADER(fdt);

-	if (*path != '/')
-		return -FDT_ERR_BADPATH;
+	/* see if we have an alias */
+	if (*path != '/') {
+		const char *q;
+		int aliasoffset = fdt_path_offset(fdt, "/aliases");
+
+		if (aliasoffset < 0)
+			return -FDT_ERR_BADPATH;
+
+		q = strchr(path, '/');
+		if (!q)
+			q = end;
+
+		p = fdt_getprop_namelen(fdt, aliasoffset, path, q - p, NULL);
+		if (!p)
+			return -FDT_ERR_BADPATH;
+		offset = fdt_path_offset(fdt, p);
+
+		p = q;
+	}

 	while (*p) {
 		const char *q;
diff --git a/tests/Makefile.tests b/tests/Makefile.tests
index 704c95d..44021b0 100644
--- a/tests/Makefile.tests
+++ b/tests/Makefile.tests
@@ -11,7 +11,7 @@ LIB_TESTS_L = get_mem_rsv \
 	open_pack rw_tree1 set_name setprop del_property del_node \
 	string_escapes references path-references boot-cpuid incbin \
 	dtbs_equal_ordered \
-	add_subnode_with_nops
+	add_subnode_with_nops path_offset_aliases
 LIB_TESTS = $(LIB_TESTS_L:%=$(TESTS_PREFIX)%)

 LIBTREE_TESTS_L = truncated_property
diff --git a/tests/aliases.dts b/tests/aliases.dts
new file mode 100644
index 0000000..39d88ff
--- /dev/null
+++ b/tests/aliases.dts
@@ -0,0 +1,21 @@
+/dts-v1/;
+
+/ {
+	aliases {
+		s1 = &sub1;
+		ss1 = &subsub1;
+		sss1 = &subsubsub1;
+	};
+
+	sub1: subnode@1 {
+		compatible = "subnode1";
+
+		subsub1: subsubnode {
+			compatible = "subsubnode1", "subsubnode";
+
+			subsubsub1: subsubsubnode {
+				compatible = "subsubsubnode1", "subsubsubnode";
+			};
+		};
+	};
+};
diff --git a/tests/path_offset_aliases.c b/tests/path_offset_aliases.c
new file mode 100644
index 0000000..191edd2
--- /dev/null
+++ b/tests/path_offset_aliases.c
@@ -0,0 +1,59 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ *	Testcase for fdt_path_offset()
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ * Copyright 2008 Kumar Gala, Freescale Semiconductor, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+void check_alias(void *fdt, const char *full_path, const char *alias_path)
+{
+	int offset, offset_a;
+
+	offset = fdt_path_offset(fdt, full_path);
+	offset_a = fdt_path_offset(fdt, alias_path);
+
+	if (offset != offset_a)
+		FAIL("Mismatch between %s path_offset (%d) and %s path_offset alias (%d)",
+		     full_path, offset, alias_path, offset_a);
+}
+
+int main(int argc, char *argv[])
+{
+	void *fdt;
+
+	test_init(argc, argv);
+	fdt = load_blob_arg(argc, argv);
+
+	check_alias(fdt, "/subnode@1", "s1");
+	check_alias(fdt, "/subnode@1/subsubnode", "ss1");
+	check_alias(fdt, "/subnode@1/subsubnode", "s1/subsubnode");
+	check_alias(fdt, "/subnode@1/subsubnode/subsubsubnode", "sss1");
+	check_alias(fdt, "/subnode@1/subsubnode/subsubsubnode", "ss1/subsubsubnode");
+	check_alias(fdt, "/subnode@1/subsubnode/subsubsubnode", "s1/subsubnode/subsubsubnode");
+
+	PASS();
+}
diff --git a/tests/run_tests.sh b/tests/run_tests.sh
index 7bfc399..eb29462 100755
--- a/tests/run_tests.sh
+++ b/tests/run_tests.sh
@@ -214,6 +214,10 @@ dtc_tests () {
     run_dtc_test -I dts -O dtb -o dtc_comments-cmp.test.dtb comments-cmp.dts
     run_test dtbs_equal_ordered dtc_comments.test.dtb dtc_comments-cmp.test.dtb

+    # Check aliases support in fdt_path_offset
+    run_dtc_test -I dts -O dtb -o aliases.dtb aliases.dts
+    run_test path_offset_aliases aliases.dtb
+
     # Check /include/ directive
     run_dtc_test -I dts -O dtb -o includes.test.dtb include0.dts
     run_test dtbs_equal_ordered includes.test.dtb test_tree1.dtb
-- 
1.5.5.1

^ permalink raw reply related


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