LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [Bugme-new] [Bug 14021] New: hfsplus caused data loss
From: Rogério Brito @ 2009-08-20 22:17 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-fsdevel, linuxppc-dev, bugzilla-daemon, bugme-daemon
In-Reply-To: <20090820150242.a4b5eccc.akpm@linux-foundation.org>

Hi, Andrew.

On Aug 20 2009, Andrew Morton wrote:
> On Thu, 20 Aug 2009 02:17:21 GMT
> bugzilla-daemon@bugzilla.kernel.org wrote:
> > ,----
> > | [30991.501804] loop: module loaded
> > | [30991.513337] hfs: create hidden dir...
> > | [39897.867830] hfs: create hidden dir...
> > | [39960.061622] hfs: splitting index node...
> > `----
> > 
> > No stack traces, no nothing. Oh, I still have the disk image that I
> > created, if it is of any interest.
>
> Gee.  Nobody really does much maintenance work on hfs/hfsplus any more.

Right.

I think that I could run some stress tests (say, like the exhaustive
regression tests that the ntfs-3g developers use), just to get some
basic functionality on HFS+ working.

> I cc'ed the ppc guys as I expect that most HFS users are over there.

Thanks once again, Andrew.

> It seems like a pretty gross failure - others should be hitting it.
> 
> I wonder if it's a weird interaction with the loop driver.

Just to make it clear: the reason why I loop-mounted the filesystem was
just to work with a low-risk situation and submit the image to the
recently "ported" fsck, just to get a little bit more confidence that I
didn't mess with the userspace side of things.

But, then, this surprise.

I had some minor inconsistencies with the HFS+ driver in the past, but
they were fixed by running the fsck.hfsplus that I packaged and I didn't
bother reporting it before. My mistake. :-(


Thanks, Rogério Brito.

-- 
Rogério Brito : rbrito@{mackenzie,ime.usp}.br : GPG key 1024D/7C2CAEB8
http://www.ime.usp.br/~rbrito : http://meusite.mackenzie.com.br/rbrito
Projects: algorithms.berlios.de : lame.sf.net : vrms.alioth.debian.org

^ permalink raw reply

* RE: [U-Boot] NAND  ECC Error with wrong SMC ording bug
From: Victor Gallardo @ 2009-08-20 22:56 UTC (permalink / raw)
  To: Sean MacLennan, Stefan Roese
  Cc: Prodyut Hazarika, u-boot, Feng Kan, linux-mtd, linuxppc-dev
In-Reply-To: <20090820153644.631dbd7b@lappy.seanm.ca>

Hi Sean,

The change is necessary in both Linux and u-boot. Without this change =
customer are seeing the problem.

Best Regards,

Victor Gallardo

> -----Original Message-----
> From: linuxppc-dev-bounces+vgallardo=3Damcc.com@lists.ozlabs.org =
[mailto:linuxppc-dev-
> bounces+vgallardo=3Damcc.com@lists.ozlabs.org] On Behalf Of Sean =
MacLennan
> Sent: Thursday, August 20, 2009 12:37 PM
> To: Stefan Roese
> Cc: u-boot@lists.denx.de; Feng Kan; linux-mtd@lists.infradead.org; =
linuxppc-dev@ozlabs.org
> Subject: Re: [U-Boot] NAND ECC Error with wrong SMC ording bug
>=20
> On Thu, 20 Aug 2009 07:01:21 +0200
> Stefan Roese <sr@denx.de> wrote:
>=20
> > On Thursday 20 August 2009 06:38:51 Sean MacLennan wrote:
> > > > I see other boards using SMC as well, can someone comment on the
> > > > change I am proposing.
> > > > Should I change the correction algorithm or the calculate
> > > > function? If the later is preferred
> > > > it would mean the change must be pushed in both U-Boot and =
Linux.
> > >
> > > Odds are the calculate function is wrong. The correction algo is
> > > used by many nand drivers, I *assume* it is correct. The calculate
> > > function was set to agree with u-boot (1.3.0).
> >
> > Yes, it seems that you changed the order in the calculation function
> > while reworking the NDFC driver for arch/powerpc. So we should
> > probably change this order back to the original version. And change
> > it in U-Boot as well.
> >
> > BTW: I didn't see any problems with ECC so far with the current =
code.
> > Feng, how did you spot this problem?
>=20
> Ok, I think I have reproduced the problem programmatically. Basically,
> I force a one bit error with the following patch:
>=20
> diff --git a/drivers/mtd/nand/nand_base.c =
b/drivers/mtd/nand/nand_base.c
> index 8c21b89..91dd5b4 100644
> --- a/drivers/mtd/nand/nand_base.c
> +++ b/drivers/mtd/nand/nand_base.c
> @@ -1628,11 +1628,22 @@ static void nand_write_page_hwecc(struct =
mtd_info *mtd, struct nand_chip
> *chip,
>  	uint8_t *ecc_calc =3D chip->buffers->ecccalc;
>  	const uint8_t *p =3D buf;
>  	uint32_t *eccpos =3D chip->ecc.layout->eccpos;
> +	static int count;
>=20
>  	for (i =3D 0; eccsteps; eccsteps--, i +=3D eccbytes, p +=3D eccsize) =
{
>  		chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
> -		chip->write_buf(mtd, p, eccsize);
> -		chip->ecc.calculate(mtd, p, &ecc_calc[i]);
> +		if (count =3D=3D 0) {
> +			count =3D 1;
> +			printk("Corrupt one bit: %08x =3D> %08x\n",
> +			       *p, *p ^ 8);
> +			*(uint8_t *)p ^=3D 8;
> +			chip->write_buf(mtd, p, eccsize);
> +			*(uint8_t *)p ^=3D 8;
> +			nand_calculate_ecc(mtd, p, &ecc_calc[i]);
> +		} else {
> +			chip->write_buf(mtd, p, eccsize);
> +			chip->ecc.calculate(mtd, p, &ecc_calc[i]);
> +		}
>  	}
>=20
>  	for (i =3D 0; i < chip->ecc.total; i++)
>=20
> Basically I write a one bit error to the NAND, but calculate with the
> correct bit. This assumes nand_calculate_ecc is correct.
>=20
> I then added debugs to the correction to make sure it corrected
> properly:
>=20
> diff --git a/drivers/mtd/nand/nand_ecc.c b/drivers/mtd/nand/nand_ecc.c
> index c0cb87d..57dcaa1 100644
> --- a/drivers/mtd/nand/nand_ecc.c
> +++ b/drivers/mtd/nand/nand_ecc.c
> @@ -483,14 +483,20 @@ int nand_correct_data(struct mtd_info *mtd, =
unsigned char *buf,
>  			byte_addr =3D (addressbits[b2 & 0x3] << 8) +
>  				    (addressbits[b1] << 4) + addressbits[b0];
>  		bit_addr =3D addressbits[b2 >> 2];
> +
> +		printk("Single bit error: correct %08x =3D> %08x\n",
> +		       buf[byte_addr], buf[byte_addr] ^ (1 << bit_addr));
> +
>  		/* flip the bit */
>  		buf[byte_addr] ^=3D (1 << bit_addr);
>  		return 1;
>=20
>  	}
>  	/* count nr of bits; use table lookup, faster than calculating it */
> -	if ((bitsperbyte[b0] + bitsperbyte[b1] + bitsperbyte[b2]) =3D=3D 1)
> +	if ((bitsperbyte[b0] + bitsperbyte[b1] + bitsperbyte[b2]) =3D=3D 1) =
{
> +		printk("ECC DATA BAD\n"); // SAM DBG
>  		return 1;	/* error in ecc data; no action needed */
> +	}
>=20
>  	printk(KERN_ERR "uncorrectable error : ");
>  	return -1;
>=20
> With the current ndfc code, the error correction gets the bits wrong.
> Switching it back to the original way and the correction is correct.
>=20
> diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c
> index 89bf85a..497e175 100644
> --- a/drivers/mtd/nand/ndfc.c
> +++ b/drivers/mtd/nand/ndfc.c
> @@ -101,9 +101,8 @@ static int ndfc_calculate_ecc(struct mtd_info =
*mtd,
>=20
>  	wmb();
>  	ecc =3D in_be32(ndfc->ndfcbase + NDFC_ECC);
> -	/* The NDFC uses Smart Media (SMC) bytes order */
> -	ecc_code[0] =3D p[2];
> -	ecc_code[1] =3D p[1];
> +	ecc_code[0] =3D p[1];
> +	ecc_code[1] =3D p[2];
>  	ecc_code[2] =3D p[3];
>=20
>  	return 0;
>=20
> Does anybody see a problem with my method of reproducing the bug? This
> bug is deadly for our customers. I don't want to make the change =
unless
> it is absolutely necessary.
>=20
> Cheers,
>    Sean
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev

^ permalink raw reply

* [PATCH] powerpc:  Adjust base and index registers in Altivec macros
From: Mike Wolf @ 2009-08-20 23:21 UTC (permalink / raw)
  To: linuxppc-dev

On POWER6 systems RA needs to be the base and RB the index.  
If they are reversed you take a misdirect hit.  

Signed-off-by: Mike Wolf <mjwolf@us.ibm.com>

----
--- altivec.orig/arch/powerpc/include/asm/ppc_asm.h	2009-08-17 15:39:52.000000000 -0500
+++ altivec/arch/powerpc/include/asm/ppc_asm.h	2009-08-20 18:08:30.000000000 -0500
@@ -98,13 +98,13 @@
 #define REST_16FPRS(n, base)	REST_8FPRS(n, base); REST_8FPRS(n+8, base)
 #define REST_32FPRS(n, base)	REST_16FPRS(n, base); REST_16FPRS(n+16, base)
 
-#define SAVE_VR(n,b,base)	li b,THREAD_VR0+(16*(n));  stvx n,b,base
+#define SAVE_VR(n,b,base)	li b,THREAD_VR0+(16*(n));  stvx n,base,b
 #define SAVE_2VRS(n,b,base)	SAVE_VR(n,b,base); SAVE_VR(n+1,b,base)
 #define SAVE_4VRS(n,b,base)	SAVE_2VRS(n,b,base); SAVE_2VRS(n+2,b,base)
 #define SAVE_8VRS(n,b,base)	SAVE_4VRS(n,b,base); SAVE_4VRS(n+4,b,base)
 #define SAVE_16VRS(n,b,base)	SAVE_8VRS(n,b,base); SAVE_8VRS(n+8,b,base)
 #define SAVE_32VRS(n,b,base)	SAVE_16VRS(n,b,base); SAVE_16VRS(n+16,b,base)
-#define REST_VR(n,b,base)	li b,THREAD_VR0+(16*(n)); lvx n,b,base
+#define REST_VR(n,b,base)	li b,THREAD_VR0+(16*(n)); lvx n,base,b
 #define REST_2VRS(n,b,base)	REST_VR(n,b,base); REST_VR(n+1,b,base)
 #define REST_4VRS(n,b,base)	REST_2VRS(n,b,base); REST_2VRS(n+2,b,base)
 #define REST_8VRS(n,b,base)	REST_4VRS(n,b,base); REST_4VRS(n+4,b,base)
@@ -112,26 +112,26 @@
 #define REST_32VRS(n,b,base)	REST_16VRS(n,b,base); REST_16VRS(n+16,b,base)
 
 /* Save the lower 32 VSRs in the thread VSR region */
-#define SAVE_VSR(n,b,base)	li b,THREAD_VSR0+(16*(n));  STXVD2X(n,b,base)
+#define SAVE_VSR(n,b,base)	li b,THREAD_VSR0+(16*(n));  STXVD2X(n,base,b)
 #define SAVE_2VSRS(n,b,base)	SAVE_VSR(n,b,base); SAVE_VSR(n+1,b,base)
 #define SAVE_4VSRS(n,b,base)	SAVE_2VSRS(n,b,base); SAVE_2VSRS(n+2,b,base)
 #define SAVE_8VSRS(n,b,base)	SAVE_4VSRS(n,b,base); SAVE_4VSRS(n+4,b,base)
 #define SAVE_16VSRS(n,b,base)	SAVE_8VSRS(n,b,base); SAVE_8VSRS(n+8,b,base)
 #define SAVE_32VSRS(n,b,base)	SAVE_16VSRS(n,b,base); SAVE_16VSRS(n+16,b,base)
-#define REST_VSR(n,b,base)	li b,THREAD_VSR0+(16*(n)); LXVD2X(n,b,base)
+#define REST_VSR(n,b,base)	li b,THREAD_VSR0+(16*(n)); LXVD2X(n,base,b)
 #define REST_2VSRS(n,b,base)	REST_VSR(n,b,base); REST_VSR(n+1,b,base)
 #define REST_4VSRS(n,b,base)	REST_2VSRS(n,b,base); REST_2VSRS(n+2,b,base)
 #define REST_8VSRS(n,b,base)	REST_4VSRS(n,b,base); REST_4VSRS(n+4,b,base)
 #define REST_16VSRS(n,b,base)	REST_8VSRS(n,b,base); REST_8VSRS(n+8,b,base)
 #define REST_32VSRS(n,b,base)	REST_16VSRS(n,b,base); REST_16VSRS(n+16,b,base)
 /* Save the upper 32 VSRs (32-63) in the thread VSX region (0-31) */
-#define SAVE_VSRU(n,b,base)	li b,THREAD_VR0+(16*(n));  STXVD2X(n+32,b,base)
+#define SAVE_VSRU(n,b,base)	li b,THREAD_VR0+(16*(n));  STXVD2X(n+32,base,b)
 #define SAVE_2VSRSU(n,b,base)	SAVE_VSRU(n,b,base); SAVE_VSRU(n+1,b,base)
 #define SAVE_4VSRSU(n,b,base)	SAVE_2VSRSU(n,b,base); SAVE_2VSRSU(n+2,b,base)
 #define SAVE_8VSRSU(n,b,base)	SAVE_4VSRSU(n,b,base); SAVE_4VSRSU(n+4,b,base)
 #define SAVE_16VSRSU(n,b,base)	SAVE_8VSRSU(n,b,base); SAVE_8VSRSU(n+8,b,base)
 #define SAVE_32VSRSU(n,b,base)	SAVE_16VSRSU(n,b,base); SAVE_16VSRSU(n+16,b,base)
-#define REST_VSRU(n,b,base)	li b,THREAD_VR0+(16*(n)); LXVD2X(n+32,b,base)
+#define REST_VSRU(n,b,base)	li b,THREAD_VR0+(16*(n)); LXVD2X(n+32,base,b)
 #define REST_2VSRSU(n,b,base)	REST_VSRU(n,b,base); REST_VSRU(n+1,b,base)
 #define REST_4VSRSU(n,b,base)	REST_2VSRSU(n,b,base); REST_2VSRSU(n+2,b,base)
 #define REST_8VSRSU(n,b,base)	REST_4VSRSU(n,b,base); REST_4VSRSU(n+4,b,base)

^ permalink raw reply

* Re: [U-Boot] NAND  ECC Error with wrong SMC ording bug
From: Feng Kan @ 2009-08-20 23:42 UTC (permalink / raw)
  To: Stefan Roese; +Cc: linuxppc-dev, u-boot, linux-mtd, Sean MacLennan
In-Reply-To: <200908200701.21076.sr@denx.de>

Hi Stefan:

We had a board with high number of correctable ECC errors. Which crashed 
the jffs when it
was miss correcting the wrong byte location.

Do you want me to submit a patch for this, or do you prefer to do it. I 
am submitting a patch
for linux right now.

Feng Kan
AMCC Software

On 08/19/2009 10:01 PM, Stefan Roese wrote:
> On Thursday 20 August 2009 06:38:51 Sean MacLennan wrote:
>    
>>> I see other boards using SMC as well, can someone comment on the
>>> change I am proposing.
>>> Should I change the correction algorithm or the calculate function?
>>> If the later is preferred
>>> it would mean the change must be pushed in both U-Boot and Linux.
>>>        
>> Odds are the calculate function is wrong. The correction algo is used
>> by many nand drivers, I *assume* it is correct. The calculate function
>> was set to agree with u-boot (1.3.0).
>>      
> Yes, it seems that you changed the order in the calculation function while
> reworking the NDFC driver for arch/powerpc. So we should probably change this
> order back to the original version. And change it in U-Boot as well.
>
> BTW: I didn't see any problems with ECC so far with the current code. Feng,
> how did you spot this problem?
>
> Cheers,
> 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

* [PATCH 1/1] Fix ECC Correction bug for SMC ordering for NDFC driver.
From: Feng Kan @ 2009-08-21  0:19 UTC (permalink / raw)
  To: linuxppc-dev, linux-mtd; +Cc: Feng Kan

Fix ECC Correction bug where the byte offset location were double
fliped causing correction routine to toggle the wrong byte location
in the ECC segment. The ndfc_calculate_ecc routine change the order
of getting the ECC code.
        /* The NDFC uses Smart Media (SMC) bytes order */
        ecc_code[0] = p[2];
        ecc_code[1] = p[1];
        ecc_code[2] = p[3];
But in the Correction algorithm when calculating the byte offset
location, the b1 is used as the upper part of the address. Which
again reverse the order making the final byte offset address 
location incorrect.
	byte_addr = (addressbits[b1] << 4) + addressbits[b0];
The order is change to read it in straight and let the correction
function to revert it to SMC order.

Signed-off-by: Feng Kan <fkan@amcc.com>
Acked-by: Victor Gallardo <vgallardo@amcc.com>
Acked-by: Prodyut Hazarika <phazarika@amcc.com>
---
 drivers/mtd/nand/ndfc.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c
index 5906c40..d9d3e6e 100644
--- a/drivers/mtd/nand/ndfc.c
+++ b/drivers/mtd/nand/ndfc.c
@@ -101,8 +101,8 @@ static int ndfc_calculate_ecc(struct mtd_info *mtd,
 	wmb();
 	ecc = in_be32(ndfc->ndfcbase + NDFC_ECC);
 	/* The NDFC uses Smart Media (SMC) bytes order */
-	ecc_code[0] = p[2];
-	ecc_code[1] = p[1];
+	ecc_code[0] = p[1];
+	ecc_code[1] = p[2];
 	ecc_code[2] = p[3];
 
 	return 0;
-- 
1.5.5

^ permalink raw reply related

* Re: [PATCH 1/1] Fix ECC Correction bug for SMC ordering for NDFC driver.
From: Sean MacLennan @ 2009-08-21  0:27 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <1250813957-1786-1-git-send-email-fkan@amcc.com>

On Thu, 20 Aug 2009 17:19:17 -0700
Feng Kan <fkan@amcc.com> wrote:

> Fix ECC Correction bug where the byte offset location were double
> fliped causing correction routine to toggle the wrong byte location
> in the ECC segment. The ndfc_calculate_ecc routine change the order
> of getting the ECC code.
>         /* The NDFC uses Smart Media (SMC) bytes order */
>         ecc_code[0] = p[2];
>         ecc_code[1] = p[1];
>         ecc_code[2] = p[3];
> But in the Correction algorithm when calculating the byte offset
> location, the b1 is used as the upper part of the address. Which
> again reverse the order making the final byte offset address 
> location incorrect.
> 	byte_addr = (addressbits[b1] << 4) + addressbits[b0];
> The order is change to read it in straight and let the correction
> function to revert it to SMC order.
> 
> Signed-off-by: Feng Kan <fkan@amcc.com>
> Acked-by: Victor Gallardo <vgallardo@amcc.com>
> Acked-by: Prodyut Hazarika <phazarika@amcc.com>
> ---
>  drivers/mtd/nand/ndfc.c |    4 ++--
>  1 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c
> index 5906c40..d9d3e6e 100644
> --- a/drivers/mtd/nand/ndfc.c
> +++ b/drivers/mtd/nand/ndfc.c
> @@ -101,8 +101,8 @@ static int ndfc_calculate_ecc(struct mtd_info
> *mtd, wmb();
>  	ecc = in_be32(ndfc->ndfcbase + NDFC_ECC);
>  	/* The NDFC uses Smart Media (SMC) bytes order */
> -	ecc_code[0] = p[2];
> -	ecc_code[1] = p[1];
> +	ecc_code[0] = p[1];
> +	ecc_code[1] = p[2];
>  	ecc_code[2] = p[3];
>  
>  	return 0;

Acked-by: Sean MacLennan <smaclennan@pikatech.com>

Cheers,
   Sean

^ permalink raw reply

* linux-next: manual merge of the agp tree with the powerpc tree
From: Stephen Rothwell @ 2009-08-21  3:56 UTC (permalink / raw)
  To: Dave Airlie
  Cc: David Woodhouse, linux-kernel, Michel Dänzer, linuxppc-dev,
	linux-next, Paul Mackerras

Hi Dave,

Today's linux-next merge of the agp tree got a conflict in
drivers/char/agp/uninorth-agp.c between commit uninorth_create_gatt_table
("agp/uninorth: Simplify cache flushing") from the powerpc tree and
commit 6a12235c7d2d75c7d94b9afcaaecd422ff845ce0 ("agp: kill phys_to_gart
() and gart_to_phys()") from the agp tree.

Just context changes.  I fixed it up (see below) and can carry the fix as
necessary.
-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

diff --cc drivers/char/agp/uninorth-agp.c
index bba29ab,4317a55..0000000
--- a/drivers/char/agp/uninorth-agp.c
+++ b/drivers/char/agp/uninorth-agp.c
@@@ -424,28 -424,14 +424,28 @@@ static int uninorth_create_gatt_table(s
  	if (table == NULL)
  		return -ENOMEM;
  
 +	pages = kmalloc((1 << page_order) * sizeof(struct page*), GFP_KERNEL);
 +	if (pages == NULL)
 +		goto enomem;
 +
  	table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
  
 -	for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)
 +	for (page = virt_to_page(table), i = 0; page <= virt_to_page(table_end);
 +	     page++, i++) {
  		SetPageReserved(page);
 +		pages[i] = page;
 +	}
  
  	bridge->gatt_table_real = (u32 *) table;
 -	bridge->gatt_table = (u32 *)table;
 +	/* Need to clear out any dirty data still sitting in caches */
 +	flush_dcache_range((unsigned long)table,
 +			   (unsigned long)(table_end + PAGE_SIZE));
 +	bridge->gatt_table = vmap(pages, (1 << page_order), 0, PAGE_KERNEL_NCG);
 +
 +	if (bridge->gatt_table == NULL)
 +		goto enomem;
 +
- 	bridge->gatt_bus_addr = virt_to_gart(table);
+ 	bridge->gatt_bus_addr = virt_to_phys(table);
  
  	for (i = 0; i < num_entries; i++)
  		bridge->gatt_table[i] = 0;

^ permalink raw reply

* Re: [U-Boot] NAND ECC Error with wrong SMC ording bug
From: vimal singh @ 2009-08-21  5:17 UTC (permalink / raw)
  To: Sean MacLennan; +Cc: u-boot, Stefan Roese, Feng Kan, linux-mtd, linuxppc-dev
In-Reply-To: <20090820153644.631dbd7b@lappy.seanm.ca>

<snip>

> With the current ndfc code, the error correction gets the bits wrong.
> Switching it back to the original way and the correction is correct.
>
> diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c
> index 89bf85a..497e175 100644
> --- a/drivers/mtd/nand/ndfc.c
> +++ b/drivers/mtd/nand/ndfc.c
> @@ -101,9 +101,8 @@ static int ndfc_calculate_ecc(struct mtd_info *mtd,
>
> =A0 =A0 =A0 =A0wmb();
> =A0 =A0 =A0 =A0ecc =3D in_be32(ndfc->ndfcbase + NDFC_ECC);
> - =A0 =A0 =A0 /* The NDFC uses Smart Media (SMC) bytes order */
> - =A0 =A0 =A0 ecc_code[0] =3D p[2];
> - =A0 =A0 =A0 ecc_code[1] =3D p[1];
> + =A0 =A0 =A0 ecc_code[0] =3D p[1];
> + =A0 =A0 =A0 ecc_code[1] =3D p[2];
> =A0 =A0 =A0 =A0ecc_code[2] =3D p[3];
>
> =A0 =A0 =A0 =A0return 0;
>
> Does anybody see a problem with my method of reproducing the bug? This
> bug is deadly for our customers. I don't want to make the change unless
> it is absolutely necessary..

Just one question: did you enabled MTD_NAND_ECC_SMC in configs?

-vimal

>
> Cheers,
> =A0 Sean
>
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/
>

^ permalink raw reply

* [RFC PATCH 0/3] Make 64-bit PCI device tree scanning code common
From: Grant Likely @ 2009-08-21  5:30 UTC (permalink / raw)
  To: benh, galak, linuxppc-dev

Ben and Kumar,

Compile tested only.  I haven't even tried to boot this on real
hardware, but I'm posting so that you guys can see what I'm up to.
Basically, I want access to the device tree scanning in ppc32 land,
and these patches start to get me there.  Please take a look and
comment.  Tomorrow I'll actually try running this stuff and debugging
the details.

Thanks,
g.

--
Grant Likely, B.Sc. P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply

* [PATCH 1/3] powerpc/pci: Remove dead checks for CONFIG_PPC_OF
From: Grant Likely @ 2009-08-21  5:30 UTC (permalink / raw)
  To: benh, galak, linuxppc-dev
In-Reply-To: <20090821052714.2289.41279.stgit@localhost.localdomain>

From: Grant Likely <grant.likely@secretlab.ca>

PPC_OF is always selected for arch/powerpc.  This patch removes the stale
#defines

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---

 arch/powerpc/kernel/pci-common.c |    8 --------
 arch/powerpc/kernel/pci_32.c     |    9 ---------
 2 files changed, 0 insertions(+), 17 deletions(-)


diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 5a56e97..23eeb3e 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -176,8 +176,6 @@ int pci_domain_nr(struct pci_bus *bus)
 }
 EXPORT_SYMBOL(pci_domain_nr);
 
-#ifdef CONFIG_PPC_OF
-
 /* This routine is meant to be used early during boot, when the
  * PCI bus numbers have not yet been assigned, and you need to
  * issue PCI config cycles to an OF device.
@@ -210,17 +208,11 @@ static ssize_t pci_show_devspec(struct device *dev,
 	return sprintf(buf, "%s", np->full_name);
 }
 static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL);
-#endif /* CONFIG_PPC_OF */
 
 /* Add sysfs properties */
 int pcibios_add_platform_entries(struct pci_dev *pdev)
 {
-#ifdef CONFIG_PPC_OF
 	return device_create_file(&pdev->dev, &dev_attr_devspec);
-#else
-	return 0;
-#endif /* CONFIG_PPC_OF */
-
 }
 
 char __devinit *pcibios_setup(char *str)
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index 3ae1c66..1e807fe 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -34,9 +34,7 @@ int pcibios_assign_bus_offset = 1;
 void pcibios_make_OF_bus_map(void);
 
 static void fixup_cpc710_pci64(struct pci_dev* dev);
-#ifdef CONFIG_PPC_OF
 static u8* pci_to_OF_bus_map;
-#endif
 
 /* By default, we don't re-assign bus numbers. We do this only on
  * some pmacs
@@ -83,7 +81,6 @@ fixup_cpc710_pci64(struct pci_dev* dev)
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_IBM,	PCI_DEVICE_ID_IBM_CPC710_PCI64,	fixup_cpc710_pci64);
 
-#ifdef CONFIG_PPC_OF
 /*
  * Functions below are used on OpenFirmware machines.
  */
@@ -357,12 +354,6 @@ pci_create_OF_bus_map(void)
 	}
 }
 
-#else /* CONFIG_PPC_OF */
-void pcibios_make_OF_bus_map(void)
-{
-}
-#endif /* CONFIG_PPC_OF */
-
 static void __devinit pcibios_scan_phb(struct pci_controller *hose)
 {
 	struct pci_bus *bus;

^ permalink raw reply related

* [PATCH 3/3] powerpc/pci: Merge ppc32 and ppc64 versions of phb_scan()
From: Grant Likely @ 2009-08-21  5:30 UTC (permalink / raw)
  To: benh, galak, linuxppc-dev
In-Reply-To: <20090821052714.2289.41279.stgit@localhost.localdomain>

From: Grant Likely <grant.likely@secretlab.ca>

The two versions are doing almost exactly the same thing.  No need to
maintain them as separate files.  This patch also has the side effect
of making the PCI device tree scanning code available to 32 bit powerpc
machines, but no board ports actually make use of this feature at this
point.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---

 arch/powerpc/include/asm/pci.h   |    2 ++
 arch/powerpc/kernel/pci-common.c |   48 ++++++++++++++++++++++++++++++++++++++
 arch/powerpc/kernel/pci_32.c     |   25 ++------------------
 arch/powerpc/kernel/pci_64.c     |   46 +++++-------------------------------
 4 files changed, 58 insertions(+), 63 deletions(-)


diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h
index 9ae2e3e..feebfed 100644
--- a/arch/powerpc/include/asm/pci.h
+++ b/arch/powerpc/include/asm/pci.h
@@ -233,6 +233,8 @@ extern void pci_resource_to_user(const struct pci_dev *dev, int bar,
 
 extern void pcibios_setup_bus_devices(struct pci_bus *bus);
 extern void pcibios_setup_bus_self(struct pci_bus *bus);
+extern void pcibios_setup_phb_io_space(struct pci_controller *hose);
+extern void pcibios_scan_phb(struct pci_controller *hose, void *data);
 
 #endif	/* __KERNEL__ */
 #endif /* __ASM_POWERPC_PCI_H */
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 3762525..7d5bf1b 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -1956,3 +1956,51 @@ void __devinit of_rescan_bus(struct device_node *node,
 }
 EXPORT_SYMBOL_GPL(of_rescan_bus);
 
+/**
+ * pci_scan_phb - Given a pci_controller, setup and scan the PCI bus
+ * @hose: Pointer to the PCI host controller instance structure
+ * @data: value to use for sysdata pointer.  ppc32 and ppc64 differ here
+ *
+ * Note: the 'data' pointer is a temporary measure.  As 32 and 64 bit
+ * pci code gets merged, this parameter should become unnecessary because
+ * both will use the same value.
+ */
+void __devinit pcibios_scan_phb(struct pci_controller *hose, void *data)
+{
+	struct pci_bus *bus;
+	struct device_node *node = hose->dn;
+	int mode;
+
+	pr_debug("PCI: Scanning PHB %s\n",
+		 node ? node->full_name : "<NO NAME>");
+
+	/* Create an empty bus for the toplevel */
+	bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, data);
+	if (bus == NULL) {
+		pr_err("Failed to create bus for PCI domain %04x\n",
+			hose->global_number);
+		return;
+	}
+	bus->secondary = hose->first_busno;
+	hose->bus = bus;
+
+	/* Get some IO space for the new PHB */
+	pcibios_setup_phb_io_space(hose);
+
+	/* Wire up PHB bus resources */
+	pcibios_setup_phb_resources(hose);
+
+	/* Get probe mode and perform scan */
+	mode = PCI_PROBE_NORMAL;
+	if (node && ppc_md.pci_probe_mode)
+		mode = ppc_md.pci_probe_mode(bus);
+	pr_debug("    probe mode: %d\n", mode);
+	if (mode == PCI_PROBE_DEVTREE) {
+		bus->subordinate = hose->last_busno;
+		of_scan_bus(node, bus);
+	}
+
+	if (mode == PCI_PROBE_NORMAL)
+		hose->last_busno = bus->subordinate = pci_scan_child_bus(bus);
+}
+
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index 1e807fe..4e415e1 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -354,36 +354,15 @@ pci_create_OF_bus_map(void)
 	}
 }
 
-static void __devinit pcibios_scan_phb(struct pci_controller *hose)
+void __devinit pcibios_setup_phb_io_space(struct pci_controller *hose)
 {
-	struct pci_bus *bus;
-	struct device_node *node = hose->dn;
 	unsigned long io_offset;
 	struct resource *res = &hose->io_resource;
 
-	pr_debug("PCI: Scanning PHB %s\n",
-		 node ? node->full_name : "<NO NAME>");
-
-	/* Create an empty bus for the toplevel */
-	bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, hose);
-	if (bus == NULL) {
-		printk(KERN_ERR "Failed to create bus for PCI domain %04x\n",
-		       hose->global_number);
-		return;
-	}
-	bus->secondary = hose->first_busno;
-	hose->bus = bus;
-
 	/* Fixup IO space offset */
 	io_offset = (unsigned long)hose->io_base_virt - isa_io_base;
 	res->start = (res->start + io_offset) & 0xffffffffu;
 	res->end = (res->end + io_offset) & 0xffffffffu;
-
-	/* Wire up PHB bus resources */
-	pcibios_setup_phb_resources(hose);
-
-	/* Scan children */
-	hose->last_busno = bus->subordinate = pci_scan_child_bus(bus);
 }
 
 static int __init pcibios_init(void)
@@ -401,7 +380,7 @@ static int __init pcibios_init(void)
 		if (pci_assign_all_buses)
 			hose->first_busno = next_busno;
 		hose->last_busno = 0xff;
-		pcibios_scan_phb(hose);
+		pcibios_scan_phb(hose, hose);
 		pci_bus_add_devices(hose->bus);
 		if (pci_assign_all_buses || next_busno <= hose->last_busno)
 			next_busno = hose->last_busno + pcibios_assign_bus_offset;
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 4d5b4ce..ba949a2 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -43,45 +43,6 @@ unsigned long pci_probe_only = 1;
 unsigned long pci_io_base = ISA_IO_BASE;
 EXPORT_SYMBOL(pci_io_base);
 
-void __devinit scan_phb(struct pci_controller *hose)
-{
-	struct pci_bus *bus;
-	struct device_node *node = hose->dn;
-	int mode;
-
-	pr_debug("PCI: Scanning PHB %s\n",
-		 node ? node->full_name : "<NO NAME>");
-
-	/* Create an empty bus for the toplevel */
-	bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, node);
-	if (bus == NULL) {
-		printk(KERN_ERR "Failed to create bus for PCI domain %04x\n",
-		       hose->global_number);
-		return;
-	}
-	bus->secondary = hose->first_busno;
-	hose->bus = bus;
-
-	/* Get some IO space for the new PHB */
-	pcibios_map_io_space(bus);
-
-	/* Wire up PHB bus resources */
-	pcibios_setup_phb_resources(hose);
-
-	/* Get probe mode and perform scan */
-	mode = PCI_PROBE_NORMAL;
-	if (node && ppc_md.pci_probe_mode)
-		mode = ppc_md.pci_probe_mode(bus);
-	pr_debug("    probe mode: %d\n", mode);
-	if (mode == PCI_PROBE_DEVTREE) {
-		bus->subordinate = hose->last_busno;
-		of_scan_bus(node, bus);
-	}
-
-	if (mode == PCI_PROBE_NORMAL)
-		hose->last_busno = bus->subordinate = pci_scan_child_bus(bus);
-}
-
 static int __init pcibios_init(void)
 {
 	struct pci_controller *hose, *tmp;
@@ -103,7 +64,7 @@ static int __init pcibios_init(void)
 
 	/* Scan all of the recorded PCI controllers.  */
 	list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
-		scan_phb(hose);
+		pcibios_scan_phb(hose, hose->dn);
 		pci_bus_add_devices(hose->bus);
 	}
 
@@ -237,6 +198,11 @@ int __devinit pcibios_map_io_space(struct pci_bus *bus)
 }
 EXPORT_SYMBOL_GPL(pcibios_map_io_space);
 
+void __devinit pcibios_setup_phb_io_space(struct pci_controller *hose)
+{
+	pcibios_map_io_space(hose->bus);
+}
+
 #define IOBASE_BRIDGE_NUMBER	0
 #define IOBASE_MEMORY		1
 #define IOBASE_IO		2

^ permalink raw reply related

* [PATCH 2/3] powerpc/pci: move pci_64.c device tree scanning code into pci-common.c
From: Grant Likely @ 2009-08-21  5:30 UTC (permalink / raw)
  To: benh, galak, linuxppc-dev
In-Reply-To: <20090821052714.2289.41279.stgit@localhost.localdomain>

From: Grant Likely <grant.likely@secretlab.ca>

The PCI device tree scanning code in pci_64.c is some useful functionality.
It allows PCI devices to be described in the device tree instead of being
probed for, which in turn allows pci devices to use all of the device tree
facilities to describe complex PCI bus architectures like GPIO and IRQ
routing (perhaps not a common situation for desktop or server systems,
but useful for embedded systems with on-board PCI devices).

This patch moves the device tree scanning into pci-common.c so it is
available for 32-bit powerpc machines too.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---

 arch/powerpc/include/asm/pci-bridge.h |    5 
 arch/powerpc/include/asm/pci.h        |    5 
 arch/powerpc/kernel/pci-common.c      |  338 +++++++++++++++++++++++++++++++++
 arch/powerpc/kernel/pci_64.c          |  289 ----------------------------
 4 files changed, 343 insertions(+), 294 deletions(-)


diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index 4c61fa0..3faf575 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -284,11 +284,6 @@ static inline int isa_vaddr_is_ioport(void __iomem *address)
 extern int pcibios_unmap_io_space(struct pci_bus *bus);
 extern int pcibios_map_io_space(struct pci_bus *bus);
 
-/* Return values for ppc_md.pci_probe_mode function */
-#define PCI_PROBE_NONE		-1	/* Don't look at this bus at all */
-#define PCI_PROBE_NORMAL	0	/* Do normal PCI probing */
-#define PCI_PROBE_DEVTREE	1	/* Instantiate from device tree */
-
 #ifdef CONFIG_NUMA
 #define PHB_SET_NODE(PHB, NODE)		((PHB)->node = (NODE))
 #else
diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h
index d9483c5..9ae2e3e 100644
--- a/arch/powerpc/include/asm/pci.h
+++ b/arch/powerpc/include/asm/pci.h
@@ -22,6 +22,11 @@
 
 #include <asm-generic/pci-dma-compat.h>
 
+/* Return values for ppc_md.pci_probe_mode function */
+#define PCI_PROBE_NONE		-1	/* Don't look at this bus at all */
+#define PCI_PROBE_NORMAL	0	/* Do normal PCI probing */
+#define PCI_PROBE_DEVTREE	1	/* Instantiate from device tree */
+
 #define PCIBIOS_MIN_IO		0x1000
 #define PCIBIOS_MIN_MEM		0x10000000
 
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 23eeb3e..3762525 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -1618,3 +1618,341 @@ void __devinit pcibios_setup_phb_resources(struct pci_controller *hose)
 
 }
 
+/**
+ * get_int_prop - Decode a u32 from a device tree property
+ */
+static u32 get_int_prop(struct device_node *np, const char *name, u32 def)
+{
+	const u32 *prop;
+	int len;
+
+	prop = of_get_property(np, name, &len);
+	if (prop && len >= 4)
+		return *prop;
+	return def;
+}
+
+/**
+ * pci_parse_of_flags - Parse the flags cell of a device tree PCI address
+ * @addr0: value of 1st cell of a device tree PCI address.
+ * @bridge: Set this flag if the address is from a bridge 'ranges' property
+ */
+unsigned int pci_parse_of_flags(u32 addr0, int bridge)
+{
+	unsigned int flags = 0;
+
+	if (addr0 & 0x02000000) {
+		flags = IORESOURCE_MEM | PCI_BASE_ADDRESS_SPACE_MEMORY;
+		flags |= (addr0 >> 22) & PCI_BASE_ADDRESS_MEM_TYPE_64;
+		flags |= (addr0 >> 28) & PCI_BASE_ADDRESS_MEM_TYPE_1M;
+		if (addr0 & 0x40000000)
+			flags |= IORESOURCE_PREFETCH
+				 | PCI_BASE_ADDRESS_MEM_PREFETCH;
+		/* Note: We don't know whether the ROM has been left enabled
+		 * by the firmware or not. We mark it as disabled (ie, we do
+		 * not set the IORESOURCE_ROM_ENABLE flag) for now rather than
+		 * do a config space read, it will be force-enabled if needed
+		 */
+		if (!bridge && (addr0 & 0xff) == 0x30)
+			flags |= IORESOURCE_READONLY;
+	} else if (addr0 & 0x01000000)
+		flags = IORESOURCE_IO | PCI_BASE_ADDRESS_SPACE_IO;
+	if (flags)
+		flags |= IORESOURCE_SIZEALIGN;
+	return flags;
+}
+
+/**
+ * of_pci_parse_addrs - Parse PCI addresses assigned in the device tree node
+ * @node: device tree node for the PCI device
+ * @dev: pci_dev structure for the device
+ *
+ * This function parses the 'assigned-addresses' property of a PCI devices'
+ * device tree node and writes them into the associated pci_dev structure.
+ */
+static void of_pci_parse_addrs(struct device_node *node, struct pci_dev *dev)
+{
+	u64 base, size;
+	unsigned int flags;
+	struct resource *res;
+	const u32 *addrs;
+	u32 i;
+	int proplen;
+
+	addrs = of_get_property(node, "assigned-addresses", &proplen);
+	if (!addrs)
+		return;
+	pr_debug("    parse addresses (%d bytes) @ %p\n", proplen, addrs);
+	for (; proplen >= 20; proplen -= 20, addrs += 5) {
+		flags = pci_parse_of_flags(addrs[0], 0);
+		if (!flags)
+			continue;
+		base = of_read_number(&addrs[1], 2);
+		size = of_read_number(&addrs[3], 2);
+		if (!size)
+			continue;
+		i = addrs[0] & 0xff;
+		pr_debug("  base: %llx, size: %llx, i: %x\n",
+			 (unsigned long long)base,
+			 (unsigned long long)size, i);
+
+		if (PCI_BASE_ADDRESS_0 <= i && i <= PCI_BASE_ADDRESS_5) {
+			res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2];
+		} else if (i == dev->rom_base_reg) {
+			res = &dev->resource[PCI_ROM_RESOURCE];
+			flags |= IORESOURCE_READONLY | IORESOURCE_CACHEABLE;
+		} else {
+			printk(KERN_ERR "PCI: bad cfg reg num 0x%x\n", i);
+			continue;
+		}
+		res->start = base;
+		res->end = base + size - 1;
+		res->flags = flags;
+		res->name = pci_name(dev);
+	}
+}
+
+/**
+ * of_create_pci_dev - Given a device tree node on a pci bus, create a pci_dev
+ * @node: device tree node pointer
+ * @bus: bus the device is sitting on
+ * @devfn: PCI function number, extracted from device tree by caller.
+ */
+struct pci_dev *of_create_pci_dev(struct device_node *node,
+				 struct pci_bus *bus, int devfn)
+{
+	struct pci_dev *dev;
+	const char *type;
+
+	dev = alloc_pci_dev();
+	if (!dev)
+		return NULL;
+	type = of_get_property(node, "device_type", NULL);
+	if (type == NULL)
+		type = "";
+
+	pr_debug("    create device, devfn: %x, type: %s\n", devfn, type);
+
+	dev->bus = bus;
+	dev->sysdata = node;
+	dev->dev.parent = bus->bridge;
+	dev->dev.bus = &pci_bus_type;
+	dev->devfn = devfn;
+	dev->multifunction = 0;		/* maybe a lie? */
+
+	dev->vendor = get_int_prop(node, "vendor-id", 0xffff);
+	dev->device = get_int_prop(node, "device-id", 0xffff);
+	dev->subsystem_vendor = get_int_prop(node, "subsystem-vendor-id", 0);
+	dev->subsystem_device = get_int_prop(node, "subsystem-id", 0);
+
+	dev->cfg_size = pci_cfg_space_size(dev);
+
+	dev_set_name(&dev->dev, "%04x:%02x:%02x.%d", pci_domain_nr(bus),
+		dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn));
+	dev->class = get_int_prop(node, "class-code", 0);
+	dev->revision = get_int_prop(node, "revision-id", 0);
+
+	pr_debug("    class: 0x%x\n", dev->class);
+	pr_debug("    revision: 0x%x\n", dev->revision);
+
+	dev->current_state = 4;		/* unknown power state */
+	dev->error_state = pci_channel_io_normal;
+	dev->dma_mask = 0xffffffff;
+
+	if (!strcmp(type, "pci") || !strcmp(type, "pciex")) {
+		/* a PCI-PCI bridge */
+		dev->hdr_type = PCI_HEADER_TYPE_BRIDGE;
+		dev->rom_base_reg = PCI_ROM_ADDRESS1;
+	} else if (!strcmp(type, "cardbus")) {
+		dev->hdr_type = PCI_HEADER_TYPE_CARDBUS;
+	} else {
+		dev->hdr_type = PCI_HEADER_TYPE_NORMAL;
+		dev->rom_base_reg = PCI_ROM_ADDRESS;
+		/* Maybe do a default OF mapping here */
+		dev->irq = NO_IRQ;
+	}
+
+	of_pci_parse_addrs(node, dev);
+
+	pr_debug("    adding to system ...\n");
+
+	pci_device_add(dev, bus);
+
+	return dev;
+}
+EXPORT_SYMBOL(of_create_pci_dev);
+
+/**
+ * of_scan_pci_bridge - Set up a PCI bridge and scan for child nodes
+ * @node: device tree node of bridge
+ * @dev: pci_dev structure for the bridge
+ *
+ * of_scan_bus() calls this routine for each PCI bridge that it finds, and
+ * this routine in turn call of_scan_bus() recusively to scan for more child
+ * devices.
+ */
+void __devinit of_scan_pci_bridge(struct device_node *node,
+				  struct pci_dev *dev)
+{
+	struct pci_bus *bus;
+	const u32 *busrange, *ranges;
+	int len, i, mode;
+	struct resource *res;
+	unsigned int flags;
+	u64 size;
+
+	pr_debug("of_scan_pci_bridge(%s)\n", node->full_name);
+
+	/* parse bus-range property */
+	busrange = of_get_property(node, "bus-range", &len);
+	if (busrange == NULL || len != 8) {
+		printk(KERN_DEBUG "Can't get bus-range for PCI-PCI bridge %s\n",
+		       node->full_name);
+		return;
+	}
+	ranges = of_get_property(node, "ranges", &len);
+	if (ranges == NULL) {
+		printk(KERN_DEBUG "Can't get ranges for PCI-PCI bridge %s\n",
+		       node->full_name);
+		return;
+	}
+
+	bus = pci_add_new_bus(dev->bus, dev, busrange[0]);
+	if (!bus) {
+		printk(KERN_ERR "Failed to create pci bus for %s\n",
+		       node->full_name);
+		return;
+	}
+
+	bus->primary = dev->bus->number;
+	bus->subordinate = busrange[1];
+	bus->bridge_ctl = 0;
+	bus->sysdata = node;
+
+	/* parse ranges property */
+	/* PCI #address-cells == 3 and #size-cells == 2 always */
+	res = &dev->resource[PCI_BRIDGE_RESOURCES];
+	for (i = 0; i < PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES; ++i) {
+		res->flags = 0;
+		bus->resource[i] = res;
+		++res;
+	}
+	i = 1;
+	for (; len >= 32; len -= 32, ranges += 8) {
+		flags = pci_parse_of_flags(ranges[0], 1);
+		size = of_read_number(&ranges[6], 2);
+		if (flags == 0 || size == 0)
+			continue;
+		if (flags & IORESOURCE_IO) {
+			res = bus->resource[0];
+			if (res->flags) {
+				printk(KERN_ERR "PCI: ignoring extra I/O range"
+				       " for bridge %s\n", node->full_name);
+				continue;
+			}
+		} else {
+			if (i >= PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES) {
+				printk(KERN_ERR "PCI: too many memory ranges"
+				       " for bridge %s\n", node->full_name);
+				continue;
+			}
+			res = bus->resource[i];
+			++i;
+		}
+		res->start = of_read_number(&ranges[1], 2);
+		res->end = res->start + size - 1;
+		res->flags = flags;
+	}
+	sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus),
+		bus->number);
+	pr_debug("    bus name: %s\n", bus->name);
+
+	mode = PCI_PROBE_NORMAL;
+	if (ppc_md.pci_probe_mode)
+		mode = ppc_md.pci_probe_mode(bus);
+	pr_debug("    probe mode: %d\n", mode);
+
+	if (mode == PCI_PROBE_DEVTREE)
+		of_scan_bus(node, bus);
+	else if (mode == PCI_PROBE_NORMAL)
+		pci_scan_child_bus(bus);
+}
+EXPORT_SYMBOL(of_scan_pci_bridge);
+
+/**
+ * __of_scan_bus - given a PCI bus node, setup bus and scan for child devices
+ * @node: device tree node for the PCI bus
+ * @bus: pci_bus structure for the PCI bus
+ * @rescan_existing: Flag indicating bus has already been set up
+ */
+static void __devinit __of_scan_bus(struct device_node *node,
+				    struct pci_bus *bus, int rescan_existing)
+{
+	struct device_node *child;
+	const u32 *reg;
+	int reglen, devfn;
+	struct pci_dev *dev;
+
+	pr_debug("of_scan_bus(%s) bus no %d... \n",
+		 node->full_name, bus->number);
+
+	/* Scan direct children */
+	for_each_child_of_node(node, child) {
+		pr_debug("  * %s\n", child->full_name);
+		reg = of_get_property(child, "reg", &reglen);
+		if (reg == NULL || reglen < 20)
+			continue;
+		devfn = (reg[0] >> 8) & 0xff;
+
+		/* create a new pci_dev for this device */
+		dev = of_create_pci_dev(child, bus, devfn);
+		if (!dev)
+			continue;
+		pr_debug("    dev header type: %x\n", dev->hdr_type);
+	}
+
+	/* Apply all fixups necessary. We don't fixup the bus "self"
+	 * for an existing bridge that is being rescanned
+	 */
+	if (!rescan_existing)
+		pcibios_setup_bus_self(bus);
+	pcibios_setup_bus_devices(bus);
+
+	/* Now scan child busses */
+	list_for_each_entry(dev, &bus->devices, bus_list) {
+		if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
+		    dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
+			struct device_node *child = pci_device_to_OF_node(dev);
+			if (dev)
+				of_scan_pci_bridge(child, dev);
+		}
+	}
+}
+
+/**
+ * of_scan_bus - given a PCI bus node, setup bus and scan for child devices
+ * @node: device tree node for the PCI bus
+ * @bus: pci_bus structure for the PCI bus
+ */
+void __devinit of_scan_bus(struct device_node *node,
+			   struct pci_bus *bus)
+{
+	__of_scan_bus(node, bus, 0);
+}
+EXPORT_SYMBOL_GPL(of_scan_bus);
+
+/**
+ * of_rescan_bus - given a PCI bus node, scan for child devices
+ * @node: device tree node for the PCI bus
+ * @bus: pci_bus structure for the PCI bus
+ *
+ * Same as of_scan_bus, but for a pci_bus structure that has already been
+ * setup.
+ */
+void __devinit of_rescan_bus(struct device_node *node,
+			     struct pci_bus *bus)
+{
+	__of_scan_bus(node, bus, 1);
+}
+EXPORT_SYMBOL_GPL(of_rescan_bus);
+
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 9e8902f..4d5b4ce 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -43,295 +43,6 @@ unsigned long pci_probe_only = 1;
 unsigned long pci_io_base = ISA_IO_BASE;
 EXPORT_SYMBOL(pci_io_base);
 
-static u32 get_int_prop(struct device_node *np, const char *name, u32 def)
-{
-	const u32 *prop;
-	int len;
-
-	prop = of_get_property(np, name, &len);
-	if (prop && len >= 4)
-		return *prop;
-	return def;
-}
-
-static unsigned int pci_parse_of_flags(u32 addr0, int bridge)
-{
-	unsigned int flags = 0;
-
-	if (addr0 & 0x02000000) {
-		flags = IORESOURCE_MEM | PCI_BASE_ADDRESS_SPACE_MEMORY;
-		flags |= (addr0 >> 22) & PCI_BASE_ADDRESS_MEM_TYPE_64;
-		flags |= (addr0 >> 28) & PCI_BASE_ADDRESS_MEM_TYPE_1M;
-		if (addr0 & 0x40000000)
-			flags |= IORESOURCE_PREFETCH
-				 | PCI_BASE_ADDRESS_MEM_PREFETCH;
-		/* Note: We don't know whether the ROM has been left enabled
-		 * by the firmware or not. We mark it as disabled (ie, we do
-		 * not set the IORESOURCE_ROM_ENABLE flag) for now rather than
-		 * do a config space read, it will be force-enabled if needed
-		 */
-		if (!bridge && (addr0 & 0xff) == 0x30)
-			flags |= IORESOURCE_READONLY;
-	} else if (addr0 & 0x01000000)
-		flags = IORESOURCE_IO | PCI_BASE_ADDRESS_SPACE_IO;
-	if (flags)
-		flags |= IORESOURCE_SIZEALIGN;
-	return flags;
-}
-
-
-static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev)
-{
-	u64 base, size;
-	unsigned int flags;
-	struct resource *res;
-	const u32 *addrs;
-	u32 i;
-	int proplen;
-
-	addrs = of_get_property(node, "assigned-addresses", &proplen);
-	if (!addrs)
-		return;
-	pr_debug("    parse addresses (%d bytes) @ %p\n", proplen, addrs);
-	for (; proplen >= 20; proplen -= 20, addrs += 5) {
-		flags = pci_parse_of_flags(addrs[0], 0);
-		if (!flags)
-			continue;
-		base = of_read_number(&addrs[1], 2);
-		size = of_read_number(&addrs[3], 2);
-		if (!size)
-			continue;
-		i = addrs[0] & 0xff;
-		pr_debug("  base: %llx, size: %llx, i: %x\n",
-			 (unsigned long long)base,
-			 (unsigned long long)size, i);
-
-		if (PCI_BASE_ADDRESS_0 <= i && i <= PCI_BASE_ADDRESS_5) {
-			res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2];
-		} else if (i == dev->rom_base_reg) {
-			res = &dev->resource[PCI_ROM_RESOURCE];
-			flags |= IORESOURCE_READONLY | IORESOURCE_CACHEABLE;
-		} else {
-			printk(KERN_ERR "PCI: bad cfg reg num 0x%x\n", i);
-			continue;
-		}
-		res->start = base;
-		res->end = base + size - 1;
-		res->flags = flags;
-		res->name = pci_name(dev);
-	}
-}
-
-struct pci_dev *of_create_pci_dev(struct device_node *node,
-				 struct pci_bus *bus, int devfn)
-{
-	struct pci_dev *dev;
-	const char *type;
-
-	dev = alloc_pci_dev();
-	if (!dev)
-		return NULL;
-	type = of_get_property(node, "device_type", NULL);
-	if (type == NULL)
-		type = "";
-
-	pr_debug("    create device, devfn: %x, type: %s\n", devfn, type);
-
-	dev->bus = bus;
-	dev->sysdata = node;
-	dev->dev.parent = bus->bridge;
-	dev->dev.bus = &pci_bus_type;
-	dev->devfn = devfn;
-	dev->multifunction = 0;		/* maybe a lie? */
-
-	dev->vendor = get_int_prop(node, "vendor-id", 0xffff);
-	dev->device = get_int_prop(node, "device-id", 0xffff);
-	dev->subsystem_vendor = get_int_prop(node, "subsystem-vendor-id", 0);
-	dev->subsystem_device = get_int_prop(node, "subsystem-id", 0);
-
-	dev->cfg_size = pci_cfg_space_size(dev);
-
-	dev_set_name(&dev->dev, "%04x:%02x:%02x.%d", pci_domain_nr(bus),
-		dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn));
-	dev->class = get_int_prop(node, "class-code", 0);
-	dev->revision = get_int_prop(node, "revision-id", 0);
-
-	pr_debug("    class: 0x%x\n", dev->class);
-	pr_debug("    revision: 0x%x\n", dev->revision);
-
-	dev->current_state = 4;		/* unknown power state */
-	dev->error_state = pci_channel_io_normal;
-	dev->dma_mask = 0xffffffff;
-
-	if (!strcmp(type, "pci") || !strcmp(type, "pciex")) {
-		/* a PCI-PCI bridge */
-		dev->hdr_type = PCI_HEADER_TYPE_BRIDGE;
-		dev->rom_base_reg = PCI_ROM_ADDRESS1;
-	} else if (!strcmp(type, "cardbus")) {
-		dev->hdr_type = PCI_HEADER_TYPE_CARDBUS;
-	} else {
-		dev->hdr_type = PCI_HEADER_TYPE_NORMAL;
-		dev->rom_base_reg = PCI_ROM_ADDRESS;
-		/* Maybe do a default OF mapping here */
-		dev->irq = NO_IRQ;
-	}
-
-	pci_parse_of_addrs(node, dev);
-
-	pr_debug("    adding to system ...\n");
-
-	pci_device_add(dev, bus);
-
-	return dev;
-}
-EXPORT_SYMBOL(of_create_pci_dev);
-
-static void __devinit __of_scan_bus(struct device_node *node,
-				    struct pci_bus *bus, int rescan_existing)
-{
-	struct device_node *child;
-	const u32 *reg;
-	int reglen, devfn;
-	struct pci_dev *dev;
-
-	pr_debug("of_scan_bus(%s) bus no %d... \n",
-		 node->full_name, bus->number);
-
-	/* Scan direct children */
-	for_each_child_of_node(node, child) {
-		pr_debug("  * %s\n", child->full_name);
-		reg = of_get_property(child, "reg", &reglen);
-		if (reg == NULL || reglen < 20)
-			continue;
-		devfn = (reg[0] >> 8) & 0xff;
-
-		/* create a new pci_dev for this device */
-		dev = of_create_pci_dev(child, bus, devfn);
-		if (!dev)
-			continue;
-		pr_debug("    dev header type: %x\n", dev->hdr_type);
-	}
-
-	/* Apply all fixups necessary. We don't fixup the bus "self"
-	 * for an existing bridge that is being rescanned
-	 */
-	if (!rescan_existing)
-		pcibios_setup_bus_self(bus);
-	pcibios_setup_bus_devices(bus);
-
-	/* Now scan child busses */
-	list_for_each_entry(dev, &bus->devices, bus_list) {
-		if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
-		    dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
-			struct device_node *child = pci_device_to_OF_node(dev);
-			if (dev)
-				of_scan_pci_bridge(child, dev);
-		}
-	}
-}
-
-void __devinit of_scan_bus(struct device_node *node,
-			   struct pci_bus *bus)
-{
-	__of_scan_bus(node, bus, 0);
-}
-EXPORT_SYMBOL_GPL(of_scan_bus);
-
-void __devinit of_rescan_bus(struct device_node *node,
-			     struct pci_bus *bus)
-{
-	__of_scan_bus(node, bus, 1);
-}
-EXPORT_SYMBOL_GPL(of_rescan_bus);
-
-void __devinit of_scan_pci_bridge(struct device_node *node,
-				  struct pci_dev *dev)
-{
-	struct pci_bus *bus;
-	const u32 *busrange, *ranges;
-	int len, i, mode;
-	struct resource *res;
-	unsigned int flags;
-	u64 size;
-
-	pr_debug("of_scan_pci_bridge(%s)\n", node->full_name);
-
-	/* parse bus-range property */
-	busrange = of_get_property(node, "bus-range", &len);
-	if (busrange == NULL || len != 8) {
-		printk(KERN_DEBUG "Can't get bus-range for PCI-PCI bridge %s\n",
-		       node->full_name);
-		return;
-	}
-	ranges = of_get_property(node, "ranges", &len);
-	if (ranges == NULL) {
-		printk(KERN_DEBUG "Can't get ranges for PCI-PCI bridge %s\n",
-		       node->full_name);
-		return;
-	}
-
-	bus = pci_add_new_bus(dev->bus, dev, busrange[0]);
-	if (!bus) {
-		printk(KERN_ERR "Failed to create pci bus for %s\n",
-		       node->full_name);
-		return;
-	}
-
-	bus->primary = dev->bus->number;
-	bus->subordinate = busrange[1];
-	bus->bridge_ctl = 0;
-	bus->sysdata = node;
-
-	/* parse ranges property */
-	/* PCI #address-cells == 3 and #size-cells == 2 always */
-	res = &dev->resource[PCI_BRIDGE_RESOURCES];
-	for (i = 0; i < PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES; ++i) {
-		res->flags = 0;
-		bus->resource[i] = res;
-		++res;
-	}
-	i = 1;
-	for (; len >= 32; len -= 32, ranges += 8) {
-		flags = pci_parse_of_flags(ranges[0], 1);
-		size = of_read_number(&ranges[6], 2);
-		if (flags == 0 || size == 0)
-			continue;
-		if (flags & IORESOURCE_IO) {
-			res = bus->resource[0];
-			if (res->flags) {
-				printk(KERN_ERR "PCI: ignoring extra I/O range"
-				       " for bridge %s\n", node->full_name);
-				continue;
-			}
-		} else {
-			if (i >= PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES) {
-				printk(KERN_ERR "PCI: too many memory ranges"
-				       " for bridge %s\n", node->full_name);
-				continue;
-			}
-			res = bus->resource[i];
-			++i;
-		}
-		res->start = of_read_number(&ranges[1], 2);
-		res->end = res->start + size - 1;
-		res->flags = flags;
-	}
-	sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus),
-		bus->number);
-	pr_debug("    bus name: %s\n", bus->name);
-
-	mode = PCI_PROBE_NORMAL;
-	if (ppc_md.pci_probe_mode)
-		mode = ppc_md.pci_probe_mode(bus);
-	pr_debug("    probe mode: %d\n", mode);
-
-	if (mode == PCI_PROBE_DEVTREE)
-		of_scan_bus(node, bus);
-	else if (mode == PCI_PROBE_NORMAL)
-		pci_scan_child_bus(bus);
-}
-EXPORT_SYMBOL(of_scan_pci_bridge);
-
 void __devinit scan_phb(struct pci_controller *hose)
 {
 	struct pci_bus *bus;

^ permalink raw reply related

* Re: [PATCH 2/2] powerpc/405ex: support cuImage via included dtb
From: tiejun.chen @ 2009-08-21  5:41 UTC (permalink / raw)
  To: Josh Boyer; +Cc: linuxppc-dev
In-Reply-To: <20090820133118.GF2530@zod.rchland.ibm.com>

Josh Boyer wrote:
> On Tue, Aug 18, 2009 at 10:28:04AM +0800, Tiejun Chen wrote:
>> To support cuImage, we need to initialize the required sections and 
>> ensure that it is built.
>>
>> -		cuboot-acadia.c cuboot-amigaone.c
>> +		cuboot-acadia.c cuboot-amigaone.c cuboot-kilauea.c
>> src-boot := $(src-wlib) $(src-plat) empty.c
>>
>> src-boot := $(addprefix $(obj)/, $(src-boot))
>> @@ -192,6 +192,7 @@ image-$(CONFIG_DEFAULT_UIMAGE)		+= uImage
>> image-$(CONFIG_EP405)			+= dtbImage.ep405
>> image-$(CONFIG_WALNUT)			+= treeImage.walnut
>> image-$(CONFIG_ACADIA)			+= cuImage.acadia
>> +image-$(CONFIG_KILAUEA)		+= cuImage.kilauea
> 
> I'm not thrilled with this part as cuImage is really the secondary
> solution if the U-Boot that comes with a board if FDT aware.  If you
> have a different board that needs this, perhaps you could add the
> target when that board support gets upstream?
> 

Agreed and I will remove this line as you expect. Right?

>> +static void kilauea_fixups(void)
>> +{
>> +	/*TODO: Please change this as the real. Note that should be 33MHZ~100MHZ.*/
> 
> What does that mean?
> 

It's difficult to check the sysclk value on all revision Kilauea board for me,
and we have to check this value only by the real target, not by reading one
register. So I hope it's safe to remind other guys here.

But I am sure that should be 33MHZ ~ 100MHZ as PPC405EX manual.

Best Regards
Tiejun

> josh
> 

^ permalink raw reply

* Re: [PATCH 1/3] powerpc/pci: Remove dead checks for CONFIG_PPC_OF
From: Stephen Rothwell @ 2009-08-21  5:46 UTC (permalink / raw)
  To: Grant Likely; +Cc: linuxppc-dev
In-Reply-To: <20090821053005.2289.59853.stgit@localhost.localdomain>

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

Hi Grant,

On Thu, 20 Aug 2009 23:30:09 -0600 Grant Likely <grant.likely@secretlab.ca> wrote:
>
> From: Grant Likely <grant.likely@secretlab.ca>
> 
> PPC_OF is always selected for arch/powerpc.  This patch removes the stale
> #defines
> 
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>

Good work.

Acked-by: Stephen Rothwell <sfr@canb.auug.org.au>

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

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

^ permalink raw reply

* Re: [PATCH 1/2] powerpc/405ex: provide necessary fixup function to support cuImage
From: tiejun.chen @ 2009-08-21  6:00 UTC (permalink / raw)
  To: Josh Boyer; +Cc: linuxppc-dev
In-Reply-To: <20090820132644.GE2530@zod.rchland.ibm.com>

Josh Boyer wrote:
> On Tue, Aug 18, 2009 at 10:28:03AM +0800, Tiejun Chen wrote:
>> For cuImage format it's necessary to provide clock fixups since u-boot will
>> not pass necessary clock frequency into the dtb included into cuImage so we 
>> implement the clock fixups as defined in the technical documentation for the 
>> board and update header file with the basic register definitions. 
>>
>> Signed-off-by: Tiejun Chen <tiejun.chen@windriver.com>
>> ---
>> arch/powerpc/boot/4xx.c |  142 +++++++++++++++++++++++++++++++++++++++++++++++
>> arch/powerpc/boot/4xx.h |    1 +
>> arch/powerpc/boot/dcr.h |   12 ++++
>> 3 files changed, 155 insertions(+), 0 deletions(-)
>>
>> diff --git a/arch/powerpc/boot/4xx.c b/arch/powerpc/boot/4xx.c
>> index 325b310..b5561b3 100644
>> --- a/arch/powerpc/boot/4xx.c
>> +++ b/arch/powerpc/boot/4xx.c
>> @@ -8,6 +8,10 @@
>>  *   Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
>>  *   Copyright (c) 2003, 2004 Zultys Technologies
>>  *
>> + * Copyright (C) 2009 Wind River Systems, Inc.
>> + *   Updated for supporting PPC405EX on Kilauea.
>> + *   Tiejun Chen <tiejun.chen@windriver.com>
>> + *
>>  * This program is free software; you can redistribute it and/or
>>  * modify it under the terms of the GNU General Public License
>>  * as published by the Free Software Foundation; either version
>> @@ -659,3 +663,141 @@ void ibm405ep_fixup_clocks(unsigned int sys_clk)
>> 	dt_fixup_clock("/plb/opb/serial@ef600300", uart0);
>> 	dt_fixup_clock("/plb/opb/serial@ef600400", uart1);
>> }
>> +
>> +static u8 fwdv_multi_bits[] = {
>> +	/* values for:  1 - 16 */
>> +	0x01, 0x02, 0x0e, 0x09, 0x04, 0x0b, 0x10, 0x0d, 0x0c, 0x05,
>> +	0x06, 0x0f, 0x0a, 0x07, 0x08, 0x03
>> +};
>> +
>> +u32 get_fwdva(unsigned long cpr_fwdv)
>> +{
>> +	u32 index;
>> +
>> +	for (index = 0; index < ARRAY_SIZE(fwdv_multi_bits); index++)
>> +		if (cpr_fwdv == (u32)fwdv_multi_bits[index])
>> +			return index + 1;
>> +
>> +	return 0;
>> +}
>> +
>> +static u8 fbdv_multi_bits[] = {
>> +	/* values for:  1 - 100 */
>> +	0x00, 0xff, 0x7e, 0xfd, 0x7a, 0xf5, 0x6a, 0xd5, 0x2a, 0xd4,
>> +	0x29, 0xd3, 0x26, 0xcc, 0x19, 0xb3, 0x67, 0xce, 0x1d, 0xbb,
>> +	0x77, 0xee, 0x5d, 0xba, 0x74, 0xe9, 0x52, 0xa5, 0x4b, 0x96,
>> +	0x2c, 0xd8, 0x31, 0xe3, 0x46, 0x8d, 0x1b, 0xb7, 0x6f, 0xde,
>> +	0x3d, 0xfb, 0x76, 0xed, 0x5a, 0xb5, 0x6b, 0xd6, 0x2d, 0xdb,
>> +	0x36, 0xec, 0x59, 0xb2, 0x64, 0xc9, 0x12, 0xa4, 0x48, 0x91,
>> +	0x23, 0xc7, 0x0e, 0x9c, 0x38, 0xf0, 0x61, 0xc2, 0x05, 0x8b,
>> +	0x17, 0xaf, 0x5f, 0xbe, 0x7c, 0xf9, 0x72, 0xe5, 0x4a, 0x95,
>> +	0x2b, 0xd7, 0x2e, 0xdc, 0x39, 0xf3, 0x66, 0xcd, 0x1a, 0xb4,
>> +	0x68, 0xd1, 0x22, 0xc4, 0x09, 0x93, 0x27, 0xcf, 0x1e, 0xbc,
>> +	/* values for:  101 - 200 */
>> +	0x78, 0xf1, 0x62, 0xc5, 0x0a, 0x94, 0x28, 0xd0, 0x21, 0xc3,
>> +	0x06, 0x8c, 0x18, 0xb0, 0x60, 0xc1, 0x02, 0x84, 0x08, 0x90,
>> +	0x20, 0xc0, 0x01, 0x83, 0x07, 0x8f, 0x1f, 0xbf, 0x7f, 0xfe,
>> +	0x7d, 0xfa, 0x75, 0xea, 0x55, 0xaa, 0x54, 0xa9, 0x53, 0xa6,
>> +	0x4c, 0x99, 0x33, 0xe7, 0x4e, 0x9d, 0x3b, 0xf7, 0x6e, 0xdd,
>> +	0x3a, 0xf4, 0x69, 0xd2, 0x25, 0xcb, 0x16, 0xac, 0x58, 0xb1,
>> +	0x63, 0xc6, 0x0d, 0x9b, 0x37, 0xef, 0x5e, 0xbd, 0x7b, 0xf6,
>> +	0x6d, 0xda, 0x35, 0xeb, 0x56, 0xad, 0x5b, 0xb6, 0x6c, 0xd9,
>> +	0x32, 0xe4, 0x49, 0x92, 0x24, 0xc8, 0x11, 0xa3, 0x47, 0x8e,
>> +	0x1c, 0xb8, 0x70, 0xe1, 0x42, 0x85, 0x0b, 0x97, 0x2f, 0xdf,
>> +	/* values for:  201 - 255 */
>> +	0x3e, 0xfc, 0x79, 0xf2, 0x65, 0xca, 0x15, 0xab, 0x57, 0xae,
>> +	0x5c, 0xb9, 0x73, 0xe6, 0x4d, 0x9a, 0x34, 0xe8, 0x51, 0xa2,
>> +	0x44, 0x89, 0x13, 0xa7, 0x4f, 0x9e, 0x3c, 0xf8, 0x71, 0xe2,
>> +	0x45, 0x8a, 0x14, 0xa8, 0x50, 0xa1, 0x43, 0x86, 0x0c, 0x98,
>> +	0x30, 0xe0, 0x41, 0x82, 0x04, 0x88, 0x10, 0xa0, 0x40, 0x81,
>> +	0x03, 0x87, 0x0f, 0x9f, 0x3f  /* END */
>> +};
>> +
>> +u32 get_fbdv(unsigned long cpr_fbdv)
>> +{
>> +	u32 index;
>> +
>> +	for (index = 0; index < ARRAY_SIZE(fbdv_multi_bits); index++)
>> +		if (cpr_fbdv == (u32)fbdv_multi_bits[index])
>> +			return index + 1;
>> +
>> +	return 0;
>> +}
> 
> Is this generic?  Can we the function and value arrays to get the fbdv for
> all 4xx boards and have the right values pop out?  If not, then all of these
> need to be prefixed with ibm405ex_.
> 

Other 4xx boards have different fwdv_multi_bits[]/fbdv_multi_bits[] array as far
as I know. So I prefer to prefix with ibm405ex as you suggestion.

>> diff --git a/arch/powerpc/boot/dcr.h b/arch/powerpc/boot/dcr.h
>> index 95b9f53..ba41624 100644
>> --- a/arch/powerpc/boot/dcr.h
>> +++ b/arch/powerpc/boot/dcr.h
>> @@ -153,6 +153,18 @@ static const unsigned long sdram_bxcr[] = { SDRAM0_B0CR, SDRAM0_B1CR,
>> #define DCRN_CPC0_PLLMR1  0xf4
>> #define DCRN_CPC0_UCR     0xf5
>>
>> +/* 405EX Clocking Control regs */
>> +#define CPR0_CLKUPD     0x0020
>> +#define CPR0_PLLC       0x0040
>> +#define CPR0_PLLD       0x0060
>> +#define CPR0_CPUD       0x0080
>> +#define CPR0_PLBD       0x00a0
>> +#define CPR0_OPBD       0x00c0
>> +#define CPR0_PERD       0x00e0
>> +#define CPR0_AHBD       0x0100
>> +#define CPR0_ICFG       0x0140
> 
> You duplicated the #defines right below this.  Just change the comment for
> the already existing defines to say "440GX/405EX Clock Control regs".

I want to isolate 405EX with other 4xx for convenient maintaining code as my
original. And although there are same offset as the register of 440GX, they are
defined with different name on manual because of different design mechanism. So
I hope we cannot be confused these when others track the codes.

But this is not problem. I can merge them if you really feel bad :)

  You
> don't need to add CPR0_ICFG either, since you don't use it anywhere.
> 

Ok.

After your reply I will send v2 so thanks your help in advance.

Best Regards
Tiejun

> josh
> 

^ permalink raw reply

* Re: [PATCH 2/3] powerpc/pci: move pci_64.c device tree scanning code into pci-common.c
From: Stephen Rothwell @ 2009-08-21  6:01 UTC (permalink / raw)
  To: Grant Likely; +Cc: David S. Miller, linuxppc-dev
In-Reply-To: <20090821053014.2289.59798.stgit@localhost.localdomain>

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

Hi Grant,

On Thu, 20 Aug 2009 23:30:17 -0600 Grant Likely <grant.likely@secretlab.ca> wrote:
>
> +/**
> + * get_int_prop - Decode a u32 from a device tree property
> + */
> +static u32 get_int_prop(struct device_node *np, const char *name, u32 def)
> +{
> +	const u32 *prop;
> +	int len;
> +
> +	prop = of_get_property(np, name, &len);
> +	if (prop && len >= 4)
> +		return *prop;
> +	return def;
> +}

Maybe you could use sparc's of_getintprop_default() (after moving it into
drivers/of ...

> +
> +/**
> + * pci_parse_of_flags - Parse the flags cell of a device tree PCI address
> + * @addr0: value of 1st cell of a device tree PCI address.
> + * @bridge: Set this flag if the address is from a bridge 'ranges' property
> + */
> +unsigned int pci_parse_of_flags(u32 addr0, int bridge)
> +{
> +	unsigned int flags = 0;
> +
> +	if (addr0 & 0x02000000) {
> +		flags = IORESOURCE_MEM | PCI_BASE_ADDRESS_SPACE_MEMORY;
> +		flags |= (addr0 >> 22) & PCI_BASE_ADDRESS_MEM_TYPE_64;
> +		flags |= (addr0 >> 28) & PCI_BASE_ADDRESS_MEM_TYPE_1M;
> +		if (addr0 & 0x40000000)
> +			flags |= IORESOURCE_PREFETCH
> +				 | PCI_BASE_ADDRESS_MEM_PREFETCH;
> +		/* Note: We don't know whether the ROM has been left enabled
> +		 * by the firmware or not. We mark it as disabled (ie, we do
> +		 * not set the IORESOURCE_ROM_ENABLE flag) for now rather than
> +		 * do a config space read, it will be force-enabled if needed
> +		 */
> +		if (!bridge && (addr0 & 0xff) == 0x30)
> +			flags |= IORESOURCE_READONLY;
> +	} else if (addr0 & 0x01000000)
> +		flags = IORESOURCE_IO | PCI_BASE_ADDRESS_SPACE_IO;
> +	if (flags)
> +		flags |= IORESOURCE_SIZEALIGN;
> +	return flags;
> +}
> +
> +/**
> + * of_pci_parse_addrs - Parse PCI addresses assigned in the device tree node
> + * @node: device tree node for the PCI device
> + * @dev: pci_dev structure for the device
> + *
> + * This function parses the 'assigned-addresses' property of a PCI devices'
> + * device tree node and writes them into the associated pci_dev structure.
> + */
> +static void of_pci_parse_addrs(struct device_node *node, struct pci_dev *dev)
> +{
> +	u64 base, size;
> +	unsigned int flags;
> +	struct resource *res;
> +	const u32 *addrs;
> +	u32 i;
> +	int proplen;
> +
> +	addrs = of_get_property(node, "assigned-addresses", &proplen);
> +	if (!addrs)
> +		return;
> +	pr_debug("    parse addresses (%d bytes) @ %p\n", proplen, addrs);
> +	for (; proplen >= 20; proplen -= 20, addrs += 5) {
> +		flags = pci_parse_of_flags(addrs[0], 0);
> +		if (!flags)
> +			continue;
> +		base = of_read_number(&addrs[1], 2);
> +		size = of_read_number(&addrs[3], 2);
> +		if (!size)
> +			continue;
> +		i = addrs[0] & 0xff;
> +		pr_debug("  base: %llx, size: %llx, i: %x\n",
> +			 (unsigned long long)base,
> +			 (unsigned long long)size, i);
> +
> +		if (PCI_BASE_ADDRESS_0 <= i && i <= PCI_BASE_ADDRESS_5) {
> +			res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2];
> +		} else if (i == dev->rom_base_reg) {
> +			res = &dev->resource[PCI_ROM_RESOURCE];
> +			flags |= IORESOURCE_READONLY | IORESOURCE_CACHEABLE;
> +		} else {
> +			printk(KERN_ERR "PCI: bad cfg reg num 0x%x\n", i);
> +			continue;
> +		}
> +		res->start = base;
> +		res->end = base + size - 1;
> +		res->flags = flags;
> +		res->name = pci_name(dev);
> +	}
> +}

And similarly with sparc's pci_parse_of_addrs() and pci_parse_of_flags
() ?  Maybe create drivers/of/pci.c (or drivers/pci/of.c)?  Or maybe they
are still too different?

There is probably scope for more consolidation there.
-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

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

^ permalink raw reply

* Re: [PATCH 2/3] powerpc/pci: move pci_64.c device tree scanning code into pci-common.c
From: Benjamin Herrenschmidt @ 2009-08-21  6:05 UTC (permalink / raw)
  To: Grant Likely; +Cc: linuxppc-dev
In-Reply-To: <20090821053014.2289.59798.stgit@localhost.localdomain>

On Thu, 2009-08-20 at 23:30 -0600, Grant Likely wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
> 
> The PCI device tree scanning code in pci_64.c is some useful functionality.
> It allows PCI devices to be described in the device tree instead of being
> probed for, which in turn allows pci devices to use all of the device tree
> facilities to describe complex PCI bus architectures like GPIO and IRQ
> routing (perhaps not a common situation for desktop or server systems,
> but useful for embedded systems with on-board PCI devices).
> 
> This patch moves the device tree scanning into pci-common.c so it is
> available for 32-bit powerpc machines too.

I'd rather move it into a separate pci-of-scan.c file so we can more
easily try to move it to drivers/of or drivers/pci for use by other
archs later on.

Ben.

^ permalink raw reply

* Re: [U-Boot] NAND ECC Error with wrong SMC ording bug
From: Sean MacLennan @ 2009-08-21  6:26 UTC (permalink / raw)
  To: vimal singh; +Cc: u-boot, Stefan Roese, Feng Kan, linux-mtd, linuxppc-dev
In-Reply-To: <ce9ab5790908202217t2430646co5059f308a23d7397@mail.gmail.com>

On Fri, 21 Aug 2009 10:47:09 +0530
vimal singh <vimal.newwork@gmail.com> wrote:

> Just one question: did you enabled MTD_NAND_ECC_SMC in configs?

It is automagically selected when you select the NDFC driver.

Cheers,
   Sean

^ permalink raw reply

* Re: [U-Boot] NAND ECC Error with wrong SMC ording bug
From: Stefan Roese @ 2009-08-21  6:27 UTC (permalink / raw)
  To: u-boot; +Cc: linuxppc-dev, linux-mtd, vimal singh, Sean MacLennan
In-Reply-To: <ce9ab5790908202217t2430646co5059f308a23d7397@mail.gmail.com>

On Friday 21 August 2009 07:17:09 vimal singh wrote:
> > diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c
> > index 89bf85a..497e175 100644
> > --- a/drivers/mtd/nand/ndfc.c
> > +++ b/drivers/mtd/nand/ndfc.c
> > @@ -101,9 +101,8 @@ static int ndfc_calculate_ecc(struct mtd_info *mtd,
> >
> >        wmb();
> >        ecc = in_be32(ndfc->ndfcbase + NDFC_ECC);
> > -       /* The NDFC uses Smart Media (SMC) bytes order */
> > -       ecc_code[0] = p[2];
> > -       ecc_code[1] = p[1];
> > +       ecc_code[0] = p[1];
> > +       ecc_code[1] = p[2];
> >        ecc_code[2] = p[3];
> >
> >        return 0;
> >
> > Does anybody see a problem with my method of reproducing the bug? This
> > bug is deadly for our customers. I don't want to make the change unless
> > it is absolutely necessary..
>
> Just one question: did you enabled MTD_NAND_ECC_SMC in configs?

Yes, MTD_NAND_ECC_SMC is selected via Kconfig for this driver.

Cheers,
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: [U-Boot] NAND ECC Error with wrong SMC ording bug
From: Victor Gallardo @ 2009-08-21  6:30 UTC (permalink / raw)
  To: vimal singh, Sean MacLennan
  Cc: u-boot, Stefan Roese, Feng Kan, linux-mtd, linuxppc-dev
In-Reply-To: <ce9ab5790908202217t2430646co5059f308a23d7397@mail.gmail.com>

Hi Vimal,=0A=0A> > With the current ndfc code, the error correction gets th=
e bits wrong.=0A> > Switching it back to the original way and the correctio=
n is correct.=0A> >=0A> > diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mt=
d/nand/ndfc.c=0A> > index 89bf85a..497e175 100644=0A> > --- a/drivers/mtd/n=
and/ndfc.c=0A> > +++ b/drivers/mtd/nand/ndfc.c=0A> > @@ -101,9 +101,8 @@ st=
atic int ndfc_calculate_ecc(struct mtd_info *mtd,=0A> >=0A> > =A0 =A0 =A0 =
=A0wmb();=0A> > =A0 =A0 =A0 =A0ecc =3D in_be32(ndfc->ndfcbase + NDFC_ECC);=
=0A> > - =A0 =A0 =A0 /* The NDFC uses Smart Media (SMC) bytes order */=0A> =
> - =A0 =A0 =A0 ecc_code[0] =3D p[2];=0A> > - =A0 =A0 =A0 ecc_code[1] =3D p=
[1];=0A> > + =A0 =A0 =A0 ecc_code[0] =3D p[1];=0A> > + =A0 =A0 =A0 ecc_code=
[1] =3D p[2];=0A> > =A0 =A0 =A0 =A0ecc_code[2] =3D p[3];=0A> >=0A> > =A0 =
=A0 =A0 =A0return 0;=0A> >=0A> > Does anybody see a problem with my method =
of reproducing the bug? This=0A> > bug is deadly for our customers. I don't=
 want to make the change unless=0A> > it is absolutely necessary..=0A> =0A>=
 Just one question: did you enabled MTD_NAND_ECC_SMC in configs?=0A=0AYes, =
it was set.=0A=0ABest Regards,=0A=0AVictor Gallardo

^ permalink raw reply

* 832x: MATH_EMUL
From: Heiko Schocher @ 2009-08-21  6:39 UTC (permalink / raw)
  To: linuxppc-dev

Hello,

I actually porting a mpc8321 based port, and because there is no FPU
on this CPU, I activated MATH_EMUL, as all other mpc832x ports did.

Is there something like a counter, which counts how many times this
Exception occurs?

Thanks.

bye
Heiko
-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany

^ permalink raw reply

* Re: [PATCH 2/2] powerpc/405ex: support cuImage via included dtb
From: Stefan Roese @ 2009-08-21  6:35 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: tiejun.chen
In-Reply-To: <4A8E3396.9030006@windriver.com>

On Friday 21 August 2009 07:41:42 tiejun.chen wrote:
> >> +static void kilauea_fixups(void)
> >> +{
> >> +	/*TODO: Please change this as the real. Note that should be
> >> 33MHZ~100MHZ.*/
> >
> > What does that mean?
>
> It's difficult to check the sysclk value on all revision Kilauea board for
> me, and we have to check this value only by the real target, not by reading
> one register. So I hope it's safe to remind other guys here.

Kilauea uses this value (33.333MHz) on all board revisions, AFAIK. Your 
comment is a bit confusing. I suggest that you just remove it.

Cheers,
Stefan

^ permalink raw reply

* Re: [PATCH 2/2] powerpc/405ex: support cuImage via included dtb
From: tiejun.chen @ 2009-08-21  6:39 UTC (permalink / raw)
  To: Stefan Roese; +Cc: linuxppc-dev
In-Reply-To: <200908210835.58288.sr@denx.de>

Stefan Roese wrote:
> On Friday 21 August 2009 07:41:42 tiejun.chen wrote:
>>>> +static void kilauea_fixups(void)
>>>> +{
>>>> +	/*TODO: Please change this as the real. Note that should be
>>>> 33MHZ~100MHZ.*/
>>> What does that mean?
>> It's difficult to check the sysclk value on all revision Kilauea board for
>> me, and we have to check this value only by the real target, not by reading
>> one register. So I hope it's safe to remind other guys here.
> 
> Kilauea uses this value (33.333MHz) on all board revisions, AFAIK. Your 
> comment is a bit confusing. I suggest that you just remove it.
> 

I appreciate your help.

Best Regards
Tiejun

> Cheers,
> Stefan
> 

^ permalink raw reply

* Re: [Bugme-new] [Bug 14021] New: hfsplus caused data loss
From: Brad Boyer @ 2009-08-21  6:19 UTC (permalink / raw)
  To: Andrew Morton
  Cc: linux-fsdevel, linuxppc-dev, bugzilla-daemon, rbrito,
	bugme-daemon
In-Reply-To: <20090820150242.a4b5eccc.akpm@linux-foundation.org>

On Thu, Aug 20, 2009 at 03:02:42PM -0700, Andrew Morton wrote:
> 
> (switched to email.  Please respond via emailed reply-to-all, not via the
> bugzilla web interface).
> 
> On Thu, 20 Aug 2009 02:17:21 GMT
> bugzilla-daemon@bugzilla.kernel.org wrote:
> 
> > http://bugzilla.kernel.org/show_bug.cgi?id=14021
> > 
> >            Summary: hfsplus caused data loss
> >            Product: File System
> >            Version: 2.5
> >     Kernel Version: 2.6.31-rc5
> >           Platform: All
> >         OS/Version: Linux
> >               Tree: Mainline
> >             Status: NEW
> >           Severity: normal
> >           Priority: P1
> >          Component: HFS/HFSPLUS
> >         AssignedTo: zippel@linux-m68k.org
> >         ReportedBy: rbrito@ime.usp.br
> >         Regression: Yes
> > 
> > 
> > Hi.
> > 
> > I am trying to package a new version of Apple's own fsck/mkfs for HFS+
> > filesystems so that they can be used in Linux as a way to transfer data among
> > computers, but I had quite a surprise when I was using the hfsplus module.
> > 
> > I just created a 100MB file with nulls (dd if=/dev/null ...) and I created an
> > HFS+ filesystem on it.
> > 
> > Then, I loop mounted it and tried to use it a little bit (in particular,
> > applying patches with quilt on a source tree). The commands spit some errors
> > about not being able to create links (I never had that problem before) and the
> > directory where I was became empty!
> > 
> > Furthermore, here is a quite, quite strange directory listing:
> > 
> > ,----
> > | rbrito@chagas:/media/usb7$ ls -lAF
> > | ls: hfsprogs_332.14-7.diff.gz: No such file or directory
> > | ls: hfsprogs_332.14-7.dsc: No such file or directory
> > | ls: hfsprogs_332.14.orig.tar.gz: No such file or directory
> > | ls: hfsprogs_332.18-1.diff.gz: No such file or directory
> > | ls: hfsprogs_332.18-1.dsc: No such file or directory
> > | ls: hfsprogs_332.18-1_amd64.changes: No such file or directory
> > | ls: hfsprogs_332.18-1_amd64.deb: No such file or directory
> > | ls: hfsprogs_332.18.orig.tar.gz: No such file or directory
> > | total 1636
> > | drwxr-xr-x 1 rbrito rbrito     39 Aug 17 08:13 hfsprogs-332.14/
> > | drwxr-xr-x 1 rbrito rbrito     39 Aug 17 08:13 hfsprogs-332.14/
> > | drwxr-xr-x 1 rbrito rbrito     45 Aug 17 15:30 hfsprogs-332.18/
> > | -rw-r--r-- 1 rbrito rbrito  35609 Aug 17 08:13 hfsprogs_332.14-7.diff.gz
> > | -rw-r--r-- 1 rbrito rbrito   1193 Aug 17 08:13 hfsprogs_332.14-7.dsc
> > | -rw-r--r-- 1 rbrito rbrito 714035 Aug 17 08:13 hfsprogs_332.14.orig.tar.gz
> > | -rw-r--r-- 1 rbrito rbrito  35342 Aug 17 15:26 hfsprogs_332.18-1.diff.gz
> > | -rw-r--r-- 1 rbrito rbrito    954 Aug 17 15:26 hfsprogs_332.18-1.dsc
> > | -rw-r--r-- 1 rbrito rbrito   2148 Aug 17 15:26
> > hfsprogs_332.18-1_amd64.changes
> > | -rw-r--r-- 1 rbrito rbrito 135398 Aug 17 15:26 hfsprogs_332.18-1_amd64.deb
> > | -rw-r--r-- 1 rbrito rbrito 732449 Aug 17 08:35 hfsprogs_332.18.orig.tar.gz
> > | rbrito@chagas:/media/usb7$
> > `----
> > 
> > I am using kernel 2.6.31-rc5-1rb.pre6 (that is, rc5 with git updates up to one
> > or two days before rc6).
> > 
> > There are no messages in the dmesg, besides these:
> > 
> > ,----
> > | [30991.501804] loop: module loaded
> > | [30991.513337] hfs: create hidden dir...
> > | [39897.867830] hfs: create hidden dir...
> > | [39960.061622] hfs: splitting index node...
> > `----
> > 
> > No stack traces, no nothing. Oh, I still have the disk image that I created, if
> > it is of any interest.
> > 
> > Please let me know if I can provide any further information.
> > 
> 
> Gee.  Nobody really does much maintenance work on hfs/hfsplus any more.
> I cc'ed the ppc guys as I expect that most HFS users are over there.
> 
> It seems like a pretty gross failure - others should be hitting it.
> 
> I wonder if it's a weird interaction with the loop driver.

I can explain the ls output in a very generic sense. This is what you
get if the lookup fails on a name returned by a readdir. I suspect
that creating hard links is failing in some way. In particular, the
"hidden dir" mentioned in the log is used to save the real files for
hard links.

As a quick explanation, HFS+ doesn't have a real concept of hard
links. Apple hacked it in after the fact. The way it works is that
there is a special hidden directory, and the real catalog entries
that match the real names are just references to the hidden file.
Both HFS and HFS+ have no separate notion of directory entries and
inode data. The metadata is stored in records keyed by file name.

Hard links were added after I stopped working on the HFS+ code, so
I don't know it in detail. I know it works for reading hard links,
but I never actually tried creating more links.

	Brad Boyer
	flar@allandria.com

^ permalink raw reply

* Re: 832x: MATH_EMUL
From: Kumar Gala @ 2009-08-21  6:55 UTC (permalink / raw)
  To: hs; +Cc: linuxppc-dev
In-Reply-To: <4A8E4128.6040905@denx.de>


On Aug 21, 2009, at 1:39 AM, Heiko Schocher wrote:

> Hello,
>
> I actually porting a mpc8321 based port, and because there is no FPU
> on this CPU, I activated MATH_EMUL, as all other mpc832x ports did.
>
> Is there something like a counter, which counts how many times this
> Exception occurs?

Geert published some patches that did something like this but there  
isn't upstream as far as I know at this point.

- k

^ 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