LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: Available user-level tool for I2C device?
From: Sam Song @ 2005-10-01  3:50 UTC (permalink / raw)
  To: Eugene Surovegin; +Cc: linuxppc-embedded
In-Reply-To: <20050929165715.GA24176@gate.ebshome.net>

Eugene Surovegin <ebs@ebshome.net>写道:
> Right approach would be making standard in-kernel
> RTC driver for this chip. In fact, such driver was 
> already posted to lm-sensors list some time ago.

I happen to have a LM75 on this board. Your hints 
remind me to follow the lm-sensors list to find 
something special on this point as well.

Thanks a lot,

Sam



	

	
		
___________________________________________________________ 
雅虎免费G邮箱-中国第一绝无垃圾邮件骚扰超大邮箱 
http://cn.mail.yahoo.com

^ permalink raw reply

* Re: [PATCH 6/9] powerpc: merge idle_power4.S and fixup traps.c
From: Paul Mackerras @ 2005-10-01  3:28 UTC (permalink / raw)
  To: Stephen Rothwell; +Cc: linuxppc64-dev, linuxppc-dev
In-Reply-To: <20051001121714.1b5886aa.sfr@canb.auug.org.au>

Stephen Rothwell writes:

> My first attempt at the merge was a real mess and a right pain, so I put
> the two files in as a compromise.  However, I have made another attempt
> and ,although it took a while,  it seems to be going ok.  How about we put
> the two in for now (as that will allow the merge of more platforms to
> continue) and I will supply a further patch in a few days that combines
> the two trapsxx.c files?

In that case, what is the advantage of having two traps*.c files in
arch/powerpc/kernel instead of having them in arch/ppc*/kernel?

Paul.

^ permalink raw reply

* Re: [PATCH 6/9] powerpc: merge idle_power4.S and fixup traps.c
From: Stephen Rothwell @ 2005-10-01  2:17 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc64-dev, linuxppc-dev
In-Reply-To: <52E29A49-AAF2-4E61-AAB2-CD02ABCBE447@freescale.com>

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

On Fri, 30 Sep 2005 15:52:40 -0500 Kumar Gala <kumar.gala@freescale.com> wrote:
>
> (My first attempt at posting to the list failed due to size)

Yes, quoting the whole patch was probably not necessary :-)

> I really dont like the ideal of splitting up traps.c into traps32.c  
> and traps64.c.  This defeats the purpose of the merge.  I expect that  
> a significant portion of traps.c is common (or can be made to be)  
> between all powerpc's.

My first attempt at the merge was a real mess and a right pain, so I put
the two files in as a compromise.  However, I have made another attempt
and ,although it took a while,  it seems to be going ok.  How about we put
the two in for now (as that will allow the merge of more platforms to
continue) and I will supply a further patch in a few days that combines
the two trapsxx.c files?

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

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

^ permalink raw reply

* [PATCH] pmac: fix cpufreq for old tipb 550Mhz
From: Benjamin Herrenschmidt @ 2005-09-30 23:21 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Andrew Morton, linuxppc-dev list

The old 550Mhz titanium powerbook can switch to a lower frequency
(500Mhz). A user has been repeately reporting overtemp conditions on his
machine at high speed so this simple patch adds support to PowerMac
cpufreq for this machine. The difference in frequency isn't big but seem
enough to fix that user's problems. The patch has been around for some
time now and doesn't seem to cause any problem, so I suppose it could go
in now.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Alain RICHARD <alain.richard@equation.fr>

Index: linux-work/arch/ppc/platforms/pmac_cpufreq.c
===================================================================
--- linux-work.orig/arch/ppc/platforms/pmac_cpufreq.c	2005-09-22 14:06:18.000000000 +1000
+++ linux-work/arch/ppc/platforms/pmac_cpufreq.c	2005-10-01 09:17:32.000000000 +1000
@@ -695,6 +695,13 @@
 		set_speed_proc = pmu_set_cpu_speed;
 		is_pmu_based = 1;
 	}
+	/* Else check for TiPb 550 */
+	else if (machine_is_compatible("PowerBook3,3") && cur_freq == 550000) {
+		hi_freq = cur_freq;
+		low_freq = 500000;
+		set_speed_proc = pmu_set_cpu_speed;
+		is_pmu_based = 1;
+	}
 	/* Else check for TiPb 400 & 500 */
 	else if (machine_is_compatible("PowerBook3,2")) {
 		/* We only know about the 400 MHz and the 500Mhz model

^ permalink raw reply

* Re: [PATCH 6/9] powerpc: merge idle_power4.S and fixup traps.c
From: Kumar Gala @ 2005-09-30 20:52 UTC (permalink / raw)
  To: Stephen Rothwell; +Cc: ppc64-dev, ppc-dev
In-Reply-To: <20051001000001.1f1d8c48.sfr@canb.auug.org.au>

(My first attempt at posting to the list failed due to size)

I really dont like the ideal of splitting up traps.c into traps32.c  
and traps64.c.  This defeats the purpose of the merge.  I expect that  
a significant portion of traps.c is common (or can be made to be)  
between all powerpc's.

- kumar


On Sep 30, 2005, at 9:00 AM, Stephen Rothwell wrote:

> Use idle_power4.S from ppc64 as we are not going to support
> 32 bit power4 in the merged tree.
>
> create traps{32,64}.c as these are hard to merge.
>
> Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
> ---
>
>  arch/powerpc/Kconfig              |    4
>  arch/powerpc/kernel/Makefile      |    4
>  arch/powerpc/kernel/idle_power4.S |   78 +++
>  arch/powerpc/kernel/traps.c       | 1047
> -------------------------------------
>  arch/powerpc/kernel/traps32.c     | 1047
> +++++++++++++++++++++++++++++++++++++
>  arch/powerpc/kernel/traps64.c     |  568 ++++++++++++++++++++
>  arch/ppc64/kernel/Makefile        |   10
>  arch/ppc64/kernel/idle_power4.S   |   79 ---
>  arch/ppc64/kernel/traps.c         |  568 --------------------
>  9 files changed, 1707 insertions(+), 1698 deletions(-)
>  create mode 100644 arch/powerpc/kernel/idle_power4.S
>  delete mode 100644 arch/powerpc/kernel/traps.c
>  create mode 100644 arch/powerpc/kernel/traps32.c
>  create mode 100644 arch/powerpc/kernel/traps64.c
>  delete mode 100644 arch/ppc64/kernel/idle_power4.S
>  delete mode 100644 arch/ppc64/kernel/traps.c
>

^ permalink raw reply

* where should readb based/platform specific memcpy_fromio() be?
From: Yasushi SHOJI @ 2005-09-30 20:02 UTC (permalink / raw)
  To: linuxppc-dev

Hello,

I'd like to add a variant of memcpy_fromio() for 16bit bus.  In-tree
implementations seem to me that most, if not all, arch have either
readb() or memcpy() based mempy_fromio.

powerpc doesn't currently have readb() based.  I assume that means all
ppc boards are 32bit clean.

if I'd like merge this readb() based or optimized for 16bit bus
version, where should I put it?  obviously I have to add ifdef in
include/asm-ppc/io.h, but should I do either:

  - add extern in io.h and body under platform/..../xxxx.c
  - add extern in io.h and body under arch/ppc/lib/io.c
  - add static inline version in io.h
  - add static inline version in platform/..../xxxxx.h which is
    included from asm-ppc/io.h

regards,
--
         yashi

^ permalink raw reply

* Re: CPM2 early console
From: Dan Malek @ 2005-09-30 20:28 UTC (permalink / raw)
  To: Kalle Pokki; +Cc: linuxppc-embedded
In-Reply-To: <433D9BCE.5000909@iki.fi>


On Sep 30, 2005, at 4:10 PM, Kalle Pokki wrote:

> ..... Still, there must be a correct way of doing this, but I think I 
> have already tried modifying every register that sounds related. The 
> errata doesn't list anything useful.

I just built an 8250. 8260, and 8270 from a very recent 2.6 tree today 
and they
all worked fine.  They all had different serial port configurations 
(SMC1, SCC1
and SCC2).  Two were u-boot and one was a proprietary boot rom.
So, the "problem" seems to be related to something unique with your 
system.

> .... I successfully tried this in another application without Linux.

This is code that has existed for many years in Linux and appears to 
continue
to work fine.  We need to identify what is causing the problem in your
environment, not look for some hack around it.

Thanks.

	-- Dan

^ permalink raw reply

* Re: CPM2 early console
From: Kalle Pokki @ 2005-09-30 20:16 UTC (permalink / raw)
  To: Alex Zeffertt; +Cc: linuxppc-embedded
In-Reply-To: <20050930144230.25f4917e.ajz@cambridgebroadband.com>

Alex Zeffertt wrote:

>>Are there any drawbacks to this approach?
>>    
>>
>
>
>To answer my own question: yes there is a drawback.
>  
>
Yes it's not so good for performance. I would be better no just 
cache-inhibit some specific memory areas.

Do you have more than one board to test this with? I only have one now, 
and this seems so odd I almost suspect a hardware flaw... but usually 
when I say this aloud it almost certainly turns out to be just a trivial 
software bug :)

^ permalink raw reply

* Re: CPM2 early console
From: Kalle Pokki @ 2005-09-30 20:10 UTC (permalink / raw)
  To: Dan Malek; +Cc: linuxppc-embedded
In-Reply-To: <2c578118c5d984e6e87ac3c073469866@embeddededge.com>

Dan Malek wrote:

> On Sep 30, 2005, at 9:22 AM, Alex Zeffertt wrote:
>
>> Are there any drawbacks to this approach?
>
> The general system performance is going to suffer,
> and if you really have a cache coherency problem
> it only solves the write case and not the read case.

The read case seems to be solved by setting the appropriate GBL bits in 
the parameter ram areas, since the buffers work correctly in both 
directions by just setting cache write-through and coherent (coherent 
alone won't help). Still, there must be a correct way of doing this, but 
I think I have already tried modifying every register that sounds 
related. The errata doesn't list anything useful.

Another way of getting around the problem would be to place the buffers 
in a cache-inhibited memory area and have copy-back caches for other 
data. I successfully tried this in another application without Linux.

^ permalink raw reply

* Re: [PATCH 3/3]MTD driver for Yucca board
From: Josh Boyer @ 2005-09-30 17:49 UTC (permalink / raw)
  To: Ruslan V. Sushko; +Cc: linuxppc-dev
In-Reply-To: <1128095076.15236.15.camel@mephisto.spb.rtsoft.ru>

On Fri, 2005-09-30 at 19:44 +0400, Ruslan V. Sushko wrote:
> This patch adds MTD driver for Yucca ppc440SPe board. The patch
> implemented for Roland Dreier git tree for Yucca 440SPe board

> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Ruslan V. Sushko <rsushko@ru.mvista.com>");
> +MODULE_DESCRIPTION("MTD map and partitions for IBM 440SPe Yucca boards");

Nit: I think you mean "AMCC 440SPe Yucca boards".  IBM no longer makes
reference boards for 4xx hardware.

josh

^ permalink raw reply

* Re: MV64x60 watchdog timer driver updates
From: Geert Uytterhoeven @ 2005-09-30 15:18 UTC (permalink / raw)
  To: Corey Minyard; +Cc: Linux/PPC Development
In-Reply-To: <433D557C.4020301@acm.org>

On Fri, 30 Sep 2005, Corey Minyard wrote:
> Mark A. Greer wrote:
> > On Thu, Sep 29, 2005 at 01:32:21PM -0500, Corey Minyard wrote:
> > > James looked at an earlier version and said it was ok, and suggested
> > > a few changes.  This has been tested against 2.6.14-rc2 on a Katana.
> > > 
> > > Note that the bus_clk value from the platform information seems to
> > > be in MHZ, but the actual frequency is generally 133,333,333, not
> > > 133,000,000.  I don't think the inaccuracy matters here, but it seems
> > > a little odd.
> > >    
> > 
> > Yes, it makes more sense to me to pass the actual frequency and not do
> > the '* 1000000'.
> >  
> The only trouble is if  you go over 4GHZ...  Maybe it should be in KHZ instead
> of MHZ?  or 64-bits?  Or maybe we don't worry about >4GHZ busses?
> 
> Also, how would one go about changing this?  Would you need something like:
> 
> if (bus_clk < 1000)
>  bus_clk *= 1000000
> 
> for backwards compatability?

Hey, don't touch the i2c! ;-)

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds

^ permalink raw reply

* [PATCH 1/3] I2C and GPIO controlers address fix on Yucca board
From: Ruslan V. Sushko @ 2005-09-30 15:30 UTC (permalink / raw)
  To: linuxppc-dev

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

This patch fixes physical address for I2C and GPIO controllers on Yucca
PPC440SPe board. The fixes below allows to enable ibm ocp i2c driver to
access to Yucca peripheral devices. The patch is implemented for Roland
Dreier git tree for Yucca PPC440SPe board.


[-- Attachment #2: yucca_i2c.patch --]
[-- Type: text/x-patch, Size: 972 bytes --]

diff --git a/arch/ppc/platforms/4xx/ppc440spe.c b/arch/ppc/platforms/4xx/ppc440spe.c
--- a/arch/ppc/platforms/4xx/ppc440spe.c
+++ b/arch/ppc/platforms/4xx/ppc440spe.c
@@ -90,7 +90,7 @@ struct ocp_def core_ocp[] = {
 	{ .vendor	= OCP_VENDOR_IBM,
 	  .function	= OCP_FUNC_IIC,
 	  .index	= 0,
-	  .paddr	= 0x00000001f0000400ULL,
+	  .paddr	= 0x00000004f0000400ULL,
 	  .irq		= 2,
 	  .pm		= IBM_CPM_IIC0,
 	  .additions	= &ppc440spe_iic0_def,
@@ -99,7 +99,7 @@ struct ocp_def core_ocp[] = {
 	{ .vendor	= OCP_VENDOR_IBM,
 	  .function	= OCP_FUNC_IIC,
 	  .index	= 1,
-	  .paddr	= 0x00000001f0000500ULL,
+	  .paddr	= 0x00000004f0000500ULL,
 	  .irq		= 3,
 	  .pm		= IBM_CPM_IIC1,
 	  .additions	= &ppc440spe_iic1_def,
@@ -108,7 +108,7 @@ struct ocp_def core_ocp[] = {
 	{ .vendor	= OCP_VENDOR_IBM,
 	  .function	= OCP_FUNC_GPIO,
 	  .index	= 0,
-	  .paddr	= 0x00000001f0000700ULL,
+	  .paddr	= 0x00000004f0000700ULL,
 	  .irq		= OCP_IRQ_NA,
 	  .pm		= IBM_CPM_GPIO0,
 	},




^ permalink raw reply

* [PATCH 1/3] Fix fphysical addresses or I2C and GPIO controllers for Yucca board
From: Ruslan V. Sushko @ 2005-09-30 15:49 UTC (permalink / raw)
  To: linuxppc-dev

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

This patch fixes physical address for I2C and GPIO controllers on Yucca
PPC440SPe board. The fixes above allows to enable ibm ocp i2c driver to
access to Yucca peripheral devices. The patch is implemented for Roland
Dreier git tree for Yucca PPC440SPe board.

Signed-off-by: Ruslan V. Sushko <rsushko@ru.mvista.com>

[-- Attachment #2: yucca_i2c.patch --]
[-- Type: text/x-patch, Size: 972 bytes --]

diff --git a/arch/ppc/platforms/4xx/ppc440spe.c b/arch/ppc/platforms/4xx/ppc440spe.c
--- a/arch/ppc/platforms/4xx/ppc440spe.c
+++ b/arch/ppc/platforms/4xx/ppc440spe.c
@@ -90,7 +90,7 @@ struct ocp_def core_ocp[] = {
 	{ .vendor	= OCP_VENDOR_IBM,
 	  .function	= OCP_FUNC_IIC,
 	  .index	= 0,
-	  .paddr	= 0x00000001f0000400ULL,
+	  .paddr	= 0x00000004f0000400ULL,
 	  .irq		= 2,
 	  .pm		= IBM_CPM_IIC0,
 	  .additions	= &ppc440spe_iic0_def,
@@ -99,7 +99,7 @@ struct ocp_def core_ocp[] = {
 	{ .vendor	= OCP_VENDOR_IBM,
 	  .function	= OCP_FUNC_IIC,
 	  .index	= 1,
-	  .paddr	= 0x00000001f0000500ULL,
+	  .paddr	= 0x00000004f0000500ULL,
 	  .irq		= 3,
 	  .pm		= IBM_CPM_IIC1,
 	  .additions	= &ppc440spe_iic1_def,
@@ -108,7 +108,7 @@ struct ocp_def core_ocp[] = {
 	{ .vendor	= OCP_VENDOR_IBM,
 	  .function	= OCP_FUNC_GPIO,
 	  .index	= 0,
-	  .paddr	= 0x00000001f0000700ULL,
+	  .paddr	= 0x00000004f0000700ULL,
 	  .irq		= OCP_IRQ_NA,
 	  .pm		= IBM_CPM_GPIO0,
 	},




^ permalink raw reply

* [PATCH 3/3]MTD driver for Yucca board
From: Ruslan V. Sushko @ 2005-09-30 15:44 UTC (permalink / raw)
  To: linuxppc-dev

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

This patch adds MTD driver for Yucca ppc440SPe board. The patch
implemented for Roland Dreier git tree for Yucca 440SPe board

Signed-off-by: Ruslan V. Sushko <rsushko@ru.mvista.com>

[-- Attachment #2: yucca_mtd.patch --]
[-- Type: text/x-patch, Size: 14331 bytes --]

diff --git a/arch/ppc/platforms/4xx/yucca.h b/arch/ppc/platforms/4xx/yucca.h
--- a/arch/ppc/platforms/4xx/yucca.h
+++ b/arch/ppc/platforms/4xx/yucca.h
@@ -32,12 +32,91 @@
 /* External timer clock frequency */
 #define YUCCA_TMR_CLK		25000000
 
+
+
+/* System Memory map (physical address, not effective address)
+ * Flash and other devices via EBC.
+ *
+ * This should be the same mapping as done by PIBS in the
+ * (not mandatory but ease code reading between two codes)
+ * xxx/boardlib/ebc.c
+ *
+ * depending of the switch setting off the board, the location of devices
+ * in the address map are not the same:
+ */
+/* Common definitions */
+
+#define BOARD_SMALL_FLASH_SIZE                    0x100000      /* 1M */
+#define BOARD_FRAM_SIZE			            0x8000
+#define BOARD_SRAM_SIZE			          0x100000
+#define BOARD_OPER_FLASH_SIZE                     0x400000      /* 4M */
+
+
+/* Configuration 1:
+ * the small flash and sram are placed on top   (CS0)
+ * the Large flash is placed below              (CS2)
+ * The FPGA and FRAM at the end                 (CS1)
+ *                                        xxxx----xxxx----      
+ */
+#define BOARD_CONF1_SMALL_FLASH         0x00000004FFF00000ull
+#define BOARD_CONF1_FRAM                0x00000004FF000000ull
+#define BOARD_CONF1_OPER_FLASH          0x00000004E7C00000ull
+#define BOARD_CONF1_SRAM                0x00000004E7000000ull
+
+/* Configuration 2:
+ * the small flash and sram are placed on top   (CS0)
+ * but now sram before smal flash
+ * the Large flash is placed below (no change)  (CS2)
+ * The FPGA and FRAM stay in same place.        (CS1)
+ *                                        xxxx----xxxx----
+ */
+#define BOARD_CONF2_OPER_FLASH          0x00000004FFC00000ull
+#define BOARD_CONF2_SRAM                0x00000004FF000000ull
+#define BOARD_CONF2_SMALL_FLASH         0x00000004E7F00000ull
+#define BOARD_CONF2_FRAM                0x00000004E7000000ull
+
+/* Configuration 3:
+ * the Large flash is placed on top,            (CS0)
+ * the small flash and sram are placed below.   (CS2)
+ * The FPGA and FRAM stay in same place.        (CS1)
+ *                                        xxxx----xxxx----
+ */
+#define BOARD_CONF3_SRAM                0x00000004FFF00000ull
+#define BOARD_CONF3_OPER_FLASH          0x00000004FF000000ull
+#define BOARD_CONF3_SMALL_FLASH         0x00000004E7F00000ull
+#define BOARD_CONF3_FRAM                0x00000004E7000000ull
+
+
 /*
  * FPGA registers
  */
 #define YUCCA_FPGA_REG_BASE			0x00000004e2000000ULL
 #define YUCCA_FPGA_REG_SIZE			0x24
 
+#define FPGA_REG10                              0x10 /* Ethernet/Reset/Boot
+                                                        configs */
+#define FPGA_REG10_ETH_MODE10                   0x8000
+#define FPGA_REG10_ETH_MODE100                  0x4000
+#define FPGA_REG10_ETH_MODE1000                 0x2000
+#define FPGA_REG10_ETH_FORCE_DUPLEX             0x1000
+#define FPGA_REG10_LOG_RESET_ETHERNET           0x0800
+#define FPGA_REG10_ETH_AUTO_NEGO                0x0400
+#define FPGA_REG10_LOG_INT_ETH                  0x0200
+#define FPGA_REG10_LOG_RESET_HISR               0x0080
+#define FPGA_REG10_LOG_RESET_DISPLAY            0x0040
+#define FPGA_REG10_LOG_RESET_SDRAM              0x0020
+#define FPGA_REG10_LOG_OPBOOT                   0x0010
+#define FPGA_REG10_LOG_SRAM_BOOT                0x0008
+#define FPGA_REG10_LOG_BTBOOT                   0x0004
+
+/*Boot configurations */
+#define BOARD_CONFIG_MASK                       (0x001C)
+#define BOARD_CONFIG_1                          (0x0018)
+#define BOARD_CONFIG_2                          (0x000C)
+#define BOARD_CONFIG_3                          (0x0014)
+#define BOARD_BOOT_OPER_FLASH(x)       (((x) & BOARD_CONFIG_MASK) == \
+                                                BOARD_CONFIG_2)
+
 #define FPGA_REG1A				0x1a
 
 #define FPGA_REG1A_PE0_GLED			0x8000
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -332,6 +332,14 @@ config MTD_OCOTEA
 	  Ocotea board. If you have one of these boards and would like to
 	  use the flash chips on it, say 'Y'.
 
+config MTD_YUCCA
+        tristate "Flash devices mapped on IBM 440SPe Yucca"
+        depends on MTD_CFI && PPC32 && 44x && YUCCA
+        help
+          This enables access routines for the flash chips on the IBM 440SPe
+          Yucca board. If you have one of these boards and would like to
+          use the flash chips on it, say 'Y'.
+
 config MTD_REDWOOD
 	tristate "CFI Flash devices mapped on IBM Redwood"
 	depends on MTD_CFI && PPC32 && 4xx && 40x && ( REDWOOD_4 || REDWOOD_5 || REDWOOD_6 )
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -56,6 +56,7 @@ obj-$(CONFIG_MTD_NETtel)	+= nettel.o
 obj-$(CONFIG_MTD_SCB2_FLASH)	+= scb2_flash.o
 obj-$(CONFIG_MTD_EBONY)		+= ebony.o
 obj-$(CONFIG_MTD_OCOTEA)	+= ocotea.o
+obj-$(CONFIG_MTD_YUCCA)         += yucca_flash.o
 obj-$(CONFIG_MTD_BEECH)		+= beech-mtd.o
 obj-$(CONFIG_MTD_ARCTIC)	+= arctic-mtd.o
 obj-$(CONFIG_MTD_WALNUT)        += walnut.o
diff --git a/drivers/mtd/maps/yucca_flash.c b/drivers/mtd/maps/yucca_flash.c
new file mode 100644
--- /dev/null
+++ b/drivers/mtd/maps/yucca_flash.c
@@ -0,0 +1,278 @@
+/*
+ * Mapping for Yucca user flash
+ *
+ * This was derived from the luan.c
+ *
+ * Ruslan Sushko <rsushko@ru.mvista.com>
+ * Matt Porter <mporter@mvista.com>
+ *
+ * Copyright (C) 2002-2005 MontaVista Software Inc.
+ * (C) Copyright IBM Corp. 2004
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/config.h>
+#include <linux/version.h>
+#include <asm/io.h>
+
+static struct mtd_info *oper_flash_mtd = NULL;
+static struct mtd_info *small_flash_mtd = NULL;
+static struct mtd_info *fram_mtd = NULL;
+static struct mtd_info *sram_mtd = NULL;
+
+static struct map_info yucca_sram_map = {
+        .name =         "Yucca SRAM",
+        .size =         BOARD_SRAM_SIZE,
+        .bankwidth = 2,
+};
+
+static struct map_info yucca_fram_map = {
+        .name =         "Yucca FRAM",
+        .size =         BOARD_FRAM_SIZE,
+        .bankwidth = 1,
+};
+
+static struct map_info yucca_small_map = {
+        .name =         "Yucca small flash",
+        .size =         BOARD_SMALL_FLASH_SIZE,
+        .bankwidth = 1,
+};
+
+static struct map_info yucca_oper_map = {
+        .name =         "Yucca Operational flash",
+        .size =         BOARD_OPER_FLASH_SIZE,
+        .bankwidth = 2,
+};
+
+static struct mtd_partition yucca_sram_partitions[] = {
+        {
+                .name =   "SRAM",
+                .offset = 0x0,
+                .size =   0x100000,
+        }
+};
+
+static struct mtd_partition yucca_fram_partitions[] = {
+        {
+                .name =   "FRAM",
+                .offset = 0x0,
+                .size =   0x8000,
+        }
+};
+
+static struct mtd_partition yucca_small_partitions[] = {
+        {
+                .name =   "U-boot",
+                .offset = 0x0,
+                .size =   0x100000,
+        }
+};
+
+static struct mtd_partition yucca_oper_partitions[] = {
+        {
+                .name =   "Linux Kernel",   
+                .offset = 0,
+                .size =   0x100000,
+        },
+        {
+                .name =   "Free Area",
+                .offset = 0x100000,
+                .size =   0x300000,
+        }
+};
+
+#define NB_OF(x)  (sizeof(x)/sizeof(x[0]))
+
+
+int __init init_yucca(void)
+{
+        u16 fpga10_reg; u16 *fpga_adr; 
+        unsigned long long small_flash_base, oper_flash_base; 
+        unsigned long long sram_base, fram_base;
+        int memconfig = 0;
+
+        fpga_adr = ioremap64(YUCCA_FPGA_REG_BASE, YUCCA_FPGA_REG_SIZE);
+        if (!fpga_adr)
+                return -ENOMEM;
+  
+
+        fpga10_reg = *((u16*)((u32)fpga_adr + FPGA_REG10));
+        iounmap(fpga_adr); 
+        switch (fpga10_reg & BOARD_CONFIG_MASK) {
+                default:
+                        printk("Memory config switches are invalid: "
+                               "fpga10_reg= %x. Using default configuration\n",
+                                        fpga10_reg);
+                case BOARD_CONFIG_1:
+                        memconfig = 1;
+                        small_flash_base =      BOARD_CONF1_SMALL_FLASH;
+                        oper_flash_base =       BOARD_CONF1_OPER_FLASH;
+		        sram_base =             BOARD_CONF1_SRAM;
+		        fram_base =             BOARD_CONF1_FRAM;
+                        break;
+                case BOARD_CONFIG_2:
+                        memconfig = 2;
+                        small_flash_base =      BOARD_CONF2_SMALL_FLASH;
+                        oper_flash_base =       BOARD_CONF2_OPER_FLASH;
+		        sram_base =             BOARD_CONF2_SRAM;
+		        fram_base =             BOARD_CONF3_FRAM;
+                        break;
+                case BOARD_CONFIG_3:
+                        memconfig = 3;
+                        small_flash_base =      BOARD_CONF3_SMALL_FLASH;
+                        oper_flash_base =       BOARD_CONF3_OPER_FLASH;
+		        sram_base =             BOARD_CONF3_SRAM;
+		        fram_base =             BOARD_CONF3_FRAM;
+                        break;
+        }
+        
+        printk("Using EBC memory configuration #%d\n", memconfig);
+
+        yucca_small_map.phys = small_flash_base;
+        yucca_small_map.virt = ioremap64(small_flash_base, 
+                        yucca_small_map.size);
+     
+        if (!yucca_small_map.virt) {
+                printk("Failed to ioremap small flash\n");
+                return -EIO;
+        }
+     
+        simple_map_init(&yucca_small_map);
+     
+        small_flash_mtd = do_map_probe("map_rom", &yucca_small_map);
+        if (small_flash_mtd) {
+                small_flash_mtd->owner = THIS_MODULE;
+                add_mtd_partitions(small_flash_mtd, yucca_small_partitions,
+                                        NB_OF(yucca_small_partitions));
+        } else {
+                printk("map probe failed for small flash\n");
+                return -ENXIO;
+        }
+        
+        yucca_oper_map.phys = oper_flash_base;
+        yucca_oper_map.virt = ioremap64(oper_flash_base,
+                        yucca_oper_map.size);
+     
+        if (!yucca_oper_map.virt) {
+                printk("Failed to ioremap oper flash\n");
+                return -EIO;
+        }
+              
+        simple_map_init(&yucca_oper_map);
+     
+        oper_flash_mtd = do_map_probe("cfi_probe", &yucca_oper_map);
+        if (oper_flash_mtd) {
+                oper_flash_mtd->owner = THIS_MODULE;
+                add_mtd_partitions(oper_flash_mtd, yucca_oper_partitions,
+                                        NB_OF(yucca_oper_partitions));
+        } else {
+                printk("map probe failed for oper flash\n");
+                return -ENXIO;
+        }
+     
+        yucca_sram_map.phys = sram_base;
+        yucca_sram_map.virt = ioremap64(sram_base,
+                                 yucca_sram_map.size);
+     
+        if (!yucca_sram_map.virt) {
+                printk("Failed to ioremap SRAM\n");
+                return -EIO;
+        }
+
+        simple_map_init(&yucca_sram_map);
+     
+        sram_mtd = do_map_probe("map_ram", &yucca_sram_map);
+        if (sram_mtd) {
+                sram_mtd->owner = THIS_MODULE;
+                add_mtd_partitions(sram_mtd, yucca_sram_partitions,
+                                        NB_OF(yucca_sram_partitions));
+        } else {
+                printk("map probe failed for SRAM\n");
+                return -ENXIO;
+        }
+     
+        yucca_fram_map.phys = fram_base;
+        yucca_fram_map.virt = ioremap64(fram_base,
+                                 yucca_fram_map.size);
+     
+        if (!yucca_fram_map.virt) {
+                printk("Failed to ioremap FRAM\n");
+                return -EIO;
+        }
+     
+        simple_map_init(&yucca_fram_map);
+     
+        fram_mtd = do_map_probe("map_ram", &yucca_fram_map);
+        if (fram_mtd) {
+                fram_mtd->owner = THIS_MODULE;
+                add_mtd_partitions(fram_mtd, yucca_fram_partitions,
+                                        NB_OF(yucca_fram_partitions));
+        } else {
+                printk("map probe failed for FRAM\n");
+                return -ENXIO;
+        }
+        return 0;
+}
+
+static void __exit cleanup_yucca(void)
+{
+        if (yucca_small_map.virt) {
+                iounmap((void *)yucca_small_map.virt);
+                yucca_small_map.virt = 0;
+        }
+
+        if (yucca_oper_map.virt) {
+                iounmap((void *)yucca_oper_map.virt);
+                yucca_oper_map.virt = 0;
+        }
+
+	if (yucca_fram_map.virt) {
+                iounmap((void *)yucca_fram_map.virt);
+                yucca_fram_map.virt = 0;
+	}
+		
+	if (yucca_sram_map.virt) {
+                iounmap((void *)yucca_sram_map.virt);
+                yucca_sram_map.virt = 0;
+	}
+
+        if (oper_flash_mtd) {
+                del_mtd_partitions(oper_flash_mtd);
+                map_destroy(oper_flash_mtd);
+        }
+
+        if (small_flash_mtd) {
+                del_mtd_partitions(small_flash_mtd);
+                map_destroy(small_flash_mtd);
+        }
+        
+        if (fram_mtd) {
+                del_mtd_partitions(fram_mtd);
+                map_destroy(fram_mtd);
+        } 
+        
+        if (sram_mtd) {
+                del_mtd_partitions(sram_mtd);
+                map_destroy(sram_mtd);
+        }
+        
+}
+
+module_init(init_yucca);
+module_exit(cleanup_yucca);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Ruslan V. Sushko <rsushko@ru.mvista.com>");
+MODULE_DESCRIPTION("MTD map and partitions for IBM 440SPe Yucca boards");
+




^ permalink raw reply

* [PATCH 2/3] PCI-X support for Yucca
From: Ruslan V. Sushko @ 2005-09-30 15:39 UTC (permalink / raw)
  To: linuxppc-dev

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

This patch adds PCIX support for Yucca PPC440SPe board. The patch is
implemented for Roland Dreier git tree for Yucca PPC440SPe board.

Signed-off-by: Ruslan V. Sushko <rsushko@ru.mvista.com>

[-- Attachment #2: yucca_pcix.patch --]
[-- Type: text/x-patch, Size: 6828 bytes --]

diff --git a/arch/ppc/platforms/4xx/yucca.c b/arch/ppc/platforms/4xx/yucca.c
--- a/arch/ppc/platforms/4xx/yucca.c
+++ b/arch/ppc/platforms/4xx/yucca.c
@@ -86,19 +86,23 @@ yucca_map_irq(struct pci_dev *dev, unsig
 	struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
 
 	/* PCIX */
-	if (hose->index == 3) {
+	if (hose->index == 0) {
 		static char pci_irq_table[][4] =
 		/*
 		 *	PCI IDSEL/INTPIN->INTLINE
 		 *	  A   B   C   D
 		 */
 		{
-			{ 81, -1, -1, -1 },	/* IDSEL 1 - PCIX0 Slot 0 */
+			{ 49, -1, -1, -1 },	/* IDSEL 1 - PCIX0 Slot 0 */
 		};
 		const long min_idsel = 1, max_idsel = 1, irqs_per_slot = 4;
-		return PCI_IRQ_TABLE_LOOKUP;
+                mtdcr(DCRN_UIC_PR(UIC1), 
+                mfdcr(DCRN_UIC_PR(UIC1)) & ~0x00004000); /* Set PCI interrupt
+                                                            (EXT IRQ12) plarity
+                                                            to Negative */
+                return PCI_IRQ_TABLE_LOOKUP;
 	/* PCIE0 */
-	} else if (hose->index == 0) {
+	} else if (hose->index == 1) {
 		static char pci_irq_table[][4] =
 		/*
 		 *	PCI IDSEL/INTPIN->INTLINE
@@ -110,7 +114,7 @@ yucca_map_irq(struct pci_dev *dev, unsig
 		const long min_idsel = 1, max_idsel = 1, irqs_per_slot = 4;
 		return PCI_IRQ_TABLE_LOOKUP;
 	/* PCIE1 */
-	} else if (hose->index == 1) {
+	} else if (hose->index == 2) {
 		static char pci_irq_table[][4] =
 		/*
 		 *	PCI IDSEL/INTPIN->INTLINE
@@ -122,7 +126,7 @@ yucca_map_irq(struct pci_dev *dev, unsig
 		const long min_idsel = 1, max_idsel = 1, irqs_per_slot = 4;
 		return PCI_IRQ_TABLE_LOOKUP;
 	/* PCIE2 */
-	} else if (hose->index == 2) {
+	} else if (hose->index == 3) {
 		static char pci_irq_table[][4] =
 		/*
 		 *	PCI IDSEL/INTPIN->INTLINE
@@ -150,10 +154,123 @@ static void __init yucca_set_emacdata(vo
 	memcpy(emacdata->mac_addr, __res.bi_enetaddr, 6);
 }
 
+#define PCIX_READW(offset) \
+	(readw((void *)((u32)pcix_reg_base+offset)))
+
+#define PCIX_WRITEW(value, offset) \
+	(writew(value, (void *)((u32)pcix_reg_base+offset)))
+
+#define PCIX_WRITEL(value, offset) \
+	(writel(value, (void *)((u32)pcix_reg_base+offset)))
+
+static void __init
+yucca_setup_pcix(void)
+{
+	void *pcix_reg_base;
+
+        pcix_reg_base = ioremap64(PCIX0_REG_BASE, PCIX_REG_SIZE);
+
+        /* Disable all windows */
+        PCIX_WRITEL(0, PCIX0_POM0SA);
+        PCIX_WRITEL(0, PCIX0_POM1SA);
+        PCIX_WRITEL(0, PCIX0_POM2SA);
+        PCIX_WRITEL(0, PCIX0_PIM0SA);
+        PCIX_WRITEL(0, PCIX0_PIM0SAH);
+        PCIX_WRITEL(0, PCIX0_PIM1SA);
+        PCIX_WRITEL(0, PCIX0_PIM2SA);
+        PCIX_WRITEL(0, PCIX0_PIM2SAH);
+
+        /*
+         * Setup 512MB PLB->PCI outbound mem window
+         * (a_n000_0000->0_n000_0000)
+         * */
+        PCIX_WRITEL(0x0000000d, PCIX0_POM0LAH);
+        PCIX_WRITEL(0x80000000, PCIX0_POM0LAL);
+        PCIX_WRITEL(0x00000000, PCIX0_POM0PCIAH);
+        PCIX_WRITEL(0x80000000, PCIX0_POM0PCIAL);
+        PCIX_WRITEL(0xe0000001, PCIX0_POM0SA);
+
+        /* Setup 1GB PCI->PLB inbound memory window at 0, enable MSIs */
+        PCIX_WRITEL(0x00000000, PCIX0_PIM0LAH);
+        PCIX_WRITEL(0x00000000, PCIX0_PIM0LAL);
+        PCIX_WRITEL(0xc0000007, PCIX0_PIM0SA);
+        PCIX_WRITEL(0xffffffff, PCIX0_PIM0SAH);
+
+                /* Enable PCIX0 I/O, Mem, and Busmaster cycles */
+        PCIX_WRITEW(PCIX_READW(PCIX0_COMMAND) | PCI_COMMAND_MEMORY |
+                        PCI_COMMAND_MASTER, PCIX0_COMMAND);
+
+        iounmap(pcix_reg_base);
+	eieio();
+}
+
+static void __init
+yucca_setup_hose(struct pci_controller *hose,
+		int lower_mem,
+		int upper_mem,
+		int cfga,
+		int cfgd,
+		u64 pcix_io_base)
+{
+	char name[20];
+
+	sprintf(name, "PCIX%d host bridge", hose->index);
+
+	hose->pci_mem_offset = YUCCA_PCIX_MEM_OFFSET;
+
+	pci_init_resource(&hose->io_resource,
+			YUCCA_PCIX_LOWER_IO,
+			YUCCA_PCIX_UPPER_IO,
+			IORESOURCE_IO,
+			name);
+
+	pci_init_resource(&hose->mem_resources[0],
+			lower_mem,
+			upper_mem,
+			IORESOURCE_MEM,
+			name);
+
+	hose->io_space.start = YUCCA_PCIX_LOWER_IO;
+	hose->io_space.end = YUCCA_PCIX_UPPER_IO;
+	hose->mem_space.start = lower_mem;
+	hose->mem_space.end = upper_mem;
+	isa_io_base =
+		(unsigned long)ioremap64(pcix_io_base, PCIX_IO_SIZE);
+	hose->io_base_virt = (void *)isa_io_base;
+
+  	setup_indirect_pci(hose, cfga, cfgd);
+	hose->set_cfg_type = 1;
+}
+
+
 static void __init
 yucca_setup_hoses(void)
 {
+	struct pci_controller *hose;
+
+	/* Configure windows on the PCI-X host bridge */
+	yucca_setup_pcix();
+        
+	/* Allocate hoses for PCIX0 */
+	hose = pcibios_alloc_controller();
+	if (!hose)
+		return;
+
+	/* Setup PCIX0 */
+	hose->first_busno = 0;
+	hose->last_busno = 0xff;
+
+	yucca_setup_hose(hose,
+			YUCCA_PCIX_LOWER_MEM,
+			YUCCA_PCIX_UPPER_MEM,
+			PCIX0_CFGA,
+			PCIX0_CFGD,
+			PCIX0_IO_BASE);
+
+  	hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
 
+	ppc_md.pci_swizzle = common_swizzle;
+	ppc_md.pci_map_irq = yucca_map_irq;
 }
 
 TODC_ALLOC();
diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile
--- a/arch/ppc/syslib/Makefile
+++ b/arch/ppc/syslib/Makefile
@@ -55,6 +55,7 @@ obj-$(CONFIG_GT64260)		+= gt64260_pic.o
 obj-$(CONFIG_LOPEC)		+= i8259.o pci_auto.o todc_time.o
 obj-$(CONFIG_HDPU)		+= pci_auto.o
 obj-$(CONFIG_LUAN)		+= indirect_pci.o pci_auto.o todc_time.o
+obj-$(CONFIG_YUCCA)		+= indirect_pci.o pci_auto.o
 obj-$(CONFIG_KATANA)		+= pci_auto.o
 obj-$(CONFIG_MV64360)		+= mv64360_pic.o
 obj-$(CONFIG_MV64X60)		+= mv64x60.o mv64x60_win.o indirect_pci.o
diff --git a/include/asm-ppc/ibm44x.h b/include/asm-ppc/ibm44x.h
--- a/include/asm-ppc/ibm44x.h
+++ b/include/asm-ppc/ibm44x.h
@@ -64,6 +64,11 @@
 #define	PPC44x_PCICFG_PAGE	0x0000000900000000ULL
 #define	PPC44x_PCIIO_PAGE	PPC44x_PCICFG_PAGE
 #define	PPC44x_PCIMEM_PAGE	0x0000000a00000000ULL
+#elif defined(CONFIG_440SPE)
+#define	PPC44x_IO_PAGE		0x0000000400000000ULL
+#define	PPC44x_PCICFG_PAGE	0x0000000C00000000ULL
+#define	PPC44x_PCIIO_PAGE	PPC44x_PCICFG_PAGE
+#define	PPC44x_PCIMEM_PAGE	0x0000000D00000000ULL
 #elif defined(CONFIG_440EP)
 #define PPC44x_IO_PAGE		0x0000000000000000ULL
 #define PPC44x_PCICFG_PAGE	0x0000000000000000ULL
@@ -552,12 +557,19 @@
 #define PCIX1_CFGD		0x1ec00004UL
 #define PCIX2_CFGD		0x2ec00004UL
 
+#if defined (CONFIG_440SPE)
+#define PCIX0_IO_BASE		0x0000000C08000000ULL
+#else /* !CONFIG_440SPE */
 #define PCIX0_IO_BASE		0x0000000908000000ULL
 #define PCIX1_IO_BASE		0x0000000908000000ULL
 #define PCIX2_IO_BASE		0x0000000908000000ULL
+#endif /* CONFIG_440SPE */
+
 #define PCIX_IO_SIZE		0x00010000
 
-#ifdef CONFIG_440SP
+#if defined (CONFIG_440SPE)
+#define PCIX0_REG_BASE		0x0000000c0ec80000ULL
+#elif defefined(CONFIG_440SP)
 #define PCIX0_REG_BASE		0x000000090ec80000ULL
 #else
 #define PCIX0_REG_BASE		0x000000020ec80000ULL




^ permalink raw reply

* Re: MV64x60 watchdog timer driver updates
From: Corey Minyard @ 2005-09-30 15:10 UTC (permalink / raw)
  To: Mark A. Greer; +Cc: linuxppc-dev
In-Reply-To: <20050929203647.GA6597@mag.az.mvista.com>

Mark A. Greer wrote:

>On Thu, Sep 29, 2005 at 01:32:21PM -0500, Corey Minyard wrote:
>  
>
>>James looked at an earlier version and said it was ok, and suggested
>>a few changes.  This has been tested against 2.6.14-rc2 on a Katana.
>>
>>Note that the bus_clk value from the platform information seems to
>>be in MHZ, but the actual frequency is generally 133,333,333, not
>>133,000,000.  I don't think the inaccuracy matters here, but it seems
>>a little odd.
>>    
>>
>
>Yes, it makes more sense to me to pass the actual frequency and not do
>the '* 1000000'.
>  
>
The only trouble is if  you go over 4GHZ...  Maybe it should be in KHZ 
instead of MHZ?  or 64-bits?  Or maybe we don't worry about >4GHZ busses?

Also, how would one go about changing this?  Would you need something like:

if (bus_clk < 1000)
  bus_clk *= 1000000

for backwards compatability?

>Also--I should have thought of this earlier--there should probably be a
>patch to add a default platform_data entry in arch/ppc/syslib/mv64x60.c
>and a patch for katana.c if the defaults in mv64x60.c aren't correct
>for the katana.  At least, that's how things are done now.
>  
>
I'm not sure I understand completely.  How would you go about setting 
the platform data?

Thanks,

-Corey

^ permalink raw reply

* [PATCH 9/9] powerpc: make iSeries boot
From: Stephen Rothwell @ 2005-09-30 14:14 UTC (permalink / raw)
  To: paulus; +Cc: ppc64-dev, ppc-dev
In-Reply-To: <20050930233602.138b6e27.sfr@canb.auug.org.au>

Now that we use the device tree, it helps to build it in.
It also helps to link the kernel at the correct address.

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

 arch/powerpc/Kconfig       |    4 ++--
 arch/powerpc/Kconfig.debug |    2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

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

1b4c416e0cf237dce004392122db45eb22dbc416
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -317,7 +317,7 @@ config PPC_BPA
 
 config PPC_OF
 	bool
-	depends on PPC_MULTIPLATFORM	# for now
+	depends on PPC_MULTIPLATFORM || PPC_ISERIES
 	default y
 
 config XICS
@@ -836,7 +836,7 @@ endmenu
 if PPC64
 config KERNEL_START
 	hex
-	default "0xc0000000"
+	default "0xc000000000000000"
 endif
 
 source "net/Kconfig"
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -55,7 +55,7 @@ config BDI_SWITCH
 
 config BOOTX_TEXT
 	bool "Support for early boot text console (BootX or OpenFirmware only)"
-	depends PPC_OF
+	depends PPC_OF && !PPC_ISERIES
 	help
 	  Say Y here to see progress messages from the boot firmware in text
 	  mode. Requires either BootX or Open Firmware.

^ permalink raw reply

* [PATCH 8/9] powerpc: make iSeries build
From: Stephen Rothwell @ 2005-09-30 14:10 UTC (permalink / raw)
  To: paulus; +Cc: ppc64-dev, ppc-dev
In-Reply-To: <20050930233602.138b6e27.sfr@canb.auug.org.au>

Also Merge vmlinux.lds.S and remove arch/powerpc/kernel/vmlinux.lds which
is a generated file.

The merge of vmlinux.lds.S would be much cleaner if it is clear that
putting the ..start/end symbols inside the section definitions is OK on
ppc32.

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

 arch/powerpc/Kconfig                      |    6 +
 arch/powerpc/Makefile                     |   27 ++--
 arch/powerpc/kernel/Makefile              |    9 +
 arch/powerpc/kernel/vmlinux.lds           |  174 ---------------------------
 arch/powerpc/kernel/vmlinux.lds.S         |  190 +++++++++++++++++++++++++++--
 arch/powerpc/platforms/iseries/lpevents.c |    2 
 arch/ppc64/kernel/Makefile                |    8 -
 include/asm-powerpc/system.h              |    4 -
 8 files changed, 214 insertions(+), 206 deletions(-)
 delete mode 100644 arch/powerpc/kernel/vmlinux.lds

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

f0c094f719829a7a15cbbea72a33093b9a7dec5d
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -833,6 +833,12 @@ config PIN_TLB
 	depends on ADVANCED_OPTIONS && 8xx
 endmenu
 
+if PPC64
+config KERNEL_START
+	hex
+	default "0xc0000000"
+endif
+
 source "net/Kconfig"
 
 source "drivers/Kconfig"
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -124,12 +124,14 @@ head-$(CONFIG_6xx)		+= arch/powerpc/kern
 head-$(CONFIG_PPC_FPU)		+= arch/powerpc/kernel/fpu.o
 endif
 
-core-y				+= arch/powerpc/kernel/ \
-				   arch/$(OLDARCH)/kernel/ \
-				   arch/powerpc/mm/ \
-				   arch/powerpc/lib/ \
-				   arch/powerpc/sysdev/ \
-				   arch/powerpc/platforms/
+core-y				+= arch/powerpc/kernel/
+core-y				+= arch/$(OLDARCH)/kernel/
+core-$(CONFIG_PPC32)		+= arch/powerpc/mm/
+core-$(CONFIG_PPC64)		+= arch/$(OLDARCH)/mm/
+core-$(CONFIG_PPC32)		+= arch/powerpc/lib/
+libs-$(CONFIG_PPC64)		+= arch/$(OLDARCH)/lib/
+core-y				+= arch/powerpc/sysdev/
+core-y				+= arch/powerpc/platforms/
 core-$(CONFIG_PPC32)		+= arch/ppc/syslib/
 core-$(CONFIG_MATH_EMULATION)	+= arch/ppc/math-emu/
 core-$(CONFIG_XMON)		+= arch/powerpc/xmon/
@@ -140,17 +142,20 @@ drivers-$(CONFIG_CPM2)		+= arch/ppc/8260
 
 drivers-$(CONFIG_OPROFILE)	+= arch/powerpc/oprofile/
 
-BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm
-
-.PHONY: $(BOOT_TARGETS)
-
-all: uImage zImage
+defaultimage-$(CONFIG_PPC32)	:= uImage zImage
+defaultimage-$(CONFIG_PPC_ISERIES) := vmlinux
+KBUILD_IMAGE := $(defaultimage-y)
+all: $(KBUILD_IMAGE)
 
 CPPFLAGS_vmlinux.lds	:= -Upowerpc
 
 # All the instructions talk about "make bzImage".
 bzImage: zImage
 
+BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm
+
+.PHONY: $(BOOT_TARGETS)
+
 boot := arch/$(OLDARCH)/boot
 
 $(BOOT_TARGETS): vmlinux
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -6,8 +6,10 @@ ifeq ($(CONFIG_PPC64),y)
 EXTRA_CFLAGS	+= -mno-minimal-toc
 endif
 
+ifeq ($(CONFIG_PPC32),y)
 extra-$(CONFIG_PPC_STD_MMU)	:= head.o
-extra_$(CONFIG_PPC64)		:= head_64.o
+endif
+extra-$(CONFIG_PPC64)		:= head_64.o
 extra-$(CONFIG_40x)		:= head_4xx.o
 extra-$(CONFIG_44x)		:= head_44x.o
 extra-$(CONFIG_FSL_BOOKE)	:= head_fsl_booke.o
@@ -23,3 +25,8 @@ ifeq ($(CONFIG_PPC32),y)
 obj-$(CONFIG_MODULES)		+= ppc_ksyms.o
 endif
 obj-$(CONFIG_ALTIVEC)		+= vecemu.o vector.o
+
+ifeq ($(CONFIG_PPC_ISERIES),y)
+arch/powerpc/kernel/head_64.o: arch/powerpc/platforms/iseries/lparmap.s
+AFLAGS_head_64.o += -Iarch/powerpc/platforms/iseries
+endif
diff --git a/arch/powerpc/kernel/vmlinux.lds b/arch/powerpc/kernel/vmlinux.lds
deleted file mode 100644
--- a/arch/powerpc/kernel/vmlinux.lds
+++ /dev/null
@@ -1,174 +0,0 @@
-/* Align . to a 8 byte boundary equals to maximum function alignment. */
-/* sched.text is aling to function alignment to secure we have same
- * address even at second ld pass when generating System.map */
-/* spinlock.text is aling to function alignment to secure we have same
- * address even at second ld pass when generating System.map */
-  /* DWARF debug sections.
-		Symbols in the DWARF debugging sections are relative to
-		the beginning of the section so we begin them at 0.  */
-  /* Stabs debugging sections.  */
-OUTPUT_ARCH(powerpc:common)
-jiffies = jiffies_64 + 4;
-SECTIONS
-{
-  /* Read-only sections, merged into text segment: */
-  . = + SIZEOF_HEADERS;
-  .interp : { *(.interp) }
-  .hash : { *(.hash) }
-  .dynsym : { *(.dynsym) }
-  .dynstr : { *(.dynstr) }
-  .rel.text : { *(.rel.text) }
-  .rela.text : { *(.rela.text) }
-  .rel.data : { *(.rel.data) }
-  .rela.data : { *(.rela.data) }
-  .rel.rodata : { *(.rel.rodata) }
-  .rela.rodata : { *(.rela.rodata) }
-  .rel.got : { *(.rel.got) }
-  .rela.got : { *(.rela.got) }
-  .rel.ctors : { *(.rel.ctors) }
-  .rela.ctors : { *(.rela.ctors) }
-  .rel.dtors : { *(.rel.dtors) }
-  .rela.dtors : { *(.rela.dtors) }
-  .rel.bss : { *(.rel.bss) }
-  .rela.bss : { *(.rela.bss) }
-  .rel.plt : { *(.rel.plt) }
-  .rela.plt : { *(.rela.plt) }
-/*  .init          : { *(.init)	} =0*/
-  .plt : { *(.plt) }
-  .text :
-  {
-    *(.text)
-    . = ALIGN(8); __sched_text_start = .; *(.sched.text) __sched_text_end = .;
-    . = ALIGN(8); __lock_text_start = .; *(.spinlock.text) __lock_text_end = .;
-    *(.fixup)
-    *(.got1)
-    __got2_start = .;
-    *(.got2)
-    __got2_end = .;
-  }
-  _etext = .;
-  PROVIDE (etext = .);
-  .rodata : AT(ADDR(.rodata) - 0) { *(.rodata) *(.rodata.*) *(__vermagic) } .rodata1 : AT(ADDR(.rodata1) - 0) { *(.rodata1) } .pci_fixup : AT(ADDR(.pci_fixup) - 0) { __start_pci_fixups_early = .; *(.pci_fixup_early) __end_pci_fixups_early = .; __start_pci_fixups_header = .; *(.pci_fixup_header) __end_pci_fixups_header = .; __start_pci_fixups_final = .; *(.pci_fixup_final) __end_pci_fixups_final = .; __start_pci_fixups_enable = .; *(.pci_fixup_enable) __end_pci_fixups_enable = .; } __ksymtab : AT(ADDR(__ksymtab) - 0) { __start___ksymtab = .; *(__ksymtab) __stop___ksymtab = .; } __ksymtab_gpl : AT(ADDR(__ksymtab_gpl) - 0) { __start___ksymtab_gpl = .; *(__ksymtab_gpl) __stop___ksymtab_gpl = .; } __kcrctab : AT(ADDR(__kcrctab) - 0) { __start___kcrctab = .; *(__kcrctab) __stop___kcrctab = .; } __kcrctab_gpl : AT(ADDR(__kcrctab_gpl) - 0) { __start___kcrctab_gpl = .; *(__kcrctab_gpl) __stop___kcrctab_gpl = .; } __ksymtab_strings : AT(ADDR(__ksymtab_strings) - 0) { *(__ksymtab_strings) } __param : AT(ADDR(__param) - 0) { __start___param = .; *(__param) __stop___param = .; }
-  .fini : { *(.fini) } =0
-  .ctors : { *(.ctors) }
-  .dtors : { *(.dtors) }
-  .fixup : { *(.fixup) }
- __ex_table : {
-  __start___ex_table = .;
-  *(__ex_table)
-  __stop___ex_table = .;
- }
- __bug_table : {
-  __start___bug_table = .;
-  *(__bug_table)
-  __stop___bug_table = .;
- }
-  /* Read-write section, merged into data segment: */
-  . = ALIGN(4096);
-  .data :
-  {
-    *(.data)
-    *(.data1)
-    *(.sdata)
-    *(.sdata2)
-    *(.got.plt) *(.got)
-    *(.dynamic)
-    CONSTRUCTORS
-  }
-
-  . = ALIGN(4096);
-  __nosave_begin = .;
-  .data_nosave : { *(.data.nosave) }
-  . = ALIGN(4096);
-  __nosave_end = .;
-
-  . = ALIGN(32);
-  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
-
-  _edata = .;
-  PROVIDE (edata = .);
-
-  . = ALIGN(8192);
-  .data.init_task : { *(.data.init_task) }
-
-  . = ALIGN(4096);
-  __init_begin = .;
-  .init.text : {
- _sinittext = .;
- *(.init.text)
- _einittext = .;
-  }
-  /* .exit.text is discarded at runtime, not link time,
-     to deal with references from __bug_table */
-  .exit.text : { *(.exit.text) }
-  .init.data : {
-    *(.init.data);
-    __vtop_table_begin = .;
-    *(.vtop_fixup);
-    __vtop_table_end = .;
-    __ptov_table_begin = .;
-    *(.ptov_fixup);
-    __ptov_table_end = .;
-  }
-  . = ALIGN(16);
-  __setup_start = .;
-  .init.setup : { *(.init.setup) }
-  __setup_end = .;
-  __initcall_start = .;
-  .initcall.init : {
- *(.initcall1.init)
- *(.initcall2.init)
- *(.initcall3.init)
- *(.initcall4.init)
- *(.initcall5.init)
- *(.initcall6.init)
- *(.initcall7.init)
-  }
-  __initcall_end = .;
-
-  __con_initcall_start = .;
-  .con_initcall.init : { *(.con_initcall.init) }
-  __con_initcall_end = .;
-
-  .security_initcall.init : AT(ADDR(.security_initcall.init) - 0) { __security_initcall_start = .; *(.security_initcall.init) __security_initcall_end = .; }
-
-  __start___ftr_fixup = .;
-  __ftr_fixup : { *(__ftr_fixup) }
-  __stop___ftr_fixup = .;
-
-  . = ALIGN(32);
-  __per_cpu_start = .;
-  .data.percpu : { *(.data.percpu) }
-  __per_cpu_end = .;
-
-  . = ALIGN(4096);
-  __initramfs_start = .;
-  .init.ramfs : { *(.init.ramfs) }
-  __initramfs_end = .;
-
-  . = ALIGN(4096);
-  __init_end = .;
-
-  . = ALIGN(4096);
-  _sextratext = .;
-  _eextratext = .;
-
-  __bss_start = .;
-  .bss :
-  {
-   *(.sbss) *(.scommon)
-   *(.dynbss)
-   *(.bss)
-   *(COMMON)
-  }
-  __bss_stop = .;
-
-  _end = . ;
-  PROVIDE (end = .);
-
-  /* Sections to be discarded. */
-  /DISCARD/ : {
-    *(.exitcall.exit)
-    *(.exit.data)
-  }
-}
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -1,10 +1,29 @@
+#include <linux/config.h>
+#ifdef CONFIG_PPC64
+#include <asm/page.h>
+#endif
 #include <asm-generic/vmlinux.lds.h>
 
+#ifdef CONFIG_PPC64
+OUTPUT_ARCH(powerpc:common64)
+jiffies = jiffies_64;
+#else
 OUTPUT_ARCH(powerpc:common)
 jiffies = jiffies_64 + 4;
+#endif
 SECTIONS
 {
+  /* Sections to be discarded. */
+  /DISCARD/ : {
+    *(.exitcall.exit)
+#ifdef CONFIG_PPC32
+    *(.exit.data)
+#endif
+  }
+
+
   /* Read-only sections, merged into text segment: */
+#ifdef CONFIG_PPC32
   . = + SIZEOF_HEADERS;
   .interp : { *(.interp) }
   .hash          : { *(.hash)		}
@@ -28,17 +47,30 @@ SECTIONS
   .rela.plt      : { *(.rela.plt)		}
 /*  .init          : { *(.init)	} =0*/
   .plt : { *(.plt) }
-  .text      :
-  {
+#endif
+  .text : {
+#ifdef CONFIG_PPC64
+    *(.text .text.*)
+#else
     *(.text)
+#endif
     SCHED_TEXT
     LOCK_TEXT
+#ifdef CONFIG_PPC64
+    KPROBES_TEXT
+#endif
     *(.fixup)
+#ifdef CONFIG_PPC32
     *(.got1)
     __got2_start = .;
     *(.got2)
     __got2_end = .;
+#else
+    . = ALIGN(PAGE_SIZE);
+    _etext = .;
+#endif
   }
+#ifdef CONFIG_PPC32
   _etext = .;
   PROVIDE (etext = .);
 
@@ -48,6 +80,7 @@ SECTIONS
   .dtors     : { *(.dtors)   }
 
   .fixup   : { *(.fixup) }
+#endif
 
 	__ex_table : {
 		__start___ex_table = .;
@@ -61,6 +94,17 @@ SECTIONS
 		__stop___bug_table = .;
 	}
 
+#ifdef CONFIG_PPC64
+	__ftr_fixup : {
+		__start___ftr_fixup = .;
+		*(__ftr_fixup)
+		__stop___ftr_fixup = .;
+	}
+
+  RODATA
+#endif
+
+#ifdef CONFIG_PPC32
   /* Read-write section, merged into data segment: */
   . = ALIGN(4096);
   .data    :
@@ -90,16 +134,25 @@ SECTIONS
   .data.init_task : { *(.data.init_task) }
 
   . = ALIGN(4096);
+#else
+  /* will be freed after init */
+  . = ALIGN(PAGE_SIZE);
+#endif
   __init_begin = .;
   .init.text : {
 	_sinittext = .;
 	*(.init.text)
 	_einittext = .;
   }
+#ifdef CONFIG_PPC32
   /* .exit.text is discarded at runtime, not link time,
      to deal with references from __bug_table */
   .exit.text : { *(.exit.text) }
+#endif
   .init.data : {
+#ifdef CONFIG_PPC64
+    *(.init.data)
+#else
     *(.init.data);
     __vtop_table_begin = .;
     *(.vtop_fixup);
@@ -107,13 +160,31 @@ SECTIONS
     __ptov_table_begin = .;
     *(.ptov_fixup);
     __ptov_table_end = .;
+#endif
   }
+
   . = ALIGN(16);
+#ifdef CONFIG_PPC32
   __setup_start = .;
-  .init.setup : { *(.init.setup) }
+#endif
+  .init.setup : {
+#ifdef CONFIG_PPC64
+    __setup_start = .;
+#endif
+    *(.init.setup)
+#ifdef CONFIG_PPC64
+    __setup_end = .;
+#endif
+  }
+#ifdef CONFIG_PPC32
   __setup_end = .;
+
   __initcall_start = .;
+#endif
   .initcall.init : {
+#ifdef CONFIG_PPC64
+	__initcall_start = .;
+#endif
 	*(.initcall1.init)
 	*(.initcall2.init)
 	*(.initcall3.init)
@@ -121,27 +192,109 @@ SECTIONS
 	*(.initcall5.init)
 	*(.initcall6.init)
 	*(.initcall7.init)
+#ifdef CONFIG_PPC64
+	__initcall_end = .;
+#endif
   }
+#ifdef CONFIG_PPC32
   __initcall_end = .;
 
   __con_initcall_start = .;
-  .con_initcall.init : { *(.con_initcall.init) }
+#endif
+  .con_initcall.init : {
+#ifdef CONFIG_PPC64
+    __con_initcall_start = .;
+#endif
+    *(.con_initcall.init)
+#ifdef CONFIG_PPC64
+    __con_initcall_end = .;
+#endif
+  }
+#ifdef CONFIG_PPC32
   __con_initcall_end = .;
+#endif
 
   SECURITY_INIT
 
+#ifdef CONFIG_PPC32
   __start___ftr_fixup = .;
   __ftr_fixup : { *(__ftr_fixup) }
   __stop___ftr_fixup = .;
+#else
+  . = ALIGN(PAGE_SIZE);
+  .init.ramfs : {
+    __initramfs_start = .;
+    *(.init.ramfs)
+    __initramfs_end = .;
+  }
+#endif
 
+#ifdef CONFIG_PPC32
   . = ALIGN(32);
   __per_cpu_start = .;
-  .data.percpu  : { *(.data.percpu) }
+#endif
+  .data.percpu : {
+#ifdef CONFIG_PPC64
+    __per_cpu_start = .;
+#endif
+    *(.data.percpu)
+#ifdef CONFIG_PPC64
+    __per_cpu_end = .;
+#endif
+  }
+#ifdef CONFIG_PPC32
   __per_cpu_end = .;
+#endif
+
+#ifdef CONFIG_PPC64
+ . = ALIGN(PAGE_SIZE);
+ . = ALIGN(16384);
+ __init_end = .;
+ /* freed after init ends here */
+
+
+ /* Read/write sections */
+ . = ALIGN(PAGE_SIZE);
+ . = ALIGN(16384);
+ /* The initial task and kernel stack */
+ .data.init_task : {
+      *(.data.init_task)
+      }
+
+ . = ALIGN(PAGE_SIZE);
+ .data.page_aligned : {
+      *(.data.page_aligned)
+      }
+
+ .data.cacheline_aligned : {
+      *(.data.cacheline_aligned)
+      }
+
+ .data : {
+      *(.data .data.rel* .toc1)
+      *(.branch_lt)
+      }
+
+ .opd : {
+      *(.opd)
+      }
+
+ .got : {
+      __toc_start = .;
+      *(.got)
+      *(.toc)
+      . = ALIGN(PAGE_SIZE);
+      _edata = .;
+      }
 
+
+  . = ALIGN(PAGE_SIZE);
+#else
   . = ALIGN(4096);
   __initramfs_start = .;
-  .init.ramfs : { *(.init.ramfs) }
+  .init.ramfs : {
+    *(.init.ramfs)
+  }
   __initramfs_end = .;
 
   . = ALIGN(4096);
@@ -152,21 +305,30 @@ SECTIONS
   _eextratext = .;
 
   __bss_start = .;
-  .bss       :
-  {
+#endif
+  .bss : {
+#ifdef CONFIG_PPC64
+    __bss_start = .;
+#else
    *(.sbss) *(.scommon)
    *(.dynbss)
+#endif
    *(.bss)
+#ifdef CONFIG_PPC32
    *(COMMON)
+#else
+  __bss_stop = .;
+#endif
   }
+#ifdef CONFIG_PPC32
   __bss_stop = .;
+#endif
 
+#ifdef CONFIG_PPC64
+  . = ALIGN(PAGE_SIZE);
+#endif
   _end = . ;
+#ifdef CONFIG_PPC32
   PROVIDE (end = .);
-
-  /* Sections to be discarded. */
-  /DISCARD/ : {
-    *(.exitcall.exit)
-    *(.exit.data)
-  }
+#endif
 }
diff --git a/arch/powerpc/platforms/iseries/lpevents.c b/arch/powerpc/platforms/iseries/lpevents.c
--- a/arch/powerpc/platforms/iseries/lpevents.c
+++ b/arch/powerpc/platforms/iseries/lpevents.c
@@ -13,6 +13,8 @@
 #include <linux/bootmem.h>
 #include <linux/seq_file.h>
 #include <linux/proc_fs.h>
+#include <linux/module.h>
+
 #include <asm/system.h>
 #include <asm/paca.h>
 #include <asm/iSeries/ItLpQueue.h>
diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile
--- a/arch/ppc64/kernel/Makefile
+++ b/arch/ppc64/kernel/Makefile
@@ -2,10 +2,10 @@
 # Makefile for the linux ppc64 kernel.
 #
 
-ifneq ($(CONFIG_PPC_MERGE),y)
-
 EXTRA_CFLAGS	+= -mno-minimal-toc
+ifneq ($(CONFIG_PPC_MERGE),y)
 extra-y		:= head.o vmlinux.lds
+endif
 
 obj-y               :=	setup.o entry.o irq.o idle.o dma.o \
 			time.o process.o signal.o syscalls.o misc.o ptrace.o \
@@ -70,11 +70,9 @@ obj-$(CONFIG_KPROBES)		+= kprobes.o
 
 CFLAGS_ioctl32.o += -Ifs/
 
+ifneq ($(CONFIG_PPC_MERGE),y)
 ifeq ($(CONFIG_PPC_ISERIES),y)
 arch/ppc64/kernel/head.o: arch/powerpc/platforms/iseries/lparmap.s
 AFLAGS_head.o += -Iarch/powerpc/platforms/iseries
 endif
-
-else
-
 endif
diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h
--- a/include/asm-powerpc/system.h
+++ b/include/asm-powerpc/system.h
@@ -118,10 +118,10 @@ extern void _set_L3CR(unsigned long);
 #endif
 
 extern void via_cuda_init(void);
-extern void pmac_nvram_init(void);
 extern void read_rtc_time(void);
 extern void pmac_find_display(void);
 extern void giveup_fpu(struct task_struct *);
+extern void disable_kernel_fp(void);
 extern void enable_kernel_fp(void);
 extern void flush_fp_to_thread(struct task_struct *);
 extern void enable_kernel_altivec(void);
@@ -346,5 +346,7 @@ __cmpxchg(volatile void *ptr, unsigned l
 
 #define arch_align_stack(x) (x)
 
+extern unsigned long reloc_offset(void);
+
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_SYSTEM_H */

^ permalink raw reply

* [PATCH 7/9] ppc64: simplify the build a little
From: Stephen Rothwell @ 2005-09-30 14:05 UTC (permalink / raw)
  To: paulus; +Cc: ppc64-dev, ppc-dev
In-Reply-To: <20050930233602.138b6e27.sfr@canb.auug.org.au>

This adds arch/powerp/kernel/ to core-y in arch/ppc64/Makefile so that we
don;t have to put in a special line in arch/ppc64/kernel/Makefile for each
file we merge.  We should be able to use a similar technique for other
directories as we get to them.

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

 arch/powerpc/Makefile        |    1 -
 arch/powerpc/kernel/Makefile |   13 +++++++++----
 arch/ppc64/Makefile          |    2 +-
 arch/ppc64/kernel/Makefile   |   11 ++---------
 4 files changed, 12 insertions(+), 15 deletions(-)

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

28163804fe2135701522671bd8c3828e1aa0ce62
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -121,7 +121,6 @@ head-$(CONFIG_FSL_BOOKE)	:= arch/powerpc
 
 ifeq ($(CONFIG_PPC32),y)
 head-$(CONFIG_6xx)		+= arch/powerpc/kernel/idle_6xx.o
-head-$(CONFIG_POWER4)		+= arch/powerpc/kernel/idle_power4.o
 head-$(CONFIG_PPC_FPU)		+= arch/powerpc/kernel/fpu.o
 endif
 
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -2,6 +2,10 @@
 # Makefile for the linux kernel.
 #
 
+ifeq ($(CONFIG_PPC64),y)
+EXTRA_CFLAGS	+= -mno-minimal-toc
+endif
+
 extra-$(CONFIG_PPC_STD_MMU)	:= head.o
 extra_$(CONFIG_PPC64)		:= head_64.o
 extra-$(CONFIG_40x)		:= head_4xx.o
@@ -9,12 +13,13 @@ extra-$(CONFIG_44x)		:= head_44x.o
 extra-$(CONFIG_FSL_BOOKE)	:= head_fsl_booke.o
 extra-$(CONFIG_8xx)		:= head_8xx.o
 extra-$(CONFIG_6xx)		+= idle_6xx.o
-extra-$(CONFIG_POWER4)		+= idle_power4.o
 extra-$(CONFIG_PPC_FPU)		+= fpu.o
 extra-y				+= vmlinux.lds
 
-obj-y				:= semaphore.o process.o
-obj-$(CONFIG_PPC32)		+= traps32.c
-obj-$(CONFIG_PPC64)		+= traps64.c
+obj-$(CONFIG_PPC32)		:= semaphore.o process.o
+obj-$(CONFIG_PPC32)		+= traps32.o
+obj-$(CONFIG_PPC64)		+= traps64.o idle_power4.o
+ifeq ($(CONFIG_PPC32),y)
 obj-$(CONFIG_MODULES)		+= ppc_ksyms.o
+endif
 obj-$(CONFIG_ALTIVEC)		+= vecemu.o vector.o
diff --git a/arch/ppc64/Makefile b/arch/ppc64/Makefile
--- a/arch/ppc64/Makefile
+++ b/arch/ppc64/Makefile
@@ -82,7 +82,7 @@ CFLAGS += $(call cc-option,-funit-at-a-t
 head-y := arch/ppc64/kernel/head.o
 
 libs-y				+= arch/ppc64/lib/
-core-y				+= arch/ppc64/kernel/
+core-y				+= arch/ppc64/kernel/ arch/powerpc/kernel/
 core-y				+= arch/ppc64/mm/
 core-y				+= arch/powerpc/platforms/
 core-$(CONFIG_XMON)		+= arch/ppc64/xmon/
diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile
--- a/arch/ppc64/kernel/Makefile
+++ b/arch/ppc64/kernel/Makefile
@@ -7,12 +7,12 @@ ifneq ($(CONFIG_PPC_MERGE),y)
 EXTRA_CFLAGS	+= -mno-minimal-toc
 extra-y		:= head.o vmlinux.lds
 
-obj-y               :=	setup.o entry.o traps64.o irq.o idle.o dma.o \
+obj-y               :=	setup.o entry.o irq.o idle.o dma.o \
 			time.o process.o signal.o syscalls.o misc.o ptrace.o \
 			align.o semaphore.o bitops.o pacaData.o \
 			udbg.o binfmt_elf32.o sys_ppc32.o ioctl32.o \
 			ptrace32.o signal32.o rtc.o init_task.o \
-			lmb.o cputable.o cpu_setup_power4.o idle_power4.o \
+			lmb.o cputable.o cpu_setup_power4.o \
 			iommu.o sysfs.o vdso.o pmc.o firmware.o prom.o
 obj-y += vdso32/ vdso64/
 
@@ -66,7 +66,6 @@ obj-$(CONFIG_PPC_BPA)		+= pSeries_smp.o
 obj-$(CONFIG_PPC_MAPLE)		+= smp-tbsync.o
 endif
 
-obj-$(CONFIG_ALTIVEC)		+= vecemu.o vector.o
 obj-$(CONFIG_KPROBES)		+= kprobes.o
 
 CFLAGS_ioctl32.o += -Ifs/
@@ -76,12 +75,6 @@ arch/ppc64/kernel/head.o: arch/powerpc/p
 AFLAGS_head.o += -Iarch/powerpc/platforms/iseries
 endif
 
-# These are here while we do the architecture merge
-vecemu-y			+= ../../powerpc/kernel/vecemu.o
-vector-y			+= ../../powerpc/kernel/vector.o
-idle_power4-y			+= ../../powerpc/kernel/idle_power4.o
-traps64-y			+= ../../powerpc/kernel/traps64.o
-
 else
 
 endif

^ permalink raw reply

* [PATCH 6/9] powerpc: merge idle_power4.S and fixup traps.c
From: Stephen Rothwell @ 2005-09-30 14:00 UTC (permalink / raw)
  To: paulus; +Cc: ppc64-dev, ppc-dev
In-Reply-To: <20050930233602.138b6e27.sfr@canb.auug.org.au>

Use idle_power4.S from ppc64 as we are not going to support
32 bit power4 in the merged tree.

create traps{32,64}.c as these are hard to merge.

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

 arch/powerpc/Kconfig              |    4 
 arch/powerpc/kernel/Makefile      |    4 
 arch/powerpc/kernel/idle_power4.S |   78 +++
 arch/powerpc/kernel/traps.c       | 1047 -------------------------------------
 arch/powerpc/kernel/traps32.c     | 1047 +++++++++++++++++++++++++++++++++++++
 arch/powerpc/kernel/traps64.c     |  568 ++++++++++++++++++++
 arch/ppc64/kernel/Makefile        |   10 
 arch/ppc64/kernel/idle_power4.S   |   79 ---
 arch/ppc64/kernel/traps.c         |  568 --------------------
 9 files changed, 1707 insertions(+), 1698 deletions(-)
 create mode 100644 arch/powerpc/kernel/idle_power4.S
 delete mode 100644 arch/powerpc/kernel/traps.c
 create mode 100644 arch/powerpc/kernel/traps32.c
 create mode 100644 arch/powerpc/kernel/traps64.c
 delete mode 100644 arch/ppc64/kernel/idle_power4.S
 delete mode 100644 arch/ppc64/kernel/traps.c

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

bbc83a78c1c417cc6bb44e5a1bdcd5a56e625bc5
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -142,8 +142,8 @@ config POWER4
 	def_bool y
 
 config PPC_FPU
-	bool
-	default y if PPC64
+	depends on PPC32
+	def_bool y
 
 config BOOKE
 	bool
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -13,6 +13,8 @@ extra-$(CONFIG_POWER4)		+= idle_power4.o
 extra-$(CONFIG_PPC_FPU)		+= fpu.o
 extra-y				+= vmlinux.lds
 
-obj-y				:= semaphore.o traps.o process.o
+obj-y				:= semaphore.o process.o
+obj-$(CONFIG_PPC32)		+= traps32.c
+obj-$(CONFIG_PPC64)		+= traps64.c
 obj-$(CONFIG_MODULES)		+= ppc_ksyms.o
 obj-$(CONFIG_ALTIVEC)		+= vecemu.o vector.o
diff --git a/arch/powerpc/kernel/idle_power4.S b/arch/powerpc/kernel/idle_power4.S
new file mode 100644
--- /dev/null
+++ b/arch/powerpc/kernel/idle_power4.S
@@ -0,0 +1,78 @@
+/*
+ *  This file contains the power_save function for 6xx & 7xxx CPUs
+ *  rewritten in assembler
+ *
+ *  Warning ! This code assumes that if your machine has a 750fx
+ *  it will have PLL 1 set to low speed mode (used during NAP/DOZE).
+ *  if this is not the case some additional changes will have to
+ *  be done to check a runtime var (a bit like powersave-nap)
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/threads.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/cputable.h>
+#include <asm/thread_info.h>
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+
+#undef DEBUG
+
+	.text
+
+/*
+ * Here is the power_save_6xx function. This could eventually be
+ * split into several functions & changing the function pointer
+ * depending on the various features.
+ */
+_GLOBAL(power4_idle)
+BEGIN_FTR_SECTION
+	blr
+END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP)
+	/* We must dynamically check for the NAP feature as it
+	 * can be cleared by CPU init after the fixups are done
+	 */
+	LOADBASE(r3,cur_cpu_spec)
+	ld	r4,cur_cpu_spec@l(r3)
+	ld	r4,CPU_SPEC_FEATURES(r4)
+	andi.	r0,r4,CPU_FTR_CAN_NAP
+	beqlr
+	/* Now check if user or arch enabled NAP mode */
+	LOADBASE(r3,powersave_nap)
+	lwz	r4,powersave_nap@l(r3)
+	cmpwi	0,r4,0
+	beqlr
+
+	/* Clear MSR:EE */
+	mfmsr	r7
+	li	r4,0
+	ori	r4,r4,MSR_EE
+	andc	r0,r7,r4
+	mtmsrd	r0
+
+	/* Check current_thread_info()->flags */
+	clrrdi	r4,r1,THREAD_SHIFT
+	ld	r4,TI_FLAGS(r4)
+	andi.	r0,r4,_TIF_NEED_RESCHED
+	beq	1f
+	mtmsrd	r7	/* out of line this ? */
+	blr
+1:
+	/* Go to NAP now */
+BEGIN_FTR_SECTION
+	DSSALL
+	sync
+END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+	oris	r7,r7,MSR_POW@h
+	sync
+	isync
+	mtmsrd	r7
+	isync
+	sync
+	blr
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
deleted file mode 100644
--- a/arch/powerpc/kernel/traps.c
+++ /dev/null
@@ -1,1047 +0,0 @@
-/*
- *  arch/powerpc/kernel/traps.c
- *
- *  Copyright (C) 1995-1996  Gary Thomas (gdt@linuxppc.org)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version
- *  2 of the License, or (at your option) any later version.
- *
- *  Modified by Cort Dougan (cort@cs.nmt.edu)
- *  and Paul Mackerras (paulus@samba.org)
- */
-
-/*
- * This file handles the architecture-dependent parts of hardware exceptions
- */
-
-#include <linux/config.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/stddef.h>
-#include <linux/unistd.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/user.h>
-#include <linux/a.out.h>
-#include <linux/interrupt.h>
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/prctl.h>
-#include <linux/delay.h>
-#include <linux/kprobes.h>
-#include <asm/kdebug.h>
-
-#include <asm/pgtable.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/reg.h>
-#include <asm/xmon.h>
-#ifdef CONFIG_PMAC_BACKLIGHT
-#include <asm/backlight.h>
-#endif
-#include <asm/perfmon.h>
-
-#ifdef CONFIG_DEBUGGER
-int (*__debugger)(struct pt_regs *regs);
-int (*__debugger_ipi)(struct pt_regs *regs);
-int (*__debugger_bpt)(struct pt_regs *regs);
-int (*__debugger_sstep)(struct pt_regs *regs);
-int (*__debugger_iabr_match)(struct pt_regs *regs);
-int (*__debugger_dabr_match)(struct pt_regs *regs);
-int (*__debugger_fault_handler)(struct pt_regs *regs);
-
-EXPORT_SYMBOL(__debugger);
-EXPORT_SYMBOL(__debugger_ipi);
-EXPORT_SYMBOL(__debugger_bpt);
-EXPORT_SYMBOL(__debugger_sstep);
-EXPORT_SYMBOL(__debugger_iabr_match);
-EXPORT_SYMBOL(__debugger_dabr_match);
-EXPORT_SYMBOL(__debugger_fault_handler);
-#endif
-
-struct notifier_block *powerpc_die_chain;
-static DEFINE_SPINLOCK(die_notifier_lock);
-
-int register_die_notifier(struct notifier_block *nb)
-{
-	int err = 0;
-	unsigned long flags;
-
-	spin_lock_irqsave(&die_notifier_lock, flags);
-	err = notifier_chain_register(&powerpc_die_chain, nb);
-	spin_unlock_irqrestore(&die_notifier_lock, flags);
-	return err;
-}
-
-/*
- * Trap & Exception support
- */
-
-static DEFINE_SPINLOCK(die_lock);
-
-int die(const char *str, struct pt_regs *regs, long err)
-{
-	static int die_counter;
-	int nl = 0;
-
-	if (debugger(regs))
-		return 1;
-
-	console_verbose();
-	spin_lock_irq(&die_lock);
-	bust_spinlocks(1);
-#ifdef CONFIG_PMAC_BACKLIGHT
-	if (_machine == _MACH_Pmac) {
-		set_backlight_enable(1);
-		set_backlight_level(BACKLIGHT_MAX);
-	}
-#endif
-	printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter);
-#ifdef CONFIG_PREEMPT
-	printk("PREEMPT ");
-	nl = 1;
-#endif
-#ifdef CONFIG_SMP
-	printk("SMP NR_CPUS=%d ", NR_CPUS);
-	nl = 1;
-#endif
-#ifdef CONFIG_DEBUG_PAGEALLOC
-	printk("DEBUG_PAGEALLOC ");
-	nl = 1;
-#endif
-#ifdef CONFIG_NUMA
-	printk("NUMA ");
-	nl = 1;
-#endif
-#ifdef CONFIG_PPC64
-	switch (systemcfg->platform) {
-	case PLATFORM_PSERIES:
-		printk("PSERIES ");
-		nl = 1;
-		break;
-	case PLATFORM_PSERIES_LPAR:
-		printk("PSERIES LPAR ");
-		nl = 1;
-		break;
-	case PLATFORM_ISERIES_LPAR:
-		printk("ISERIES LPAR ");
-		nl = 1;
-		break;
-	case PLATFORM_POWERMAC:
-		printk("POWERMAC ");
-		nl = 1;
-		break;
-	case PLATFORM_BPA:
-		printk("BPA ");
-		nl = 1;
-		break;
-	}
-#endif
-	if (nl)
-		printk("\n");
-	print_modules();
-	show_regs(regs);
-	bust_spinlocks(0);
-	spin_unlock_irq(&die_lock);
-
-	if (in_interrupt())
-		panic("Fatal exception in interrupt");
-
-	if (panic_on_oops) {
-		panic("Fatal exception");
-	}
-	do_exit(err);
-
-	return 0;
-}
-
-void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
-{
-	siginfo_t info;
-
-	if (!user_mode(regs)) {
-		if (die("Exception in kernel mode", regs, signr))
-			return;
-	}
-
-	memset(&info, 0, sizeof(info));
-	info.si_signo = signr;
-	info.si_code = code;
-	info.si_addr = (void __user *) addr;
-	force_sig_info(signr, &info, current);
-
-	/*
-	 * Init gets no signals that it doesn't have a handler for.
-	 * That's all very well, but if it has caused a synchronous
-	 * exception and we ignore the resulting signal, it will just
-	 * generate the same exception over and over again and we get
-	 * nowhere.  Better to kill it and let the kernel panic.
-	 */
-	if (current->pid == 1) {
-		__sighandler_t handler;
-
-		spin_lock_irq(&current->sighand->siglock);
-		handler = current->sighand->action[signr-1].sa.sa_handler;
-		spin_unlock_irq(&current->sighand->siglock);
-		if (handler == SIG_DFL) {
-			/* init has generated a synchronous exception
-			   and it doesn't have a handler for the signal */
-			printk(KERN_CRIT "init has generated signal %d "
-			       "but has no handler for it\n", signr);
-			do_exit(signr);
-		}
-	}
-}
-
-#ifdef CONFIG_PPC64
-void system_reset_exception(struct pt_regs *regs)
-{
-	/* See if any machine dependent calls */
-	if (ppc_md.system_reset_exception)
-		ppc_md.system_reset_exception(regs);
-
-	die("System Reset", regs, SIGABRT);
-
-	/* Must die if the interrupt is not recoverable */
-	if (!(regs->msr & MSR_RI))
-		panic("Unrecoverable System Reset");
-
-	/* What should we do here? We could issue a shutdown or hard reset. */
-}
-#endif
-
-/*
- * I/O accesses can cause machine checks on powermacs.
- * Check if the NIP corresponds to the address of a sync
- * instruction for which there is an entry in the exception
- * table.
- * Note that the 601 only takes a machine check on TEA
- * (transfer error ack) signal assertion, and does not
- * set any of the top 16 bits of SRR1.
- *  -- paulus.
- */
-static inline int check_io_access(struct pt_regs *regs)
-{
-#ifdef CONFIG_PPC_PMAC
-	unsigned long msr = regs->msr;
-	const struct exception_table_entry *entry;
-	unsigned int *nip = (unsigned int *)regs->nip;
-
-	if (((msr & 0xffff0000) == 0 || (msr & (0x80000 | 0x40000)))
-	    && (entry = search_exception_tables(regs->nip)) != NULL) {
-		/*
-		 * Check that it's a sync instruction, or somewhere
-		 * in the twi; isync; nop sequence that inb/inw/inl uses.
-		 * As the address is in the exception table
-		 * we should be able to read the instr there.
-		 * For the debug message, we look at the preceding
-		 * load or store.
-		 */
-		if (*nip == 0x60000000)		/* nop */
-			nip -= 2;
-		else if (*nip == 0x4c00012c)	/* isync */
-			--nip;
-		if (*nip == 0x7c0004ac || (*nip >> 26) == 3) {
-			/* sync or twi */
-			unsigned int rb;
-
-			--nip;
-			rb = (*nip >> 11) & 0x1f;
-			printk(KERN_DEBUG "%s bad port %lx at %p\n",
-			       (*nip & 0x100)? "OUT to": "IN from",
-			       regs->gpr[rb] - _IO_BASE, nip);
-			regs->msr |= MSR_RI;
-			regs->nip = entry->fixup;
-			return 1;
-		}
-	}
-#endif /* CONFIG_PPC_PMAC */
-	return 0;
-}
-
-#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
-/* On 4xx, the reason for the machine check or program exception
-   is in the ESR. */
-#define get_reason(regs)	((regs)->dsisr)
-#ifndef CONFIG_FSL_BOOKE
-#define get_mc_reason(regs)	((regs)->dsisr)
-#else
-#define get_mc_reason(regs)	(mfspr(SPRN_MCSR))
-#endif
-#define REASON_FP		ESR_FP
-#define REASON_ILLEGAL		(ESR_PIL | ESR_PUO)
-#define REASON_PRIVILEGED	ESR_PPR
-#define REASON_TRAP		ESR_PTR
-
-/* single-step stuff */
-#define single_stepping(regs)	(current->thread.dbcr0 & DBCR0_IC)
-#define clear_single_step(regs)	(current->thread.dbcr0 &= ~DBCR0_IC)
-
-#else
-/* On non-4xx, the reason for the machine check or program
-   exception is in the MSR. */
-#define get_reason(regs)	((regs)->msr)
-#define get_mc_reason(regs)	((regs)->msr)
-#define REASON_FP		0x100000
-#define REASON_ILLEGAL		0x80000
-#define REASON_PRIVILEGED	0x40000
-#define REASON_TRAP		0x20000
-
-#define single_stepping(regs)	((regs)->msr & MSR_SE)
-#define clear_single_step(regs)	((regs)->msr &= ~MSR_SE)
-#endif
-
-/*
- * This is "fall-back" implementation for configurations
- * which don't provide platform-specific machine check info
- */
-void __attribute__ ((weak))
-platform_machine_check(struct pt_regs *regs)
-{
-}
-
-void MachineCheckException(struct pt_regs *regs)
-{
-#ifdef CONFIG_PPC64
-	int recover = 0;
-
-	/* See if any machine dependent calls */
-	if (ppc_md.machine_check_exception)
-		recover = ppc_md.machine_check_exception(regs);
-
-	if (recover)
-		return;
-#else
-	unsigned long reason = get_mc_reason(regs);
-
-	if (user_mode(regs)) {
-		regs->msr |= MSR_RI;
-		_exception(SIGBUS, regs, BUS_ADRERR, regs->nip);
-		return;
-	}
-
-#if defined(CONFIG_8xx) && defined(CONFIG_PCI)
-	/* the qspan pci read routines can cause machine checks -- Cort */
-	bad_page_fault(regs, regs->dar, SIGBUS);
-	return;
-#endif
-
-	if (debugger_fault_handler(regs)) {
-		regs->msr |= MSR_RI;
-		return;
-	}
-
-	if (check_io_access(regs))
-		return;
-
-#if defined(CONFIG_4xx) && !defined(CONFIG_440A)
-	if (reason & ESR_IMCP) {
-		printk("Instruction");
-		mtspr(SPRN_ESR, reason & ~ESR_IMCP);
-	} else
-		printk("Data");
-	printk(" machine check in kernel mode.\n");
-#elif defined(CONFIG_440A)
-	printk("Machine check in kernel mode.\n");
-	if (reason & ESR_IMCP){
-		printk("Instruction Synchronous Machine Check exception\n");
-		mtspr(SPRN_ESR, reason & ~ESR_IMCP);
-	}
-	else {
-		u32 mcsr = mfspr(SPRN_MCSR);
-		if (mcsr & MCSR_IB)
-			printk("Instruction Read PLB Error\n");
-		if (mcsr & MCSR_DRB)
-			printk("Data Read PLB Error\n");
-		if (mcsr & MCSR_DWB)
-			printk("Data Write PLB Error\n");
-		if (mcsr & MCSR_TLBP)
-			printk("TLB Parity Error\n");
-		if (mcsr & MCSR_ICP){
-			flush_instruction_cache();
-			printk("I-Cache Parity Error\n");
-		}
-		if (mcsr & MCSR_DCSP)
-			printk("D-Cache Search Parity Error\n");
-		if (mcsr & MCSR_DCFP)
-			printk("D-Cache Flush Parity Error\n");
-		if (mcsr & MCSR_IMPE)
-			printk("Machine Check exception is imprecise\n");
-
-		/* Clear MCSR */
-		mtspr(SPRN_MCSR, mcsr);
-	}
-#elif defined (CONFIG_E500)
-	printk("Machine check in kernel mode.\n");
-	printk("Caused by (from MCSR=%lx): ", reason);
-
-	if (reason & MCSR_MCP)
-		printk("Machine Check Signal\n");
-	if (reason & MCSR_ICPERR)
-		printk("Instruction Cache Parity Error\n");
-	if (reason & MCSR_DCP_PERR)
-		printk("Data Cache Push Parity Error\n");
-	if (reason & MCSR_DCPERR)
-		printk("Data Cache Parity Error\n");
-	if (reason & MCSR_GL_CI)
-		printk("Guarded Load or Cache-Inhibited stwcx.\n");
-	if (reason & MCSR_BUS_IAERR)
-		printk("Bus - Instruction Address Error\n");
-	if (reason & MCSR_BUS_RAERR)
-		printk("Bus - Read Address Error\n");
-	if (reason & MCSR_BUS_WAERR)
-		printk("Bus - Write Address Error\n");
-	if (reason & MCSR_BUS_IBERR)
-		printk("Bus - Instruction Data Error\n");
-	if (reason & MCSR_BUS_RBERR)
-		printk("Bus - Read Data Bus Error\n");
-	if (reason & MCSR_BUS_WBERR)
-		printk("Bus - Read Data Bus Error\n");
-	if (reason & MCSR_BUS_IPERR)
-		printk("Bus - Instruction Parity Error\n");
-	if (reason & MCSR_BUS_RPERR)
-		printk("Bus - Read Parity Error\n");
-#elif defined (CONFIG_E200)
-	printk("Machine check in kernel mode.\n");
-	printk("Caused by (from MCSR=%lx): ", reason);
-
-	if (reason & MCSR_MCP)
-		printk("Machine Check Signal\n");
-	if (reason & MCSR_CP_PERR)
-		printk("Cache Push Parity Error\n");
-	if (reason & MCSR_CPERR)
-		printk("Cache Parity Error\n");
-	if (reason & MCSR_EXCP_ERR)
-		printk("ISI, ITLB, or Bus Error on first instruction fetch for an exception handler\n");
-	if (reason & MCSR_BUS_IRERR)
-		printk("Bus - Read Bus Error on instruction fetch\n");
-	if (reason & MCSR_BUS_DRERR)
-		printk("Bus - Read Bus Error on data load\n");
-	if (reason & MCSR_BUS_WRERR)
-		printk("Bus - Write Bus Error on buffered store or cache line push\n");
-#else /* !CONFIG_4xx && !CONFIG_E500 && !CONFIG_E200 */
-	printk("Machine check in kernel mode.\n");
-	printk("Caused by (from SRR1=%lx): ", reason);
-	switch (reason & 0x601F0000) {
-	case 0x80000:
-		printk("Machine check signal\n");
-		break;
-	case 0:		/* for 601 */
-	case 0x40000:
-	case 0x140000:	/* 7450 MSS error and TEA */
-		printk("Transfer error ack signal\n");
-		break;
-	case 0x20000:
-		printk("Data parity error signal\n");
-		break;
-	case 0x10000:
-		printk("Address parity error signal\n");
-		break;
-	case 0x20000000:
-		printk("L1 Data Cache error\n");
-		break;
-	case 0x40000000:
-		printk("L1 Instruction Cache error\n");
-		break;
-	case 0x00100000:
-		printk("L2 data cache parity error\n");
-		break;
-	default:
-		printk("Unknown values in msr\n");
-	}
-#endif /* CONFIG_4xx */
-
-	/*
-	 * Optional platform-provided routine to print out
-	 * additional info, e.g. bus error registers.
-	 */
-	platform_machine_check(regs);
-#endif /* CONFIG_PPC64 */
-
-	if (debugger_fault_handler(regs))
-		return;
-	die("Machine check", regs, SIGBUS);
-
-	/* Must die if the interrupt is not recoverable */
-	if (!(regs->msr & MSR_RI))
-		panic("Unrecoverable Machine check");
-}
-
-void SMIException(struct pt_regs *regs)
-{
-	die("System Management Interrupt", regs, SIGABRT);
-}
-
-void UnknownException(struct pt_regs *regs)
-{
-	printk("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
-	       regs->nip, regs->msr, regs->trap);
-
-	_exception(SIGTRAP, regs, 0, 0);
-}
-
-void InstructionBreakpoint(struct pt_regs *regs)
-{
-	if (notify_die(DIE_IABR_MATCH, "iabr_match", regs, 5,
-					5, SIGTRAP) == NOTIFY_STOP)
-		return;
-	if (debugger_iabr_match(regs))
-		return;
-	_exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
-}
-
-void RunModeException(struct pt_regs *regs)
-{
-	_exception(SIGTRAP, regs, 0, 0);
-}
-
-void SingleStepException(struct pt_regs *regs)
-{
-	regs->msr &= ~(MSR_SE | MSR_BE);  /* Turn off 'trace' bits */
-
-	if (notify_die(DIE_SSTEP, "single_step", regs, 5,
-					5, SIGTRAP) == NOTIFY_STOP)
-		return;
-	if (debugger_sstep(regs))
-		return;
-
-	_exception(SIGTRAP, regs, TRAP_TRACE, regs->nip);
-}
-
-/*
- * After we have successfully emulated an instruction, we have to
- * check if the instruction was being single-stepped, and if so,
- * pretend we got a single-step exception.  This was pointed out
- * by Kumar Gala.  -- paulus
- */
-static void emulate_single_step(struct pt_regs *regs)
-{
-	if (single_stepping(regs)) {
-		clear_single_step(regs);
-		_exception(SIGTRAP, regs, TRAP_TRACE, 0);
-	}
-}
-
-/* Illegal instruction emulation support.  Originally written to
- * provide the PVR to user applications using the mfspr rd, PVR.
- * Return non-zero if we can't emulate, or -EFAULT if the associated
- * memory access caused an access fault.  Return zero on success.
- *
- * There are a couple of ways to do this, either "decode" the instruction
- * or directly match lots of bits.  In this case, matching lots of
- * bits is faster and easier.
- *
- */
-#define INST_MFSPR_PVR		0x7c1f42a6
-#define INST_MFSPR_PVR_MASK	0xfc1fffff
-
-#define INST_DCBA		0x7c0005ec
-#define INST_DCBA_MASK		0x7c0007fe
-
-#define INST_MCRXR		0x7c000400
-#define INST_MCRXR_MASK		0x7c0007fe
-
-#define INST_STRING		0x7c00042a
-#define INST_STRING_MASK	0x7c0007fe
-#define INST_STRING_GEN_MASK	0x7c00067e
-#define INST_LSWI		0x7c0004aa
-#define INST_LSWX		0x7c00042a
-#define INST_STSWI		0x7c0005aa
-#define INST_STSWX		0x7c00052a
-
-static int emulate_string_inst(struct pt_regs *regs, u32 instword)
-{
-	u8 rT = (instword >> 21) & 0x1f;
-	u8 rA = (instword >> 16) & 0x1f;
-	u8 NB_RB = (instword >> 11) & 0x1f;
-	u32 num_bytes;
-	unsigned long EA;
-	int pos = 0;
-
-	/* Early out if we are an invalid form of lswx */
-	if ((instword & INST_STRING_MASK) == INST_LSWX)
-		if ((rT == rA) || (rT == NB_RB))
-			return -EINVAL;
-
-	EA = (rA == 0) ? 0 : regs->gpr[rA];
-
-	switch (instword & INST_STRING_MASK) {
-		case INST_LSWX:
-		case INST_STSWX:
-			EA += NB_RB;
-			num_bytes = regs->xer & 0x7f;
-			break;
-		case INST_LSWI:
-		case INST_STSWI:
-			num_bytes = (NB_RB == 0) ? 32 : NB_RB;
-			break;
-		default:
-			return -EINVAL;
-	}
-
-	while (num_bytes != 0)
-	{
-		u8 val;
-		u32 shift = 8 * (3 - (pos & 0x3));
-
-		switch ((instword & INST_STRING_MASK)) {
-			case INST_LSWX:
-			case INST_LSWI:
-				if (get_user(val, (u8 __user *)EA))
-					return -EFAULT;
-				/* first time updating this reg,
-				 * zero it out */
-				if (pos == 0)
-					regs->gpr[rT] = 0;
-				regs->gpr[rT] |= val << shift;
-				break;
-			case INST_STSWI:
-			case INST_STSWX:
-				val = regs->gpr[rT] >> shift;
-				if (put_user(val, (u8 __user *)EA))
-					return -EFAULT;
-				break;
-		}
-		/* move EA to next address */
-		EA += 1;
-		num_bytes--;
-
-		/* manage our position within the register */
-		if (++pos == 4) {
-			pos = 0;
-			if (++rT == 32)
-				rT = 0;
-		}
-	}
-
-	return 0;
-}
-
-static int emulate_instruction(struct pt_regs *regs)
-{
-	u32 instword;
-	u32 rd;
-
-	if (!user_mode(regs))
-		return -EINVAL;
-	CHECK_FULL_REGS(regs);
-
-	if (get_user(instword, (u32 __user *)(regs->nip)))
-		return -EFAULT;
-
-	/* Emulate the mfspr rD, PVR. */
-	if ((instword & INST_MFSPR_PVR_MASK) == INST_MFSPR_PVR) {
-		rd = (instword >> 21) & 0x1f;
-		regs->gpr[rd] = mfspr(SPRN_PVR);
-		return 0;
-	}
-
-	/* Emulating the dcba insn is just a no-op.  */
-	if ((instword & INST_DCBA_MASK) == INST_DCBA)
-		return 0;
-
-	/* Emulate the mcrxr insn.  */
-	if ((instword & INST_MCRXR_MASK) == INST_MCRXR) {
-		int shift = (instword >> 21) & 0x1c;
-		unsigned long msk = 0xf0000000UL >> shift;
-
-		regs->ccr = (regs->ccr & ~msk) | ((regs->xer >> shift) & msk);
-		regs->xer &= ~0xf0000000UL;
-		return 0;
-	}
-
-	/* Emulate load/store string insn. */
-	if ((instword & INST_STRING_GEN_MASK) == INST_STRING)
-		return emulate_string_inst(regs, instword);
-
-	return -EINVAL;
-}
-
-/*
- * Look through the list of trap instructions that are used for BUG(),
- * BUG_ON() and WARN_ON() and see if we hit one.  At this point we know
- * that the exception was caused by a trap instruction of some kind.
- * Returns 1 if we should continue (i.e. it was a WARN_ON) or 0
- * otherwise.
- */
-extern struct bug_entry __start___bug_table[], __stop___bug_table[];
-
-#ifndef CONFIG_MODULES
-#define module_find_bug(x)	NULL
-#endif
-
-struct bug_entry *find_bug(unsigned long bugaddr)
-{
-	struct bug_entry *bug;
-
-	for (bug = __start___bug_table; bug < __stop___bug_table; ++bug)
-		if (bugaddr == bug->bug_addr)
-			return bug;
-	return module_find_bug(bugaddr);
-}
-
-int check_bug_trap(struct pt_regs *regs)
-{
-	struct bug_entry *bug;
-	unsigned long addr;
-
-	if (regs->msr & MSR_PR)
-		return 0;	/* not in kernel */
-	addr = regs->nip;	/* address of trap instruction */
-	if (addr < PAGE_OFFSET)
-		return 0;
-	bug = find_bug(regs->nip);
-	if (bug == NULL)
-		return 0;
-	if (bug->line & BUG_WARNING_TRAP) {
-		/* this is a WARN_ON rather than BUG/BUG_ON */
-#ifdef CONFIG_XMON
-		xmon_printf(KERN_ERR "Badness in %s at %s:%d\n",
-		       bug->function, bug->file,
-		       bug->line & ~BUG_WARNING_TRAP);
-#endif /* CONFIG_XMON */		
-		printk(KERN_ERR "Badness in %s at %s:%d\n",
-		       bug->function, bug->file,
-		       bug->line & ~BUG_WARNING_TRAP);
-		dump_stack();
-		return 1;
-	}
-#ifdef CONFIG_XMON
-	xmon_printf(KERN_CRIT "kernel BUG in %s at %s:%d!\n",
-	       bug->function, bug->file, bug->line);
-	xmon(regs);
-#endif /* CONFIG_XMON */
-	printk(KERN_CRIT "kernel BUG in %s at %s:%d!\n",
-	       bug->function, bug->file, bug->line);
-
-	return 0;
-}
-
-void ProgramCheckException(struct pt_regs *regs)
-{
-	unsigned int reason = get_reason(regs);
-	extern int do_mathemu(struct pt_regs *regs);
-
-#ifdef CONFIG_MATH_EMULATION
-	/* (reason & REASON_ILLEGAL) would be the obvious thing here,
-	 * but there seems to be a hardware bug on the 405GP (RevD)
-	 * that means ESR is sometimes set incorrectly - either to
-	 * ESR_DST (!?) or 0.  In the process of chasing this with the
-	 * hardware people - not sure if it can happen on any illegal
-	 * instruction or only on FP instructions, whether there is a
-	 * pattern to occurences etc. -dgibson 31/Mar/2003 */
-	if (!(reason & REASON_TRAP) && do_mathemu(regs) == 0) {
-		emulate_single_step(regs);
-		return;
-	}
-#endif /* CONFIG_MATH_EMULATION */
-
-	if (reason & REASON_FP) {
-		/* IEEE FP exception */
-		int code = 0;
-		u32 fpscr;
-
-		/* We must make sure the FP state is consistent with
-		 * our MSR_FP in regs
-		 */
-		preempt_disable();
-		if (regs->msr & MSR_FP)
-			giveup_fpu(current);
-		preempt_enable();
-
-		fpscr = current->thread.fpscr;
-		fpscr &= fpscr << 22;	/* mask summary bits with enables */
-		if (fpscr & FPSCR_VX)
-			code = FPE_FLTINV;
-		else if (fpscr & FPSCR_OX)
-			code = FPE_FLTOVF;
-		else if (fpscr & FPSCR_UX)
-			code = FPE_FLTUND;
-		else if (fpscr & FPSCR_ZX)
-			code = FPE_FLTDIV;
-		else if (fpscr & FPSCR_XX)
-			code = FPE_FLTRES;
-		_exception(SIGFPE, regs, code, regs->nip);
-		return;
-	}
-
-	if (reason & REASON_TRAP) {
-		/* trap exception */
-		if (debugger_bpt(regs))
-			return;
-		if (check_bug_trap(regs)) {
-			regs->nip += 4;
-			return;
-		}
-		_exception(SIGTRAP, regs, TRAP_BRKPT, 0);
-		return;
-	}
-
-	/* Try to emulate it if we should. */
-	if (reason & (REASON_ILLEGAL | REASON_PRIVILEGED)) {
-		switch (emulate_instruction(regs)) {
-		case 0:
-			regs->nip += 4;
-			emulate_single_step(regs);
-			return;
-		case -EFAULT:
-			_exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip);
-			return;
-		}
-	}
-
-	if (reason & REASON_PRIVILEGED)
-		_exception(SIGILL, regs, ILL_PRVOPC, regs->nip);
-	else
-		_exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
-}
-
-void AlignmentException(struct pt_regs *regs)
-{
-	int fixed;
-
-	fixed = fix_alignment(regs);
-
-	if (fixed == 1) {
-		regs->nip += 4;	/* skip over emulated instruction */
-		emulate_single_step(regs);
-		return;
-	}
-
-	/* Operand address was bad */	
-	if (fixed == -EFAULT) {
-		if (user_mode(regs))
-			_exception(SIGSEGV, regs, SEGV_ACCERR, regs->dar);
-		else
-			/* Search exception table */
-			bad_page_fault(regs, regs->dar, SIGSEGV);
-		return;
-	}
-	_exception(SIGBUS, regs, BUS_ADRALN, regs->dar);
-}
-
-void StackOverflow(struct pt_regs *regs)
-{
-	printk(KERN_CRIT "Kernel stack overflow in process %p, r1=%lx\n",
-	       current, regs->gpr[1]);
-	debugger(regs);
-	show_regs(regs);
-	panic("kernel stack overflow");
-}
-
-void nonrecoverable_exception(struct pt_regs *regs)
-{
-	printk(KERN_ERR "Non-recoverable exception at PC=%lx MSR=%lx\n",
-	       regs->nip, regs->msr);
-	debugger(regs);
-	die("nonrecoverable exception", regs, SIGKILL);
-}
-
-void trace_syscall(struct pt_regs *regs)
-{
-	printk("Task: %p(%d), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld    %s\n",
-	       current, current->pid, regs->nip, regs->link, regs->gpr[0],
-	       regs->ccr&0x10000000?"Error=":"", regs->gpr[3], print_tainted());
-}
-
-#ifdef CONFIG_8xx
-void SoftwareEmulation(struct pt_regs *regs)
-{
-	extern int do_mathemu(struct pt_regs *);
-	extern int Soft_emulate_8xx(struct pt_regs *);
-	int errcode;
-
-	CHECK_FULL_REGS(regs);
-
-	if (!user_mode(regs)) {
-		debugger(regs);
-		die("Kernel Mode Software FPU Emulation", regs, SIGFPE);
-	}
-
-#ifdef CONFIG_MATH_EMULATION
-	errcode = do_mathemu(regs);
-#else
-	errcode = Soft_emulate_8xx(regs);
-#endif
-	if (errcode) {
-		if (errcode > 0)
-			_exception(SIGFPE, regs, 0, 0);
-		else if (errcode == -EFAULT)
-			_exception(SIGSEGV, regs, 0, 0);
-		else
-			_exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
-	} else
-		emulate_single_step(regs);
-}
-#endif /* CONFIG_8xx */
-
-#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
-
-void DebugException(struct pt_regs *regs, unsigned long debug_status)
-{
-	if (debug_status & DBSR_IC) {	/* instruction completion */
-		regs->msr &= ~MSR_DE;
-		if (user_mode(regs)) {
-			current->thread.dbcr0 &= ~DBCR0_IC;
-		} else {
-			/* Disable instruction completion */
-			mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) & ~DBCR0_IC);
-			/* Clear the instruction completion event */
-			mtspr(SPRN_DBSR, DBSR_IC);
-			if (debugger_sstep(regs))
-				return;
-		}
-		_exception(SIGTRAP, regs, TRAP_TRACE, 0);
-	}
-}
-#endif /* CONFIG_4xx || CONFIG_BOOKE */
-
-#if !defined(CONFIG_TAU_INT)
-void TAUException(struct pt_regs *regs)
-{
-	printk("TAU trap at PC: %lx, MSR: %lx, vector=%lx    %s\n",
-	       regs->nip, regs->msr, regs->trap, print_tainted());
-}
-#endif /* CONFIG_INT_TAU */
-
-void AltivecUnavailException(struct pt_regs *regs)
-{
-	static int kernel_altivec_count;
-
-#ifndef CONFIG_ALTIVEC
-	if (user_mode(regs)) {
-		/* A user program has executed an altivec instruction,
-		   but this kernel doesn't support altivec. */
-		_exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
-		return;
-	}
-#endif
-	/* The kernel has executed an altivec instruction without
-	   first enabling altivec.  Whinge but let it do it. */
-	if (++kernel_altivec_count < 10)
-		printk(KERN_ERR "AltiVec used in kernel (task=%p, pc=%lx)\n",
-		       current, regs->nip);
-	regs->msr |= MSR_VEC;
-}
-
-#ifdef CONFIG_ALTIVEC
-void AltivecAssistException(struct pt_regs *regs)
-{
-	int err;
-
-	preempt_disable();
-	if (regs->msr & MSR_VEC)
-		giveup_altivec(current);
-	preempt_enable();
-	if (!user_mode(regs)) {
-		printk(KERN_EMERG "VMX/Altivec assist exception in kernel mode"
-		       " at %lx\n", regs->nip);
-		die("Kernel Altivec assist exception", regs, SIGILL);
-	}
-
-	err = emulate_altivec(regs);
-	if (err == 0) {
-		regs->nip += 4;		/* skip emulated instruction */
-		emulate_single_step(regs);
-		return;
-	}
-
-	if (err == -EFAULT) {
-		/* got an error reading the instruction */
-		_exception(SIGSEGV, regs, SEGV_ACCERR, regs->nip);
-	} else {
-		/* didn't recognize the instruction */
-		/* XXX quick hack for now: set the non-Java bit in the VSCR */
-		if (printk_ratelimit())
-			printk(KERN_ERR "Unrecognized altivec instruction "
-			       "in %s at %lx\n", current->comm, regs->nip);
-		current->thread.vscr.u[3] |= 0x10000;
-	}
-}
-#endif /* CONFIG_ALTIVEC */
-
-#ifdef CONFIG_E500
-void PerformanceMonitorException(struct pt_regs *regs)
-{
-	perf_irq(regs);
-}
-#endif
-
-#ifdef CONFIG_FSL_BOOKE
-void CacheLockingException(struct pt_regs *regs, unsigned long address,
-			   unsigned long error_code)
-{
-	/* We treat cache locking instructions from the user
-	 * as priv ops, in the future we could try to do
-	 * something smarter
-	 */
-	if (error_code & (ESR_DLK|ESR_ILK))
-		_exception(SIGILL, regs, ILL_PRVOPC, regs->nip);
-	return;
-}
-#endif /* CONFIG_FSL_BOOKE */
-
-#ifdef CONFIG_SPE
-void SPEFloatingPointException(struct pt_regs *regs)
-{
-	unsigned long spefscr;
-	int fpexc_mode;
-	int code = 0;
-
-	spefscr = current->thread.spefscr;
-	fpexc_mode = current->thread.fpexc_mode;
-
-	/* Hardware does not neccessarily set sticky
-	 * underflow/overflow/invalid flags */
-	if ((spefscr & SPEFSCR_FOVF) && (fpexc_mode & PR_FP_EXC_OVF)) {
-		code = FPE_FLTOVF;
-		spefscr |= SPEFSCR_FOVFS;
-	}
-	else if ((spefscr & SPEFSCR_FUNF) && (fpexc_mode & PR_FP_EXC_UND)) {
-		code = FPE_FLTUND;
-		spefscr |= SPEFSCR_FUNFS;
-	}
-	else if ((spefscr & SPEFSCR_FDBZ) && (fpexc_mode & PR_FP_EXC_DIV))
-		code = FPE_FLTDIV;
-	else if ((spefscr & SPEFSCR_FINV) && (fpexc_mode & PR_FP_EXC_INV)) {
-		code = FPE_FLTINV;
-		spefscr |= SPEFSCR_FINVS;
-	}
-	else if ((spefscr & (SPEFSCR_FG | SPEFSCR_FX)) && (fpexc_mode & PR_FP_EXC_RES))
-		code = FPE_FLTRES;
-
-	current->thread.spefscr = spefscr;
-
-	_exception(SIGFPE, regs, code, regs->nip);
-	return;
-}
-#endif
-
-#ifdef CONFIG_BOOKE_WDT
-/*
- * Default handler for a Watchdog exception,
- * spins until a reboot occurs
- */
-void __attribute__ ((weak)) WatchdogHandler(struct pt_regs *regs)
-{
-	/* Generic WatchdogHandler, implement your own */
-	mtspr(SPRN_TCR, mfspr(SPRN_TCR)&(~TCR_WIE));
-	return;
-}
-
-void WatchdogException(struct pt_regs *regs)
-{
-	printk (KERN_EMERG "PowerPC Book-E Watchdog Exception\n");
-	WatchdogHandler(regs);
-}
-#endif
-
-void __init trap_init(void)
-{
-}
diff --git a/arch/powerpc/kernel/traps32.c b/arch/powerpc/kernel/traps32.c
new file mode 100644
--- /dev/null
+++ b/arch/powerpc/kernel/traps32.c
@@ -0,0 +1,1047 @@
+/*
+ *  arch/powerpc/kernel/traps.c
+ *
+ *  Copyright (C) 1995-1996  Gary Thomas (gdt@linuxppc.org)
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ *
+ *  Modified by Cort Dougan (cort@cs.nmt.edu)
+ *  and Paul Mackerras (paulus@samba.org)
+ */
+
+/*
+ * This file handles the architecture-dependent parts of hardware exceptions
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/interrupt.h>
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/prctl.h>
+#include <linux/delay.h>
+#include <linux/kprobes.h>
+#include <asm/kdebug.h>
+
+#include <asm/pgtable.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/reg.h>
+#include <asm/xmon.h>
+#ifdef CONFIG_PMAC_BACKLIGHT
+#include <asm/backlight.h>
+#endif
+#include <asm/perfmon.h>
+
+#ifdef CONFIG_DEBUGGER
+int (*__debugger)(struct pt_regs *regs);
+int (*__debugger_ipi)(struct pt_regs *regs);
+int (*__debugger_bpt)(struct pt_regs *regs);
+int (*__debugger_sstep)(struct pt_regs *regs);
+int (*__debugger_iabr_match)(struct pt_regs *regs);
+int (*__debugger_dabr_match)(struct pt_regs *regs);
+int (*__debugger_fault_handler)(struct pt_regs *regs);
+
+EXPORT_SYMBOL(__debugger);
+EXPORT_SYMBOL(__debugger_ipi);
+EXPORT_SYMBOL(__debugger_bpt);
+EXPORT_SYMBOL(__debugger_sstep);
+EXPORT_SYMBOL(__debugger_iabr_match);
+EXPORT_SYMBOL(__debugger_dabr_match);
+EXPORT_SYMBOL(__debugger_fault_handler);
+#endif
+
+struct notifier_block *powerpc_die_chain;
+static DEFINE_SPINLOCK(die_notifier_lock);
+
+int register_die_notifier(struct notifier_block *nb)
+{
+	int err = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&die_notifier_lock, flags);
+	err = notifier_chain_register(&powerpc_die_chain, nb);
+	spin_unlock_irqrestore(&die_notifier_lock, flags);
+	return err;
+}
+
+/*
+ * Trap & Exception support
+ */
+
+static DEFINE_SPINLOCK(die_lock);
+
+int die(const char *str, struct pt_regs *regs, long err)
+{
+	static int die_counter;
+	int nl = 0;
+
+	if (debugger(regs))
+		return 1;
+
+	console_verbose();
+	spin_lock_irq(&die_lock);
+	bust_spinlocks(1);
+#ifdef CONFIG_PMAC_BACKLIGHT
+	if (_machine == _MACH_Pmac) {
+		set_backlight_enable(1);
+		set_backlight_level(BACKLIGHT_MAX);
+	}
+#endif
+	printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter);
+#ifdef CONFIG_PREEMPT
+	printk("PREEMPT ");
+	nl = 1;
+#endif
+#ifdef CONFIG_SMP
+	printk("SMP NR_CPUS=%d ", NR_CPUS);
+	nl = 1;
+#endif
+#ifdef CONFIG_DEBUG_PAGEALLOC
+	printk("DEBUG_PAGEALLOC ");
+	nl = 1;
+#endif
+#ifdef CONFIG_NUMA
+	printk("NUMA ");
+	nl = 1;
+#endif
+#ifdef CONFIG_PPC64
+	switch (systemcfg->platform) {
+	case PLATFORM_PSERIES:
+		printk("PSERIES ");
+		nl = 1;
+		break;
+	case PLATFORM_PSERIES_LPAR:
+		printk("PSERIES LPAR ");
+		nl = 1;
+		break;
+	case PLATFORM_ISERIES_LPAR:
+		printk("ISERIES LPAR ");
+		nl = 1;
+		break;
+	case PLATFORM_POWERMAC:
+		printk("POWERMAC ");
+		nl = 1;
+		break;
+	case PLATFORM_BPA:
+		printk("BPA ");
+		nl = 1;
+		break;
+	}
+#endif
+	if (nl)
+		printk("\n");
+	print_modules();
+	show_regs(regs);
+	bust_spinlocks(0);
+	spin_unlock_irq(&die_lock);
+
+	if (in_interrupt())
+		panic("Fatal exception in interrupt");
+
+	if (panic_on_oops) {
+		panic("Fatal exception");
+	}
+	do_exit(err);
+
+	return 0;
+}
+
+void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
+{
+	siginfo_t info;
+
+	if (!user_mode(regs)) {
+		if (die("Exception in kernel mode", regs, signr))
+			return;
+	}
+
+	memset(&info, 0, sizeof(info));
+	info.si_signo = signr;
+	info.si_code = code;
+	info.si_addr = (void __user *) addr;
+	force_sig_info(signr, &info, current);
+
+	/*
+	 * Init gets no signals that it doesn't have a handler for.
+	 * That's all very well, but if it has caused a synchronous
+	 * exception and we ignore the resulting signal, it will just
+	 * generate the same exception over and over again and we get
+	 * nowhere.  Better to kill it and let the kernel panic.
+	 */
+	if (current->pid == 1) {
+		__sighandler_t handler;
+
+		spin_lock_irq(&current->sighand->siglock);
+		handler = current->sighand->action[signr-1].sa.sa_handler;
+		spin_unlock_irq(&current->sighand->siglock);
+		if (handler == SIG_DFL) {
+			/* init has generated a synchronous exception
+			   and it doesn't have a handler for the signal */
+			printk(KERN_CRIT "init has generated signal %d "
+			       "but has no handler for it\n", signr);
+			do_exit(signr);
+		}
+	}
+}
+
+#ifdef CONFIG_PPC64
+void system_reset_exception(struct pt_regs *regs)
+{
+	/* See if any machine dependent calls */
+	if (ppc_md.system_reset_exception)
+		ppc_md.system_reset_exception(regs);
+
+	die("System Reset", regs, SIGABRT);
+
+	/* Must die if the interrupt is not recoverable */
+	if (!(regs->msr & MSR_RI))
+		panic("Unrecoverable System Reset");
+
+	/* What should we do here? We could issue a shutdown or hard reset. */
+}
+#endif
+
+/*
+ * I/O accesses can cause machine checks on powermacs.
+ * Check if the NIP corresponds to the address of a sync
+ * instruction for which there is an entry in the exception
+ * table.
+ * Note that the 601 only takes a machine check on TEA
+ * (transfer error ack) signal assertion, and does not
+ * set any of the top 16 bits of SRR1.
+ *  -- paulus.
+ */
+static inline int check_io_access(struct pt_regs *regs)
+{
+#ifdef CONFIG_PPC_PMAC
+	unsigned long msr = regs->msr;
+	const struct exception_table_entry *entry;
+	unsigned int *nip = (unsigned int *)regs->nip;
+
+	if (((msr & 0xffff0000) == 0 || (msr & (0x80000 | 0x40000)))
+	    && (entry = search_exception_tables(regs->nip)) != NULL) {
+		/*
+		 * Check that it's a sync instruction, or somewhere
+		 * in the twi; isync; nop sequence that inb/inw/inl uses.
+		 * As the address is in the exception table
+		 * we should be able to read the instr there.
+		 * For the debug message, we look at the preceding
+		 * load or store.
+		 */
+		if (*nip == 0x60000000)		/* nop */
+			nip -= 2;
+		else if (*nip == 0x4c00012c)	/* isync */
+			--nip;
+		if (*nip == 0x7c0004ac || (*nip >> 26) == 3) {
+			/* sync or twi */
+			unsigned int rb;
+
+			--nip;
+			rb = (*nip >> 11) & 0x1f;
+			printk(KERN_DEBUG "%s bad port %lx at %p\n",
+			       (*nip & 0x100)? "OUT to": "IN from",
+			       regs->gpr[rb] - _IO_BASE, nip);
+			regs->msr |= MSR_RI;
+			regs->nip = entry->fixup;
+			return 1;
+		}
+	}
+#endif /* CONFIG_PPC_PMAC */
+	return 0;
+}
+
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+/* On 4xx, the reason for the machine check or program exception
+   is in the ESR. */
+#define get_reason(regs)	((regs)->dsisr)
+#ifndef CONFIG_FSL_BOOKE
+#define get_mc_reason(regs)	((regs)->dsisr)
+#else
+#define get_mc_reason(regs)	(mfspr(SPRN_MCSR))
+#endif
+#define REASON_FP		ESR_FP
+#define REASON_ILLEGAL		(ESR_PIL | ESR_PUO)
+#define REASON_PRIVILEGED	ESR_PPR
+#define REASON_TRAP		ESR_PTR
+
+/* single-step stuff */
+#define single_stepping(regs)	(current->thread.dbcr0 & DBCR0_IC)
+#define clear_single_step(regs)	(current->thread.dbcr0 &= ~DBCR0_IC)
+
+#else
+/* On non-4xx, the reason for the machine check or program
+   exception is in the MSR. */
+#define get_reason(regs)	((regs)->msr)
+#define get_mc_reason(regs)	((regs)->msr)
+#define REASON_FP		0x100000
+#define REASON_ILLEGAL		0x80000
+#define REASON_PRIVILEGED	0x40000
+#define REASON_TRAP		0x20000
+
+#define single_stepping(regs)	((regs)->msr & MSR_SE)
+#define clear_single_step(regs)	((regs)->msr &= ~MSR_SE)
+#endif
+
+/*
+ * This is "fall-back" implementation for configurations
+ * which don't provide platform-specific machine check info
+ */
+void __attribute__ ((weak))
+platform_machine_check(struct pt_regs *regs)
+{
+}
+
+void MachineCheckException(struct pt_regs *regs)
+{
+#ifdef CONFIG_PPC64
+	int recover = 0;
+
+	/* See if any machine dependent calls */
+	if (ppc_md.machine_check_exception)
+		recover = ppc_md.machine_check_exception(regs);
+
+	if (recover)
+		return;
+#else
+	unsigned long reason = get_mc_reason(regs);
+
+	if (user_mode(regs)) {
+		regs->msr |= MSR_RI;
+		_exception(SIGBUS, regs, BUS_ADRERR, regs->nip);
+		return;
+	}
+
+#if defined(CONFIG_8xx) && defined(CONFIG_PCI)
+	/* the qspan pci read routines can cause machine checks -- Cort */
+	bad_page_fault(regs, regs->dar, SIGBUS);
+	return;
+#endif
+
+	if (debugger_fault_handler(regs)) {
+		regs->msr |= MSR_RI;
+		return;
+	}
+
+	if (check_io_access(regs))
+		return;
+
+#if defined(CONFIG_4xx) && !defined(CONFIG_440A)
+	if (reason & ESR_IMCP) {
+		printk("Instruction");
+		mtspr(SPRN_ESR, reason & ~ESR_IMCP);
+	} else
+		printk("Data");
+	printk(" machine check in kernel mode.\n");
+#elif defined(CONFIG_440A)
+	printk("Machine check in kernel mode.\n");
+	if (reason & ESR_IMCP){
+		printk("Instruction Synchronous Machine Check exception\n");
+		mtspr(SPRN_ESR, reason & ~ESR_IMCP);
+	}
+	else {
+		u32 mcsr = mfspr(SPRN_MCSR);
+		if (mcsr & MCSR_IB)
+			printk("Instruction Read PLB Error\n");
+		if (mcsr & MCSR_DRB)
+			printk("Data Read PLB Error\n");
+		if (mcsr & MCSR_DWB)
+			printk("Data Write PLB Error\n");
+		if (mcsr & MCSR_TLBP)
+			printk("TLB Parity Error\n");
+		if (mcsr & MCSR_ICP){
+			flush_instruction_cache();
+			printk("I-Cache Parity Error\n");
+		}
+		if (mcsr & MCSR_DCSP)
+			printk("D-Cache Search Parity Error\n");
+		if (mcsr & MCSR_DCFP)
+			printk("D-Cache Flush Parity Error\n");
+		if (mcsr & MCSR_IMPE)
+			printk("Machine Check exception is imprecise\n");
+
+		/* Clear MCSR */
+		mtspr(SPRN_MCSR, mcsr);
+	}
+#elif defined (CONFIG_E500)
+	printk("Machine check in kernel mode.\n");
+	printk("Caused by (from MCSR=%lx): ", reason);
+
+	if (reason & MCSR_MCP)
+		printk("Machine Check Signal\n");
+	if (reason & MCSR_ICPERR)
+		printk("Instruction Cache Parity Error\n");
+	if (reason & MCSR_DCP_PERR)
+		printk("Data Cache Push Parity Error\n");
+	if (reason & MCSR_DCPERR)
+		printk("Data Cache Parity Error\n");
+	if (reason & MCSR_GL_CI)
+		printk("Guarded Load or Cache-Inhibited stwcx.\n");
+	if (reason & MCSR_BUS_IAERR)
+		printk("Bus - Instruction Address Error\n");
+	if (reason & MCSR_BUS_RAERR)
+		printk("Bus - Read Address Error\n");
+	if (reason & MCSR_BUS_WAERR)
+		printk("Bus - Write Address Error\n");
+	if (reason & MCSR_BUS_IBERR)
+		printk("Bus - Instruction Data Error\n");
+	if (reason & MCSR_BUS_RBERR)
+		printk("Bus - Read Data Bus Error\n");
+	if (reason & MCSR_BUS_WBERR)
+		printk("Bus - Read Data Bus Error\n");
+	if (reason & MCSR_BUS_IPERR)
+		printk("Bus - Instruction Parity Error\n");
+	if (reason & MCSR_BUS_RPERR)
+		printk("Bus - Read Parity Error\n");
+#elif defined (CONFIG_E200)
+	printk("Machine check in kernel mode.\n");
+	printk("Caused by (from MCSR=%lx): ", reason);
+
+	if (reason & MCSR_MCP)
+		printk("Machine Check Signal\n");
+	if (reason & MCSR_CP_PERR)
+		printk("Cache Push Parity Error\n");
+	if (reason & MCSR_CPERR)
+		printk("Cache Parity Error\n");
+	if (reason & MCSR_EXCP_ERR)
+		printk("ISI, ITLB, or Bus Error on first instruction fetch for an exception handler\n");
+	if (reason & MCSR_BUS_IRERR)
+		printk("Bus - Read Bus Error on instruction fetch\n");
+	if (reason & MCSR_BUS_DRERR)
+		printk("Bus - Read Bus Error on data load\n");
+	if (reason & MCSR_BUS_WRERR)
+		printk("Bus - Write Bus Error on buffered store or cache line push\n");
+#else /* !CONFIG_4xx && !CONFIG_E500 && !CONFIG_E200 */
+	printk("Machine check in kernel mode.\n");
+	printk("Caused by (from SRR1=%lx): ", reason);
+	switch (reason & 0x601F0000) {
+	case 0x80000:
+		printk("Machine check signal\n");
+		break;
+	case 0:		/* for 601 */
+	case 0x40000:
+	case 0x140000:	/* 7450 MSS error and TEA */
+		printk("Transfer error ack signal\n");
+		break;
+	case 0x20000:
+		printk("Data parity error signal\n");
+		break;
+	case 0x10000:
+		printk("Address parity error signal\n");
+		break;
+	case 0x20000000:
+		printk("L1 Data Cache error\n");
+		break;
+	case 0x40000000:
+		printk("L1 Instruction Cache error\n");
+		break;
+	case 0x00100000:
+		printk("L2 data cache parity error\n");
+		break;
+	default:
+		printk("Unknown values in msr\n");
+	}
+#endif /* CONFIG_4xx */
+
+	/*
+	 * Optional platform-provided routine to print out
+	 * additional info, e.g. bus error registers.
+	 */
+	platform_machine_check(regs);
+#endif /* CONFIG_PPC64 */
+
+	if (debugger_fault_handler(regs))
+		return;
+	die("Machine check", regs, SIGBUS);
+
+	/* Must die if the interrupt is not recoverable */
+	if (!(regs->msr & MSR_RI))
+		panic("Unrecoverable Machine check");
+}
+
+void SMIException(struct pt_regs *regs)
+{
+	die("System Management Interrupt", regs, SIGABRT);
+}
+
+void UnknownException(struct pt_regs *regs)
+{
+	printk("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
+	       regs->nip, regs->msr, regs->trap);
+
+	_exception(SIGTRAP, regs, 0, 0);
+}
+
+void InstructionBreakpoint(struct pt_regs *regs)
+{
+	if (notify_die(DIE_IABR_MATCH, "iabr_match", regs, 5,
+					5, SIGTRAP) == NOTIFY_STOP)
+		return;
+	if (debugger_iabr_match(regs))
+		return;
+	_exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
+}
+
+void RunModeException(struct pt_regs *regs)
+{
+	_exception(SIGTRAP, regs, 0, 0);
+}
+
+void SingleStepException(struct pt_regs *regs)
+{
+	regs->msr &= ~(MSR_SE | MSR_BE);  /* Turn off 'trace' bits */
+
+	if (notify_die(DIE_SSTEP, "single_step", regs, 5,
+					5, SIGTRAP) == NOTIFY_STOP)
+		return;
+	if (debugger_sstep(regs))
+		return;
+
+	_exception(SIGTRAP, regs, TRAP_TRACE, regs->nip);
+}
+
+/*
+ * After we have successfully emulated an instruction, we have to
+ * check if the instruction was being single-stepped, and if so,
+ * pretend we got a single-step exception.  This was pointed out
+ * by Kumar Gala.  -- paulus
+ */
+static void emulate_single_step(struct pt_regs *regs)
+{
+	if (single_stepping(regs)) {
+		clear_single_step(regs);
+		_exception(SIGTRAP, regs, TRAP_TRACE, 0);
+	}
+}
+
+/* Illegal instruction emulation support.  Originally written to
+ * provide the PVR to user applications using the mfspr rd, PVR.
+ * Return non-zero if we can't emulate, or -EFAULT if the associated
+ * memory access caused an access fault.  Return zero on success.
+ *
+ * There are a couple of ways to do this, either "decode" the instruction
+ * or directly match lots of bits.  In this case, matching lots of
+ * bits is faster and easier.
+ *
+ */
+#define INST_MFSPR_PVR		0x7c1f42a6
+#define INST_MFSPR_PVR_MASK	0xfc1fffff
+
+#define INST_DCBA		0x7c0005ec
+#define INST_DCBA_MASK		0x7c0007fe
+
+#define INST_MCRXR		0x7c000400
+#define INST_MCRXR_MASK		0x7c0007fe
+
+#define INST_STRING		0x7c00042a
+#define INST_STRING_MASK	0x7c0007fe
+#define INST_STRING_GEN_MASK	0x7c00067e
+#define INST_LSWI		0x7c0004aa
+#define INST_LSWX		0x7c00042a
+#define INST_STSWI		0x7c0005aa
+#define INST_STSWX		0x7c00052a
+
+static int emulate_string_inst(struct pt_regs *regs, u32 instword)
+{
+	u8 rT = (instword >> 21) & 0x1f;
+	u8 rA = (instword >> 16) & 0x1f;
+	u8 NB_RB = (instword >> 11) & 0x1f;
+	u32 num_bytes;
+	unsigned long EA;
+	int pos = 0;
+
+	/* Early out if we are an invalid form of lswx */
+	if ((instword & INST_STRING_MASK) == INST_LSWX)
+		if ((rT == rA) || (rT == NB_RB))
+			return -EINVAL;
+
+	EA = (rA == 0) ? 0 : regs->gpr[rA];
+
+	switch (instword & INST_STRING_MASK) {
+		case INST_LSWX:
+		case INST_STSWX:
+			EA += NB_RB;
+			num_bytes = regs->xer & 0x7f;
+			break;
+		case INST_LSWI:
+		case INST_STSWI:
+			num_bytes = (NB_RB == 0) ? 32 : NB_RB;
+			break;
+		default:
+			return -EINVAL;
+	}
+
+	while (num_bytes != 0)
+	{
+		u8 val;
+		u32 shift = 8 * (3 - (pos & 0x3));
+
+		switch ((instword & INST_STRING_MASK)) {
+			case INST_LSWX:
+			case INST_LSWI:
+				if (get_user(val, (u8 __user *)EA))
+					return -EFAULT;
+				/* first time updating this reg,
+				 * zero it out */
+				if (pos == 0)
+					regs->gpr[rT] = 0;
+				regs->gpr[rT] |= val << shift;
+				break;
+			case INST_STSWI:
+			case INST_STSWX:
+				val = regs->gpr[rT] >> shift;
+				if (put_user(val, (u8 __user *)EA))
+					return -EFAULT;
+				break;
+		}
+		/* move EA to next address */
+		EA += 1;
+		num_bytes--;
+
+		/* manage our position within the register */
+		if (++pos == 4) {
+			pos = 0;
+			if (++rT == 32)
+				rT = 0;
+		}
+	}
+
+	return 0;
+}
+
+static int emulate_instruction(struct pt_regs *regs)
+{
+	u32 instword;
+	u32 rd;
+
+	if (!user_mode(regs))
+		return -EINVAL;
+	CHECK_FULL_REGS(regs);
+
+	if (get_user(instword, (u32 __user *)(regs->nip)))
+		return -EFAULT;
+
+	/* Emulate the mfspr rD, PVR. */
+	if ((instword & INST_MFSPR_PVR_MASK) == INST_MFSPR_PVR) {
+		rd = (instword >> 21) & 0x1f;
+		regs->gpr[rd] = mfspr(SPRN_PVR);
+		return 0;
+	}
+
+	/* Emulating the dcba insn is just a no-op.  */
+	if ((instword & INST_DCBA_MASK) == INST_DCBA)
+		return 0;
+
+	/* Emulate the mcrxr insn.  */
+	if ((instword & INST_MCRXR_MASK) == INST_MCRXR) {
+		int shift = (instword >> 21) & 0x1c;
+		unsigned long msk = 0xf0000000UL >> shift;
+
+		regs->ccr = (regs->ccr & ~msk) | ((regs->xer >> shift) & msk);
+		regs->xer &= ~0xf0000000UL;
+		return 0;
+	}
+
+	/* Emulate load/store string insn. */
+	if ((instword & INST_STRING_GEN_MASK) == INST_STRING)
+		return emulate_string_inst(regs, instword);
+
+	return -EINVAL;
+}
+
+/*
+ * Look through the list of trap instructions that are used for BUG(),
+ * BUG_ON() and WARN_ON() and see if we hit one.  At this point we know
+ * that the exception was caused by a trap instruction of some kind.
+ * Returns 1 if we should continue (i.e. it was a WARN_ON) or 0
+ * otherwise.
+ */
+extern struct bug_entry __start___bug_table[], __stop___bug_table[];
+
+#ifndef CONFIG_MODULES
+#define module_find_bug(x)	NULL
+#endif
+
+struct bug_entry *find_bug(unsigned long bugaddr)
+{
+	struct bug_entry *bug;
+
+	for (bug = __start___bug_table; bug < __stop___bug_table; ++bug)
+		if (bugaddr == bug->bug_addr)
+			return bug;
+	return module_find_bug(bugaddr);
+}
+
+int check_bug_trap(struct pt_regs *regs)
+{
+	struct bug_entry *bug;
+	unsigned long addr;
+
+	if (regs->msr & MSR_PR)
+		return 0;	/* not in kernel */
+	addr = regs->nip;	/* address of trap instruction */
+	if (addr < PAGE_OFFSET)
+		return 0;
+	bug = find_bug(regs->nip);
+	if (bug == NULL)
+		return 0;
+	if (bug->line & BUG_WARNING_TRAP) {
+		/* this is a WARN_ON rather than BUG/BUG_ON */
+#ifdef CONFIG_XMON
+		xmon_printf(KERN_ERR "Badness in %s at %s:%d\n",
+		       bug->function, bug->file,
+		       bug->line & ~BUG_WARNING_TRAP);
+#endif /* CONFIG_XMON */		
+		printk(KERN_ERR "Badness in %s at %s:%d\n",
+		       bug->function, bug->file,
+		       bug->line & ~BUG_WARNING_TRAP);
+		dump_stack();
+		return 1;
+	}
+#ifdef CONFIG_XMON
+	xmon_printf(KERN_CRIT "kernel BUG in %s at %s:%d!\n",
+	       bug->function, bug->file, bug->line);
+	xmon(regs);
+#endif /* CONFIG_XMON */
+	printk(KERN_CRIT "kernel BUG in %s at %s:%d!\n",
+	       bug->function, bug->file, bug->line);
+
+	return 0;
+}
+
+void ProgramCheckException(struct pt_regs *regs)
+{
+	unsigned int reason = get_reason(regs);
+	extern int do_mathemu(struct pt_regs *regs);
+
+#ifdef CONFIG_MATH_EMULATION
+	/* (reason & REASON_ILLEGAL) would be the obvious thing here,
+	 * but there seems to be a hardware bug on the 405GP (RevD)
+	 * that means ESR is sometimes set incorrectly - either to
+	 * ESR_DST (!?) or 0.  In the process of chasing this with the
+	 * hardware people - not sure if it can happen on any illegal
+	 * instruction or only on FP instructions, whether there is a
+	 * pattern to occurences etc. -dgibson 31/Mar/2003 */
+	if (!(reason & REASON_TRAP) && do_mathemu(regs) == 0) {
+		emulate_single_step(regs);
+		return;
+	}
+#endif /* CONFIG_MATH_EMULATION */
+
+	if (reason & REASON_FP) {
+		/* IEEE FP exception */
+		int code = 0;
+		u32 fpscr;
+
+		/* We must make sure the FP state is consistent with
+		 * our MSR_FP in regs
+		 */
+		preempt_disable();
+		if (regs->msr & MSR_FP)
+			giveup_fpu(current);
+		preempt_enable();
+
+		fpscr = current->thread.fpscr;
+		fpscr &= fpscr << 22;	/* mask summary bits with enables */
+		if (fpscr & FPSCR_VX)
+			code = FPE_FLTINV;
+		else if (fpscr & FPSCR_OX)
+			code = FPE_FLTOVF;
+		else if (fpscr & FPSCR_UX)
+			code = FPE_FLTUND;
+		else if (fpscr & FPSCR_ZX)
+			code = FPE_FLTDIV;
+		else if (fpscr & FPSCR_XX)
+			code = FPE_FLTRES;
+		_exception(SIGFPE, regs, code, regs->nip);
+		return;
+	}
+
+	if (reason & REASON_TRAP) {
+		/* trap exception */
+		if (debugger_bpt(regs))
+			return;
+		if (check_bug_trap(regs)) {
+			regs->nip += 4;
+			return;
+		}
+		_exception(SIGTRAP, regs, TRAP_BRKPT, 0);
+		return;
+	}
+
+	/* Try to emulate it if we should. */
+	if (reason & (REASON_ILLEGAL | REASON_PRIVILEGED)) {
+		switch (emulate_instruction(regs)) {
+		case 0:
+			regs->nip += 4;
+			emulate_single_step(regs);
+			return;
+		case -EFAULT:
+			_exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip);
+			return;
+		}
+	}
+
+	if (reason & REASON_PRIVILEGED)
+		_exception(SIGILL, regs, ILL_PRVOPC, regs->nip);
+	else
+		_exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
+}
+
+void AlignmentException(struct pt_regs *regs)
+{
+	int fixed;
+
+	fixed = fix_alignment(regs);
+
+	if (fixed == 1) {
+		regs->nip += 4;	/* skip over emulated instruction */
+		emulate_single_step(regs);
+		return;
+	}
+
+	/* Operand address was bad */	
+	if (fixed == -EFAULT) {
+		if (user_mode(regs))
+			_exception(SIGSEGV, regs, SEGV_ACCERR, regs->dar);
+		else
+			/* Search exception table */
+			bad_page_fault(regs, regs->dar, SIGSEGV);
+		return;
+	}
+	_exception(SIGBUS, regs, BUS_ADRALN, regs->dar);
+}
+
+void StackOverflow(struct pt_regs *regs)
+{
+	printk(KERN_CRIT "Kernel stack overflow in process %p, r1=%lx\n",
+	       current, regs->gpr[1]);
+	debugger(regs);
+	show_regs(regs);
+	panic("kernel stack overflow");
+}
+
+void nonrecoverable_exception(struct pt_regs *regs)
+{
+	printk(KERN_ERR "Non-recoverable exception at PC=%lx MSR=%lx\n",
+	       regs->nip, regs->msr);
+	debugger(regs);
+	die("nonrecoverable exception", regs, SIGKILL);
+}
+
+void trace_syscall(struct pt_regs *regs)
+{
+	printk("Task: %p(%d), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld    %s\n",
+	       current, current->pid, regs->nip, regs->link, regs->gpr[0],
+	       regs->ccr&0x10000000?"Error=":"", regs->gpr[3], print_tainted());
+}
+
+#ifdef CONFIG_8xx
+void SoftwareEmulation(struct pt_regs *regs)
+{
+	extern int do_mathemu(struct pt_regs *);
+	extern int Soft_emulate_8xx(struct pt_regs *);
+	int errcode;
+
+	CHECK_FULL_REGS(regs);
+
+	if (!user_mode(regs)) {
+		debugger(regs);
+		die("Kernel Mode Software FPU Emulation", regs, SIGFPE);
+	}
+
+#ifdef CONFIG_MATH_EMULATION
+	errcode = do_mathemu(regs);
+#else
+	errcode = Soft_emulate_8xx(regs);
+#endif
+	if (errcode) {
+		if (errcode > 0)
+			_exception(SIGFPE, regs, 0, 0);
+		else if (errcode == -EFAULT)
+			_exception(SIGSEGV, regs, 0, 0);
+		else
+			_exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
+	} else
+		emulate_single_step(regs);
+}
+#endif /* CONFIG_8xx */
+
+#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
+
+void DebugException(struct pt_regs *regs, unsigned long debug_status)
+{
+	if (debug_status & DBSR_IC) {	/* instruction completion */
+		regs->msr &= ~MSR_DE;
+		if (user_mode(regs)) {
+			current->thread.dbcr0 &= ~DBCR0_IC;
+		} else {
+			/* Disable instruction completion */
+			mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) & ~DBCR0_IC);
+			/* Clear the instruction completion event */
+			mtspr(SPRN_DBSR, DBSR_IC);
+			if (debugger_sstep(regs))
+				return;
+		}
+		_exception(SIGTRAP, regs, TRAP_TRACE, 0);
+	}
+}
+#endif /* CONFIG_4xx || CONFIG_BOOKE */
+
+#if !defined(CONFIG_TAU_INT)
+void TAUException(struct pt_regs *regs)
+{
+	printk("TAU trap at PC: %lx, MSR: %lx, vector=%lx    %s\n",
+	       regs->nip, regs->msr, regs->trap, print_tainted());
+}
+#endif /* CONFIG_INT_TAU */
+
+void AltivecUnavailException(struct pt_regs *regs)
+{
+	static int kernel_altivec_count;
+
+#ifndef CONFIG_ALTIVEC
+	if (user_mode(regs)) {
+		/* A user program has executed an altivec instruction,
+		   but this kernel doesn't support altivec. */
+		_exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
+		return;
+	}
+#endif
+	/* The kernel has executed an altivec instruction without
+	   first enabling altivec.  Whinge but let it do it. */
+	if (++kernel_altivec_count < 10)
+		printk(KERN_ERR "AltiVec used in kernel (task=%p, pc=%lx)\n",
+		       current, regs->nip);
+	regs->msr |= MSR_VEC;
+}
+
+#ifdef CONFIG_ALTIVEC
+void AltivecAssistException(struct pt_regs *regs)
+{
+	int err;
+
+	preempt_disable();
+	if (regs->msr & MSR_VEC)
+		giveup_altivec(current);
+	preempt_enable();
+	if (!user_mode(regs)) {
+		printk(KERN_EMERG "VMX/Altivec assist exception in kernel mode"
+		       " at %lx\n", regs->nip);
+		die("Kernel Altivec assist exception", regs, SIGILL);
+	}
+
+	err = emulate_altivec(regs);
+	if (err == 0) {
+		regs->nip += 4;		/* skip emulated instruction */
+		emulate_single_step(regs);
+		return;
+	}
+
+	if (err == -EFAULT) {
+		/* got an error reading the instruction */
+		_exception(SIGSEGV, regs, SEGV_ACCERR, regs->nip);
+	} else {
+		/* didn't recognize the instruction */
+		/* XXX quick hack for now: set the non-Java bit in the VSCR */
+		if (printk_ratelimit())
+			printk(KERN_ERR "Unrecognized altivec instruction "
+			       "in %s at %lx\n", current->comm, regs->nip);
+		current->thread.vscr.u[3] |= 0x10000;
+	}
+}
+#endif /* CONFIG_ALTIVEC */
+
+#ifdef CONFIG_E500
+void PerformanceMonitorException(struct pt_regs *regs)
+{
+	perf_irq(regs);
+}
+#endif
+
+#ifdef CONFIG_FSL_BOOKE
+void CacheLockingException(struct pt_regs *regs, unsigned long address,
+			   unsigned long error_code)
+{
+	/* We treat cache locking instructions from the user
+	 * as priv ops, in the future we could try to do
+	 * something smarter
+	 */
+	if (error_code & (ESR_DLK|ESR_ILK))
+		_exception(SIGILL, regs, ILL_PRVOPC, regs->nip);
+	return;
+}
+#endif /* CONFIG_FSL_BOOKE */
+
+#ifdef CONFIG_SPE
+void SPEFloatingPointException(struct pt_regs *regs)
+{
+	unsigned long spefscr;
+	int fpexc_mode;
+	int code = 0;
+
+	spefscr = current->thread.spefscr;
+	fpexc_mode = current->thread.fpexc_mode;
+
+	/* Hardware does not neccessarily set sticky
+	 * underflow/overflow/invalid flags */
+	if ((spefscr & SPEFSCR_FOVF) && (fpexc_mode & PR_FP_EXC_OVF)) {
+		code = FPE_FLTOVF;
+		spefscr |= SPEFSCR_FOVFS;
+	}
+	else if ((spefscr & SPEFSCR_FUNF) && (fpexc_mode & PR_FP_EXC_UND)) {
+		code = FPE_FLTUND;
+		spefscr |= SPEFSCR_FUNFS;
+	}
+	else if ((spefscr & SPEFSCR_FDBZ) && (fpexc_mode & PR_FP_EXC_DIV))
+		code = FPE_FLTDIV;
+	else if ((spefscr & SPEFSCR_FINV) && (fpexc_mode & PR_FP_EXC_INV)) {
+		code = FPE_FLTINV;
+		spefscr |= SPEFSCR_FINVS;
+	}
+	else if ((spefscr & (SPEFSCR_FG | SPEFSCR_FX)) && (fpexc_mode & PR_FP_EXC_RES))
+		code = FPE_FLTRES;
+
+	current->thread.spefscr = spefscr;
+
+	_exception(SIGFPE, regs, code, regs->nip);
+	return;
+}
+#endif
+
+#ifdef CONFIG_BOOKE_WDT
+/*
+ * Default handler for a Watchdog exception,
+ * spins until a reboot occurs
+ */
+void __attribute__ ((weak)) WatchdogHandler(struct pt_regs *regs)
+{
+	/* Generic WatchdogHandler, implement your own */
+	mtspr(SPRN_TCR, mfspr(SPRN_TCR)&(~TCR_WIE));
+	return;
+}
+
+void WatchdogException(struct pt_regs *regs)
+{
+	printk (KERN_EMERG "PowerPC Book-E Watchdog Exception\n");
+	WatchdogHandler(regs);
+}
+#endif
+
+void __init trap_init(void)
+{
+}
diff --git a/arch/powerpc/kernel/traps64.c b/arch/powerpc/kernel/traps64.c
new file mode 100644
--- /dev/null
+++ b/arch/powerpc/kernel/traps64.c
@@ -0,0 +1,568 @@
+/*
+ *  linux/arch/ppc64/kernel/traps.c
+ *
+ *  Copyright (C) 1995-1996  Gary Thomas (gdt@linuxppc.org)
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ *
+ *  Modified by Cort Dougan (cort@cs.nmt.edu)
+ *  and Paul Mackerras (paulus@cs.anu.edu.au)
+ */
+
+/*
+ * This file handles the architecture-dependent parts of hardware exceptions
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/slab.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/kprobes.h>
+#include <asm/kdebug.h>
+
+#include <asm/pgtable.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/ppcdebug.h>
+#include <asm/rtas.h>
+#include <asm/systemcfg.h>
+#include <asm/machdep.h>
+#include <asm/pmc.h>
+
+#ifdef CONFIG_DEBUGGER
+int (*__debugger)(struct pt_regs *regs);
+int (*__debugger_ipi)(struct pt_regs *regs);
+int (*__debugger_bpt)(struct pt_regs *regs);
+int (*__debugger_sstep)(struct pt_regs *regs);
+int (*__debugger_iabr_match)(struct pt_regs *regs);
+int (*__debugger_dabr_match)(struct pt_regs *regs);
+int (*__debugger_fault_handler)(struct pt_regs *regs);
+
+EXPORT_SYMBOL(__debugger);
+EXPORT_SYMBOL(__debugger_ipi);
+EXPORT_SYMBOL(__debugger_bpt);
+EXPORT_SYMBOL(__debugger_sstep);
+EXPORT_SYMBOL(__debugger_iabr_match);
+EXPORT_SYMBOL(__debugger_dabr_match);
+EXPORT_SYMBOL(__debugger_fault_handler);
+#endif
+
+struct notifier_block *powerpc_die_chain;
+static DEFINE_SPINLOCK(die_notifier_lock);
+
+int register_die_notifier(struct notifier_block *nb)
+{
+	int err = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&die_notifier_lock, flags);
+	err = notifier_chain_register(&powerpc_die_chain, nb);
+	spin_unlock_irqrestore(&die_notifier_lock, flags);
+	return err;
+}
+
+/*
+ * Trap & Exception support
+ */
+
+static DEFINE_SPINLOCK(die_lock);
+
+int die(const char *str, struct pt_regs *regs, long err)
+{
+	static int die_counter;
+	int nl = 0;
+
+	if (debugger(regs))
+		return 1;
+
+	console_verbose();
+	spin_lock_irq(&die_lock);
+	bust_spinlocks(1);
+	printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter);
+#ifdef CONFIG_PREEMPT
+	printk("PREEMPT ");
+	nl = 1;
+#endif
+#ifdef CONFIG_SMP
+	printk("SMP NR_CPUS=%d ", NR_CPUS);
+	nl = 1;
+#endif
+#ifdef CONFIG_DEBUG_PAGEALLOC
+	printk("DEBUG_PAGEALLOC ");
+	nl = 1;
+#endif
+#ifdef CONFIG_NUMA
+	printk("NUMA ");
+	nl = 1;
+#endif
+	switch(systemcfg->platform) {
+		case PLATFORM_PSERIES:
+			printk("PSERIES ");
+			nl = 1;
+			break;
+		case PLATFORM_PSERIES_LPAR:
+			printk("PSERIES LPAR ");
+			nl = 1;
+			break;
+		case PLATFORM_ISERIES_LPAR:
+			printk("ISERIES LPAR ");
+			nl = 1;
+			break;
+		case PLATFORM_POWERMAC:
+			printk("POWERMAC ");
+			nl = 1;
+			break;
+		case PLATFORM_BPA:
+			printk("BPA ");
+			nl = 1;
+			break;
+	}
+	if (nl)
+		printk("\n");
+	print_modules();
+	show_regs(regs);
+	bust_spinlocks(0);
+	spin_unlock_irq(&die_lock);
+
+	if (in_interrupt())
+		panic("Fatal exception in interrupt");
+
+	if (panic_on_oops) {
+		printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n");
+		ssleep(5);
+		panic("Fatal exception");
+	}
+	do_exit(SIGSEGV);
+
+	return 0;
+}
+
+void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
+{
+	siginfo_t info;
+
+	if (!user_mode(regs)) {
+		if (die("Exception in kernel mode", regs, signr))
+			return;
+	}
+
+	memset(&info, 0, sizeof(info));
+	info.si_signo = signr;
+	info.si_code = code;
+	info.si_addr = (void __user *) addr;
+	force_sig_info(signr, &info, current);
+}
+
+void system_reset_exception(struct pt_regs *regs)
+{
+	/* See if any machine dependent calls */
+	if (ppc_md.system_reset_exception)
+		ppc_md.system_reset_exception(regs);
+
+	die("System Reset", regs, 0);
+
+	/* Must die if the interrupt is not recoverable */
+	if (!(regs->msr & MSR_RI))
+		panic("Unrecoverable System Reset");
+
+	/* What should we do here? We could issue a shutdown or hard reset. */
+}
+
+void machine_check_exception(struct pt_regs *regs)
+{
+	int recover = 0;
+
+	/* See if any machine dependent calls */
+	if (ppc_md.machine_check_exception)
+		recover = ppc_md.machine_check_exception(regs);
+
+	if (recover)
+		return;
+
+	if (debugger_fault_handler(regs))
+		return;
+	die("Machine check", regs, 0);
+
+	/* Must die if the interrupt is not recoverable */
+	if (!(regs->msr & MSR_RI))
+		panic("Unrecoverable Machine check");
+}
+
+void unknown_exception(struct pt_regs *regs)
+{
+	printk("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
+	       regs->nip, regs->msr, regs->trap);
+
+	_exception(SIGTRAP, regs, 0, 0);
+}
+
+void instruction_breakpoint_exception(struct pt_regs *regs)
+{
+	if (notify_die(DIE_IABR_MATCH, "iabr_match", regs, 5,
+					5, SIGTRAP) == NOTIFY_STOP)
+		return;
+	if (debugger_iabr_match(regs))
+		return;
+	_exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
+}
+
+void __kprobes single_step_exception(struct pt_regs *regs)
+{
+	regs->msr &= ~MSR_SE;  /* Turn off 'trace' bit */
+
+	if (notify_die(DIE_SSTEP, "single_step", regs, 5,
+					5, SIGTRAP) == NOTIFY_STOP)
+		return;
+	if (debugger_sstep(regs))
+		return;
+
+	_exception(SIGTRAP, regs, TRAP_TRACE, regs->nip);
+}
+
+/*
+ * After we have successfully emulated an instruction, we have to
+ * check if the instruction was being single-stepped, and if so,
+ * pretend we got a single-step exception.  This was pointed out
+ * by Kumar Gala.  -- paulus
+ */
+static inline void emulate_single_step(struct pt_regs *regs)
+{
+	if (regs->msr & MSR_SE)
+		single_step_exception(regs);
+}
+
+static void parse_fpe(struct pt_regs *regs)
+{
+	int code = 0;
+	unsigned long fpscr;
+
+	flush_fp_to_thread(current);
+
+	fpscr = current->thread.fpscr;
+
+	/* Invalid operation */
+	if ((fpscr & FPSCR_VE) && (fpscr & FPSCR_VX))
+		code = FPE_FLTINV;
+
+	/* Overflow */
+	else if ((fpscr & FPSCR_OE) && (fpscr & FPSCR_OX))
+		code = FPE_FLTOVF;
+
+	/* Underflow */
+	else if ((fpscr & FPSCR_UE) && (fpscr & FPSCR_UX))
+		code = FPE_FLTUND;
+
+	/* Divide by zero */
+	else if ((fpscr & FPSCR_ZE) && (fpscr & FPSCR_ZX))
+		code = FPE_FLTDIV;
+
+	/* Inexact result */
+	else if ((fpscr & FPSCR_XE) && (fpscr & FPSCR_XX))
+		code = FPE_FLTRES;
+
+	_exception(SIGFPE, regs, code, regs->nip);
+}
+
+/*
+ * Illegal instruction emulation support.  Return non-zero if we can't
+ * emulate, or -EFAULT if the associated memory access caused an access
+ * fault.  Return zero on success.
+ */
+
+#define INST_MFSPR_PVR		0x7c1f42a6
+#define INST_MFSPR_PVR_MASK	0xfc1fffff
+
+#define INST_DCBA		0x7c0005ec
+#define INST_DCBA_MASK		0x7c0007fe
+
+#define INST_MCRXR		0x7c000400
+#define INST_MCRXR_MASK		0x7c0007fe
+
+static int emulate_instruction(struct pt_regs *regs)
+{
+	unsigned int instword;
+
+	if (!user_mode(regs))
+		return -EINVAL;
+
+	CHECK_FULL_REGS(regs);
+
+	if (get_user(instword, (unsigned int __user *)(regs->nip)))
+		return -EFAULT;
+
+	/* Emulate the mfspr rD, PVR. */
+	if ((instword & INST_MFSPR_PVR_MASK) == INST_MFSPR_PVR) {
+		unsigned int rd;
+
+		rd = (instword >> 21) & 0x1f;
+		regs->gpr[rd] = mfspr(SPRN_PVR);
+		return 0;
+	}
+
+	/* Emulating the dcba insn is just a no-op.  */
+	if ((instword & INST_DCBA_MASK) == INST_DCBA) {
+		static int warned;
+
+		if (!warned) {
+			printk(KERN_WARNING
+			       "process %d (%s) uses obsolete 'dcba' insn\n",
+			       current->pid, current->comm);
+			warned = 1;
+		}
+		return 0;
+	}
+
+	/* Emulate the mcrxr insn.  */
+	if ((instword & INST_MCRXR_MASK) == INST_MCRXR) {
+		static int warned;
+		unsigned int shift;
+
+		if (!warned) {
+			printk(KERN_WARNING
+			       "process %d (%s) uses obsolete 'mcrxr' insn\n",
+			       current->pid, current->comm);
+			warned = 1;
+		}
+
+		shift = (instword >> 21) & 0x1c;
+		regs->ccr &= ~(0xf0000000 >> shift);
+		regs->ccr |= (regs->xer & 0xf0000000) >> shift;
+		regs->xer &= ~0xf0000000;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+/*
+ * Look through the list of trap instructions that are used for BUG(),
+ * BUG_ON() and WARN_ON() and see if we hit one.  At this point we know
+ * that the exception was caused by a trap instruction of some kind.
+ * Returns 1 if we should continue (i.e. it was a WARN_ON) or 0
+ * otherwise.
+ */
+extern struct bug_entry __start___bug_table[], __stop___bug_table[];
+
+#ifndef CONFIG_MODULES
+#define module_find_bug(x)	NULL
+#endif
+
+struct bug_entry *find_bug(unsigned long bugaddr)
+{
+	struct bug_entry *bug;
+
+	for (bug = __start___bug_table; bug < __stop___bug_table; ++bug)
+		if (bugaddr == bug->bug_addr)
+			return bug;
+	return module_find_bug(bugaddr);
+}
+
+static int
+check_bug_trap(struct pt_regs *regs)
+{
+	struct bug_entry *bug;
+	unsigned long addr;
+
+	if (regs->msr & MSR_PR)
+		return 0;	/* not in kernel */
+	addr = regs->nip;	/* address of trap instruction */
+	if (addr < PAGE_OFFSET)
+		return 0;
+	bug = find_bug(regs->nip);
+	if (bug == NULL)
+		return 0;
+	if (bug->line & BUG_WARNING_TRAP) {
+		/* this is a WARN_ON rather than BUG/BUG_ON */
+		printk(KERN_ERR "Badness in %s at %s:%d\n",
+		       bug->function, bug->file,
+		       bug->line & ~BUG_WARNING_TRAP);
+		show_stack(current, (void *)regs->gpr[1]);
+		return 1;
+	}
+	printk(KERN_CRIT "kernel BUG in %s at %s:%d!\n",
+	       bug->function, bug->file, bug->line);
+	return 0;
+}
+
+void __kprobes program_check_exception(struct pt_regs *regs)
+{
+	if (debugger_fault_handler(regs))
+		return;
+
+	if (regs->msr & 0x100000) {
+		/* IEEE FP exception */
+		parse_fpe(regs);
+	} else if (regs->msr & 0x20000) {
+		/* trap exception */
+
+		if (notify_die(DIE_BPT, "breakpoint", regs, 5,
+					5, SIGTRAP) == NOTIFY_STOP)
+			return;
+		if (debugger_bpt(regs))
+			return;
+
+		if (check_bug_trap(regs)) {
+			regs->nip += 4;
+			return;
+		}
+		_exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
+
+	} else {
+		/* Privileged or illegal instruction; try to emulate it. */
+		switch (emulate_instruction(regs)) {
+		case 0:
+			regs->nip += 4;
+			emulate_single_step(regs);
+			break;
+
+		case -EFAULT:
+			_exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip);
+			break;
+
+		default:
+			if (regs->msr & 0x40000)
+				/* priveleged */
+				_exception(SIGILL, regs, ILL_PRVOPC, regs->nip);
+			else
+				/* illegal */
+				_exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
+			break;
+		}
+	}
+}
+
+void kernel_fp_unavailable_exception(struct pt_regs *regs)
+{
+	printk(KERN_EMERG "Unrecoverable FP Unavailable Exception "
+			  "%lx at %lx\n", regs->trap, regs->nip);
+	die("Unrecoverable FP Unavailable Exception", regs, SIGABRT);
+}
+
+void altivec_unavailable_exception(struct pt_regs *regs)
+{
+	if (user_mode(regs)) {
+		/* A user program has executed an altivec instruction,
+		   but this kernel doesn't support altivec. */
+		_exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
+		return;
+	}
+	printk(KERN_EMERG "Unrecoverable VMX/Altivec Unavailable Exception "
+			  "%lx at %lx\n", regs->trap, regs->nip);
+	die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT);
+}
+
+extern perf_irq_t perf_irq;
+
+void performance_monitor_exception(struct pt_regs *regs)
+{
+	perf_irq(regs);
+}
+
+void alignment_exception(struct pt_regs *regs)
+{
+	int fixed;
+
+	fixed = fix_alignment(regs);
+
+	if (fixed == 1) {
+		regs->nip += 4;	/* skip over emulated instruction */
+		emulate_single_step(regs);
+		return;
+	}
+
+	/* Operand address was bad */	
+	if (fixed == -EFAULT) {
+		if (user_mode(regs)) {
+			_exception(SIGSEGV, regs, SEGV_MAPERR, regs->dar);
+		} else {
+			/* Search exception table */
+			bad_page_fault(regs, regs->dar, SIGSEGV);
+		}
+
+		return;
+	}
+
+	_exception(SIGBUS, regs, BUS_ADRALN, regs->nip);
+}
+
+#ifdef CONFIG_ALTIVEC
+void altivec_assist_exception(struct pt_regs *regs)
+{
+	int err;
+	siginfo_t info;
+
+	if (!user_mode(regs)) {
+		printk(KERN_EMERG "VMX/Altivec assist exception in kernel mode"
+		       " at %lx\n", regs->nip);
+		die("Kernel VMX/Altivec assist exception", regs, SIGILL);
+	}
+
+	flush_altivec_to_thread(current);
+
+	err = emulate_altivec(regs);
+	if (err == 0) {
+		regs->nip += 4;		/* skip emulated instruction */
+		emulate_single_step(regs);
+		return;
+	}
+
+	if (err == -EFAULT) {
+		/* got an error reading the instruction */
+		info.si_signo = SIGSEGV;
+		info.si_errno = 0;
+		info.si_code = SEGV_MAPERR;
+		info.si_addr = (void __user *) regs->nip;
+		force_sig_info(SIGSEGV, &info, current);
+	} else {
+		/* didn't recognize the instruction */
+		/* XXX quick hack for now: set the non-Java bit in the VSCR */
+		if (printk_ratelimit())
+			printk(KERN_ERR "Unrecognized altivec instruction "
+			       "in %s at %lx\n", current->comm, regs->nip);
+		current->thread.vscr.u[3] |= 0x10000;
+	}
+}
+#endif /* CONFIG_ALTIVEC */
+
+/*
+ * We enter here if we get an unrecoverable exception, that is, one
+ * that happened at a point where the RI (recoverable interrupt) bit
+ * in the MSR is 0.  This indicates that SRR0/1 are live, and that
+ * we therefore lost state by taking this exception.
+ */
+void unrecoverable_exception(struct pt_regs *regs)
+{
+	printk(KERN_EMERG "Unrecoverable exception %lx at %lx\n",
+	       regs->trap, regs->nip);
+	die("Unrecoverable exception", regs, SIGABRT);
+}
+
+/*
+ * We enter here if we discover during exception entry that we are
+ * running in supervisor mode with a userspace value in the stack pointer.
+ */
+void kernel_bad_stack(struct pt_regs *regs)
+{
+	printk(KERN_EMERG "Bad kernel stack pointer %lx at %lx\n",
+	       regs->gpr[1], regs->nip);
+	die("Bad kernel stack pointer", regs, SIGABRT);
+}
+
+void __init trap_init(void)
+{
+}
diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile
--- a/arch/ppc64/kernel/Makefile
+++ b/arch/ppc64/kernel/Makefile
@@ -2,10 +2,12 @@
 # Makefile for the linux ppc64 kernel.
 #
 
+ifneq ($(CONFIG_PPC_MERGE),y)
+
 EXTRA_CFLAGS	+= -mno-minimal-toc
 extra-y		:= head.o vmlinux.lds
 
-obj-y               :=	setup.o entry.o traps.o irq.o idle.o dma.o \
+obj-y               :=	setup.o entry.o traps64.o irq.o idle.o dma.o \
 			time.o process.o signal.o syscalls.o misc.o ptrace.o \
 			align.o semaphore.o bitops.o pacaData.o \
 			udbg.o binfmt_elf32.o sys_ppc32.o ioctl32.o \
@@ -77,3 +79,9 @@ endif
 # These are here while we do the architecture merge
 vecemu-y			+= ../../powerpc/kernel/vecemu.o
 vector-y			+= ../../powerpc/kernel/vector.o
+idle_power4-y			+= ../../powerpc/kernel/idle_power4.o
+traps64-y			+= ../../powerpc/kernel/traps64.o
+
+else
+
+endif
diff --git a/arch/ppc64/kernel/idle_power4.S b/arch/ppc64/kernel/idle_power4.S
deleted file mode 100644
--- a/arch/ppc64/kernel/idle_power4.S
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- *  This file contains the power_save function for 6xx & 7xxx CPUs
- *  rewritten in assembler
- *
- *  Warning ! This code assumes that if your machine has a 750fx
- *  it will have PLL 1 set to low speed mode (used during NAP/DOZE).
- *  if this is not the case some additional changes will have to
- *  be done to check a runtime var (a bit like powersave-nap)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version
- *  2 of the License, or (at your option) any later version.
- */
-
-#include <linux/config.h>
-#include <linux/threads.h>
-#include <asm/processor.h>
-#include <asm/page.h>
-#include <asm/cputable.h>
-#include <asm/thread_info.h>
-#include <asm/ppc_asm.h>
-#include <asm/asm-offsets.h>
-
-#undef DEBUG
-
-	.text
-
-/*
- * Here is the power_save_6xx function. This could eventually be
- * split into several functions & changing the function pointer
- * depending on the various features.
- */
-_GLOBAL(power4_idle)
-BEGIN_FTR_SECTION
-	blr
-END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP)
-	/* We must dynamically check for the NAP feature as it
-	 * can be cleared by CPU init after the fixups are done
-	 */
-	LOADBASE(r3,cur_cpu_spec)
-	ld	r4,cur_cpu_spec@l(r3)
-	ld	r4,CPU_SPEC_FEATURES(r4)
-	andi.	r0,r4,CPU_FTR_CAN_NAP
-	beqlr
-	/* Now check if user or arch enabled NAP mode */
-	LOADBASE(r3,powersave_nap)
-	lwz	r4,powersave_nap@l(r3)
-	cmpwi	0,r4,0
-	beqlr
-
-	/* Clear MSR:EE */
-	mfmsr	r7
-	li	r4,0
-	ori	r4,r4,MSR_EE
-	andc	r0,r7,r4
-	mtmsrd	r0
-
-	/* Check current_thread_info()->flags */
-	clrrdi	r4,r1,THREAD_SHIFT
-	ld	r4,TI_FLAGS(r4)
-	andi.	r0,r4,_TIF_NEED_RESCHED
-	beq	1f
-	mtmsrd	r7	/* out of line this ? */
-	blr
-1:	
-	/* Go to NAP now */	
-BEGIN_FTR_SECTION
-	DSSALL
-	sync
-END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
-	oris	r7,r7,MSR_POW@h
-	sync
-	isync
-	mtmsrd	r7
-	isync
-	sync
-	blr
-	
diff --git a/arch/ppc64/kernel/traps.c b/arch/ppc64/kernel/traps.c
deleted file mode 100644
--- a/arch/ppc64/kernel/traps.c
+++ /dev/null
@@ -1,568 +0,0 @@
-/*
- *  linux/arch/ppc64/kernel/traps.c
- *
- *  Copyright (C) 1995-1996  Gary Thomas (gdt@linuxppc.org)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version
- *  2 of the License, or (at your option) any later version.
- *
- *  Modified by Cort Dougan (cort@cs.nmt.edu)
- *  and Paul Mackerras (paulus@cs.anu.edu.au)
- */
-
-/*
- * This file handles the architecture-dependent parts of hardware exceptions
- */
-
-#include <linux/config.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/stddef.h>
-#include <linux/unistd.h>
-#include <linux/slab.h>
-#include <linux/user.h>
-#include <linux/a.out.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/kprobes.h>
-#include <asm/kdebug.h>
-
-#include <asm/pgtable.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/processor.h>
-#include <asm/ppcdebug.h>
-#include <asm/rtas.h>
-#include <asm/systemcfg.h>
-#include <asm/machdep.h>
-#include <asm/pmc.h>
-
-#ifdef CONFIG_DEBUGGER
-int (*__debugger)(struct pt_regs *regs);
-int (*__debugger_ipi)(struct pt_regs *regs);
-int (*__debugger_bpt)(struct pt_regs *regs);
-int (*__debugger_sstep)(struct pt_regs *regs);
-int (*__debugger_iabr_match)(struct pt_regs *regs);
-int (*__debugger_dabr_match)(struct pt_regs *regs);
-int (*__debugger_fault_handler)(struct pt_regs *regs);
-
-EXPORT_SYMBOL(__debugger);
-EXPORT_SYMBOL(__debugger_ipi);
-EXPORT_SYMBOL(__debugger_bpt);
-EXPORT_SYMBOL(__debugger_sstep);
-EXPORT_SYMBOL(__debugger_iabr_match);
-EXPORT_SYMBOL(__debugger_dabr_match);
-EXPORT_SYMBOL(__debugger_fault_handler);
-#endif
-
-struct notifier_block *powerpc_die_chain;
-static DEFINE_SPINLOCK(die_notifier_lock);
-
-int register_die_notifier(struct notifier_block *nb)
-{
-	int err = 0;
-	unsigned long flags;
-
-	spin_lock_irqsave(&die_notifier_lock, flags);
-	err = notifier_chain_register(&powerpc_die_chain, nb);
-	spin_unlock_irqrestore(&die_notifier_lock, flags);
-	return err;
-}
-
-/*
- * Trap & Exception support
- */
-
-static DEFINE_SPINLOCK(die_lock);
-
-int die(const char *str, struct pt_regs *regs, long err)
-{
-	static int die_counter;
-	int nl = 0;
-
-	if (debugger(regs))
-		return 1;
-
-	console_verbose();
-	spin_lock_irq(&die_lock);
-	bust_spinlocks(1);
-	printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter);
-#ifdef CONFIG_PREEMPT
-	printk("PREEMPT ");
-	nl = 1;
-#endif
-#ifdef CONFIG_SMP
-	printk("SMP NR_CPUS=%d ", NR_CPUS);
-	nl = 1;
-#endif
-#ifdef CONFIG_DEBUG_PAGEALLOC
-	printk("DEBUG_PAGEALLOC ");
-	nl = 1;
-#endif
-#ifdef CONFIG_NUMA
-	printk("NUMA ");
-	nl = 1;
-#endif
-	switch(systemcfg->platform) {
-		case PLATFORM_PSERIES:
-			printk("PSERIES ");
-			nl = 1;
-			break;
-		case PLATFORM_PSERIES_LPAR:
-			printk("PSERIES LPAR ");
-			nl = 1;
-			break;
-		case PLATFORM_ISERIES_LPAR:
-			printk("ISERIES LPAR ");
-			nl = 1;
-			break;
-		case PLATFORM_POWERMAC:
-			printk("POWERMAC ");
-			nl = 1;
-			break;
-		case PLATFORM_BPA:
-			printk("BPA ");
-			nl = 1;
-			break;
-	}
-	if (nl)
-		printk("\n");
-	print_modules();
-	show_regs(regs);
-	bust_spinlocks(0);
-	spin_unlock_irq(&die_lock);
-
-	if (in_interrupt())
-		panic("Fatal exception in interrupt");
-
-	if (panic_on_oops) {
-		printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n");
-		ssleep(5);
-		panic("Fatal exception");
-	}
-	do_exit(SIGSEGV);
-
-	return 0;
-}
-
-void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
-{
-	siginfo_t info;
-
-	if (!user_mode(regs)) {
-		if (die("Exception in kernel mode", regs, signr))
-			return;
-	}
-
-	memset(&info, 0, sizeof(info));
-	info.si_signo = signr;
-	info.si_code = code;
-	info.si_addr = (void __user *) addr;
-	force_sig_info(signr, &info, current);
-}
-
-void system_reset_exception(struct pt_regs *regs)
-{
-	/* See if any machine dependent calls */
-	if (ppc_md.system_reset_exception)
-		ppc_md.system_reset_exception(regs);
-
-	die("System Reset", regs, 0);
-
-	/* Must die if the interrupt is not recoverable */
-	if (!(regs->msr & MSR_RI))
-		panic("Unrecoverable System Reset");
-
-	/* What should we do here? We could issue a shutdown or hard reset. */
-}
-
-void machine_check_exception(struct pt_regs *regs)
-{
-	int recover = 0;
-
-	/* See if any machine dependent calls */
-	if (ppc_md.machine_check_exception)
-		recover = ppc_md.machine_check_exception(regs);
-
-	if (recover)
-		return;
-
-	if (debugger_fault_handler(regs))
-		return;
-	die("Machine check", regs, 0);
-
-	/* Must die if the interrupt is not recoverable */
-	if (!(regs->msr & MSR_RI))
-		panic("Unrecoverable Machine check");
-}
-
-void unknown_exception(struct pt_regs *regs)
-{
-	printk("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
-	       regs->nip, regs->msr, regs->trap);
-
-	_exception(SIGTRAP, regs, 0, 0);
-}
-
-void instruction_breakpoint_exception(struct pt_regs *regs)
-{
-	if (notify_die(DIE_IABR_MATCH, "iabr_match", regs, 5,
-					5, SIGTRAP) == NOTIFY_STOP)
-		return;
-	if (debugger_iabr_match(regs))
-		return;
-	_exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
-}
-
-void __kprobes single_step_exception(struct pt_regs *regs)
-{
-	regs->msr &= ~MSR_SE;  /* Turn off 'trace' bit */
-
-	if (notify_die(DIE_SSTEP, "single_step", regs, 5,
-					5, SIGTRAP) == NOTIFY_STOP)
-		return;
-	if (debugger_sstep(regs))
-		return;
-
-	_exception(SIGTRAP, regs, TRAP_TRACE, regs->nip);
-}
-
-/*
- * After we have successfully emulated an instruction, we have to
- * check if the instruction was being single-stepped, and if so,
- * pretend we got a single-step exception.  This was pointed out
- * by Kumar Gala.  -- paulus
- */
-static inline void emulate_single_step(struct pt_regs *regs)
-{
-	if (regs->msr & MSR_SE)
-		single_step_exception(regs);
-}
-
-static void parse_fpe(struct pt_regs *regs)
-{
-	int code = 0;
-	unsigned long fpscr;
-
-	flush_fp_to_thread(current);
-
-	fpscr = current->thread.fpscr;
-
-	/* Invalid operation */
-	if ((fpscr & FPSCR_VE) && (fpscr & FPSCR_VX))
-		code = FPE_FLTINV;
-
-	/* Overflow */
-	else if ((fpscr & FPSCR_OE) && (fpscr & FPSCR_OX))
-		code = FPE_FLTOVF;
-
-	/* Underflow */
-	else if ((fpscr & FPSCR_UE) && (fpscr & FPSCR_UX))
-		code = FPE_FLTUND;
-
-	/* Divide by zero */
-	else if ((fpscr & FPSCR_ZE) && (fpscr & FPSCR_ZX))
-		code = FPE_FLTDIV;
-
-	/* Inexact result */
-	else if ((fpscr & FPSCR_XE) && (fpscr & FPSCR_XX))
-		code = FPE_FLTRES;
-
-	_exception(SIGFPE, regs, code, regs->nip);
-}
-
-/*
- * Illegal instruction emulation support.  Return non-zero if we can't
- * emulate, or -EFAULT if the associated memory access caused an access
- * fault.  Return zero on success.
- */
-
-#define INST_MFSPR_PVR		0x7c1f42a6
-#define INST_MFSPR_PVR_MASK	0xfc1fffff
-
-#define INST_DCBA		0x7c0005ec
-#define INST_DCBA_MASK		0x7c0007fe
-
-#define INST_MCRXR		0x7c000400
-#define INST_MCRXR_MASK		0x7c0007fe
-
-static int emulate_instruction(struct pt_regs *regs)
-{
-	unsigned int instword;
-
-	if (!user_mode(regs))
-		return -EINVAL;
-
-	CHECK_FULL_REGS(regs);
-
-	if (get_user(instword, (unsigned int __user *)(regs->nip)))
-		return -EFAULT;
-
-	/* Emulate the mfspr rD, PVR. */
-	if ((instword & INST_MFSPR_PVR_MASK) == INST_MFSPR_PVR) {
-		unsigned int rd;
-
-		rd = (instword >> 21) & 0x1f;
-		regs->gpr[rd] = mfspr(SPRN_PVR);
-		return 0;
-	}
-
-	/* Emulating the dcba insn is just a no-op.  */
-	if ((instword & INST_DCBA_MASK) == INST_DCBA) {
-		static int warned;
-
-		if (!warned) {
-			printk(KERN_WARNING
-			       "process %d (%s) uses obsolete 'dcba' insn\n",
-			       current->pid, current->comm);
-			warned = 1;
-		}
-		return 0;
-	}
-
-	/* Emulate the mcrxr insn.  */
-	if ((instword & INST_MCRXR_MASK) == INST_MCRXR) {
-		static int warned;
-		unsigned int shift;
-
-		if (!warned) {
-			printk(KERN_WARNING
-			       "process %d (%s) uses obsolete 'mcrxr' insn\n",
-			       current->pid, current->comm);
-			warned = 1;
-		}
-
-		shift = (instword >> 21) & 0x1c;
-		regs->ccr &= ~(0xf0000000 >> shift);
-		regs->ccr |= (regs->xer & 0xf0000000) >> shift;
-		regs->xer &= ~0xf0000000;
-		return 0;
-	}
-
-	return -EINVAL;
-}
-
-/*
- * Look through the list of trap instructions that are used for BUG(),
- * BUG_ON() and WARN_ON() and see if we hit one.  At this point we know
- * that the exception was caused by a trap instruction of some kind.
- * Returns 1 if we should continue (i.e. it was a WARN_ON) or 0
- * otherwise.
- */
-extern struct bug_entry __start___bug_table[], __stop___bug_table[];
-
-#ifndef CONFIG_MODULES
-#define module_find_bug(x)	NULL
-#endif
-
-struct bug_entry *find_bug(unsigned long bugaddr)
-{
-	struct bug_entry *bug;
-
-	for (bug = __start___bug_table; bug < __stop___bug_table; ++bug)
-		if (bugaddr == bug->bug_addr)
-			return bug;
-	return module_find_bug(bugaddr);
-}
-
-static int
-check_bug_trap(struct pt_regs *regs)
-{
-	struct bug_entry *bug;
-	unsigned long addr;
-
-	if (regs->msr & MSR_PR)
-		return 0;	/* not in kernel */
-	addr = regs->nip;	/* address of trap instruction */
-	if (addr < PAGE_OFFSET)
-		return 0;
-	bug = find_bug(regs->nip);
-	if (bug == NULL)
-		return 0;
-	if (bug->line & BUG_WARNING_TRAP) {
-		/* this is a WARN_ON rather than BUG/BUG_ON */
-		printk(KERN_ERR "Badness in %s at %s:%d\n",
-		       bug->function, bug->file,
-		       bug->line & ~BUG_WARNING_TRAP);
-		show_stack(current, (void *)regs->gpr[1]);
-		return 1;
-	}
-	printk(KERN_CRIT "kernel BUG in %s at %s:%d!\n",
-	       bug->function, bug->file, bug->line);
-	return 0;
-}
-
-void __kprobes program_check_exception(struct pt_regs *regs)
-{
-	if (debugger_fault_handler(regs))
-		return;
-
-	if (regs->msr & 0x100000) {
-		/* IEEE FP exception */
-		parse_fpe(regs);
-	} else if (regs->msr & 0x20000) {
-		/* trap exception */
-
-		if (notify_die(DIE_BPT, "breakpoint", regs, 5,
-					5, SIGTRAP) == NOTIFY_STOP)
-			return;
-		if (debugger_bpt(regs))
-			return;
-
-		if (check_bug_trap(regs)) {
-			regs->nip += 4;
-			return;
-		}
-		_exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
-
-	} else {
-		/* Privileged or illegal instruction; try to emulate it. */
-		switch (emulate_instruction(regs)) {
-		case 0:
-			regs->nip += 4;
-			emulate_single_step(regs);
-			break;
-
-		case -EFAULT:
-			_exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip);
-			break;
-
-		default:
-			if (regs->msr & 0x40000)
-				/* priveleged */
-				_exception(SIGILL, regs, ILL_PRVOPC, regs->nip);
-			else
-				/* illegal */
-				_exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
-			break;
-		}
-	}
-}
-
-void kernel_fp_unavailable_exception(struct pt_regs *regs)
-{
-	printk(KERN_EMERG "Unrecoverable FP Unavailable Exception "
-			  "%lx at %lx\n", regs->trap, regs->nip);
-	die("Unrecoverable FP Unavailable Exception", regs, SIGABRT);
-}
-
-void altivec_unavailable_exception(struct pt_regs *regs)
-{
-	if (user_mode(regs)) {
-		/* A user program has executed an altivec instruction,
-		   but this kernel doesn't support altivec. */
-		_exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
-		return;
-	}
-	printk(KERN_EMERG "Unrecoverable VMX/Altivec Unavailable Exception "
-			  "%lx at %lx\n", regs->trap, regs->nip);
-	die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT);
-}
-
-extern perf_irq_t perf_irq;
-
-void performance_monitor_exception(struct pt_regs *regs)
-{
-	perf_irq(regs);
-}
-
-void alignment_exception(struct pt_regs *regs)
-{
-	int fixed;
-
-	fixed = fix_alignment(regs);
-
-	if (fixed == 1) {
-		regs->nip += 4;	/* skip over emulated instruction */
-		emulate_single_step(regs);
-		return;
-	}
-
-	/* Operand address was bad */	
-	if (fixed == -EFAULT) {
-		if (user_mode(regs)) {
-			_exception(SIGSEGV, regs, SEGV_MAPERR, regs->dar);
-		} else {
-			/* Search exception table */
-			bad_page_fault(regs, regs->dar, SIGSEGV);
-		}
-
-		return;
-	}
-
-	_exception(SIGBUS, regs, BUS_ADRALN, regs->nip);
-}
-
-#ifdef CONFIG_ALTIVEC
-void altivec_assist_exception(struct pt_regs *regs)
-{
-	int err;
-	siginfo_t info;
-
-	if (!user_mode(regs)) {
-		printk(KERN_EMERG "VMX/Altivec assist exception in kernel mode"
-		       " at %lx\n", regs->nip);
-		die("Kernel VMX/Altivec assist exception", regs, SIGILL);
-	}
-
-	flush_altivec_to_thread(current);
-
-	err = emulate_altivec(regs);
-	if (err == 0) {
-		regs->nip += 4;		/* skip emulated instruction */
-		emulate_single_step(regs);
-		return;
-	}
-
-	if (err == -EFAULT) {
-		/* got an error reading the instruction */
-		info.si_signo = SIGSEGV;
-		info.si_errno = 0;
-		info.si_code = SEGV_MAPERR;
-		info.si_addr = (void __user *) regs->nip;
-		force_sig_info(SIGSEGV, &info, current);
-	} else {
-		/* didn't recognize the instruction */
-		/* XXX quick hack for now: set the non-Java bit in the VSCR */
-		if (printk_ratelimit())
-			printk(KERN_ERR "Unrecognized altivec instruction "
-			       "in %s at %lx\n", current->comm, regs->nip);
-		current->thread.vscr.u[3] |= 0x10000;
-	}
-}
-#endif /* CONFIG_ALTIVEC */
-
-/*
- * We enter here if we get an unrecoverable exception, that is, one
- * that happened at a point where the RI (recoverable interrupt) bit
- * in the MSR is 0.  This indicates that SRR0/1 are live, and that
- * we therefore lost state by taking this exception.
- */
-void unrecoverable_exception(struct pt_regs *regs)
-{
-	printk(KERN_EMERG "Unrecoverable exception %lx at %lx\n",
-	       regs->trap, regs->nip);
-	die("Unrecoverable exception", regs, SIGABRT);
-}
-
-/*
- * We enter here if we discover during exception entry that we are
- * running in supervisor mode with a userspace value in the stack pointer.
- */
-void kernel_bad_stack(struct pt_regs *regs)
-{
-	printk(KERN_EMERG "Bad kernel stack pointer %lx at %lx\n",
-	       regs->gpr[1], regs->nip);
-	die("Bad kernel stack pointer", regs, SIGABRT);
-}
-
-void __init trap_init(void)
-{
-}

^ permalink raw reply

* Re: CPM2 early console
From: Dan Malek @ 2005-09-30 13:58 UTC (permalink / raw)
  To: Alex Zeffertt; +Cc: linuxppc-embedded
In-Reply-To: <20050930142218.348041d6.ajz@cambridgebroadband.com>


On Sep 30, 2005, at 9:22 AM, Alex Zeffertt wrote:

> Are there any drawbacks to this approach?

The general system performance is going to suffer,
and if you really have a cache coherency problem
it only solves the write case and not the read case.


	-- Dan

^ permalink raw reply

* [PATCH 5/9] powerpc: Move lparmap.c to powerpc/platforms
From: Stephen Rothwell @ 2005-09-30 13:56 UTC (permalink / raw)
  To: paulus; +Cc: ppc64-dev, ppc-dev
In-Reply-To: <20050930233602.138b6e27.sfr@canb.auug.org.au>

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

 arch/powerpc/platforms/iseries/lparmap.c |   31 ++++++++++++++++++++++++++++++
 arch/ppc64/kernel/Makefile               |    4 ++--
 arch/ppc64/kernel/lparmap.c              |   31 ------------------------------
 3 files changed, 33 insertions(+), 33 deletions(-)
 create mode 100644 arch/powerpc/platforms/iseries/lparmap.c
 delete mode 100644 arch/ppc64/kernel/lparmap.c

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

d96024c688b59d4d1e60dbb0e226964eb758aa01
diff --git a/arch/powerpc/platforms/iseries/lparmap.c b/arch/powerpc/platforms/iseries/lparmap.c
new file mode 100644
--- /dev/null
+++ b/arch/powerpc/platforms/iseries/lparmap.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2005  Stephen Rothwell  IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <asm/mmu.h>
+#include <asm/page.h>
+#include <asm/iSeries/LparMap.h>
+
+const struct LparMap __attribute__((__section__(".text"))) xLparMap = {
+	.xNumberEsids = HvEsidsToMap,
+	.xNumberRanges = HvRangesToMap,
+	.xSegmentTableOffs = STAB0_PAGE,
+
+	.xEsids = {
+		{ .xKernelEsid = GET_ESID(KERNELBASE),
+		  .xKernelVsid = KERNEL_VSID(KERNELBASE), },
+		{ .xKernelEsid = GET_ESID(VMALLOCBASE),
+		  .xKernelVsid = KERNEL_VSID(VMALLOCBASE), },
+	},
+
+	.xRanges = {
+		{ .xPages = HvPagesToMap,
+		  .xOffset = 0,
+		  .xVPN = KERNEL_VSID(KERNELBASE) << (SID_SHIFT - PAGE_SHIFT),
+		},
+	},
+};
diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile
--- a/arch/ppc64/kernel/Makefile
+++ b/arch/ppc64/kernel/Makefile
@@ -70,8 +70,8 @@ obj-$(CONFIG_KPROBES)		+= kprobes.o
 CFLAGS_ioctl32.o += -Ifs/
 
 ifeq ($(CONFIG_PPC_ISERIES),y)
-arch/ppc64/kernel/head.o: arch/ppc64/kernel/lparmap.s
-AFLAGS_head.o += -Iarch/ppc64/kernel
+arch/ppc64/kernel/head.o: arch/powerpc/platforms/iseries/lparmap.s
+AFLAGS_head.o += -Iarch/powerpc/platforms/iseries
 endif
 
 # These are here while we do the architecture merge
diff --git a/arch/ppc64/kernel/lparmap.c b/arch/ppc64/kernel/lparmap.c
deleted file mode 100644
--- a/arch/ppc64/kernel/lparmap.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2005  Stephen Rothwell  IBM Corp.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#include <asm/mmu.h>
-#include <asm/page.h>
-#include <asm/iSeries/LparMap.h>
-
-const struct LparMap __attribute__((__section__(".text"))) xLparMap = {
-	.xNumberEsids = HvEsidsToMap,
-	.xNumberRanges = HvRangesToMap,
-	.xSegmentTableOffs = STAB0_PAGE,
-
-	.xEsids = {
-		{ .xKernelEsid = GET_ESID(KERNELBASE),
-		  .xKernelVsid = KERNEL_VSID(KERNELBASE), },
-		{ .xKernelEsid = GET_ESID(VMALLOCBASE),
-		  .xKernelVsid = KERNEL_VSID(VMALLOCBASE), },
-	},
-
-	.xRanges = {
-		{ .xPages = HvPagesToMap,
-		  .xOffset = 0,
-		  .xVPN = KERNEL_VSID(KERNELBASE) << (SID_SHIFT - PAGE_SHIFT),
-		},
-	},
-};

^ permalink raw reply

* Re: AW: mpc8xx and LCD
From: Dan Malek @ 2005-09-30 13:55 UTC (permalink / raw)
  To: Fend, Matthias; +Cc: linuxppc-embedded
In-Reply-To: <8D4C69676E66D511A1CB00508BBBB192052D4395@ranmx1.cs.myharris.net>


On Sep 30, 2005, at 7:07 AM, Fend, Matthias wrote:

> As I know at least the S1D13700 is brand new (the people from Epson 
> are working
> on a
> Linux driver at the moment).

OK.

> Do you think it's possible to write the device driver in such a way 
> that
> he also translates the pixel data into the indirect register mode of 
> the
> S1D13700 ?

The only way I can think of is to access protect the "frame buffer",
trap all accesses and then do some translation in software.  Very, very
slow and inefficient.  The most efficient way is for applications (like 
X)
to do this internally.


> ? You mean the 823 has an internal LCD controller -

Yes.

> ..... I know that but I want to
> use a 860 or 855 (we already use them in other products).

Oh well .... :-)


> Do you think it would be the best way to use an 823 and a driver-only 
> display ?

I don't understand the question.

> As there are so many devices with LCD display in use, I thought there 
> could be a
> an easy going standard solution for this, but it seems to be a little 
> bit tricky

There is a standard.  Attach your graphics device to the processor bus 
as
a memory mapped device and use a Linux frame buffer :-)  The complexity
of your graphics requirements will determine how much additional 
software
you have to write.  Since I like to use X-windows, most of the software 
I
end up writing is in that server, not the Linux driver.

Thanks.

	-- Dan

^ permalink raw reply

* [PATCH 4/9] powerpc: more cleanup of powerpc/kernel
From: Stephen Rothwell @ 2005-09-30 13:55 UTC (permalink / raw)
  To: paulus; +Cc: ppc64-dev, ppc-dev
In-Reply-To: <20050930233602.138b6e27.sfr@canb.auug.org.au>

Update head_64.S from arch/ppc64
Remove arch/ppc/kernel/fpu.S

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

 arch/powerpc/kernel/head_64.S |    9 ++-
 arch/ppc/kernel/Makefile      |    1 
 arch/ppc/kernel/fpu.S         |  133 -----------------------------------------
 3 files changed, 7 insertions(+), 136 deletions(-)
 delete mode 100644 arch/ppc/kernel/fpu.S

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

ee400b63f37120987bd12a2fada850c6212d7563
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -1253,7 +1253,7 @@ unrecov_slb:
  *
  * On iSeries, the hypervisor must fill in at least one entry before
  * we get control (with relocate on).  The address is give to the hv
- * as a page number (see xLparMap in LparData.c), so this must be at a
+ * as a page number (see xLparMap in lpardata.c), so this must be at a
  * fixed address (the linker can't compute (u64)&initial_stab >>
  * PAGE_SHIFT).
  */
@@ -1364,6 +1364,7 @@ _STATIC(__start_initialization_iSeries)
 	addi	r2,r2,0x4000
 
 	bl	.iSeries_early_setup
+	bl	.early_setup
 
 	/* relocation is on at this point */
 
@@ -1970,20 +1971,22 @@ _GLOBAL(hmt_start_secondary)
 	blr
 #endif
 
-#if defined(CONFIG_KEXEC) || (defined(CONFIG_SMP) && !defined(CONFIG_PPC_ISERIES))
+#if defined(CONFIG_KEXEC) || defined(CONFIG_SMP)
 _GLOBAL(smp_release_cpus)
 	/* All secondary cpus are spinning on a common
 	 * spinloop, release them all now so they can start
 	 * to spin on their individual paca spinloops.
 	 * For non SMP kernels, the secondary cpus never
 	 * get out of the common spinloop.
+	 * XXX This does nothing useful on iSeries, secondaries are
+	 * already waiting on their paca.
 	 */
 	li	r3,1
 	LOADADDR(r5,__secondary_hold_spinloop)
 	std	r3,0(r5)
 	sync
 	blr
-#endif /* CONFIG_SMP && !CONFIG_PPC_ISERIES */
+#endif /* CONFIG_SMP */
 
 
 /*
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
--- a/arch/ppc/kernel/Makefile
+++ b/arch/ppc/kernel/Makefile
@@ -39,6 +39,7 @@ endif
 # These are here while we do the architecture merge
 vecemu-y			+= ../../powerpc/kernel/vecemu.o
 vector-y			+= ../../powerpc/kernel/vector.o
+fpu-y				+= ../../powerpc/kernel/fpu.o
 
 else
 obj-y				:= entry.o irq.o idle.o time.o misc.o \
diff --git a/arch/ppc/kernel/fpu.S b/arch/ppc/kernel/fpu.S
deleted file mode 100644
--- a/arch/ppc/kernel/fpu.S
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- *  FPU support code, moved here from head.S so that it can be used
- *  by chips which use other head-whatever.S files.
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version
- *  2 of the License, or (at your option) any later version.
- *
- */
-
-#include <linux/config.h>
-#include <asm/processor.h>
-#include <asm/page.h>
-#include <asm/mmu.h>
-#include <asm/pgtable.h>
-#include <asm/cputable.h>
-#include <asm/cache.h>
-#include <asm/thread_info.h>
-#include <asm/ppc_asm.h>
-#include <asm/asm-offsets.h>
-
-/*
- * This task wants to use the FPU now.
- * On UP, disable FP for the task which had the FPU previously,
- * and save its floating-point registers in its thread_struct.
- * Load up this task's FP registers from its thread_struct,
- * enable the FPU for the current task and return to the task.
- */
-	.globl	load_up_fpu
-load_up_fpu:
-	mfmsr	r5
-	ori	r5,r5,MSR_FP
-#ifdef CONFIG_PPC64BRIDGE
-	clrldi	r5,r5,1			/* turn off 64-bit mode */
-#endif /* CONFIG_PPC64BRIDGE */
-	SYNC
-	MTMSRD(r5)			/* enable use of fpu now */
-	isync
-/*
- * For SMP, we don't do lazy FPU switching because it just gets too
- * horrendously complex, especially when a task switches from one CPU
- * to another.  Instead we call giveup_fpu in switch_to.
- */
-#ifndef CONFIG_SMP
-	tophys(r6,0)			/* get __pa constant */
-	addis	r3,r6,last_task_used_math@ha
-	lwz	r4,last_task_used_math@l(r3)
-	cmpwi	0,r4,0
-	beq	1f
-	add	r4,r4,r6
-	addi	r4,r4,THREAD		/* want last_task_used_math->thread */
-	SAVE_32FPRS(0, r4)
-	mffs	fr0
-	stfd	fr0,THREAD_FPSCR-4(r4)
-	lwz	r5,PT_REGS(r4)
-	add	r5,r5,r6
-	lwz	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-	li	r10,MSR_FP|MSR_FE0|MSR_FE1
-	andc	r4,r4,r10		/* disable FP for previous task */
-	stw	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-1:
-#endif /* CONFIG_SMP */
-	/* enable use of FP after return */
-	mfspr	r5,SPRN_SPRG3		/* current task's THREAD (phys) */
-	lwz	r4,THREAD_FPEXC_MODE(r5)
-	ori	r9,r9,MSR_FP		/* enable FP for current */
-	or	r9,r9,r4
-	lfd	fr0,THREAD_FPSCR-4(r5)
-	mtfsf	0xff,fr0
-	REST_32FPRS(0, r5)
-#ifndef CONFIG_SMP
-	subi	r4,r5,THREAD
-	sub	r4,r4,r6
-	stw	r4,last_task_used_math@l(r3)
-#endif /* CONFIG_SMP */
-	/* restore registers and return */
-	/* we haven't used ctr or xer or lr */
-	b	fast_exception_return
-
-/*
- * FP unavailable trap from kernel - print a message, but let
- * the task use FP in the kernel until it returns to user mode.
- */
- 	.globl	KernelFP
-KernelFP:
-	lwz	r3,_MSR(r1)
-	ori	r3,r3,MSR_FP
-	stw	r3,_MSR(r1)		/* enable use of FP after return */
-	lis	r3,86f@h
-	ori	r3,r3,86f@l
-	mr	r4,r2			/* current */
-	lwz	r5,_NIP(r1)
-	bl	printk
-	b	ret_from_except
-86:	.string	"floating point used in kernel (task=%p, pc=%x)\n"
-	.align	4,0
-
-/*
- * giveup_fpu(tsk)
- * Disable FP for the task given as the argument,
- * and save the floating-point registers in its thread_struct.
- * Enables the FPU for use in the kernel on return.
- */
-	.globl	giveup_fpu
-giveup_fpu:
-	mfmsr	r5
-	ori	r5,r5,MSR_FP
-	SYNC_601
-	ISYNC_601
-	MTMSRD(r5)			/* enable use of fpu now */
-	SYNC_601
-	isync
-	cmpwi	0,r3,0
-	beqlr-				/* if no previous owner, done */
-	addi	r3,r3,THREAD	        /* want THREAD of task */
-	lwz	r5,PT_REGS(r3)
-	cmpwi	0,r5,0
-	SAVE_32FPRS(0, r3)
-	mffs	fr0
-	stfd	fr0,THREAD_FPSCR-4(r3)
-	beq	1f
-	lwz	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-	li	r3,MSR_FP|MSR_FE0|MSR_FE1
-	andc	r4,r4,r3		/* disable FP for previous task */
-	stw	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-1:
-#ifndef CONFIG_SMP
-	li	r5,0
-	lis	r4,last_task_used_math@ha
-	stw	r5,last_task_used_math@l(r4)
-#endif /* CONFIG_SMP */
-	blr

^ permalink raw reply

* [PATCH 3/9] powerpc: remove old vector.S files
From: Stephen Rothwell @ 2005-09-30 13:52 UTC (permalink / raw)
  To: paulus; +Cc: ppc64-dev, ppc-dev
In-Reply-To: <20050930233602.138b6e27.sfr@canb.auug.org.au>

Update old kernel/Makefiles to cope

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

---

 arch/ppc/kernel/Makefile   |    1 
 arch/ppc/kernel/vector.S   |  217 --------------------------------------------
 arch/ppc64/kernel/Makefile |    1 
 arch/ppc64/kernel/vector.S |  172 -----------------------------------
 4 files changed, 2 insertions(+), 389 deletions(-)
 delete mode 100644 arch/ppc/kernel/vector.S
 delete mode 100644 arch/ppc64/kernel/vector.S

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

dcff1b170b43d9b8cb83e275cb3451dfd261c23e
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
--- a/arch/ppc/kernel/Makefile
+++ b/arch/ppc/kernel/Makefile
@@ -38,6 +38,7 @@ endif
 
 # These are here while we do the architecture merge
 vecemu-y			+= ../../powerpc/kernel/vecemu.o
+vector-y			+= ../../powerpc/kernel/vector.o
 
 else
 obj-y				:= entry.o irq.o idle.o time.o misc.o \
diff --git a/arch/ppc/kernel/vector.S b/arch/ppc/kernel/vector.S
deleted file mode 100644
--- a/arch/ppc/kernel/vector.S
+++ /dev/null
@@ -1,217 +0,0 @@
-#include <asm/ppc_asm.h>
-#include <asm/processor.h>
-
-/*
- * The routines below are in assembler so we can closely control the
- * usage of floating-point registers.  These routines must be called
- * with preempt disabled.
- */
-	.data
-fpzero:
-	.long	0
-fpone:
-	.long	0x3f800000	/* 1.0 in single-precision FP */
-fphalf:
-	.long	0x3f000000	/* 0.5 in single-precision FP */
-
-	.text
-/*
- * Internal routine to enable floating point and set FPSCR to 0.
- * Don't call it from C; it doesn't use the normal calling convention.
- */
-fpenable:
-	mfmsr	r10
-	ori	r11,r10,MSR_FP
-	mtmsr	r11
-	isync
-	stfd	fr0,24(r1)
-	stfd	fr1,16(r1)
-	stfd	fr31,8(r1)
-	lis	r11,fpzero@ha
-	mffs	fr31
-	lfs	fr1,fpzero@l(r11)
-	mtfsf	0xff,fr1
-	blr
-
-fpdisable:
-	mtfsf	0xff,fr31
-	lfd	fr31,8(r1)
-	lfd	fr1,16(r1)
-	lfd	fr0,24(r1)
-	mtmsr	r10
-	isync
-	blr
-
-/*
- * Vector add, floating point.
- */
-	.globl	vaddfp
-vaddfp:
-	stwu	r1,-32(r1)
-	mflr	r0
-	stw	r0,36(r1)
-	bl	fpenable
-	li	r0,4
-	mtctr	r0
-	li	r6,0
-1:	lfsx	fr0,r4,r6
-	lfsx	fr1,r5,r6
-	fadds	fr0,fr0,fr1
-	stfsx	fr0,r3,r6
-	addi	r6,r6,4
-	bdnz	1b
-	bl	fpdisable
-	lwz	r0,36(r1)
-	mtlr	r0
-	addi	r1,r1,32
-	blr
-
-/*
- * Vector subtract, floating point.
- */
-	.globl	vsubfp
-vsubfp:
-	stwu	r1,-32(r1)
-	mflr	r0
-	stw	r0,36(r1)
-	bl	fpenable
-	li	r0,4
-	mtctr	r0
-	li	r6,0
-1:	lfsx	fr0,r4,r6
-	lfsx	fr1,r5,r6
-	fsubs	fr0,fr0,fr1
-	stfsx	fr0,r3,r6
-	addi	r6,r6,4
-	bdnz	1b
-	bl	fpdisable
-	lwz	r0,36(r1)
-	mtlr	r0
-	addi	r1,r1,32
-	blr
-
-/*
- * Vector multiply and add, floating point.
- */
-	.globl	vmaddfp
-vmaddfp:
-	stwu	r1,-48(r1)
-	mflr	r0
-	stw	r0,52(r1)
-	bl	fpenable
-	stfd	fr2,32(r1)
-	li	r0,4
-	mtctr	r0
-	li	r7,0
-1:	lfsx	fr0,r4,r7
-	lfsx	fr1,r5,r7
-	lfsx	fr2,r6,r7
-	fmadds	fr0,fr0,fr2,fr1
-	stfsx	fr0,r3,r7
-	addi	r7,r7,4
-	bdnz	1b
-	lfd	fr2,32(r1)
-	bl	fpdisable
-	lwz	r0,52(r1)
-	mtlr	r0
-	addi	r1,r1,48
-	blr
-
-/*
- * Vector negative multiply and subtract, floating point.
- */
-	.globl	vnmsubfp
-vnmsubfp:
-	stwu	r1,-48(r1)
-	mflr	r0
-	stw	r0,52(r1)
-	bl	fpenable
-	stfd	fr2,32(r1)
-	li	r0,4
-	mtctr	r0
-	li	r7,0
-1:	lfsx	fr0,r4,r7
-	lfsx	fr1,r5,r7
-	lfsx	fr2,r6,r7
-	fnmsubs	fr0,fr0,fr2,fr1
-	stfsx	fr0,r3,r7
-	addi	r7,r7,4
-	bdnz	1b
-	lfd	fr2,32(r1)
-	bl	fpdisable
-	lwz	r0,52(r1)
-	mtlr	r0
-	addi	r1,r1,48
-	blr
-
-/*
- * Vector reciprocal estimate.  We just compute 1.0/x.
- * r3 -> destination, r4 -> source.
- */
-	.globl	vrefp
-vrefp:
-	stwu	r1,-32(r1)
-	mflr	r0
-	stw	r0,36(r1)
-	bl	fpenable
-	lis	r9,fpone@ha
-	li	r0,4
-	lfs	fr1,fpone@l(r9)
-	mtctr	r0
-	li	r6,0
-1:	lfsx	fr0,r4,r6
-	fdivs	fr0,fr1,fr0
-	stfsx	fr0,r3,r6
-	addi	r6,r6,4
-	bdnz	1b
-	bl	fpdisable
-	lwz	r0,36(r1)
-	mtlr	r0
-	addi	r1,r1,32
-	blr
-
-/*
- * Vector reciprocal square-root estimate, floating point.
- * We use the frsqrte instruction for the initial estimate followed
- * by 2 iterations of Newton-Raphson to get sufficient accuracy.
- * r3 -> destination, r4 -> source.
- */
-	.globl	vrsqrtefp
-vrsqrtefp:
-	stwu	r1,-48(r1)
-	mflr	r0
-	stw	r0,52(r1)
-	bl	fpenable
-	stfd	fr2,32(r1)
-	stfd	fr3,40(r1)
-	stfd	fr4,48(r1)
-	stfd	fr5,56(r1)
-	lis	r9,fpone@ha
-	lis	r8,fphalf@ha
-	li	r0,4
-	lfs	fr4,fpone@l(r9)
-	lfs	fr5,fphalf@l(r8)
-	mtctr	r0
-	li	r6,0
-1:	lfsx	fr0,r4,r6
-	frsqrte	fr1,fr0		/* r = frsqrte(s) */
-	fmuls	fr3,fr1,fr0	/* r * s */
-	fmuls	fr2,fr1,fr5	/* r * 0.5 */
-	fnmsubs	fr3,fr1,fr3,fr4	/* 1 - s * r * r */
-	fmadds	fr1,fr2,fr3,fr1	/* r = r + 0.5 * r * (1 - s * r * r) */
-	fmuls	fr3,fr1,fr0	/* r * s */
-	fmuls	fr2,fr1,fr5	/* r * 0.5 */
-	fnmsubs	fr3,fr1,fr3,fr4	/* 1 - s * r * r */
-	fmadds	fr1,fr2,fr3,fr1	/* r = r + 0.5 * r * (1 - s * r * r) */
-	stfsx	fr1,r3,r6
-	addi	r6,r6,4
-	bdnz	1b
-	lfd	fr5,56(r1)
-	lfd	fr4,48(r1)
-	lfd	fr3,40(r1)
-	lfd	fr2,32(r1)
-	bl	fpdisable
-	lwz	r0,36(r1)
-	mtlr	r0
-	addi	r1,r1,32
-	blr
diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile
--- a/arch/ppc64/kernel/Makefile
+++ b/arch/ppc64/kernel/Makefile
@@ -76,3 +76,4 @@ endif
 
 # These are here while we do the architecture merge
 vecemu-y			+= ../../powerpc/kernel/vecemu.o
+vector-y			+= ../../powerpc/kernel/vector.o
diff --git a/arch/ppc64/kernel/vector.S b/arch/ppc64/kernel/vector.S
deleted file mode 100644
--- a/arch/ppc64/kernel/vector.S
+++ /dev/null
@@ -1,172 +0,0 @@
-#include <asm/ppc_asm.h>
-#include <asm/processor.h>
-
-/*
- * The routines below are in assembler so we can closely control the
- * usage of floating-point registers.  These routines must be called
- * with preempt disabled.
- */
-	.section ".toc","aw"
-fpzero:
-	.tc	FD_0_0[TC],0
-fpone:
-	.tc	FD_3ff00000_0[TC],0x3ff0000000000000	/* 1.0 */
-fphalf:
-	.tc	FD_3fe00000_0[TC],0x3fe0000000000000	/* 0.5 */
-
-	.text
-/*
- * Internal routine to enable floating point and set FPSCR to 0.
- * Don't call it from C; it doesn't use the normal calling convention.
- */
-fpenable:
-	mfmsr	r10
-	ori	r11,r10,MSR_FP
-	mtmsr	r11
-	isync
-	stfd	fr31,-8(r1)
-	stfd	fr0,-16(r1)
-	stfd	fr1,-24(r1)
-	mffs	fr31
-	lfd	fr1,fpzero@toc(r2)
-	mtfsf	0xff,fr1
-	blr
-
-fpdisable:
-	mtlr	r12
-	mtfsf	0xff,fr31
-	lfd	fr1,-24(r1)
-	lfd	fr0,-16(r1)
-	lfd	fr31,-8(r1)
-	mtmsr	r10
-	isync
-	blr
-
-/*
- * Vector add, floating point.
- */
-_GLOBAL(vaddfp)
-	mflr	r12
-	bl	fpenable
-	li	r0,4
-	mtctr	r0
-	li	r6,0
-1:	lfsx	fr0,r4,r6
-	lfsx	fr1,r5,r6
-	fadds	fr0,fr0,fr1
-	stfsx	fr0,r3,r6
-	addi	r6,r6,4
-	bdnz	1b
-	b	fpdisable
-
-/*
- * Vector subtract, floating point.
- */
-_GLOBAL(vsubfp)
-	mflr	r12
-	bl	fpenable
-	li	r0,4
-	mtctr	r0
-	li	r6,0
-1:	lfsx	fr0,r4,r6
-	lfsx	fr1,r5,r6
-	fsubs	fr0,fr0,fr1
-	stfsx	fr0,r3,r6
-	addi	r6,r6,4
-	bdnz	1b
-	b	fpdisable
-
-/*
- * Vector multiply and add, floating point.
- */
-_GLOBAL(vmaddfp)
-	mflr	r12
-	bl	fpenable
-	stfd	fr2,-32(r1)
-	li	r0,4
-	mtctr	r0
-	li	r7,0
-1:	lfsx	fr0,r4,r7
-	lfsx	fr1,r5,r7
-	lfsx	fr2,r6,r7
-	fmadds	fr0,fr0,fr2,fr1
-	stfsx	fr0,r3,r7
-	addi	r7,r7,4
-	bdnz	1b
-	lfd	fr2,-32(r1)
-	b	fpdisable
-
-/*
- * Vector negative multiply and subtract, floating point.
- */
-_GLOBAL(vnmsubfp)
-	mflr	r12
-	bl	fpenable
-	stfd	fr2,-32(r1)
-	li	r0,4
-	mtctr	r0
-	li	r7,0
-1:	lfsx	fr0,r4,r7
-	lfsx	fr1,r5,r7
-	lfsx	fr2,r6,r7
-	fnmsubs	fr0,fr0,fr2,fr1
-	stfsx	fr0,r3,r7
-	addi	r7,r7,4
-	bdnz	1b
-	lfd	fr2,-32(r1)
-	b	fpdisable
-
-/*
- * Vector reciprocal estimate.  We just compute 1.0/x.
- * r3 -> destination, r4 -> source.
- */
-_GLOBAL(vrefp)
-	mflr	r12
-	bl	fpenable
-	li	r0,4
-	lfd	fr1,fpone@toc(r2)
-	mtctr	r0
-	li	r6,0
-1:	lfsx	fr0,r4,r6
-	fdivs	fr0,fr1,fr0
-	stfsx	fr0,r3,r6
-	addi	r6,r6,4
-	bdnz	1b
-	b	fpdisable
-
-/*
- * Vector reciprocal square-root estimate, floating point.
- * We use the frsqrte instruction for the initial estimate followed
- * by 2 iterations of Newton-Raphson to get sufficient accuracy.
- * r3 -> destination, r4 -> source.
- */
-_GLOBAL(vrsqrtefp)
-	mflr	r12
-	bl	fpenable
-	stfd	fr2,-32(r1)
-	stfd	fr3,-40(r1)
-	stfd	fr4,-48(r1)
-	stfd	fr5,-56(r1)
-	li	r0,4
-	lfd	fr4,fpone@toc(r2)
-	lfd	fr5,fphalf@toc(r2)
-	mtctr	r0
-	li	r6,0
-1:	lfsx	fr0,r4,r6
-	frsqrte	fr1,fr0		/* r = frsqrte(s) */
-	fmuls	fr3,fr1,fr0	/* r * s */
-	fmuls	fr2,fr1,fr5	/* r * 0.5 */
-	fnmsubs	fr3,fr1,fr3,fr4	/* 1 - s * r * r */
-	fmadds	fr1,fr2,fr3,fr1	/* r = r + 0.5 * r * (1 - s * r * r) */
-	fmuls	fr3,fr1,fr0	/* r * s */
-	fmuls	fr2,fr1,fr5	/* r * 0.5 */
-	fnmsubs	fr3,fr1,fr3,fr4	/* 1 - s * r * r */
-	fmadds	fr1,fr2,fr3,fr1	/* r = r + 0.5 * r * (1 - s * r * r) */
-	stfsx	fr1,r3,r6
-	addi	r6,r6,4
-	bdnz	1b
-	lfd	fr5,-56(r1)
-	lfd	fr4,-48(r1)
-	lfd	fr3,-40(r1)
-	lfd	fr2,-32(r1)
-	b	fpdisable

^ 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