LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH] PowerPC 44x: add missing define TARGET_4xx and TARGET_440GX to cuboot-taishan.c
From: Josh Boyer @ 2008-02-27 14:57 UTC (permalink / raw)
  To: Valentine Barshak; +Cc: linuxppc-dev
In-Reply-To: <20080226145853.GA18212@ru.mvista.com>

On Tue, 26 Feb 2008 17:58:53 +0300
Valentine Barshak <vbarshak@ru.mvista.com> wrote:

> In order to get the proper boad info (bd_info) structure defined in ppcboot.h
> both TARGET_4xx and TARGET_44x should be defined for all PowerPC 440 boards.
> The 440GX boards also need TARGET_440GX defined since they have 4 EMACs and
> there are 4 MAC addesses in bd_info passed by u-boot.

Thanks, looks much better.  I'll send this to Paul later today.

josh

^ permalink raw reply

* [PATCH] Always define pmu_sys_suspended
From: Guido Günther @ 2008-02-27 14:14 UTC (permalink / raw)
  To: linuxppc-dev

In current Linus git pmu_sys_suspended is only defined if
CONFIG_SUSPEND is set, so compilation fails with:

drivers/built-in.o: In function `pmu_led_set':
via-pmu-led.c:(.text+0x48622): undefined reference to `pmu_sys_suspended'
via-pmu-led.c:(.text+0x48626): undefined reference to `pmu_sys_suspended'
drivers/built-in.o: In function `pmu_req_done':
via-pmu-led.c:(.text+0x48696): undefined reference to `pmu_sys_suspended'
via-pmu-led.c:(.text+0x4869a): undefined reference to `pmu_sys_suspended'
make: *** [.tmp_vmlinux1] Error 1

since via-pmu-led.c uses it unconditionally. Instead of adding more '#ifdef'
clutter I moved it out of the #ifdef so it's always available. Need to fix
compilation on PPC32 without CONFIG_SUSPEND.

Signed-off-by: Guido Guenther <agx@sigxcpu.org>
---
 drivers/macintosh/via-pmu.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index ebec663..296edcb 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -2437,8 +2437,8 @@ void pmu_blink(int n)
 }
 #endif /* DEBUG_SLEEP */
 
-#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32)
 int pmu_sys_suspended;
+#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32)
 
 static int pmu_sys_suspend(struct sys_device *sysdev, pm_message_t state)
 {
-- 
1.5.4.2

^ permalink raw reply related

* [PATCH] Export pmu_* variables unconditionally
From: Guido Günther @ 2008-02-27 14:16 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <20080227141452.GA10345@bogon.ms20.nix>

Otherwise without CONFIG_SUSPEND we have:

ERROR: "pmu_batteries" [drivers/macintosh/apm_emu.ko] undefined!
ERROR: "pmu_battery_count" [drivers/macintosh/apm_emu.ko] undefined!
ERROR: "pmu_power_flags" [drivers/macintosh/apm_emu.ko] undefined!

on PPC32. The variables aren't wrapped in '#if defined(CONFIG_SUSPEND)'
so we probably shouldn't wrap the exports either. Fixes compilation on
ppc32.

Signed-off-by: Guido Guenther <agx@sigxcpu.org>
---
 drivers/macintosh/via-pmu.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index 296edcb..399fc7f 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -2528,7 +2528,7 @@ EXPORT_SYMBOL(pmu_wait_complete);
 EXPORT_SYMBOL(pmu_suspend);
 EXPORT_SYMBOL(pmu_resume);
 EXPORT_SYMBOL(pmu_unlock);
-#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32)
+#if defined(CONFIG_PPC32)
 EXPORT_SYMBOL(pmu_enable_irled);
 EXPORT_SYMBOL(pmu_battery_count);
 EXPORT_SYMBOL(pmu_batteries);
-- 
1.5.4.2

^ permalink raw reply related

* Re: copy_from_user problem
From: Arnd Bergmann @ 2008-02-27 12:40 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <47C5574D.2090409@us.ibm.com>

On Wednesday 27 February 2008, Maynard Johnson wrote:
> > Sounds to me that your kernel module will try to copy_from_user() from
> > the user context of ... insmod :-)
> > =A0=20
> Yeah, that's probably the problem (along with my lack of understanding=20
> how VM works =A0-- heh). =A0I guess I was just getting lucky with the 32-=
bit=20
> test in that the 32-bit libc was being loaded for my insmod process at=20
> the same virtual memory address as for my C test program.
> > You need to do your copy_from_user() from within the context of the
> > program you try to access the memory from !
> > =A0=20
> Can't do that in the "real" code I'm developing, so I guess I'll need to=
=20
> use get_user_pages. =A0Hmmm . . . not quite as simple to use as=20
> copy_from_user, and I don't see any doc on it. =A0But at least I've found=
=20
> a couple examples in the kernel tree.

Are you sure that this has to run in kernel space? You may be able to
do the same thing with ptrace() from another user process, which is
normally a lot easier to do, especially if you're not familiar with all
the corner cases in powerpc linux memory management.

> > If you need to access another context than the current one, you then
> > need to use a different mechanism, such as get_user_pages(), though
> > beware that you can only do that for memory, not SPE local store or
> > register mappings.
> > =A0=20
> The "real" code I'm developing is targeted at POWER, not Cell.

Cell systems are compliant to the Power architecture and they run
the same software, so you should at least make sure you have error
handling in place to deal with an access of SPU local store pages
and don't cause random crashes.

	Arnd <><

^ permalink raw reply

* 2.6.25-rc3 on mpc8548amc doesn't boot
From: maxime louvel @ 2008-02-27 12:37 UTC (permalink / raw)
  To: linuxppc-embedded


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

Hi,

I am still trying to make a 2.6.25-rc3 vanilla kernel boot (an work fine in
a second time) on a mpc8548amc board.
I have add the platform specific stuff from the sources of the current
kernel running on the cards.
What I have basically add is:
- arch/powerpc/platforms/85xx/mpc85xx_amc.c
- arch/powerpc/boot/dts/mpc8548amc.dts
I have also changed the Kconfig and Makefile in the
arch/powerpc/platforms/85xx to make the kernel try to support my board

I have encountered some problem when compiling a uImage that I have
basically solve like this (in arch/powerpc/boot/Makefile)
#$(obj)/4xx.o: BOOTCFLAGS += -mcpu=405
#$(obj)/ebony.o: BOOTCFLAGS += -mcpu=405
#$(obj)/cuboot-taishan.o: BOOTCFLAGS += -mcpu=405
#$(obj)/cuboot-katmai.o: BOOTCFLAGS += -mcpu=405
#$(obj)/treeboot-walnut.o: BOOTCFLAGS += -mcpu=405

I have a gcc-3.4.3 embedded compiler with some stuff specific to the
platform.

After the previous hack, I have been able to compile a uImage.

I have tried to boot it and this is what I got:
AMC=> bootm 0x1000000
## Booting image at 01000000 ...
  Image Name:   Linux-2.6.24
  Image Type:   PowerPC Linux Kernel Image (gzip compressed)
  Data Size:    1802038 Bytes =  1.7 MB
  Load Address: 00000000
  Entry Point:  00000000
  Verifying Checksum ... OK
  Uncompressing Kernel Image ... OK

No further messages...

I have recently updated the uboot of the cards (to support the new image
version) and I am capable of booting a 2.6.23.6 image.
This last image has been compiled from a vanilla kernel where I have add the
platform specific stuff (cf beginning of this mail).

Since my 2.6.23.6 image works fine, I have tried to adapt the file I have
added to the 2.6.25-rc3 kernel.

I have made some changes in the arch/powerpc/platforms/85xx/mpc85xx_amc.c
file and in the mpc8548amc.dts file.
I have attached the changes I have done on both files.

Do you have an idea ?

cheers,
Maxime

-- 
Maxime Louvel
0044 7964 5555 80
43 Allen road
Whitemore reans
WV60AW Wolverhampton
United Kingdom

[-- Attachment #1.2: Type: text/html, Size: 2322 bytes --]

[-- Attachment #2: 2.6.23.6.mpc8548_amc_2.6.25-rc3.mpc85xx_amc --]
[-- Type: application/octet-stream, Size: 1263 bytes --]

--- ../../srcChanges/2.6.23.6/mpc8548_amc.c	2008-02-27 12:27:33.000000000 +0000
+++ linux-2.6.25-rc3_changed/arch/powerpc/platforms/85xx/mpc85xx_amc.c	2008-02-27 10:29:13.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * MPC8548 AMC board specific routines
+ * MPC85xx AMC board specific routines
  *
  * Copyright 2006 Freescale Semiconductor Inc.
  *
@@ -23,14 +23,20 @@
 #include <asm/prom.h>
 #include <mm/mmu_decl.h>
 #include <asm/udbg.h>
-#include <asm/of_device.h>
-#include <asm/of_platform.h>
+/* #include <asm/of_device.h> */
+/* #include <asm/of_platform.h> */
+/* commit:
+ * [POWERPC] 8xxx: Convert #include of asm/of_{platform, device}.h
+                   into linux/of_{platform, device}.h.
+ */
+#include <linux/of_device.h>  
+#include <linux/of_platform.h>
 
 #include <asm/mpic.h>
 
 #include <sysdev/fsl_soc.h>
-/*#include <sysdev/fsl_rio.h>*/
-#include "mpc85xx.h"
+#include <sysdev/fsl_rio.h>
+/* #include "mpc85xx.h" */
 
 #ifndef CONFIG_PCI
 unsigned long isa_io_base = 0;
@@ -141,7 +147,7 @@
 	.init_IRQ		= mpc85xx_amc_pic_init,
 	.show_cpuinfo		= mpc85xx_amc_show_cpuinfo,
 	.get_irq		= mpic_get_irq,
-	.restart		= mpc85xx_restart,
+	.restart		= fsl_rstcr_restart,
 	.calibrate_decr		= generic_calibrate_decr,
 	.progress		= udbg_progress,
 };

[-- Attachment #3: 2.6.23.6.mpc8548dts_2.6.25-rc3.mpc8548dts --]
[-- Type: application/octet-stream, Size: 2593 bytes --]

--- ../../srcChanges/2.6.23.6/mpc8548amc.dts	2008-02-27 12:27:46.000000000 +0000
+++ linux-2.6.25-rc3_changed/arch/powerpc/boot/dts/mpc8548amc.dts	2008-02-27 10:22:13.000000000 +0000
@@ -15,6 +15,12 @@
 	compatible = "MPC8548AMC";
 	#address-cells = <1>;
 	#size-cells = <1>;
+	aliases {
+	        ethernet0 = &enet0;
+		ethernet1 = &enet1;
+		ethernet2 = &enet2;
+		ethernet3 = &enet3;
+        };
 
 	cpus {
 		#cpus = <1>;
@@ -31,7 +37,6 @@
 			timebase-frequency = <0>;	// 33 MHz, from uboot
 			bus-frequency = <0>;		// From uboot
 			clock-frequency = <0>;		// From uboot
-			32-bit;
 		};
 	};
 
@@ -43,14 +48,15 @@
 	soc8548@e0000000 {
 		#address-cells = <1>;
 		#size-cells = <1>;
-		#interrupt-cells = <2>;
 		device_type = "soc";
 		ranges = <0 e0000000 00100000>;
 		reg = <e0000000 00100000>;	// CCSRBAR 1M
 		bus-frequency = <0>;
-
+	
 		i2c@3000 {
-			device_type = "i2c";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			cell-index = <0>
 			compatible = "fsl-i2c";
 			reg = <3000 100>;
 			interrupts = <1b 2>;
@@ -58,13 +64,24 @@
 			dfsrr;
 		};
 
+		i2c@3100 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			cell-index = <1>;
+			compatible = "fsl-i2c";
+			reg = <3100 100>;
+			interrupts = <1b 2>;
+			interrupt-parent = <&mpic>;
+			dfsrr;
+		};
+
 		mdio@24520 {
 			#address-cells = <1>;
 			#size-cells = <0>;
-			device_type = "mdio";
-			compatible = "gianfar";
+			compatible = "fsl,gianfar-mdio";
 			reg = <24520 20>;
 			linux,phandle = <24520>;
+			
 			phy0: ethernet-phy@10 {
 				interrupt-parent = <&mpic>;
 				interrupts = <34 1>;
@@ -91,9 +108,8 @@
 			};
 		};
 
-		ethernet@24000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
+		enet0: ethernet@24000 {
+		        cell-index = <0>;
 			device_type = "network";
 			model = "eTSEC";
 			compatible = "gianfar";
@@ -104,9 +120,8 @@
 			phy-handle = <&phy0>;
 		};
 
-		ethernet@25000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
+		enet1: ethernet@25000 {
+		        cell-index = <1>;
 			device_type = "network";
 			model = "eTSEC";
 			compatible = "gianfar";
@@ -117,9 +132,8 @@
 			phy-handle = <&phy1>;
 		};
 		
-		ethernet@26000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
+		enet3: ethernet@26000 {
+		        cell-index = <2>;
 			device_type = "network";
 			model = "eTSEC";
 			compatible = "gianfar";
@@ -130,9 +144,8 @@
 			phy-handle = <&phy2>;
 		};
 
-		ethernet@27000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
+		enet4: ethernet@27000 {
+		        cell-index = <3>;
 			device_type = "network";
 			model = "eTSEC";
 			compatible = "gianfar";

^ permalink raw reply

* Re: copy_from_user problem
From: Maynard Johnson @ 2008-02-27 12:27 UTC (permalink / raw)
  To: benh; +Cc: linuxppc-dev
In-Reply-To: <1204068146.15052.188.camel@pasglop>

Benjamin Herrenschmidt wrote:
> On Tue, 2008-02-26 at 08:49 -0600, Maynard Johnson wrote:
>   
>> 2. Compile C program as 32-bit; then run it.  While the program is 
>> waiting for input, obtain its PID and do 'cat /proc/<pid>/maps' to
>> get 
>> the address of where libc is loaded.
>> 3. From the dir where you build the uaccess_test kernel module:
>>          'insmod ./uaccess_test.ko lib_addr=0x<mem_loc_libc>'
>>     This should succeed.  dmesg to verify.
>> 4. Unload the module.
>> 5. Recompile your C program with -m64; start it up and obtain the 
>> address of libc again (now a 64-bit address).
>> 6. Load the uaccess_test kernel module and pass 
>> 'lib_addr=0x<mem_loc_libc>'.  Note that this time, the load fails. 
>> dmesg to see debug printk's.
>>     
>
> Sounds to me that your kernel module will try to copy_from_user() from
> the user context of ... insmod :-)
>   
Yeah, that's probably the problem (along with my lack of understanding 
how VM works  -- heh).  I guess I was just getting lucky with the 32-bit 
test in that the 32-bit libc was being loaded for my insmod process at 
the same virtual memory address as for my C test program.
> You need to do your copy_from_user() from within the context of the
> program you try to access the memory from !
>   
Can't do that in the "real" code I'm developing, so I guess I'll need to 
use get_user_pages.  Hmmm . . . not quite as simple to use as 
copy_from_user, and I don't see any doc on it.  But at least I've found 
a couple examples in the kernel tree.
> If you need to access another context than the current one, you then
> need to use a different mechanism, such as get_user_pages(), though
> beware that you can only do that for memory, not SPE local store or
> register mappings.
>   
The "real" code I'm developing is targeted at POWER, not Cell.

Thanks, Ben!

-Maynard
> Ben.
>
>
>   

^ permalink raw reply

* Re: [PATCH 3/8] Remove unused pte_offset variable
From: Benjamin Herrenschmidt @ 2008-02-27  8:18 UTC (permalink / raw)
  To: michael; +Cc: linuxppc-dev
In-Reply-To: <1204099860.6932.2.camel@concordia>


On Wed, 2008-02-27 at 19:11 +1100, Michael Ellerman wrote:

> I'm pretty sure I tested it and it worked.
> 
> But I didn't actually change anything WRT the spider offset anyway, we
> still add it to it_offset just like we used to, it's just we don't put
> it in the window and then pull it out again.
> 
> The only thing that's changed is we now use offset (aka. base) in the
> tce routines in addition to pte_offset.

Ok. Should be fine then.

Ben.

^ permalink raw reply

* Re: [PATCH 3/8] Remove unused pte_offset variable
From: Michael Ellerman @ 2008-02-27  8:11 UTC (permalink / raw)
  To: benh; +Cc: linuxppc-dev
In-Reply-To: <1204099491.15052.227.camel@pasglop>

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

On Wed, 2008-02-27 at 19:04 +1100, Benjamin Herrenschmidt wrote:
> On Wed, 2008-02-27 at 18:28 +1100, Michael Ellerman wrote:
> > The cell IOMMU code no longer needs to save the pte_offset variable
> > separately, it is incorporated into tbl->it_offset.
> > 
> > Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
> > ---
> 
> Do this work on spider ?
> 
> There is a subtle difference with spider is that the 0x80000000 you give
> to devices disappears when reaching the iommu (so isn't to be catered
> in the iommu offset).
> 
> It's a bit like the offset you have to add to the direct mapping on
> axon, in fact (the 0x8000060000000000 or so ...)

I'm pretty sure I tested it and it worked.

But I didn't actually change anything WRT the spider offset anyway, we
still add it to it_offset just like we used to, it's just we don't put
it in the window and then pull it out again.

The only thing that's changed is we now use offset (aka. base) in the
tce routines in addition to pte_offset.

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 3/8] Remove unused pte_offset variable
From: Benjamin Herrenschmidt @ 2008-02-27  8:04 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: linuxppc-dev
In-Reply-To: <180c3c87682d05b1d58e50df77f99478f98d9b30.1204097262.git.michael@ellerman.id.au>


On Wed, 2008-02-27 at 18:28 +1100, Michael Ellerman wrote:
> The cell IOMMU code no longer needs to save the pte_offset variable
> separately, it is incorporated into tbl->it_offset.
> 
> Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
> ---

Do this work on spider ?

There is a subtle difference with spider is that the 0x80000000 you give
to devices disappears when reaching the iommu (so isn't to be catered
in the iommu offset).

It's a bit like the offset you have to add to the direct mapping on
axon, in fact (the 0x8000060000000000 or so ...)

Ben.

>  arch/powerpc/platforms/cell/iommu.c |    5 +----
>  1 files changed, 1 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
> index 4e75919..555d264 100644
> --- a/arch/powerpc/platforms/cell/iommu.c
> +++ b/arch/powerpc/platforms/cell/iommu.c
> @@ -123,7 +123,6 @@ struct iommu_window {
>  	struct cbe_iommu *iommu;
>  	unsigned long offset;
>  	unsigned long size;
> -	unsigned long pte_offset;
>  	unsigned int ioid;
>  	struct iommu_table table;
>  };
> @@ -475,13 +474,11 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np,
>  	window->size = size;
>  	window->ioid = ioid;
>  	window->iommu = iommu;
> -	window->pte_offset = pte_offset;
>  
>  	window->table.it_blocksize = 16;
>  	window->table.it_base = (unsigned long)iommu->ptab;
>  	window->table.it_index = iommu->nid;
> -	window->table.it_offset = (offset >> IOMMU_PAGE_SHIFT) +
> -		window->pte_offset;
> +	window->table.it_offset = (offset >> IOMMU_PAGE_SHIFT) + pte_offset;
>  	window->table.it_size = size >> IOMMU_PAGE_SHIFT;
>  
>  	iommu_init_table(&window->table, iommu->nid);

^ permalink raw reply

* [PATCH 8/8] Convert the cell IOMMU fixed mapping to 16M IOMMU pages
From: Michael Ellerman @ 2008-02-27  7:28 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <4108415683edeb799fd4880a8dba3e9f27a34415.1204097262.git.michael@ellerman.id.au>

The only tricky part is we need to adjust the PTE insertion loop to
cater for holes in the page table. The PTEs for each segment start on
a 4K boundary, so with 16M pages we have 16 PTEs per segment and then
a gap to the next 4K page boundary.

It might be possible to allocate the PTEs for each segment separately,
saving the memory currently filling the gaps. However we'd need to
check that's OK with the hardware, and that it actually saves memory.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
 arch/powerpc/platforms/cell/iommu.c |   36 +++++++++++++++++++++-------------
 1 files changed, 22 insertions(+), 14 deletions(-)

diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index 12db681..0e82255 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -875,37 +875,45 @@ static void cell_dma_dev_setup_fixed(struct device *dev)
 	dev_dbg(dev, "iommu: fixed addr = %lx\n", addr);
 }
 
+static void insert_16M_pte(unsigned long addr, unsigned long *ptab,
+			   unsigned long base_pte)
+{
+	unsigned long segment, offset;
+
+	segment = addr >> IO_SEGMENT_SHIFT;
+	offset = (addr >> 24) - (segment << IO_PAGENO_BITS(24));
+	ptab = ptab + (segment * (1 << 12) / sizeof(unsigned long));
+
+	pr_debug("iommu: addr %lx ptab %p segment %lx offset %lx\n",
+		  addr, ptab, segment, offset);
+
+	ptab[offset] = base_pte | (__pa(addr) & IOPTE_RPN_Mask);
+}
+
 static void cell_iommu_setup_fixed_ptab(struct cbe_iommu *iommu,
 	struct device_node *np, unsigned long dbase, unsigned long dsize,
 	unsigned long fbase, unsigned long fsize)
 {
-	int i;
-	unsigned long base_pte, uaddr, *io_pte, *ptab;
+	unsigned long base_pte, uaddr, ioaddr, *ptab;
 
-	ptab = cell_iommu_alloc_ptab(iommu, fbase, fsize, IOMMU_PAGE_SHIFT);
+	ptab = cell_iommu_alloc_ptab(iommu, fbase, fsize, 24);
 
 	dma_iommu_fixed_base = fbase;
 
-	/* convert from bytes into page table indices */
-	dbase = dbase >> IOMMU_PAGE_SHIFT;
-	dsize = dsize >> IOMMU_PAGE_SHIFT;
-	fbase = fbase >> IOMMU_PAGE_SHIFT;
-	fsize = fsize >> IOMMU_PAGE_SHIFT;
-
 	pr_debug("iommu: mapping 0x%lx pages from 0x%lx\n", fsize, fbase);
 
-	io_pte = ptab;
 	base_pte = IOPTE_PP_W | IOPTE_PP_R | IOPTE_M | IOPTE_SO_RW
 		    | (cell_iommu_get_ioid(np) & IOPTE_IOID_Mask);
 
-	uaddr = 0;
-	for (i = fbase; i < fbase + fsize; i++, uaddr += IOMMU_PAGE_SIZE) {
+	for (uaddr = 0; uaddr < fsize; uaddr += (1 << 24)) {
 		/* Don't touch the dynamic region */
-		if (i >= dbase && i < (dbase + dsize)) {
+		ioaddr = uaddr + fbase;
+		if (ioaddr >= dbase && ioaddr < (dbase + dsize)) {
 			pr_debug("iommu: fixed/dynamic overlap, skipping\n");
 			continue;
 		}
-		io_pte[i - fbase] = base_pte | (__pa(uaddr) & IOPTE_RPN_Mask);
+
+		insert_16M_pte(uaddr, ptab, base_pte);
 	}
 
 	mb();
-- 
1.5.2.rc1.1884.g59b20

^ permalink raw reply related

* [PATCH 7/8] Allow for different IOMMU page sizes in cell IOMMU code
From: Michael Ellerman @ 2008-02-27  7:28 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <4108415683edeb799fd4880a8dba3e9f27a34415.1204097262.git.michael@ellerman.id.au>

Make some preliminary changes to cell_iommu_alloc_ptab() to allow it to
take the page size as a parameter rather than assuming IOMMU_PAGE_SIZE.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
 arch/powerpc/platforms/cell/iommu.c |   28 ++++++++++++++++------------
 1 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index a7bbc0a..12db681 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -113,7 +113,7 @@
 
 /* IOMMU sizing */
 #define IO_SEGMENT_SHIFT	28
-#define IO_PAGENO_BITS		(IO_SEGMENT_SHIFT - IOMMU_PAGE_SHIFT)
+#define IO_PAGENO_BITS(shift)	(IO_SEGMENT_SHIFT - (shift))
 
 /* The high bit needs to be set on every DMA address */
 #define SPIDER_DMA_OFFSET	0x80000000ul
@@ -327,7 +327,8 @@ static void cell_iommu_setup_stab(struct cbe_iommu *iommu,
 }
 
 static unsigned long *cell_iommu_alloc_ptab(struct cbe_iommu *iommu,
-				  unsigned long base, unsigned long size)
+				  unsigned long base, unsigned long size,
+				  unsigned long page_shift)
 {
 	struct page *page;
 	int i;
@@ -336,7 +337,10 @@ static unsigned long *cell_iommu_alloc_ptab(struct cbe_iommu *iommu,
 
 	start_seg = base >> IO_SEGMENT_SHIFT;
 	segments  = size >> IO_SEGMENT_SHIFT;
-	pages_per_segment = 1ull << IO_PAGENO_BITS;
+	pages_per_segment = 1ull << IO_PAGENO_BITS(page_shift);
+	/* PTEs for each segment must start on a 4K bounday */
+	pages_per_segment = max(pages_per_segment,
+				(1 << 12) / sizeof(unsigned long));
 
 	ptab_size = segments * pages_per_segment * sizeof(unsigned long);
 	pr_debug("%s: iommu[%d]: ptab_size: %lu, order: %d\n", __FUNCTION__,
@@ -357,13 +361,12 @@ static unsigned long *cell_iommu_alloc_ptab(struct cbe_iommu *iommu,
 	/* initialise the STEs */
 	reg = IOSTE_V | ((n_pte_pages - 1) << 5);
 
-	if (IOMMU_PAGE_SIZE == 0x1000)
-		reg |= IOSTE_PS_4K;
-	else if (IOMMU_PAGE_SIZE == 0x10000)
-		reg |= IOSTE_PS_64K;
-	else {
-		extern void __unknown_page_size_error(void);
-		__unknown_page_size_error();
+	switch (page_shift) {
+	case 12: reg |= IOSTE_PS_4K;  break;
+	case 16: reg |= IOSTE_PS_64K; break;
+	case 20: reg |= IOSTE_PS_1M;  break;
+	case 24: reg |= IOSTE_PS_16M; break;
+	default: BUG();
 	}
 
 	pr_debug("Setting up IOMMU stab:\n");
@@ -421,7 +424,8 @@ static void cell_iommu_setup_hardware(struct cbe_iommu *iommu,
 	unsigned long base, unsigned long size)
 {
 	cell_iommu_setup_stab(iommu, base, size, 0, 0);
-	iommu->ptab = cell_iommu_alloc_ptab(iommu, base, size);
+	iommu->ptab = cell_iommu_alloc_ptab(iommu, base, size,
+					    IOMMU_PAGE_SHIFT);
 	cell_iommu_enable_hardware(iommu);
 }
 
@@ -878,7 +882,7 @@ static void cell_iommu_setup_fixed_ptab(struct cbe_iommu *iommu,
 	int i;
 	unsigned long base_pte, uaddr, *io_pte, *ptab;
 
-	ptab = cell_iommu_alloc_ptab(iommu, fbase, fsize);
+	ptab = cell_iommu_alloc_ptab(iommu, fbase, fsize, IOMMU_PAGE_SHIFT);
 
 	dma_iommu_fixed_base = fbase;
 
-- 
1.5.2.rc1.1884.g59b20

^ permalink raw reply related

* [PATCH 6/8] Cell IOMMU: n_pte_pages is in 4K page units, not IOMMU_PAGE_SIZE
From: Michael Ellerman @ 2008-02-27  7:28 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <4108415683edeb799fd4880a8dba3e9f27a34415.1204097262.git.michael@ellerman.id.au>

We use n_pte_pages to calculate the stride through the page tables, but
we also use it to set the NPPT value in the segment table entry. That is
defined as the number of 4K pages per segment, so we should calculate
it as such regardless of the IOMMU page size.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
 arch/powerpc/platforms/cell/iommu.c |    9 ++++-----
 1 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index 2c703f6..a7bbc0a 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -347,9 +347,8 @@ static unsigned long *cell_iommu_alloc_ptab(struct cbe_iommu *iommu,
 	ptab = page_address(page);
 	memset(ptab, 0, ptab_size);
 
-	/* number of pages needed for a page table */
-	n_pte_pages = (pages_per_segment *
-		       sizeof(unsigned long)) >> IOMMU_PAGE_SHIFT;
+	/* number of 4K pages needed for a page table */
+	n_pte_pages = (pages_per_segment * sizeof(unsigned long)) >> 12;
 
 	pr_debug("%s: iommu[%d]: stab at %p, ptab at %p, n_pte_pages: %lu\n",
 			__FUNCTION__, iommu->nid, iommu->stab, ptab,
@@ -369,8 +368,8 @@ static unsigned long *cell_iommu_alloc_ptab(struct cbe_iommu *iommu,
 
 	pr_debug("Setting up IOMMU stab:\n");
 	for (i = start_seg; i < (start_seg + segments); i++) {
-		iommu->stab[i] = reg | (__pa(ptab) + n_pte_pages *
-					IOMMU_PAGE_SIZE * (i - start_seg));
+		iommu->stab[i] = reg | (__pa(ptab) + (n_pte_pages << 12) *
+					(i - start_seg));
 		pr_debug("\t[%d] 0x%016lx\n", i, iommu->stab[i]);
 	}
 
-- 
1.5.2.rc1.1884.g59b20

^ permalink raw reply related

* [PATCH 5/8] Split setup of IOMMU stab and ptab, allocate dynamic/fixed ptabs separately
From: Michael Ellerman @ 2008-02-27  7:28 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <4108415683edeb799fd4880a8dba3e9f27a34415.1204097262.git.michael@ellerman.id.au>

Currently the cell IOMMU code allocates the entire IOMMU page table in a
contiguous chunk. This is nice and tidy, but for machines with larger
amounts of RAM the page table allocation can fail due to it simply being
too large.

So split the segment table and page table setup routine, and arrange to
have the dynamic and fixed page tables allocated separately.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
 arch/powerpc/platforms/cell/iommu.c |   62 ++++++++++++++++++++--------------
 1 files changed, 36 insertions(+), 26 deletions(-)

diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index 8e57e1a..2c703f6 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -306,50 +306,53 @@ static int cell_iommu_find_ioc(int nid, unsigned long *base)
 	return -ENODEV;
 }
 
-static void cell_iommu_setup_page_tables(struct cbe_iommu *iommu,
+static void cell_iommu_setup_stab(struct cbe_iommu *iommu,
 				unsigned long dbase, unsigned long dsize,
 				unsigned long fbase, unsigned long fsize)
 {
 	struct page *page;
-	int i;
-	unsigned long reg, segments, pages_per_segment, ptab_size, stab_size,
-		      n_pte_pages, base;
-
-	base = dbase;
-	if (fsize != 0)
-		base = min(fbase, dbase);
+	unsigned long segments, stab_size;
 
 	segments = max(dbase + dsize, fbase + fsize) >> IO_SEGMENT_SHIFT;
-	pages_per_segment = 1ull << IO_PAGENO_BITS;
 
-	pr_debug("%s: iommu[%d]: segments: %lu, pages per segment: %lu\n",
-			__FUNCTION__, iommu->nid, segments, pages_per_segment);
+	pr_debug("%s: iommu[%d]: segments: %lu\n",
+			__FUNCTION__, iommu->nid, segments);
 
 	/* set up the segment table */
 	stab_size = segments * sizeof(unsigned long);
 	page = alloc_pages_node(iommu->nid, GFP_KERNEL, get_order(stab_size));
 	BUG_ON(!page);
 	iommu->stab = page_address(page);
-	clear_page(iommu->stab);
+	memset(iommu->stab, 0, stab_size);
+}
+
+static unsigned long *cell_iommu_alloc_ptab(struct cbe_iommu *iommu,
+				  unsigned long base, unsigned long size)
+{
+	struct page *page;
+	int i;
+	unsigned long reg, segments, pages_per_segment, ptab_size,
+		      n_pte_pages, start_seg, *ptab;
+
+	start_seg = base >> IO_SEGMENT_SHIFT;
+	segments  = size >> IO_SEGMENT_SHIFT;
+	pages_per_segment = 1ull << IO_PAGENO_BITS;
 
-	/* ... and the page tables. Since these are contiguous, we can treat
-	 * the page tables as one array of ptes, like pSeries does.
-	 */
 	ptab_size = segments * pages_per_segment * sizeof(unsigned long);
 	pr_debug("%s: iommu[%d]: ptab_size: %lu, order: %d\n", __FUNCTION__,
 			iommu->nid, ptab_size, get_order(ptab_size));
 	page = alloc_pages_node(iommu->nid, GFP_KERNEL, get_order(ptab_size));
 	BUG_ON(!page);
 
-	iommu->ptab = page_address(page);
-	memset(iommu->ptab, 0, ptab_size);
+	ptab = page_address(page);
+	memset(ptab, 0, ptab_size);
 
 	/* number of pages needed for a page table */
 	n_pte_pages = (pages_per_segment *
 		       sizeof(unsigned long)) >> IOMMU_PAGE_SHIFT;
 
 	pr_debug("%s: iommu[%d]: stab at %p, ptab at %p, n_pte_pages: %lu\n",
-			__FUNCTION__, iommu->nid, iommu->stab, iommu->ptab,
+			__FUNCTION__, iommu->nid, iommu->stab, ptab,
 			n_pte_pages);
 
 	/* initialise the STEs */
@@ -365,11 +368,13 @@ static void cell_iommu_setup_page_tables(struct cbe_iommu *iommu,
 	}
 
 	pr_debug("Setting up IOMMU stab:\n");
-	for (i = base >> IO_SEGMENT_SHIFT; i < segments; i++) {
-		iommu->stab[i] = reg |
-			(__pa(iommu->ptab) + n_pte_pages * IOMMU_PAGE_SIZE * i);
+	for (i = start_seg; i < (start_seg + segments); i++) {
+		iommu->stab[i] = reg | (__pa(ptab) + n_pte_pages *
+					IOMMU_PAGE_SIZE * (i - start_seg));
 		pr_debug("\t[%d] 0x%016lx\n", i, iommu->stab[i]);
 	}
+
+	return ptab;
 }
 
 static void cell_iommu_enable_hardware(struct cbe_iommu *iommu)
@@ -416,7 +421,8 @@ static void cell_iommu_enable_hardware(struct cbe_iommu *iommu)
 static void cell_iommu_setup_hardware(struct cbe_iommu *iommu,
 	unsigned long base, unsigned long size)
 {
-	cell_iommu_setup_page_tables(iommu, base, size, 0, 0);
+	cell_iommu_setup_stab(iommu, base, size, 0, 0);
+	iommu->ptab = cell_iommu_alloc_ptab(iommu, base, size);
 	cell_iommu_enable_hardware(iommu);
 }
 
@@ -870,8 +876,10 @@ static void cell_iommu_setup_fixed_ptab(struct cbe_iommu *iommu,
 	struct device_node *np, unsigned long dbase, unsigned long dsize,
 	unsigned long fbase, unsigned long fsize)
 {
-	unsigned long base_pte, uaddr, *io_pte;
 	int i;
+	unsigned long base_pte, uaddr, *io_pte, *ptab;
+
+	ptab = cell_iommu_alloc_ptab(iommu, fbase, fsize);
 
 	dma_iommu_fixed_base = fbase;
 
@@ -883,7 +891,7 @@ static void cell_iommu_setup_fixed_ptab(struct cbe_iommu *iommu,
 
 	pr_debug("iommu: mapping 0x%lx pages from 0x%lx\n", fsize, fbase);
 
-	io_pte = iommu->ptab;
+	io_pte = ptab;
 	base_pte = IOPTE_PP_W | IOPTE_PP_R | IOPTE_M | IOPTE_SO_RW
 		    | (cell_iommu_get_ioid(np) & IOPTE_IOID_Mask);
 
@@ -894,7 +902,7 @@ static void cell_iommu_setup_fixed_ptab(struct cbe_iommu *iommu,
 			pr_debug("iommu: fixed/dynamic overlap, skipping\n");
 			continue;
 		}
-		io_pte[i] = base_pte | (__pa(uaddr) & IOPTE_RPN_Mask);
+		io_pte[i - fbase] = base_pte | (__pa(uaddr) & IOPTE_RPN_Mask);
 	}
 
 	mb();
@@ -992,7 +1000,9 @@ static int __init cell_iommu_fixed_mapping_init(void)
 			"fixed window 0x%lx-0x%lx\n", iommu->nid, dbase,
 			 dbase + dsize, fbase, fbase + fsize);
 
-		cell_iommu_setup_page_tables(iommu, dbase, dsize, fbase, fsize);
+		cell_iommu_setup_stab(iommu, dbase, dsize, fbase, fsize);
+		iommu->ptab = cell_iommu_alloc_ptab(iommu, dbase, dsize,
+						    IOMMU_PAGE_SHIFT);
 		cell_iommu_setup_fixed_ptab(iommu, np, dbase, dsize,
 					     fbase, fsize);
 		cell_iommu_enable_hardware(iommu);
-- 
1.5.2.rc1.1884.g59b20

^ permalink raw reply related

* [PATCH 4/8] Move allocation of cell IOMMU pad page
From: Michael Ellerman @ 2008-02-27  7:28 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <4108415683edeb799fd4880a8dba3e9f27a34415.1204097262.git.michael@ellerman.id.au>

There's no need to allocate the pad page unless we're going to actually
use it - so move the allocation to where we know we're going to use it.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
 arch/powerpc/platforms/cell/iommu.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index 555d264..8e57e1a 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -344,12 +344,6 @@ static void cell_iommu_setup_page_tables(struct cbe_iommu *iommu,
 	iommu->ptab = page_address(page);
 	memset(iommu->ptab, 0, ptab_size);
 
-	/* allocate a bogus page for the end of each mapping */
-	page = alloc_pages_node(iommu->nid, GFP_KERNEL, 0);
-	BUG_ON(!page);
-	iommu->pad_page = page_address(page);
-	clear_page(iommu->pad_page);
-
 	/* number of pages needed for a page table */
 	n_pte_pages = (pages_per_segment *
 		       sizeof(unsigned long)) >> IOMMU_PAGE_SHIFT;
@@ -463,6 +457,7 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np,
 			unsigned long pte_offset)
 {
 	struct iommu_window *window;
+	struct page *page;
 	u32 ioid;
 
 	ioid = cell_iommu_get_ioid(np);
@@ -501,6 +496,11 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np,
 	 * This code also assumes that we have a window that starts at 0,
 	 * which is the case on all spider based blades.
 	 */
+	page = alloc_pages_node(iommu->nid, GFP_KERNEL, 0);
+	BUG_ON(!page);
+	iommu->pad_page = page_address(page);
+	clear_page(iommu->pad_page);
+
 	__set_bit(0, window->table.it_map);
 	tce_build_cell(&window->table, window->table.it_offset, 1,
 		       (unsigned long)iommu->pad_page, DMA_TO_DEVICE);
-- 
1.5.2.rc1.1884.g59b20

^ permalink raw reply related

* [PATCH 3/8] Remove unused pte_offset variable
From: Michael Ellerman @ 2008-02-27  7:28 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <4108415683edeb799fd4880a8dba3e9f27a34415.1204097262.git.michael@ellerman.id.au>

The cell IOMMU code no longer needs to save the pte_offset variable
separately, it is incorporated into tbl->it_offset.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
 arch/powerpc/platforms/cell/iommu.c |    5 +----
 1 files changed, 1 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index 4e75919..555d264 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -123,7 +123,6 @@ struct iommu_window {
 	struct cbe_iommu *iommu;
 	unsigned long offset;
 	unsigned long size;
-	unsigned long pte_offset;
 	unsigned int ioid;
 	struct iommu_table table;
 };
@@ -475,13 +474,11 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np,
 	window->size = size;
 	window->ioid = ioid;
 	window->iommu = iommu;
-	window->pte_offset = pte_offset;
 
 	window->table.it_blocksize = 16;
 	window->table.it_base = (unsigned long)iommu->ptab;
 	window->table.it_index = iommu->nid;
-	window->table.it_offset = (offset >> IOMMU_PAGE_SHIFT) +
-		window->pte_offset;
+	window->table.it_offset = (offset >> IOMMU_PAGE_SHIFT) + pte_offset;
 	window->table.it_size = size >> IOMMU_PAGE_SHIFT;
 
 	iommu_init_table(&window->table, iommu->nid);
-- 
1.5.2.rc1.1884.g59b20

^ permalink raw reply related

* [PATCH 2/8] Use it_offset not pte_offset in cell IOMMU code
From: Michael Ellerman @ 2008-02-27  7:28 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <4108415683edeb799fd4880a8dba3e9f27a34415.1204097262.git.michael@ellerman.id.au>

The cell IOMMU tce build and free routines use pte_offset to convert
the index passed from the generic IOMMU code into a page table offset.

This takes into account the SPIDER_DMA_OFFSET which sets the top bit
of every DMA address.

However it doesn't cater for the IOMMU window starting at a non-zero
address, as the base of the window is not incorporated into pte_offset
at all.

As it turns out tbl->it_offset already contains the value we need, it
takes into account the base of the window and also pte_offset. So use
it instead!

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
 arch/powerpc/platforms/cell/iommu.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index bbe8389..4e75919 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -200,7 +200,7 @@ static void tce_build_cell(struct iommu_table *tbl, long index, long npages,
 		(window->ioid & IOPTE_IOID_Mask);
 #endif
 
-	io_pte = (unsigned long *)tbl->it_base + (index - window->pte_offset);
+	io_pte = (unsigned long *)tbl->it_base + (index - tbl->it_offset);
 
 	for (i = 0; i < npages; i++, uaddr += IOMMU_PAGE_SIZE)
 		io_pte[i] = base_pte | (__pa(uaddr) & IOPTE_RPN_Mask);
@@ -232,7 +232,7 @@ static void tce_free_cell(struct iommu_table *tbl, long index, long npages)
 		| (window->ioid & IOPTE_IOID_Mask);
 #endif
 
-	io_pte = (unsigned long *)tbl->it_base + (index - window->pte_offset);
+	io_pte = (unsigned long *)tbl->it_base + (index - tbl->it_offset);
 
 	for (i = 0; i < npages; i++)
 		io_pte[i] = pte;
-- 
1.5.2.rc1.1884.g59b20

^ permalink raw reply related

* [PATCH 1/8] Clearup cell IOMMU fixed mapping terminology
From: Michael Ellerman @ 2008-02-27  7:28 UTC (permalink / raw)
  To: linuxppc-dev

It's called the fixed mapping, not the static mapping.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
 arch/powerpc/platforms/cell/iommu.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index edab631..bbe8389 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -549,7 +549,7 @@ static void cell_dma_dev_setup_iommu(struct device *dev)
 	archdata->dma_data = &window->table;
 }
 
-static void cell_dma_dev_setup_static(struct device *dev);
+static void cell_dma_dev_setup_fixed(struct device *dev);
 
 static void cell_dma_dev_setup(struct device *dev)
 {
@@ -557,7 +557,7 @@ static void cell_dma_dev_setup(struct device *dev)
 
 	/* Order is important here, these are not mutually exclusive */
 	if (get_dma_ops(dev) == &dma_iommu_fixed_ops)
-		cell_dma_dev_setup_static(dev);
+		cell_dma_dev_setup_fixed(dev);
 	else if (get_pci_dma_ops() == &dma_iommu_ops)
 		cell_dma_dev_setup_iommu(dev);
 	else if (get_pci_dma_ops() == &dma_direct_ops)
@@ -858,7 +858,7 @@ static int dma_set_mask_and_switch(struct device *dev, u64 dma_mask)
 	return 0;
 }
 
-static void cell_dma_dev_setup_static(struct device *dev)
+static void cell_dma_dev_setup_fixed(struct device *dev)
 {
 	struct dev_archdata *archdata = &dev->archdata;
 	u64 addr;
@@ -894,7 +894,7 @@ static void cell_iommu_setup_fixed_ptab(struct cbe_iommu *iommu,
 	for (i = fbase; i < fbase + fsize; i++, uaddr += IOMMU_PAGE_SIZE) {
 		/* Don't touch the dynamic region */
 		if (i >= dbase && i < (dbase + dsize)) {
-			pr_debug("iommu: static/dynamic overlap, skipping\n");
+			pr_debug("iommu: fixed/dynamic overlap, skipping\n");
 			continue;
 		}
 		io_pte[i] = base_pte | (__pa(uaddr) & IOPTE_RPN_Mask);
-- 
1.5.2.rc1.1884.g59b20

^ permalink raw reply related

* dtc: Implement checks for the format of node and property names
From: David Gibson @ 2008-02-27  2:45 UTC (permalink / raw)
  To: Jon Loeliger; +Cc: linuxppc-dev

This patch adds checks to the checking framework to verify that node
and property names contain only legal characters, and in the case of
node names there is at most one '@'.

At present when coming from dts input, this is mostly already ensured
by the grammer, however putting the check later means its easier to
generate helpful error messages rather than just "syntax error".  For
dtb input, these checks replace the older similar check built into
flattree.c.

Testcases for the checks are also implemented.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>

---
 checks.c           |   37 +++++++++++++++++++++++++++++++++++++
 flattree.c         |   28 +++++-----------------------
 tests/dumptrees.c  |    1 +
 tests/run_tests.sh |    3 +++
 tests/testdata.h   |    3 +++
 tests/trees.S      |   48 ++++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 97 insertions(+), 23 deletions(-)

Index: dtc/checks.c
===================================================================
--- dtc.orig/checks.c	2008-02-27 13:25:08.000000000 +1100
+++ dtc/checks.c	2008-02-27 13:29:05.000000000 +1100
@@ -242,6 +242,42 @@
 }
 NODE_CHECK(duplicate_property_names, NULL, ERROR);
 
+#define LOWERCASE	"abcdefghijklmnopqrstuvwxyz"
+#define UPPERCASE	"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+#define DIGITS		"0123456789"
+#define PROPNODECHARS	LOWERCASE UPPERCASE DIGITS ",._+*#?-"
+
+static void check_node_name_chars(struct check *c, struct node *dt,
+				  struct node *node)
+{
+	int n = strspn(node->name, c->data);
+
+	if (n < strlen(node->name))
+		FAIL(c, "Bad character '%c' in node %s",
+		     node->name[n], node->fullpath);
+}
+NODE_CHECK(node_name_chars, PROPNODECHARS "@", ERROR);
+
+static void check_node_name_format(struct check *c, struct node *dt,
+				   struct node *node)
+{
+	if (strchr(get_unitname(node), '@'))
+		FAIL(c, "Node %s has multiple '@' characters in name",
+		     node->fullpath);
+}
+NODE_CHECK(node_name_format, NULL, ERROR, &node_name_chars);
+
+static void check_property_name_chars(struct check *c, struct node *dt,
+				      struct node *node, struct property *prop)
+{
+	int n = strspn(prop->name, c->data);
+
+	if (n < strlen(prop->name))
+		FAIL(c, "Bad character '%c' in property name \"%s\", node %s",
+		     prop->name[n], prop->name, node->fullpath);
+}
+PROP_CHECK(property_name_chars, PROPNODECHARS, ERROR);
+
 static void check_explicit_phandles(struct check *c, struct node *root,
 					  struct node *node)
 {
@@ -498,6 +534,7 @@
 
 static struct check *check_table[] = {
 	&duplicate_node_names, &duplicate_property_names,
+	&node_name_chars, &node_name_format, &property_name_chars,
 	&name_is_string, &name_properties,
 	&explicit_phandles,
 	&phandle_references, &path_references,
Index: dtc/tests/trees.S
===================================================================
--- dtc.orig/tests/trees.S	2008-02-27 13:25:08.000000000 +1100
+++ dtc/tests/trees.S	2008-02-27 13:28:33.000000000 +1100
@@ -136,3 +136,51 @@
 truncated_property_strings_end:
 
 truncated_property_end:
+
+
+	TREE_HDR(bad_node_char)
+	EMPTY_RSVMAP(bad_node_char)
+
+bad_node_char_struct:
+	BEGIN_NODE("")
+	BEGIN_NODE("sub$node")
+	END_NODE
+	END_NODE
+	FDTLONG(FDT_END)
+bad_node_char_struct_end:
+
+bad_node_char_strings:
+bad_node_char_strings_end:
+bad_node_char_end:
+
+
+	TREE_HDR(bad_node_format)
+	EMPTY_RSVMAP(bad_node_format)
+
+bad_node_format_struct:
+	BEGIN_NODE("")
+	BEGIN_NODE("subnode@1@2")
+	END_NODE
+	END_NODE
+	FDTLONG(FDT_END)
+bad_node_format_struct_end:
+
+bad_node_format_strings:
+bad_node_format_strings_end:
+bad_node_format_end:
+
+
+	TREE_HDR(bad_prop_char)
+	EMPTY_RSVMAP(bad_prop_char)
+
+bad_prop_char_struct:
+	BEGIN_NODE("")
+	PROP_INT(bad_prop_char, prop, TEST_VALUE_1)
+	END_NODE
+	FDTLONG(FDT_END)
+bad_prop_char_struct_end:
+
+bad_prop_char_strings:
+	STRING(bad_prop_char, prop, "prop$erty")
+bad_prop_char_strings_end:
+bad_prop_char_end:
Index: dtc/flattree.c
===================================================================
--- dtc.orig/flattree.c	2008-02-27 13:25:08.000000000 +1100
+++ dtc/flattree.c	2008-02-27 13:41:06.000000000 +1100
@@ -729,29 +729,14 @@
 	return strdup(lslash+1);
 }
 
-static const char PROPCHAR[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,._+*#?-";
-static const char UNITCHAR[] = "0123456789abcdef,";
-
-static int check_node_name(const char *name)
+static int find_basenamelen(const char *name)
 {
-	const char *atpos;
-	int basenamelen;
-
-	atpos = strrchr(name, '@');
+	const char *atpos = strchr(name, '@');
 
 	if (atpos)
-		basenamelen = atpos - name;
+		return atpos - name;
 	else
-		basenamelen = strlen(name);
-
-	if (strspn(name, PROPCHAR) < basenamelen)
-		return -1;
-
-	if (atpos
-	    && ((basenamelen + 1 + strspn(atpos+1, UNITCHAR)) < strlen(name)))
-		return -1;
-
-	return basenamelen;
+		return strlen(name);
 }
 
 static struct node *unflatten_tree(struct inbuf *dtbuf,
@@ -775,10 +760,7 @@
 		node->fullpath = join_path(parent_path, node->name);
 	}
 
-	node->basenamelen = check_node_name(node->name);
-	if (node->basenamelen < 0) {
-		fprintf(stderr, "Warning \"%s\" has incorrect format\n", node->name);
-	}
+	node->basenamelen = find_basenamelen(node->name);
 
 	do {
 		struct property *prop;
Index: dtc/tests/dumptrees.c
===================================================================
--- dtc.orig/tests/dumptrees.c	2008-02-27 13:25:08.000000000 +1100
+++ dtc/tests/dumptrees.c	2008-02-27 13:25:09.000000000 +1100
@@ -37,6 +37,7 @@
 } trees[] = {
 #define TREE(name)	{ &_##name, #name ".dtb" }
 	TREE(test_tree1),
+	TREE(bad_node_char), TREE(bad_node_format), TREE(bad_prop_char),
 };
 
 #define NUM_TREES	(sizeof(trees) / sizeof(trees[0]))
Index: dtc/tests/run_tests.sh
===================================================================
--- dtc.orig/tests/run_tests.sh	2008-02-27 13:25:08.000000000 +1100
+++ dtc/tests/run_tests.sh	2008-02-27 13:25:09.000000000 +1100
@@ -189,6 +189,9 @@
     run_test dtc-checkfails.sh ranges_format -- -I dts -O dtb bad-empty-ranges.dts
     run_test dtc-checkfails.sh avoid_default_addr_size -- -I dts -O dtb default-addr-size.dts
     run_test dtc-checkfails.sh obsolete_chosen_interrupt_controller -- -I dts -O dtb obsolete-chosen-interrupt-controller.dts
+    run_test dtc-checkfails.sh node_name_chars -- -I dtb -O dtb bad_node_char.dtb
+    run_test dtc-checkfails.sh node_name_format -- -I dtb -O dtb bad_node_format.dtb
+    run_test dtc-checkfails.sh prop_name_chars -- -I dtb -O dtb bad_prop_char.dtb
 }
 
 while getopts "vt:m" ARG ; do
Index: dtc/tests/testdata.h
===================================================================
--- dtc.orig/tests/testdata.h	2008-02-27 13:25:08.000000000 +1100
+++ dtc/tests/testdata.h	2008-02-27 13:25:09.000000000 +1100
@@ -33,4 +33,7 @@
 #ifndef __ASSEMBLY__
 extern struct fdt_header _test_tree1;
 extern struct fdt_header _truncated_property;
+extern struct fdt_header _bad_node_char;
+extern struct fdt_header _bad_node_format;
+extern struct fdt_header _bad_prop_char;
 #endif /* ! __ASSEMBLY */

-- 
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

* Re: Patches added to master & powerpc-next branches of powerpc.git
From: Paul Mackerras @ 2008-02-27  1:24 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <12F84CB4-8344-4F70-A89F-4A1FF590C35C@kernel.crashing.org>

Kumar Gala writes:

> How do you plan on managing the powerpc-next branch in the future?   
> For example, I assume at some point linus will pull it into what would  
> be 2.6.26.  Would you rebase this branch?  etc.

Yes, it is basically the for-2.6.26 branch.  I will try very hard not
to rebase it, but I don't promise that I will never rebase it.

I'm expecting to get requests to pull your tree into it, as well as
Josh's, Grant's, etc., once you have stuff that you are reasonably
confident should go in to the next release and won't need to be
rebased.

Paul.

^ permalink raw reply

* Re: Patches added to master & powerpc-next branches of powerpc.git
From: Benjamin Herrenschmidt @ 2008-02-27  0:46 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <18372.45605.265760.646342@cargo.ozlabs.ibm.com>


On Wed, 2008-02-27 at 11:43 +1100, Paul Mackerras wrote:
> Benjamin Herrenschmidt writes:
> 
> > On Tue, 2008-02-26 at 23:03 +1100, Paul Mackerras wrote:
> > > Benjamin Herrenschmidt (1):
> > >       [POWERPC] Fix thinko in cpu_thread_mask_to_cores()
> > > 
> > 
> > Any reason why this isn't going into .25 ?
> 
> I thought you said nothing uses it.

I'm worried some out of tree stuff might...

But if not, yeah, it's fine.

Ben.

^ permalink raw reply

* Re: Patches added to master & powerpc-next branches of powerpc.git
From: Paul Mackerras @ 2008-02-27  0:43 UTC (permalink / raw)
  To: benh; +Cc: linuxppc-dev
In-Reply-To: <1204070815.15052.194.camel@pasglop>

Benjamin Herrenschmidt writes:

> On Tue, 2008-02-26 at 23:03 +1100, Paul Mackerras wrote:
> > Benjamin Herrenschmidt (1):
> >       [POWERPC] Fix thinko in cpu_thread_mask_to_cores()
> > 
> 
> Any reason why this isn't going into .25 ?

I thought you said nothing uses it.

Paul.

^ permalink raw reply

* Re: Patches added to master & powerpc-next branches of powerpc.git
From: Benjamin Herrenschmidt @ 2008-02-27  0:06 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <18371.65529.312001.673609@cargo.ozlabs.ibm.com>


On Tue, 2008-02-26 at 23:03 +1100, Paul Mackerras wrote:
> Benjamin Herrenschmidt (1):
>       [POWERPC] Fix thinko in cpu_thread_mask_to_cores()
> 

Any reason why this isn't going into .25 ?

Ben.

^ permalink raw reply

* Re: [PATCH][OF] Add of_device_is_available function
From: Josh Boyer @ 2008-02-26 23:53 UTC (permalink / raw)
  To: David Miller; +Cc: linuxppc-dev, paulus, sfr
In-Reply-To: <20080226.144423.138965691.davem@davemloft.net>

On Tue, 26 Feb 2008 14:44:23 -0800 (PST)
David Miller <davem@davemloft.net> wrote:

> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Date: Wed, 27 Feb 2008 08:45:37 +1100
> 
> > I doubt we do that. Properties that contain things like ranges, or "reg"
> > properties are expected to be of a size that is a multiple of
> > #size-cells/#address-cells and I'm not sure that won't break things here
> > or there if they suddenly get one more byte..
> > 
> > Or do you mean you/we are appending that-without- changing the length
> > field ?
> 
> Right, simply don't change the length field.  Put the zero byte
> at offset "length + 1"
> 
> It's stupid to validate NULL termination everywhere when we
> can make it an invariant in one spot.

I don't mind fixing up the function to use strncmp and checking for a 0
length from of_get_property.  However, I'm almost certain that other
places in the code have the same issue so what you're saying here seems
to make sense.

josh

^ permalink raw reply

* Re: copy_from_user problem
From: Benjamin Herrenschmidt @ 2008-02-26 23:22 UTC (permalink / raw)
  To: maynardj; +Cc: linuxppc-dev
In-Reply-To: <47C426F8.7070203@us.ibm.com>


On Tue, 2008-02-26 at 08:49 -0600, Maynard Johnson wrote:
> 2. Compile C program as 32-bit; then run it.  While the program is 
> waiting for input, obtain its PID and do 'cat /proc/<pid>/maps' to
> get 
> the address of where libc is loaded.
> 3. From the dir where you build the uaccess_test kernel module:
>          'insmod ./uaccess_test.ko lib_addr=0x<mem_loc_libc>'
>     This should succeed.  dmesg to verify.
> 4. Unload the module.
> 5. Recompile your C program with -m64; start it up and obtain the 
> address of libc again (now a 64-bit address).
> 6. Load the uaccess_test kernel module and pass 
> 'lib_addr=0x<mem_loc_libc>'.  Note that this time, the load fails. 
> dmesg to see debug printk's.

Sounds to me that your kernel module will try to copy_from_user() from
the user context of ... insmod :-)

You need to do your copy_from_user() from within the context of the
program you try to access the memory from !

If you need to access another context than the current one, you then
need to use a different mechanism, such as get_user_pages(), though
beware that you can only do that for memory, not SPE local store or
register mappings.

Ben.

^ permalink raw reply

* Re: [PATCH][OF] Add of_device_is_available function
From: Benjamin Herrenschmidt @ 2008-02-26 22:58 UTC (permalink / raw)
  To: David Miller; +Cc: sfr, paulus, linuxppc-dev
In-Reply-To: <20080226.144423.138965691.davem@davemloft.net>


On Tue, 2008-02-26 at 14:44 -0800, David Miller wrote:
> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Date: Wed, 27 Feb 2008 08:45:37 +1100
> 
> > I doubt we do that. Properties that contain things like ranges, or "reg"
> > properties are expected to be of a size that is a multiple of
> > #size-cells/#address-cells and I'm not sure that won't break things here
> > or there if they suddenly get one more byte..
> > 
> > Or do you mean you/we are appending that-without- changing the length
> > field ?
> 
> Right, simply don't change the length field.  Put the zero byte
> at offset "length + 1"
> 
> It's stupid to validate NULL termination everywhere when we
> can make it an invariant in one spot.

Fair enough.

Ben.

^ 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