diff --git a/[refs] b/[refs]
index 06d6363a74b5..d525da24c317 100644
--- a/[refs]
+++ b/[refs]
@@ -1,2 +1,2 @@
---
-refs/heads/master: 14cf11af6cf608eb8c23e989ddb17a715ddce109
+refs/heads/master: 9f497581fda5fd804e9ebd7d8f6d80c3a0e9f883
diff --git a/trunk/Documentation/DocBook/kernel-hacking.tmpl b/trunk/Documentation/DocBook/kernel-hacking.tmpl
index 582032eea872..6367bba32d22 100644
--- a/trunk/Documentation/DocBook/kernel-hacking.tmpl
+++ b/trunk/Documentation/DocBook/kernel-hacking.tmpl
@@ -1105,7 +1105,7 @@ static struct block_device_operations opt_fops = {
- Function names as strings (__FUNCTION__).
+ Function names as strings (__func__).
diff --git a/trunk/Documentation/device-mapper/snapshot.txt b/trunk/Documentation/device-mapper/snapshot.txt
deleted file mode 100644
index dca274ff4005..000000000000
--- a/trunk/Documentation/device-mapper/snapshot.txt
+++ /dev/null
@@ -1,73 +0,0 @@
-Device-mapper snapshot support
-==============================
-
-Device-mapper allows you, without massive data copying:
-
-*) To create snapshots of any block device i.e. mountable, saved states of
-the block device which are also writable without interfering with the
-original content;
-*) To create device "forks", i.e. multiple different versions of the
-same data stream.
-
-
-In both cases, dm copies only the chunks of data that get changed and
-uses a separate copy-on-write (COW) block device for storage.
-
-
-There are two dm targets available: snapshot and snapshot-origin.
-
-*) snapshot-origin
-
-which will normally have one or more snapshots based on it.
-You must create the snapshot-origin device before you can create snapshots.
-Reads will be mapped directly to the backing device. For each write, the
-original data will be saved in the of each snapshot to keep
-its visible content unchanged, at least until the fills up.
-
-
-*) snapshot
-
-A snapshot is created of the block device. Changed chunks of
- sectors will be stored on the . Writes will
-only go to the . Reads will come from the or
-from for unchanged data. will often be
-smaller than the origin and if it fills up the snapshot will become
-useless and be disabled, returning errors. So it is important to monitor
-the amount of free space and expand the before it fills up.
-
- is P (Persistent) or N (Not persistent - will not survive
-after reboot).
-
-
-How this is used by LVM2
-========================
-When you create the first LVM2 snapshot of a volume, four dm devices are used:
-
-1) a device containing the original mapping table of the source volume;
-2) a device used as the ;
-3) a "snapshot" device, combining #1 and #2, which is the visible snapshot
- volume;
-4) the "original" volume (which uses the device number used by the original
- source volume), whose table is replaced by a "snapshot-origin" mapping
- from device #1.
-
-A fixed naming scheme is used, so with the following commands:
-
-lvcreate -L 1G -n base volumeGroup
-lvcreate -L 100M --snapshot -n snap volumeGroup/base
-
-we'll have this situation (with volumes in above order):
-
-# dmsetup table|grep volumeGroup
-
-volumeGroup-base-real: 0 2097152 linear 8:19 384
-volumeGroup-snap-cow: 0 204800 linear 8:19 2097536
-volumeGroup-snap: 0 2097152 snapshot 254:11 254:12 P 16
-volumeGroup-base: 0 2097152 snapshot-origin 254:11
-
-# ls -lL /dev/mapper/volumeGroup-*
-brw------- 1 root root 254, 11 29 ago 18:15 /dev/mapper/volumeGroup-base-real
-brw------- 1 root root 254, 12 29 ago 18:15 /dev/mapper/volumeGroup-snap-cow
-brw------- 1 root root 254, 13 29 ago 18:15 /dev/mapper/volumeGroup-snap
-brw------- 1 root root 254, 10 29 ago 18:14 /dev/mapper/volumeGroup-base
-
diff --git a/trunk/Documentation/sparse.txt b/trunk/Documentation/sparse.txt
index 1829009db771..5df44dc894e5 100644
--- a/trunk/Documentation/sparse.txt
+++ b/trunk/Documentation/sparse.txt
@@ -51,9 +51,9 @@ or you don't get any checking at all.
Where to get sparse
~~~~~~~~~~~~~~~~~~~
-With git, you can just get it from
+With BK, you can just get it from
- rsync://rsync.kernel.org/pub/scm/devel/sparse/sparse.git
+ bk://sparse.bkbits.net/sparse
and DaveJ has tar-balls at
diff --git a/trunk/Documentation/usb/URB.txt b/trunk/Documentation/usb/URB.txt
index a49e5f2c2b46..d59b95cc6f1b 100644
--- a/trunk/Documentation/usb/URB.txt
+++ b/trunk/Documentation/usb/URB.txt
@@ -1,6 +1,5 @@
Revised: 2000-Dec-05.
Again: 2002-Jul-06
-Again: 2005-Sep-19
NOTE:
@@ -19,8 +18,8 @@ called USB Request Block, or URB for short.
and deliver the data and status back.
- Execution of an URB is inherently an asynchronous operation, i.e. the
- usb_submit_urb(urb) call returns immediately after it has successfully
- queued the requested action.
+ usb_submit_urb(urb) call returns immediately after it has successfully queued
+ the requested action.
- Transfers for one URB can be canceled with usb_unlink_urb(urb) at any time.
@@ -95,9 +94,8 @@ To free an URB, use
void usb_free_urb(struct urb *urb)
-You may free an urb that you've submitted, but which hasn't yet been
-returned to you in a completion callback. It will automatically be
-deallocated when it is no longer in use.
+You may not free an urb that you've submitted, but which hasn't yet been
+returned to you in a completion callback.
1.4. What has to be filled in?
@@ -147,36 +145,30 @@ to get seamless ISO streaming.
1.6. How to cancel an already running URB?
-There are two ways to cancel an URB you've submitted but which hasn't
-been returned to your driver yet. For an asynchronous cancel, call
+For an URB which you've submitted, but which hasn't been returned to
+your driver by the host controller, call
int usb_unlink_urb(struct urb *urb)
It removes the urb from the internal list and frees all allocated
-HW descriptors. The status is changed to reflect unlinking. Note
-that the URB will not normally have finished when usb_unlink_urb()
-returns; you must still wait for the completion handler to be called.
+HW descriptors. The status is changed to reflect unlinking. After
+usb_unlink_urb() returns with that status code, you can free the URB
+with usb_free_urb().
-To cancel an URB synchronously, call
-
- void usb_kill_urb(struct urb *urb)
-
-It does everything usb_unlink_urb does, and in addition it waits
-until after the URB has been returned and the completion handler
-has finished. It also marks the URB as temporarily unusable, so
-that if the completion handler or anyone else tries to resubmit it
-they will get a -EPERM error. Thus you can be sure that when
-usb_kill_urb() returns, the URB is totally idle.
+There is also an asynchronous unlink mode. To use this, set the
+the URB_ASYNC_UNLINK flag in urb->transfer flags before calling
+usb_unlink_urb(). When using async unlinking, the URB will not
+normally be unlinked when usb_unlink_urb() returns. Instead, wait
+for the completion handler to be called.
1.7. What about the completion handler?
The handler is of the following type:
- typedef void (*usb_complete_t)(struct urb *, struct pt_regs *)
+ typedef void (*usb_complete_t)(struct urb *);
-I.e., it gets the URB that caused the completion call, plus the
-register values at the time of the corresponding interrupt (if any).
+i.e. it gets just the URB that caused the completion call.
In the completion handler, you should have a look at urb->status to
detect any USB errors. Since the context parameter is included in the URB,
you can pass information to the completion handler.
@@ -184,11 +176,17 @@ you can pass information to the completion handler.
Note that even when an error (or unlink) is reported, data may have been
transferred. That's because USB transfers are packetized; it might take
sixteen packets to transfer your 1KByte buffer, and ten of them might
-have transferred succesfully before the completion was called.
+have transferred succesfully before the completion is called.
NOTE: ***** WARNING *****
-NEVER SLEEP IN A COMPLETION HANDLER. These are normally called
+Don't use urb->dev field in your completion handler; it's cleared
+as part of giving urbs back to drivers. (Addressing an issue with
+ownership of periodic URBs, which was otherwise ambiguous.) Instead,
+use urb->context to hold all the data your driver needs.
+
+NOTE: ***** WARNING *****
+Also, NEVER SLEEP IN A COMPLETION HANDLER. These are normally called
during hardware interrupt processing. If you can, defer substantial
work to a tasklet (bottom half) to keep system latencies low. You'll
probably need to use spinlocks to protect data structures you manipulate
@@ -231,10 +229,24 @@ ISO data with some other event stream.
Interrupt transfers, like isochronous transfers, are periodic, and happen
in intervals that are powers of two (1, 2, 4 etc) units. Units are frames
for full and low speed devices, and microframes for high speed ones.
+
+Currently, after you submit one interrupt URB, that urb is owned by the
+host controller driver until you cancel it with usb_unlink_urb(). You
+may unlink interrupt urbs in their completion handlers, if you need to.
+
+After a transfer completion is called, the URB is automagically resubmitted.
+THIS BEHAVIOR IS EXPECTED TO BE REMOVED!!
+
+Interrupt transfers may only send (or receive) the "maxpacket" value for
+the given interrupt endpoint; if you need more data, you will need to
+copy that data out of (or into) another buffer. Similarly, you can't
+queue interrupt transfers.
+THESE RESTRICTIONS ARE EXPECTED TO BE REMOVED!!
+
+Note that this automagic resubmission model does make it awkward to use
+interrupt OUT transfers. The portable solution involves unlinking those
+OUT urbs after the data is transferred, and perhaps submitting a final
+URB for a short packet.
+
The usb_submit_urb() call modifies urb->interval to the implemented interval
value that is less than or equal to the requested interval value.
-
-In Linux 2.6, unlike earlier versions, interrupt URBs are not automagically
-restarted when they complete. They end when the completion handler is
-called, just like other URBs. If you want an interrupt URB to be restarted,
-your completion handler must resubmit it.
diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS
index 7d1dd5bad39a..dc8f3babcabd 100644
--- a/trunk/MAINTAINERS
+++ b/trunk/MAINTAINERS
@@ -1063,6 +1063,8 @@ M: wli@holomorphy.com
S: Maintained
I2C SUBSYSTEM
+P: Greg Kroah-Hartman
+M: greg@kroah.com
P: Jean Delvare
M: khali@linux-fr.org
L: lm-sensors@lm-sensors.org
@@ -1402,18 +1404,6 @@ L: linux-kernel@vger.kernel.org
L: fastboot@osdl.org
S: Maintained
-KPROBES
-P: Prasanna S Panchamukhi
-M: prasanna@in.ibm.com
-P: Ananth N Mavinakayanahalli
-M: ananth@in.ibm.com
-P: Anil S Keshavamurthy
-M: anil.s.keshavamurthy@intel.com
-P: David S. Miller
-M: davem@davemloft.net
-L: linux-kernel@vger.kernel.org
-S: Maintained
-
LANMEDIA WAN CARD DRIVER
P: Andrew Stanley-Jones
M: asj@lanmedia.com
@@ -2276,12 +2266,6 @@ M: kristen.c.accardi@intel.com
L: pcihpd-discuss@lists.sourceforge.net
S: Maintained
-SKGE, SKY2 10/100/1000 GIGABIT ETHERNET DRIVERS
-P: Stephen Hemminger
-M: shemminger@osdl.org
-L: netdev@vger.kernel.org
-S: Maintained
-
SPARC (sparc32):
P: William L. Irwin
M: wli@holomorphy.com
diff --git a/trunk/Makefile b/trunk/Makefile
index 8cf6becf68dc..4e0d7c68d223 100644
--- a/trunk/Makefile
+++ b/trunk/Makefile
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 14
-EXTRAVERSION =-rc2
+EXTRAVERSION =-rc1
NAME=Affluent Albatross
# *DOCUMENTATION*
diff --git a/trunk/README b/trunk/README
index d1edcc7adabe..76dd780d88ed 100644
--- a/trunk/README
+++ b/trunk/README
@@ -149,9 +149,6 @@ CONFIGURING the kernel:
"make gconfig" X windows (Gtk) based configuration tool.
"make oldconfig" Default all questions based on the contents of
your existing ./.config file.
- "make silentoldconfig"
- Like above, but avoids cluttering the screen
- with questions already answered.
NOTES on "make config":
- having unnecessary drivers will make the kernel bigger, and can
@@ -172,6 +169,9 @@ CONFIGURING the kernel:
should probably answer 'n' to the questions for
"development", "experimental", or "debugging" features.
+ - Check the top Makefile for further site-dependent configuration
+ (default SVGA mode etc).
+
COMPILING the kernel:
- Make sure you have gcc 2.95.3 available.
@@ -199,9 +199,6 @@ COMPILING the kernel:
are installing a new kernel with the same version number as your
working kernel, make a backup of your modules directory before you
do a "make modules_install".
- Alternatively, before compiling, use the kernel config option
- "LOCALVERSION" to append a unique suffix to the regular kernel version.
- LOCALVERSION can be set in the "General Setup" menu.
- In order to boot your new kernel, you'll need to copy the kernel
image (e.g. .../linux/arch/i386/boot/bzImage after compilation)
diff --git a/trunk/arch/alpha/kernel/process.c b/trunk/arch/alpha/kernel/process.c
index eb20c3afff58..fa98dae3cd98 100644
--- a/trunk/arch/alpha/kernel/process.c
+++ b/trunk/arch/alpha/kernel/process.c
@@ -127,10 +127,6 @@ common_shutdown_1(void *generic_ptr)
/* If booted from SRM, reset some of the original environment. */
if (alpha_using_srm) {
#ifdef CONFIG_DUMMY_CONSOLE
- /* If we've gotten here after SysRq-b, leave interrupt
- context before taking over the console. */
- if (in_interrupt())
- irq_exit();
/* This has the effect of resetting the VGA video origin. */
take_over_console(&dummy_con, 0, MAX_NR_CONSOLES-1, 1);
#endif
diff --git a/trunk/arch/alpha/kernel/sys_dp264.c b/trunk/arch/alpha/kernel/sys_dp264.c
index d5da6b1b28ee..9e36b07fa940 100644
--- a/trunk/arch/alpha/kernel/sys_dp264.c
+++ b/trunk/arch/alpha/kernel/sys_dp264.c
@@ -394,22 +394,6 @@ clipper_init_irq(void)
* 10 64 bit PCI option slot 3 (not bus 0)
*/
-static int __init
-isa_irq_fixup(struct pci_dev *dev, int irq)
-{
- u8 irq8;
-
- if (irq > 0)
- return irq;
-
- /* This interrupt is routed via ISA bridge, so we'll
- just have to trust whatever value the console might
- have assigned. */
- pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq8);
-
- return irq8 & 0xf;
-}
-
static int __init
dp264_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
@@ -423,13 +407,25 @@ dp264_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{ 16+ 3, 16+ 3, 16+ 2, 16+ 1, 16+ 0} /* IdSel 10 slot 3 */
};
const long min_idsel = 5, max_idsel = 10, irqs_per_slot = 5;
+
struct pci_controller *hose = dev->sysdata;
int irq = COMMON_TABLE_LOOKUP;
- if (irq > 0)
+ if (irq > 0) {
irq += 16 * hose->index;
+ } else {
+ /* ??? The Contaq IDE controller on the ISA bridge uses
+ "legacy" interrupts 14 and 15. I don't know if anything
+ can wind up at the same slot+pin on hose1, so we'll
+ just have to trust whatever value the console might
+ have assigned. */
+
+ u8 irq8;
+ pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq8);
+ irq = irq8;
+ }
- return isa_irq_fixup(dev, irq);
+ return irq;
}
static int __init
@@ -457,8 +453,7 @@ monet_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{ 24, 24, 25, 26, 27} /* IdSel 15 slot 5 PCI2*/
};
const long min_idsel = 3, max_idsel = 15, irqs_per_slot = 5;
-
- return isa_irq_fixup(dev, COMMON_TABLE_LOOKUP);
+ return COMMON_TABLE_LOOKUP;
}
static u8 __init
@@ -512,8 +507,7 @@ webbrick_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{ 47, 47, 46, 45, 44}, /* IdSel 17 slot 3 */
};
const long min_idsel = 7, max_idsel = 17, irqs_per_slot = 5;
-
- return isa_irq_fixup(dev, COMMON_TABLE_LOOKUP);
+ return COMMON_TABLE_LOOKUP;
}
static int __init
@@ -530,13 +524,14 @@ clipper_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{ -1, -1, -1, -1, -1} /* IdSel 7 ISA Bridge */
};
const long min_idsel = 1, max_idsel = 7, irqs_per_slot = 5;
+
struct pci_controller *hose = dev->sysdata;
int irq = COMMON_TABLE_LOOKUP;
if (irq > 0)
irq += 16 * hose->index;
- return isa_irq_fixup(dev, irq);
+ return irq;
}
static void __init
diff --git a/trunk/arch/arm/boot/compressed/ofw-shark.c b/trunk/arch/arm/boot/compressed/ofw-shark.c
index 465c54b6b128..7f6f5db0d060 100644
--- a/trunk/arch/arm/boot/compressed/ofw-shark.c
+++ b/trunk/arch/arm/boot/compressed/ofw-shark.c
@@ -256,5 +256,5 @@ asmlinkage void ofw_init(ofw_handle_t o, int *nomr, int *pointer)
temp[11]='\0';
mem_len = OF_getproplen(o,phandle, temp);
OF_getprop(o,phandle, temp, buffer, mem_len);
- * ((unsigned char *) &pointer[32]) = ((unsigned char *) buffer)[mem_len-2];
+ (unsigned char) pointer[32] = ((unsigned char *) buffer)[mem_len-2];
}
diff --git a/trunk/arch/arm/kernel/entry-armv.S b/trunk/arch/arm/kernel/entry-armv.S
index 93b5e8e5292e..7152bfbee581 100644
--- a/trunk/arch/arm/kernel/entry-armv.S
+++ b/trunk/arch/arm/kernel/entry-armv.S
@@ -537,7 +537,7 @@ ENTRY(__switch_to)
#ifdef CONFIG_CPU_MPCORE
clrex
#else
- strex r5, r4, [ip] @ Clear exclusive monitor
+ strex r3, r4, [ip] @ Clear exclusive monitor
#endif
#endif
#if defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_IWMMXT)
diff --git a/trunk/arch/arm/kernel/io.c b/trunk/arch/arm/kernel/io.c
index 1f6822dfae74..6c20c1188b60 100644
--- a/trunk/arch/arm/kernel/io.c
+++ b/trunk/arch/arm/kernel/io.c
@@ -7,7 +7,7 @@
* Copy data from IO memory space to "real" memory space.
* This needs to be optimized.
*/
-void _memcpy_fromio(void *to, const volatile void __iomem *from, size_t count)
+void _memcpy_fromio(void *to, void __iomem *from, size_t count)
{
unsigned char *t = to;
while (count) {
@@ -22,7 +22,7 @@ void _memcpy_fromio(void *to, const volatile void __iomem *from, size_t count)
* Copy data from "real" memory space to IO memory space.
* This needs to be optimized.
*/
-void _memcpy_toio(volatile void __iomem *to, const void *from, size_t count)
+void _memcpy_toio(void __iomem *to, const void *from, size_t count)
{
const unsigned char *f = from;
while (count) {
@@ -37,7 +37,7 @@ void _memcpy_toio(volatile void __iomem *to, const void *from, size_t count)
* "memset" on IO memory space.
* This needs to be optimized.
*/
-void _memset_io(volatile void __iomem *dst, int c, size_t count)
+void _memset_io(void __iomem *dst, int c, size_t count)
{
while (count) {
count--;
diff --git a/trunk/arch/arm/kernel/semaphore.c b/trunk/arch/arm/kernel/semaphore.c
index 4c31f2923055..ac423e3e224b 100644
--- a/trunk/arch/arm/kernel/semaphore.c
+++ b/trunk/arch/arm/kernel/semaphore.c
@@ -178,7 +178,7 @@ int __down_trylock(struct semaphore * sem)
* registers (r0 to r3 and lr), but not ip, as we use it as a return
* value in some cases..
*/
-asm(" .section .sched.text,\"ax\",%progbits \n\
+asm(" .section .sched.text,\"ax\" \n\
.align 5 \n\
.globl __down_failed \n\
__down_failed: \n\
diff --git a/trunk/arch/arm/kernel/traps.c b/trunk/arch/arm/kernel/traps.c
index e7d22dbcb691..4554c961251c 100644
--- a/trunk/arch/arm/kernel/traps.c
+++ b/trunk/arch/arm/kernel/traps.c
@@ -624,9 +624,6 @@ void __attribute__((noreturn)) __bug(const char *file, int line, void *data)
printk(" - extra data = %p", data);
printk("\n");
*(int *)0 = 0;
-
- /* Avoid "noreturn function does return" */
- for (;;);
}
EXPORT_SYMBOL(__bug);
diff --git a/trunk/arch/arm/kernel/vmlinux.lds.S b/trunk/arch/arm/kernel/vmlinux.lds.S
index 08e58ecd44be..ad2d66c93a5c 100644
--- a/trunk/arch/arm/kernel/vmlinux.lds.S
+++ b/trunk/arch/arm/kernel/vmlinux.lds.S
@@ -23,20 +23,20 @@ SECTIONS
*(.init.text)
_einittext = .;
__proc_info_begin = .;
- *(.proc.info.init)
+ *(.proc.info)
__proc_info_end = .;
__arch_info_begin = .;
- *(.arch.info.init)
+ *(.arch.info)
__arch_info_end = .;
__tagtable_begin = .;
- *(.taglist.init)
+ *(.taglist)
__tagtable_end = .;
. = ALIGN(16);
__setup_start = .;
*(.init.setup)
__setup_end = .;
__early_begin = .;
- *(.early_param.init)
+ *(__early_param)
__early_end = .;
__initcall_start = .;
*(.initcall1.init)
diff --git a/trunk/arch/arm/mach-ixp4xx/ixdp425-setup.c b/trunk/arch/arm/mach-ixp4xx/ixdp425-setup.c
index 39b06ed80646..ae1fa099d5fa 100644
--- a/trunk/arch/arm/mach-ixp4xx/ixdp425-setup.c
+++ b/trunk/arch/arm/mach-ixp4xx/ixdp425-setup.c
@@ -123,7 +123,6 @@ static void __init ixdp425_init(void)
platform_add_devices(ixdp425_devices, ARRAY_SIZE(ixdp425_devices));
}
-#ifdef CONFIG_ARCH_IXDP465
MACHINE_START(IXDP425, "Intel IXDP425 Development Platform")
/* Maintainer: MontaVista Software, Inc. */
.phys_ram = PHYS_OFFSET,
@@ -135,9 +134,7 @@ MACHINE_START(IXDP425, "Intel IXDP425 Development Platform")
.boot_params = 0x0100,
.init_machine = ixdp425_init,
MACHINE_END
-#endif
-#ifdef CONFIG_MACH_IXDP465
MACHINE_START(IXDP465, "Intel IXDP465 Development Platform")
/* Maintainer: MontaVista Software, Inc. */
.phys_ram = PHYS_OFFSET,
@@ -149,9 +146,7 @@ MACHINE_START(IXDP465, "Intel IXDP465 Development Platform")
.boot_params = 0x0100,
.init_machine = ixdp425_init,
MACHINE_END
-#endif
-#ifdef CONFIG_ARCH_PRPMC1100
MACHINE_START(IXCDP1100, "Intel IXCDP1100 Development Platform")
/* Maintainer: MontaVista Software, Inc. */
.phys_ram = PHYS_OFFSET,
@@ -163,7 +158,6 @@ MACHINE_START(IXCDP1100, "Intel IXCDP1100 Development Platform")
.boot_params = 0x0100,
.init_machine = ixdp425_init,
MACHINE_END
-#endif
/*
* Avila is functionally equivalent to IXDP425 except that it adds
diff --git a/trunk/arch/arm/mach-s3c2410/mach-anubis.c b/trunk/arch/arm/mach-s3c2410/mach-anubis.c
index 7c05f27fe1d6..f87aa0b669ad 100644
--- a/trunk/arch/arm/mach-s3c2410/mach-anubis.c
+++ b/trunk/arch/arm/mach-s3c2410/mach-anubis.c
@@ -12,7 +12,6 @@
*
* Modifications:
* 02-May-2005 BJD Copied from mach-bast.c
- * 20-Sep-2005 BJD Added static to non-exported items
*/
#include
@@ -233,7 +232,7 @@ static struct s3c24xx_board anubis_board __initdata = {
.clocks_count = ARRAY_SIZE(anubis_clocks)
};
-static void __init anubis_map_io(void)
+void __init anubis_map_io(void)
{
/* initialise the clocks */
diff --git a/trunk/arch/arm/mach-s3c2410/mach-bast.c b/trunk/arch/arm/mach-s3c2410/mach-bast.c
index ed1f07d7252f..1a3367da6408 100644
--- a/trunk/arch/arm/mach-s3c2410/mach-bast.c
+++ b/trunk/arch/arm/mach-s3c2410/mach-bast.c
@@ -31,7 +31,6 @@
* 17-Jul-2005 BJD Changed to platform device for SuperIO 16550s
* 25-Jul-2005 BJD Removed ASIX static mappings
* 27-Jul-2005 BJD Ensure maximum frequency of i2c bus
- * 20-Sep-2005 BJD Added static to non-exported items
*/
#include
@@ -429,7 +428,7 @@ static struct s3c24xx_board bast_board __initdata = {
.clocks_count = ARRAY_SIZE(bast_clocks)
};
-static void __init bast_map_io(void)
+void __init bast_map_io(void)
{
/* initialise the clocks */
diff --git a/trunk/arch/arm/mach-s3c2410/mach-h1940.c b/trunk/arch/arm/mach-s3c2410/mach-h1940.c
index fb3cb01266e5..6ff1889fbd21 100644
--- a/trunk/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/trunk/arch/arm/mach-s3c2410/mach-h1940.c
@@ -24,7 +24,6 @@
* 10-Jan-2005 BJD Removed include of s3c2410.h
* 14-Jan-2005 BJD Added clock init
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
- * 20-Sep-2005 BJD Added static to non-exported items
*/
#include
@@ -148,7 +147,7 @@ static struct s3c24xx_board h1940_board __initdata = {
.devices_count = ARRAY_SIZE(h1940_devices)
};
-static void __init h1940_map_io(void)
+void __init h1940_map_io(void)
{
s3c24xx_init_io(h1940_iodesc, ARRAY_SIZE(h1940_iodesc));
s3c24xx_init_clocks(0);
@@ -156,13 +155,13 @@ static void __init h1940_map_io(void)
s3c24xx_set_board(&h1940_board);
}
-static void __init h1940_init_irq(void)
+void __init h1940_init_irq(void)
{
s3c24xx_init_irq();
}
-static void __init h1940_init(void)
+void __init h1940_init(void)
{
set_s3c2410fb_info(&h1940_lcdcfg);
}
diff --git a/trunk/arch/arm/mach-s3c2410/mach-n30.c b/trunk/arch/arm/mach-s3c2410/mach-n30.c
index 5c0f2b091f95..66bf5bb2b3db 100644
--- a/trunk/arch/arm/mach-s3c2410/mach-n30.c
+++ b/trunk/arch/arm/mach-s3c2410/mach-n30.c
@@ -97,7 +97,7 @@ static struct s3c24xx_board n30_board __initdata = {
.devices_count = ARRAY_SIZE(n30_devices)
};
-static void __init n30_map_io(void)
+void __init n30_map_io(void)
{
s3c24xx_init_io(n30_iodesc, ARRAY_SIZE(n30_iodesc));
s3c24xx_init_clocks(0);
@@ -105,14 +105,14 @@ static void __init n30_map_io(void)
s3c24xx_set_board(&n30_board);
}
-static void __init n30_init_irq(void)
+void __init n30_init_irq(void)
{
s3c24xx_init_irq();
}
/* GPB3 is the line that controls the pull-up for the USB D+ line */
-static void __init n30_init(void)
+void __init n30_init(void)
{
s3c_device_i2c.dev.platform_data = &n30_i2ccfg;
diff --git a/trunk/arch/arm/mach-s3c2410/mach-nexcoder.c b/trunk/arch/arm/mach-s3c2410/mach-nexcoder.c
index c22f8216032d..d24c242414ca 100644
--- a/trunk/arch/arm/mach-s3c2410/mach-nexcoder.c
+++ b/trunk/arch/arm/mach-s3c2410/mach-nexcoder.c
@@ -136,7 +136,7 @@ static void __init nexcoder_sensorboard_init(void)
s3c2410_gpio_cfgpin(S3C2410_GPF2, S3C2410_GPF2_OUTP); // CAM_GPIO6 => CAM_PWRDN
}
-static void __init nexcoder_map_io(void)
+void __init nexcoder_map_io(void)
{
s3c24xx_init_io(nexcoder_iodesc, ARRAY_SIZE(nexcoder_iodesc));
s3c24xx_init_clocks(0);
diff --git a/trunk/arch/arm/mach-s3c2410/mach-otom.c b/trunk/arch/arm/mach-s3c2410/mach-otom.c
index ad1459e402e2..d901ed492ff5 100644
--- a/trunk/arch/arm/mach-s3c2410/mach-otom.c
+++ b/trunk/arch/arm/mach-s3c2410/mach-otom.c
@@ -105,7 +105,7 @@ static struct s3c24xx_board otom11_board __initdata = {
};
-static void __init otom11_map_io(void)
+void __init otom11_map_io(void)
{
s3c24xx_init_io(otom11_iodesc, ARRAY_SIZE(otom11_iodesc));
s3c24xx_init_clocks(0);
diff --git a/trunk/arch/arm/mach-s3c2410/mach-rx3715.c b/trunk/arch/arm/mach-s3c2410/mach-rx3715.c
index 22d9e070fd68..a73d61c1de46 100644
--- a/trunk/arch/arm/mach-s3c2410/mach-rx3715.c
+++ b/trunk/arch/arm/mach-s3c2410/mach-rx3715.c
@@ -16,7 +16,6 @@
* 14-Jan-2005 BJD Added new clock init
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
* 14-Mar-2005 BJD Fixed __iomem warnings
- * 20-Sep-2005 BJD Added static to non-exported items
*/
#include
@@ -109,7 +108,7 @@ static struct s3c24xx_board rx3715_board __initdata = {
.devices_count = ARRAY_SIZE(rx3715_devices)
};
-static void __init rx3715_map_io(void)
+void __init rx3715_map_io(void)
{
s3c24xx_init_io(rx3715_iodesc, ARRAY_SIZE(rx3715_iodesc));
s3c24xx_init_clocks(16934000);
@@ -117,7 +116,7 @@ static void __init rx3715_map_io(void)
s3c24xx_set_board(&rx3715_board);
}
-static void __init rx3715_init_irq(void)
+void __init rx3715_init_irq(void)
{
s3c24xx_init_irq();
}
diff --git a/trunk/arch/arm/mach-s3c2410/mach-smdk2410.c b/trunk/arch/arm/mach-s3c2410/mach-smdk2410.c
index 2eda55a6b678..67e903a700d3 100644
--- a/trunk/arch/arm/mach-s3c2410/mach-smdk2410.c
+++ b/trunk/arch/arm/mach-s3c2410/mach-smdk2410.c
@@ -28,7 +28,6 @@
* Ben Dooks
*
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
- * 20-Sep-2005 BJD Added static to non-exported items
*
***********************************************************************/
@@ -98,7 +97,7 @@ static struct s3c24xx_board smdk2410_board __initdata = {
.devices_count = ARRAY_SIZE(smdk2410_devices)
};
-static void __init smdk2410_map_io(void)
+void __init smdk2410_map_io(void)
{
s3c24xx_init_io(smdk2410_iodesc, ARRAY_SIZE(smdk2410_iodesc));
s3c24xx_init_clocks(0);
@@ -106,7 +105,7 @@ static void __init smdk2410_map_io(void)
s3c24xx_set_board(&smdk2410_board);
}
-static void __init smdk2410_init_irq(void)
+void __init smdk2410_init_irq(void)
{
s3c24xx_init_irq();
}
diff --git a/trunk/arch/arm/mach-s3c2410/mach-smdk2440.c b/trunk/arch/arm/mach-s3c2410/mach-smdk2440.c
index 722ef46b630a..357522106f68 100644
--- a/trunk/arch/arm/mach-s3c2410/mach-smdk2440.c
+++ b/trunk/arch/arm/mach-s3c2410/mach-smdk2440.c
@@ -18,7 +18,6 @@
* 22-Feb-2005 BJD Updated for 2.6.11-rc5 relesa
* 10-Mar-2005 LCVR Replaced S3C2410_VA by S3C24XX_VA
* 14-Mar-2005 BJD void __iomem fixes
- * 20-Sep-2005 BJD Added static to non-exported items
*/
#include
@@ -99,7 +98,7 @@ static struct s3c24xx_board smdk2440_board __initdata = {
.devices_count = ARRAY_SIZE(smdk2440_devices)
};
-static void __init smdk2440_map_io(void)
+void __init smdk2440_map_io(void)
{
s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc));
s3c24xx_init_clocks(16934400);
@@ -107,7 +106,7 @@ static void __init smdk2440_map_io(void)
s3c24xx_set_board(&smdk2440_board);
}
-static void __init smdk2440_machine_init(void)
+void __init smdk2440_machine_init(void)
{
/* Configure the LEDs (even if we have no LED support)*/
diff --git a/trunk/arch/arm/mach-s3c2410/mach-vr1000.c b/trunk/arch/arm/mach-s3c2410/mach-vr1000.c
index 663a7f98fc0b..8f9ab2893df4 100644
--- a/trunk/arch/arm/mach-s3c2410/mach-vr1000.c
+++ b/trunk/arch/arm/mach-s3c2410/mach-vr1000.c
@@ -28,7 +28,6 @@
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
* 14-Mar-2006 BJD void __iomem fixes
* 22-Jun-2006 BJD Added DM9000 platform information
- * 20-Sep-2005 BJD Added static to non-exported items
*/
#include
@@ -348,7 +347,7 @@ static void vr1000_power_off(void)
s3c2410_gpio_setpin(S3C2410_GPB9, 1);
}
-static void __init vr1000_map_io(void)
+void __init vr1000_map_io(void)
{
/* initialise clock sources */
diff --git a/trunk/arch/arm/mach-sa1100/generic.h b/trunk/arch/arm/mach-sa1100/generic.h
index f085d68e568e..279e3afa3c39 100644
--- a/trunk/arch/arm/mach-sa1100/generic.h
+++ b/trunk/arch/arm/mach-sa1100/generic.h
@@ -39,6 +39,3 @@ extern void sa11x0_set_ssp_data(struct sa11x0_ssp_plat_ops *ops);
struct irda_platform_data;
void sa11x0_set_irda_data(struct irda_platform_data *irda);
-
-struct mcp_plat_data;
-void sa11x0_set_mcp_data(struct mcp_plat_data *data);
diff --git a/trunk/arch/arm/mm/fault.c b/trunk/arch/arm/mm/fault.c
index 4a884baf3b9c..0b6c4db44e08 100644
--- a/trunk/arch/arm/mm/fault.c
+++ b/trunk/arch/arm/mm/fault.c
@@ -233,17 +233,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
if (in_interrupt() || !mm)
goto no_context;
- /*
- * As per x86, we may deadlock here. However, since the kernel only
- * validly references user space from well defined areas of the code,
- * we can bug out early if this is from code which shouldn't.
- */
- if (!down_read_trylock(&mm->mmap_sem)) {
- if (!user_mode(regs) && !search_exception_tables(regs->ARM_pc))
- goto no_context;
- down_read(&mm->mmap_sem);
- }
-
+ down_read(&mm->mmap_sem);
fault = __do_page_fault(mm, addr, fsr, tsk);
up_read(&mm->mmap_sem);
diff --git a/trunk/arch/arm/mm/proc-arm1020.S b/trunk/arch/arm/mm/proc-arm1020.S
index 82ec954e45b6..1d739d282a45 100644
--- a/trunk/arch/arm/mm/proc-arm1020.S
+++ b/trunk/arch/arm/mm/proc-arm1020.S
@@ -509,7 +509,7 @@ cpu_arm1020_name:
.align
- .section ".proc.info.init", #alloc, #execinstr
+ .section ".proc.info", #alloc, #execinstr
.type __arm1020_proc_info,#object
__arm1020_proc_info:
diff --git a/trunk/arch/arm/mm/proc-arm1020e.S b/trunk/arch/arm/mm/proc-arm1020e.S
index 7375fe930f72..9b725665b5c7 100644
--- a/trunk/arch/arm/mm/proc-arm1020e.S
+++ b/trunk/arch/arm/mm/proc-arm1020e.S
@@ -491,7 +491,7 @@ cpu_arm1020e_name:
.align
- .section ".proc.info.init", #alloc, #execinstr
+ .section ".proc.info", #alloc, #execinstr
.type __arm1020e_proc_info,#object
__arm1020e_proc_info:
diff --git a/trunk/arch/arm/mm/proc-arm1022.S b/trunk/arch/arm/mm/proc-arm1022.S
index 6ca639094d6f..37b70fa21c76 100644
--- a/trunk/arch/arm/mm/proc-arm1022.S
+++ b/trunk/arch/arm/mm/proc-arm1022.S
@@ -473,7 +473,7 @@ cpu_arm1022_name:
.align
- .section ".proc.info.init", #alloc, #execinstr
+ .section ".proc.info", #alloc, #execinstr
.type __arm1022_proc_info,#object
__arm1022_proc_info:
diff --git a/trunk/arch/arm/mm/proc-arm1026.S b/trunk/arch/arm/mm/proc-arm1026.S
index 10317e4f55d2..931b690d1be2 100644
--- a/trunk/arch/arm/mm/proc-arm1026.S
+++ b/trunk/arch/arm/mm/proc-arm1026.S
@@ -469,7 +469,7 @@ cpu_arm1026_name:
.align
- .section ".proc.info.init", #alloc, #execinstr
+ .section ".proc.info", #alloc, #execinstr
.type __arm1026_proc_info,#object
__arm1026_proc_info:
diff --git a/trunk/arch/arm/mm/proc-arm6_7.S b/trunk/arch/arm/mm/proc-arm6_7.S
index 8e7e1e70ab05..d0f1bbb48f6c 100644
--- a/trunk/arch/arm/mm/proc-arm6_7.S
+++ b/trunk/arch/arm/mm/proc-arm6_7.S
@@ -332,7 +332,7 @@ cpu_arm710_name:
.align
- .section ".proc.info.init", #alloc, #execinstr
+ .section ".proc.info", #alloc, #execinstr
.type __arm6_proc_info, #object
__arm6_proc_info:
diff --git a/trunk/arch/arm/mm/proc-arm720.S b/trunk/arch/arm/mm/proc-arm720.S
index a13e0184d343..c69c9de32391 100644
--- a/trunk/arch/arm/mm/proc-arm720.S
+++ b/trunk/arch/arm/mm/proc-arm720.S
@@ -222,7 +222,7 @@ cpu_arm720_name:
* See linux/include/asm-arm/procinfo.h for a definition of this structure.
*/
- .section ".proc.info.init", #alloc, #execinstr
+ .section ".proc.info", #alloc, #execinstr
.type __arm710_proc_info, #object
__arm710_proc_info:
diff --git a/trunk/arch/arm/mm/proc-arm920.S b/trunk/arch/arm/mm/proc-arm920.S
index d16513899999..0f490a0fcb71 100644
--- a/trunk/arch/arm/mm/proc-arm920.S
+++ b/trunk/arch/arm/mm/proc-arm920.S
@@ -452,7 +452,7 @@ cpu_arm920_name:
.align
- .section ".proc.info.init", #alloc, #execinstr
+ .section ".proc.info", #alloc, #execinstr
.type __arm920_proc_info,#object
__arm920_proc_info:
diff --git a/trunk/arch/arm/mm/proc-arm922.S b/trunk/arch/arm/mm/proc-arm922.S
index 23b8ed97f4e3..62bc34a139ee 100644
--- a/trunk/arch/arm/mm/proc-arm922.S
+++ b/trunk/arch/arm/mm/proc-arm922.S
@@ -456,7 +456,7 @@ cpu_arm922_name:
.align
- .section ".proc.info.init", #alloc, #execinstr
+ .section ".proc.info", #alloc, #execinstr
.type __arm922_proc_info,#object
__arm922_proc_info:
diff --git a/trunk/arch/arm/mm/proc-arm925.S b/trunk/arch/arm/mm/proc-arm925.S
index ee95c52db513..ee49aa2ca781 100644
--- a/trunk/arch/arm/mm/proc-arm925.S
+++ b/trunk/arch/arm/mm/proc-arm925.S
@@ -521,7 +521,7 @@ cpu_arm925_name:
.align
- .section ".proc.info.init", #alloc, #execinstr
+ .section ".proc.info", #alloc, #execinstr
.type __arm925_proc_info,#object
__arm925_proc_info:
diff --git a/trunk/arch/arm/mm/proc-arm926.S b/trunk/arch/arm/mm/proc-arm926.S
index 7d042dc20c47..bb95cc9fed03 100644
--- a/trunk/arch/arm/mm/proc-arm926.S
+++ b/trunk/arch/arm/mm/proc-arm926.S
@@ -471,7 +471,7 @@ cpu_arm926_name:
.align
- .section ".proc.info.init", #alloc, #execinstr
+ .section ".proc.info", #alloc, #execinstr
.type __arm926_proc_info,#object
__arm926_proc_info:
diff --git a/trunk/arch/arm/mm/proc-sa110.S b/trunk/arch/arm/mm/proc-sa110.S
index bd330c4075a1..34f7e7d3f419 100644
--- a/trunk/arch/arm/mm/proc-sa110.S
+++ b/trunk/arch/arm/mm/proc-sa110.S
@@ -249,7 +249,7 @@ cpu_sa110_name:
.align
- .section ".proc.info.init", #alloc, #execinstr
+ .section ".proc.info", #alloc, #execinstr
.type __sa110_proc_info,#object
__sa110_proc_info:
diff --git a/trunk/arch/arm/mm/proc-sa1100.S b/trunk/arch/arm/mm/proc-sa1100.S
index 91b89124c0d7..ca14f80d5ab4 100644
--- a/trunk/arch/arm/mm/proc-sa1100.S
+++ b/trunk/arch/arm/mm/proc-sa1100.S
@@ -280,7 +280,7 @@ cpu_sa1110_name:
.align
- .section ".proc.info.init", #alloc, #execinstr
+ .section ".proc.info", #alloc, #execinstr
.type __sa1100_proc_info,#object
__sa1100_proc_info:
diff --git a/trunk/arch/arm/mm/proc-v6.S b/trunk/arch/arm/mm/proc-v6.S
index caf3b19b167f..eb34823c9dbf 100644
--- a/trunk/arch/arm/mm/proc-v6.S
+++ b/trunk/arch/arm/mm/proc-v6.S
@@ -240,7 +240,7 @@ cpu_elf_name:
.size cpu_elf_name, . - cpu_elf_name
.align
- .section ".proc.info.init", #alloc, #execinstr
+ .section ".proc.info", #alloc, #execinstr
/*
* Match any ARMv6 processor core.
diff --git a/trunk/arch/arm/mm/proc-xscale.S b/trunk/arch/arm/mm/proc-xscale.S
index 861b35947280..b88de2700146 100644
--- a/trunk/arch/arm/mm/proc-xscale.S
+++ b/trunk/arch/arm/mm/proc-xscale.S
@@ -578,7 +578,7 @@ cpu_pxa270_name:
.align
- .section ".proc.info.init", #alloc, #execinstr
+ .section ".proc.info", #alloc, #execinstr
.type __80200_proc_info,#object
__80200_proc_info:
diff --git a/trunk/arch/ia64/hp/sim/simscsi.c b/trunk/arch/ia64/hp/sim/simscsi.c
index a18983a3c934..56405dbfd739 100644
--- a/trunk/arch/ia64/hp/sim/simscsi.c
+++ b/trunk/arch/ia64/hp/sim/simscsi.c
@@ -233,23 +233,6 @@ simscsi_readwrite10 (struct scsi_cmnd *sc, int mode)
simscsi_readwrite(sc, mode, offset, ((sc->cmnd[7] << 8) | sc->cmnd[8])*512);
}
-static void simscsi_fillresult(struct scsi_cmnd *sc, char *buf, unsigned len)
-{
-
- int scatterlen = sc->use_sg;
- struct scatterlist *slp;
-
- if (scatterlen == 0)
- memcpy(sc->request_buffer, buf, len);
- else for (slp = (struct scatterlist *)sc->buffer; scatterlen-- > 0 && len > 0; slp++) {
- unsigned thislen = min(len, slp->length);
-
- memcpy(page_address(slp->page) + slp->offset, buf, thislen);
- slp++;
- len -= thislen;
- }
-}
-
static int
simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
{
@@ -257,7 +240,6 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
char fname[MAX_ROOT_LEN+16];
size_t disk_size;
char *buf;
- char localbuf[36];
#if DEBUG_SIMSCSI
register long sp asm ("sp");
@@ -281,7 +263,7 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
/* disk doesn't exist... */
break;
}
- buf = localbuf;
+ buf = sc->request_buffer;
buf[0] = 0; /* magnetic disk */
buf[1] = 0; /* not a removable medium */
buf[2] = 2; /* SCSI-2 compliant device */
@@ -291,7 +273,6 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
buf[6] = 0; /* reserved */
buf[7] = 0; /* various flags */
memcpy(buf + 8, "HP SIMULATED DISK 0.00", 28);
- simscsi_fillresult(sc, buf, 36);
sc->result = GOOD;
break;
@@ -323,13 +304,16 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
simscsi_readwrite10(sc, SSC_WRITE);
break;
+
case READ_CAPACITY:
if (desc[target_id] < 0 || sc->request_bufflen < 8) {
break;
}
- buf = localbuf;
+ buf = sc->request_buffer;
+
disk_size = simscsi_get_disk_size(desc[target_id]);
+ /* pretend to be a 1GB disk (partition table contains real stuff): */
buf[0] = (disk_size >> 24) & 0xff;
buf[1] = (disk_size >> 16) & 0xff;
buf[2] = (disk_size >> 8) & 0xff;
@@ -339,14 +323,13 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
buf[5] = 0;
buf[6] = 2;
buf[7] = 0;
- simscsi_fillresult(sc, buf, 8);
sc->result = GOOD;
break;
case MODE_SENSE:
case MODE_SENSE_10:
/* sd.c uses this to determine whether disk does write-caching. */
- simscsi_fillresult(sc, (char *)empty_zero_page, sc->request_bufflen);
+ memset(sc->request_buffer, 0, 128);
sc->result = GOOD;
break;
diff --git a/trunk/arch/ia64/kernel/mca_asm.S b/trunk/arch/ia64/kernel/mca_asm.S
index db32fc1d3935..499a065f4e60 100644
--- a/trunk/arch/ia64/kernel/mca_asm.S
+++ b/trunk/arch/ia64/kernel/mca_asm.S
@@ -489,27 +489,24 @@ ia64_state_save:
;;
st8 [temp1]=r17,16 // pal_min_state
st8 [temp2]=r6,16 // prev_IA64_KR_CURRENT
- mov r6=IA64_KR(CURRENT_STACK)
- ;;
- st8 [temp1]=r6,16 // prev_IA64_KR_CURRENT_STACK
- st8 [temp2]=r0,16 // prev_task, starts off as NULL
mov r6=cr.ifa
;;
- st8 [temp1]=r12,16 // cr.isr
- st8 [temp2]=r6,16 // cr.ifa
+ st8 [temp1]=r0,16 // prev_task, starts off as NULL
+ st8 [temp2]=r12,16 // cr.isr
mov r12=cr.itir
;;
- st8 [temp1]=r12,16 // cr.itir
- st8 [temp2]=r11,16 // cr.iipa
+ st8 [temp1]=r6,16 // cr.ifa
+ st8 [temp2]=r12,16 // cr.itir
mov r12=cr.iim
;;
- st8 [temp1]=r12,16 // cr.iim
+ st8 [temp1]=r11,16 // cr.iipa
+ st8 [temp2]=r12,16 // cr.iim
+ mov r6=cr.iha
(p1) mov r12=IA64_MCA_COLD_BOOT
(p2) mov r12=IA64_INIT_WARM_BOOT
- mov r6=cr.iha
;;
- st8 [temp2]=r6,16 // cr.iha
- st8 [temp1]=r12 // os_status, default is cold boot
+ st8 [temp1]=r6,16 // cr.iha
+ st8 [temp2]=r12 // os_status, default is cold boot
mov r6=IA64_MCA_SAME_CONTEXT
;;
st8 [temp1]=r6 // context, default is same context
@@ -826,12 +823,9 @@ ia64_state_restore:
ld8 r12=[temp1],16 // sal_ra
ld8 r9=[temp2],16 // sal_gp
;;
- ld8 r22=[temp1],16 // pal_min_state, virtual
+ ld8 r22=[temp1],24 // pal_min_state, virtual. skip prev_task
ld8 r21=[temp2],16 // prev_IA64_KR_CURRENT
;;
- ld8 r16=[temp1],16 // prev_IA64_KR_CURRENT_STACK
- ld8 r20=[temp2],16 // prev_task
- ;;
ld8 temp3=[temp1],16 // cr.isr
ld8 temp4=[temp2],16 // cr.ifa
;;
@@ -852,45 +846,6 @@ ia64_state_restore:
ld8 r8=[temp1] // os_status
ld8 r10=[temp2] // context
- /* Wire IA64_TR_CURRENT_STACK to the stack that we are resuming to. To
- * avoid any dependencies on the algorithm in ia64_switch_to(), just
- * purge any existing CURRENT_STACK mapping and insert the new one.
- *
- * r16 contains prev_IA64_KR_CURRENT_STACK, r21 contains
- * prev_IA64_KR_CURRENT, these values may have been changed by the C
- * code. Do not use r8, r9, r10, r22, they contain values ready for
- * the return to SAL.
- */
-
- mov r15=IA64_KR(CURRENT_STACK) // physical granule mapped by IA64_TR_CURRENT_STACK
- ;;
- shl r15=r15,IA64_GRANULE_SHIFT
- ;;
- dep r15=-1,r15,61,3 // virtual granule
- mov r18=IA64_GRANULE_SHIFT<<2 // for cr.itir.ps
- ;;
- ptr.d r15,r18
- ;;
- srlz.d
-
- extr.u r19=r21,61,3 // r21 = prev_IA64_KR_CURRENT
- shl r20=r16,IA64_GRANULE_SHIFT // r16 = prev_IA64_KR_CURRENT_STACK
- movl r21=PAGE_KERNEL // page properties
- ;;
- mov IA64_KR(CURRENT_STACK)=r16
- cmp.ne p6,p0=RGN_KERNEL,r19 // new stack is in the kernel region?
- or r21=r20,r21 // construct PA | page properties
-(p6) br.spnt 1f // the dreaded cpu 0 idle task in region 5:(
- ;;
- mov cr.itir=r18
- mov cr.ifa=r21
- mov r20=IA64_TR_CURRENT_STACK
- ;;
- itr.d dtr[r20]=r21
- ;;
- srlz.d
-1:
-
br.sptk b0
//EndStub//////////////////////////////////////////////////////////////////////
@@ -1027,7 +982,6 @@ ia64_set_kernel_registers:
add temp4=temp4, temp1 // &struct ia64_sal_os_state.os_gp
add r12=temp1, temp3 // kernel stack pointer on MCA/INIT stack
add r13=temp1, r3 // set current to start of MCA/INIT stack
- add r20=temp1, r3 // physical start of MCA/INIT stack
;;
ld8 r1=[temp4] // OS GP from SAL OS state
;;
@@ -1037,35 +991,7 @@ ia64_set_kernel_registers:
;;
mov IA64_KR(CURRENT)=r13
- /* Wire IA64_TR_CURRENT_STACK to the MCA/INIT handler stack. To avoid
- * any dependencies on the algorithm in ia64_switch_to(), just purge
- * any existing CURRENT_STACK mapping and insert the new one.
- */
-
- mov r16=IA64_KR(CURRENT_STACK) // physical granule mapped by IA64_TR_CURRENT_STACK
- ;;
- shl r16=r16,IA64_GRANULE_SHIFT
- ;;
- dep r16=-1,r16,61,3 // virtual granule
- mov r18=IA64_GRANULE_SHIFT<<2 // for cr.itir.ps
- ;;
- ptr.d r16,r18
- ;;
- srlz.d
-
- shr.u r16=r20,IA64_GRANULE_SHIFT // r20 = physical start of MCA/INIT stack
- movl r21=PAGE_KERNEL // page properties
- ;;
- mov IA64_KR(CURRENT_STACK)=r16
- or r21=r20,r21 // construct PA | page properties
- ;;
- mov cr.itir=r18
- mov cr.ifa=r13
- mov r20=IA64_TR_CURRENT_STACK
- ;;
- itr.d dtr[r20]=r21
- ;;
- srlz.d
+ // FIXME: do I need to wire IA64_KR_CURRENT_STACK and IA64_TR_CURRENT_STACK?
br.sptk b0
diff --git a/trunk/arch/ia64/kernel/mca_drv.c b/trunk/arch/ia64/kernel/mca_drv.c
index f081c60ab206..80f83d6cdbfc 100644
--- a/trunk/arch/ia64/kernel/mca_drv.c
+++ b/trunk/arch/ia64/kernel/mca_drv.c
@@ -56,9 +56,8 @@ static struct page *page_isolate[MAX_PAGE_ISOLATE];
static int num_page_isolate = 0;
typedef enum {
- ISOLATE_NG,
- ISOLATE_OK,
- ISOLATE_NONE
+ ISOLATE_NG = 0,
+ ISOLATE_OK = 1
} isolate_status_t;
/*
@@ -75,7 +74,7 @@ static struct {
* @paddr: poisoned memory location
*
* Return value:
- * one of isolate_status_t, ISOLATE_OK/NG/NONE.
+ * ISOLATE_OK / ISOLATE_NG
*/
static isolate_status_t
@@ -86,10 +85,7 @@ mca_page_isolate(unsigned long paddr)
/* whether physical address is valid or not */
if (!ia64_phys_addr_valid(paddr))
- return ISOLATE_NONE;
-
- if (!pfn_valid(paddr))
- return ISOLATE_NONE;
+ return ISOLATE_NG;
/* convert physical address to physical page number */
p = pfn_to_page(paddr>>PAGE_SHIFT);
@@ -126,15 +122,10 @@ mca_handler_bh(unsigned long paddr)
current->pid, current->comm);
spin_lock(&mca_bh_lock);
- switch (mca_page_isolate(paddr)) {
- case ISOLATE_OK:
+ if (mca_page_isolate(paddr) == ISOLATE_OK) {
printk(KERN_DEBUG "Page isolation: ( %lx ) success.\n", paddr);
- break;
- case ISOLATE_NG:
+ } else {
printk(KERN_DEBUG "Page isolation: ( %lx ) failure.\n", paddr);
- break;
- default:
- break;
}
spin_unlock(&mca_bh_lock);
diff --git a/trunk/arch/powerpc/Kconfig b/trunk/arch/powerpc/Kconfig
deleted file mode 100644
index edfac467b9e0..000000000000
--- a/trunk/arch/powerpc/Kconfig
+++ /dev/null
@@ -1,861 +0,0 @@
-# For a description of the syntax of this configuration file,
-# see Documentation/kbuild/kconfig-language.txt.
-#
-
-mainmenu "Linux/PowerPC Kernel Configuration"
-
-config PPC64
- bool "64-bit kernel"
- default n
- help
- This option selects whether a 32-bit or a 64-bit kernel
- will be built.
-
-config PPC32
- bool
- default y if !PPC64
-
-config 64BIT
- bool
- default y if PPC64
-
-config PPC_MERGE
- def_bool y
-
-config MMU
- bool
- default y
-
-config UID16
- bool
-
-config GENERIC_HARDIRQS
- bool
- default y
-
-config RWSEM_GENERIC_SPINLOCK
- bool
-
-config RWSEM_XCHGADD_ALGORITHM
- bool
- default y
-
-config GENERIC_CALIBRATE_DELAY
- bool
- default y
-
-config PPC
- bool
- default y
-
-config EARLY_PRINTK
- bool
- default y if PPC64
-
-config COMPAT
- bool
- default y if PPC64
-
-config SYSVIPC_COMPAT
- bool
- depends on COMPAT && SYSVIPC
- default y
-
-# All PPC32s use generic nvram driver through ppc_md
-config GENERIC_NVRAM
- bool
- default y if PPC32
-
-config SCHED_NO_NO_OMIT_FRAME_POINTER
- bool
- default y
-
-config ARCH_MAY_HAVE_PC_FDC
- bool
- default y
-
-menu "Processor support"
-choice
- prompt "Processor Type"
- depends on PPC32
- default 6xx
-
-config 6xx
- bool "6xx/7xx/74xx"
- select PPC_FPU
- help
- There are four families of PowerPC chips supported. The more common
- types (601, 603, 604, 740, 750, 7400), the Motorola embedded
- versions (821, 823, 850, 855, 860, 52xx, 82xx, 83xx), the AMCC
- embedded versions (403 and 405) and the high end 64 bit Power
- processors (POWER 3, POWER4, and IBM PPC970 also known as G5).
-
- Unless you are building a kernel for one of the embedded processor
- systems, 64 bit IBM RS/6000 or an Apple G5, choose 6xx.
- Note that the kernel runs in 32-bit mode even on 64-bit chips.
-
-config PPC_52xx
- bool "Freescale 52xx"
-
-config PPC_82xx
- bool "Freescale 82xx"
-
-config PPC_83xx
- bool "Freescale 83xx"
-
-config 40x
- bool "AMCC 40x"
-
-config 44x
- bool "AMCC 44x"
-
-config PPC64BRIDGE
- select PPC_FPU
- bool "POWER3, POWER4 and PPC970 (G5)"
-
-config 8xx
- bool "Freescale 8xx"
-
-config E200
- bool "Freescale e200"
-
-config E500
- bool "Freescale e500"
-endchoice
-
-config POWER4_ONLY
- bool "Optimize for POWER4"
- depends on PPC64 || PPC64BRIDGE
- default n
- ---help---
- Cause the compiler to optimize for POWER4/POWER5/PPC970 processors.
- The resulting binary will not work on POWER3 or RS64 processors
- when compiled with binutils 2.15 or later.
-
-config POWER3
- bool
- depends on PPC64 || PPC64BRIDGE
- default y if !POWER4_ONLY
-
-config POWER4
- depends on PPC64 || PPC64BRIDGE
- def_bool y
-
-config PPC_FPU
- bool
- default y if PPC64
-
-config BOOKE
- bool
- depends on E200 || E500
- default y
-
-config FSL_BOOKE
- bool
- depends on E200 || E500
- default y
-
-config PTE_64BIT
- bool
- depends on 44x || E500
- default y if 44x
- default y if E500 && PHYS_64BIT
-
-config PHYS_64BIT
- bool 'Large physical address support' if E500
- depends on 44x || E500
- default y if 44x
- ---help---
- This option enables kernel support for larger than 32-bit physical
- addresses. This features is not be available on all e500 cores.
-
- If in doubt, say N here.
-
-config ALTIVEC
- bool "AltiVec Support"
- depends on 6xx || POWER4
- ---help---
- This option enables kernel support for the Altivec extensions to the
- PowerPC processor. The kernel currently supports saving and restoring
- altivec registers, and turning on the 'altivec enable' bit so user
- processes can execute altivec instructions.
-
- This option is only usefully if you have a processor that supports
- altivec (G4, otherwise known as 74xx series), but does not have
- any affect on a non-altivec cpu (it does, however add code to the
- kernel).
-
- If in doubt, say Y here.
-
-config SPE
- bool "SPE Support"
- depends on E200 || E500
- ---help---
- This option enables kernel support for the Signal Processing
- Extensions (SPE) to the PowerPC processor. The kernel currently
- supports saving and restoring SPE registers, and turning on the
- 'spe enable' bit so user processes can execute SPE instructions.
-
- This option is only useful if you have a processor that supports
- SPE (e500, otherwise known as 85xx series), but does not have any
- effect on a non-spe cpu (it does, however add code to the kernel).
-
- If in doubt, say Y here.
-
-config PPC_STD_MMU
- bool
- depends on 6xx || POWER3 || POWER4 || PPC64
- default y
-
-config PPC_STD_MMU_32
- def_bool y
- depends on PPC_STD_MMU && PPC32
-
-config SMP
- depends on PPC_STD_MMU
- bool "Symmetric multi-processing support"
- ---help---
- This enables support for systems with more than one CPU. If you have
- a system with only one CPU, say N. If you have a system with more
- than one CPU, say Y. Note that the kernel does not currently
- support SMP machines with 603/603e/603ev or PPC750 ("G3") processors
- since they have inadequate hardware support for multiprocessor
- operation.
-
- If you say N here, the kernel will run on single and multiprocessor
- machines, but will use only one CPU of a multiprocessor machine. If
- you say Y here, the kernel will run on single-processor machines.
- On a single-processor machine, the kernel will run faster if you say
- N here.
-
- If you don't know what to do here, say N.
-
-config NR_CPUS
- int "Maximum number of CPUs (2-32)"
- range 2 128
- depends on SMP
- default "32" if PPC64
- default "4"
-
-config NOT_COHERENT_CACHE
- bool
- depends on 4xx || 8xx || E200
- default y
-endmenu
-
-source "init/Kconfig"
-
-menu "Platform support"
- depends on PPC64 || 6xx
-
-choice
- prompt "Machine type"
- default PPC_MULTIPLATFORM
-
-config PPC_MULTIPLATFORM
- bool "Generic desktop/server/laptop"
- help
- Select this option if configuring for an IBM pSeries or
- RS/6000 machine, an Apple machine, or a PReP, CHRP,
- Maple or Cell-based machine.
-
-config PPC_ISERIES
- bool "IBM Legacy iSeries"
- depends on PPC64
-
-config EMBEDDED6xx
- bool "Embedded 6xx/7xx/7xxx-based board"
- depends on PPC32
-
-config APUS
- bool "Amiga-APUS"
- depends on PPC32 && BROKEN
- help
- Select APUS if configuring for a PowerUP Amiga.
- More information is available at:
- .
-endchoice
-
-config PPC_PSERIES
- depends on PPC_MULTIPLATFORM && PPC64
- bool " IBM pSeries & new (POWER5-based) iSeries"
- default y
-
-config PPC_CHRP
- bool " Common Hardware Reference Platform (CHRP) based machines"
- depends on PPC_MULTIPLATFORM && PPC32
- default y
-
-config PPC_PMAC
- bool " Apple PowerMac based machines"
- depends on PPC_MULTIPLATFORM
- default y
-
-config PPC_PMAC64
- bool
- depends on PPC_PMAC && POWER4
- default y
-
-config PPC_PREP
- bool " PowerPC Reference Platform (PReP) based machines"
- depends on PPC_MULTIPLATFORM && PPC32
- default y
-
-config PPC_MAPLE
- depends on PPC_MULTIPLATFORM && PPC64
- bool " Maple 970FX Evaluation Board"
- select U3_DART
- select MPIC_BROKEN_U3
- default n
- help
- This option enables support for the Maple 970FX Evaluation Board.
- For more informations, refer to
-
-config PPC_BPA
- bool " Broadband Processor Architecture"
- depends on PPC_MULTIPLATFORM && PPC64
-
-config PPC_OF
- bool
- depends on PPC_MULTIPLATFORM # for now
- default y
-
-config XICS
- depends on PPC_PSERIES
- bool
- default y
-
-config U3_DART
- bool
- depends on PPC_MULTIPLATFORM && PPC64
- default n
-
-config MPIC
- depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE
- bool
- default y
-
-config MPIC_BROKEN_U3
- bool
- depends on PPC_MAPLE
- default y
-
-config BPA_IIC
- depends on PPC_BPA
- bool
- default y
-
-config IBMVIO
- depends on PPC_PSERIES || PPC_ISERIES
- bool
- default y
-
-source "drivers/cpufreq/Kconfig"
-
-config CPU_FREQ_PMAC
- bool "Support for Apple PowerBooks"
- depends on CPU_FREQ && ADB_PMU && PPC32
- select CPU_FREQ_TABLE
- help
- This adds support for frequency switching on Apple PowerBooks,
- this currently includes some models of iBook & Titanium
- PowerBook.
-
-config PPC601_SYNC_FIX
- bool "Workarounds for PPC601 bugs"
- depends on 6xx && (PPC_PREP || PPC_PMAC)
- help
- Some versions of the PPC601 (the first PowerPC chip) have bugs which
- mean that extra synchronization instructions are required near
- certain instructions, typically those that make major changes to the
- CPU state. These extra instructions reduce performance slightly.
- If you say N here, these extra instructions will not be included,
- resulting in a kernel which will run faster but may not run at all
- on some systems with the PPC601 chip.
-
- If in doubt, say Y here.
-
-config TAU
- bool "Thermal Management Support"
- depends on 6xx
- help
- G3 and G4 processors have an on-chip temperature sensor called the
- 'Thermal Assist Unit (TAU)', which, in theory, can measure the on-die
- temperature within 2-4 degrees Celsius. This option shows the current
- on-die temperature in /proc/cpuinfo if the cpu supports it.
-
- Unfortunately, on some chip revisions, this sensor is very inaccurate
- and in some cases, does not work at all, so don't assume the cpu
- temp is actually what /proc/cpuinfo says it is.
-
-config TAU_INT
- bool "Interrupt driven TAU driver (DANGEROUS)"
- depends on TAU
- ---help---
- The TAU supports an interrupt driven mode which causes an interrupt
- whenever the temperature goes out of range. This is the fastest way
- to get notified the temp has exceeded a range. With this option off,
- a timer is used to re-check the temperature periodically.
-
- However, on some cpus it appears that the TAU interrupt hardware
- is buggy and can cause a situation which would lead unexplained hard
- lockups.
-
- Unless you are extending the TAU driver, or enjoy kernel/hardware
- debugging, leave this option off.
-
-config TAU_AVERAGE
- bool "Average high and low temp"
- depends on TAU
- ---help---
- The TAU hardware can compare the temperature to an upper and lower
- bound. The default behavior is to show both the upper and lower
- bound in /proc/cpuinfo. If the range is large, the temperature is
- either changing a lot, or the TAU hardware is broken (likely on some
- G4's). If the range is small (around 4 degrees), the temperature is
- relatively stable. If you say Y here, a single temperature value,
- halfway between the upper and lower bounds, will be reported in
- /proc/cpuinfo.
-
- If in doubt, say N here.
-endmenu
-
-source arch/powerpc/platforms/embedded6xx/Kconfig
-source arch/powerpc/platforms/4xx/Kconfig
-source arch/powerpc/platforms/85xx/Kconfig
-source arch/powerpc/platforms/8xx/Kconfig
-
-menu "Kernel options"
-
-config HIGHMEM
- bool "High memory support"
- depends on PPC32
-
-source kernel/Kconfig.hz
-source kernel/Kconfig.preempt
-source "fs/Kconfig.binfmt"
-
-# We optimistically allocate largepages from the VM, so make the limit
-# large enough (16MB). This badly named config option is actually
-# max order + 1
-config FORCE_MAX_ZONEORDER
- int
- depends on PPC64
- default "13"
-
-config MATH_EMULATION
- bool "Math emulation"
- depends on 4xx || 8xx || E200 || E500
- ---help---
- Some PowerPC chips designed for embedded applications do not have
- a floating-point unit and therefore do not implement the
- floating-point instructions in the PowerPC instruction set. If you
- say Y here, the kernel will include code to emulate a floating-point
- unit, which will allow programs that use floating-point
- instructions to run.
-
-config IOMMU_VMERGE
- bool "Enable IOMMU virtual merging (EXPERIMENTAL)"
- depends on EXPERIMENTAL && PPC64
- default n
- help
- Cause IO segments sent to a device for DMA to be merged virtually
- by the IOMMU when they happen to have been allocated contiguously.
- This doesn't add pressure to the IOMMU allocator. However, some
- drivers don't support getting large merged segments coming back
- from *_map_sg(). Say Y if you know the drivers you are using are
- properly handling this case.
-
-config HOTPLUG_CPU
- bool "Support for enabling/disabling CPUs"
- depends on SMP && HOTPLUG && EXPERIMENTAL && (PPC_PSERIES || PPC_PMAC)
- ---help---
- Say Y here to be able to disable and re-enable individual
- CPUs at runtime on SMP machines.
-
- Say N if you are unsure.
-
-config KEXEC
- bool "kexec system call (EXPERIMENTAL)"
- depends on PPC_MULTIPLATFORM && EXPERIMENTAL
- help
- kexec is a system call that implements the ability to shutdown your
- current kernel, and to start another kernel. It is like a reboot
- but it is indepedent of the system firmware. And like a reboot
- you can start any kernel with it, not just Linux.
-
- The name comes from the similiarity to the exec system call.
-
- It is an ongoing process to be certain the hardware in a machine
- is properly shutdown, so do not be surprised if this code does not
- initially work for you. It may help to enable device hotplugging
- support. As of this writing the exact hardware interface is
- strongly in flux, so no good recommendation can be made.
-
-config EMBEDDEDBOOT
- bool
- depends on 8xx || 8260
- default y
-
-config PC_KEYBOARD
- bool "PC PS/2 style Keyboard"
- depends on 4xx || CPM2
-
-config PPCBUG_NVRAM
- bool "Enable reading PPCBUG NVRAM during boot" if PPLUS || LOPEC
- default y if PPC_PREP
-
-config IRQ_ALL_CPUS
- bool "Distribute interrupts on all CPUs by default"
- depends on SMP && !MV64360
- help
- This option gives the kernel permission to distribute IRQs across
- multiple CPUs. Saying N here will route all IRQs to the first
- CPU. Generally saying Y is safe, although some problems have been
- reported with SMP Power Macintoshes with this option enabled.
-
-source "arch/powerpc/platforms/pseries/Kconfig"
-
-config ARCH_SELECT_MEMORY_MODEL
- def_bool y
- depends on PPC64
-
-config ARCH_FLATMEM_ENABLE
- def_bool y
- depends on PPC64 && !NUMA
-
-config ARCH_DISCONTIGMEM_ENABLE
- def_bool y
- depends on SMP && PPC_PSERIES
-
-config ARCH_DISCONTIGMEM_DEFAULT
- def_bool y
- depends on ARCH_DISCONTIGMEM_ENABLE
-
-config ARCH_FLATMEM_ENABLE
- def_bool y
- depends on PPC64
-
-config ARCH_SPARSEMEM_ENABLE
- def_bool y
- depends on ARCH_DISCONTIGMEM_ENABLE
-
-source "mm/Kconfig"
-
-config HAVE_ARCH_EARLY_PFN_TO_NID
- def_bool y
- depends on NEED_MULTIPLE_NODES
-
-# Some NUMA nodes have memory ranges that span
-# other nodes. Even though a pfn is valid and
-# between a node's start and end pfns, it may not
-# reside on that node.
-#
-# This is a relatively temporary hack that should
-# be able to go away when sparsemem is fully in
-# place
-
-config NODES_SPAN_OTHER_NODES
- def_bool y
- depends on NEED_MULTIPLE_NODES
-
-config NUMA
- bool "NUMA support"
- default y if DISCONTIGMEM || SPARSEMEM
-
-config SCHED_SMT
- bool "SMT (Hyperthreading) scheduler support"
- depends on PPC64 && SMP
- default off
- help
- SMT scheduler support improves the CPU scheduler's decision making
- when dealing with POWER5 cpus at a cost of slightly increased
- overhead in some places. If unsure say N here.
-
-config PROC_DEVICETREE
- bool "Support for Open Firmware device tree in /proc"
- depends on PPC_OF && PROC_FS
- help
- This option adds a device-tree directory under /proc which contains
- an image of the device tree that the kernel copies from Open
- Firmware. If unsure, say Y here.
-
-source "arch/powerpc/platforms/prep/Kconfig"
-
-config CMDLINE_BOOL
- bool "Default bootloader kernel arguments"
- depends on !PPC_ISERIES
-
-config CMDLINE
- string "Initial kernel command string"
- depends on CMDLINE_BOOL
- default "console=ttyS0,9600 console=tty0 root=/dev/sda2"
- help
- On some platforms, there is currently no way for the boot loader to
- pass arguments to the kernel. For these platforms, you can supply
- some command-line options at build time by entering them here. In
- most cases you will need to specify the root device here.
-
-if !44x || BROKEN
-source kernel/power/Kconfig
-endif
-
-config SECCOMP
- bool "Enable seccomp to safely compute untrusted bytecode"
- depends on PROC_FS
- default y
- help
- This kernel feature is useful for number crunching applications
- that may need to compute untrusted bytecode during their
- execution. By using pipes or other transports made available to
- the process as file descriptors supporting the read/write
- syscalls, it's possible to isolate those applications in
- their own address space using seccomp. Once seccomp is
- enabled via /proc//seccomp, it cannot be disabled
- and the task is only allowed to execute a few safe syscalls
- defined by each seccomp mode.
-
- If unsure, say Y. Only embedded should say N here.
-
-endmenu
-
-config ISA_DMA_API
- bool
- default y
-
-menu "Bus options"
-
-config ISA
- bool "Support for ISA-bus hardware"
- depends on PPC_PREP || PPC_CHRP
- help
- Find out whether you have ISA slots on your motherboard. ISA is the
- name of a bus system, i.e. the way the CPU talks to the other stuff
- inside your box. If you have an Apple machine, say N here; if you
- have an IBM RS/6000 or pSeries machine or a PReP machine, say Y. If
- you have an embedded board, consult your board documentation.
-
-config GENERIC_ISA_DMA
- bool
- depends on PPC64 || POWER4 || 6xx && !CPM2
- default y
-
-config EISA
- bool
-
-config SBUS
- bool
-
-# Yes MCA RS/6000s exist but Linux-PPC does not currently support any
-config MCA
- bool
-
-config PCI
- bool "PCI support" if 40x || CPM2 || 83xx || 85xx || PPC_MPC52xx || (EMBEDDED && PPC_ISERIES)
- default y if !40x && !CPM2 && !8xx && !APUS && !83xx && !85xx
- default PCI_PERMEDIA if !4xx && !CPM2 && !8xx && APUS
- default PCI_QSPAN if !4xx && !CPM2 && 8xx
- help
- Find out whether your system includes a PCI bus. PCI is the name of
- a bus system, i.e. the way the CPU talks to the other stuff inside
- your box. If you say Y here, the kernel will include drivers and
- infrastructure code to support PCI bus devices.
-
-config PCI_DOMAINS
- bool
- default PCI
-
-config MPC83xx_PCI2
- bool " Supprt for 2nd PCI host controller"
- depends on PCI && MPC834x
- default y if MPC834x_SYS
-
-config PCI_QSPAN
- bool "QSpan PCI"
- depends on !4xx && !CPM2 && 8xx
- help
- Say Y here if you have a system based on a Motorola 8xx-series
- embedded processor with a QSPAN PCI interface, otherwise say N.
-
-config PCI_8260
- bool
- depends on PCI && 8260
- default y
-
-config 8260_PCI9
- bool " Enable workaround for MPC826x erratum PCI 9"
- depends on PCI_8260 && !ADS8272
- default y
-
-choice
- prompt " IDMA channel for PCI 9 workaround"
- depends on 8260_PCI9
-
-config 8260_PCI9_IDMA1
- bool "IDMA1"
-
-config 8260_PCI9_IDMA2
- bool "IDMA2"
-
-config 8260_PCI9_IDMA3
- bool "IDMA3"
-
-config 8260_PCI9_IDMA4
- bool "IDMA4"
-
-endchoice
-
-source "drivers/pci/Kconfig"
-
-source "drivers/pcmcia/Kconfig"
-
-source "drivers/pci/hotplug/Kconfig"
-
-endmenu
-
-menu "Advanced setup"
- depends on PPC32
-
-config ADVANCED_OPTIONS
- bool "Prompt for advanced kernel configuration options"
- help
- This option will enable prompting for a variety of advanced kernel
- configuration options. These options can cause the kernel to not
- work if they are set incorrectly, but can be used to optimize certain
- aspects of kernel memory management.
-
- Unless you know what you are doing, say N here.
-
-comment "Default settings for advanced configuration options are used"
- depends on !ADVANCED_OPTIONS
-
-config HIGHMEM_START_BOOL
- bool "Set high memory pool address"
- depends on ADVANCED_OPTIONS && HIGHMEM
- help
- This option allows you to set the base address of the kernel virtual
- area used to map high memory pages. This can be useful in
- optimizing the layout of kernel virtual memory.
-
- Say N here unless you know what you are doing.
-
-config HIGHMEM_START
- hex "Virtual start address of high memory pool" if HIGHMEM_START_BOOL
- default "0xfe000000"
-
-config LOWMEM_SIZE_BOOL
- bool "Set maximum low memory"
- depends on ADVANCED_OPTIONS
- help
- This option allows you to set the maximum amount of memory which
- will be used as "low memory", that is, memory which the kernel can
- access directly, without having to set up a kernel virtual mapping.
- This can be useful in optimizing the layout of kernel virtual
- memory.
-
- Say N here unless you know what you are doing.
-
-config LOWMEM_SIZE
- hex "Maximum low memory size (in bytes)" if LOWMEM_SIZE_BOOL
- default "0x30000000"
-
-config KERNEL_START_BOOL
- bool "Set custom kernel base address"
- depends on ADVANCED_OPTIONS
- help
- This option allows you to set the kernel virtual address at which
- the kernel will map low memory (the kernel image will be linked at
- this address). This can be useful in optimizing the virtual memory
- layout of the system.
-
- Say N here unless you know what you are doing.
-
-config KERNEL_START
- hex "Virtual address of kernel base" if KERNEL_START_BOOL
- default "0xc0000000"
-
-config TASK_SIZE_BOOL
- bool "Set custom user task size"
- depends on ADVANCED_OPTIONS
- help
- This option allows you to set the amount of virtual address space
- allocated to user tasks. This can be useful in optimizing the
- virtual memory layout of the system.
-
- Say N here unless you know what you are doing.
-
-config TASK_SIZE
- hex "Size of user task space" if TASK_SIZE_BOOL
- default "0x80000000"
-
-config CONSISTENT_START_BOOL
- bool "Set custom consistent memory pool address"
- depends on ADVANCED_OPTIONS && NOT_COHERENT_CACHE
- help
- This option allows you to set the base virtual address
- of the the consistent memory pool. This pool of virtual
- memory is used to make consistent memory allocations.
-
-config CONSISTENT_START
- hex "Base virtual address of consistent memory pool" if CONSISTENT_START_BOOL
- default "0xff100000" if NOT_COHERENT_CACHE
-
-config CONSISTENT_SIZE_BOOL
- bool "Set custom consistent memory pool size"
- depends on ADVANCED_OPTIONS && NOT_COHERENT_CACHE
- help
- This option allows you to set the size of the the
- consistent memory pool. This pool of virtual memory
- is used to make consistent memory allocations.
-
-config CONSISTENT_SIZE
- hex "Size of consistent memory pool" if CONSISTENT_SIZE_BOOL
- default "0x00200000" if NOT_COHERENT_CACHE
-
-config BOOT_LOAD_BOOL
- bool "Set the boot link/load address"
- depends on ADVANCED_OPTIONS && !PPC_MULTIPLATFORM
- help
- This option allows you to set the initial load address of the zImage
- or zImage.initrd file. This can be useful if you are on a board
- which has a small amount of memory.
-
- Say N here unless you know what you are doing.
-
-config BOOT_LOAD
- hex "Link/load address for booting" if BOOT_LOAD_BOOL
- default "0x00400000" if 40x || 8xx || 8260
- default "0x01000000" if 44x
- default "0x00800000"
-
-config PIN_TLB
- bool "Pinned Kernel TLBs (860 ONLY)"
- depends on ADVANCED_OPTIONS && 8xx
-endmenu
-
-source "net/Kconfig"
-
-source "drivers/Kconfig"
-
-source "fs/Kconfig"
-
-# XXX source "arch/ppc/8xx_io/Kconfig"
-
-# XXX source "arch/ppc/8260_io/Kconfig"
-
-source "arch/powerpc/platforms/iseries/Kconfig"
-
-source "lib/Kconfig"
-
-source "arch/powerpc/oprofile/Kconfig"
-
-source "arch/powerpc/Kconfig.debug"
-
-source "security/Kconfig"
-
-config KEYS_COMPAT
- bool
- depends on COMPAT && KEYS
- default y
-
-source "crypto/Kconfig"
diff --git a/trunk/arch/powerpc/Kconfig.debug b/trunk/arch/powerpc/Kconfig.debug
deleted file mode 100644
index 61653cb60c4e..000000000000
--- a/trunk/arch/powerpc/Kconfig.debug
+++ /dev/null
@@ -1,73 +0,0 @@
-menu "Kernel hacking"
-
-source "lib/Kconfig.debug"
-
-config KGDB
- bool "Include kgdb kernel debugger"
- depends on DEBUG_KERNEL && (BROKEN || PPC_GEN550 || 4xx)
- select DEBUG_INFO
- help
- Include in-kernel hooks for kgdb, the Linux kernel source level
- debugger. See for more information.
- Unless you are intending to debug the kernel, say N here.
-
-choice
- prompt "Serial Port"
- depends on KGDB
- default KGDB_TTYS1
-
-config KGDB_TTYS0
- bool "ttyS0"
-
-config KGDB_TTYS1
- bool "ttyS1"
-
-config KGDB_TTYS2
- bool "ttyS2"
-
-config KGDB_TTYS3
- bool "ttyS3"
-
-endchoice
-
-config KGDB_CONSOLE
- bool "Enable serial console thru kgdb port"
- depends on KGDB && 8xx || CPM2
- help
- If you enable this, all serial console messages will be sent
- over the gdb stub.
- If unsure, say N.
-
-config XMON
- bool "Include xmon kernel debugger"
- depends on DEBUG_KERNEL
- help
- Include in-kernel hooks for the xmon kernel monitor/debugger.
- Unless you are intending to debug the kernel, say N here.
-
-config BDI_SWITCH
- bool "Include BDI-2000 user context switcher"
- depends on DEBUG_KERNEL
- help
- Include in-kernel support for the Abatron BDI2000 debugger.
- Unless you are intending to debug the kernel with one of these
- machines, say N here.
-
-config BOOTX_TEXT
- bool "Support for early boot text console (BootX or OpenFirmware only)"
- depends PPC_OF
- help
- Say Y here to see progress messages from the boot firmware in text
- mode. Requires either BootX or Open Firmware.
-
-config SERIAL_TEXT_DEBUG
- bool "Support for early boot texts over serial port"
- depends on 4xx || LOPEC || MV64X60 || PPLUS || PRPMC800 || \
- PPC_GEN550 || PPC_MPC52xx
-
-config PPC_OCP
- bool
- depends on IBM_OCP || XILINX_OCP
- default y
-
-endmenu
diff --git a/trunk/arch/powerpc/Makefile b/trunk/arch/powerpc/Makefile
deleted file mode 100644
index 8a65e112211b..000000000000
--- a/trunk/arch/powerpc/Makefile
+++ /dev/null
@@ -1,222 +0,0 @@
-# This file is included by the global makefile so that you can add your own
-# architecture-specific flags and dependencies. Remember to do have actions
-# for "archclean" and "archdep" for cleaning up and making dependencies for
-# this architecture.
-#
-# This file is subject to the terms and conditions of the GNU General Public
-# License. See the file "COPYING" in the main directory of this archive
-# for more details.
-#
-# Copyright (C) 1994 by Linus Torvalds
-# Changes for PPC by Gary Thomas
-# Rewritten by Cort Dougan and Paul Mackerras
-#
-
-# This must match PAGE_OFFSET in include/asm-powerpc/page.h.
-KERNELLOAD := $(CONFIG_KERNEL_START)
-
-HAS_BIARCH := $(call cc-option-yn, -m32)
-
-ifeq ($(CONFIG_PPC64),y)
-SZ := 64
-
-# Set default 32 bits cross compilers for vdso and boot wrapper
-CROSS32_COMPILE ?=
-
-CROSS32CC := $(CROSS32_COMPILE)gcc
-CROSS32AS := $(CROSS32_COMPILE)as
-CROSS32LD := $(CROSS32_COMPILE)ld
-CROSS32OBJCOPY := $(CROSS32_COMPILE)objcopy
-
-ifeq ($(HAS_BIARCH),y)
-ifeq ($(CROSS32_COMPILE),)
-CROSS32CC := $(CC) -m32
-CROSS32AS := $(AS) -a32
-CROSS32LD := $(LD) -m elf32ppc
-CROSS32OBJCOPY := $(OBJCOPY)
-endif
-endif
-
-export CROSS32CC CROSS32AS CROSS32LD CROSS32OBJCOPY
-
-new_nm := $(shell if $(NM) --help 2>&1 | grep -- '--synthetic' > /dev/null; then echo y; else echo n; fi)
-
-ifeq ($(new_nm),y)
-NM := $(NM) --synthetic
-endif
-
-else
-SZ := 32
-endif
-
-ifeq ($(HAS_BIARCH),y)
-override AS += -a$(SZ)
-override LD += -m elf$(SZ)ppc
-override CC += -m$(SZ)
-endif
-
-LDFLAGS_vmlinux := -Ttext $(KERNELLOAD) -Bstatic -e $(KERNELLOAD)
-
-# The -Iarch/$(ARCH)/include is temporary while we are merging
-CPPFLAGS += -Iarch/$(ARCH) -Iarch/$(ARCH)/include
-AFLAGS += -Iarch/$(ARCH)
-CFLAGS += -Iarch/$(ARCH) -msoft-float -pipe
-ifeq ($(CONFIG_PPC64),y)
-CFLAGS += -mminimal-toc -mtraceback=none -mcall-aixdesc
-else
-CFLAGS += -ffixed-r2 -mmultiple
-endif
-CPP = $(CC) -E $(CFLAGS)
-# Temporary hack until we have migrated to asm-powerpc
-LINUXINCLUDE += -Iarch/$(ARCH)/include
-
-CHECKFLAGS += -m$(SZ) -D__powerpc__ -D__powerpc$(SZ)__
-
-ifeq ($(CONFIG_PPC64),y)
-GCC_VERSION := $(call cc-version)
-GCC_BROKEN_VEC := $(shell if [ $(GCC_VERSION) -lt 0400 ] ; then echo "y"; fi)
-
-ifeq ($(CONFIG_POWER4_ONLY),y)
-ifeq ($(CONFIG_ALTIVEC),y)
-ifeq ($(GCC_BROKEN_VEC),y)
- CFLAGS += $(call cc-option,-mcpu=970)
-else
- CFLAGS += $(call cc-option,-mcpu=power4)
-endif
-else
- CFLAGS += $(call cc-option,-mcpu=power4)
-endif
-else
- CFLAGS += $(call cc-option,-mtune=power4)
-endif
-endif
-
-# Enable unit-at-a-time mode when possible. It shrinks the
-# kernel considerably.
-CFLAGS += $(call cc-option,-funit-at-a-time)
-
-ifndef CONFIG_FSL_BOOKE
-CFLAGS += -mstring
-endif
-
-cpu-as-$(CONFIG_PPC64BRIDGE) += -Wa,-mppc64bridge
-cpu-as-$(CONFIG_4xx) += -Wa,-m405
-cpu-as-$(CONFIG_6xx) += -Wa,-maltivec
-cpu-as-$(CONFIG_POWER4) += -Wa,-maltivec
-cpu-as-$(CONFIG_E500) += -Wa,-me500
-cpu-as-$(CONFIG_E200) += -Wa,-me200
-
-AFLAGS += $(cpu-as-y)
-CFLAGS += $(cpu-as-y)
-
-# Default to the common case.
-KBUILD_DEFCONFIG := common_defconfig
-
-head-y := arch/powerpc/kernel/head.o
-head-$(CONFIG_PPC64) := arch/powerpc/kernel/head_64.o
-head-$(CONFIG_8xx) := arch/powerpc/kernel/head_8xx.o
-head-$(CONFIG_4xx) := arch/powerpc/kernel/head_4xx.o
-head-$(CONFIG_44x) := arch/powerpc/kernel/head_44x.o
-head-$(CONFIG_FSL_BOOKE) := arch/powerpc/kernel/head_fsl_booke.o
-
-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
-
-core-y += arch/powerpc/kernel/ \
- arch/powerpc/mm/ \
- arch/powerpc/lib/ \
- arch/powerpc/sysdev/
-core-$(CONFIG_PPC32) += arch/ppc/kernel/ \
- arch/ppc/syslib/
-core-$(CONFIG_PPC64) += arch/ppc64/kernel/
-core-$(CONFIG_PPC_PMAC) += arch/powerpc/platforms/powermac/
-core-$(CONFIG_4xx) += arch/ppc/platforms/4xx/
-core-$(CONFIG_83xx) += arch/ppc/platforms/83xx/
-core-$(CONFIG_85xx) += arch/ppc/platforms/85xx/
-core-$(CONFIG_MATH_EMULATION) += arch/ppc/math-emu/
-core-$(CONFIG_XMON) += arch/powerpc/xmon/
-core-$(CONFIG_APUS) += arch/ppc/amiga/
-drivers-$(CONFIG_8xx) += arch/ppc/8xx_io/
-drivers-$(CONFIG_4xx) += arch/ppc/4xx_io/
-drivers-$(CONFIG_CPM2) += arch/ppc/8260_io/
-
-drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/
-
-BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm
-
-.PHONY: $(BOOT_TARGETS)
-
-all: uImage zImage
-
-CPPFLAGS_vmlinux.lds := -Upowerpc
-
-# All the instructions talk about "make bzImage".
-bzImage: zImage
-
-boot := arch/$(ARCH)/boot
-
-$(BOOT_TARGETS): vmlinux
- $(Q)$(MAKE) $(build)=$(boot) $@
-
-uImage: vmlinux
- $(Q)$(MAKE) $(build)=$(boot)/images $(boot)/images/$@
-
-define archhelp
- @echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/images/zImage.*)'
- @echo ' uImage - Create a bootable image for U-Boot / PPCBoot'
- @echo ' install - Install kernel using'
- @echo ' (your) ~/bin/installkernel or'
- @echo ' (distribution) /sbin/installkernel or'
- @echo ' install to $$(INSTALL_PATH) and run lilo'
- @echo ' *_defconfig - Select default config from arch/$(ARCH)/ppc/configs'
-endef
-
-archclean:
- $(Q)$(MAKE) $(clean)=arch/ppc/boot
- # Temporary hack until we have migrated to asm-powerpc
- $(Q)rm -rf arch/$(ARCH)/include
-
-archprepare: checkbin
-
-# Temporary hack until we have migrated to asm-powerpc
-ifeq ($(CONFIG_PPC64),y)
-include/asm: arch/$(ARCH)/include/asm
-arch/$(ARCH)/include/asm:
- $(Q)if [ ! -d arch/$(ARCH)/include ]; then mkdir -p arch/$(ARCH)/include; fi
- $(Q)ln -fsn $(srctree)/include/asm-ppc64 arch/$(ARCH)/include/asm
-else
-include/asm: arch/$(ARCH)/include/asm
-arch/$(ARCH)/include/asm:
- $(Q)if [ ! -d arch/$(ARCH)/include ]; then mkdir -p arch/$(ARCH)/include; fi
- $(Q)ln -fsn $(srctree)/include/asm-ppc arch/$(ARCH)/include/asm
-endif
-
-# Use the file '.tmp_gas_check' for binutils tests, as gas won't output
-# to stdout and these checks are run even on install targets.
-TOUT := .tmp_gas_check
-# Ensure this is binutils 2.12.1 (or 2.12.90.0.7) or later for altivec
-# instructions.
-# gcc-3.4 and binutils-2.14 are a fatal combination.
-GCC_VERSION := $(call cc-version)
-
-checkbin:
- @if test "$(GCC_VERSION)" = "0304" ; then \
- if ! /bin/echo mftb 5 | $(AS) -v -mppc -many -o $(TOUT) >/dev/null 2>&1 ; then \
- echo -n '*** ${VERSION}.${PATCHLEVEL} kernels no longer build '; \
- echo 'correctly with gcc-3.4 and your version of binutils.'; \
- echo '*** Please upgrade your binutils or downgrade your gcc'; \
- false; \
- fi ; \
- fi
- @if ! /bin/echo dssall | $(AS) -many -o $(TOUT) >/dev/null 2>&1 ; then \
- echo -n '*** ${VERSION}.${PATCHLEVEL} kernels no longer build ' ; \
- echo 'correctly with old versions of binutils.' ; \
- echo '*** Please upgrade your binutils to 2.12.1 or newer' ; \
- false ; \
- fi
-
-CLEAN_FILES += $(TOUT)
-
diff --git a/trunk/arch/powerpc/kernel/Makefile b/trunk/arch/powerpc/kernel/Makefile
deleted file mode 100644
index 62c4a51a23d7..000000000000
--- a/trunk/arch/powerpc/kernel/Makefile
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Makefile for the linux kernel.
-#
-
-extra-$(CONFIG_PPC_STD_MMU) := head.o
-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
-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 traps.o process.o
-
-obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o
diff --git a/trunk/arch/powerpc/kernel/asm-offsets.c b/trunk/arch/powerpc/kernel/asm-offsets.c
deleted file mode 100644
index 16cf0b7ee2b7..000000000000
--- a/trunk/arch/powerpc/kernel/asm-offsets.c
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * This program is used to generate definitions needed by
- * assembly language modules.
- *
- * We use the technique used in the OSF Mach kernel code:
- * generate asm statements containing #defines,
- * compile this file to assembler, and then extract the
- * #defines from the assembly-language output.
- *
- * 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
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#ifdef CONFIG_PPC64
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#endif
-
-#define DEFINE(sym, val) \
- asm volatile("\n->" #sym " %0 " #val : : "i" (val))
-
-#define BLANK() asm volatile("\n->" : : )
-
-int main(void)
-{
- /* thread struct on stack */
- DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
- DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
- DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
-#ifdef CONFIG_PPC32
- DEFINE(TI_LOCAL_FLAGS, offsetof(struct thread_info, local_flags));
-#endif
-#ifdef CONFIG_PPC64
- DEFINE(TI_SC_NOERR, offsetof(struct thread_info, syscall_noerror));
- DEFINE(THREAD_SHIFT, THREAD_SHIFT);
-#endif
- DEFINE(THREAD_SIZE, THREAD_SIZE);
-
- /* task_struct->thread */
- DEFINE(THREAD, offsetof(struct task_struct, thread));
- DEFINE(THREAD_INFO, offsetof(struct task_struct, thread_info));
- DEFINE(MM, offsetof(struct task_struct, mm));
- DEFINE(PTRACE, offsetof(struct task_struct, ptrace));
- DEFINE(KSP, offsetof(struct thread_struct, ksp));
- DEFINE(PGDIR, offsetof(struct thread_struct, pgdir));
- DEFINE(LAST_SYSCALL, offsetof(struct thread_struct, last_syscall));
- DEFINE(PT_REGS, offsetof(struct thread_struct, regs));
- DEFINE(THREAD_FPEXC_MODE, offsetof(struct thread_struct, fpexc_mode));
- DEFINE(THREAD_FPR0, offsetof(struct thread_struct, fpr[0]));
- DEFINE(THREAD_FPSCR, offsetof(struct thread_struct, fpscr));
-#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
- DEFINE(THREAD_DBCR0, offsetof(struct thread_struct, dbcr0));
- DEFINE(PT_PTRACED, PT_PTRACED);
-#endif
-#ifdef CONFIG_PPC64
- DEFINE(KSP_VSID, offsetof(struct thread_struct, ksp_vsid));
-#endif
-
-#ifdef CONFIG_ALTIVEC
- DEFINE(THREAD_VR0, offsetof(struct thread_struct, vr[0]));
- DEFINE(THREAD_VRSAVE, offsetof(struct thread_struct, vrsave));
- DEFINE(THREAD_VSCR, offsetof(struct thread_struct, vscr));
- DEFINE(THREAD_USED_VR, offsetof(struct thread_struct, used_vr));
-#endif /* CONFIG_ALTIVEC */
-#ifdef CONFIG_SPE
- DEFINE(THREAD_EVR0, offsetof(struct thread_struct, evr[0]));
- DEFINE(THREAD_ACC, offsetof(struct thread_struct, acc));
- DEFINE(THREAD_SPEFSCR, offsetof(struct thread_struct, spefscr));
- DEFINE(THREAD_USED_SPE, offsetof(struct thread_struct, used_spe));
-#endif /* CONFIG_SPE */
- /* Interrupt register frame */
- DEFINE(STACK_FRAME_OVERHEAD, STACK_FRAME_OVERHEAD);
-#ifndef CONFIG_PPC64
- DEFINE(INT_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs));
-#else
- DEFINE(SWITCH_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs));
-
- /* 288 = # of volatile regs, int & fp, for leaf routines */
- /* which do not stack a frame. See the PPC64 ABI. */
- DEFINE(INT_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 288);
-#endif
- /* in fact we only use gpr0 - gpr9 and gpr20 - gpr23 */
- DEFINE(GPR0, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[0]));
- DEFINE(GPR1, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[1]));
- DEFINE(GPR2, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[2]));
- DEFINE(GPR3, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[3]));
- DEFINE(GPR4, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[4]));
- DEFINE(GPR5, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[5]));
- DEFINE(GPR6, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[6]));
- DEFINE(GPR7, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[7]));
- DEFINE(GPR8, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[8]));
- DEFINE(GPR9, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[9]));
- DEFINE(GPR10, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[10]));
- DEFINE(GPR11, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[11]));
- DEFINE(GPR12, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[12]));
- DEFINE(GPR13, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[13]));
- DEFINE(GPR14, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[14]));
- DEFINE(GPR15, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[15]));
- DEFINE(GPR16, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[16]));
- DEFINE(GPR17, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[17]));
- DEFINE(GPR18, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[18]));
- DEFINE(GPR19, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[19]));
- DEFINE(GPR20, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[20]));
- DEFINE(GPR21, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[21]));
- DEFINE(GPR22, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[22]));
- DEFINE(GPR23, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[23]));
- DEFINE(GPR24, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[24]));
- DEFINE(GPR25, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[25]));
- DEFINE(GPR26, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[26]));
- DEFINE(GPR27, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[27]));
- DEFINE(GPR28, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[28]));
- DEFINE(GPR29, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[29]));
- DEFINE(GPR30, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[30]));
- DEFINE(GPR31, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[31]));
- /*
- * Note: these symbols include _ because they overlap with special
- * register names
- */
- DEFINE(_NIP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, nip));
- DEFINE(_MSR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, msr));
- DEFINE(_CTR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, ctr));
- DEFINE(_LINK, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, link));
- DEFINE(_CCR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, ccr));
- DEFINE(_MQ, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, mq));
- DEFINE(_XER, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, xer));
- DEFINE(_DAR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dar));
- DEFINE(_DSISR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dsisr));
- /* The PowerPC 400-class & Book-E processors have neither the DAR nor the DSISR
- * SPRs. Hence, we overload them to hold the similar DEAR and ESR SPRs
- * for such processors. For critical interrupts we use them to
- * hold SRR0 and SRR1.
- */
- DEFINE(_DEAR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dar));
- DEFINE(_ESR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dsisr));
- DEFINE(ORIG_GPR3, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, orig_gpr3));
- DEFINE(RESULT, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, result));
- DEFINE(TRAP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, trap));
- DEFINE(CLONE_VM, CLONE_VM);
- DEFINE(CLONE_UNTRACED, CLONE_UNTRACED);
- DEFINE(MM_PGD, offsetof(struct mm_struct, pgd));
-
- /* About the CPU features table */
- DEFINE(CPU_SPEC_ENTRY_SIZE, sizeof(struct cpu_spec));
- DEFINE(CPU_SPEC_PVR_MASK, offsetof(struct cpu_spec, pvr_mask));
- DEFINE(CPU_SPEC_PVR_VALUE, offsetof(struct cpu_spec, pvr_value));
- DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features));
- DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup));
-
-#ifdef CONFIG_PPC64
- DEFINE(MM, offsetof(struct task_struct, mm));
- DEFINE(AUDITCONTEXT, offsetof(struct task_struct, audit_context));
-
- DEFINE(DCACHEL1LINESIZE, offsetof(struct ppc64_caches, dline_size));
- DEFINE(DCACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_dline_size));
- DEFINE(DCACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, dlines_per_page));
- DEFINE(ICACHEL1LINESIZE, offsetof(struct ppc64_caches, iline_size));
- DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size));
- DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page));
- DEFINE(PLATFORM, offsetof(struct systemcfg, platform));
-
- /* paca */
- DEFINE(PACA_SIZE, sizeof(struct paca_struct));
- DEFINE(PACAPACAINDEX, offsetof(struct paca_struct, paca_index));
- DEFINE(PACAPROCSTART, offsetof(struct paca_struct, cpu_start));
- DEFINE(PACAKSAVE, offsetof(struct paca_struct, kstack));
- DEFINE(PACACURRENT, offsetof(struct paca_struct, __current));
- DEFINE(PACASAVEDMSR, offsetof(struct paca_struct, saved_msr));
- DEFINE(PACASTABREAL, offsetof(struct paca_struct, stab_real));
- DEFINE(PACASTABVIRT, offsetof(struct paca_struct, stab_addr));
- DEFINE(PACASTABRR, offsetof(struct paca_struct, stab_rr));
- DEFINE(PACAR1, offsetof(struct paca_struct, saved_r1));
- DEFINE(PACATOC, offsetof(struct paca_struct, kernel_toc));
- DEFINE(PACAPROCENABLED, offsetof(struct paca_struct, proc_enabled));
- DEFINE(PACASLBCACHE, offsetof(struct paca_struct, slb_cache));
- DEFINE(PACASLBCACHEPTR, offsetof(struct paca_struct, slb_cache_ptr));
- DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id));
-#ifdef CONFIG_HUGETLB_PAGE
- DEFINE(PACALOWHTLBAREAS, offsetof(struct paca_struct, context.low_htlb_areas));
- DEFINE(PACAHIGHHTLBAREAS, offsetof(struct paca_struct, context.high_htlb_areas));
-#endif /* CONFIG_HUGETLB_PAGE */
- DEFINE(PACADEFAULTDECR, offsetof(struct paca_struct, default_decr));
- DEFINE(PACA_EXGEN, offsetof(struct paca_struct, exgen));
- DEFINE(PACA_EXMC, offsetof(struct paca_struct, exmc));
- DEFINE(PACA_EXSLB, offsetof(struct paca_struct, exslb));
- DEFINE(PACA_EXDSI, offsetof(struct paca_struct, exdsi));
- DEFINE(PACAEMERGSP, offsetof(struct paca_struct, emergency_sp));
- DEFINE(PACALPPACA, offsetof(struct paca_struct, lppaca));
- DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id));
- DEFINE(LPPACASRR0, offsetof(struct lppaca, saved_srr0));
- DEFINE(LPPACASRR1, offsetof(struct lppaca, saved_srr1));
- DEFINE(LPPACAANYINT, offsetof(struct lppaca, int_dword.any_int));
- DEFINE(LPPACADECRINT, offsetof(struct lppaca, int_dword.fields.decr_int));
-
- /* RTAS */
- DEFINE(RTASBASE, offsetof(struct rtas_t, base));
- DEFINE(RTASENTRY, offsetof(struct rtas_t, entry));
-
- DEFINE(_TRAP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, trap));
- DEFINE(SOFTE, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, softe));
-
- /* Create extra stack space for SRR0 and SRR1 when calling prom/rtas. */
- DEFINE(PROM_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16);
- DEFINE(RTAS_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16);
-
- /* These _only_ to be used with {PROM,RTAS}_FRAME_SIZE!!! */
- DEFINE(_SRR0, STACK_FRAME_OVERHEAD+sizeof(struct pt_regs));
- DEFINE(_SRR1, STACK_FRAME_OVERHEAD+sizeof(struct pt_regs)+8);
-
- /* systemcfg offsets for use by vdso */
- DEFINE(CFG_TB_ORIG_STAMP, offsetof(struct systemcfg, tb_orig_stamp));
- DEFINE(CFG_TB_TICKS_PER_SEC, offsetof(struct systemcfg, tb_ticks_per_sec));
- DEFINE(CFG_TB_TO_XS, offsetof(struct systemcfg, tb_to_xs));
- DEFINE(CFG_STAMP_XSEC, offsetof(struct systemcfg, stamp_xsec));
- DEFINE(CFG_TB_UPDATE_COUNT, offsetof(struct systemcfg, tb_update_count));
- DEFINE(CFG_TZ_MINUTEWEST, offsetof(struct systemcfg, tz_minuteswest));
- DEFINE(CFG_TZ_DSTTIME, offsetof(struct systemcfg, tz_dsttime));
- DEFINE(CFG_SYSCALL_MAP32, offsetof(struct systemcfg, syscall_map_32));
- DEFINE(CFG_SYSCALL_MAP64, offsetof(struct systemcfg, syscall_map_64));
-
- /* timeval/timezone offsets for use by vdso */
- DEFINE(TVAL64_TV_SEC, offsetof(struct timeval, tv_sec));
- DEFINE(TVAL64_TV_USEC, offsetof(struct timeval, tv_usec));
- DEFINE(TVAL32_TV_SEC, offsetof(struct compat_timeval, tv_sec));
- DEFINE(TVAL32_TV_USEC, offsetof(struct compat_timeval, tv_usec));
- DEFINE(TZONE_TZ_MINWEST, offsetof(struct timezone, tz_minuteswest));
- DEFINE(TZONE_TZ_DSTTIME, offsetof(struct timezone, tz_dsttime));
-#endif
-
- DEFINE(pbe_address, offsetof(struct pbe, address));
- DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address));
- DEFINE(pbe_next, offsetof(struct pbe, next));
-
- DEFINE(NUM_USER_SEGMENTS, TASK_SIZE>>28);
- return 0;
-}
diff --git a/trunk/arch/powerpc/kernel/fpu.S b/trunk/arch/powerpc/kernel/fpu.S
deleted file mode 100644
index 665d7d34304c..000000000000
--- a/trunk/arch/powerpc/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
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-/*
- * 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
diff --git a/trunk/arch/powerpc/kernel/head.S b/trunk/arch/powerpc/kernel/head.S
deleted file mode 100644
index d05509f197d0..000000000000
--- a/trunk/arch/powerpc/kernel/head.S
+++ /dev/null
@@ -1,1545 +0,0 @@
-/*
- * PowerPC version
- * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
- *
- * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
- * Copyright (C) 1996 Cort Dougan
- * Adapted for Power Macintosh by Paul Mackerras.
- * Low-level exception handlers and MMU support
- * rewritten by Paul Mackerras.
- * Copyright (C) 1996 Paul Mackerras.
- * MPC8xx modifications Copyright (C) 1997 Dan Malek (dmalek@jlc.net).
- * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
- *
- * This file contains the low-level support and setup for the
- * PowerPC platform, including trap and interrupt dispatch.
- * (The PPC 8xx embedded CPUs use head_8xx.S instead.)
- *
- * 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
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#ifdef CONFIG_APUS
-#include
-#endif
-
-#ifdef CONFIG_PPC64BRIDGE
-#define LOAD_BAT(n, reg, RA, RB) \
- ld RA,(n*32)+0(reg); \
- ld RB,(n*32)+8(reg); \
- mtspr SPRN_IBAT##n##U,RA; \
- mtspr SPRN_IBAT##n##L,RB; \
- ld RA,(n*32)+16(reg); \
- ld RB,(n*32)+24(reg); \
- mtspr SPRN_DBAT##n##U,RA; \
- mtspr SPRN_DBAT##n##L,RB; \
-
-#else /* CONFIG_PPC64BRIDGE */
-
-/* 601 only have IBAT; cr0.eq is set on 601 when using this macro */
-#define LOAD_BAT(n, reg, RA, RB) \
- /* see the comment for clear_bats() -- Cort */ \
- li RA,0; \
- mtspr SPRN_IBAT##n##U,RA; \
- mtspr SPRN_DBAT##n##U,RA; \
- lwz RA,(n*16)+0(reg); \
- lwz RB,(n*16)+4(reg); \
- mtspr SPRN_IBAT##n##U,RA; \
- mtspr SPRN_IBAT##n##L,RB; \
- beq 1f; \
- lwz RA,(n*16)+8(reg); \
- lwz RB,(n*16)+12(reg); \
- mtspr SPRN_DBAT##n##U,RA; \
- mtspr SPRN_DBAT##n##L,RB; \
-1:
-#endif /* CONFIG_PPC64BRIDGE */
-
- .text
- .stabs "arch/ppc/kernel/",N_SO,0,0,0f
- .stabs "head.S",N_SO,0,0,0f
-0:
- .globl _stext
-_stext:
-
-/*
- * _start is defined this way because the XCOFF loader in the OpenFirmware
- * on the powermac expects the entry point to be a procedure descriptor.
- */
- .text
- .globl _start
-_start:
- /*
- * These are here for legacy reasons, the kernel used to
- * need to look like a coff function entry for the pmac
- * but we're always started by some kind of bootloader now.
- * -- Cort
- */
- nop /* used by __secondary_hold on prep (mtx) and chrp smp */
- nop /* used by __secondary_hold on prep (mtx) and chrp smp */
- nop
-
-/* PMAC
- * Enter here with the kernel text, data and bss loaded starting at
- * 0, running with virtual == physical mapping.
- * r5 points to the prom entry point (the client interface handler
- * address). Address translation is turned on, with the prom
- * managing the hash table. Interrupts are disabled. The stack
- * pointer (r1) points to just below the end of the half-meg region
- * from 0x380000 - 0x400000, which is mapped in already.
- *
- * If we are booted from MacOS via BootX, we enter with the kernel
- * image loaded somewhere, and the following values in registers:
- * r3: 'BooX' (0x426f6f58)
- * r4: virtual address of boot_infos_t
- * r5: 0
- *
- * APUS
- * r3: 'APUS'
- * r4: physical address of memory base
- * Linux/m68k style BootInfo structure at &_end.
- *
- * PREP
- * This is jumped to on prep systems right after the kernel is relocated
- * to its proper place in memory by the boot loader. The expected layout
- * of the regs is:
- * r3: ptr to residual data
- * r4: initrd_start or if no initrd then 0
- * r5: initrd_end - unused if r4 is 0
- * r6: Start of command line string
- * r7: End of command line string
- *
- * This just gets a minimal mmu environment setup so we can call
- * start_here() to do the real work.
- * -- Cort
- */
-
- .globl __start
-__start:
-/*
- * We have to do any OF calls before we map ourselves to KERNELBASE,
- * because OF may have I/O devices mapped into that area
- * (particularly on CHRP).
- */
- mr r31,r3 /* save parameters */
- mr r30,r4
- mr r29,r5
- mr r28,r6
- mr r27,r7
- li r24,0 /* cpu # */
-
-/*
- * early_init() does the early machine identification and does
- * the necessary low-level setup and clears the BSS
- * -- Cort
- */
- bl early_init
-
-/*
- * On POWER4, we first need to tweak some CPU configuration registers
- * like real mode cache inhibit or exception base
- */
-#ifdef CONFIG_POWER4
- bl __970_cpu_preinit
-#endif /* CONFIG_POWER4 */
-
-#ifdef CONFIG_APUS
-/* On APUS the __va/__pa constants need to be set to the correct
- * values before continuing.
- */
- mr r4,r30
- bl fix_mem_constants
-#endif /* CONFIG_APUS */
-
-/* Switch MMU off, clear BATs and flush TLB. At this point, r3 contains
- * the physical address we are running at, returned by early_init()
- */
- bl mmu_off
-__after_mmu_off:
-#ifndef CONFIG_POWER4
- bl clear_bats
- bl flush_tlbs
-
- bl initial_bats
-#if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT)
- bl setup_disp_bat
-#endif
-#else /* CONFIG_POWER4 */
- bl reloc_offset
- bl initial_mm_power4
-#endif /* CONFIG_POWER4 */
-
-/*
- * Call setup_cpu for CPU 0 and initialize 6xx Idle
- */
- bl reloc_offset
- li r24,0 /* cpu# */
- bl call_setup_cpu /* Call setup_cpu for this CPU */
-#ifdef CONFIG_6xx
- bl reloc_offset
- bl init_idle_6xx
-#endif /* CONFIG_6xx */
-#ifdef CONFIG_POWER4
- bl reloc_offset
- bl init_idle_power4
-#endif /* CONFIG_POWER4 */
-
-
-#ifndef CONFIG_APUS
-/*
- * We need to run with _start at physical address 0.
- * On CHRP, we are loaded at 0x10000 since OF on CHRP uses
- * the exception vectors at 0 (and therefore this copy
- * overwrites OF's exception vectors with our own).
- * If the MMU is already turned on, we copy stuff to KERNELBASE,
- * otherwise we copy it to 0.
- */
- bl reloc_offset
- mr r26,r3
- addis r4,r3,KERNELBASE@h /* current address of _start */
- cmpwi 0,r4,0 /* are we already running at 0? */
- bne relocate_kernel
-#endif /* CONFIG_APUS */
-/*
- * we now have the 1st 16M of ram mapped with the bats.
- * prep needs the mmu to be turned on here, but pmac already has it on.
- * this shouldn't bother the pmac since it just gets turned on again
- * as we jump to our code at KERNELBASE. -- Cort
- * Actually no, pmac doesn't have it on any more. BootX enters with MMU
- * off, and in other cases, we now turn it off before changing BATs above.
- */
-turn_on_mmu:
- mfmsr r0
- ori r0,r0,MSR_DR|MSR_IR
- mtspr SPRN_SRR1,r0
- lis r0,start_here@h
- ori r0,r0,start_here@l
- mtspr SPRN_SRR0,r0
- SYNC
- RFI /* enables MMU */
-
-/*
- * We need __secondary_hold as a place to hold the other cpus on
- * an SMP machine, even when we are running a UP kernel.
- */
- . = 0xc0 /* for prep bootloader */
- li r3,1 /* MTX only has 1 cpu */
- .globl __secondary_hold
-__secondary_hold:
- /* tell the master we're here */
- stw r3,4(0)
-#ifdef CONFIG_SMP
-100: lwz r4,0(0)
- /* wait until we're told to start */
- cmpw 0,r4,r3
- bne 100b
- /* our cpu # was at addr 0 - go */
- mr r24,r3 /* cpu # */
- b __secondary_start
-#else
- b .
-#endif /* CONFIG_SMP */
-
-/*
- * Exception entry code. This code runs with address translation
- * turned off, i.e. using physical addresses.
- * We assume sprg3 has the physical address of the current
- * task's thread_struct.
- */
-#define EXCEPTION_PROLOG \
- mtspr SPRN_SPRG0,r10; \
- mtspr SPRN_SPRG1,r11; \
- mfcr r10; \
- EXCEPTION_PROLOG_1; \
- EXCEPTION_PROLOG_2
-
-#define EXCEPTION_PROLOG_1 \
- mfspr r11,SPRN_SRR1; /* check whether user or kernel */ \
- andi. r11,r11,MSR_PR; \
- tophys(r11,r1); /* use tophys(r1) if kernel */ \
- beq 1f; \
- mfspr r11,SPRN_SPRG3; \
- lwz r11,THREAD_INFO-THREAD(r11); \
- addi r11,r11,THREAD_SIZE; \
- tophys(r11,r11); \
-1: subi r11,r11,INT_FRAME_SIZE /* alloc exc. frame */
-
-
-#define EXCEPTION_PROLOG_2 \
- CLR_TOP32(r11); \
- stw r10,_CCR(r11); /* save registers */ \
- stw r12,GPR12(r11); \
- stw r9,GPR9(r11); \
- mfspr r10,SPRN_SPRG0; \
- stw r10,GPR10(r11); \
- mfspr r12,SPRN_SPRG1; \
- stw r12,GPR11(r11); \
- mflr r10; \
- stw r10,_LINK(r11); \
- mfspr r12,SPRN_SRR0; \
- mfspr r9,SPRN_SRR1; \
- stw r1,GPR1(r11); \
- stw r1,0(r11); \
- tovirt(r1,r11); /* set new kernel sp */ \
- li r10,MSR_KERNEL & ~(MSR_IR|MSR_DR); /* can take exceptions */ \
- MTMSRD(r10); /* (except for mach check in rtas) */ \
- stw r0,GPR0(r11); \
- SAVE_4GPRS(3, r11); \
- SAVE_2GPRS(7, r11)
-
-/*
- * Note: code which follows this uses cr0.eq (set if from kernel),
- * r11, r12 (SRR0), and r9 (SRR1).
- *
- * Note2: once we have set r1 we are in a position to take exceptions
- * again, and we could thus set MSR:RI at that point.
- */
-
-/*
- * Exception vectors.
- */
-#define EXCEPTION(n, label, hdlr, xfer) \
- . = n; \
-label: \
- EXCEPTION_PROLOG; \
- addi r3,r1,STACK_FRAME_OVERHEAD; \
- xfer(n, hdlr)
-
-#define EXC_XFER_TEMPLATE(n, hdlr, trap, copyee, tfer, ret) \
- li r10,trap; \
- stw r10,TRAP(r11); \
- li r10,MSR_KERNEL; \
- copyee(r10, r9); \
- bl tfer; \
-i##n: \
- .long hdlr; \
- .long ret
-
-#define COPY_EE(d, s) rlwimi d,s,0,16,16
-#define NOCOPY(d, s)
-
-#define EXC_XFER_STD(n, hdlr) \
- EXC_XFER_TEMPLATE(n, hdlr, n, NOCOPY, transfer_to_handler_full, \
- ret_from_except_full)
-
-#define EXC_XFER_LITE(n, hdlr) \
- EXC_XFER_TEMPLATE(n, hdlr, n+1, NOCOPY, transfer_to_handler, \
- ret_from_except)
-
-#define EXC_XFER_EE(n, hdlr) \
- EXC_XFER_TEMPLATE(n, hdlr, n, COPY_EE, transfer_to_handler_full, \
- ret_from_except_full)
-
-#define EXC_XFER_EE_LITE(n, hdlr) \
- EXC_XFER_TEMPLATE(n, hdlr, n+1, COPY_EE, transfer_to_handler, \
- ret_from_except)
-
-/* System reset */
-/* core99 pmac starts the seconary here by changing the vector, and
- putting it back to what it was (UnknownException) when done. */
-#if defined(CONFIG_GEMINI) && defined(CONFIG_SMP)
- . = 0x100
- b __secondary_start_gemini
-#else
- EXCEPTION(0x100, Reset, UnknownException, EXC_XFER_STD)
-#endif
-
-/* Machine check */
-/*
- * On CHRP, this is complicated by the fact that we could get a
- * machine check inside RTAS, and we have no guarantee that certain
- * critical registers will have the values we expect. The set of
- * registers that might have bad values includes all the GPRs
- * and all the BATs. We indicate that we are in RTAS by putting
- * a non-zero value, the address of the exception frame to use,
- * in SPRG2. The machine check handler checks SPRG2 and uses its
- * value if it is non-zero. If we ever needed to free up SPRG2,
- * we could use a field in the thread_info or thread_struct instead.
- * (Other exception handlers assume that r1 is a valid kernel stack
- * pointer when we take an exception from supervisor mode.)
- * -- paulus.
- */
- . = 0x200
- mtspr SPRN_SPRG0,r10
- mtspr SPRN_SPRG1,r11
- mfcr r10
-#ifdef CONFIG_PPC_CHRP
- mfspr r11,SPRN_SPRG2
- cmpwi 0,r11,0
- bne 7f
-#endif /* CONFIG_PPC_CHRP */
- EXCEPTION_PROLOG_1
-7: EXCEPTION_PROLOG_2
- addi r3,r1,STACK_FRAME_OVERHEAD
-#ifdef CONFIG_PPC_CHRP
- mfspr r4,SPRN_SPRG2
- cmpwi cr1,r4,0
- bne cr1,1f
-#endif
- EXC_XFER_STD(0x200, MachineCheckException)
-#ifdef CONFIG_PPC_CHRP
-1: b machine_check_in_rtas
-#endif
-
-/* Data access exception. */
- . = 0x300
-#ifdef CONFIG_PPC64BRIDGE
- b DataAccess
-DataAccessCont:
-#else
-DataAccess:
- EXCEPTION_PROLOG
-#endif /* CONFIG_PPC64BRIDGE */
- mfspr r10,SPRN_DSISR
- andis. r0,r10,0xa470 /* weird error? */
- bne 1f /* if not, try to put a PTE */
- mfspr r4,SPRN_DAR /* into the hash table */
- rlwinm r3,r10,32-15,21,21 /* DSISR_STORE -> _PAGE_RW */
- bl hash_page
-1: stw r10,_DSISR(r11)
- mr r5,r10
- mfspr r4,SPRN_DAR
- EXC_XFER_EE_LITE(0x300, handle_page_fault)
-
-#ifdef CONFIG_PPC64BRIDGE
-/* SLB fault on data access. */
- . = 0x380
- b DataSegment
-#endif /* CONFIG_PPC64BRIDGE */
-
-/* Instruction access exception. */
- . = 0x400
-#ifdef CONFIG_PPC64BRIDGE
- b InstructionAccess
-InstructionAccessCont:
-#else
-InstructionAccess:
- EXCEPTION_PROLOG
-#endif /* CONFIG_PPC64BRIDGE */
- andis. r0,r9,0x4000 /* no pte found? */
- beq 1f /* if so, try to put a PTE */
- li r3,0 /* into the hash table */
- mr r4,r12 /* SRR0 is fault address */
- bl hash_page
-1: mr r4,r12
- mr r5,r9
- EXC_XFER_EE_LITE(0x400, handle_page_fault)
-
-#ifdef CONFIG_PPC64BRIDGE
-/* SLB fault on instruction access. */
- . = 0x480
- b InstructionSegment
-#endif /* CONFIG_PPC64BRIDGE */
-
-/* External interrupt */
- EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE)
-
-/* Alignment exception */
- . = 0x600
-Alignment:
- EXCEPTION_PROLOG
- mfspr r4,SPRN_DAR
- stw r4,_DAR(r11)
- mfspr r5,SPRN_DSISR
- stw r5,_DSISR(r11)
- addi r3,r1,STACK_FRAME_OVERHEAD
- EXC_XFER_EE(0x600, AlignmentException)
-
-/* Program check exception */
- EXCEPTION(0x700, ProgramCheck, ProgramCheckException, EXC_XFER_STD)
-
-/* Floating-point unavailable */
- . = 0x800
-FPUnavailable:
- EXCEPTION_PROLOG
- bne load_up_fpu /* if from user, just load it up */
- addi r3,r1,STACK_FRAME_OVERHEAD
- EXC_XFER_EE_LITE(0x800, KernelFP)
-
-/* Decrementer */
- EXCEPTION(0x900, Decrementer, timer_interrupt, EXC_XFER_LITE)
-
- EXCEPTION(0xa00, Trap_0a, UnknownException, EXC_XFER_EE)
- EXCEPTION(0xb00, Trap_0b, UnknownException, EXC_XFER_EE)
-
-/* System call */
- . = 0xc00
-SystemCall:
- EXCEPTION_PROLOG
- EXC_XFER_EE_LITE(0xc00, DoSyscall)
-
-/* Single step - not used on 601 */
- EXCEPTION(0xd00, SingleStep, SingleStepException, EXC_XFER_STD)
- EXCEPTION(0xe00, Trap_0e, UnknownException, EXC_XFER_EE)
-
-/*
- * The Altivec unavailable trap is at 0x0f20. Foo.
- * We effectively remap it to 0x3000.
- * We include an altivec unavailable exception vector even if
- * not configured for Altivec, so that you can't panic a
- * non-altivec kernel running on a machine with altivec just
- * by executing an altivec instruction.
- */
- . = 0xf00
- b Trap_0f
-
- . = 0xf20
- b AltiVecUnavailable
-
-Trap_0f:
- EXCEPTION_PROLOG
- addi r3,r1,STACK_FRAME_OVERHEAD
- EXC_XFER_EE(0xf00, UnknownException)
-
-/*
- * Handle TLB miss for instruction on 603/603e.
- * Note: we get an alternate set of r0 - r3 to use automatically.
- */
- . = 0x1000
-InstructionTLBMiss:
-/*
- * r0: stored ctr
- * r1: linux style pte ( later becomes ppc hardware pte )
- * r2: ptr to linux-style pte
- * r3: scratch
- */
- mfctr r0
- /* Get PTE (linux-style) and check access */
- mfspr r3,SPRN_IMISS
- lis r1,KERNELBASE@h /* check if kernel address */
- cmplw 0,r3,r1
- mfspr r2,SPRN_SPRG3
- li r1,_PAGE_USER|_PAGE_PRESENT /* low addresses tested as user */
- lwz r2,PGDIR(r2)
- blt+ 112f
- lis r2,swapper_pg_dir@ha /* if kernel address, use */
- addi r2,r2,swapper_pg_dir@l /* kernel page table */
- mfspr r1,SPRN_SRR1 /* and MSR_PR bit from SRR1 */
- rlwinm r1,r1,32-12,29,29 /* shift MSR_PR to _PAGE_USER posn */
-112: tophys(r2,r2)
- rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */
- lwz r2,0(r2) /* get pmd entry */
- rlwinm. r2,r2,0,0,19 /* extract address of pte page */
- beq- InstructionAddressInvalid /* return if no mapping */
- rlwimi r2,r3,22,20,29 /* insert next 10 bits of address */
- lwz r3,0(r2) /* get linux-style pte */
- andc. r1,r1,r3 /* check access & ~permission */
- bne- InstructionAddressInvalid /* return if access not permitted */
- ori r3,r3,_PAGE_ACCESSED /* set _PAGE_ACCESSED in pte */
- /*
- * NOTE! We are assuming this is not an SMP system, otherwise
- * we would need to update the pte atomically with lwarx/stwcx.
- */
- stw r3,0(r2) /* update PTE (accessed bit) */
- /* Convert linux-style PTE to low word of PPC-style PTE */
- rlwinm r1,r3,32-10,31,31 /* _PAGE_RW -> PP lsb */
- rlwinm r2,r3,32-7,31,31 /* _PAGE_DIRTY -> PP lsb */
- and r1,r1,r2 /* writable if _RW and _DIRTY */
- rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */
- rlwimi r3,r3,32-1,31,31 /* _PAGE_USER -> PP lsb */
- ori r1,r1,0xe14 /* clear out reserved bits and M */
- andc r1,r3,r1 /* PP = user? (rw&dirty? 2: 3): 0 */
- mtspr SPRN_RPA,r1
- mfspr r3,SPRN_IMISS
- tlbli r3
- mfspr r3,SPRN_SRR1 /* Need to restore CR0 */
- mtcrf 0x80,r3
- rfi
-InstructionAddressInvalid:
- mfspr r3,SPRN_SRR1
- rlwinm r1,r3,9,6,6 /* Get load/store bit */
-
- addis r1,r1,0x2000
- mtspr SPRN_DSISR,r1 /* (shouldn't be needed) */
- mtctr r0 /* Restore CTR */
- andi. r2,r3,0xFFFF /* Clear upper bits of SRR1 */
- or r2,r2,r1
- mtspr SPRN_SRR1,r2
- mfspr r1,SPRN_IMISS /* Get failing address */
- rlwinm. r2,r2,0,31,31 /* Check for little endian access */
- rlwimi r2,r2,1,30,30 /* change 1 -> 3 */
- xor r1,r1,r2
- mtspr SPRN_DAR,r1 /* Set fault address */
- mfmsr r0 /* Restore "normal" registers */
- xoris r0,r0,MSR_TGPR>>16
- mtcrf 0x80,r3 /* Restore CR0 */
- mtmsr r0
- b InstructionAccess
-
-/*
- * Handle TLB miss for DATA Load operation on 603/603e
- */
- . = 0x1100
-DataLoadTLBMiss:
-/*
- * r0: stored ctr
- * r1: linux style pte ( later becomes ppc hardware pte )
- * r2: ptr to linux-style pte
- * r3: scratch
- */
- mfctr r0
- /* Get PTE (linux-style) and check access */
- mfspr r3,SPRN_DMISS
- lis r1,KERNELBASE@h /* check if kernel address */
- cmplw 0,r3,r1
- mfspr r2,SPRN_SPRG3
- li r1,_PAGE_USER|_PAGE_PRESENT /* low addresses tested as user */
- lwz r2,PGDIR(r2)
- blt+ 112f
- lis r2,swapper_pg_dir@ha /* if kernel address, use */
- addi r2,r2,swapper_pg_dir@l /* kernel page table */
- mfspr r1,SPRN_SRR1 /* and MSR_PR bit from SRR1 */
- rlwinm r1,r1,32-12,29,29 /* shift MSR_PR to _PAGE_USER posn */
-112: tophys(r2,r2)
- rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */
- lwz r2,0(r2) /* get pmd entry */
- rlwinm. r2,r2,0,0,19 /* extract address of pte page */
- beq- DataAddressInvalid /* return if no mapping */
- rlwimi r2,r3,22,20,29 /* insert next 10 bits of address */
- lwz r3,0(r2) /* get linux-style pte */
- andc. r1,r1,r3 /* check access & ~permission */
- bne- DataAddressInvalid /* return if access not permitted */
- ori r3,r3,_PAGE_ACCESSED /* set _PAGE_ACCESSED in pte */
- /*
- * NOTE! We are assuming this is not an SMP system, otherwise
- * we would need to update the pte atomically with lwarx/stwcx.
- */
- stw r3,0(r2) /* update PTE (accessed bit) */
- /* Convert linux-style PTE to low word of PPC-style PTE */
- rlwinm r1,r3,32-10,31,31 /* _PAGE_RW -> PP lsb */
- rlwinm r2,r3,32-7,31,31 /* _PAGE_DIRTY -> PP lsb */
- and r1,r1,r2 /* writable if _RW and _DIRTY */
- rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */
- rlwimi r3,r3,32-1,31,31 /* _PAGE_USER -> PP lsb */
- ori r1,r1,0xe14 /* clear out reserved bits and M */
- andc r1,r3,r1 /* PP = user? (rw&dirty? 2: 3): 0 */
- mtspr SPRN_RPA,r1
- mfspr r3,SPRN_DMISS
- tlbld r3
- mfspr r3,SPRN_SRR1 /* Need to restore CR0 */
- mtcrf 0x80,r3
- rfi
-DataAddressInvalid:
- mfspr r3,SPRN_SRR1
- rlwinm r1,r3,9,6,6 /* Get load/store bit */
- addis r1,r1,0x2000
- mtspr SPRN_DSISR,r1
- mtctr r0 /* Restore CTR */
- andi. r2,r3,0xFFFF /* Clear upper bits of SRR1 */
- mtspr SPRN_SRR1,r2
- mfspr r1,SPRN_DMISS /* Get failing address */
- rlwinm. r2,r2,0,31,31 /* Check for little endian access */
- beq 20f /* Jump if big endian */
- xori r1,r1,3
-20: mtspr SPRN_DAR,r1 /* Set fault address */
- mfmsr r0 /* Restore "normal" registers */
- xoris r0,r0,MSR_TGPR>>16
- mtcrf 0x80,r3 /* Restore CR0 */
- mtmsr r0
- b DataAccess
-
-/*
- * Handle TLB miss for DATA Store on 603/603e
- */
- . = 0x1200
-DataStoreTLBMiss:
-/*
- * r0: stored ctr
- * r1: linux style pte ( later becomes ppc hardware pte )
- * r2: ptr to linux-style pte
- * r3: scratch
- */
- mfctr r0
- /* Get PTE (linux-style) and check access */
- mfspr r3,SPRN_DMISS
- lis r1,KERNELBASE@h /* check if kernel address */
- cmplw 0,r3,r1
- mfspr r2,SPRN_SPRG3
- li r1,_PAGE_RW|_PAGE_USER|_PAGE_PRESENT /* access flags */
- lwz r2,PGDIR(r2)
- blt+ 112f
- lis r2,swapper_pg_dir@ha /* if kernel address, use */
- addi r2,r2,swapper_pg_dir@l /* kernel page table */
- mfspr r1,SPRN_SRR1 /* and MSR_PR bit from SRR1 */
- rlwinm r1,r1,32-12,29,29 /* shift MSR_PR to _PAGE_USER posn */
-112: tophys(r2,r2)
- rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */
- lwz r2,0(r2) /* get pmd entry */
- rlwinm. r2,r2,0,0,19 /* extract address of pte page */
- beq- DataAddressInvalid /* return if no mapping */
- rlwimi r2,r3,22,20,29 /* insert next 10 bits of address */
- lwz r3,0(r2) /* get linux-style pte */
- andc. r1,r1,r3 /* check access & ~permission */
- bne- DataAddressInvalid /* return if access not permitted */
- ori r3,r3,_PAGE_ACCESSED|_PAGE_DIRTY
- /*
- * NOTE! We are assuming this is not an SMP system, otherwise
- * we would need to update the pte atomically with lwarx/stwcx.
- */
- stw r3,0(r2) /* update PTE (accessed/dirty bits) */
- /* Convert linux-style PTE to low word of PPC-style PTE */
- rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */
- li r1,0xe15 /* clear out reserved bits and M */
- andc r1,r3,r1 /* PP = user? 2: 0 */
- mtspr SPRN_RPA,r1
- mfspr r3,SPRN_DMISS
- tlbld r3
- mfspr r3,SPRN_SRR1 /* Need to restore CR0 */
- mtcrf 0x80,r3
- rfi
-
-#ifndef CONFIG_ALTIVEC
-#define AltivecAssistException UnknownException
-#endif
-
- EXCEPTION(0x1300, Trap_13, InstructionBreakpoint, EXC_XFER_EE)
- EXCEPTION(0x1400, SMI, SMIException, EXC_XFER_EE)
- EXCEPTION(0x1500, Trap_15, UnknownException, EXC_XFER_EE)
-#ifdef CONFIG_POWER4
- EXCEPTION(0x1600, Trap_16, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1700, Trap_17, AltivecAssistException, EXC_XFER_EE)
- EXCEPTION(0x1800, Trap_18, TAUException, EXC_XFER_STD)
-#else /* !CONFIG_POWER4 */
- EXCEPTION(0x1600, Trap_16, AltivecAssistException, EXC_XFER_EE)
- EXCEPTION(0x1700, Trap_17, TAUException, EXC_XFER_STD)
- EXCEPTION(0x1800, Trap_18, UnknownException, EXC_XFER_EE)
-#endif /* CONFIG_POWER4 */
- EXCEPTION(0x1900, Trap_19, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1a00, Trap_1a, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1b00, Trap_1b, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1c00, Trap_1c, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1d00, Trap_1d, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1e00, Trap_1e, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1f00, Trap_1f, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2000, RunMode, RunModeException, EXC_XFER_EE)
- EXCEPTION(0x2100, Trap_21, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2200, Trap_22, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2300, Trap_23, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2400, Trap_24, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2500, Trap_25, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2600, Trap_26, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2700, Trap_27, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2800, Trap_28, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2900, Trap_29, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2a00, Trap_2a, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2b00, Trap_2b, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2c00, Trap_2c, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2d00, Trap_2d, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2e00, Trap_2e, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x2f00, MOLTrampoline, UnknownException, EXC_XFER_EE_LITE)
-
- .globl mol_trampoline
- .set mol_trampoline, i0x2f00
-
- . = 0x3000
-
-AltiVecUnavailable:
- EXCEPTION_PROLOG
-#ifdef CONFIG_ALTIVEC
- bne load_up_altivec /* if from user, just load it up */
-#endif /* CONFIG_ALTIVEC */
- EXC_XFER_EE_LITE(0xf20, AltivecUnavailException)
-
-#ifdef CONFIG_PPC64BRIDGE
-DataAccess:
- EXCEPTION_PROLOG
- b DataAccessCont
-
-InstructionAccess:
- EXCEPTION_PROLOG
- b InstructionAccessCont
-
-DataSegment:
- EXCEPTION_PROLOG
- addi r3,r1,STACK_FRAME_OVERHEAD
- mfspr r4,SPRN_DAR
- stw r4,_DAR(r11)
- EXC_XFER_STD(0x380, UnknownException)
-
-InstructionSegment:
- EXCEPTION_PROLOG
- addi r3,r1,STACK_FRAME_OVERHEAD
- EXC_XFER_STD(0x480, UnknownException)
-#endif /* CONFIG_PPC64BRIDGE */
-
-#ifdef CONFIG_ALTIVEC
-/* Note that the AltiVec support is closely modeled after the FP
- * support. Changes to one are likely to be applicable to the
- * other! */
-load_up_altivec:
-/*
- * Disable AltiVec for the task which had AltiVec previously,
- * and save its AltiVec registers in its thread_struct.
- * Enables AltiVec for use in the kernel on return.
- * On SMP we know the AltiVec units are free, since we give it up every
- * switch. -- Kumar
- */
- mfmsr r5
- oris r5,r5,MSR_VEC@h
- MTMSRD(r5) /* enable use of AltiVec now */
- isync
-/*
- * For SMP, we don't do lazy AltiVec switching because it just gets too
- * horrendously complex, especially when a task switches from one CPU
- * to another. Instead we call giveup_altivec in switch_to.
- */
-#ifndef CONFIG_SMP
- tophys(r6,0)
- addis r3,r6,last_task_used_altivec@ha
- lwz r4,last_task_used_altivec@l(r3)
- cmpwi 0,r4,0
- beq 1f
- add r4,r4,r6
- addi r4,r4,THREAD /* want THREAD of last_task_used_altivec */
- SAVE_32VRS(0,r10,r4)
- mfvscr vr0
- li r10,THREAD_VSCR
- stvx vr0,r10,r4
- lwz r5,PT_REGS(r4)
- add r5,r5,r6
- lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5)
- lis r10,MSR_VEC@h
- andc r4,r4,r10 /* disable altivec for previous task */
- stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-1:
-#endif /* CONFIG_SMP */
- /* enable use of AltiVec after return */
- oris r9,r9,MSR_VEC@h
- mfspr r5,SPRN_SPRG3 /* current task's THREAD (phys) */
- li r4,1
- li r10,THREAD_VSCR
- stw r4,THREAD_USED_VR(r5)
- lvx vr0,r10,r5
- mtvscr vr0
- REST_32VRS(0,r10,r5)
-#ifndef CONFIG_SMP
- subi r4,r5,THREAD
- sub r4,r4,r6
- stw r4,last_task_used_altivec@l(r3)
-#endif /* CONFIG_SMP */
- /* restore registers and return */
- /* we haven't used ctr or xer or lr */
- b fast_exception_return
-
-/*
- * AltiVec unavailable trap from kernel - print a message, but let
- * the task use AltiVec in the kernel until it returns to user mode.
- */
-KernelAltiVec:
- lwz r3,_MSR(r1)
- oris r3,r3,MSR_VEC@h
- stw r3,_MSR(r1) /* enable use of AltiVec after return */
- lis r3,87f@h
- ori r3,r3,87f@l
- mr r4,r2 /* current */
- lwz r5,_NIP(r1)
- bl printk
- b ret_from_except
-87: .string "AltiVec used in kernel (task=%p, pc=%x) \n"
- .align 4,0
-
-/*
- * giveup_altivec(tsk)
- * Disable AltiVec for the task given as the argument,
- * and save the AltiVec registers in its thread_struct.
- * Enables AltiVec for use in the kernel on return.
- */
-
- .globl giveup_altivec
-giveup_altivec:
- mfmsr r5
- oris r5,r5,MSR_VEC@h
- SYNC
- MTMSRD(r5) /* enable use of AltiVec now */
- 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_32VRS(0, r4, r3)
- mfvscr vr0
- li r4,THREAD_VSCR
- stvx vr0,r4,r3
- beq 1f
- lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5)
- lis r3,MSR_VEC@h
- andc r4,r4,r3 /* disable AltiVec for previous task */
- stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-1:
-#ifndef CONFIG_SMP
- li r5,0
- lis r4,last_task_used_altivec@ha
- stw r5,last_task_used_altivec@l(r4)
-#endif /* CONFIG_SMP */
- blr
-#endif /* CONFIG_ALTIVEC */
-
-/*
- * This code is jumped to from the startup code to copy
- * the kernel image to physical address 0.
- */
-relocate_kernel:
- addis r9,r26,klimit@ha /* fetch klimit */
- lwz r25,klimit@l(r9)
- addis r25,r25,-KERNELBASE@h
- li r3,0 /* Destination base address */
- li r6,0 /* Destination offset */
- li r5,0x4000 /* # bytes of memory to copy */
- bl copy_and_flush /* copy the first 0x4000 bytes */
- addi r0,r3,4f@l /* jump to the address of 4f */
- mtctr r0 /* in copy and do the rest. */
- bctr /* jump to the copy */
-4: mr r5,r25
- bl copy_and_flush /* copy the rest */
- b turn_on_mmu
-
-/*
- * Copy routine used to copy the kernel to start at physical address 0
- * and flush and invalidate the caches as needed.
- * r3 = dest addr, r4 = source addr, r5 = copy limit, r6 = start offset
- * on exit, r3, r4, r5 are unchanged, r6 is updated to be >= r5.
- */
-copy_and_flush:
- addi r5,r5,-4
- addi r6,r6,-4
-4: li r0,L1_CACHE_LINE_SIZE/4
- mtctr r0
-3: addi r6,r6,4 /* copy a cache line */
- lwzx r0,r6,r4
- stwx r0,r6,r3
- bdnz 3b
- dcbst r6,r3 /* write it to memory */
- sync
- icbi r6,r3 /* flush the icache line */
- cmplw 0,r6,r5
- blt 4b
- sync /* additional sync needed on g4 */
- isync
- addi r5,r5,4
- addi r6,r6,4
- blr
-
-#ifdef CONFIG_APUS
-/*
- * On APUS the physical base address of the kernel is not known at compile
- * time, which means the __pa/__va constants used are incorrect. In the
- * __init section is recorded the virtual addresses of instructions using
- * these constants, so all that has to be done is fix these before
- * continuing the kernel boot.
- *
- * r4 = The physical address of the kernel base.
- */
-fix_mem_constants:
- mr r10,r4
- addis r10,r10,-KERNELBASE@h /* virt_to_phys constant */
- neg r11,r10 /* phys_to_virt constant */
-
- lis r12,__vtop_table_begin@h
- ori r12,r12,__vtop_table_begin@l
- add r12,r12,r10 /* table begin phys address */
- lis r13,__vtop_table_end@h
- ori r13,r13,__vtop_table_end@l
- add r13,r13,r10 /* table end phys address */
- subi r12,r12,4
- subi r13,r13,4
-1: lwzu r14,4(r12) /* virt address of instruction */
- add r14,r14,r10 /* phys address of instruction */
- lwz r15,0(r14) /* instruction, now insert top */
- rlwimi r15,r10,16,16,31 /* half of vp const in low half */
- stw r15,0(r14) /* of instruction and restore. */
- dcbst r0,r14 /* write it to memory */
- sync
- icbi r0,r14 /* flush the icache line */
- cmpw r12,r13
- bne 1b
- sync /* additional sync needed on g4 */
- isync
-
-/*
- * Map the memory where the exception handlers will
- * be copied to when hash constants have been patched.
- */
-#ifdef CONFIG_APUS_FAST_EXCEPT
- lis r8,0xfff0
-#else
- lis r8,0
-#endif
- ori r8,r8,0x2 /* 128KB, supervisor */
- mtspr SPRN_DBAT3U,r8
- mtspr SPRN_DBAT3L,r8
-
- lis r12,__ptov_table_begin@h
- ori r12,r12,__ptov_table_begin@l
- add r12,r12,r10 /* table begin phys address */
- lis r13,__ptov_table_end@h
- ori r13,r13,__ptov_table_end@l
- add r13,r13,r10 /* table end phys address */
- subi r12,r12,4
- subi r13,r13,4
-1: lwzu r14,4(r12) /* virt address of instruction */
- add r14,r14,r10 /* phys address of instruction */
- lwz r15,0(r14) /* instruction, now insert top */
- rlwimi r15,r11,16,16,31 /* half of pv const in low half*/
- stw r15,0(r14) /* of instruction and restore. */
- dcbst r0,r14 /* write it to memory */
- sync
- icbi r0,r14 /* flush the icache line */
- cmpw r12,r13
- bne 1b
-
- sync /* additional sync needed on g4 */
- isync /* No speculative loading until now */
- blr
-
-/***********************************************************************
- * Please note that on APUS the exception handlers are located at the
- * physical address 0xfff0000. For this reason, the exception handlers
- * cannot use relative branches to access the code below.
- ***********************************************************************/
-#endif /* CONFIG_APUS */
-
-#ifdef CONFIG_SMP
-#ifdef CONFIG_GEMINI
- .globl __secondary_start_gemini
-__secondary_start_gemini:
- mfspr r4,SPRN_HID0
- ori r4,r4,HID0_ICFI
- li r3,0
- ori r3,r3,HID0_ICE
- andc r4,r4,r3
- mtspr SPRN_HID0,r4
- sync
- b __secondary_start
-#endif /* CONFIG_GEMINI */
-
- .globl __secondary_start_pmac_0
-__secondary_start_pmac_0:
- /* NB the entries for cpus 0, 1, 2 must each occupy 8 bytes. */
- li r24,0
- b 1f
- li r24,1
- b 1f
- li r24,2
- b 1f
- li r24,3
-1:
- /* on powersurge, we come in here with IR=0 and DR=1, and DBAT 0
- set to map the 0xf0000000 - 0xffffffff region */
- mfmsr r0
- rlwinm r0,r0,0,28,26 /* clear DR (0x10) */
- SYNC
- mtmsr r0
- isync
-
- .globl __secondary_start
-__secondary_start:
-#ifdef CONFIG_PPC64BRIDGE
- mfmsr r0
- clrldi r0,r0,1 /* make sure it's in 32-bit mode */
- SYNC
- MTMSRD(r0)
- isync
-#endif
- /* Copy some CPU settings from CPU 0 */
- bl __restore_cpu_setup
-
- lis r3,-KERNELBASE@h
- mr r4,r24
- bl identify_cpu
- bl call_setup_cpu /* Call setup_cpu for this CPU */
-#ifdef CONFIG_6xx
- lis r3,-KERNELBASE@h
- bl init_idle_6xx
-#endif /* CONFIG_6xx */
-#ifdef CONFIG_POWER4
- lis r3,-KERNELBASE@h
- bl init_idle_power4
-#endif /* CONFIG_POWER4 */
-
- /* get current_thread_info and current */
- lis r1,secondary_ti@ha
- tophys(r1,r1)
- lwz r1,secondary_ti@l(r1)
- tophys(r2,r1)
- lwz r2,TI_TASK(r2)
-
- /* stack */
- addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
- li r0,0
- tophys(r3,r1)
- stw r0,0(r3)
-
- /* load up the MMU */
- bl load_up_mmu
-
- /* ptr to phys current thread */
- tophys(r4,r2)
- addi r4,r4,THREAD /* phys address of our thread_struct */
- CLR_TOP32(r4)
- mtspr SPRN_SPRG3,r4
- li r3,0
- mtspr SPRN_SPRG2,r3 /* 0 => not in RTAS */
-
- /* enable MMU and jump to start_secondary */
- li r4,MSR_KERNEL
- FIX_SRR1(r4,r5)
- lis r3,start_secondary@h
- ori r3,r3,start_secondary@l
- mtspr SPRN_SRR0,r3
- mtspr SPRN_SRR1,r4
- SYNC
- RFI
-#endif /* CONFIG_SMP */
-
-/*
- * Those generic dummy functions are kept for CPUs not
- * included in CONFIG_6xx
- */
-_GLOBAL(__setup_cpu_power3)
- blr
-_GLOBAL(__setup_cpu_generic)
- blr
-
-#if !defined(CONFIG_6xx) && !defined(CONFIG_POWER4)
-_GLOBAL(__save_cpu_setup)
- blr
-_GLOBAL(__restore_cpu_setup)
- blr
-#endif /* !defined(CONFIG_6xx) && !defined(CONFIG_POWER4) */
-
-
-/*
- * Load stuff into the MMU. Intended to be called with
- * IR=0 and DR=0.
- */
-load_up_mmu:
- sync /* Force all PTE updates to finish */
- isync
- tlbia /* Clear all TLB entries */
- sync /* wait for tlbia/tlbie to finish */
- TLBSYNC /* ... on all CPUs */
- /* Load the SDR1 register (hash table base & size) */
- lis r6,_SDR1@ha
- tophys(r6,r6)
- lwz r6,_SDR1@l(r6)
- mtspr SPRN_SDR1,r6
-#ifdef CONFIG_PPC64BRIDGE
- /* clear the ASR so we only use the pseudo-segment registers. */
- li r6,0
- mtasr r6
-#endif /* CONFIG_PPC64BRIDGE */
- li r0,16 /* load up segment register values */
- mtctr r0 /* for context 0 */
- lis r3,0x2000 /* Ku = 1, VSID = 0 */
- li r4,0
-3: mtsrin r3,r4
- addi r3,r3,0x111 /* increment VSID */
- addis r4,r4,0x1000 /* address of next segment */
- bdnz 3b
-#ifndef CONFIG_POWER4
-/* Load the BAT registers with the values set up by MMU_init.
- MMU_init takes care of whether we're on a 601 or not. */
- mfpvr r3
- srwi r3,r3,16
- cmpwi r3,1
- lis r3,BATS@ha
- addi r3,r3,BATS@l
- tophys(r3,r3)
- LOAD_BAT(0,r3,r4,r5)
- LOAD_BAT(1,r3,r4,r5)
- LOAD_BAT(2,r3,r4,r5)
- LOAD_BAT(3,r3,r4,r5)
-#endif /* CONFIG_POWER4 */
- blr
-
-/*
- * This is where the main kernel code starts.
- */
-start_here:
- /* ptr to current */
- lis r2,init_task@h
- ori r2,r2,init_task@l
- /* Set up for using our exception vectors */
- /* ptr to phys current thread */
- tophys(r4,r2)
- addi r4,r4,THREAD /* init task's THREAD */
- CLR_TOP32(r4)
- mtspr SPRN_SPRG3,r4
- li r3,0
- mtspr SPRN_SPRG2,r3 /* 0 => not in RTAS */
-
- /* stack */
- lis r1,init_thread_union@ha
- addi r1,r1,init_thread_union@l
- li r0,0
- stwu r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1)
-/*
- * Do early bootinfo parsing, platform-specific initialization,
- * and set up the MMU.
- */
- mr r3,r31
- mr r4,r30
- mr r5,r29
- mr r6,r28
- mr r7,r27
- bl machine_init
- bl MMU_init
-
-#ifdef CONFIG_APUS
- /* Copy exception code to exception vector base on APUS. */
- lis r4,KERNELBASE@h
-#ifdef CONFIG_APUS_FAST_EXCEPT
- lis r3,0xfff0 /* Copy to 0xfff00000 */
-#else
- lis r3,0 /* Copy to 0x00000000 */
-#endif
- li r5,0x4000 /* # bytes of memory to copy */
- li r6,0
- bl copy_and_flush /* copy the first 0x4000 bytes */
-#endif /* CONFIG_APUS */
-
-/*
- * Go back to running unmapped so we can load up new values
- * for SDR1 (hash table pointer) and the segment registers
- * and change to using our exception vectors.
- */
- lis r4,2f@h
- ori r4,r4,2f@l
- tophys(r4,r4)
- li r3,MSR_KERNEL & ~(MSR_IR|MSR_DR)
- FIX_SRR1(r3,r5)
- mtspr SPRN_SRR0,r4
- mtspr SPRN_SRR1,r3
- SYNC
- RFI
-/* Load up the kernel context */
-2: bl load_up_mmu
-
-#ifdef CONFIG_BDI_SWITCH
- /* Add helper information for the Abatron bdiGDB debugger.
- * We do this here because we know the mmu is disabled, and
- * will be enabled for real in just a few instructions.
- */
- lis r5, abatron_pteptrs@h
- ori r5, r5, abatron_pteptrs@l
- stw r5, 0xf0(r0) /* This much match your Abatron config */
- lis r6, swapper_pg_dir@h
- ori r6, r6, swapper_pg_dir@l
- tophys(r5, r5)
- stw r6, 0(r5)
-#endif /* CONFIG_BDI_SWITCH */
-
-/* Now turn on the MMU for real! */
- li r4,MSR_KERNEL
- FIX_SRR1(r4,r5)
- lis r3,start_kernel@h
- ori r3,r3,start_kernel@l
- mtspr SPRN_SRR0,r3
- mtspr SPRN_SRR1,r4
- SYNC
- RFI
-
-/*
- * Set up the segment registers for a new context.
- */
-_GLOBAL(set_context)
- mulli r3,r3,897 /* multiply context by skew factor */
- rlwinm r3,r3,4,8,27 /* VSID = (context & 0xfffff) << 4 */
- addis r3,r3,0x6000 /* Set Ks, Ku bits */
- li r0,NUM_USER_SEGMENTS
- mtctr r0
-
-#ifdef CONFIG_BDI_SWITCH
- /* Context switch the PTE pointer for the Abatron BDI2000.
- * The PGDIR is passed as second argument.
- */
- lis r5, KERNELBASE@h
- lwz r5, 0xf0(r5)
- stw r4, 0x4(r5)
-#endif
- li r4,0
- isync
-3:
-#ifdef CONFIG_PPC64BRIDGE
- slbie r4
-#endif /* CONFIG_PPC64BRIDGE */
- mtsrin r3,r4
- addi r3,r3,0x111 /* next VSID */
- rlwinm r3,r3,0,8,3 /* clear out any overflow from VSID field */
- addis r4,r4,0x1000 /* address of next segment */
- bdnz 3b
- sync
- isync
- blr
-
-/*
- * An undocumented "feature" of 604e requires that the v bit
- * be cleared before changing BAT values.
- *
- * Also, newer IBM firmware does not clear bat3 and 4 so
- * this makes sure it's done.
- * -- Cort
- */
-clear_bats:
- li r10,0
- mfspr r9,SPRN_PVR
- rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */
- cmpwi r9, 1
- beq 1f
-
- mtspr SPRN_DBAT0U,r10
- mtspr SPRN_DBAT0L,r10
- mtspr SPRN_DBAT1U,r10
- mtspr SPRN_DBAT1L,r10
- mtspr SPRN_DBAT2U,r10
- mtspr SPRN_DBAT2L,r10
- mtspr SPRN_DBAT3U,r10
- mtspr SPRN_DBAT3L,r10
-1:
- mtspr SPRN_IBAT0U,r10
- mtspr SPRN_IBAT0L,r10
- mtspr SPRN_IBAT1U,r10
- mtspr SPRN_IBAT1L,r10
- mtspr SPRN_IBAT2U,r10
- mtspr SPRN_IBAT2L,r10
- mtspr SPRN_IBAT3U,r10
- mtspr SPRN_IBAT3L,r10
-BEGIN_FTR_SECTION
- /* Here's a tweak: at this point, CPU setup have
- * not been called yet, so HIGH_BAT_EN may not be
- * set in HID0 for the 745x processors. However, it
- * seems that doesn't affect our ability to actually
- * write to these SPRs.
- */
- mtspr SPRN_DBAT4U,r10
- mtspr SPRN_DBAT4L,r10
- mtspr SPRN_DBAT5U,r10
- mtspr SPRN_DBAT5L,r10
- mtspr SPRN_DBAT6U,r10
- mtspr SPRN_DBAT6L,r10
- mtspr SPRN_DBAT7U,r10
- mtspr SPRN_DBAT7L,r10
- mtspr SPRN_IBAT4U,r10
- mtspr SPRN_IBAT4L,r10
- mtspr SPRN_IBAT5U,r10
- mtspr SPRN_IBAT5L,r10
- mtspr SPRN_IBAT6U,r10
- mtspr SPRN_IBAT6L,r10
- mtspr SPRN_IBAT7U,r10
- mtspr SPRN_IBAT7L,r10
-END_FTR_SECTION_IFSET(CPU_FTR_HAS_HIGH_BATS)
- blr
-
-flush_tlbs:
- lis r10, 0x40
-1: addic. r10, r10, -0x1000
- tlbie r10
- blt 1b
- sync
- blr
-
-mmu_off:
- addi r4, r3, __after_mmu_off - _start
- mfmsr r3
- andi. r0,r3,MSR_DR|MSR_IR /* MMU enabled? */
- beqlr
- andc r3,r3,r0
- mtspr SPRN_SRR0,r4
- mtspr SPRN_SRR1,r3
- sync
- RFI
-
-#ifndef CONFIG_POWER4
-/*
- * Use the first pair of BAT registers to map the 1st 16MB
- * of RAM to KERNELBASE. From this point on we can't safely
- * call OF any more.
- */
-initial_bats:
- lis r11,KERNELBASE@h
-#ifndef CONFIG_PPC64BRIDGE
- mfspr r9,SPRN_PVR
- rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */
- cmpwi 0,r9,1
- bne 4f
- ori r11,r11,4 /* set up BAT registers for 601 */
- li r8,0x7f /* valid, block length = 8MB */
- oris r9,r11,0x800000@h /* set up BAT reg for 2nd 8M */
- oris r10,r8,0x800000@h /* set up BAT reg for 2nd 8M */
- mtspr SPRN_IBAT0U,r11 /* N.B. 601 has valid bit in */
- mtspr SPRN_IBAT0L,r8 /* lower BAT register */
- mtspr SPRN_IBAT1U,r9
- mtspr SPRN_IBAT1L,r10
- isync
- blr
-#endif /* CONFIG_PPC64BRIDGE */
-
-4: tophys(r8,r11)
-#ifdef CONFIG_SMP
- ori r8,r8,0x12 /* R/W access, M=1 */
-#else
- ori r8,r8,2 /* R/W access */
-#endif /* CONFIG_SMP */
-#ifdef CONFIG_APUS
- ori r11,r11,BL_8M<<2|0x2 /* set up 8MB BAT registers for 604 */
-#else
- ori r11,r11,BL_256M<<2|0x2 /* set up BAT registers for 604 */
-#endif /* CONFIG_APUS */
-
-#ifdef CONFIG_PPC64BRIDGE
- /* clear out the high 32 bits in the BAT */
- clrldi r11,r11,32
- clrldi r8,r8,32
-#endif /* CONFIG_PPC64BRIDGE */
- mtspr SPRN_DBAT0L,r8 /* N.B. 6xx (not 601) have valid */
- mtspr SPRN_DBAT0U,r11 /* bit in upper BAT register */
- mtspr SPRN_IBAT0L,r8
- mtspr SPRN_IBAT0U,r11
- isync
- blr
-
-#if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT)
-setup_disp_bat:
- /*
- * setup the display bat prepared for us in prom.c
- */
- mflr r8
- bl reloc_offset
- mtlr r8
- addis r8,r3,disp_BAT@ha
- addi r8,r8,disp_BAT@l
- lwz r11,0(r8)
- lwz r8,4(r8)
- mfspr r9,SPRN_PVR
- rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */
- cmpwi 0,r9,1
- beq 1f
- mtspr SPRN_DBAT3L,r8
- mtspr SPRN_DBAT3U,r11
- blr
-1: mtspr SPRN_IBAT3L,r8
- mtspr SPRN_IBAT3U,r11
- blr
-
-#endif /* !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) */
-
-#else /* CONFIG_POWER4 */
-/*
- * Load up the SDR1 and segment register values now
- * since we don't have the BATs.
- * Also make sure we are running in 32-bit mode.
- */
-
-initial_mm_power4:
- addis r14,r3,_SDR1@ha /* get the value from _SDR1 */
- lwz r14,_SDR1@l(r14) /* assume hash table below 4GB */
- mtspr SPRN_SDR1,r14
- slbia
- lis r4,0x2000 /* set pseudo-segment reg 12 */
- ori r5,r4,0x0ccc
- mtsr 12,r5
-#if 0
- ori r5,r4,0x0888 /* set pseudo-segment reg 8 */
- mtsr 8,r5 /* (for access to serial port) */
-#endif
-#ifdef CONFIG_BOOTX_TEXT
- ori r5,r4,0x0999 /* set pseudo-segment reg 9 */
- mtsr 9,r5 /* (for access to screen) */
-#endif
- mfmsr r0
- clrldi r0,r0,1
- sync
- mtmsr r0
- isync
- blr
-
-#endif /* CONFIG_POWER4 */
-
-#ifdef CONFIG_8260
-/* Jump into the system reset for the rom.
- * We first disable the MMU, and then jump to the ROM reset address.
- *
- * r3 is the board info structure, r4 is the location for starting.
- * I use this for building a small kernel that can load other kernels,
- * rather than trying to write or rely on a rom monitor that can tftp load.
- */
- .globl m8260_gorom
-m8260_gorom:
- mfmsr r0
- rlwinm r0,r0,0,17,15 /* clear MSR_EE in r0 */
- sync
- mtmsr r0
- sync
- mfspr r11, SPRN_HID0
- lis r10, 0
- ori r10,r10,HID0_ICE|HID0_DCE
- andc r11, r11, r10
- mtspr SPRN_HID0, r11
- isync
- li r5, MSR_ME|MSR_RI
- lis r6,2f@h
- addis r6,r6,-KERNELBASE@h
- ori r6,r6,2f@l
- mtspr SPRN_SRR0,r6
- mtspr SPRN_SRR1,r5
- isync
- sync
- rfi
-2:
- mtlr r4
- blr
-#endif
-
-
-/*
- * We put a few things here that have to be page-aligned.
- * This stuff goes at the beginning of the data segment,
- * which is page-aligned.
- */
- .data
- .globl sdata
-sdata:
- .globl empty_zero_page
-empty_zero_page:
- .space 4096
-
- .globl swapper_pg_dir
-swapper_pg_dir:
- .space 4096
-
-/*
- * This space gets a copy of optional info passed to us by the bootstrap
- * Used to pass parameters into the kernel like root=/dev/sda1, etc.
- */
- .globl cmd_line
-cmd_line:
- .space 512
-
- .globl intercept_table
-intercept_table:
- .long 0, 0, i0x200, i0x300, i0x400, 0, i0x600, i0x700
- .long i0x800, 0, 0, 0, 0, i0xd00, 0, 0
- .long 0, 0, 0, i0x1300, 0, 0, 0, 0
- .long 0, 0, 0, 0, 0, 0, 0, 0
- .long 0, 0, 0, 0, 0, 0, 0, 0
- .long 0, 0, 0, 0, 0, 0, 0, 0
-
-/* Room for two PTE pointers, usually the kernel and current user pointers
- * to their respective root page table.
- */
-abatron_pteptrs:
- .space 8
diff --git a/trunk/arch/powerpc/kernel/head_44x.S b/trunk/arch/powerpc/kernel/head_44x.S
deleted file mode 100644
index 599245b0407e..000000000000
--- a/trunk/arch/powerpc/kernel/head_44x.S
+++ /dev/null
@@ -1,778 +0,0 @@
-/*
- * arch/ppc/kernel/head_44x.S
- *
- * Kernel execution entry point code.
- *
- * Copyright (c) 1995-1996 Gary Thomas
- * Initial PowerPC version.
- * Copyright (c) 1996 Cort Dougan
- * Rewritten for PReP
- * Copyright (c) 1996 Paul Mackerras
- * Low-level exception handers, MMU support, and rewrite.
- * Copyright (c) 1997 Dan Malek
- * PowerPC 8xx modifications.
- * Copyright (c) 1998-1999 TiVo, Inc.
- * PowerPC 403GCX modifications.
- * Copyright (c) 1999 Grant Erickson
- * PowerPC 403GCX/405GP modifications.
- * Copyright 2000 MontaVista Software Inc.
- * PPC405 modifications
- * PowerPC 403GCX/405GP modifications.
- * Author: MontaVista Software, Inc.
- * frank_rowand@mvista.com or source@mvista.com
- * debbie_chu@mvista.com
- * Copyright 2002-2005 MontaVista Software, Inc.
- * PowerPC 44x support, Matt Porter
- *
- * 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
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include "head_booke.h"
-
-
-/* As with the other PowerPC ports, it is expected that when code
- * execution begins here, the following registers contain valid, yet
- * optional, information:
- *
- * r3 - Board info structure pointer (DRAM, frequency, MAC address, etc.)
- * r4 - Starting address of the init RAM disk
- * r5 - Ending address of the init RAM disk
- * r6 - Start of kernel command line string (e.g. "mem=128")
- * r7 - End of kernel command line string
- *
- */
- .text
-_GLOBAL(_stext)
-_GLOBAL(_start)
- /*
- * Reserve a word at a fixed location to store the address
- * of abatron_pteptrs
- */
- nop
-/*
- * Save parameters we are passed
- */
- mr r31,r3
- mr r30,r4
- mr r29,r5
- mr r28,r6
- mr r27,r7
- li r24,0 /* CPU number */
-
-/*
- * Set up the initial MMU state
- *
- * We are still executing code at the virtual address
- * mappings set by the firmware for the base of RAM.
- *
- * We first invalidate all TLB entries but the one
- * we are running from. We then load the KERNELBASE
- * mappings so we can begin to use kernel addresses
- * natively and so the interrupt vector locations are
- * permanently pinned (necessary since Book E
- * implementations always have translation enabled).
- *
- * TODO: Use the known TLB entry we are running from to
- * determine which physical region we are located
- * in. This can be used to determine where in RAM
- * (on a shared CPU system) or PCI memory space
- * (on a DRAMless system) we are located.
- * For now, we assume a perfect world which means
- * we are located at the base of DRAM (physical 0).
- */
-
-/*
- * Search TLB for entry that we are currently using.
- * Invalidate all entries but the one we are using.
- */
- /* Load our current PID->MMUCR TID and MSR IS->MMUCR STS */
- mfspr r3,SPRN_PID /* Get PID */
- mfmsr r4 /* Get MSR */
- andi. r4,r4,MSR_IS@l /* TS=1? */
- beq wmmucr /* If not, leave STS=0 */
- oris r3,r3,PPC44x_MMUCR_STS@h /* Set STS=1 */
-wmmucr: mtspr SPRN_MMUCR,r3 /* Put MMUCR */
- sync
-
- bl invstr /* Find our address */
-invstr: mflr r5 /* Make it accessible */
- tlbsx r23,0,r5 /* Find entry we are in */
- li r4,0 /* Start at TLB entry 0 */
- li r3,0 /* Set PAGEID inval value */
-1: cmpw r23,r4 /* Is this our entry? */
- beq skpinv /* If so, skip the inval */
- tlbwe r3,r4,PPC44x_TLB_PAGEID /* If not, inval the entry */
-skpinv: addi r4,r4,1 /* Increment */
- cmpwi r4,64 /* Are we done? */
- bne 1b /* If not, repeat */
- isync /* If so, context change */
-
-/*
- * Configure and load pinned entry into TLB slot 63.
- */
-
- lis r3,KERNELBASE@h /* Load the kernel virtual address */
- ori r3,r3,KERNELBASE@l
-
- /* Kernel is at the base of RAM */
- li r4, 0 /* Load the kernel physical address */
-
- /* Load the kernel PID = 0 */
- li r0,0
- mtspr SPRN_PID,r0
- sync
-
- /* Initialize MMUCR */
- li r5,0
- mtspr SPRN_MMUCR,r5
- sync
-
- /* pageid fields */
- clrrwi r3,r3,10 /* Mask off the effective page number */
- ori r3,r3,PPC44x_TLB_VALID | PPC44x_TLB_256M
-
- /* xlat fields */
- clrrwi r4,r4,10 /* Mask off the real page number */
- /* ERPN is 0 for first 4GB page */
-
- /* attrib fields */
- /* Added guarded bit to protect against speculative loads/stores */
- li r5,0
- ori r5,r5,(PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G)
-
- li r0,63 /* TLB slot 63 */
-
- tlbwe r3,r0,PPC44x_TLB_PAGEID /* Load the pageid fields */
- tlbwe r4,r0,PPC44x_TLB_XLAT /* Load the translation fields */
- tlbwe r5,r0,PPC44x_TLB_ATTRIB /* Load the attrib/access fields */
-
- /* Force context change */
- mfmsr r0
- mtspr SPRN_SRR1, r0
- lis r0,3f@h
- ori r0,r0,3f@l
- mtspr SPRN_SRR0,r0
- sync
- rfi
-
- /* If necessary, invalidate original entry we used */
-3: cmpwi r23,63
- beq 4f
- li r6,0
- tlbwe r6,r23,PPC44x_TLB_PAGEID
- isync
-
-4:
-#ifdef CONFIG_SERIAL_TEXT_DEBUG
- /*
- * Add temporary UART mapping for early debug.
- * We can map UART registers wherever we want as long as they don't
- * interfere with other system mappings (e.g. with pinned entries).
- * For an example of how we handle this - see ocotea.h. --ebs
- */
- /* pageid fields */
- lis r3,UART0_IO_BASE@h
- ori r3,r3,PPC44x_TLB_VALID | PPC44x_TLB_4K
-
- /* xlat fields */
- lis r4,UART0_PHYS_IO_BASE@h /* RPN depends on SoC */
-#ifndef CONFIG_440EP
- ori r4,r4,0x0001 /* ERPN is 1 for second 4GB page */
-#endif
-
- /* attrib fields */
- li r5,0
- ori r5,r5,(PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_I | PPC44x_TLB_G)
-
- li r0,0 /* TLB slot 0 */
-
- tlbwe r3,r0,PPC44x_TLB_PAGEID /* Load the pageid fields */
- tlbwe r4,r0,PPC44x_TLB_XLAT /* Load the translation fields */
- tlbwe r5,r0,PPC44x_TLB_ATTRIB /* Load the attrib/access fields */
-
- /* Force context change */
- isync
-#endif /* CONFIG_SERIAL_TEXT_DEBUG */
-
- /* Establish the interrupt vector offsets */
- SET_IVOR(0, CriticalInput);
- SET_IVOR(1, MachineCheck);
- SET_IVOR(2, DataStorage);
- SET_IVOR(3, InstructionStorage);
- SET_IVOR(4, ExternalInput);
- SET_IVOR(5, Alignment);
- SET_IVOR(6, Program);
- SET_IVOR(7, FloatingPointUnavailable);
- SET_IVOR(8, SystemCall);
- SET_IVOR(9, AuxillaryProcessorUnavailable);
- SET_IVOR(10, Decrementer);
- SET_IVOR(11, FixedIntervalTimer);
- SET_IVOR(12, WatchdogTimer);
- SET_IVOR(13, DataTLBError);
- SET_IVOR(14, InstructionTLBError);
- SET_IVOR(15, Debug);
-
- /* Establish the interrupt vector base */
- lis r4,interrupt_base@h /* IVPR only uses the high 16-bits */
- mtspr SPRN_IVPR,r4
-
-#ifdef CONFIG_440EP
- /* Clear DAPUIB flag in CCR0 (enable APU between CPU and FPU) */
- mfspr r2,SPRN_CCR0
- lis r3,0xffef
- ori r3,r3,0xffff
- and r2,r2,r3
- mtspr SPRN_CCR0,r2
- isync
-#endif
-
- /*
- * This is where the main kernel code starts.
- */
-
- /* ptr to current */
- lis r2,init_task@h
- ori r2,r2,init_task@l
-
- /* ptr to current thread */
- addi r4,r2,THREAD /* init task's THREAD */
- mtspr SPRN_SPRG3,r4
-
- /* stack */
- lis r1,init_thread_union@h
- ori r1,r1,init_thread_union@l
- li r0,0
- stwu r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1)
-
- bl early_init
-
-/*
- * Decide what sort of machine this is and initialize the MMU.
- */
- mr r3,r31
- mr r4,r30
- mr r5,r29
- mr r6,r28
- mr r7,r27
- bl machine_init
- bl MMU_init
-
- /* Setup PTE pointers for the Abatron bdiGDB */
- lis r6, swapper_pg_dir@h
- ori r6, r6, swapper_pg_dir@l
- lis r5, abatron_pteptrs@h
- ori r5, r5, abatron_pteptrs@l
- lis r4, KERNELBASE@h
- ori r4, r4, KERNELBASE@l
- stw r5, 0(r4) /* Save abatron_pteptrs at a fixed location */
- stw r6, 0(r5)
-
- /* Let's move on */
- lis r4,start_kernel@h
- ori r4,r4,start_kernel@l
- lis r3,MSR_KERNEL@h
- ori r3,r3,MSR_KERNEL@l
- mtspr SPRN_SRR0,r4
- mtspr SPRN_SRR1,r3
- rfi /* change context and jump to start_kernel */
-
-/*
- * Interrupt vector entry code
- *
- * The Book E MMUs are always on so we don't need to handle
- * interrupts in real mode as with previous PPC processors. In
- * this case we handle interrupts in the kernel virtual address
- * space.
- *
- * Interrupt vectors are dynamically placed relative to the
- * interrupt prefix as determined by the address of interrupt_base.
- * The interrupt vectors offsets are programmed using the labels
- * for each interrupt vector entry.
- *
- * Interrupt vectors must be aligned on a 16 byte boundary.
- * We align on a 32 byte cache line boundary for good measure.
- */
-
-interrupt_base:
- /* Critical Input Interrupt */
- CRITICAL_EXCEPTION(0x0100, CriticalInput, UnknownException)
-
- /* Machine Check Interrupt */
-#ifdef CONFIG_440A
- MCHECK_EXCEPTION(0x0200, MachineCheck, MachineCheckException)
-#else
- CRITICAL_EXCEPTION(0x0200, MachineCheck, MachineCheckException)
-#endif
-
- /* Data Storage Interrupt */
- START_EXCEPTION(DataStorage)
- mtspr SPRN_SPRG0, r10 /* Save some working registers */
- mtspr SPRN_SPRG1, r11
- mtspr SPRN_SPRG4W, r12
- mtspr SPRN_SPRG5W, r13
- mfcr r11
- mtspr SPRN_SPRG7W, r11
-
- /*
- * Check if it was a store fault, if not then bail
- * because a user tried to access a kernel or
- * read-protected page. Otherwise, get the
- * offending address and handle it.
- */
- mfspr r10, SPRN_ESR
- andis. r10, r10, ESR_ST@h
- beq 2f
-
- mfspr r10, SPRN_DEAR /* Get faulting address */
-
- /* If we are faulting a kernel address, we have to use the
- * kernel page tables.
- */
- lis r11, TASK_SIZE@h
- cmplw r10, r11
- blt+ 3f
- lis r11, swapper_pg_dir@h
- ori r11, r11, swapper_pg_dir@l
-
- mfspr r12,SPRN_MMUCR
- rlwinm r12,r12,0,0,23 /* Clear TID */
-
- b 4f
-
- /* Get the PGD for the current thread */
-3:
- mfspr r11,SPRN_SPRG3
- lwz r11,PGDIR(r11)
-
- /* Load PID into MMUCR TID */
- mfspr r12,SPRN_MMUCR /* Get MMUCR */
- mfspr r13,SPRN_PID /* Get PID */
- rlwimi r12,r13,0,24,31 /* Set TID */
-
-4:
- mtspr SPRN_MMUCR,r12
-
- rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */
- lwzx r11, r12, r11 /* Get pgd/pmd entry */
- rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */
- beq 2f /* Bail if no table */
-
- rlwimi r12, r10, 23, 20, 28 /* Compute pte address */
- lwz r11, 4(r12) /* Get pte entry */
-
- andi. r13, r11, _PAGE_RW /* Is it writeable? */
- beq 2f /* Bail if not */
-
- /* Update 'changed'.
- */
- ori r11, r11, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE
- stw r11, 4(r12) /* Update Linux page table */
-
- li r13, PPC44x_TLB_SR@l /* Set SR */
- rlwimi r13, r11, 29, 29, 29 /* SX = _PAGE_HWEXEC */
- rlwimi r13, r11, 0, 30, 30 /* SW = _PAGE_RW */
- rlwimi r13, r11, 29, 28, 28 /* UR = _PAGE_USER */
- rlwimi r12, r11, 31, 26, 26 /* (_PAGE_USER>>1)->r12 */
- rlwimi r12, r11, 29, 30, 30 /* (_PAGE_USER>>3)->r12 */
- and r12, r12, r11 /* HWEXEC/RW & USER */
- rlwimi r13, r12, 0, 26, 26 /* UX = HWEXEC & USER */
- rlwimi r13, r12, 3, 27, 27 /* UW = RW & USER */
-
- rlwimi r11,r13,0,26,31 /* Insert static perms */
-
- rlwinm r11,r11,0,20,15 /* Clear U0-U3 */
-
- /* find the TLB index that caused the fault. It has to be here. */
- tlbsx r10, 0, r10
-
- tlbwe r11, r10, PPC44x_TLB_ATTRIB /* Write ATTRIB */
-
- /* Done...restore registers and get out of here.
- */
- mfspr r11, SPRN_SPRG7R
- mtcr r11
- mfspr r13, SPRN_SPRG5R
- mfspr r12, SPRN_SPRG4R
-
- mfspr r11, SPRN_SPRG1
- mfspr r10, SPRN_SPRG0
- rfi /* Force context change */
-
-2:
- /*
- * The bailout. Restore registers to pre-exception conditions
- * and call the heavyweights to help us out.
- */
- mfspr r11, SPRN_SPRG7R
- mtcr r11
- mfspr r13, SPRN_SPRG5R
- mfspr r12, SPRN_SPRG4R
-
- mfspr r11, SPRN_SPRG1
- mfspr r10, SPRN_SPRG0
- b data_access
-
- /* Instruction Storage Interrupt */
- INSTRUCTION_STORAGE_EXCEPTION
-
- /* External Input Interrupt */
- EXCEPTION(0x0500, ExternalInput, do_IRQ, EXC_XFER_LITE)
-
- /* Alignment Interrupt */
- ALIGNMENT_EXCEPTION
-
- /* Program Interrupt */
- PROGRAM_EXCEPTION
-
- /* Floating Point Unavailable Interrupt */
-#ifdef CONFIG_PPC_FPU
- FP_UNAVAILABLE_EXCEPTION
-#else
- EXCEPTION(0x2010, FloatingPointUnavailable, UnknownException, EXC_XFER_EE)
-#endif
-
- /* System Call Interrupt */
- START_EXCEPTION(SystemCall)
- NORMAL_EXCEPTION_PROLOG
- EXC_XFER_EE_LITE(0x0c00, DoSyscall)
-
- /* Auxillary Processor Unavailable Interrupt */
- EXCEPTION(0x2020, AuxillaryProcessorUnavailable, UnknownException, EXC_XFER_EE)
-
- /* Decrementer Interrupt */
- DECREMENTER_EXCEPTION
-
- /* Fixed Internal Timer Interrupt */
- /* TODO: Add FIT support */
- EXCEPTION(0x1010, FixedIntervalTimer, UnknownException, EXC_XFER_EE)
-
- /* Watchdog Timer Interrupt */
- /* TODO: Add watchdog support */
-#ifdef CONFIG_BOOKE_WDT
- CRITICAL_EXCEPTION(0x1020, WatchdogTimer, WatchdogException)
-#else
- CRITICAL_EXCEPTION(0x1020, WatchdogTimer, UnknownException)
-#endif
-
- /* Data TLB Error Interrupt */
- START_EXCEPTION(DataTLBError)
- mtspr SPRN_SPRG0, r10 /* Save some working registers */
- mtspr SPRN_SPRG1, r11
- mtspr SPRN_SPRG4W, r12
- mtspr SPRN_SPRG5W, r13
- mfcr r11
- mtspr SPRN_SPRG7W, r11
- mfspr r10, SPRN_DEAR /* Get faulting address */
-
- /* If we are faulting a kernel address, we have to use the
- * kernel page tables.
- */
- lis r11, TASK_SIZE@h
- cmplw r10, r11
- blt+ 3f
- lis r11, swapper_pg_dir@h
- ori r11, r11, swapper_pg_dir@l
-
- mfspr r12,SPRN_MMUCR
- rlwinm r12,r12,0,0,23 /* Clear TID */
-
- b 4f
-
- /* Get the PGD for the current thread */
-3:
- mfspr r11,SPRN_SPRG3
- lwz r11,PGDIR(r11)
-
- /* Load PID into MMUCR TID */
- mfspr r12,SPRN_MMUCR
- mfspr r13,SPRN_PID /* Get PID */
- rlwimi r12,r13,0,24,31 /* Set TID */
-
-4:
- mtspr SPRN_MMUCR,r12
-
- rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */
- lwzx r11, r12, r11 /* Get pgd/pmd entry */
- rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */
- beq 2f /* Bail if no table */
-
- rlwimi r12, r10, 23, 20, 28 /* Compute pte address */
- lwz r11, 4(r12) /* Get pte entry */
- andi. r13, r11, _PAGE_PRESENT /* Is the page present? */
- beq 2f /* Bail if not present */
-
- ori r11, r11, _PAGE_ACCESSED
- stw r11, 4(r12)
-
- /* Jump to common tlb load */
- b finish_tlb_load
-
-2:
- /* The bailout. Restore registers to pre-exception conditions
- * and call the heavyweights to help us out.
- */
- mfspr r11, SPRN_SPRG7R
- mtcr r11
- mfspr r13, SPRN_SPRG5R
- mfspr r12, SPRN_SPRG4R
- mfspr r11, SPRN_SPRG1
- mfspr r10, SPRN_SPRG0
- b data_access
-
- /* Instruction TLB Error Interrupt */
- /*
- * Nearly the same as above, except we get our
- * information from different registers and bailout
- * to a different point.
- */
- START_EXCEPTION(InstructionTLBError)
- mtspr SPRN_SPRG0, r10 /* Save some working registers */
- mtspr SPRN_SPRG1, r11
- mtspr SPRN_SPRG4W, r12
- mtspr SPRN_SPRG5W, r13
- mfcr r11
- mtspr SPRN_SPRG7W, r11
- mfspr r10, SPRN_SRR0 /* Get faulting address */
-
- /* If we are faulting a kernel address, we have to use the
- * kernel page tables.
- */
- lis r11, TASK_SIZE@h
- cmplw r10, r11
- blt+ 3f
- lis r11, swapper_pg_dir@h
- ori r11, r11, swapper_pg_dir@l
-
- mfspr r12,SPRN_MMUCR
- rlwinm r12,r12,0,0,23 /* Clear TID */
-
- b 4f
-
- /* Get the PGD for the current thread */
-3:
- mfspr r11,SPRN_SPRG3
- lwz r11,PGDIR(r11)
-
- /* Load PID into MMUCR TID */
- mfspr r12,SPRN_MMUCR
- mfspr r13,SPRN_PID /* Get PID */
- rlwimi r12,r13,0,24,31 /* Set TID */
-
-4:
- mtspr SPRN_MMUCR,r12
-
- rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */
- lwzx r11, r12, r11 /* Get pgd/pmd entry */
- rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */
- beq 2f /* Bail if no table */
-
- rlwimi r12, r10, 23, 20, 28 /* Compute pte address */
- lwz r11, 4(r12) /* Get pte entry */
- andi. r13, r11, _PAGE_PRESENT /* Is the page present? */
- beq 2f /* Bail if not present */
-
- ori r11, r11, _PAGE_ACCESSED
- stw r11, 4(r12)
-
- /* Jump to common TLB load point */
- b finish_tlb_load
-
-2:
- /* The bailout. Restore registers to pre-exception conditions
- * and call the heavyweights to help us out.
- */
- mfspr r11, SPRN_SPRG7R
- mtcr r11
- mfspr r13, SPRN_SPRG5R
- mfspr r12, SPRN_SPRG4R
- mfspr r11, SPRN_SPRG1
- mfspr r10, SPRN_SPRG0
- b InstructionStorage
-
- /* Debug Interrupt */
- DEBUG_EXCEPTION
-
-/*
- * Local functions
- */
- /*
- * Data TLB exceptions will bail out to this point
- * if they can't resolve the lightweight TLB fault.
- */
-data_access:
- NORMAL_EXCEPTION_PROLOG
- mfspr r5,SPRN_ESR /* Grab the ESR, save it, pass arg3 */
- stw r5,_ESR(r11)
- mfspr r4,SPRN_DEAR /* Grab the DEAR, save it, pass arg2 */
- EXC_XFER_EE_LITE(0x0300, handle_page_fault)
-
-/*
-
- * Both the instruction and data TLB miss get to this
- * point to load the TLB.
- * r10 - EA of fault
- * r11 - available to use
- * r12 - Pointer to the 64-bit PTE
- * r13 - available to use
- * MMUCR - loaded with proper value when we get here
- * Upon exit, we reload everything and RFI.
- */
-finish_tlb_load:
- /*
- * We set execute, because we don't have the granularity to
- * properly set this at the page level (Linux problem).
- * If shared is set, we cause a zero PID->TID load.
- * Many of these bits are software only. Bits we don't set
- * here we (properly should) assume have the appropriate value.
- */
-
- /* Load the next available TLB index */
- lis r13, tlb_44x_index@ha
- lwz r13, tlb_44x_index@l(r13)
- /* Load the TLB high watermark */
- lis r11, tlb_44x_hwater@ha
- lwz r11, tlb_44x_hwater@l(r11)
-
- /* Increment, rollover, and store TLB index */
- addi r13, r13, 1
- cmpw 0, r13, r11 /* reserve entries */
- ble 7f
- li r13, 0
-7:
- /* Store the next available TLB index */
- lis r11, tlb_44x_index@ha
- stw r13, tlb_44x_index@l(r11)
-
- lwz r11, 0(r12) /* Get MS word of PTE */
- lwz r12, 4(r12) /* Get LS word of PTE */
- rlwimi r11, r12, 0, 0 , 19 /* Insert RPN */
- tlbwe r11, r13, PPC44x_TLB_XLAT /* Write XLAT */
-
- /*
- * Create PAGEID. This is the faulting address,
- * page size, and valid flag.
- */
- li r11, PPC44x_TLB_VALID | PPC44x_TLB_4K
- rlwimi r10, r11, 0, 20, 31 /* Insert valid and page size */
- tlbwe r10, r13, PPC44x_TLB_PAGEID /* Write PAGEID */
-
- li r10, PPC44x_TLB_SR@l /* Set SR */
- rlwimi r10, r12, 0, 30, 30 /* Set SW = _PAGE_RW */
- rlwimi r10, r12, 29, 29, 29 /* SX = _PAGE_HWEXEC */
- rlwimi r10, r12, 29, 28, 28 /* UR = _PAGE_USER */
- rlwimi r11, r12, 31, 26, 26 /* (_PAGE_USER>>1)->r12 */
- and r11, r12, r11 /* HWEXEC & USER */
- rlwimi r10, r11, 0, 26, 26 /* UX = HWEXEC & USER */
-
- rlwimi r12, r10, 0, 26, 31 /* Insert static perms */
- rlwinm r12, r12, 0, 20, 15 /* Clear U0-U3 */
- tlbwe r12, r13, PPC44x_TLB_ATTRIB /* Write ATTRIB */
-
- /* Done...restore registers and get out of here.
- */
- mfspr r11, SPRN_SPRG7R
- mtcr r11
- mfspr r13, SPRN_SPRG5R
- mfspr r12, SPRN_SPRG4R
- mfspr r11, SPRN_SPRG1
- mfspr r10, SPRN_SPRG0
- rfi /* Force context change */
-
-/*
- * Global functions
- */
-
-/*
- * extern void giveup_altivec(struct task_struct *prev)
- *
- * The 44x core does not have an AltiVec unit.
- */
-_GLOBAL(giveup_altivec)
- blr
-
-/*
- * extern void giveup_fpu(struct task_struct *prev)
- *
- * The 44x core does not have an FPU.
- */
-#ifndef CONFIG_PPC_FPU
-_GLOBAL(giveup_fpu)
- blr
-#endif
-
-/*
- * extern void abort(void)
- *
- * At present, this routine just applies a system reset.
- */
-_GLOBAL(abort)
- mfspr r13,SPRN_DBCR0
- oris r13,r13,DBCR0_RST_SYSTEM@h
- mtspr SPRN_DBCR0,r13
-
-_GLOBAL(set_context)
-
-#ifdef CONFIG_BDI_SWITCH
- /* Context switch the PTE pointer for the Abatron BDI2000.
- * The PGDIR is the second parameter.
- */
- lis r5, abatron_pteptrs@h
- ori r5, r5, abatron_pteptrs@l
- stw r4, 0x4(r5)
-#endif
- mtspr SPRN_PID,r3
- isync /* Force context change */
- blr
-
-/*
- * We put a few things here that have to be page-aligned. This stuff
- * goes at the beginning of the data segment, which is page-aligned.
- */
- .data
-_GLOBAL(sdata)
-_GLOBAL(empty_zero_page)
- .space 4096
-
-/*
- * To support >32-bit physical addresses, we use an 8KB pgdir.
- */
-_GLOBAL(swapper_pg_dir)
- .space 8192
-
-/* Reserved 4k for the critical exception stack & 4k for the machine
- * check stack per CPU for kernel mode exceptions */
- .section .bss
- .align 12
-exception_stack_bottom:
- .space BOOKE_EXCEPTION_STACK_SIZE
-_GLOBAL(exception_stack_top)
-
-/*
- * This space gets a copy of optional info passed to us by the bootstrap
- * which is used to pass parameters into the kernel like root=/dev/sda1, etc.
- */
-_GLOBAL(cmd_line)
- .space 512
-
-/*
- * Room for two PTE pointers, usually the kernel and current user pointers
- * to their respective root page table.
- */
-abatron_pteptrs:
- .space 8
-
-
diff --git a/trunk/arch/powerpc/kernel/head_4xx.S b/trunk/arch/powerpc/kernel/head_4xx.S
deleted file mode 100644
index 8562b807b37c..000000000000
--- a/trunk/arch/powerpc/kernel/head_4xx.S
+++ /dev/null
@@ -1,1016 +0,0 @@
-/*
- * Copyright (c) 1995-1996 Gary Thomas
- * Initial PowerPC version.
- * Copyright (c) 1996 Cort Dougan
- * Rewritten for PReP
- * Copyright (c) 1996 Paul Mackerras
- * Low-level exception handers, MMU support, and rewrite.
- * Copyright (c) 1997 Dan Malek
- * PowerPC 8xx modifications.
- * Copyright (c) 1998-1999 TiVo, Inc.
- * PowerPC 403GCX modifications.
- * Copyright (c) 1999 Grant Erickson
- * PowerPC 403GCX/405GP modifications.
- * Copyright 2000 MontaVista Software Inc.
- * PPC405 modifications
- * PowerPC 403GCX/405GP modifications.
- * Author: MontaVista Software, Inc.
- * frank_rowand@mvista.com or source@mvista.com
- * debbie_chu@mvista.com
- *
- *
- * Module name: head_4xx.S
- *
- * Description:
- * Kernel execution entry point code.
- *
- * 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
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-/* As with the other PowerPC ports, it is expected that when code
- * execution begins here, the following registers contain valid, yet
- * optional, information:
- *
- * r3 - Board info structure pointer (DRAM, frequency, MAC address, etc.)
- * r4 - Starting address of the init RAM disk
- * r5 - Ending address of the init RAM disk
- * r6 - Start of kernel command line string (e.g. "mem=96m")
- * r7 - End of kernel command line string
- *
- * This is all going to change RSN when we add bi_recs....... -- Dan
- */
- .text
-_GLOBAL(_stext)
-_GLOBAL(_start)
-
- /* Save parameters we are passed.
- */
- mr r31,r3
- mr r30,r4
- mr r29,r5
- mr r28,r6
- mr r27,r7
-
- /* We have to turn on the MMU right away so we get cache modes
- * set correctly.
- */
- bl initial_mmu
-
-/* We now have the lower 16 Meg mapped into TLB entries, and the caches
- * ready to work.
- */
-turn_on_mmu:
- lis r0,MSR_KERNEL@h
- ori r0,r0,MSR_KERNEL@l
- mtspr SPRN_SRR1,r0
- lis r0,start_here@h
- ori r0,r0,start_here@l
- mtspr SPRN_SRR0,r0
- SYNC
- rfi /* enables MMU */
- b . /* prevent prefetch past rfi */
-
-/*
- * This area is used for temporarily saving registers during the
- * critical exception prolog.
- */
- . = 0xc0
-crit_save:
-_GLOBAL(crit_r10)
- .space 4
-_GLOBAL(crit_r11)
- .space 4
-
-/*
- * Exception vector entry code. This code runs with address translation
- * turned off (i.e. using physical addresses). We assume SPRG3 has the
- * physical address of the current task thread_struct.
- * Note that we have to have decremented r1 before we write to any fields
- * of the exception frame, since a critical interrupt could occur at any
- * time, and it will write to the area immediately below the current r1.
- */
-#define NORMAL_EXCEPTION_PROLOG \
- mtspr SPRN_SPRG0,r10; /* save two registers to work with */\
- mtspr SPRN_SPRG1,r11; \
- mtspr SPRN_SPRG2,r1; \
- mfcr r10; /* save CR in r10 for now */\
- mfspr r11,SPRN_SRR1; /* check whether user or kernel */\
- andi. r11,r11,MSR_PR; \
- beq 1f; \
- mfspr r1,SPRN_SPRG3; /* if from user, start at top of */\
- lwz r1,THREAD_INFO-THREAD(r1); /* this thread's kernel stack */\
- addi r1,r1,THREAD_SIZE; \
-1: subi r1,r1,INT_FRAME_SIZE; /* Allocate an exception frame */\
- tophys(r11,r1); \
- stw r10,_CCR(r11); /* save various registers */\
- stw r12,GPR12(r11); \
- stw r9,GPR9(r11); \
- mfspr r10,SPRN_SPRG0; \
- stw r10,GPR10(r11); \
- mfspr r12,SPRN_SPRG1; \
- stw r12,GPR11(r11); \
- mflr r10; \
- stw r10,_LINK(r11); \
- mfspr r10,SPRN_SPRG2; \
- mfspr r12,SPRN_SRR0; \
- stw r10,GPR1(r11); \
- mfspr r9,SPRN_SRR1; \
- stw r10,0(r11); \
- rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\
- stw r0,GPR0(r11); \
- SAVE_4GPRS(3, r11); \
- SAVE_2GPRS(7, r11)
-
-/*
- * Exception prolog for critical exceptions. This is a little different
- * from the normal exception prolog above since a critical exception
- * can potentially occur at any point during normal exception processing.
- * Thus we cannot use the same SPRG registers as the normal prolog above.
- * Instead we use a couple of words of memory at low physical addresses.
- * This is OK since we don't support SMP on these processors.
- */
-#define CRITICAL_EXCEPTION_PROLOG \
- stw r10,crit_r10@l(0); /* save two registers to work with */\
- stw r11,crit_r11@l(0); \
- mfcr r10; /* save CR in r10 for now */\
- mfspr r11,SPRN_SRR3; /* check whether user or kernel */\
- andi. r11,r11,MSR_PR; \
- lis r11,critical_stack_top@h; \
- ori r11,r11,critical_stack_top@l; \
- beq 1f; \
- /* COMING FROM USER MODE */ \
- mfspr r11,SPRN_SPRG3; /* if from user, start at top of */\
- lwz r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\
- addi r11,r11,THREAD_SIZE; \
-1: subi r11,r11,INT_FRAME_SIZE; /* Allocate an exception frame */\
- tophys(r11,r11); \
- stw r10,_CCR(r11); /* save various registers */\
- stw r12,GPR12(r11); \
- stw r9,GPR9(r11); \
- mflr r10; \
- stw r10,_LINK(r11); \
- mfspr r12,SPRN_DEAR; /* save DEAR and ESR in the frame */\
- stw r12,_DEAR(r11); /* since they may have had stuff */\
- mfspr r9,SPRN_ESR; /* in them at the point where the */\
- stw r9,_ESR(r11); /* exception was taken */\
- mfspr r12,SPRN_SRR2; \
- stw r1,GPR1(r11); \
- mfspr r9,SPRN_SRR3; \
- stw r1,0(r11); \
- tovirt(r1,r11); \
- rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\
- stw r0,GPR0(r11); \
- SAVE_4GPRS(3, r11); \
- SAVE_2GPRS(7, r11)
-
- /*
- * State at this point:
- * r9 saved in stack frame, now saved SRR3 & ~MSR_WE
- * r10 saved in crit_r10 and in stack frame, trashed
- * r11 saved in crit_r11 and in stack frame,
- * now phys stack/exception frame pointer
- * r12 saved in stack frame, now saved SRR2
- * CR saved in stack frame, CR0.EQ = !SRR3.PR
- * LR, DEAR, ESR in stack frame
- * r1 saved in stack frame, now virt stack/excframe pointer
- * r0, r3-r8 saved in stack frame
- */
-
-/*
- * Exception vectors.
- */
-#define START_EXCEPTION(n, label) \
- . = n; \
-label:
-
-#define EXCEPTION(n, label, hdlr, xfer) \
- START_EXCEPTION(n, label); \
- NORMAL_EXCEPTION_PROLOG; \
- addi r3,r1,STACK_FRAME_OVERHEAD; \
- xfer(n, hdlr)
-
-#define CRITICAL_EXCEPTION(n, label, hdlr) \
- START_EXCEPTION(n, label); \
- CRITICAL_EXCEPTION_PROLOG; \
- addi r3,r1,STACK_FRAME_OVERHEAD; \
- EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
- NOCOPY, crit_transfer_to_handler, \
- ret_from_crit_exc)
-
-#define EXC_XFER_TEMPLATE(hdlr, trap, msr, copyee, tfer, ret) \
- li r10,trap; \
- stw r10,TRAP(r11); \
- lis r10,msr@h; \
- ori r10,r10,msr@l; \
- copyee(r10, r9); \
- bl tfer; \
- .long hdlr; \
- .long ret
-
-#define COPY_EE(d, s) rlwimi d,s,0,16,16
-#define NOCOPY(d, s)
-
-#define EXC_XFER_STD(n, hdlr) \
- EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, NOCOPY, transfer_to_handler_full, \
- ret_from_except_full)
-
-#define EXC_XFER_LITE(n, hdlr) \
- EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, NOCOPY, transfer_to_handler, \
- ret_from_except)
-
-#define EXC_XFER_EE(n, hdlr) \
- EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, COPY_EE, transfer_to_handler_full, \
- ret_from_except_full)
-
-#define EXC_XFER_EE_LITE(n, hdlr) \
- EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, COPY_EE, transfer_to_handler, \
- ret_from_except)
-
-
-/*
- * 0x0100 - Critical Interrupt Exception
- */
- CRITICAL_EXCEPTION(0x0100, CriticalInterrupt, UnknownException)
-
-/*
- * 0x0200 - Machine Check Exception
- */
- CRITICAL_EXCEPTION(0x0200, MachineCheck, MachineCheckException)
-
-/*
- * 0x0300 - Data Storage Exception
- * This happens for just a few reasons. U0 set (but we don't do that),
- * or zone protection fault (user violation, write to protected page).
- * If this is just an update of modified status, we do that quickly
- * and exit. Otherwise, we call heavywight functions to do the work.
- */
- START_EXCEPTION(0x0300, DataStorage)
- mtspr SPRN_SPRG0, r10 /* Save some working registers */
- mtspr SPRN_SPRG1, r11
-#ifdef CONFIG_403GCX
- stw r12, 0(r0)
- stw r9, 4(r0)
- mfcr r11
- mfspr r12, SPRN_PID
- stw r11, 8(r0)
- stw r12, 12(r0)
-#else
- mtspr SPRN_SPRG4, r12
- mtspr SPRN_SPRG5, r9
- mfcr r11
- mfspr r12, SPRN_PID
- mtspr SPRN_SPRG7, r11
- mtspr SPRN_SPRG6, r12
-#endif
-
- /* First, check if it was a zone fault (which means a user
- * tried to access a kernel or read-protected page - always
- * a SEGV). All other faults here must be stores, so no
- * need to check ESR_DST as well. */
- mfspr r10, SPRN_ESR
- andis. r10, r10, ESR_DIZ@h
- bne 2f
-
- mfspr r10, SPRN_DEAR /* Get faulting address */
-
- /* If we are faulting a kernel address, we have to use the
- * kernel page tables.
- */
- lis r11, TASK_SIZE@h
- cmplw r10, r11
- blt+ 3f
- lis r11, swapper_pg_dir@h
- ori r11, r11, swapper_pg_dir@l
- li r9, 0
- mtspr SPRN_PID, r9 /* TLB will have 0 TID */
- b 4f
-
- /* Get the PGD for the current thread.
- */
-3:
- mfspr r11,SPRN_SPRG3
- lwz r11,PGDIR(r11)
-4:
- tophys(r11, r11)
- rlwimi r11, r10, 12, 20, 29 /* Create L1 (pgdir/pmd) address */
- lwz r11, 0(r11) /* Get L1 entry */
- rlwinm. r12, r11, 0, 0, 19 /* Extract L2 (pte) base address */
- beq 2f /* Bail if no table */
-
- rlwimi r12, r10, 22, 20, 29 /* Compute PTE address */
- lwz r11, 0(r12) /* Get Linux PTE */
-
- andi. r9, r11, _PAGE_RW /* Is it writeable? */
- beq 2f /* Bail if not */
-
- /* Update 'changed'.
- */
- ori r11, r11, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE
- stw r11, 0(r12) /* Update Linux page table */
-
- /* Most of the Linux PTE is ready to load into the TLB LO.
- * We set ZSEL, where only the LS-bit determines user access.
- * We set execute, because we don't have the granularity to
- * properly set this at the page level (Linux problem).
- * If shared is set, we cause a zero PID->TID load.
- * Many of these bits are software only. Bits we don't set
- * here we (properly should) assume have the appropriate value.
- */
- li r12, 0x0ce2
- andc r11, r11, r12 /* Make sure 20, 21 are zero */
-
- /* find the TLB index that caused the fault. It has to be here.
- */
- tlbsx r9, 0, r10
-
- tlbwe r11, r9, TLB_DATA /* Load TLB LO */
-
- /* Done...restore registers and get out of here.
- */
-#ifdef CONFIG_403GCX
- lwz r12, 12(r0)
- lwz r11, 8(r0)
- mtspr SPRN_PID, r12
- mtcr r11
- lwz r9, 4(r0)
- lwz r12, 0(r0)
-#else
- mfspr r12, SPRN_SPRG6
- mfspr r11, SPRN_SPRG7
- mtspr SPRN_PID, r12
- mtcr r11
- mfspr r9, SPRN_SPRG5
- mfspr r12, SPRN_SPRG4
-#endif
- mfspr r11, SPRN_SPRG1
- mfspr r10, SPRN_SPRG0
- PPC405_ERR77_SYNC
- rfi /* Should sync shadow TLBs */
- b . /* prevent prefetch past rfi */
-
-2:
- /* The bailout. Restore registers to pre-exception conditions
- * and call the heavyweights to help us out.
- */
-#ifdef CONFIG_403GCX
- lwz r12, 12(r0)
- lwz r11, 8(r0)
- mtspr SPRN_PID, r12
- mtcr r11
- lwz r9, 4(r0)
- lwz r12, 0(r0)
-#else
- mfspr r12, SPRN_SPRG6
- mfspr r11, SPRN_SPRG7
- mtspr SPRN_PID, r12
- mtcr r11
- mfspr r9, SPRN_SPRG5
- mfspr r12, SPRN_SPRG4
-#endif
- mfspr r11, SPRN_SPRG1
- mfspr r10, SPRN_SPRG0
- b DataAccess
-
-/*
- * 0x0400 - Instruction Storage Exception
- * This is caused by a fetch from non-execute or guarded pages.
- */
- START_EXCEPTION(0x0400, InstructionAccess)
- NORMAL_EXCEPTION_PROLOG
- mr r4,r12 /* Pass SRR0 as arg2 */
- li r5,0 /* Pass zero as arg3 */
- EXC_XFER_EE_LITE(0x400, handle_page_fault)
-
-/* 0x0500 - External Interrupt Exception */
- EXCEPTION(0x0500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE)
-
-/* 0x0600 - Alignment Exception */
- START_EXCEPTION(0x0600, Alignment)
- NORMAL_EXCEPTION_PROLOG
- mfspr r4,SPRN_DEAR /* Grab the DEAR and save it */
- stw r4,_DEAR(r11)
- addi r3,r1,STACK_FRAME_OVERHEAD
- EXC_XFER_EE(0x600, AlignmentException)
-
-/* 0x0700 - Program Exception */
- START_EXCEPTION(0x0700, ProgramCheck)
- NORMAL_EXCEPTION_PROLOG
- mfspr r4,SPRN_ESR /* Grab the ESR and save it */
- stw r4,_ESR(r11)
- addi r3,r1,STACK_FRAME_OVERHEAD
- EXC_XFER_STD(0x700, ProgramCheckException)
-
- EXCEPTION(0x0800, Trap_08, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x0900, Trap_09, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x0A00, Trap_0A, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x0B00, Trap_0B, UnknownException, EXC_XFER_EE)
-
-/* 0x0C00 - System Call Exception */
- START_EXCEPTION(0x0C00, SystemCall)
- NORMAL_EXCEPTION_PROLOG
- EXC_XFER_EE_LITE(0xc00, DoSyscall)
-
- EXCEPTION(0x0D00, Trap_0D, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x0E00, Trap_0E, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x0F00, Trap_0F, UnknownException, EXC_XFER_EE)
-
-/* 0x1000 - Programmable Interval Timer (PIT) Exception */
- START_EXCEPTION(0x1000, Decrementer)
- NORMAL_EXCEPTION_PROLOG
- lis r0,TSR_PIS@h
- mtspr SPRN_TSR,r0 /* Clear the PIT exception */
- addi r3,r1,STACK_FRAME_OVERHEAD
- EXC_XFER_LITE(0x1000, timer_interrupt)
-
-#if 0
-/* NOTE:
- * FIT and WDT handlers are not implemented yet.
- */
-
-/* 0x1010 - Fixed Interval Timer (FIT) Exception
-*/
- STND_EXCEPTION(0x1010, FITException, UnknownException)
-
-/* 0x1020 - Watchdog Timer (WDT) Exception
-*/
-#ifdef CONFIG_BOOKE_WDT
- CRITICAL_EXCEPTION(0x1020, WDTException, WatchdogException)
-#else
- CRITICAL_EXCEPTION(0x1020, WDTException, UnknownException)
-#endif
-#endif
-
-/* 0x1100 - Data TLB Miss Exception
- * As the name implies, translation is not in the MMU, so search the
- * page tables and fix it. The only purpose of this function is to
- * load TLB entries from the page table if they exist.
- */
- START_EXCEPTION(0x1100, DTLBMiss)
- mtspr SPRN_SPRG0, r10 /* Save some working registers */
- mtspr SPRN_SPRG1, r11
-#ifdef CONFIG_403GCX
- stw r12, 0(r0)
- stw r9, 4(r0)
- mfcr r11
- mfspr r12, SPRN_PID
- stw r11, 8(r0)
- stw r12, 12(r0)
-#else
- mtspr SPRN_SPRG4, r12
- mtspr SPRN_SPRG5, r9
- mfcr r11
- mfspr r12, SPRN_PID
- mtspr SPRN_SPRG7, r11
- mtspr SPRN_SPRG6, r12
-#endif
- mfspr r10, SPRN_DEAR /* Get faulting address */
-
- /* If we are faulting a kernel address, we have to use the
- * kernel page tables.
- */
- lis r11, TASK_SIZE@h
- cmplw r10, r11
- blt+ 3f
- lis r11, swapper_pg_dir@h
- ori r11, r11, swapper_pg_dir@l
- li r9, 0
- mtspr SPRN_PID, r9 /* TLB will have 0 TID */
- b 4f
-
- /* Get the PGD for the current thread.
- */
-3:
- mfspr r11,SPRN_SPRG3
- lwz r11,PGDIR(r11)
-4:
- tophys(r11, r11)
- rlwimi r11, r10, 12, 20, 29 /* Create L1 (pgdir/pmd) address */
- lwz r12, 0(r11) /* Get L1 entry */
- andi. r9, r12, _PMD_PRESENT /* Check if it points to a PTE page */
- beq 2f /* Bail if no table */
-
- rlwimi r12, r10, 22, 20, 29 /* Compute PTE address */
- lwz r11, 0(r12) /* Get Linux PTE */
- andi. r9, r11, _PAGE_PRESENT
- beq 5f
-
- ori r11, r11, _PAGE_ACCESSED
- stw r11, 0(r12)
-
- /* Create TLB tag. This is the faulting address plus a static
- * set of bits. These are size, valid, E, U0.
- */
- li r12, 0x00c0
- rlwimi r10, r12, 0, 20, 31
-
- b finish_tlb_load
-
-2: /* Check for possible large-page pmd entry */
- rlwinm. r9, r12, 2, 22, 24
- beq 5f
-
- /* Create TLB tag. This is the faulting address, plus a static
- * set of bits (valid, E, U0) plus the size from the PMD.
- */
- ori r9, r9, 0x40
- rlwimi r10, r9, 0, 20, 31
- mr r11, r12
-
- b finish_tlb_load
-
-5:
- /* The bailout. Restore registers to pre-exception conditions
- * and call the heavyweights to help us out.
- */
-#ifdef CONFIG_403GCX
- lwz r12, 12(r0)
- lwz r11, 8(r0)
- mtspr SPRN_PID, r12
- mtcr r11
- lwz r9, 4(r0)
- lwz r12, 0(r0)
-#else
- mfspr r12, SPRN_SPRG6
- mfspr r11, SPRN_SPRG7
- mtspr SPRN_PID, r12
- mtcr r11
- mfspr r9, SPRN_SPRG5
- mfspr r12, SPRN_SPRG4
-#endif
- mfspr r11, SPRN_SPRG1
- mfspr r10, SPRN_SPRG0
- b DataAccess
-
-/* 0x1200 - Instruction TLB Miss Exception
- * Nearly the same as above, except we get our information from different
- * registers and bailout to a different point.
- */
- START_EXCEPTION(0x1200, ITLBMiss)
- mtspr SPRN_SPRG0, r10 /* Save some working registers */
- mtspr SPRN_SPRG1, r11
-#ifdef CONFIG_403GCX
- stw r12, 0(r0)
- stw r9, 4(r0)
- mfcr r11
- mfspr r12, SPRN_PID
- stw r11, 8(r0)
- stw r12, 12(r0)
-#else
- mtspr SPRN_SPRG4, r12
- mtspr SPRN_SPRG5, r9
- mfcr r11
- mfspr r12, SPRN_PID
- mtspr SPRN_SPRG7, r11
- mtspr SPRN_SPRG6, r12
-#endif
- mfspr r10, SPRN_SRR0 /* Get faulting address */
-
- /* If we are faulting a kernel address, we have to use the
- * kernel page tables.
- */
- lis r11, TASK_SIZE@h
- cmplw r10, r11
- blt+ 3f
- lis r11, swapper_pg_dir@h
- ori r11, r11, swapper_pg_dir@l
- li r9, 0
- mtspr SPRN_PID, r9 /* TLB will have 0 TID */
- b 4f
-
- /* Get the PGD for the current thread.
- */
-3:
- mfspr r11,SPRN_SPRG3
- lwz r11,PGDIR(r11)
-4:
- tophys(r11, r11)
- rlwimi r11, r10, 12, 20, 29 /* Create L1 (pgdir/pmd) address */
- lwz r12, 0(r11) /* Get L1 entry */
- andi. r9, r12, _PMD_PRESENT /* Check if it points to a PTE page */
- beq 2f /* Bail if no table */
-
- rlwimi r12, r10, 22, 20, 29 /* Compute PTE address */
- lwz r11, 0(r12) /* Get Linux PTE */
- andi. r9, r11, _PAGE_PRESENT
- beq 5f
-
- ori r11, r11, _PAGE_ACCESSED
- stw r11, 0(r12)
-
- /* Create TLB tag. This is the faulting address plus a static
- * set of bits. These are size, valid, E, U0.
- */
- li r12, 0x00c0
- rlwimi r10, r12, 0, 20, 31
-
- b finish_tlb_load
-
-2: /* Check for possible large-page pmd entry */
- rlwinm. r9, r12, 2, 22, 24
- beq 5f
-
- /* Create TLB tag. This is the faulting address, plus a static
- * set of bits (valid, E, U0) plus the size from the PMD.
- */
- ori r9, r9, 0x40
- rlwimi r10, r9, 0, 20, 31
- mr r11, r12
-
- b finish_tlb_load
-
-5:
- /* The bailout. Restore registers to pre-exception conditions
- * and call the heavyweights to help us out.
- */
-#ifdef CONFIG_403GCX
- lwz r12, 12(r0)
- lwz r11, 8(r0)
- mtspr SPRN_PID, r12
- mtcr r11
- lwz r9, 4(r0)
- lwz r12, 0(r0)
-#else
- mfspr r12, SPRN_SPRG6
- mfspr r11, SPRN_SPRG7
- mtspr SPRN_PID, r12
- mtcr r11
- mfspr r9, SPRN_SPRG5
- mfspr r12, SPRN_SPRG4
-#endif
- mfspr r11, SPRN_SPRG1
- mfspr r10, SPRN_SPRG0
- b InstructionAccess
-
- EXCEPTION(0x1300, Trap_13, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1400, Trap_14, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1500, Trap_15, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1600, Trap_16, UnknownException, EXC_XFER_EE)
-#ifdef CONFIG_IBM405_ERR51
- /* 405GP errata 51 */
- START_EXCEPTION(0x1700, Trap_17)
- b DTLBMiss
-#else
- EXCEPTION(0x1700, Trap_17, UnknownException, EXC_XFER_EE)
-#endif
- EXCEPTION(0x1800, Trap_18, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1900, Trap_19, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1A00, Trap_1A, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1B00, Trap_1B, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1C00, Trap_1C, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1D00, Trap_1D, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1E00, Trap_1E, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1F00, Trap_1F, UnknownException, EXC_XFER_EE)
-
-/* Check for a single step debug exception while in an exception
- * handler before state has been saved. This is to catch the case
- * where an instruction that we are trying to single step causes
- * an exception (eg ITLB/DTLB miss) and thus the first instruction of
- * the exception handler generates a single step debug exception.
- *
- * If we get a debug trap on the first instruction of an exception handler,
- * we reset the MSR_DE in the _exception handler's_ MSR (the debug trap is
- * a critical exception, so we are using SPRN_CSRR1 to manipulate the MSR).
- * The exception handler was handling a non-critical interrupt, so it will
- * save (and later restore) the MSR via SPRN_SRR1, which will still have
- * the MSR_DE bit set.
- */
- /* 0x2000 - Debug Exception */
- START_EXCEPTION(0x2000, DebugTrap)
- CRITICAL_EXCEPTION_PROLOG
-
- /*
- * If this is a single step or branch-taken exception in an
- * exception entry sequence, it was probably meant to apply to
- * the code where the exception occurred (since exception entry
- * doesn't turn off DE automatically). We simulate the effect
- * of turning off DE on entry to an exception handler by turning
- * off DE in the SRR3 value and clearing the debug status.
- */
- mfspr r10,SPRN_DBSR /* check single-step/branch taken */
- andis. r10,r10,DBSR_IC@h
- beq+ 2f
-
- andi. r10,r9,MSR_IR|MSR_PR /* check supervisor + MMU off */
- beq 1f /* branch and fix it up */
-
- mfspr r10,SPRN_SRR2 /* Faulting instruction address */
- cmplwi r10,0x2100
- bgt+ 2f /* address above exception vectors */
-
- /* here it looks like we got an inappropriate debug exception. */
-1: rlwinm r9,r9,0,~MSR_DE /* clear DE in the SRR3 value */
- lis r10,DBSR_IC@h /* clear the IC event */
- mtspr SPRN_DBSR,r10
- /* restore state and get out */
- lwz r10,_CCR(r11)
- lwz r0,GPR0(r11)
- lwz r1,GPR1(r11)
- mtcrf 0x80,r10
- mtspr SPRN_SRR2,r12
- mtspr SPRN_SRR3,r9
- lwz r9,GPR9(r11)
- lwz r12,GPR12(r11)
- lwz r10,crit_r10@l(0)
- lwz r11,crit_r11@l(0)
- PPC405_ERR77_SYNC
- rfci
- b .
-
- /* continue normal handling for a critical exception... */
-2: mfspr r4,SPRN_DBSR
- addi r3,r1,STACK_FRAME_OVERHEAD
- EXC_XFER_TEMPLATE(DebugException, 0x2002, \
- (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
- NOCOPY, crit_transfer_to_handler, ret_from_crit_exc)
-
-/*
- * The other Data TLB exceptions bail out to this point
- * if they can't resolve the lightweight TLB fault.
- */
-DataAccess:
- NORMAL_EXCEPTION_PROLOG
- mfspr r5,SPRN_ESR /* Grab the ESR, save it, pass arg3 */
- stw r5,_ESR(r11)
- mfspr r4,SPRN_DEAR /* Grab the DEAR, save it, pass arg2 */
- EXC_XFER_EE_LITE(0x300, handle_page_fault)
-
-/* Other PowerPC processors, namely those derived from the 6xx-series
- * have vectors from 0x2100 through 0x2F00 defined, but marked as reserved.
- * However, for the 4xx-series processors these are neither defined nor
- * reserved.
- */
-
- /* Damn, I came up one instruction too many to fit into the
- * exception space :-). Both the instruction and data TLB
- * miss get to this point to load the TLB.
- * r10 - TLB_TAG value
- * r11 - Linux PTE
- * r12, r9 - avilable to use
- * PID - loaded with proper value when we get here
- * Upon exit, we reload everything and RFI.
- * Actually, it will fit now, but oh well.....a common place
- * to load the TLB.
- */
-tlb_4xx_index:
- .long 0
-finish_tlb_load:
- /* load the next available TLB index.
- */
- lwz r9, tlb_4xx_index@l(0)
- addi r9, r9, 1
- andi. r9, r9, (PPC4XX_TLB_SIZE-1)
- stw r9, tlb_4xx_index@l(0)
-
-6:
- /*
- * Clear out the software-only bits in the PTE to generate the
- * TLB_DATA value. These are the bottom 2 bits of the RPM, the
- * top 3 bits of the zone field, and M.
- */
- li r12, 0x0ce2
- andc r11, r11, r12
-
- tlbwe r11, r9, TLB_DATA /* Load TLB LO */
- tlbwe r10, r9, TLB_TAG /* Load TLB HI */
-
- /* Done...restore registers and get out of here.
- */
-#ifdef CONFIG_403GCX
- lwz r12, 12(r0)
- lwz r11, 8(r0)
- mtspr SPRN_PID, r12
- mtcr r11
- lwz r9, 4(r0)
- lwz r12, 0(r0)
-#else
- mfspr r12, SPRN_SPRG6
- mfspr r11, SPRN_SPRG7
- mtspr SPRN_PID, r12
- mtcr r11
- mfspr r9, SPRN_SPRG5
- mfspr r12, SPRN_SPRG4
-#endif
- mfspr r11, SPRN_SPRG1
- mfspr r10, SPRN_SPRG0
- PPC405_ERR77_SYNC
- rfi /* Should sync shadow TLBs */
- b . /* prevent prefetch past rfi */
-
-/* extern void giveup_fpu(struct task_struct *prev)
- *
- * The PowerPC 4xx family of processors do not have an FPU, so this just
- * returns.
- */
-_GLOBAL(giveup_fpu)
- blr
-
-/* This is where the main kernel code starts.
- */
-start_here:
-
- /* ptr to current */
- lis r2,init_task@h
- ori r2,r2,init_task@l
-
- /* ptr to phys current thread */
- tophys(r4,r2)
- addi r4,r4,THREAD /* init task's THREAD */
- mtspr SPRN_SPRG3,r4
-
- /* stack */
- lis r1,init_thread_union@ha
- addi r1,r1,init_thread_union@l
- li r0,0
- stwu r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1)
-
- bl early_init /* We have to do this with MMU on */
-
-/*
- * Decide what sort of machine this is and initialize the MMU.
- */
- mr r3,r31
- mr r4,r30
- mr r5,r29
- mr r6,r28
- mr r7,r27
- bl machine_init
- bl MMU_init
-
-/* Go back to running unmapped so we can load up new values
- * and change to using our exception vectors.
- * On the 4xx, all we have to do is invalidate the TLB to clear
- * the old 16M byte TLB mappings.
- */
- lis r4,2f@h
- ori r4,r4,2f@l
- tophys(r4,r4)
- lis r3,(MSR_KERNEL & ~(MSR_IR|MSR_DR))@h
- ori r3,r3,(MSR_KERNEL & ~(MSR_IR|MSR_DR))@l
- mtspr SPRN_SRR0,r4
- mtspr SPRN_SRR1,r3
- rfi
- b . /* prevent prefetch past rfi */
-
-/* Load up the kernel context */
-2:
- sync /* Flush to memory before changing TLB */
- tlbia
- isync /* Flush shadow TLBs */
-
- /* set up the PTE pointers for the Abatron bdiGDB.
- */
- lis r6, swapper_pg_dir@h
- ori r6, r6, swapper_pg_dir@l
- lis r5, abatron_pteptrs@h
- ori r5, r5, abatron_pteptrs@l
- stw r5, 0xf0(r0) /* Must match your Abatron config file */
- tophys(r5,r5)
- stw r6, 0(r5)
-
-/* Now turn on the MMU for real! */
- lis r4,MSR_KERNEL@h
- ori r4,r4,MSR_KERNEL@l
- lis r3,start_kernel@h
- ori r3,r3,start_kernel@l
- mtspr SPRN_SRR0,r3
- mtspr SPRN_SRR1,r4
- rfi /* enable MMU and jump to start_kernel */
- b . /* prevent prefetch past rfi */
-
-/* Set up the initial MMU state so we can do the first level of
- * kernel initialization. This maps the first 16 MBytes of memory 1:1
- * virtual to physical and more importantly sets the cache mode.
- */
-initial_mmu:
- tlbia /* Invalidate all TLB entries */
- isync
-
- /* We should still be executing code at physical address 0x0000xxxx
- * at this point. However, start_here is at virtual address
- * 0xC000xxxx. So, set up a TLB mapping to cover this once
- * translation is enabled.
- */
-
- lis r3,KERNELBASE@h /* Load the kernel virtual address */
- ori r3,r3,KERNELBASE@l
- tophys(r4,r3) /* Load the kernel physical address */
-
- iccci r0,r3 /* Invalidate the i-cache before use */
-
- /* Load the kernel PID.
- */
- li r0,0
- mtspr SPRN_PID,r0
- sync
-
- /* Configure and load two entries into TLB slots 62 and 63.
- * In case we are pinning TLBs, these are reserved in by the
- * other TLB functions. If not reserving, then it doesn't
- * matter where they are loaded.
- */
- clrrwi r4,r4,10 /* Mask off the real page number */
- ori r4,r4,(TLB_WR | TLB_EX) /* Set the write and execute bits */
-
- clrrwi r3,r3,10 /* Mask off the effective page number */
- ori r3,r3,(TLB_VALID | TLB_PAGESZ(PAGESZ_16M))
-
- li r0,63 /* TLB slot 63 */
-
- tlbwe r4,r0,TLB_DATA /* Load the data portion of the entry */
- tlbwe r3,r0,TLB_TAG /* Load the tag portion of the entry */
-
-#if defined(CONFIG_SERIAL_TEXT_DEBUG) && defined(SERIAL_DEBUG_IO_BASE)
-
- /* Load a TLB entry for the UART, so that ppc4xx_progress() can use
- * the UARTs nice and early. We use a 4k real==virtual mapping. */
-
- lis r3,SERIAL_DEBUG_IO_BASE@h
- ori r3,r3,SERIAL_DEBUG_IO_BASE@l
- mr r4,r3
- clrrwi r4,r4,12
- ori r4,r4,(TLB_WR|TLB_I|TLB_M|TLB_G)
-
- clrrwi r3,r3,12
- ori r3,r3,(TLB_VALID | TLB_PAGESZ(PAGESZ_4K))
-
- li r0,0 /* TLB slot 0 */
- tlbwe r4,r0,TLB_DATA
- tlbwe r3,r0,TLB_TAG
-#endif /* CONFIG_SERIAL_DEBUG_TEXT && SERIAL_DEBUG_IO_BASE */
-
- isync
-
- /* Establish the exception vector base
- */
- lis r4,KERNELBASE@h /* EVPR only uses the high 16-bits */
- tophys(r0,r4) /* Use the physical address */
- mtspr SPRN_EVPR,r0
-
- blr
-
-_GLOBAL(abort)
- mfspr r13,SPRN_DBCR0
- oris r13,r13,DBCR0_RST_SYSTEM@h
- mtspr SPRN_DBCR0,r13
-
-_GLOBAL(set_context)
-
-#ifdef CONFIG_BDI_SWITCH
- /* Context switch the PTE pointer for the Abatron BDI2000.
- * The PGDIR is the second parameter.
- */
- lis r5, KERNELBASE@h
- lwz r5, 0xf0(r5)
- stw r4, 0x4(r5)
-#endif
- sync
- mtspr SPRN_PID,r3
- isync /* Need an isync to flush shadow */
- /* TLBs after changing PID */
- blr
-
-/* We put a few things here that have to be page-aligned. This stuff
- * goes at the beginning of the data segment, which is page-aligned.
- */
- .data
-_GLOBAL(sdata)
-_GLOBAL(empty_zero_page)
- .space 4096
-_GLOBAL(swapper_pg_dir)
- .space 4096
-
-
-/* Stack for handling critical exceptions from kernel mode */
- .section .bss
- .align 12
-exception_stack_bottom:
- .space 4096
-critical_stack_top:
-_GLOBAL(exception_stack_top)
-
-/* This space gets a copy of optional info passed to us by the bootstrap
- * which is used to pass parameters into the kernel like root=/dev/sda1, etc.
- */
-_GLOBAL(cmd_line)
- .space 512
-
-/* Room for two PTE pointers, usually the kernel and current user pointers
- * to their respective root page table.
- */
-abatron_pteptrs:
- .space 8
diff --git a/trunk/arch/powerpc/kernel/head_64.S b/trunk/arch/powerpc/kernel/head_64.S
deleted file mode 100644
index 22a5ee07e1ea..000000000000
--- a/trunk/arch/powerpc/kernel/head_64.S
+++ /dev/null
@@ -1,2011 +0,0 @@
-/*
- * arch/ppc64/kernel/head.S
- *
- * PowerPC version
- * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
- *
- * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
- * Copyright (C) 1996 Cort Dougan
- * Adapted for Power Macintosh by Paul Mackerras.
- * Low-level exception handlers and MMU support
- * rewritten by Paul Mackerras.
- * Copyright (C) 1996 Paul Mackerras.
- *
- * Adapted for 64bit PowerPC by Dave Engebretsen, Peter Bergner, and
- * Mike Corrigan {engebret|bergner|mikejc}@us.ibm.com
- *
- * This file contains the low-level support and setup for the
- * PowerPC-64 platform, including trap and interrupt dispatch.
- *
- * 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
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#ifdef CONFIG_PPC_ISERIES
-#define DO_SOFT_DISABLE
-#endif
-
-/*
- * We layout physical memory as follows:
- * 0x0000 - 0x00ff : Secondary processor spin code
- * 0x0100 - 0x2fff : pSeries Interrupt prologs
- * 0x3000 - 0x5fff : interrupt support, iSeries and common interrupt prologs
- * 0x6000 - 0x6fff : Initial (CPU0) segment table
- * 0x7000 - 0x7fff : FWNMI data area
- * 0x8000 - : Early init and support code
- */
-
-/*
- * SPRG Usage
- *
- * Register Definition
- *
- * SPRG0 reserved for hypervisor
- * SPRG1 temp - used to save gpr
- * SPRG2 temp - used to save gpr
- * SPRG3 virt addr of paca
- */
-
-/*
- * Entering into this code we make the following assumptions:
- * For pSeries:
- * 1. The MMU is off & open firmware is running in real mode.
- * 2. The kernel is entered at __start
- *
- * For iSeries:
- * 1. The MMU is on (as it always is for iSeries)
- * 2. The kernel is entered at system_reset_iSeries
- */
-
- .text
- .globl _stext
-_stext:
-#ifdef CONFIG_PPC_MULTIPLATFORM
-_GLOBAL(__start)
- /* NOP this out unconditionally */
-BEGIN_FTR_SECTION
- b .__start_initialization_multiplatform
-END_FTR_SECTION(0, 1)
-#endif /* CONFIG_PPC_MULTIPLATFORM */
-
- /* Catch branch to 0 in real mode */
- trap
-
-#ifdef CONFIG_PPC_ISERIES
- /*
- * At offset 0x20, there is a pointer to iSeries LPAR data.
- * This is required by the hypervisor
- */
- . = 0x20
- .llong hvReleaseData-KERNELBASE
-
- /*
- * At offset 0x28 and 0x30 are offsets to the mschunks_map
- * array (used by the iSeries LPAR debugger to do translation
- * between physical addresses and absolute addresses) and
- * to the pidhash table (also used by the debugger)
- */
- .llong mschunks_map-KERNELBASE
- .llong 0 /* pidhash-KERNELBASE SFRXXX */
-
- /* Offset 0x38 - Pointer to start of embedded System.map */
- .globl embedded_sysmap_start
-embedded_sysmap_start:
- .llong 0
- /* Offset 0x40 - Pointer to end of embedded System.map */
- .globl embedded_sysmap_end
-embedded_sysmap_end:
- .llong 0
-
-#endif /* CONFIG_PPC_ISERIES */
-
- /* Secondary processors spin on this value until it goes to 1. */
- .globl __secondary_hold_spinloop
-__secondary_hold_spinloop:
- .llong 0x0
-
- /* Secondary processors write this value with their cpu # */
- /* after they enter the spin loop immediately below. */
- .globl __secondary_hold_acknowledge
-__secondary_hold_acknowledge:
- .llong 0x0
-
- . = 0x60
-/*
- * The following code is used on pSeries to hold secondary processors
- * in a spin loop after they have been freed from OpenFirmware, but
- * before the bulk of the kernel has been relocated. This code
- * is relocated to physical address 0x60 before prom_init is run.
- * All of it must fit below the first exception vector at 0x100.
- */
-_GLOBAL(__secondary_hold)
- mfmsr r24
- ori r24,r24,MSR_RI
- mtmsrd r24 /* RI on */
-
- /* Grab our linux cpu number */
- mr r24,r3
-
- /* Tell the master cpu we're here */
- /* Relocation is off & we are located at an address less */
- /* than 0x100, so only need to grab low order offset. */
- std r24,__secondary_hold_acknowledge@l(0)
- sync
-
- /* All secondary cpus wait here until told to start. */
-100: ld r4,__secondary_hold_spinloop@l(0)
- cmpdi 0,r4,1
- bne 100b
-
-#ifdef CONFIG_HMT
- b .hmt_init
-#else
-#ifdef CONFIG_SMP
- mr r3,r24
- b .pSeries_secondary_smp_init
-#else
- BUG_OPCODE
-#endif
-#endif
-
-/* This value is used to mark exception frames on the stack. */
- .section ".toc","aw"
-exception_marker:
- .tc ID_72656773_68657265[TC],0x7265677368657265
- .text
-
-/*
- * The following macros define the code that appears as
- * the prologue to each of the exception handlers. They
- * are split into two parts to allow a single kernel binary
- * to be used for pSeries and iSeries.
- * LOL. One day... - paulus
- */
-
-/*
- * We make as much of the exception code common between native
- * exception handlers (including pSeries LPAR) and iSeries LPAR
- * implementations as possible.
- */
-
-/*
- * This is the start of the interrupt handlers for pSeries
- * This code runs with relocation off.
- */
-#define EX_R9 0
-#define EX_R10 8
-#define EX_R11 16
-#define EX_R12 24
-#define EX_R13 32
-#define EX_SRR0 40
-#define EX_R3 40 /* SLB miss saves R3, but not SRR0 */
-#define EX_DAR 48
-#define EX_LR 48 /* SLB miss saves LR, but not DAR */
-#define EX_DSISR 56
-#define EX_CCR 60
-
-#define EXCEPTION_PROLOG_PSERIES(area, label) \
- mfspr r13,SPRG3; /* get paca address into r13 */ \
- std r9,area+EX_R9(r13); /* save r9 - r12 */ \
- std r10,area+EX_R10(r13); \
- std r11,area+EX_R11(r13); \
- std r12,area+EX_R12(r13); \
- mfspr r9,SPRG1; \
- std r9,area+EX_R13(r13); \
- mfcr r9; \
- clrrdi r12,r13,32; /* get high part of &label */ \
- mfmsr r10; \
- mfspr r11,SRR0; /* save SRR0 */ \
- ori r12,r12,(label)@l; /* virt addr of handler */ \
- ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \
- mtspr SRR0,r12; \
- mfspr r12,SRR1; /* and SRR1 */ \
- mtspr SRR1,r10; \
- rfid; \
- b . /* prevent speculative execution */
-
-/*
- * This is the start of the interrupt handlers for iSeries
- * This code runs with relocation on.
- */
-#define EXCEPTION_PROLOG_ISERIES_1(area) \
- mfspr r13,SPRG3; /* get paca address into r13 */ \
- std r9,area+EX_R9(r13); /* save r9 - r12 */ \
- std r10,area+EX_R10(r13); \
- std r11,area+EX_R11(r13); \
- std r12,area+EX_R12(r13); \
- mfspr r9,SPRG1; \
- std r9,area+EX_R13(r13); \
- mfcr r9
-
-#define EXCEPTION_PROLOG_ISERIES_2 \
- mfmsr r10; \
- ld r11,PACALPPACA+LPPACASRR0(r13); \
- ld r12,PACALPPACA+LPPACASRR1(r13); \
- ori r10,r10,MSR_RI; \
- mtmsrd r10,1
-
-/*
- * The common exception prolog is used for all except a few exceptions
- * such as a segment miss on a kernel address. We have to be prepared
- * to take another exception from the point where we first touch the
- * kernel stack onwards.
- *
- * On entry r13 points to the paca, r9-r13 are saved in the paca,
- * r9 contains the saved CR, r11 and r12 contain the saved SRR0 and
- * SRR1, and relocation is on.
- */
-#define EXCEPTION_PROLOG_COMMON(n, area) \
- andi. r10,r12,MSR_PR; /* See if coming from user */ \
- mr r10,r1; /* Save r1 */ \
- subi r1,r1,INT_FRAME_SIZE; /* alloc frame on kernel stack */ \
- beq- 1f; \
- ld r1,PACAKSAVE(r13); /* kernel stack to use */ \
-1: cmpdi cr1,r1,0; /* check if r1 is in userspace */ \
- bge- cr1,bad_stack; /* abort if it is */ \
- std r9,_CCR(r1); /* save CR in stackframe */ \
- std r11,_NIP(r1); /* save SRR0 in stackframe */ \
- std r12,_MSR(r1); /* save SRR1 in stackframe */ \
- std r10,0(r1); /* make stack chain pointer */ \
- std r0,GPR0(r1); /* save r0 in stackframe */ \
- std r10,GPR1(r1); /* save r1 in stackframe */ \
- std r2,GPR2(r1); /* save r2 in stackframe */ \
- SAVE_4GPRS(3, r1); /* save r3 - r6 in stackframe */ \
- SAVE_2GPRS(7, r1); /* save r7, r8 in stackframe */ \
- ld r9,area+EX_R9(r13); /* move r9, r10 to stackframe */ \
- ld r10,area+EX_R10(r13); \
- std r9,GPR9(r1); \
- std r10,GPR10(r1); \
- ld r9,area+EX_R11(r13); /* move r11 - r13 to stackframe */ \
- ld r10,area+EX_R12(r13); \
- ld r11,area+EX_R13(r13); \
- std r9,GPR11(r1); \
- std r10,GPR12(r1); \
- std r11,GPR13(r1); \
- ld r2,PACATOC(r13); /* get kernel TOC into r2 */ \
- mflr r9; /* save LR in stackframe */ \
- std r9,_LINK(r1); \
- mfctr r10; /* save CTR in stackframe */ \
- std r10,_CTR(r1); \
- mfspr r11,XER; /* save XER in stackframe */ \
- std r11,_XER(r1); \
- li r9,(n)+1; \
- std r9,_TRAP(r1); /* set trap number */ \
- li r10,0; \
- ld r11,exception_marker@toc(r2); \
- std r10,RESULT(r1); /* clear regs->result */ \
- std r11,STACK_FRAME_OVERHEAD-16(r1); /* mark the frame */
-
-/*
- * Exception vectors.
- */
-#define STD_EXCEPTION_PSERIES(n, label) \
- . = n; \
- .globl label##_pSeries; \
-label##_pSeries: \
- HMT_MEDIUM; \
- mtspr SPRG1,r13; /* save r13 */ \
- RUNLATCH_ON(r13); \
- EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
-
-#define STD_EXCEPTION_ISERIES(n, label, area) \
- .globl label##_iSeries; \
-label##_iSeries: \
- HMT_MEDIUM; \
- mtspr SPRG1,r13; /* save r13 */ \
- RUNLATCH_ON(r13); \
- EXCEPTION_PROLOG_ISERIES_1(area); \
- EXCEPTION_PROLOG_ISERIES_2; \
- b label##_common
-
-#define MASKABLE_EXCEPTION_ISERIES(n, label) \
- .globl label##_iSeries; \
-label##_iSeries: \
- HMT_MEDIUM; \
- mtspr SPRG1,r13; /* save r13 */ \
- RUNLATCH_ON(r13); \
- EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN); \
- lbz r10,PACAPROCENABLED(r13); \
- cmpwi 0,r10,0; \
- beq- label##_iSeries_masked; \
- EXCEPTION_PROLOG_ISERIES_2; \
- b label##_common; \
-
-#ifdef DO_SOFT_DISABLE
-#define DISABLE_INTS \
- lbz r10,PACAPROCENABLED(r13); \
- li r11,0; \
- std r10,SOFTE(r1); \
- mfmsr r10; \
- stb r11,PACAPROCENABLED(r13); \
- ori r10,r10,MSR_EE; \
- mtmsrd r10,1
-
-#define ENABLE_INTS \
- lbz r10,PACAPROCENABLED(r13); \
- mfmsr r11; \
- std r10,SOFTE(r1); \
- ori r11,r11,MSR_EE; \
- mtmsrd r11,1
-
-#else /* hard enable/disable interrupts */
-#define DISABLE_INTS
-
-#define ENABLE_INTS \
- ld r12,_MSR(r1); \
- mfmsr r11; \
- rlwimi r11,r12,0,MSR_EE; \
- mtmsrd r11,1
-
-#endif
-
-#define STD_EXCEPTION_COMMON(trap, label, hdlr) \
- .align 7; \
- .globl label##_common; \
-label##_common: \
- EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \
- DISABLE_INTS; \
- bl .save_nvgprs; \
- addi r3,r1,STACK_FRAME_OVERHEAD; \
- bl hdlr; \
- b .ret_from_except
-
-#define STD_EXCEPTION_COMMON_LITE(trap, label, hdlr) \
- .align 7; \
- .globl label##_common; \
-label##_common: \
- EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \
- DISABLE_INTS; \
- addi r3,r1,STACK_FRAME_OVERHEAD; \
- bl hdlr; \
- b .ret_from_except_lite
-
-/*
- * Start of pSeries system interrupt routines
- */
- . = 0x100
- .globl __start_interrupts
-__start_interrupts:
-
- STD_EXCEPTION_PSERIES(0x100, system_reset)
-
- . = 0x200
-_machine_check_pSeries:
- HMT_MEDIUM
- mtspr SPRG1,r13 /* save r13 */
- RUNLATCH_ON(r13)
- EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
-
- . = 0x300
- .globl data_access_pSeries
-data_access_pSeries:
- HMT_MEDIUM
- mtspr SPRG1,r13
-BEGIN_FTR_SECTION
- mtspr SPRG2,r12
- mfspr r13,DAR
- mfspr r12,DSISR
- srdi r13,r13,60
- rlwimi r13,r12,16,0x20
- mfcr r12
- cmpwi r13,0x2c
- beq .do_stab_bolted_pSeries
- mtcrf 0x80,r12
- mfspr r12,SPRG2
-END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
- EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common)
-
- . = 0x380
- .globl data_access_slb_pSeries
-data_access_slb_pSeries:
- HMT_MEDIUM
- mtspr SPRG1,r13
- RUNLATCH_ON(r13)
- mfspr r13,SPRG3 /* get paca address into r13 */
- std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */
- std r10,PACA_EXSLB+EX_R10(r13)
- std r11,PACA_EXSLB+EX_R11(r13)
- std r12,PACA_EXSLB+EX_R12(r13)
- std r3,PACA_EXSLB+EX_R3(r13)
- mfspr r9,SPRG1
- std r9,PACA_EXSLB+EX_R13(r13)
- mfcr r9
- mfspr r12,SRR1 /* and SRR1 */
- mfspr r3,DAR
- b .do_slb_miss /* Rel. branch works in real mode */
-
- STD_EXCEPTION_PSERIES(0x400, instruction_access)
-
- . = 0x480
- .globl instruction_access_slb_pSeries
-instruction_access_slb_pSeries:
- HMT_MEDIUM
- mtspr SPRG1,r13
- RUNLATCH_ON(r13)
- mfspr r13,SPRG3 /* get paca address into r13 */
- std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */
- std r10,PACA_EXSLB+EX_R10(r13)
- std r11,PACA_EXSLB+EX_R11(r13)
- std r12,PACA_EXSLB+EX_R12(r13)
- std r3,PACA_EXSLB+EX_R3(r13)
- mfspr r9,SPRG1
- std r9,PACA_EXSLB+EX_R13(r13)
- mfcr r9
- mfspr r12,SRR1 /* and SRR1 */
- mfspr r3,SRR0 /* SRR0 is faulting address */
- b .do_slb_miss /* Rel. branch works in real mode */
-
- STD_EXCEPTION_PSERIES(0x500, hardware_interrupt)
- STD_EXCEPTION_PSERIES(0x600, alignment)
- STD_EXCEPTION_PSERIES(0x700, program_check)
- STD_EXCEPTION_PSERIES(0x800, fp_unavailable)
- STD_EXCEPTION_PSERIES(0x900, decrementer)
- STD_EXCEPTION_PSERIES(0xa00, trap_0a)
- STD_EXCEPTION_PSERIES(0xb00, trap_0b)
-
- . = 0xc00
- .globl system_call_pSeries
-system_call_pSeries:
- HMT_MEDIUM
- RUNLATCH_ON(r9)
- mr r9,r13
- mfmsr r10
- mfspr r13,SPRG3
- mfspr r11,SRR0
- clrrdi r12,r13,32
- oris r12,r12,system_call_common@h
- ori r12,r12,system_call_common@l
- mtspr SRR0,r12
- ori r10,r10,MSR_IR|MSR_DR|MSR_RI
- mfspr r12,SRR1
- mtspr SRR1,r10
- rfid
- b . /* prevent speculative execution */
-
- STD_EXCEPTION_PSERIES(0xd00, single_step)
- STD_EXCEPTION_PSERIES(0xe00, trap_0e)
-
- /* We need to deal with the Altivec unavailable exception
- * here which is at 0xf20, thus in the middle of the
- * prolog code of the PerformanceMonitor one. A little
- * trickery is thus necessary
- */
- . = 0xf00
- b performance_monitor_pSeries
-
- STD_EXCEPTION_PSERIES(0xf20, altivec_unavailable)
-
- STD_EXCEPTION_PSERIES(0x1300, instruction_breakpoint)
- STD_EXCEPTION_PSERIES(0x1700, altivec_assist)
-
- . = 0x3000
-
-/*** pSeries interrupt support ***/
-
- /* moved from 0xf00 */
- STD_EXCEPTION_PSERIES(., performance_monitor)
-
- .align 7
-_GLOBAL(do_stab_bolted_pSeries)
- mtcrf 0x80,r12
- mfspr r12,SPRG2
- EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted)
-
-/*
- * Vectors for the FWNMI option. Share common code.
- */
- .globl system_reset_fwnmi
-system_reset_fwnmi:
- HMT_MEDIUM
- mtspr SPRG1,r13 /* save r13 */
- RUNLATCH_ON(r13)
- EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common)
-
- .globl machine_check_fwnmi
-machine_check_fwnmi:
- HMT_MEDIUM
- mtspr SPRG1,r13 /* save r13 */
- RUNLATCH_ON(r13)
- EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
-
-#ifdef CONFIG_PPC_ISERIES
-/*** ISeries-LPAR interrupt handlers ***/
-
- STD_EXCEPTION_ISERIES(0x200, machine_check, PACA_EXMC)
-
- .globl data_access_iSeries
-data_access_iSeries:
- mtspr SPRG1,r13
-BEGIN_FTR_SECTION
- mtspr SPRG2,r12
- mfspr r13,DAR
- mfspr r12,DSISR
- srdi r13,r13,60
- rlwimi r13,r12,16,0x20
- mfcr r12
- cmpwi r13,0x2c
- beq .do_stab_bolted_iSeries
- mtcrf 0x80,r12
- mfspr r12,SPRG2
-END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
- EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN)
- EXCEPTION_PROLOG_ISERIES_2
- b data_access_common
-
-.do_stab_bolted_iSeries:
- mtcrf 0x80,r12
- mfspr r12,SPRG2
- EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB)
- EXCEPTION_PROLOG_ISERIES_2
- b .do_stab_bolted
-
- .globl data_access_slb_iSeries
-data_access_slb_iSeries:
- mtspr SPRG1,r13 /* save r13 */
- EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB)
- std r3,PACA_EXSLB+EX_R3(r13)
- ld r12,PACALPPACA+LPPACASRR1(r13)
- mfspr r3,DAR
- b .do_slb_miss
-
- STD_EXCEPTION_ISERIES(0x400, instruction_access, PACA_EXGEN)
-
- .globl instruction_access_slb_iSeries
-instruction_access_slb_iSeries:
- mtspr SPRG1,r13 /* save r13 */
- EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB)
- std r3,PACA_EXSLB+EX_R3(r13)
- ld r12,PACALPPACA+LPPACASRR1(r13)
- ld r3,PACALPPACA+LPPACASRR0(r13)
- b .do_slb_miss
-
- MASKABLE_EXCEPTION_ISERIES(0x500, hardware_interrupt)
- STD_EXCEPTION_ISERIES(0x600, alignment, PACA_EXGEN)
- STD_EXCEPTION_ISERIES(0x700, program_check, PACA_EXGEN)
- STD_EXCEPTION_ISERIES(0x800, fp_unavailable, PACA_EXGEN)
- MASKABLE_EXCEPTION_ISERIES(0x900, decrementer)
- STD_EXCEPTION_ISERIES(0xa00, trap_0a, PACA_EXGEN)
- STD_EXCEPTION_ISERIES(0xb00, trap_0b, PACA_EXGEN)
-
- .globl system_call_iSeries
-system_call_iSeries:
- mr r9,r13
- mfspr r13,SPRG3
- EXCEPTION_PROLOG_ISERIES_2
- b system_call_common
-
- STD_EXCEPTION_ISERIES( 0xd00, single_step, PACA_EXGEN)
- STD_EXCEPTION_ISERIES( 0xe00, trap_0e, PACA_EXGEN)
- STD_EXCEPTION_ISERIES( 0xf00, performance_monitor, PACA_EXGEN)
-
- .globl system_reset_iSeries
-system_reset_iSeries:
- mfspr r13,SPRG3 /* Get paca address */
- mfmsr r24
- ori r24,r24,MSR_RI
- mtmsrd r24 /* RI on */
- lhz r24,PACAPACAINDEX(r13) /* Get processor # */
- cmpwi 0,r24,0 /* Are we processor 0? */
- beq .__start_initialization_iSeries /* Start up the first processor */
- mfspr r4,SPRN_CTRLF
- li r5,CTRL_RUNLATCH /* Turn off the run light */
- andc r4,r4,r5
- mtspr SPRN_CTRLT,r4
-
-1:
- HMT_LOW
-#ifdef CONFIG_SMP
- lbz r23,PACAPROCSTART(r13) /* Test if this processor
- * should start */
- sync
- LOADADDR(r3,current_set)
- sldi r28,r24,3 /* get current_set[cpu#] */
- ldx r3,r3,r28
- addi r1,r3,THREAD_SIZE
- subi r1,r1,STACK_FRAME_OVERHEAD
-
- cmpwi 0,r23,0
- beq iSeries_secondary_smp_loop /* Loop until told to go */
- bne .__secondary_start /* Loop until told to go */
-iSeries_secondary_smp_loop:
- /* Let the Hypervisor know we are alive */
- /* 8002 is a call to HvCallCfg::getLps, a harmless Hypervisor function */
- lis r3,0x8002
- rldicr r3,r3,32,15 /* r0 = (r3 << 32) & 0xffff000000000000 */
-#else /* CONFIG_SMP */
- /* Yield the processor. This is required for non-SMP kernels
- which are running on multi-threaded machines. */
- lis r3,0x8000
- rldicr r3,r3,32,15 /* r3 = (r3 << 32) & 0xffff000000000000 */
- addi r3,r3,18 /* r3 = 0x8000000000000012 which is "yield" */
- li r4,0 /* "yield timed" */
- li r5,-1 /* "yield forever" */
-#endif /* CONFIG_SMP */
- li r0,-1 /* r0=-1 indicates a Hypervisor call */
- sc /* Invoke the hypervisor via a system call */
- mfspr r13,SPRG3 /* Put r13 back ???? */
- b 1b /* If SMP not configured, secondaries
- * loop forever */
-
- .globl decrementer_iSeries_masked
-decrementer_iSeries_masked:
- li r11,1
- stb r11,PACALPPACA+LPPACADECRINT(r13)
- lwz r12,PACADEFAULTDECR(r13)
- mtspr SPRN_DEC,r12
- /* fall through */
-
- .globl hardware_interrupt_iSeries_masked
-hardware_interrupt_iSeries_masked:
- mtcrf 0x80,r9 /* Restore regs */
- ld r11,PACALPPACA+LPPACASRR0(r13)
- ld r12,PACALPPACA+LPPACASRR1(r13)
- mtspr SRR0,r11
- mtspr SRR1,r12
- ld r9,PACA_EXGEN+EX_R9(r13)
- ld r10,PACA_EXGEN+EX_R10(r13)
- ld r11,PACA_EXGEN+EX_R11(r13)
- ld r12,PACA_EXGEN+EX_R12(r13)
- ld r13,PACA_EXGEN+EX_R13(r13)
- rfid
- b . /* prevent speculative execution */
-#endif /* CONFIG_PPC_ISERIES */
-
-/*** Common interrupt handlers ***/
-
- STD_EXCEPTION_COMMON(0x100, system_reset, .system_reset_exception)
-
- /*
- * Machine check is different because we use a different
- * save area: PACA_EXMC instead of PACA_EXGEN.
- */
- .align 7
- .globl machine_check_common
-machine_check_common:
- EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC)
- DISABLE_INTS
- bl .save_nvgprs
- addi r3,r1,STACK_FRAME_OVERHEAD
- bl .machine_check_exception
- b .ret_from_except
-
- STD_EXCEPTION_COMMON_LITE(0x900, decrementer, .timer_interrupt)
- STD_EXCEPTION_COMMON(0xa00, trap_0a, .unknown_exception)
- STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception)
- STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception)
- STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception)
- STD_EXCEPTION_COMMON(0xf00, performance_monitor, .performance_monitor_exception)
- STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception)
-#ifdef CONFIG_ALTIVEC
- STD_EXCEPTION_COMMON(0x1700, altivec_assist, .altivec_assist_exception)
-#else
- STD_EXCEPTION_COMMON(0x1700, altivec_assist, .unknown_exception)
-#endif
-
-/*
- * Here we have detected that the kernel stack pointer is bad.
- * R9 contains the saved CR, r13 points to the paca,
- * r10 contains the (bad) kernel stack pointer,
- * r11 and r12 contain the saved SRR0 and SRR1.
- * We switch to using an emergency stack, save the registers there,
- * and call kernel_bad_stack(), which panics.
- */
-bad_stack:
- ld r1,PACAEMERGSP(r13)
- subi r1,r1,64+INT_FRAME_SIZE
- std r9,_CCR(r1)
- std r10,GPR1(r1)
- std r11,_NIP(r1)
- std r12,_MSR(r1)
- mfspr r11,DAR
- mfspr r12,DSISR
- std r11,_DAR(r1)
- std r12,_DSISR(r1)
- mflr r10
- mfctr r11
- mfxer r12
- std r10,_LINK(r1)
- std r11,_CTR(r1)
- std r12,_XER(r1)
- SAVE_GPR(0,r1)
- SAVE_GPR(2,r1)
- SAVE_4GPRS(3,r1)
- SAVE_2GPRS(7,r1)
- SAVE_10GPRS(12,r1)
- SAVE_10GPRS(22,r1)
- addi r11,r1,INT_FRAME_SIZE
- std r11,0(r1)
- li r12,0
- std r12,0(r11)
- ld r2,PACATOC(r13)
-1: addi r3,r1,STACK_FRAME_OVERHEAD
- bl .kernel_bad_stack
- b 1b
-
-/*
- * Return from an exception with minimal checks.
- * The caller is assumed to have done EXCEPTION_PROLOG_COMMON.
- * If interrupts have been enabled, or anything has been
- * done that might have changed the scheduling status of
- * any task or sent any task a signal, you should use
- * ret_from_except or ret_from_except_lite instead of this.
- */
-fast_exception_return:
- ld r12,_MSR(r1)
- ld r11,_NIP(r1)
- andi. r3,r12,MSR_RI /* check if RI is set */
- beq- unrecov_fer
- ld r3,_CCR(r1)
- ld r4,_LINK(r1)
- ld r5,_CTR(r1)
- ld r6,_XER(r1)
- mtcr r3
- mtlr r4
- mtctr r5
- mtxer r6
- REST_GPR(0, r1)
- REST_8GPRS(2, r1)
-
- mfmsr r10
- clrrdi r10,r10,2 /* clear RI (LE is 0 already) */
- mtmsrd r10,1
-
- mtspr SRR1,r12
- mtspr SRR0,r11
- REST_4GPRS(10, r1)
- ld r1,GPR1(r1)
- rfid
- b . /* prevent speculative execution */
-
-unrecov_fer:
- bl .save_nvgprs
-1: addi r3,r1,STACK_FRAME_OVERHEAD
- bl .unrecoverable_exception
- b 1b
-
-/*
- * Here r13 points to the paca, r9 contains the saved CR,
- * SRR0 and SRR1 are saved in r11 and r12,
- * r9 - r13 are saved in paca->exgen.
- */
- .align 7
- .globl data_access_common
-data_access_common:
- RUNLATCH_ON(r10) /* It wont fit in the 0x300 handler */
- mfspr r10,DAR
- std r10,PACA_EXGEN+EX_DAR(r13)
- mfspr r10,DSISR
- stw r10,PACA_EXGEN+EX_DSISR(r13)
- EXCEPTION_PROLOG_COMMON(0x300, PACA_EXGEN)
- ld r3,PACA_EXGEN+EX_DAR(r13)
- lwz r4,PACA_EXGEN+EX_DSISR(r13)
- li r5,0x300
- b .do_hash_page /* Try to handle as hpte fault */
-
- .align 7
- .globl instruction_access_common
-instruction_access_common:
- EXCEPTION_PROLOG_COMMON(0x400, PACA_EXGEN)
- ld r3,_NIP(r1)
- andis. r4,r12,0x5820
- li r5,0x400
- b .do_hash_page /* Try to handle as hpte fault */
-
- .align 7
- .globl hardware_interrupt_common
- .globl hardware_interrupt_entry
-hardware_interrupt_common:
- EXCEPTION_PROLOG_COMMON(0x500, PACA_EXGEN)
-hardware_interrupt_entry:
- DISABLE_INTS
- addi r3,r1,STACK_FRAME_OVERHEAD
- bl .do_IRQ
- b .ret_from_except_lite
-
- .align 7
- .globl alignment_common
-alignment_common:
- mfspr r10,DAR
- std r10,PACA_EXGEN+EX_DAR(r13)
- mfspr r10,DSISR
- stw r10,PACA_EXGEN+EX_DSISR(r13)
- EXCEPTION_PROLOG_COMMON(0x600, PACA_EXGEN)
- ld r3,PACA_EXGEN+EX_DAR(r13)
- lwz r4,PACA_EXGEN+EX_DSISR(r13)
- std r3,_DAR(r1)
- std r4,_DSISR(r1)
- bl .save_nvgprs
- addi r3,r1,STACK_FRAME_OVERHEAD
- ENABLE_INTS
- bl .alignment_exception
- b .ret_from_except
-
- .align 7
- .globl program_check_common
-program_check_common:
- EXCEPTION_PROLOG_COMMON(0x700, PACA_EXGEN)
- bl .save_nvgprs
- addi r3,r1,STACK_FRAME_OVERHEAD
- ENABLE_INTS
- bl .program_check_exception
- b .ret_from_except
-
- .align 7
- .globl fp_unavailable_common
-fp_unavailable_common:
- EXCEPTION_PROLOG_COMMON(0x800, PACA_EXGEN)
- bne .load_up_fpu /* if from user, just load it up */
- bl .save_nvgprs
- addi r3,r1,STACK_FRAME_OVERHEAD
- ENABLE_INTS
- bl .kernel_fp_unavailable_exception
- BUG_OPCODE
-
-/*
- * load_up_fpu(unused, unused, tsk)
- * Disable FP for the task which had the FPU previously,
- * and save its floating-point registers in its thread_struct.
- * Enables the FPU for use in the kernel on return.
- * On SMP we know the fpu is free, since we give it up every
- * switch (ie, no lazy save of the FP registers).
- * On entry: r13 == 'current' && last_task_used_math != 'current'
- */
-_STATIC(load_up_fpu)
- mfmsr r5 /* grab the current MSR */
- ori r5,r5,MSR_FP
- 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
- ld r3,last_task_used_math@got(r2)
- ld r4,0(r3)
- cmpdi 0,r4,0
- beq 1f
- /* Save FP state to last_task_used_math's THREAD struct */
- addi r4,r4,THREAD
- SAVE_32FPRS(0, r4)
- mffs fr0
- stfd fr0,THREAD_FPSCR(r4)
- /* Disable FP for last_task_used_math */
- ld r5,PT_REGS(r4)
- ld r4,_MSR-STACK_FRAME_OVERHEAD(r5)
- li r6,MSR_FP|MSR_FE0|MSR_FE1
- andc r4,r4,r6
- std r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-1:
-#endif /* CONFIG_SMP */
- /* enable use of FP after return */
- ld r4,PACACURRENT(r13)
- addi r5,r4,THREAD /* Get THREAD */
- ld r4,THREAD_FPEXC_MODE(r5)
- ori r12,r12,MSR_FP
- or r12,r12,r4
- std r12,_MSR(r1)
- lfd fr0,THREAD_FPSCR(r5)
- mtfsf 0xff,fr0
- REST_32FPRS(0, r5)
-#ifndef CONFIG_SMP
- /* Update last_task_used_math to 'current' */
- subi r4,r5,THREAD /* Back to 'current' */
- std r4,0(r3)
-#endif /* CONFIG_SMP */
- /* restore registers and return */
- b fast_exception_return
-
- .align 7
- .globl altivec_unavailable_common
-altivec_unavailable_common:
- EXCEPTION_PROLOG_COMMON(0xf20, PACA_EXGEN)
-#ifdef CONFIG_ALTIVEC
-BEGIN_FTR_SECTION
- bne .load_up_altivec /* if from user, just load it up */
-END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
-#endif
- bl .save_nvgprs
- addi r3,r1,STACK_FRAME_OVERHEAD
- ENABLE_INTS
- bl .altivec_unavailable_exception
- b .ret_from_except
-
-#ifdef CONFIG_ALTIVEC
-/*
- * load_up_altivec(unused, unused, tsk)
- * Disable VMX for the task which had it previously,
- * and save its vector registers in its thread_struct.
- * Enables the VMX for use in the kernel on return.
- * On SMP we know the VMX is free, since we give it up every
- * switch (ie, no lazy save of the vector registers).
- * On entry: r13 == 'current' && last_task_used_altivec != 'current'
- */
-_STATIC(load_up_altivec)
- mfmsr r5 /* grab the current MSR */
- oris r5,r5,MSR_VEC@h
- mtmsrd r5 /* enable use of VMX now */
- isync
-
-/*
- * For SMP, we don't do lazy VMX switching because it just gets too
- * horrendously complex, especially when a task switches from one CPU
- * to another. Instead we call giveup_altvec in switch_to.
- * VRSAVE isn't dealt with here, that is done in the normal context
- * switch code. Note that we could rely on vrsave value to eventually
- * avoid saving all of the VREGs here...
- */
-#ifndef CONFIG_SMP
- ld r3,last_task_used_altivec@got(r2)
- ld r4,0(r3)
- cmpdi 0,r4,0
- beq 1f
- /* Save VMX state to last_task_used_altivec's THREAD struct */
- addi r4,r4,THREAD
- SAVE_32VRS(0,r5,r4)
- mfvscr vr0
- li r10,THREAD_VSCR
- stvx vr0,r10,r4
- /* Disable VMX for last_task_used_altivec */
- ld r5,PT_REGS(r4)
- ld r4,_MSR-STACK_FRAME_OVERHEAD(r5)
- lis r6,MSR_VEC@h
- andc r4,r4,r6
- std r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-1:
-#endif /* CONFIG_SMP */
- /* Hack: if we get an altivec unavailable trap with VRSAVE
- * set to all zeros, we assume this is a broken application
- * that fails to set it properly, and thus we switch it to
- * all 1's
- */
- mfspr r4,SPRN_VRSAVE
- cmpdi 0,r4,0
- bne+ 1f
- li r4,-1
- mtspr SPRN_VRSAVE,r4
-1:
- /* enable use of VMX after return */
- ld r4,PACACURRENT(r13)
- addi r5,r4,THREAD /* Get THREAD */
- oris r12,r12,MSR_VEC@h
- std r12,_MSR(r1)
- li r4,1
- li r10,THREAD_VSCR
- stw r4,THREAD_USED_VR(r5)
- lvx vr0,r10,r5
- mtvscr vr0
- REST_32VRS(0,r4,r5)
-#ifndef CONFIG_SMP
- /* Update last_task_used_math to 'current' */
- subi r4,r5,THREAD /* Back to 'current' */
- std r4,0(r3)
-#endif /* CONFIG_SMP */
- /* restore registers and return */
- b fast_exception_return
-#endif /* CONFIG_ALTIVEC */
-
-/*
- * Hash table stuff
- */
- .align 7
-_GLOBAL(do_hash_page)
- std r3,_DAR(r1)
- std r4,_DSISR(r1)
-
- andis. r0,r4,0xa450 /* weird error? */
- bne- .handle_page_fault /* if not, try to insert a HPTE */
-BEGIN_FTR_SECTION
- andis. r0,r4,0x0020 /* Is it a segment table fault? */
- bne- .do_ste_alloc /* If so handle it */
-END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
-
- /*
- * We need to set the _PAGE_USER bit if MSR_PR is set or if we are
- * accessing a userspace segment (even from the kernel). We assume
- * kernel addresses always have the high bit set.
- */
- rlwinm r4,r4,32-25+9,31-9,31-9 /* DSISR_STORE -> _PAGE_RW */
- rotldi r0,r3,15 /* Move high bit into MSR_PR posn */
- orc r0,r12,r0 /* MSR_PR | ~high_bit */
- rlwimi r4,r0,32-13,30,30 /* becomes _PAGE_USER access bit */
- ori r4,r4,1 /* add _PAGE_PRESENT */
- rlwimi r4,r5,22+2,31-2,31-2 /* Set _PAGE_EXEC if trap is 0x400 */
-
- /*
- * On iSeries, we soft-disable interrupts here, then
- * hard-enable interrupts so that the hash_page code can spin on
- * the hash_table_lock without problems on a shared processor.
- */
- DISABLE_INTS
-
- /*
- * r3 contains the faulting address
- * r4 contains the required access permissions
- * r5 contains the trap number
- *
- * at return r3 = 0 for success
- */
- bl .hash_page /* build HPTE if possible */
- cmpdi r3,0 /* see if hash_page succeeded */
-
-#ifdef DO_SOFT_DISABLE
- /*
- * If we had interrupts soft-enabled at the point where the
- * DSI/ISI occurred, and an interrupt came in during hash_page,
- * handle it now.
- * We jump to ret_from_except_lite rather than fast_exception_return
- * because ret_from_except_lite will check for and handle pending
- * interrupts if necessary.
- */
- beq .ret_from_except_lite
- /* For a hash failure, we don't bother re-enabling interrupts */
- ble- 12f
-
- /*
- * hash_page couldn't handle it, set soft interrupt enable back
- * to what it was before the trap. Note that .local_irq_restore
- * handles any interrupts pending at this point.
- */
- ld r3,SOFTE(r1)
- bl .local_irq_restore
- b 11f
-#else
- beq fast_exception_return /* Return from exception on success */
- ble- 12f /* Failure return from hash_page */
-
- /* fall through */
-#endif
-
-/* Here we have a page fault that hash_page can't handle. */
-_GLOBAL(handle_page_fault)
- ENABLE_INTS
-11: ld r4,_DAR(r1)
- ld r5,_DSISR(r1)
- addi r3,r1,STACK_FRAME_OVERHEAD
- bl .do_page_fault
- cmpdi r3,0
- beq+ .ret_from_except_lite
- bl .save_nvgprs
- mr r5,r3
- addi r3,r1,STACK_FRAME_OVERHEAD
- lwz r4,_DAR(r1)
- bl .bad_page_fault
- b .ret_from_except
-
-/* We have a page fault that hash_page could handle but HV refused
- * the PTE insertion
- */
-12: bl .save_nvgprs
- addi r3,r1,STACK_FRAME_OVERHEAD
- lwz r4,_DAR(r1)
- bl .low_hash_fault
- b .ret_from_except
-
- /* here we have a segment miss */
-_GLOBAL(do_ste_alloc)
- bl .ste_allocate /* try to insert stab entry */
- cmpdi r3,0
- beq+ fast_exception_return
- b .handle_page_fault
-
-/*
- * r13 points to the PACA, r9 contains the saved CR,
- * r11 and r12 contain the saved SRR0 and SRR1.
- * r9 - r13 are saved in paca->exslb.
- * We assume we aren't going to take any exceptions during this procedure.
- * We assume (DAR >> 60) == 0xc.
- */
- .align 7
-_GLOBAL(do_stab_bolted)
- stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */
- std r11,PACA_EXSLB+EX_SRR0(r13) /* save SRR0 in exc. frame */
-
- /* Hash to the primary group */
- ld r10,PACASTABVIRT(r13)
- mfspr r11,DAR
- srdi r11,r11,28
- rldimi r10,r11,7,52 /* r10 = first ste of the group */
-
- /* Calculate VSID */
- /* This is a kernel address, so protovsid = ESID */
- ASM_VSID_SCRAMBLE(r11, r9)
- rldic r9,r11,12,16 /* r9 = vsid << 12 */
-
- /* Search the primary group for a free entry */
-1: ld r11,0(r10) /* Test valid bit of the current ste */
- andi. r11,r11,0x80
- beq 2f
- addi r10,r10,16
- andi. r11,r10,0x70
- bne 1b
-
- /* Stick for only searching the primary group for now. */
- /* At least for now, we use a very simple random castout scheme */
- /* Use the TB as a random number ; OR in 1 to avoid entry 0 */
- mftb r11
- rldic r11,r11,4,57 /* r11 = (r11 << 4) & 0x70 */
- ori r11,r11,0x10
-
- /* r10 currently points to an ste one past the group of interest */
- /* make it point to the randomly selected entry */
- subi r10,r10,128
- or r10,r10,r11 /* r10 is the entry to invalidate */
-
- isync /* mark the entry invalid */
- ld r11,0(r10)
- rldicl r11,r11,56,1 /* clear the valid bit */
- rotldi r11,r11,8
- std r11,0(r10)
- sync
-
- clrrdi r11,r11,28 /* Get the esid part of the ste */
- slbie r11
-
-2: std r9,8(r10) /* Store the vsid part of the ste */
- eieio
-
- mfspr r11,DAR /* Get the new esid */
- clrrdi r11,r11,28 /* Permits a full 32b of ESID */
- ori r11,r11,0x90 /* Turn on valid and kp */
- std r11,0(r10) /* Put new entry back into the stab */
-
- sync
-
- /* All done -- return from exception. */
- lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */
- ld r11,PACA_EXSLB+EX_SRR0(r13) /* get saved SRR0 */
-
- andi. r10,r12,MSR_RI
- beq- unrecov_slb
-
- mtcrf 0x80,r9 /* restore CR */
-
- mfmsr r10
- clrrdi r10,r10,2
- mtmsrd r10,1
-
- mtspr SRR0,r11
- mtspr SRR1,r12
- ld r9,PACA_EXSLB+EX_R9(r13)
- ld r10,PACA_EXSLB+EX_R10(r13)
- ld r11,PACA_EXSLB+EX_R11(r13)
- ld r12,PACA_EXSLB+EX_R12(r13)
- ld r13,PACA_EXSLB+EX_R13(r13)
- rfid
- b . /* prevent speculative execution */
-
-/*
- * r13 points to the PACA, r9 contains the saved CR,
- * r11 and r12 contain the saved SRR0 and SRR1.
- * r3 has the faulting address
- * r9 - r13 are saved in paca->exslb.
- * r3 is saved in paca->slb_r3
- * We assume we aren't going to take any exceptions during this procedure.
- */
-_GLOBAL(do_slb_miss)
- mflr r10
-
- stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */
- std r10,PACA_EXSLB+EX_LR(r13) /* save LR */
-
- bl .slb_allocate /* handle it */
-
- /* All done -- return from exception. */
-
- ld r10,PACA_EXSLB+EX_LR(r13)
- ld r3,PACA_EXSLB+EX_R3(r13)
- lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */
-#ifdef CONFIG_PPC_ISERIES
- ld r11,PACALPPACA+LPPACASRR0(r13) /* get SRR0 value */
-#endif /* CONFIG_PPC_ISERIES */
-
- mtlr r10
-
- andi. r10,r12,MSR_RI /* check for unrecoverable exception */
- beq- unrecov_slb
-
-.machine push
-.machine "power4"
- mtcrf 0x80,r9
- mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */
-.machine pop
-
-#ifdef CONFIG_PPC_ISERIES
- mtspr SRR0,r11
- mtspr SRR1,r12
-#endif /* CONFIG_PPC_ISERIES */
- ld r9,PACA_EXSLB+EX_R9(r13)
- ld r10,PACA_EXSLB+EX_R10(r13)
- ld r11,PACA_EXSLB+EX_R11(r13)
- ld r12,PACA_EXSLB+EX_R12(r13)
- ld r13,PACA_EXSLB+EX_R13(r13)
- rfid
- b . /* prevent speculative execution */
-
-unrecov_slb:
- EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB)
- DISABLE_INTS
- bl .save_nvgprs
-1: addi r3,r1,STACK_FRAME_OVERHEAD
- bl .unrecoverable_exception
- b 1b
-
-/*
- * Space for CPU0's segment table.
- *
- * 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
- * fixed address (the linker can't compute (u64)&initial_stab >>
- * PAGE_SHIFT).
- */
- . = STAB0_PHYS_ADDR /* 0x6000 */
- .globl initial_stab
-initial_stab:
- .space 4096
-
-/*
- * Data area reserved for FWNMI option.
- * This address (0x7000) is fixed by the RPA.
- */
- .= 0x7000
- .globl fwnmi_data_area
-fwnmi_data_area:
-
- /* iSeries does not use the FWNMI stuff, so it is safe to put
- * this here, even if we later allow kernels that will boot on
- * both pSeries and iSeries */
-#ifdef CONFIG_PPC_ISERIES
- . = LPARMAP_PHYS
-#include "lparmap.s"
-/*
- * This ".text" is here for old compilers that generate a trailing
- * .note section when compiling .c files to .s
- */
- .text
-#endif /* CONFIG_PPC_ISERIES */
-
- . = 0x8000
-
-/*
- * On pSeries, secondary processors spin in the following code.
- * At entry, r3 = this processor's number (physical cpu id)
- */
-_GLOBAL(pSeries_secondary_smp_init)
- mr r24,r3
-
- /* turn on 64-bit mode */
- bl .enable_64b_mode
- isync
-
- /* Copy some CPU settings from CPU 0 */
- bl .__restore_cpu_setup
-
- /* Set up a paca value for this processor. Since we have the
- * physical cpu id in r24, we need to search the pacas to find
- * which logical id maps to our physical one.
- */
- LOADADDR(r13, paca) /* Get base vaddr of paca array */
- li r5,0 /* logical cpu id */
-1: lhz r6,PACAHWCPUID(r13) /* Load HW procid from paca */
- cmpw r6,r24 /* Compare to our id */
- beq 2f
- addi r13,r13,PACA_SIZE /* Loop to next PACA on miss */
- addi r5,r5,1
- cmpwi r5,NR_CPUS
- blt 1b
-
- mr r3,r24 /* not found, copy phys to r3 */
- b .kexec_wait /* next kernel might do better */
-
-2: mtspr SPRG3,r13 /* Save vaddr of paca in SPRG3 */
- /* From now on, r24 is expected to be logical cpuid */
- mr r24,r5
-3: HMT_LOW
- lbz r23,PACAPROCSTART(r13) /* Test if this processor should */
- /* start. */
- sync
-
- /* Create a temp kernel stack for use before relocation is on. */
- ld r1,PACAEMERGSP(r13)
- subi r1,r1,STACK_FRAME_OVERHEAD
-
- cmpwi 0,r23,0
-#ifdef CONFIG_SMP
- bne .__secondary_start
-#endif
- b 3b /* Loop until told to go */
-
-#ifdef CONFIG_PPC_ISERIES
-_STATIC(__start_initialization_iSeries)
- /* Clear out the BSS */
- LOADADDR(r11,__bss_stop)
- LOADADDR(r8,__bss_start)
- sub r11,r11,r8 /* bss size */
- addi r11,r11,7 /* round up to an even double word */
- rldicl. r11,r11,61,3 /* shift right by 3 */
- beq 4f
- addi r8,r8,-8
- li r0,0
- mtctr r11 /* zero this many doublewords */
-3: stdu r0,8(r8)
- bdnz 3b
-4:
- LOADADDR(r1,init_thread_union)
- addi r1,r1,THREAD_SIZE
- li r0,0
- stdu r0,-STACK_FRAME_OVERHEAD(r1)
-
- LOADADDR(r3,cpu_specs)
- LOADADDR(r4,cur_cpu_spec)
- li r5,0
- bl .identify_cpu
-
- LOADADDR(r2,__toc_start)
- addi r2,r2,0x4000
- addi r2,r2,0x4000
-
- bl .iSeries_early_setup
-
- /* relocation is on at this point */
-
- b .start_here_common
-#endif /* CONFIG_PPC_ISERIES */
-
-#ifdef CONFIG_PPC_MULTIPLATFORM
-
-_STATIC(__mmu_off)
- mfmsr r3
- andi. r0,r3,MSR_IR|MSR_DR
- beqlr
- andc r3,r3,r0
- mtspr SPRN_SRR0,r4
- mtspr SPRN_SRR1,r3
- sync
- rfid
- b . /* prevent speculative execution */
-
-
-/*
- * Here is our main kernel entry point. We support currently 2 kind of entries
- * depending on the value of r5.
- *
- * r5 != NULL -> OF entry, we go to prom_init, "legacy" parameter content
- * in r3...r7
- *
- * r5 == NULL -> kexec style entry. r3 is a physical pointer to the
- * DT block, r4 is a physical pointer to the kernel itself
- *
- */
-_GLOBAL(__start_initialization_multiplatform)
- /*
- * Are we booted from a PROM Of-type client-interface ?
- */
- cmpldi cr0,r5,0
- bne .__boot_from_prom /* yes -> prom */
-
- /* Save parameters */
- mr r31,r3
- mr r30,r4
-
- /* Make sure we are running in 64 bits mode */
- bl .enable_64b_mode
-
- /* Setup some critical 970 SPRs before switching MMU off */
- bl .__970_cpu_preinit
-
- /* cpu # */
- li r24,0
-
- /* Switch off MMU if not already */
- LOADADDR(r4, .__after_prom_start - KERNELBASE)
- add r4,r4,r30
- bl .__mmu_off
- b .__after_prom_start
-
-_STATIC(__boot_from_prom)
- /* Save parameters */
- mr r31,r3
- mr r30,r4
- mr r29,r5
- mr r28,r6
- mr r27,r7
-
- /* Make sure we are running in 64 bits mode */
- bl .enable_64b_mode
-
- /* put a relocation offset into r3 */
- bl .reloc_offset
-
- LOADADDR(r2,__toc_start)
- addi r2,r2,0x4000
- addi r2,r2,0x4000
-
- /* Relocate the TOC from a virt addr to a real addr */
- sub r2,r2,r3
-
- /* Restore parameters */
- mr r3,r31
- mr r4,r30
- mr r5,r29
- mr r6,r28
- mr r7,r27
-
- /* Do all of the interaction with OF client interface */
- bl .prom_init
- /* We never return */
- trap
-
-/*
- * At this point, r3 contains the physical address we are running at,
- * returned by prom_init()
- */
-_STATIC(__after_prom_start)
-
-/*
- * We need to run with __start at physical address 0.
- * This will leave some code in the first 256B of
- * real memory, which are reserved for software use.
- * The remainder of the first page is loaded with the fixed
- * interrupt vectors. The next two pages are filled with
- * unknown exception placeholders.
- *
- * Note: This process overwrites the OF exception vectors.
- * r26 == relocation offset
- * r27 == KERNELBASE
- */
- bl .reloc_offset
- mr r26,r3
- SET_REG_TO_CONST(r27,KERNELBASE)
-
- li r3,0 /* target addr */
-
- // XXX FIXME: Use phys returned by OF (r30)
- sub r4,r27,r26 /* source addr */
- /* current address of _start */
- /* i.e. where we are running */
- /* the source addr */
-
- LOADADDR(r5,copy_to_here) /* # bytes of memory to copy */
- sub r5,r5,r27
-
- li r6,0x100 /* Start offset, the first 0x100 */
- /* bytes were copied earlier. */
-
- bl .copy_and_flush /* copy the first n bytes */
- /* this includes the code being */
- /* executed here. */
-
- LOADADDR(r0, 4f) /* Jump to the copy of this code */
- mtctr r0 /* that we just made/relocated */
- bctr
-
-4: LOADADDR(r5,klimit)
- sub r5,r5,r26
- ld r5,0(r5) /* get the value of klimit */
- sub r5,r5,r27
- bl .copy_and_flush /* copy the rest */
- b .start_here_multiplatform
-
-#endif /* CONFIG_PPC_MULTIPLATFORM */
-
-/*
- * Copy routine used to copy the kernel to start at physical address 0
- * and flush and invalidate the caches as needed.
- * r3 = dest addr, r4 = source addr, r5 = copy limit, r6 = start offset
- * on exit, r3, r4, r5 are unchanged, r6 is updated to be >= r5.
- *
- * Note: this routine *only* clobbers r0, r6 and lr
- */
-_GLOBAL(copy_and_flush)
- addi r5,r5,-8
- addi r6,r6,-8
-4: li r0,16 /* Use the least common */
- /* denominator cache line */
- /* size. This results in */
- /* extra cache line flushes */
- /* but operation is correct. */
- /* Can't get cache line size */
- /* from NACA as it is being */
- /* moved too. */
-
- mtctr r0 /* put # words/line in ctr */
-3: addi r6,r6,8 /* copy a cache line */
- ldx r0,r6,r4
- stdx r0,r6,r3
- bdnz 3b
- dcbst r6,r3 /* write it to memory */
- sync
- icbi r6,r3 /* flush the icache line */
- cmpld 0,r6,r5
- blt 4b
- sync
- addi r5,r5,8
- addi r6,r6,8
- blr
-
-.align 8
-copy_to_here:
-
-#ifdef CONFIG_SMP
-#ifdef CONFIG_PPC_PMAC
-/*
- * On PowerMac, secondary processors starts from the reset vector, which
- * is temporarily turned into a call to one of the functions below.
- */
- .section ".text";
- .align 2 ;
-
- .globl pmac_secondary_start_1
-pmac_secondary_start_1:
- li r24, 1
- b .pmac_secondary_start
-
- .globl pmac_secondary_start_2
-pmac_secondary_start_2:
- li r24, 2
- b .pmac_secondary_start
-
- .globl pmac_secondary_start_3
-pmac_secondary_start_3:
- li r24, 3
- b .pmac_secondary_start
-
-_GLOBAL(pmac_secondary_start)
- /* turn on 64-bit mode */
- bl .enable_64b_mode
- isync
-
- /* Copy some CPU settings from CPU 0 */
- bl .__restore_cpu_setup
-
- /* pSeries do that early though I don't think we really need it */
- mfmsr r3
- ori r3,r3,MSR_RI
- mtmsrd r3 /* RI on */
-
- /* Set up a paca value for this processor. */
- LOADADDR(r4, paca) /* Get base vaddr of paca array */
- mulli r13,r24,PACA_SIZE /* Calculate vaddr of right paca */
- add r13,r13,r4 /* for this processor. */
- mtspr SPRG3,r13 /* Save vaddr of paca in SPRG3 */
-
- /* Create a temp kernel stack for use before relocation is on. */
- ld r1,PACAEMERGSP(r13)
- subi r1,r1,STACK_FRAME_OVERHEAD
-
- b .__secondary_start
-
-#endif /* CONFIG_PPC_PMAC */
-
-/*
- * This function is called after the master CPU has released the
- * secondary processors. The execution environment is relocation off.
- * The paca for this processor has the following fields initialized at
- * this point:
- * 1. Processor number
- * 2. Segment table pointer (virtual address)
- * On entry the following are set:
- * r1 = stack pointer. vaddr for iSeries, raddr (temp stack) for pSeries
- * r24 = cpu# (in Linux terms)
- * r13 = paca virtual address
- * SPRG3 = paca virtual address
- */
-_GLOBAL(__secondary_start)
-
- HMT_MEDIUM /* Set thread priority to MEDIUM */
-
- ld r2,PACATOC(r13)
- li r6,0
- stb r6,PACAPROCENABLED(r13)
-
-#ifndef CONFIG_PPC_ISERIES
- /* Initialize the page table pointer register. */
- LOADADDR(r6,_SDR1)
- ld r6,0(r6) /* get the value of _SDR1 */
- mtspr SDR1,r6 /* set the htab location */
-#endif
- /* Initialize the first segment table (or SLB) entry */
- ld r3,PACASTABVIRT(r13) /* get addr of segment table */
- bl .stab_initialize
-
- /* Initialize the kernel stack. Just a repeat for iSeries. */
- LOADADDR(r3,current_set)
- sldi r28,r24,3 /* get current_set[cpu#] */
- ldx r1,r3,r28
- addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
- std r1,PACAKSAVE(r13)
-
- ld r3,PACASTABREAL(r13) /* get raddr of segment table */
- ori r4,r3,1 /* turn on valid bit */
-
-#ifdef CONFIG_PPC_ISERIES
- li r0,-1 /* hypervisor call */
- li r3,1
- sldi r3,r3,63 /* 0x8000000000000000 */
- ori r3,r3,4 /* 0x8000000000000004 */
- sc /* HvCall_setASR */
-#else
- /* set the ASR */
- ld r3,systemcfg@got(r2) /* r3 = ptr to systemcfg */
- ld r3,0(r3)
- lwz r3,PLATFORM(r3) /* r3 = platform flags */
- andi. r3,r3,PLATFORM_LPAR /* Test if bit 0 is set (LPAR bit) */
- beq 98f /* branch if result is 0 */
- mfspr r3,PVR
- srwi r3,r3,16
- cmpwi r3,0x37 /* SStar */
- beq 97f
- cmpwi r3,0x36 /* IStar */
- beq 97f
- cmpwi r3,0x34 /* Pulsar */
- bne 98f
-97: li r3,H_SET_ASR /* hcall = H_SET_ASR */
- HVSC /* Invoking hcall */
- b 99f
-98: /* !(rpa hypervisor) || !(star) */
- mtasr r4 /* set the stab location */
-99:
-#endif
- li r7,0
- mtlr r7
-
- /* enable MMU and jump to start_secondary */
- LOADADDR(r3,.start_secondary_prolog)
- SET_REG_TO_CONST(r4, MSR_KERNEL)
-#ifdef DO_SOFT_DISABLE
- ori r4,r4,MSR_EE
-#endif
- mtspr SRR0,r3
- mtspr SRR1,r4
- rfid
- b . /* prevent speculative execution */
-
-/*
- * Running with relocation on at this point. All we want to do is
- * zero the stack back-chain pointer before going into C code.
- */
-_GLOBAL(start_secondary_prolog)
- li r3,0
- std r3,0(r1) /* Zero the stack frame pointer */
- bl .start_secondary
-#endif
-
-/*
- * This subroutine clobbers r11 and r12
- */
-_GLOBAL(enable_64b_mode)
- mfmsr r11 /* grab the current MSR */
- li r12,1
- rldicr r12,r12,MSR_SF_LG,(63-MSR_SF_LG)
- or r11,r11,r12
- li r12,1
- rldicr r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG)
- or r11,r11,r12
- mtmsrd r11
- isync
- blr
-
-#ifdef CONFIG_PPC_MULTIPLATFORM
-/*
- * This is where the main kernel code starts.
- */
-_STATIC(start_here_multiplatform)
- /* get a new offset, now that the kernel has moved. */
- bl .reloc_offset
- mr r26,r3
-
- /* Clear out the BSS. It may have been done in prom_init,
- * already but that's irrelevant since prom_init will soon
- * be detached from the kernel completely. Besides, we need
- * to clear it now for kexec-style entry.
- */
- LOADADDR(r11,__bss_stop)
- LOADADDR(r8,__bss_start)
- sub r11,r11,r8 /* bss size */
- addi r11,r11,7 /* round up to an even double word */
- rldicl. r11,r11,61,3 /* shift right by 3 */
- beq 4f
- addi r8,r8,-8
- li r0,0
- mtctr r11 /* zero this many doublewords */
-3: stdu r0,8(r8)
- bdnz 3b
-4:
-
- mfmsr r6
- ori r6,r6,MSR_RI
- mtmsrd r6 /* RI on */
-
-#ifdef CONFIG_HMT
- /* Start up the second thread on cpu 0 */
- mfspr r3,PVR
- srwi r3,r3,16
- cmpwi r3,0x34 /* Pulsar */
- beq 90f
- cmpwi r3,0x36 /* Icestar */
- beq 90f
- cmpwi r3,0x37 /* SStar */
- beq 90f
- b 91f /* HMT not supported */
-90: li r3,0
- bl .hmt_start_secondary
-91:
-#endif
-
- /* The following gets the stack and TOC set up with the regs */
- /* pointing to the real addr of the kernel stack. This is */
- /* all done to support the C function call below which sets */
- /* up the htab. This is done because we have relocated the */
- /* kernel but are still running in real mode. */
-
- LOADADDR(r3,init_thread_union)
- sub r3,r3,r26
-
- /* set up a stack pointer (physical address) */
- addi r1,r3,THREAD_SIZE
- li r0,0
- stdu r0,-STACK_FRAME_OVERHEAD(r1)
-
- /* set up the TOC (physical address) */
- LOADADDR(r2,__toc_start)
- addi r2,r2,0x4000
- addi r2,r2,0x4000
- sub r2,r2,r26
-
- LOADADDR(r3,cpu_specs)
- sub r3,r3,r26
- LOADADDR(r4,cur_cpu_spec)
- sub r4,r4,r26
- mr r5,r26
- bl .identify_cpu
-
- /* Save some low level config HIDs of CPU0 to be copied to
- * other CPUs later on, or used for suspend/resume
- */
- bl .__save_cpu_setup
- sync
-
- /* Setup a valid physical PACA pointer in SPRG3 for early_setup
- * note that boot_cpuid can always be 0 nowadays since there is
- * nowhere it can be initialized differently before we reach this
- * code
- */
- LOADADDR(r27, boot_cpuid)
- sub r27,r27,r26
- lwz r27,0(r27)
-
- LOADADDR(r24, paca) /* Get base vaddr of paca array */
- mulli r13,r27,PACA_SIZE /* Calculate vaddr of right paca */
- add r13,r13,r24 /* for this processor. */
- sub r13,r13,r26 /* convert to physical addr */
- mtspr SPRG3,r13 /* PPPBBB: Temp... -Peter */
-
- /* Do very early kernel initializations, including initial hash table,
- * stab and slb setup before we turn on relocation. */
-
- /* Restore parameters passed from prom_init/kexec */
- mr r3,r31
- bl .early_setup
-
- /* set the ASR */
- ld r3,PACASTABREAL(r13)
- ori r4,r3,1 /* turn on valid bit */
- ld r3,systemcfg@got(r2) /* r3 = ptr to systemcfg */
- ld r3,0(r3)
- lwz r3,PLATFORM(r3) /* r3 = platform flags */
- andi. r3,r3,PLATFORM_LPAR /* Test if bit 0 is set (LPAR bit) */
- beq 98f /* branch if result is 0 */
- mfspr r3,PVR
- srwi r3,r3,16
- cmpwi r3,0x37 /* SStar */
- beq 97f
- cmpwi r3,0x36 /* IStar */
- beq 97f
- cmpwi r3,0x34 /* Pulsar */
- bne 98f
-97: li r3,H_SET_ASR /* hcall = H_SET_ASR */
- HVSC /* Invoking hcall */
- b 99f
-98: /* !(rpa hypervisor) || !(star) */
- mtasr r4 /* set the stab location */
-99:
- /* Set SDR1 (hash table pointer) */
- ld r3,systemcfg@got(r2) /* r3 = ptr to systemcfg */
- ld r3,0(r3)
- lwz r3,PLATFORM(r3) /* r3 = platform flags */
- /* Test if bit 0 is set (LPAR bit) */
- andi. r3,r3,PLATFORM_LPAR
- bne 98f /* branch if result is !0 */
- LOADADDR(r6,_SDR1) /* Only if NOT LPAR */
- sub r6,r6,r26
- ld r6,0(r6) /* get the value of _SDR1 */
- mtspr SDR1,r6 /* set the htab location */
-98:
- LOADADDR(r3,.start_here_common)
- SET_REG_TO_CONST(r4, MSR_KERNEL)
- mtspr SRR0,r3
- mtspr SRR1,r4
- rfid
- b . /* prevent speculative execution */
-#endif /* CONFIG_PPC_MULTIPLATFORM */
-
- /* This is where all platforms converge execution */
-_STATIC(start_here_common)
- /* relocation is on at this point */
-
- /* The following code sets up the SP and TOC now that we are */
- /* running with translation enabled. */
-
- LOADADDR(r3,init_thread_union)
-
- /* set up the stack */
- addi r1,r3,THREAD_SIZE
- li r0,0
- stdu r0,-STACK_FRAME_OVERHEAD(r1)
-
- /* Apply the CPUs-specific fixups (nop out sections not relevant
- * to this CPU
- */
- li r3,0
- bl .do_cpu_ftr_fixups
-
- LOADADDR(r26, boot_cpuid)
- lwz r26,0(r26)
-
- LOADADDR(r24, paca) /* Get base vaddr of paca array */
- mulli r13,r26,PACA_SIZE /* Calculate vaddr of right paca */
- add r13,r13,r24 /* for this processor. */
- mtspr SPRG3,r13
-
- /* ptr to current */
- LOADADDR(r4,init_task)
- std r4,PACACURRENT(r13)
-
- /* Load the TOC */
- ld r2,PACATOC(r13)
- std r1,PACAKSAVE(r13)
-
- bl .setup_system
-
- /* Load up the kernel context */
-5:
-#ifdef DO_SOFT_DISABLE
- li r5,0
- stb r5,PACAPROCENABLED(r13) /* Soft Disabled */
- mfmsr r5
- ori r5,r5,MSR_EE /* Hard Enabled */
- mtmsrd r5
-#endif
-
- bl .start_kernel
-
-_GLOBAL(hmt_init)
-#ifdef CONFIG_HMT
- LOADADDR(r5, hmt_thread_data)
- mfspr r7,PVR
- srwi r7,r7,16
- cmpwi r7,0x34 /* Pulsar */
- beq 90f
- cmpwi r7,0x36 /* Icestar */
- beq 91f
- cmpwi r7,0x37 /* SStar */
- beq 91f
- b 101f
-90: mfspr r6,PIR
- andi. r6,r6,0x1f
- b 92f
-91: mfspr r6,PIR
- andi. r6,r6,0x3ff
-92: sldi r4,r24,3
- stwx r6,r5,r4
- bl .hmt_start_secondary
- b 101f
-
-__hmt_secondary_hold:
- LOADADDR(r5, hmt_thread_data)
- clrldi r5,r5,4
- li r7,0
- mfspr r6,PIR
- mfspr r8,PVR
- srwi r8,r8,16
- cmpwi r8,0x34
- bne 93f
- andi. r6,r6,0x1f
- b 103f
-93: andi. r6,r6,0x3f
-
-103: lwzx r8,r5,r7
- cmpw r8,r6
- beq 104f
- addi r7,r7,8
- b 103b
-
-104: addi r7,r7,4
- lwzx r9,r5,r7
- mr r24,r9
-101:
-#endif
- mr r3,r24
- b .pSeries_secondary_smp_init
-
-#ifdef CONFIG_HMT
-_GLOBAL(hmt_start_secondary)
- LOADADDR(r4,__hmt_secondary_hold)
- clrldi r4,r4,4
- mtspr NIADORM, r4
- mfspr r4, MSRDORM
- li r5, -65
- and r4, r4, r5
- mtspr MSRDORM, r4
- lis r4,0xffef
- ori r4,r4,0x7403
- mtspr TSC, r4
- li r4,0x1f4
- mtspr TST, r4
- mfspr r4, HID0
- ori r4, r4, 0x1
- mtspr HID0, r4
- mfspr r4, SPRN_CTRLF
- oris r4, r4, 0x40
- mtspr SPRN_CTRLT, r4
- blr
-#endif
-
-#if defined(CONFIG_KEXEC) || (defined(CONFIG_SMP) && !defined(CONFIG_PPC_ISERIES))
-_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.
- */
- li r3,1
- LOADADDR(r5,__secondary_hold_spinloop)
- std r3,0(r5)
- sync
- blr
-#endif /* CONFIG_SMP && !CONFIG_PPC_ISERIES */
-
-
-/*
- * We put a few things here that have to be page-aligned.
- * This stuff goes at the beginning of the bss, which is page-aligned.
- */
- .section ".bss"
-
- .align PAGE_SHIFT
-
- .globl empty_zero_page
-empty_zero_page:
- .space PAGE_SIZE
-
- .globl swapper_pg_dir
-swapper_pg_dir:
- .space PAGE_SIZE
-
-/*
- * This space gets a copy of optional info passed to us by the bootstrap
- * Used to pass parameters into the kernel like root=/dev/sda1, etc.
- */
- .globl cmd_line
-cmd_line:
- .space COMMAND_LINE_SIZE
diff --git a/trunk/arch/powerpc/kernel/head_8xx.S b/trunk/arch/powerpc/kernel/head_8xx.S
deleted file mode 100644
index cb1a3a54a026..000000000000
--- a/trunk/arch/powerpc/kernel/head_8xx.S
+++ /dev/null
@@ -1,860 +0,0 @@
-/*
- * arch/ppc/kernel/except_8xx.S
- *
- * PowerPC version
- * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
- * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
- * Copyright (C) 1996 Cort Dougan
- * Low-level exception handlers and MMU support
- * rewritten by Paul Mackerras.
- * Copyright (C) 1996 Paul Mackerras.
- * MPC8xx modifications by Dan Malek
- * Copyright (C) 1997 Dan Malek (dmalek@jlc.net).
- *
- * This file contains low-level support and setup for PowerPC 8xx
- * embedded processors, including trap and interrupt dispatch.
- *
- * 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
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-/* Macro to make the code more readable. */
-#ifdef CONFIG_8xx_CPU6
-#define DO_8xx_CPU6(val, reg) \
- li reg, val; \
- stw reg, 12(r0); \
- lwz reg, 12(r0);
-#else
-#define DO_8xx_CPU6(val, reg)
-#endif
- .text
- .globl _stext
-_stext:
- .text
- .globl _start
-_start:
-
-/* MPC8xx
- * This port was done on an MBX board with an 860. Right now I only
- * support an ELF compressed (zImage) boot from EPPC-Bug because the
- * code there loads up some registers before calling us:
- * r3: ptr to board info data
- * r4: initrd_start or if no initrd then 0
- * r5: initrd_end - unused if r4 is 0
- * r6: Start of command line string
- * r7: End of command line string
- *
- * I decided to use conditional compilation instead of checking PVR and
- * adding more processor specific branches around code I don't need.
- * Since this is an embedded processor, I also appreciate any memory
- * savings I can get.
- *
- * The MPC8xx does not have any BATs, but it supports large page sizes.
- * We first initialize the MMU to support 8M byte pages, then load one
- * entry into each of the instruction and data TLBs to map the first
- * 8M 1:1. I also mapped an additional I/O space 1:1 so we can get to
- * the "internal" processor registers before MMU_init is called.
- *
- * The TLB code currently contains a major hack. Since I use the condition
- * code register, I have to save and restore it. I am out of registers, so
- * I just store it in memory location 0 (the TLB handlers are not reentrant).
- * To avoid making any decisions, I need to use the "segment" valid bit
- * in the first level table, but that would require many changes to the
- * Linux page directory/table functions that I don't want to do right now.
- *
- * I used to use SPRG2 for a temporary register in the TLB handler, but it
- * has since been put to other uses. I now use a hack to save a register
- * and the CCR at memory location 0.....Someday I'll fix this.....
- * -- Dan
- */
- .globl __start
-__start:
- mr r31,r3 /* save parameters */
- mr r30,r4
- mr r29,r5
- mr r28,r6
- mr r27,r7
-
- /* We have to turn on the MMU right away so we get cache modes
- * set correctly.
- */
- bl initial_mmu
-
-/* We now have the lower 8 Meg mapped into TLB entries, and the caches
- * ready to work.
- */
-
-turn_on_mmu:
- mfmsr r0
- ori r0,r0,MSR_DR|MSR_IR
- mtspr SPRN_SRR1,r0
- lis r0,start_here@h
- ori r0,r0,start_here@l
- mtspr SPRN_SRR0,r0
- SYNC
- rfi /* enables MMU */
-
-/*
- * Exception entry code. This code runs with address translation
- * turned off, i.e. using physical addresses.
- * We assume sprg3 has the physical address of the current
- * task's thread_struct.
- */
-#define EXCEPTION_PROLOG \
- mtspr SPRN_SPRG0,r10; \
- mtspr SPRN_SPRG1,r11; \
- mfcr r10; \
- EXCEPTION_PROLOG_1; \
- EXCEPTION_PROLOG_2
-
-#define EXCEPTION_PROLOG_1 \
- mfspr r11,SPRN_SRR1; /* check whether user or kernel */ \
- andi. r11,r11,MSR_PR; \
- tophys(r11,r1); /* use tophys(r1) if kernel */ \
- beq 1f; \
- mfspr r11,SPRN_SPRG3; \
- lwz r11,THREAD_INFO-THREAD(r11); \
- addi r11,r11,THREAD_SIZE; \
- tophys(r11,r11); \
-1: subi r11,r11,INT_FRAME_SIZE /* alloc exc. frame */
-
-
-#define EXCEPTION_PROLOG_2 \
- CLR_TOP32(r11); \
- stw r10,_CCR(r11); /* save registers */ \
- stw r12,GPR12(r11); \
- stw r9,GPR9(r11); \
- mfspr r10,SPRN_SPRG0; \
- stw r10,GPR10(r11); \
- mfspr r12,SPRN_SPRG1; \
- stw r12,GPR11(r11); \
- mflr r10; \
- stw r10,_LINK(r11); \
- mfspr r12,SPRN_SRR0; \
- mfspr r9,SPRN_SRR1; \
- stw r1,GPR1(r11); \
- stw r1,0(r11); \
- tovirt(r1,r11); /* set new kernel sp */ \
- li r10,MSR_KERNEL & ~(MSR_IR|MSR_DR); /* can take exceptions */ \
- MTMSRD(r10); /* (except for mach check in rtas) */ \
- stw r0,GPR0(r11); \
- SAVE_4GPRS(3, r11); \
- SAVE_2GPRS(7, r11)
-
-/*
- * Note: code which follows this uses cr0.eq (set if from kernel),
- * r11, r12 (SRR0), and r9 (SRR1).
- *
- * Note2: once we have set r1 we are in a position to take exceptions
- * again, and we could thus set MSR:RI at that point.
- */
-
-/*
- * Exception vectors.
- */
-#define EXCEPTION(n, label, hdlr, xfer) \
- . = n; \
-label: \
- EXCEPTION_PROLOG; \
- addi r3,r1,STACK_FRAME_OVERHEAD; \
- xfer(n, hdlr)
-
-#define EXC_XFER_TEMPLATE(n, hdlr, trap, copyee, tfer, ret) \
- li r10,trap; \
- stw r10,TRAP(r11); \
- li r10,MSR_KERNEL; \
- copyee(r10, r9); \
- bl tfer; \
-i##n: \
- .long hdlr; \
- .long ret
-
-#define COPY_EE(d, s) rlwimi d,s,0,16,16
-#define NOCOPY(d, s)
-
-#define EXC_XFER_STD(n, hdlr) \
- EXC_XFER_TEMPLATE(n, hdlr, n, NOCOPY, transfer_to_handler_full, \
- ret_from_except_full)
-
-#define EXC_XFER_LITE(n, hdlr) \
- EXC_XFER_TEMPLATE(n, hdlr, n+1, NOCOPY, transfer_to_handler, \
- ret_from_except)
-
-#define EXC_XFER_EE(n, hdlr) \
- EXC_XFER_TEMPLATE(n, hdlr, n, COPY_EE, transfer_to_handler_full, \
- ret_from_except_full)
-
-#define EXC_XFER_EE_LITE(n, hdlr) \
- EXC_XFER_TEMPLATE(n, hdlr, n+1, COPY_EE, transfer_to_handler, \
- ret_from_except)
-
-/* System reset */
- EXCEPTION(0x100, Reset, UnknownException, EXC_XFER_STD)
-
-/* Machine check */
- . = 0x200
-MachineCheck:
- EXCEPTION_PROLOG
- mfspr r4,SPRN_DAR
- stw r4,_DAR(r11)
- mfspr r5,SPRN_DSISR
- stw r5,_DSISR(r11)
- addi r3,r1,STACK_FRAME_OVERHEAD
- EXC_XFER_STD(0x200, MachineCheckException)
-
-/* Data access exception.
- * This is "never generated" by the MPC8xx. We jump to it for other
- * translation errors.
- */
- . = 0x300
-DataAccess:
- EXCEPTION_PROLOG
- mfspr r10,SPRN_DSISR
- stw r10,_DSISR(r11)
- mr r5,r10
- mfspr r4,SPRN_DAR
- EXC_XFER_EE_LITE(0x300, handle_page_fault)
-
-/* Instruction access exception.
- * This is "never generated" by the MPC8xx. We jump to it for other
- * translation errors.
- */
- . = 0x400
-InstructionAccess:
- EXCEPTION_PROLOG
- mr r4,r12
- mr r5,r9
- EXC_XFER_EE_LITE(0x400, handle_page_fault)
-
-/* External interrupt */
- EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE)
-
-/* Alignment exception */
- . = 0x600
-Alignment:
- EXCEPTION_PROLOG
- mfspr r4,SPRN_DAR
- stw r4,_DAR(r11)
- mfspr r5,SPRN_DSISR
- stw r5,_DSISR(r11)
- addi r3,r1,STACK_FRAME_OVERHEAD
- EXC_XFER_EE(0x600, AlignmentException)
-
-/* Program check exception */
- EXCEPTION(0x700, ProgramCheck, ProgramCheckException, EXC_XFER_STD)
-
-/* No FPU on MPC8xx. This exception is not supposed to happen.
-*/
- EXCEPTION(0x800, FPUnavailable, UnknownException, EXC_XFER_STD)
-
-/* Decrementer */
- EXCEPTION(0x900, Decrementer, timer_interrupt, EXC_XFER_LITE)
-
- EXCEPTION(0xa00, Trap_0a, UnknownException, EXC_XFER_EE)
- EXCEPTION(0xb00, Trap_0b, UnknownException, EXC_XFER_EE)
-
-/* System call */
- . = 0xc00
-SystemCall:
- EXCEPTION_PROLOG
- EXC_XFER_EE_LITE(0xc00, DoSyscall)
-
-/* Single step - not used on 601 */
- EXCEPTION(0xd00, SingleStep, SingleStepException, EXC_XFER_STD)
- EXCEPTION(0xe00, Trap_0e, UnknownException, EXC_XFER_EE)
- EXCEPTION(0xf00, Trap_0f, UnknownException, EXC_XFER_EE)
-
-/* On the MPC8xx, this is a software emulation interrupt. It occurs
- * for all unimplemented and illegal instructions.
- */
- EXCEPTION(0x1000, SoftEmu, SoftwareEmulation, EXC_XFER_STD)
-
- . = 0x1100
-/*
- * For the MPC8xx, this is a software tablewalk to load the instruction
- * TLB. It is modelled after the example in the Motorola manual. The task
- * switch loads the M_TWB register with the pointer to the first level table.
- * If we discover there is no second level table (value is zero) or if there
- * is an invalid pte, we load that into the TLB, which causes another fault
- * into the TLB Error interrupt where we can handle such problems.
- * We have to use the MD_xxx registers for the tablewalk because the
- * equivalent MI_xxx registers only perform the attribute functions.
- */
-InstructionTLBMiss:
-#ifdef CONFIG_8xx_CPU6
- stw r3, 8(r0)
-#endif
- DO_8xx_CPU6(0x3f80, r3)
- mtspr SPRN_M_TW, r10 /* Save a couple of working registers */
- mfcr r10
- stw r10, 0(r0)
- stw r11, 4(r0)
- mfspr r10, SPRN_SRR0 /* Get effective address of fault */
- DO_8xx_CPU6(0x3780, r3)
- mtspr SPRN_MD_EPN, r10 /* Have to use MD_EPN for walk, MI_EPN can't */
- mfspr r10, SPRN_M_TWB /* Get level 1 table entry address */
-
- /* If we are faulting a kernel address, we have to use the
- * kernel page tables.
- */
- andi. r11, r10, 0x0800 /* Address >= 0x80000000 */
- beq 3f
- lis r11, swapper_pg_dir@h
- ori r11, r11, swapper_pg_dir@l
- rlwimi r10, r11, 0, 2, 19
-3:
- lwz r11, 0(r10) /* Get the level 1 entry */
- rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */
- beq 2f /* If zero, don't try to find a pte */
-
- /* We have a pte table, so load the MI_TWC with the attributes
- * for this "segment."
- */
- ori r11,r11,1 /* Set valid bit */
- DO_8xx_CPU6(0x2b80, r3)
- mtspr SPRN_MI_TWC, r11 /* Set segment attributes */
- DO_8xx_CPU6(0x3b80, r3)
- mtspr SPRN_MD_TWC, r11 /* Load pte table base address */
- mfspr r11, SPRN_MD_TWC /* ....and get the pte address */
- lwz r10, 0(r11) /* Get the pte */
-
- ori r10, r10, _PAGE_ACCESSED
- stw r10, 0(r11)
-
- /* The Linux PTE won't go exactly into the MMU TLB.
- * Software indicator bits 21, 22 and 28 must be clear.
- * Software indicator bits 24, 25, 26, and 27 must be
- * set. All other Linux PTE bits control the behavior
- * of the MMU.
- */
-2: li r11, 0x00f0
- rlwimi r10, r11, 0, 24, 28 /* Set 24-27, clear 28 */
- DO_8xx_CPU6(0x2d80, r3)
- mtspr SPRN_MI_RPN, r10 /* Update TLB entry */
-
- mfspr r10, SPRN_M_TW /* Restore registers */
- lwz r11, 0(r0)
- mtcr r11
- lwz r11, 4(r0)
-#ifdef CONFIG_8xx_CPU6
- lwz r3, 8(r0)
-#endif
- rfi
-
- . = 0x1200
-DataStoreTLBMiss:
-#ifdef CONFIG_8xx_CPU6
- stw r3, 8(r0)
-#endif
- DO_8xx_CPU6(0x3f80, r3)
- mtspr SPRN_M_TW, r10 /* Save a couple of working registers */
- mfcr r10
- stw r10, 0(r0)
- stw r11, 4(r0)
- mfspr r10, SPRN_M_TWB /* Get level 1 table entry address */
-
- /* If we are faulting a kernel address, we have to use the
- * kernel page tables.
- */
- andi. r11, r10, 0x0800
- beq 3f
- lis r11, swapper_pg_dir@h
- ori r11, r11, swapper_pg_dir@l
- rlwimi r10, r11, 0, 2, 19
-3:
- lwz r11, 0(r10) /* Get the level 1 entry */
- rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */
- beq 2f /* If zero, don't try to find a pte */
-
- /* We have a pte table, so load fetch the pte from the table.
- */
- ori r11, r11, 1 /* Set valid bit in physical L2 page */
- DO_8xx_CPU6(0x3b80, r3)
- mtspr SPRN_MD_TWC, r11 /* Load pte table base address */
- mfspr r10, SPRN_MD_TWC /* ....and get the pte address */
- lwz r10, 0(r10) /* Get the pte */
-
- /* Insert the Guarded flag into the TWC from the Linux PTE.
- * It is bit 27 of both the Linux PTE and the TWC (at least
- * I got that right :-). It will be better when we can put
- * this into the Linux pgd/pmd and load it in the operation
- * above.
- */
- rlwimi r11, r10, 0, 27, 27
- DO_8xx_CPU6(0x3b80, r3)
- mtspr SPRN_MD_TWC, r11
-
- mfspr r11, SPRN_MD_TWC /* get the pte address again */
- ori r10, r10, _PAGE_ACCESSED
- stw r10, 0(r11)
-
- /* The Linux PTE won't go exactly into the MMU TLB.
- * Software indicator bits 21, 22 and 28 must be clear.
- * Software indicator bits 24, 25, 26, and 27 must be
- * set. All other Linux PTE bits control the behavior
- * of the MMU.
- */
-2: li r11, 0x00f0
- rlwimi r10, r11, 0, 24, 28 /* Set 24-27, clear 28 */
- DO_8xx_CPU6(0x3d80, r3)
- mtspr SPRN_MD_RPN, r10 /* Update TLB entry */
-
- mfspr r10, SPRN_M_TW /* Restore registers */
- lwz r11, 0(r0)
- mtcr r11
- lwz r11, 4(r0)
-#ifdef CONFIG_8xx_CPU6
- lwz r3, 8(r0)
-#endif
- rfi
-
-/* This is an instruction TLB error on the MPC8xx. This could be due
- * to many reasons, such as executing guarded memory or illegal instruction
- * addresses. There is nothing to do but handle a big time error fault.
- */
- . = 0x1300
-InstructionTLBError:
- b InstructionAccess
-
-/* This is the data TLB error on the MPC8xx. This could be due to
- * many reasons, including a dirty update to a pte. We can catch that
- * one here, but anything else is an error. First, we track down the
- * Linux pte. If it is valid, write access is allowed, but the
- * page dirty bit is not set, we will set it and reload the TLB. For
- * any other case, we bail out to a higher level function that can
- * handle it.
- */
- . = 0x1400
-DataTLBError:
-#ifdef CONFIG_8xx_CPU6
- stw r3, 8(r0)
-#endif
- DO_8xx_CPU6(0x3f80, r3)
- mtspr SPRN_M_TW, r10 /* Save a couple of working registers */
- mfcr r10
- stw r10, 0(r0)
- stw r11, 4(r0)
-
- /* First, make sure this was a store operation.
- */
- mfspr r10, SPRN_DSISR
- andis. r11, r10, 0x0200 /* If set, indicates store op */
- beq 2f
-
- /* The EA of a data TLB miss is automatically stored in the MD_EPN
- * register. The EA of a data TLB error is automatically stored in
- * the DAR, but not the MD_EPN register. We must copy the 20 most
- * significant bits of the EA from the DAR to MD_EPN before we
- * start walking the page tables. We also need to copy the CASID
- * value from the M_CASID register.
- * Addendum: The EA of a data TLB error is _supposed_ to be stored
- * in DAR, but it seems that this doesn't happen in some cases, such
- * as when the error is due to a dcbi instruction to a page with a
- * TLB that doesn't have the changed bit set. In such cases, there
- * does not appear to be any way to recover the EA of the error
- * since it is neither in DAR nor MD_EPN. As a workaround, the
- * _PAGE_HWWRITE bit is set for all kernel data pages when the PTEs
- * are initialized in mapin_ram(). This will avoid the problem,
- * assuming we only use the dcbi instruction on kernel addresses.
- */
- mfspr r10, SPRN_DAR
- rlwinm r11, r10, 0, 0, 19
- ori r11, r11, MD_EVALID
- mfspr r10, SPRN_M_CASID
- rlwimi r11, r10, 0, 28, 31
- DO_8xx_CPU6(0x3780, r3)
- mtspr SPRN_MD_EPN, r11
-
- mfspr r10, SPRN_M_TWB /* Get level 1 table entry address */
-
- /* If we are faulting a kernel address, we have to use the
- * kernel page tables.
- */
- andi. r11, r10, 0x0800
- beq 3f
- lis r11, swapper_pg_dir@h
- ori r11, r11, swapper_pg_dir@l
- rlwimi r10, r11, 0, 2, 19
-3:
- lwz r11, 0(r10) /* Get the level 1 entry */
- rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */
- beq 2f /* If zero, bail */
-
- /* We have a pte table, so fetch the pte from the table.
- */
- ori r11, r11, 1 /* Set valid bit in physical L2 page */
- DO_8xx_CPU6(0x3b80, r3)
- mtspr SPRN_MD_TWC, r11 /* Load pte table base address */
- mfspr r11, SPRN_MD_TWC /* ....and get the pte address */
- lwz r10, 0(r11) /* Get the pte */
-
- andi. r11, r10, _PAGE_RW /* Is it writeable? */
- beq 2f /* Bail out if not */
-
- /* Update 'changed', among others.
- */
- ori r10, r10, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE
- mfspr r11, SPRN_MD_TWC /* Get pte address again */
- stw r10, 0(r11) /* and update pte in table */
-
- /* The Linux PTE won't go exactly into the MMU TLB.
- * Software indicator bits 21, 22 and 28 must be clear.
- * Software indicator bits 24, 25, 26, and 27 must be
- * set. All other Linux PTE bits control the behavior
- * of the MMU.
- */
- li r11, 0x00f0
- rlwimi r10, r11, 0, 24, 28 /* Set 24-27, clear 28 */
- DO_8xx_CPU6(0x3d80, r3)
- mtspr SPRN_MD_RPN, r10 /* Update TLB entry */
-
- mfspr r10, SPRN_M_TW /* Restore registers */
- lwz r11, 0(r0)
- mtcr r11
- lwz r11, 4(r0)
-#ifdef CONFIG_8xx_CPU6
- lwz r3, 8(r0)
-#endif
- rfi
-2:
- mfspr r10, SPRN_M_TW /* Restore registers */
- lwz r11, 0(r0)
- mtcr r11
- lwz r11, 4(r0)
-#ifdef CONFIG_8xx_CPU6
- lwz r3, 8(r0)
-#endif
- b DataAccess
-
- EXCEPTION(0x1500, Trap_15, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1600, Trap_16, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1700, Trap_17, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1800, Trap_18, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1900, Trap_19, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1a00, Trap_1a, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1b00, Trap_1b, UnknownException, EXC_XFER_EE)
-
-/* On the MPC8xx, these next four traps are used for development
- * support of breakpoints and such. Someday I will get around to
- * using them.
- */
- EXCEPTION(0x1c00, Trap_1c, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1d00, Trap_1d, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1e00, Trap_1e, UnknownException, EXC_XFER_EE)
- EXCEPTION(0x1f00, Trap_1f, UnknownException, EXC_XFER_EE)
-
- . = 0x2000
-
- .globl giveup_fpu
-giveup_fpu:
- blr
-
-/*
- * This is where the main kernel code starts.
- */
-start_here:
- /* ptr to current */
- lis r2,init_task@h
- ori r2,r2,init_task@l
-
- /* ptr to phys current thread */
- tophys(r4,r2)
- addi r4,r4,THREAD /* init task's THREAD */
- mtspr SPRN_SPRG3,r4
- li r3,0
- mtspr SPRN_SPRG2,r3 /* 0 => r1 has kernel sp */
-
- /* stack */
- lis r1,init_thread_union@ha
- addi r1,r1,init_thread_union@l
- li r0,0
- stwu r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1)
-
- bl early_init /* We have to do this with MMU on */
-
-/*
- * Decide what sort of machine this is and initialize the MMU.
- */
- mr r3,r31
- mr r4,r30
- mr r5,r29
- mr r6,r28
- mr r7,r27
- bl machine_init
- bl MMU_init
-
-/*
- * Go back to running unmapped so we can load up new values
- * and change to using our exception vectors.
- * On the 8xx, all we have to do is invalidate the TLB to clear
- * the old 8M byte TLB mappings and load the page table base register.
- */
- /* The right way to do this would be to track it down through
- * init's THREAD like the context switch code does, but this is
- * easier......until someone changes init's static structures.
- */
- lis r6, swapper_pg_dir@h
- ori r6, r6, swapper_pg_dir@l
- tophys(r6,r6)
-#ifdef CONFIG_8xx_CPU6
- lis r4, cpu6_errata_word@h
- ori r4, r4, cpu6_errata_word@l
- li r3, 0x3980
- stw r3, 12(r4)
- lwz r3, 12(r4)
-#endif
- mtspr SPRN_M_TWB, r6
- lis r4,2f@h
- ori r4,r4,2f@l
- tophys(r4,r4)
- li r3,MSR_KERNEL & ~(MSR_IR|MSR_DR)
- mtspr SPRN_SRR0,r4
- mtspr SPRN_SRR1,r3
- rfi
-/* Load up the kernel context */
-2:
- SYNC /* Force all PTE updates to finish */
- tlbia /* Clear all TLB entries */
- sync /* wait for tlbia/tlbie to finish */
- TLBSYNC /* ... on all CPUs */
-
- /* set up the PTE pointers for the Abatron bdiGDB.
- */
- tovirt(r6,r6)
- lis r5, abatron_pteptrs@h
- ori r5, r5, abatron_pteptrs@l
- stw r5, 0xf0(r0) /* Must match your Abatron config file */
- tophys(r5,r5)
- stw r6, 0(r5)
-
-/* Now turn on the MMU for real! */
- li r4,MSR_KERNEL
- lis r3,start_kernel@h
- ori r3,r3,start_kernel@l
- mtspr SPRN_SRR0,r3
- mtspr SPRN_SRR1,r4
- rfi /* enable MMU and jump to start_kernel */
-
-/* Set up the initial MMU state so we can do the first level of
- * kernel initialization. This maps the first 8 MBytes of memory 1:1
- * virtual to physical. Also, set the cache mode since that is defined
- * by TLB entries and perform any additional mapping (like of the IMMR).
- * If configured to pin some TLBs, we pin the first 8 Mbytes of kernel,
- * 24 Mbytes of data, and the 8M IMMR space. Anything not covered by
- * these mappings is mapped by page tables.
- */
-initial_mmu:
- tlbia /* Invalidate all TLB entries */
-#ifdef CONFIG_PIN_TLB
- lis r8, MI_RSV4I@h
- ori r8, r8, 0x1c00
-#else
- li r8, 0
-#endif
- mtspr SPRN_MI_CTR, r8 /* Set instruction MMU control */
-
-#ifdef CONFIG_PIN_TLB
- lis r10, (MD_RSV4I | MD_RESETVAL)@h
- ori r10, r10, 0x1c00
- mr r8, r10
-#else
- lis r10, MD_RESETVAL@h
-#endif
-#ifndef CONFIG_8xx_COPYBACK
- oris r10, r10, MD_WTDEF@h
-#endif
- mtspr SPRN_MD_CTR, r10 /* Set data TLB control */
-
- /* Now map the lower 8 Meg into the TLBs. For this quick hack,
- * we can load the instruction and data TLB registers with the
- * same values.
- */
- lis r8, KERNELBASE@h /* Create vaddr for TLB */
- ori r8, r8, MI_EVALID /* Mark it valid */
- mtspr SPRN_MI_EPN, r8
- mtspr SPRN_MD_EPN, r8
- li r8, MI_PS8MEG /* Set 8M byte page */
- ori r8, r8, MI_SVALID /* Make it valid */
- mtspr SPRN_MI_TWC, r8
- mtspr SPRN_MD_TWC, r8
- li r8, MI_BOOTINIT /* Create RPN for address 0 */
- mtspr SPRN_MI_RPN, r8 /* Store TLB entry */
- mtspr SPRN_MD_RPN, r8
- lis r8, MI_Kp@h /* Set the protection mode */
- mtspr SPRN_MI_AP, r8
- mtspr SPRN_MD_AP, r8
-
- /* Map another 8 MByte at the IMMR to get the processor
- * internal registers (among other things).
- */
-#ifdef CONFIG_PIN_TLB
- addi r10, r10, 0x0100
- mtspr SPRN_MD_CTR, r10
-#endif
- mfspr r9, 638 /* Get current IMMR */
- andis. r9, r9, 0xff80 /* Get 8Mbyte boundary */
-
- mr r8, r9 /* Create vaddr for TLB */
- ori r8, r8, MD_EVALID /* Mark it valid */
- mtspr SPRN_MD_EPN, r8
- li r8, MD_PS8MEG /* Set 8M byte page */
- ori r8, r8, MD_SVALID /* Make it valid */
- mtspr SPRN_MD_TWC, r8
- mr r8, r9 /* Create paddr for TLB */
- ori r8, r8, MI_BOOTINIT|0x2 /* Inhibit cache -- Cort */
- mtspr SPRN_MD_RPN, r8
-
-#ifdef CONFIG_PIN_TLB
- /* Map two more 8M kernel data pages.
- */
- addi r10, r10, 0x0100
- mtspr SPRN_MD_CTR, r10
-
- lis r8, KERNELBASE@h /* Create vaddr for TLB */
- addis r8, r8, 0x0080 /* Add 8M */
- ori r8, r8, MI_EVALID /* Mark it valid */
- mtspr SPRN_MD_EPN, r8
- li r9, MI_PS8MEG /* Set 8M byte page */
- ori r9, r9, MI_SVALID /* Make it valid */
- mtspr SPRN_MD_TWC, r9
- li r11, MI_BOOTINIT /* Create RPN for address 0 */
- addis r11, r11, 0x0080 /* Add 8M */
- mtspr SPRN_MD_RPN, r8
-
- addis r8, r8, 0x0080 /* Add 8M */
- mtspr SPRN_MD_EPN, r8
- mtspr SPRN_MD_TWC, r9
- addis r11, r11, 0x0080 /* Add 8M */
- mtspr SPRN_MD_RPN, r8
-#endif
-
- /* Since the cache is enabled according to the information we
- * just loaded into the TLB, invalidate and enable the caches here.
- * We should probably check/set other modes....later.
- */
- lis r8, IDC_INVALL@h
- mtspr SPRN_IC_CST, r8
- mtspr SPRN_DC_CST, r8
- lis r8, IDC_ENABLE@h
- mtspr SPRN_IC_CST, r8
-#ifdef CONFIG_8xx_COPYBACK
- mtspr SPRN_DC_CST, r8
-#else
- /* For a debug option, I left this here to easily enable
- * the write through cache mode
- */
- lis r8, DC_SFWT@h
- mtspr SPRN_DC_CST, r8
- lis r8, IDC_ENABLE@h
- mtspr SPRN_DC_CST, r8
-#endif
- blr
-
-
-/*
- * Set up to use a given MMU context.
- * r3 is context number, r4 is PGD pointer.
- *
- * We place the physical address of the new task page directory loaded
- * into the MMU base register, and set the ASID compare register with
- * the new "context."
- */
-_GLOBAL(set_context)
-
-#ifdef CONFIG_BDI_SWITCH
- /* Context switch the PTE pointer for the Abatron BDI2000.
- * The PGDIR is passed as second argument.
- */
- lis r5, KERNELBASE@h
- lwz r5, 0xf0(r5)
- stw r4, 0x4(r5)
-#endif
-
-#ifdef CONFIG_8xx_CPU6
- lis r6, cpu6_errata_word@h
- ori r6, r6, cpu6_errata_word@l
- tophys (r4, r4)
- li r7, 0x3980
- stw r7, 12(r6)
- lwz r7, 12(r6)
- mtspr SPRN_M_TWB, r4 /* Update MMU base address */
- li r7, 0x3380
- stw r7, 12(r6)
- lwz r7, 12(r6)
- mtspr SPRN_M_CASID, r3 /* Update context */
-#else
- mtspr SPRN_M_CASID,r3 /* Update context */
- tophys (r4, r4)
- mtspr SPRN_M_TWB, r4 /* and pgd */
-#endif
- SYNC
- blr
-
-#ifdef CONFIG_8xx_CPU6
-/* It's here because it is unique to the 8xx.
- * It is important we get called with interrupts disabled. I used to
- * do that, but it appears that all code that calls this already had
- * interrupt disabled.
- */
- .globl set_dec_cpu6
-set_dec_cpu6:
- lis r7, cpu6_errata_word@h
- ori r7, r7, cpu6_errata_word@l
- li r4, 0x2c00
- stw r4, 8(r7)
- lwz r4, 8(r7)
- mtspr 22, r3 /* Update Decrementer */
- SYNC
- blr
-#endif
-
-/*
- * We put a few things here that have to be page-aligned.
- * This stuff goes at the beginning of the data segment,
- * which is page-aligned.
- */
- .data
- .globl sdata
-sdata:
- .globl empty_zero_page
-empty_zero_page:
- .space 4096
-
- .globl swapper_pg_dir
-swapper_pg_dir:
- .space 4096
-
-/*
- * This space gets a copy of optional info passed to us by the bootstrap
- * Used to pass parameters into the kernel like root=/dev/sda1, etc.
- */
- .globl cmd_line
-cmd_line:
- .space 512
-
-/* Room for two PTE table poiners, usually the kernel and current user
- * pointer to their respective root page table (pgdir).
- */
-abatron_pteptrs:
- .space 8
-
-#ifdef CONFIG_8xx_CPU6
- .globl cpu6_errata_word
-cpu6_errata_word:
- .space 16
-#endif
-
diff --git a/trunk/arch/powerpc/kernel/head_fsl_booke.S b/trunk/arch/powerpc/kernel/head_fsl_booke.S
deleted file mode 100644
index eba5a5f8ff08..000000000000
--- a/trunk/arch/powerpc/kernel/head_fsl_booke.S
+++ /dev/null
@@ -1,1058 +0,0 @@
-/*
- * arch/ppc/kernel/head_fsl_booke.S
- *
- * Kernel execution entry point code.
- *
- * Copyright (c) 1995-1996 Gary Thomas
- * Initial PowerPC version.
- * Copyright (c) 1996 Cort Dougan
- * Rewritten for PReP
- * Copyright (c) 1996 Paul Mackerras
- * Low-level exception handers, MMU support, and rewrite.
- * Copyright (c) 1997 Dan Malek
- * PowerPC 8xx modifications.
- * Copyright (c) 1998-1999 TiVo, Inc.
- * PowerPC 403GCX modifications.
- * Copyright (c) 1999 Grant Erickson
- * PowerPC 403GCX/405GP modifications.
- * Copyright 2000 MontaVista Software Inc.
- * PPC405 modifications
- * PowerPC 403GCX/405GP modifications.
- * Author: MontaVista Software, Inc.
- * frank_rowand@mvista.com or source@mvista.com
- * debbie_chu@mvista.com
- * Copyright 2002-2004 MontaVista Software, Inc.
- * PowerPC 44x support, Matt Porter
- * Copyright 2004 Freescale Semiconductor, Inc
- * PowerPC e500 modifications, Kumar Gala
- *
- * 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
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include "head_booke.h"
-
-/* As with the other PowerPC ports, it is expected that when code
- * execution begins here, the following registers contain valid, yet
- * optional, information:
- *
- * r3 - Board info structure pointer (DRAM, frequency, MAC address, etc.)
- * r4 - Starting address of the init RAM disk
- * r5 - Ending address of the init RAM disk
- * r6 - Start of kernel command line string (e.g. "mem=128")
- * r7 - End of kernel command line string
- *
- */
- .text
-_GLOBAL(_stext)
-_GLOBAL(_start)
- /*
- * Reserve a word at a fixed location to store the address
- * of abatron_pteptrs
- */
- nop
-/*
- * Save parameters we are passed
- */
- mr r31,r3
- mr r30,r4
- mr r29,r5
- mr r28,r6
- mr r27,r7
- li r24,0 /* CPU number */
-
-/* We try to not make any assumptions about how the boot loader
- * setup or used the TLBs. We invalidate all mappings from the
- * boot loader and load a single entry in TLB1[0] to map the
- * first 16M of kernel memory. Any boot info passed from the
- * bootloader needs to live in this first 16M.
- *
- * Requirement on bootloader:
- * - The page we're executing in needs to reside in TLB1 and
- * have IPROT=1. If not an invalidate broadcast could
- * evict the entry we're currently executing in.
- *
- * r3 = Index of TLB1 were executing in
- * r4 = Current MSR[IS]
- * r5 = Index of TLB1 temp mapping
- *
- * Later in mapin_ram we will correctly map lowmem, and resize TLB1[0]
- * if needed
- */
-
-/* 1. Find the index of the entry we're executing in */
- bl invstr /* Find our address */
-invstr: mflr r6 /* Make it accessible */
- mfmsr r7
- rlwinm r4,r7,27,31,31 /* extract MSR[IS] */
- mfspr r7, SPRN_PID0
- slwi r7,r7,16
- or r7,r7,r4
- mtspr SPRN_MAS6,r7
- tlbsx 0,r6 /* search MSR[IS], SPID=PID0 */
-#ifndef CONFIG_E200
- mfspr r7,SPRN_MAS1
- andis. r7,r7,MAS1_VALID@h
- bne match_TLB
- mfspr r7,SPRN_PID1
- slwi r7,r7,16
- or r7,r7,r4
- mtspr SPRN_MAS6,r7
- tlbsx 0,r6 /* search MSR[IS], SPID=PID1 */
- mfspr r7,SPRN_MAS1
- andis. r7,r7,MAS1_VALID@h
- bne match_TLB
- mfspr r7, SPRN_PID2
- slwi r7,r7,16
- or r7,r7,r4
- mtspr SPRN_MAS6,r7
- tlbsx 0,r6 /* Fall through, we had to match */
-#endif
-match_TLB:
- mfspr r7,SPRN_MAS0
- rlwinm r3,r7,16,20,31 /* Extract MAS0(Entry) */
-
- mfspr r7,SPRN_MAS1 /* Insure IPROT set */
- oris r7,r7,MAS1_IPROT@h
- mtspr SPRN_MAS1,r7
- tlbwe
-
-/* 2. Invalidate all entries except the entry we're executing in */
- mfspr r9,SPRN_TLB1CFG
- andi. r9,r9,0xfff
- li r6,0 /* Set Entry counter to 0 */
-1: lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */
- rlwimi r7,r6,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r6) */
- mtspr SPRN_MAS0,r7
- tlbre
- mfspr r7,SPRN_MAS1
- rlwinm r7,r7,0,2,31 /* Clear MAS1 Valid and IPROT */
- cmpw r3,r6
- beq skpinv /* Dont update the current execution TLB */
- mtspr SPRN_MAS1,r7
- tlbwe
- isync
-skpinv: addi r6,r6,1 /* Increment */
- cmpw r6,r9 /* Are we done? */
- bne 1b /* If not, repeat */
-
- /* Invalidate TLB0 */
- li r6,0x04
- tlbivax 0,r6
-#ifdef CONFIG_SMP
- tlbsync
-#endif
- /* Invalidate TLB1 */
- li r6,0x0c
- tlbivax 0,r6
-#ifdef CONFIG_SMP
- tlbsync
-#endif
- msync
-
-/* 3. Setup a temp mapping and jump to it */
- andi. r5, r3, 0x1 /* Find an entry not used and is non-zero */
- addi r5, r5, 0x1
- lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */
- rlwimi r7,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */
- mtspr SPRN_MAS0,r7
- tlbre
-
- /* Just modify the entry ID and EPN for the temp mapping */
- lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */
- rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */
- mtspr SPRN_MAS0,r7
- xori r6,r4,1 /* Setup TMP mapping in the other Address space */
- slwi r6,r6,12
- oris r6,r6,(MAS1_VALID|MAS1_IPROT)@h
- ori r6,r6,(MAS1_TSIZE(BOOKE_PAGESZ_4K))@l
- mtspr SPRN_MAS1,r6
- mfspr r6,SPRN_MAS2
- li r7,0 /* temp EPN = 0 */
- rlwimi r7,r6,0,20,31
- mtspr SPRN_MAS2,r7
- tlbwe
-
- xori r6,r4,1
- slwi r6,r6,5 /* setup new context with other address space */
- bl 1f /* Find our address */
-1: mflr r9
- rlwimi r7,r9,0,20,31
- addi r7,r7,24
- mtspr SPRN_SRR0,r7
- mtspr SPRN_SRR1,r6
- rfi
-
-/* 4. Clear out PIDs & Search info */
- li r6,0
- mtspr SPRN_PID0,r6
-#ifndef CONFIG_E200
- mtspr SPRN_PID1,r6
- mtspr SPRN_PID2,r6
-#endif
- mtspr SPRN_MAS6,r6
-
-/* 5. Invalidate mapping we started in */
- lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */
- rlwimi r7,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */
- mtspr SPRN_MAS0,r7
- tlbre
- li r6,0
- mtspr SPRN_MAS1,r6
- tlbwe
- /* Invalidate TLB1 */
- li r9,0x0c
- tlbivax 0,r9
-#ifdef CONFIG_SMP
- tlbsync
-#endif
- msync
-
-/* 6. Setup KERNELBASE mapping in TLB1[0] */
- lis r6,0x1000 /* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */
- mtspr SPRN_MAS0,r6
- lis r6,(MAS1_VALID|MAS1_IPROT)@h
- ori r6,r6,(MAS1_TSIZE(BOOKE_PAGESZ_16M))@l
- mtspr SPRN_MAS1,r6
- li r7,0
- lis r6,KERNELBASE@h
- ori r6,r6,KERNELBASE@l
- rlwimi r6,r7,0,20,31
- mtspr SPRN_MAS2,r6
- li r7,(MAS3_SX|MAS3_SW|MAS3_SR)
- mtspr SPRN_MAS3,r7
- tlbwe
-
-/* 7. Jump to KERNELBASE mapping */
- lis r7,MSR_KERNEL@h
- ori r7,r7,MSR_KERNEL@l
- bl 1f /* Find our address */
-1: mflr r9
- rlwimi r6,r9,0,20,31
- addi r6,r6,24
- mtspr SPRN_SRR0,r6
- mtspr SPRN_SRR1,r7
- rfi /* start execution out of TLB1[0] entry */
-
-/* 8. Clear out the temp mapping */
- lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */
- rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */
- mtspr SPRN_MAS0,r7
- tlbre
- mtspr SPRN_MAS1,r8
- tlbwe
- /* Invalidate TLB1 */
- li r9,0x0c
- tlbivax 0,r9
-#ifdef CONFIG_SMP
- tlbsync
-#endif
- msync
-
- /* Establish the interrupt vector offsets */
- SET_IVOR(0, CriticalInput);
- SET_IVOR(1, MachineCheck);
- SET_IVOR(2, DataStorage);
- SET_IVOR(3, InstructionStorage);
- SET_IVOR(4, ExternalInput);
- SET_IVOR(5, Alignment);
- SET_IVOR(6, Program);
- SET_IVOR(7, FloatingPointUnavailable);
- SET_IVOR(8, SystemCall);
- SET_IVOR(9, AuxillaryProcessorUnavailable);
- SET_IVOR(10, Decrementer);
- SET_IVOR(11, FixedIntervalTimer);
- SET_IVOR(12, WatchdogTimer);
- SET_IVOR(13, DataTLBError);
- SET_IVOR(14, InstructionTLBError);
- SET_IVOR(15, Debug);
- SET_IVOR(32, SPEUnavailable);
- SET_IVOR(33, SPEFloatingPointData);
- SET_IVOR(34, SPEFloatingPointRound);
-#ifndef CONFIG_E200
- SET_IVOR(35, PerformanceMonitor);
-#endif
-
- /* Establish the interrupt vector base */
- lis r4,interrupt_base@h /* IVPR only uses the high 16-bits */
- mtspr SPRN_IVPR,r4
-
- /* Setup the defaults for TLB entries */
- li r2,(MAS4_TSIZED(BOOKE_PAGESZ_4K))@l
-#ifdef CONFIG_E200
- oris r2,r2,MAS4_TLBSELD(1)@h
-#endif
- mtspr SPRN_MAS4, r2
-
-#if 0
- /* Enable DOZE */
- mfspr r2,SPRN_HID0
- oris r2,r2,HID0_DOZE@h
- mtspr SPRN_HID0, r2
-#endif
-#ifdef CONFIG_E200
- /* enable dedicated debug exception handling resources (Debug APU) */
- mfspr r2,SPRN_HID0
- ori r2,r2,HID0_DAPUEN@l
- mtspr SPRN_HID0,r2
-#endif
-
-#if !defined(CONFIG_BDI_SWITCH)
- /*
- * The Abatron BDI JTAG debugger does not tolerate others
- * mucking with the debug registers.
- */
- lis r2,DBCR0_IDM@h
- mtspr SPRN_DBCR0,r2
- /* clear any residual debug events */
- li r2,-1
- mtspr SPRN_DBSR,r2
-#endif
-
- /*
- * This is where the main kernel code starts.
- */
-
- /* ptr to current */
- lis r2,init_task@h
- ori r2,r2,init_task@l
-
- /* ptr to current thread */
- addi r4,r2,THREAD /* init task's THREAD */
- mtspr SPRN_SPRG3,r4
-
- /* stack */
- lis r1,init_thread_union@h
- ori r1,r1,init_thread_union@l
- li r0,0
- stwu r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1)
-
- bl early_init
-
- mfspr r3,SPRN_TLB1CFG
- andi. r3,r3,0xfff
- lis r4,num_tlbcam_entries@ha
- stw r3,num_tlbcam_entries@l(r4)
-/*
- * Decide what sort of machine this is and initialize the MMU.
- */
- mr r3,r31
- mr r4,r30
- mr r5,r29
- mr r6,r28
- mr r7,r27
- bl machine_init
- bl MMU_init
-
- /* Setup PTE pointers for the Abatron bdiGDB */
- lis r6, swapper_pg_dir@h
- ori r6, r6, swapper_pg_dir@l
- lis r5, abatron_pteptrs@h
- ori r5, r5, abatron_pteptrs@l
- lis r4, KERNELBASE@h
- ori r4, r4, KERNELBASE@l
- stw r5, 0(r4) /* Save abatron_pteptrs at a fixed location */
- stw r6, 0(r5)
-
- /* Let's move on */
- lis r4,start_kernel@h
- ori r4,r4,start_kernel@l
- lis r3,MSR_KERNEL@h
- ori r3,r3,MSR_KERNEL@l
- mtspr SPRN_SRR0,r4
- mtspr SPRN_SRR1,r3
- rfi /* change context and jump to start_kernel */
-
-/* Macros to hide the PTE size differences
- *
- * FIND_PTE -- walks the page tables given EA & pgdir pointer
- * r10 -- EA of fault
- * r11 -- PGDIR pointer
- * r12 -- free
- * label 2: is the bailout case
- *
- * if we find the pte (fall through):
- * r11 is low pte word
- * r12 is pointer to the pte
- */
-#ifdef CONFIG_PTE_64BIT
-#define PTE_FLAGS_OFFSET 4
-#define FIND_PTE \
- rlwinm r12, r10, 13, 19, 29; /* Compute pgdir/pmd offset */ \
- lwzx r11, r12, r11; /* Get pgd/pmd entry */ \
- rlwinm. r12, r11, 0, 0, 20; /* Extract pt base address */ \
- beq 2f; /* Bail if no table */ \
- rlwimi r12, r10, 23, 20, 28; /* Compute pte address */ \
- lwz r11, 4(r12); /* Get pte entry */
-#else
-#define PTE_FLAGS_OFFSET 0
-#define FIND_PTE \
- rlwimi r11, r10, 12, 20, 29; /* Create L1 (pgdir/pmd) address */ \
- lwz r11, 0(r11); /* Get L1 entry */ \
- rlwinm. r12, r11, 0, 0, 19; /* Extract L2 (pte) base address */ \
- beq 2f; /* Bail if no table */ \
- rlwimi r12, r10, 22, 20, 29; /* Compute PTE address */ \
- lwz r11, 0(r12); /* Get Linux PTE */
-#endif
-
-/*
- * Interrupt vector entry code
- *
- * The Book E MMUs are always on so we don't need to handle
- * interrupts in real mode as with previous PPC processors. In
- * this case we handle interrupts in the kernel virtual address
- * space.
- *
- * Interrupt vectors are dynamically placed relative to the
- * interrupt prefix as determined by the address of interrupt_base.
- * The interrupt vectors offsets are programmed using the labels
- * for each interrupt vector entry.
- *
- * Interrupt vectors must be aligned on a 16 byte boundary.
- * We align on a 32 byte cache line boundary for good measure.
- */
-
-interrupt_base:
- /* Critical Input Interrupt */
- CRITICAL_EXCEPTION(0x0100, CriticalInput, UnknownException)
-
- /* Machine Check Interrupt */
-#ifdef CONFIG_E200
- /* no RFMCI, MCSRRs on E200 */
- CRITICAL_EXCEPTION(0x0200, MachineCheck, MachineCheckException)
-#else
- MCHECK_EXCEPTION(0x0200, MachineCheck, MachineCheckException)
-#endif
-
- /* Data Storage Interrupt */
- START_EXCEPTION(DataStorage)
- mtspr SPRN_SPRG0, r10 /* Save some working registers */
- mtspr SPRN_SPRG1, r11
- mtspr SPRN_SPRG4W, r12
- mtspr SPRN_SPRG5W, r13
- mfcr r11
- mtspr SPRN_SPRG7W, r11
-
- /*
- * Check if it was a store fault, if not then bail
- * because a user tried to access a kernel or
- * read-protected page. Otherwise, get the
- * offending address and handle it.
- */
- mfspr r10, SPRN_ESR
- andis. r10, r10, ESR_ST@h
- beq 2f
-
- mfspr r10, SPRN_DEAR /* Get faulting address */
-
- /* If we are faulting a kernel address, we have to use the
- * kernel page tables.
- */
- lis r11, TASK_SIZE@h
- ori r11, r11, TASK_SIZE@l
- cmplw 0, r10, r11
- bge 2f
-
- /* Get the PGD for the current thread */
-3:
- mfspr r11,SPRN_SPRG3
- lwz r11,PGDIR(r11)
-4:
- FIND_PTE
-
- /* Are _PAGE_USER & _PAGE_RW set & _PAGE_HWWRITE not? */
- andi. r13, r11, _PAGE_RW|_PAGE_USER|_PAGE_HWWRITE
- cmpwi 0, r13, _PAGE_RW|_PAGE_USER
- bne 2f /* Bail if not */
-
- /* Update 'changed'. */
- ori r11, r11, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE
- stw r11, PTE_FLAGS_OFFSET(r12) /* Update Linux page table */
-
- /* MAS2 not updated as the entry does exist in the tlb, this
- fault taken to detect state transition (eg: COW -> DIRTY)
- */
- andi. r11, r11, _PAGE_HWEXEC
- rlwimi r11, r11, 31, 27, 27 /* SX <- _PAGE_HWEXEC */
- ori r11, r11, (MAS3_UW|MAS3_SW|MAS3_UR|MAS3_SR)@l /* set static perms */
-
- /* update search PID in MAS6, AS = 0 */
- mfspr r12, SPRN_PID0
- slwi r12, r12, 16
- mtspr SPRN_MAS6, r12
-
- /* find the TLB index that caused the fault. It has to be here. */
- tlbsx 0, r10
-
- /* only update the perm bits, assume the RPN is fine */
- mfspr r12, SPRN_MAS3
- rlwimi r12, r11, 0, 20, 31
- mtspr SPRN_MAS3,r12
- tlbwe
-
- /* Done...restore registers and get out of here. */
- mfspr r11, SPRN_SPRG7R
- mtcr r11
- mfspr r13, SPRN_SPRG5R
- mfspr r12, SPRN_SPRG4R
- mfspr r11, SPRN_SPRG1
- mfspr r10, SPRN_SPRG0
- rfi /* Force context change */
-
-2:
- /*
- * The bailout. Restore registers to pre-exception conditions
- * and call the heavyweights to help us out.
- */
- mfspr r11, SPRN_SPRG7R
- mtcr r11
- mfspr r13, SPRN_SPRG5R
- mfspr r12, SPRN_SPRG4R
- mfspr r11, SPRN_SPRG1
- mfspr r10, SPRN_SPRG0
- b data_access
-
- /* Instruction Storage Interrupt */
- INSTRUCTION_STORAGE_EXCEPTION
-
- /* External Input Interrupt */
- EXCEPTION(0x0500, ExternalInput, do_IRQ, EXC_XFER_LITE)
-
- /* Alignment Interrupt */
- ALIGNMENT_EXCEPTION
-
- /* Program Interrupt */
- PROGRAM_EXCEPTION
-
- /* Floating Point Unavailable Interrupt */
-#ifdef CONFIG_PPC_FPU
- FP_UNAVAILABLE_EXCEPTION
-#else
-#ifdef CONFIG_E200
- /* E200 treats 'normal' floating point instructions as FP Unavail exception */
- EXCEPTION(0x0800, FloatingPointUnavailable, ProgramCheckException, EXC_XFER_EE)
-#else
- EXCEPTION(0x0800, FloatingPointUnavailable, UnknownException, EXC_XFER_EE)
-#endif
-#endif
-
- /* System Call Interrupt */
- START_EXCEPTION(SystemCall)
- NORMAL_EXCEPTION_PROLOG
- EXC_XFER_EE_LITE(0x0c00, DoSyscall)
-
- /* Auxillary Processor Unavailable Interrupt */
- EXCEPTION(0x2900, AuxillaryProcessorUnavailable, UnknownException, EXC_XFER_EE)
-
- /* Decrementer Interrupt */
- DECREMENTER_EXCEPTION
-
- /* Fixed Internal Timer Interrupt */
- /* TODO: Add FIT support */
- EXCEPTION(0x3100, FixedIntervalTimer, UnknownException, EXC_XFER_EE)
-
- /* Watchdog Timer Interrupt */
-#ifdef CONFIG_BOOKE_WDT
- CRITICAL_EXCEPTION(0x3200, WatchdogTimer, WatchdogException)
-#else
- CRITICAL_EXCEPTION(0x3200, WatchdogTimer, UnknownException)
-#endif
-
- /* Data TLB Error Interrupt */
- START_EXCEPTION(DataTLBError)
- mtspr SPRN_SPRG0, r10 /* Save some working registers */
- mtspr SPRN_SPRG1, r11
- mtspr SPRN_SPRG4W, r12
- mtspr SPRN_SPRG5W, r13
- mfcr r11
- mtspr SPRN_SPRG7W, r11
- mfspr r10, SPRN_DEAR /* Get faulting address */
-
- /* If we are faulting a kernel address, we have to use the
- * kernel page tables.
- */
- lis r11, TASK_SIZE@h
- ori r11, r11, TASK_SIZE@l
- cmplw 5, r10, r11
- blt 5, 3f
- lis r11, swapper_pg_dir@h
- ori r11, r11, swapper_pg_dir@l
-
- mfspr r12,SPRN_MAS1 /* Set TID to 0 */
- rlwinm r12,r12,0,16,1
- mtspr SPRN_MAS1,r12
-
- b 4f
-
- /* Get the PGD for the current thread */
-3:
- mfspr r11,SPRN_SPRG3
- lwz r11,PGDIR(r11)
-
-4:
- FIND_PTE
- andi. r13, r11, _PAGE_PRESENT /* Is the page present? */
- beq 2f /* Bail if not present */
-
-#ifdef CONFIG_PTE_64BIT
- lwz r13, 0(r12)
-#endif
- ori r11, r11, _PAGE_ACCESSED
- stw r11, PTE_FLAGS_OFFSET(r12)
-
- /* Jump to common tlb load */
- b finish_tlb_load
-2:
- /* The bailout. Restore registers to pre-exception conditions
- * and call the heavyweights to help us out.
- */
- mfspr r11, SPRN_SPRG7R
- mtcr r11
- mfspr r13, SPRN_SPRG5R
- mfspr r12, SPRN_SPRG4R
- mfspr r11, SPRN_SPRG1
- mfspr r10, SPRN_SPRG0
- b data_access
-
- /* Instruction TLB Error Interrupt */
- /*
- * Nearly the same as above, except we get our
- * information from different registers and bailout
- * to a different point.
- */
- START_EXCEPTION(InstructionTLBError)
- mtspr SPRN_SPRG0, r10 /* Save some working registers */
- mtspr SPRN_SPRG1, r11
- mtspr SPRN_SPRG4W, r12
- mtspr SPRN_SPRG5W, r13
- mfcr r11
- mtspr SPRN_SPRG7W, r11
- mfspr r10, SPRN_SRR0 /* Get faulting address */
-
- /* If we are faulting a kernel address, we have to use the
- * kernel page tables.
- */
- lis r11, TASK_SIZE@h
- ori r11, r11, TASK_SIZE@l
- cmplw 5, r10, r11
- blt 5, 3f
- lis r11, swapper_pg_dir@h
- ori r11, r11, swapper_pg_dir@l
-
- mfspr r12,SPRN_MAS1 /* Set TID to 0 */
- rlwinm r12,r12,0,16,1
- mtspr SPRN_MAS1,r12
-
- b 4f
-
- /* Get the PGD for the current thread */
-3:
- mfspr r11,SPRN_SPRG3
- lwz r11,PGDIR(r11)
-
-4:
- FIND_PTE
- andi. r13, r11, _PAGE_PRESENT /* Is the page present? */
- beq 2f /* Bail if not present */
-
-#ifdef CONFIG_PTE_64BIT
- lwz r13, 0(r12)
-#endif
- ori r11, r11, _PAGE_ACCESSED
- stw r11, PTE_FLAGS_OFFSET(r12)
-
- /* Jump to common TLB load point */
- b finish_tlb_load
-
-2:
- /* The bailout. Restore registers to pre-exception conditions
- * and call the heavyweights to help us out.
- */
- mfspr r11, SPRN_SPRG7R
- mtcr r11
- mfspr r13, SPRN_SPRG5R
- mfspr r12, SPRN_SPRG4R
- mfspr r11, SPRN_SPRG1
- mfspr r10, SPRN_SPRG0
- b InstructionStorage
-
-#ifdef CONFIG_SPE
- /* SPE Unavailable */
- START_EXCEPTION(SPEUnavailable)
- NORMAL_EXCEPTION_PROLOG
- bne load_up_spe
- addi r3,r1,STACK_FRAME_OVERHEAD
- EXC_XFER_EE_LITE(0x2010, KernelSPE)
-#else
- EXCEPTION(0x2020, SPEUnavailable, UnknownException, EXC_XFER_EE)
-#endif /* CONFIG_SPE */
-
- /* SPE Floating Point Data */
-#ifdef CONFIG_SPE
- EXCEPTION(0x2030, SPEFloatingPointData, SPEFloatingPointException, EXC_XFER_EE);
-#else
- EXCEPTION(0x2040, SPEFloatingPointData, UnknownException, EXC_XFER_EE)
-#endif /* CONFIG_SPE */
-
- /* SPE Floating Point Round */
- EXCEPTION(0x2050, SPEFloatingPointRound, UnknownException, EXC_XFER_EE)
-
- /* Performance Monitor */
- EXCEPTION(0x2060, PerformanceMonitor, PerformanceMonitorException, EXC_XFER_STD)
-
-
- /* Debug Interrupt */
- DEBUG_EXCEPTION
-
-/*
- * Local functions
- */
-
- /*
- * Data TLB exceptions will bail out to this point
- * if they can't resolve the lightweight TLB fault.
- */
-data_access:
- NORMAL_EXCEPTION_PROLOG
- mfspr r5,SPRN_ESR /* Grab the ESR, save it, pass arg3 */
- stw r5,_ESR(r11)
- mfspr r4,SPRN_DEAR /* Grab the DEAR, save it, pass arg2 */
- andis. r10,r5,(ESR_ILK|ESR_DLK)@h
- bne 1f
- EXC_XFER_EE_LITE(0x0300, handle_page_fault)
-1:
- addi r3,r1,STACK_FRAME_OVERHEAD
- EXC_XFER_EE_LITE(0x0300, CacheLockingException)
-
-/*
-
- * Both the instruction and data TLB miss get to this
- * point to load the TLB.
- * r10 - EA of fault
- * r11 - TLB (info from Linux PTE)
- * r12, r13 - available to use
- * CR5 - results of addr < TASK_SIZE
- * MAS0, MAS1 - loaded with proper value when we get here
- * MAS2, MAS3 - will need additional info from Linux PTE
- * Upon exit, we reload everything and RFI.
- */
-finish_tlb_load:
- /*
- * We set execute, because we don't have the granularity to
- * properly set this at the page level (Linux problem).
- * Many of these bits are software only. Bits we don't set
- * here we (properly should) assume have the appropriate value.
- */
-
- mfspr r12, SPRN_MAS2
-#ifdef CONFIG_PTE_64BIT
- rlwimi r12, r11, 26, 24, 31 /* extract ...WIMGE from pte */
-#else
- rlwimi r12, r11, 26, 27, 31 /* extract WIMGE from pte */
-#endif
- mtspr SPRN_MAS2, r12
-
- bge 5, 1f
-
- /* is user addr */
- andi. r12, r11, (_PAGE_USER | _PAGE_HWWRITE | _PAGE_HWEXEC)
- andi. r10, r11, _PAGE_USER /* Test for _PAGE_USER */
- srwi r10, r12, 1
- or r12, r12, r10 /* Copy user perms into supervisor */
- iseleq r12, 0, r12
- b 2f
-
- /* is kernel addr */
-1: rlwinm r12, r11, 31, 29, 29 /* Extract _PAGE_HWWRITE into SW */
- ori r12, r12, (MAS3_SX | MAS3_SR)
-
-#ifdef CONFIG_PTE_64BIT
-2: rlwimi r12, r13, 24, 0, 7 /* grab RPN[32:39] */
- rlwimi r12, r11, 24, 8, 19 /* grab RPN[40:51] */
- mtspr SPRN_MAS3, r12
-BEGIN_FTR_SECTION
- srwi r10, r13, 8 /* grab RPN[8:31] */
- mtspr SPRN_MAS7, r10
-END_FTR_SECTION_IFSET(CPU_FTR_BIG_PHYS)
-#else
-2: rlwimi r11, r12, 0, 20, 31 /* Extract RPN from PTE and merge with perms */
- mtspr SPRN_MAS3, r11
-#endif
-#ifdef CONFIG_E200
- /* Round robin TLB1 entries assignment */
- mfspr r12, SPRN_MAS0
-
- /* Extract TLB1CFG(NENTRY) */
- mfspr r11, SPRN_TLB1CFG
- andi. r11, r11, 0xfff
-
- /* Extract MAS0(NV) */
- andi. r13, r12, 0xfff
- addi r13, r13, 1
- cmpw 0, r13, r11
- addi r12, r12, 1
-
- /* check if we need to wrap */
- blt 7f
-
- /* wrap back to first free tlbcam entry */
- lis r13, tlbcam_index@ha
- lwz r13, tlbcam_index@l(r13)
- rlwimi r12, r13, 0, 20, 31
-7:
- mtspr SPRN_MAS0,r12
-#endif /* CONFIG_E200 */
-
- tlbwe
-
- /* Done...restore registers and get out of here. */
- mfspr r11, SPRN_SPRG7R
- mtcr r11
- mfspr r13, SPRN_SPRG5R
- mfspr r12, SPRN_SPRG4R
- mfspr r11, SPRN_SPRG1
- mfspr r10, SPRN_SPRG0
- rfi /* Force context change */
-
-#ifdef CONFIG_SPE
-/* Note that the SPE support is closely modeled after the AltiVec
- * support. Changes to one are likely to be applicable to the
- * other! */
-load_up_spe:
-/*
- * Disable SPE for the task which had SPE previously,
- * and save its SPE registers in its thread_struct.
- * Enables SPE for use in the kernel on return.
- * On SMP we know the SPE units are free, since we give it up every
- * switch. -- Kumar
- */
- mfmsr r5
- oris r5,r5,MSR_SPE@h
- mtmsr r5 /* enable use of SPE now */
- isync
-/*
- * For SMP, we don't do lazy SPE switching because it just gets too
- * horrendously complex, especially when a task switches from one CPU
- * to another. Instead we call giveup_spe in switch_to.
- */
-#ifndef CONFIG_SMP
- lis r3,last_task_used_spe@ha
- lwz r4,last_task_used_spe@l(r3)
- cmpi 0,r4,0
- beq 1f
- addi r4,r4,THREAD /* want THREAD of last_task_used_spe */
- SAVE_32EVRS(0,r10,r4)
- evxor evr10, evr10, evr10 /* clear out evr10 */
- evmwumiaa evr10, evr10, evr10 /* evr10 <- ACC = 0 * 0 + ACC */
- li r5,THREAD_ACC
- evstddx evr10, r4, r5 /* save off accumulator */
- lwz r5,PT_REGS(r4)
- lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5)
- lis r10,MSR_SPE@h
- andc r4,r4,r10 /* disable SPE for previous task */
- stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-1:
-#endif /* CONFIG_SMP */
- /* enable use of SPE after return */
- oris r9,r9,MSR_SPE@h
- mfspr r5,SPRN_SPRG3 /* current task's THREAD (phys) */
- li r4,1
- li r10,THREAD_ACC
- stw r4,THREAD_USED_SPE(r5)
- evlddx evr4,r10,r5
- evmra evr4,evr4
- REST_32EVRS(0,r10,r5)
-#ifndef CONFIG_SMP
- subi r4,r5,THREAD
- stw r4,last_task_used_spe@l(r3)
-#endif /* CONFIG_SMP */
- /* restore registers and return */
-2: REST_4GPRS(3, r11)
- lwz r10,_CCR(r11)
- REST_GPR(1, r11)
- mtcr r10
- lwz r10,_LINK(r11)
- mtlr r10
- REST_GPR(10, r11)
- mtspr SPRN_SRR1,r9
- mtspr SPRN_SRR0,r12
- REST_GPR(9, r11)
- REST_GPR(12, r11)
- lwz r11,GPR11(r11)
- SYNC
- rfi
-
-/*
- * SPE unavailable trap from kernel - print a message, but let
- * the task use SPE in the kernel until it returns to user mode.
- */
-KernelSPE:
- lwz r3,_MSR(r1)
- oris r3,r3,MSR_SPE@h
- stw r3,_MSR(r1) /* enable use of SPE after return */
- lis r3,87f@h
- ori r3,r3,87f@l
- mr r4,r2 /* current */
- lwz r5,_NIP(r1)
- bl printk
- b ret_from_except
-87: .string "SPE used in kernel (task=%p, pc=%x) \n"
- .align 4,0
-
-#endif /* CONFIG_SPE */
-
-/*
- * Global functions
- */
-
-/*
- * extern void loadcam_entry(unsigned int index)
- *
- * Load TLBCAM[index] entry in to the L2 CAM MMU
- */
-_GLOBAL(loadcam_entry)
- lis r4,TLBCAM@ha
- addi r4,r4,TLBCAM@l
- mulli r5,r3,20
- add r3,r5,r4
- lwz r4,0(r3)
- mtspr SPRN_MAS0,r4
- lwz r4,4(r3)
- mtspr SPRN_MAS1,r4
- lwz r4,8(r3)
- mtspr SPRN_MAS2,r4
- lwz r4,12(r3)
- mtspr SPRN_MAS3,r4
- tlbwe
- isync
- blr
-
-/*
- * extern void giveup_altivec(struct task_struct *prev)
- *
- * The e500 core does not have an AltiVec unit.
- */
-_GLOBAL(giveup_altivec)
- blr
-
-#ifdef CONFIG_SPE
-/*
- * extern void giveup_spe(struct task_struct *prev)
- *
- */
-_GLOBAL(giveup_spe)
- mfmsr r5
- oris r5,r5,MSR_SPE@h
- SYNC
- mtmsr r5 /* enable use of SPE now */
- isync
- cmpi 0,r3,0
- beqlr- /* if no previous owner, done */
- addi r3,r3,THREAD /* want THREAD of task */
- lwz r5,PT_REGS(r3)
- cmpi 0,r5,0
- SAVE_32EVRS(0, r4, r3)
- evxor evr6, evr6, evr6 /* clear out evr6 */
- evmwumiaa evr6, evr6, evr6 /* evr6 <- ACC = 0 * 0 + ACC */
- li r4,THREAD_ACC
- evstddx evr6, r4, r3 /* save off accumulator */
- mfspr r6,SPRN_SPEFSCR
- stw r6,THREAD_SPEFSCR(r3) /* save spefscr register value */
- beq 1f
- lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5)
- lis r3,MSR_SPE@h
- andc r4,r4,r3 /* disable SPE for previous task */
- stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-1:
-#ifndef CONFIG_SMP
- li r5,0
- lis r4,last_task_used_spe@ha
- stw r5,last_task_used_spe@l(r4)
-#endif /* CONFIG_SMP */
- blr
-#endif /* CONFIG_SPE */
-
-/*
- * extern void giveup_fpu(struct task_struct *prev)
- *
- * Not all FSL Book-E cores have an FPU
- */
-#ifndef CONFIG_PPC_FPU
-_GLOBAL(giveup_fpu)
- blr
-#endif
-
-/*
- * extern void abort(void)
- *
- * At present, this routine just applies a system reset.
- */
-_GLOBAL(abort)
- li r13,0
- mtspr SPRN_DBCR0,r13 /* disable all debug events */
- mfmsr r13
- ori r13,r13,MSR_DE@l /* Enable Debug Events */
- mtmsr r13
- mfspr r13,SPRN_DBCR0
- lis r13,(DBCR0_IDM|DBCR0_RST_CHIP)@h
- mtspr SPRN_DBCR0,r13
-
-_GLOBAL(set_context)
-
-#ifdef CONFIG_BDI_SWITCH
- /* Context switch the PTE pointer for the Abatron BDI2000.
- * The PGDIR is the second parameter.
- */
- lis r5, abatron_pteptrs@h
- ori r5, r5, abatron_pteptrs@l
- stw r4, 0x4(r5)
-#endif
- mtspr SPRN_PID,r3
- isync /* Force context change */
- blr
-
-/*
- * We put a few things here that have to be page-aligned. This stuff
- * goes at the beginning of the data segment, which is page-aligned.
- */
- .data
-_GLOBAL(sdata)
-_GLOBAL(empty_zero_page)
- .space 4096
-_GLOBAL(swapper_pg_dir)
- .space 4096
-
-/* Reserved 4k for the critical exception stack & 4k for the machine
- * check stack per CPU for kernel mode exceptions */
- .section .bss
- .align 12
-exception_stack_bottom:
- .space BOOKE_EXCEPTION_STACK_SIZE * NR_CPUS
-_GLOBAL(exception_stack_top)
-
-/*
- * This space gets a copy of optional info passed to us by the bootstrap
- * which is used to pass parameters into the kernel like root=/dev/sda1, etc.
- */
-_GLOBAL(cmd_line)
- .space 512
-
-/*
- * Room for two PTE pointers, usually the kernel and current user pointers
- * to their respective root page table.
- */
-abatron_pteptrs:
- .space 8
-
diff --git a/trunk/arch/powerpc/kernel/idle_6xx.S b/trunk/arch/powerpc/kernel/idle_6xx.S
deleted file mode 100644
index 1a2194cf6828..000000000000
--- a/trunk/arch/powerpc/kernel/idle_6xx.S
+++ /dev/null
@@ -1,233 +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
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#undef DEBUG
-
- .text
-
-/*
- * Init idle, called at early CPU setup time from head.S for each CPU
- * Make sure no rest of NAP mode remains in HID0, save default
- * values for some CPU specific registers. Called with r24
- * containing CPU number and r3 reloc offset
- */
-_GLOBAL(init_idle_6xx)
-BEGIN_FTR_SECTION
- mfspr r4,SPRN_HID0
- rlwinm r4,r4,0,10,8 /* Clear NAP */
- mtspr SPRN_HID0, r4
- b 1f
-END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
- blr
-1:
- slwi r5,r24,2
- add r5,r5,r3
-BEGIN_FTR_SECTION
- mfspr r4,SPRN_MSSCR0
- addis r6,r5, nap_save_msscr0@ha
- stw r4,nap_save_msscr0@l(r6)
-END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR)
-BEGIN_FTR_SECTION
- mfspr r4,SPRN_HID1
- addis r6,r5,nap_save_hid1@ha
- stw r4,nap_save_hid1@l(r6)
-END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX)
- blr
-
-/*
- * 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(ppc6xx_idle)
- /* Check if we can nap or doze, put HID0 mask in r3
- */
- lis r3, 0
-BEGIN_FTR_SECTION
- lis r3,HID0_DOZE@h
-END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
-BEGIN_FTR_SECTION
- /* We must dynamically check for the NAP feature as it
- * can be cleared by CPU init after the fixups are done
- */
- lis r4,cur_cpu_spec@ha
- lwz r4,cur_cpu_spec@l(r4)
- lwz r4,CPU_SPEC_FEATURES(r4)
- andi. r0,r4,CPU_FTR_CAN_NAP
- beq 1f
- /* Now check if user or arch enabled NAP mode */
- lis r4,powersave_nap@ha
- lwz r4,powersave_nap@l(r4)
- cmpwi 0,r4,0
- beq 1f
- lis r3,HID0_NAP@h
-1:
-END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
- cmpwi 0,r3,0
- beqlr
-
- /* Clear MSR:EE */
- mfmsr r7
- rlwinm r0,r7,0,17,15
- mtmsr r0
-
- /* Check current_thread_info()->flags */
- rlwinm r4,r1,0,0,18
- lwz r4,TI_FLAGS(r4)
- andi. r0,r4,_TIF_NEED_RESCHED
- beq 1f
- mtmsr r7 /* out of line this ? */
- blr
-1:
- /* Some pre-nap cleanups needed on some CPUs */
- andis. r0,r3,HID0_NAP@h
- beq 2f
-BEGIN_FTR_SECTION
- /* Disable L2 prefetch on some 745x and try to ensure
- * L2 prefetch engines are idle. As explained by errata
- * text, we can't be sure they are, we just hope very hard
- * that well be enough (sic !). At least I noticed Apple
- * doesn't even bother doing the dcbf's here...
- */
- mfspr r4,SPRN_MSSCR0
- rlwinm r4,r4,0,0,29
- sync
- mtspr SPRN_MSSCR0,r4
- sync
- isync
- lis r4,KERNELBASE@h
- dcbf 0,r4
- dcbf 0,r4
- dcbf 0,r4
- dcbf 0,r4
-END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR)
-#ifdef DEBUG
- lis r6,nap_enter_count@ha
- lwz r4,nap_enter_count@l(r6)
- addi r4,r4,1
- stw r4,nap_enter_count@l(r6)
-#endif
-2:
-BEGIN_FTR_SECTION
- /* Go to low speed mode on some 750FX */
- lis r4,powersave_lowspeed@ha
- lwz r4,powersave_lowspeed@l(r4)
- cmpwi 0,r4,0
- beq 1f
- mfspr r4,SPRN_HID1
- oris r4,r4,0x0001
- mtspr SPRN_HID1,r4
-1:
-END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX)
-
- /* Go to NAP or DOZE now */
- mfspr r4,SPRN_HID0
- lis r5,(HID0_NAP|HID0_SLEEP)@h
-BEGIN_FTR_SECTION
- oris r5,r5,HID0_DOZE@h
-END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
- andc r4,r4,r5
- or r4,r4,r3
-BEGIN_FTR_SECTION
- oris r4,r4,HID0_DPM@h /* that should be done once for all */
-END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM)
- mtspr SPRN_HID0,r4
-BEGIN_FTR_SECTION
- DSSALL
- sync
-END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
- ori r7,r7,MSR_EE /* Could be ommited (already set) */
- oris r7,r7,MSR_POW@h
- sync
- isync
- mtmsr r7
- isync
- sync
- blr
-
-/*
- * Return from NAP/DOZE mode, restore some CPU specific registers,
- * we are called with DR/IR still off and r2 containing physical
- * address of current.
- */
-_GLOBAL(power_save_6xx_restore)
- mfspr r11,SPRN_HID0
- rlwinm. r11,r11,0,10,8 /* Clear NAP & copy NAP bit !state to cr1 EQ */
- cror 4*cr1+eq,4*cr0+eq,4*cr0+eq
-BEGIN_FTR_SECTION
- rlwinm r11,r11,0,9,7 /* Clear DOZE */
-END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
- mtspr SPRN_HID0, r11
-
-#ifdef DEBUG
- beq cr1,1f
- lis r11,(nap_return_count-KERNELBASE)@ha
- lwz r9,nap_return_count@l(r11)
- addi r9,r9,1
- stw r9,nap_return_count@l(r11)
-1:
-#endif
-
- rlwinm r9,r1,0,0,18
- tophys(r9,r9)
- lwz r11,TI_CPU(r9)
- slwi r11,r11,2
- /* Todo make sure all these are in the same page
- * and load r22 (@ha part + CPU offset) only once
- */
-BEGIN_FTR_SECTION
- beq cr1,1f
- addis r9,r11,(nap_save_msscr0-KERNELBASE)@ha
- lwz r9,nap_save_msscr0@l(r9)
- mtspr SPRN_MSSCR0, r9
- sync
- isync
-1:
-END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR)
-BEGIN_FTR_SECTION
- addis r9,r11,(nap_save_hid1-KERNELBASE)@ha
- lwz r9,nap_save_hid1@l(r9)
- mtspr SPRN_HID1, r9
-END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX)
- b transfer_to_handler_cont
-
- .data
-
-_GLOBAL(nap_save_msscr0)
- .space 4*NR_CPUS
-
-_GLOBAL(nap_save_hid1)
- .space 4*NR_CPUS
-
-_GLOBAL(powersave_nap)
- .long 0
-_GLOBAL(powersave_lowspeed)
- .long 0
-
-#ifdef DEBUG
-_GLOBAL(nap_enter_count)
- .space 4
-_GLOBAL(nap_return_count)
- .space 4
-#endif
diff --git a/trunk/arch/powerpc/kernel/process.c b/trunk/arch/powerpc/kernel/process.c
deleted file mode 100644
index f5a9d2a84fa1..000000000000
--- a/trunk/arch/powerpc/kernel/process.c
+++ /dev/null
@@ -1,724 +0,0 @@
-/*
- * arch/ppc/kernel/process.c
- *
- * Derived from "arch/i386/kernel/process.c"
- * Copyright (C) 1995 Linus Torvalds
- *
- * Updated and modified by Cort Dougan (cort@cs.nmt.edu) and
- * Paul Mackerras (paulus@cs.anu.edu.au)
- *
- * PowerPC version
- * 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.
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-extern unsigned long _get_SP(void);
-
-#ifndef CONFIG_SMP
-struct task_struct *last_task_used_math = NULL;
-struct task_struct *last_task_used_altivec = NULL;
-struct task_struct *last_task_used_spe = NULL;
-#endif
-
-static struct fs_struct init_fs = INIT_FS;
-static struct files_struct init_files = INIT_FILES;
-static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
-static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
-struct mm_struct init_mm = INIT_MM(init_mm);
-EXPORT_SYMBOL(init_mm);
-
-/* this is 8kB-aligned so we can get to the thread_info struct
- at the base of it from the stack pointer with 1 integer instruction. */
-union thread_union init_thread_union
- __attribute__((__section__(".data.init_task"))) =
-{ INIT_THREAD_INFO(init_task) };
-
-/* initial task structure */
-struct task_struct init_task = INIT_TASK(init_task);
-EXPORT_SYMBOL(init_task);
-
-/* only used to get secondary processor up */
-struct task_struct *current_set[NR_CPUS] = {&init_task, };
-
-/*
- * Make sure the floating-point register state in the
- * the thread_struct is up to date for task tsk.
- */
-void flush_fp_to_thread(struct task_struct *tsk)
-{
- if (tsk->thread.regs) {
- /*
- * We need to disable preemption here because if we didn't,
- * another process could get scheduled after the regs->msr
- * test but before we have finished saving the FP registers
- * to the thread_struct. That process could take over the
- * FPU, and then when we get scheduled again we would store
- * bogus values for the remaining FP registers.
- */
- preempt_disable();
- if (tsk->thread.regs->msr & MSR_FP) {
-#ifdef CONFIG_SMP
- /*
- * This should only ever be called for current or
- * for a stopped child process. Since we save away
- * the FP register state on context switch on SMP,
- * there is something wrong if a stopped child appears
- * to still have its FP state in the CPU registers.
- */
- BUG_ON(tsk != current);
-#endif
- giveup_fpu(current);
- }
- preempt_enable();
- }
-}
-
-void enable_kernel_fp(void)
-{
- WARN_ON(preemptible());
-
-#ifdef CONFIG_SMP
- if (current->thread.regs && (current->thread.regs->msr & MSR_FP))
- giveup_fpu(current);
- else
- giveup_fpu(NULL); /* just enables FP for kernel */
-#else
- giveup_fpu(last_task_used_math);
-#endif /* CONFIG_SMP */
-}
-EXPORT_SYMBOL(enable_kernel_fp);
-
-int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs)
-{
- if (!tsk->thread.regs)
- return 0;
- flush_fp_to_thread(current);
-
- memcpy(fpregs, &tsk->thread.fpr[0], sizeof(*fpregs));
-
- return 1;
-}
-
-#ifdef CONFIG_ALTIVEC
-void enable_kernel_altivec(void)
-{
- WARN_ON(preemptible());
-
-#ifdef CONFIG_SMP
- if (current->thread.regs && (current->thread.regs->msr & MSR_VEC))
- giveup_altivec(current);
- else
- giveup_altivec(NULL); /* just enable AltiVec for kernel - force */
-#else
- giveup_altivec(last_task_used_altivec);
-#endif /* CONFIG_SMP */
-}
-EXPORT_SYMBOL(enable_kernel_altivec);
-
-/*
- * Make sure the VMX/Altivec register state in the
- * the thread_struct is up to date for task tsk.
- */
-void flush_altivec_to_thread(struct task_struct *tsk)
-{
- if (tsk->thread.regs) {
- preempt_disable();
- if (tsk->thread.regs->msr & MSR_VEC) {
-#ifdef CONFIG_SMP
- BUG_ON(tsk != current);
-#endif
- giveup_altivec(current);
- }
- preempt_enable();
- }
-}
-
-int dump_task_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs)
-{
- flush_altivec_to_thread(current);
- memcpy(vrregs, ¤t->thread.vr[0], sizeof(*vrregs));
- return 1;
-}
-#endif /* CONFIG_ALTIVEC */
-
-#ifdef CONFIG_SPE
-
-void enable_kernel_spe(void)
-{
- WARN_ON(preemptible());
-
-#ifdef CONFIG_SMP
- if (current->thread.regs && (current->thread.regs->msr & MSR_SPE))
- giveup_spe(current);
- else
- giveup_spe(NULL); /* just enable SPE for kernel - force */
-#else
- giveup_spe(last_task_used_spe);
-#endif /* __SMP __ */
-}
-EXPORT_SYMBOL(enable_kernel_spe);
-
-void flush_spe_to_thread(struct task_struct *tsk)
-{
- if (tsk->thread.regs) {
- preempt_disable();
- if (tsk->thread.regs->msr & MSR_SPE) {
-#ifdef CONFIG_SMP
- BUG_ON(tsk != current);
-#endif
- giveup_spe(current);
- }
- preempt_enable();
- }
-}
-
-int dump_spe(struct pt_regs *regs, elf_vrregset_t *evrregs)
-{
- flush_spe_to_thread(current);
- /* We copy u32 evr[32] + u64 acc + u32 spefscr -> 35 */
- memcpy(evrregs, ¤t->thread.evr[0], sizeof(u32) * 35);
- return 1;
-}
-#endif /* CONFIG_SPE */
-
-static void set_dabr_spr(unsigned long val)
-{
- mtspr(SPRN_DABR, val);
-}
-
-int set_dabr(unsigned long dabr)
-{
- int ret = 0;
-
-#ifdef CONFIG_PPC64
- if (firmware_has_feature(FW_FEATURE_XDABR)) {
- /* We want to catch accesses from kernel and userspace */
- unsigned long flags = H_DABRX_KERNEL|H_DABRX_USER;
- ret = plpar_set_xdabr(dabr, flags);
- } else if (firmware_has_feature(FW_FEATURE_DABR)) {
- ret = plpar_set_dabr(dabr);
- } else
-#endif
- set_dabr_spr(dabr);
-
- return ret;
-}
-
-static DEFINE_PER_CPU(unsigned long, current_dabr);
-
-struct task_struct *__switch_to(struct task_struct *prev,
- struct task_struct *new)
-{
- struct thread_struct *new_thread, *old_thread;
- unsigned long flags;
- struct task_struct *last;
-
-#ifdef CONFIG_SMP
- /* avoid complexity of lazy save/restore of fpu
- * by just saving it every time we switch out if
- * this task used the fpu during the last quantum.
- *
- * If it tries to use the fpu again, it'll trap and
- * reload its fp regs. So we don't have to do a restore
- * every switch, just a save.
- * -- Cort
- */
- if (prev->thread.regs && (prev->thread.regs->msr & MSR_FP))
- giveup_fpu(prev);
-#ifdef CONFIG_ALTIVEC
- /*
- * If the previous thread used altivec in the last quantum
- * (thus changing altivec regs) then save them.
- * We used to check the VRSAVE register but not all apps
- * set it, so we don't rely on it now (and in fact we need
- * to save & restore VSCR even if VRSAVE == 0). -- paulus
- *
- * On SMP we always save/restore altivec regs just to avoid the
- * complexity of changing processors.
- * -- Cort
- */
- if (prev->thread.regs && (prev->thread.regs->msr & MSR_VEC))
- giveup_altivec(prev);
- /* Avoid the trap. On smp this this never happens since
- * we don't set last_task_used_altivec -- Cort
- */
- if (new->thread.regs && last_task_used_altivec == new)
- new->thread.regs->msr |= MSR_VEC;
-#endif /* CONFIG_ALTIVEC */
-#ifdef CONFIG_SPE
- /*
- * If the previous thread used spe in the last quantum
- * (thus changing spe regs) then save them.
- *
- * On SMP we always save/restore spe regs just to avoid the
- * complexity of changing processors.
- */
- if ((prev->thread.regs && (prev->thread.regs->msr & MSR_SPE)))
- giveup_spe(prev);
- /* Avoid the trap. On smp this this never happens since
- * we don't set last_task_used_spe
- */
- if (new->thread.regs && last_task_used_spe == new)
- new->thread.regs->msr |= MSR_SPE;
-#endif /* CONFIG_SPE */
-#endif /* CONFIG_SMP */
-
-#ifdef CONFIG_PPC64 /* for now */
- if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr)) {
- set_dabr(new->thread.dabr);
- __get_cpu_var(current_dabr) = new->thread.dabr;
- }
-#endif
-
- new_thread = &new->thread;
- old_thread = ¤t->thread;
- local_irq_save(flags);
- last = _switch(old_thread, new_thread);
-
- local_irq_restore(flags);
-
- return last;
-}
-
-void show_regs(struct pt_regs * regs)
-{
- int i, trap;
-
- printk("NIP: %08lX LR: %08lX SP: %08lX REGS: %p TRAP: %04lx %s\n",
- regs->nip, regs->link, regs->gpr[1], regs, regs->trap,
- print_tainted());
- printk("MSR: %08lx EE: %01x PR: %01x FP: %01x ME: %01x IR/DR: %01x%01x\n",
- regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0,
- regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0,
- regs->msr&MSR_IR ? 1 : 0,
- regs->msr&MSR_DR ? 1 : 0);
- trap = TRAP(regs);
- if (trap == 0x300 || trap == 0x600)
- printk("DAR: %08lX, DSISR: %08lX\n", regs->dar, regs->dsisr);
- printk("TASK = %p[%d] '%s' THREAD: %p\n",
- current, current->pid, current->comm, current->thread_info);
- printk("Last syscall: %ld ", current->thread.last_syscall);
-
-#ifdef CONFIG_SMP
- printk(" CPU: %d", smp_processor_id());
-#endif /* CONFIG_SMP */
-
- for (i = 0; i < 32; i++) {
- long r;
- if ((i % 8) == 0)
- printk("\n" KERN_INFO "GPR%02d: ", i);
- if (__get_user(r, ®s->gpr[i]))
- break;
- printk("%08lX ", r);
- if (i == 12 && !FULL_REGS(regs))
- break;
- }
- printk("\n");
-#ifdef CONFIG_KALLSYMS
- /*
- * Lookup NIP late so we have the best change of getting the
- * above info out without failing
- */
- printk("NIP [%08lx] ", regs->nip);
- print_symbol("%s\n", regs->nip);
- printk("LR [%08lx] ", regs->link);
- print_symbol("%s\n", regs->link);
-#endif
- show_stack(current, (unsigned long *) regs->gpr[1]);
-}
-
-void exit_thread(void)
-{
-#ifndef CONFIG_SMP
- if (last_task_used_math == current)
- last_task_used_math = NULL;
-#ifdef CONFIG_ALTIVEC
- if (last_task_used_altivec == current)
- last_task_used_altivec = NULL;
-#endif /* CONFIG_ALTIVEC */
-#ifdef CONFIG_SPE
- if (last_task_used_spe == current)
- last_task_used_spe = NULL;
-#endif
-#endif /* CONFIG_SMP */
-}
-
-void flush_thread(void)
-{
-#ifndef CONFIG_SMP
- if (last_task_used_math == current)
- last_task_used_math = NULL;
-#ifdef CONFIG_ALTIVEC
- if (last_task_used_altivec == current)
- last_task_used_altivec = NULL;
-#endif /* CONFIG_ALTIVEC */
-#ifdef CONFIG_SPE
- if (last_task_used_spe == current)
- last_task_used_spe = NULL;
-#endif
-#endif /* CONFIG_SMP */
-
-#ifdef CONFIG_PPC64 /* for now */
- if (current->thread.dabr) {
- current->thread.dabr = 0;
- set_dabr(0);
- }
-#endif
-}
-
-void
-release_thread(struct task_struct *t)
-{
-}
-
-/*
- * This gets called before we allocate a new thread and copy
- * the current task into it.
- */
-void prepare_to_copy(struct task_struct *tsk)
-{
- flush_fp_to_thread(current);
- flush_altivec_to_thread(current);
- flush_spe_to_thread(current);
-}
-
-/*
- * Copy a thread..
- */
-int
-copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
- unsigned long unused,
- struct task_struct *p, struct pt_regs *regs)
-{
- struct pt_regs *childregs, *kregs;
- extern void ret_from_fork(void);
- unsigned long sp = (unsigned long)p->thread_info + THREAD_SIZE;
- unsigned long childframe;
-
- CHECK_FULL_REGS(regs);
- /* Copy registers */
- sp -= sizeof(struct pt_regs);
- childregs = (struct pt_regs *) sp;
- *childregs = *regs;
- if ((childregs->msr & MSR_PR) == 0) {
- /* for kernel thread, set `current' and stackptr in new task */
- childregs->gpr[1] = sp + sizeof(struct pt_regs);
- childregs->gpr[2] = (unsigned long) p;
- p->thread.regs = NULL; /* no user register state */
- } else {
- childregs->gpr[1] = usp;
- p->thread.regs = childregs;
- if (clone_flags & CLONE_SETTLS)
- childregs->gpr[2] = childregs->gpr[6];
- }
- childregs->gpr[3] = 0; /* Result from fork() */
- sp -= STACK_FRAME_OVERHEAD;
- childframe = sp;
-
- /*
- * The way this works is that at some point in the future
- * some task will call _switch to switch to the new task.
- * That will pop off the stack frame created below and start
- * the new task running at ret_from_fork. The new task will
- * do some house keeping and then return from the fork or clone
- * system call, using the stack frame created above.
- */
- sp -= sizeof(struct pt_regs);
- kregs = (struct pt_regs *) sp;
- sp -= STACK_FRAME_OVERHEAD;
- p->thread.ksp = sp;
- kregs->nip = (unsigned long)ret_from_fork;
-
- p->thread.last_syscall = -1;
-
- return 0;
-}
-
-/*
- * Set up a thread for executing a new program
- */
-void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp)
-{
- set_fs(USER_DS);
- memset(regs->gpr, 0, sizeof(regs->gpr));
- regs->ctr = 0;
- regs->link = 0;
- regs->xer = 0;
- regs->ccr = 0;
- regs->mq = 0;
- regs->nip = nip;
- regs->gpr[1] = sp;
- regs->msr = MSR_USER;
-#ifndef CONFIG_SMP
- if (last_task_used_math == current)
- last_task_used_math = NULL;
-#ifdef CONFIG_ALTIVEC
- if (last_task_used_altivec == current)
- last_task_used_altivec = NULL;
-#endif
-#ifdef CONFIG_SPE
- if (last_task_used_spe == current)
- last_task_used_spe = NULL;
-#endif
-#endif /* CONFIG_SMP */
- memset(current->thread.fpr, 0, sizeof(current->thread.fpr));
- current->thread.fpscr = 0;
-#ifdef CONFIG_ALTIVEC
- memset(current->thread.vr, 0, sizeof(current->thread.vr));
- memset(¤t->thread.vscr, 0, sizeof(current->thread.vscr));
- current->thread.vrsave = 0;
- current->thread.used_vr = 0;
-#endif /* CONFIG_ALTIVEC */
-#ifdef CONFIG_SPE
- memset(current->thread.evr, 0, sizeof(current->thread.evr));
- current->thread.acc = 0;
- current->thread.spefscr = 0;
- current->thread.used_spe = 0;
-#endif /* CONFIG_SPE */
-}
-
-#define PR_FP_ALL_EXCEPT (PR_FP_EXC_DIV | PR_FP_EXC_OVF | PR_FP_EXC_UND \
- | PR_FP_EXC_RES | PR_FP_EXC_INV)
-
-int set_fpexc_mode(struct task_struct *tsk, unsigned int val)
-{
- struct pt_regs *regs = tsk->thread.regs;
-
- /* This is a bit hairy. If we are an SPE enabled processor
- * (have embedded fp) we store the IEEE exception enable flags in
- * fpexc_mode. fpexc_mode is also used for setting FP exception
- * mode (asyn, precise, disabled) for 'Classic' FP. */
- if (val & PR_FP_EXC_SW_ENABLE) {
-#ifdef CONFIG_SPE
- tsk->thread.fpexc_mode = val &
- (PR_FP_EXC_SW_ENABLE | PR_FP_ALL_EXCEPT);
-#else
- return -EINVAL;
-#endif
- } else {
- /* on a CONFIG_SPE this does not hurt us. The bits that
- * __pack_fe01 use do not overlap with bits used for
- * PR_FP_EXC_SW_ENABLE. Additionally, the MSR[FE0,FE1] bits
- * on CONFIG_SPE implementations are reserved so writing to
- * them does not change anything */
- if (val > PR_FP_EXC_PRECISE)
- return -EINVAL;
- tsk->thread.fpexc_mode = __pack_fe01(val);
- if (regs != NULL && (regs->msr & MSR_FP) != 0)
- regs->msr = (regs->msr & ~(MSR_FE0|MSR_FE1))
- | tsk->thread.fpexc_mode;
- }
- return 0;
-}
-
-int get_fpexc_mode(struct task_struct *tsk, unsigned long adr)
-{
- unsigned int val;
-
- if (tsk->thread.fpexc_mode & PR_FP_EXC_SW_ENABLE)
-#ifdef CONFIG_SPE
- val = tsk->thread.fpexc_mode;
-#else
- return -EINVAL;
-#endif
- else
- val = __unpack_fe01(tsk->thread.fpexc_mode);
- return put_user(val, (unsigned int __user *) adr);
-}
-
-int sys_clone(unsigned long clone_flags, unsigned long usp,
- int __user *parent_tidp, void __user *child_threadptr,
- int __user *child_tidp, int p6,
- struct pt_regs *regs)
-{
- CHECK_FULL_REGS(regs);
- if (usp == 0)
- usp = regs->gpr[1]; /* stack pointer for child */
- return do_fork(clone_flags, usp, regs, 0, parent_tidp, child_tidp);
-}
-
-int sys_fork(unsigned long p1, unsigned long p2, unsigned long p3,
- unsigned long p4, unsigned long p5, unsigned long p6,
- struct pt_regs *regs)
-{
- CHECK_FULL_REGS(regs);
- return do_fork(SIGCHLD, regs->gpr[1], regs, 0, NULL, NULL);
-}
-
-int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3,
- unsigned long p4, unsigned long p5, unsigned long p6,
- struct pt_regs *regs)
-{
- CHECK_FULL_REGS(regs);
- return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gpr[1],
- regs, 0, NULL, NULL);
-}
-
-int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
- unsigned long a3, unsigned long a4, unsigned long a5,
- struct pt_regs *regs)
-{
- int error;
- char * filename;
-
- filename = getname((char __user *) a0);
- error = PTR_ERR(filename);
- if (IS_ERR(filename))
- goto out;
- flush_fp_to_thread(current);
- flush_altivec_to_thread(current);
- flush_spe_to_thread(current);
- if (error == 0) {
- task_lock(current);
- current->ptrace &= ~PT_DTRACE;
- task_unlock(current);
- }
- putname(filename);
-out:
- return error;
-}
-
-static int validate_sp(unsigned long sp, struct task_struct *p,
- unsigned long nbytes)
-{
- unsigned long stack_page = (unsigned long)p->thread_info;
-
- if (sp >= stack_page + sizeof(struct thread_struct)
- && sp <= stack_page + THREAD_SIZE - nbytes)
- return 1;
-
-#ifdef CONFIG_IRQSTACKS
- stack_page = (unsigned long) hardirq_ctx[task_cpu(p)];
- if (sp >= stack_page + sizeof(struct thread_struct)
- && sp <= stack_page + THREAD_SIZE - nbytes)
- return 1;
-
- stack_page = (unsigned long) softirq_ctx[task_cpu(p)];
- if (sp >= stack_page + sizeof(struct thread_struct)
- && sp <= stack_page + THREAD_SIZE - nbytes)
- return 1;
-#endif
-
- return 0;
-}
-
-void dump_stack(void)
-{
- show_stack(current, NULL);
-}
-
-EXPORT_SYMBOL(dump_stack);
-
-void show_stack(struct task_struct *tsk, unsigned long *stack)
-{
- unsigned long sp, stack_top, prev_sp, ret;
- int count = 0;
- unsigned long next_exc = 0;
- struct pt_regs *regs;
- extern char ret_from_except, ret_from_except_full, ret_from_syscall;
-
- sp = (unsigned long) stack;
- if (tsk == NULL)
- tsk = current;
- if (sp == 0) {
- if (tsk == current)
- asm("mr %0,1" : "=r" (sp));
- else
- sp = tsk->thread.ksp;
- }
-
- prev_sp = (unsigned long) (tsk->thread_info + 1);
- stack_top = (unsigned long) tsk->thread_info + THREAD_SIZE;
- while (count < 16 && sp > prev_sp && sp < stack_top && (sp & 3) == 0) {
- if (count == 0) {
- printk("Call trace:");
-#ifdef CONFIG_KALLSYMS
- printk("\n");
-#endif
- } else {
- if (next_exc) {
- ret = next_exc;
- next_exc = 0;
- } else
- ret = *(unsigned long *)(sp + 4);
- printk(" [%08lx] ", ret);
-#ifdef CONFIG_KALLSYMS
- print_symbol("%s", ret);
- printk("\n");
-#endif
- if (ret == (unsigned long) &ret_from_except
- || ret == (unsigned long) &ret_from_except_full
- || ret == (unsigned long) &ret_from_syscall) {
- /* sp + 16 points to an exception frame */
- regs = (struct pt_regs *) (sp + 16);
- if (sp + 16 + sizeof(*regs) <= stack_top)
- next_exc = regs->nip;
- }
- }
- ++count;
- sp = *(unsigned long *)sp;
- }
-#ifndef CONFIG_KALLSYMS
- if (count > 0)
- printk("\n");
-#endif
-}
-
-unsigned long get_wchan(struct task_struct *p)
-{
- unsigned long ip, sp;
- int count = 0;
-
- if (!p || p == current || p->state == TASK_RUNNING)
- return 0;
-
- sp = p->thread.ksp;
- if (!validate_sp(sp, p, 16))
- return 0;
-
- do {
- sp = *(unsigned long *)sp;
- if (!validate_sp(sp, p, 16))
- return 0;
- if (count > 0) {
- ip = *(unsigned long *)(sp + 4);
- if (!in_sched_functions(ip))
- return ip;
- }
- } while (count++ < 16);
- return 0;
-}
-EXPORT_SYMBOL(get_wchan);
diff --git a/trunk/arch/powerpc/kernel/semaphore.c b/trunk/arch/powerpc/kernel/semaphore.c
deleted file mode 100644
index 2f8c3c951394..000000000000
--- a/trunk/arch/powerpc/kernel/semaphore.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * PowerPC-specific semaphore code.
- *
- * Copyright (C) 1999 Cort Dougan
- *
- * 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.
- *
- * April 2001 - Reworked by Paul Mackerras
- * to eliminate the SMP races in the old version between the updates
- * of `count' and `waking'. Now we use negative `count' values to
- * indicate that some process(es) are waiting for the semaphore.
- */
-
-#include
-#include
-#include
-
-#include
-#include
-#include
-
-/*
- * Atomically update sem->count.
- * This does the equivalent of the following:
- *
- * old_count = sem->count;
- * tmp = MAX(old_count, 0) + incr;
- * sem->count = tmp;
- * return old_count;
- */
-static inline int __sem_update_count(struct semaphore *sem, int incr)
-{
- int old_count, tmp;
-
- __asm__ __volatile__("\n"
-"1: lwarx %0,0,%3\n"
-" srawi %1,%0,31\n"
-" andc %1,%0,%1\n"
-" add %1,%1,%4\n"
- PPC405_ERR77(0,%3)
-" stwcx. %1,0,%3\n"
-" bne 1b"
- : "=&r" (old_count), "=&r" (tmp), "=m" (sem->count)
- : "r" (&sem->count), "r" (incr), "m" (sem->count)
- : "cc");
-
- return old_count;
-}
-
-void __up(struct semaphore *sem)
-{
- /*
- * Note that we incremented count in up() before we came here,
- * but that was ineffective since the result was <= 0, and
- * any negative value of count is equivalent to 0.
- * This ends up setting count to 1, unless count is now > 0
- * (i.e. because some other cpu has called up() in the meantime),
- * in which case we just increment count.
- */
- __sem_update_count(sem, 1);
- wake_up(&sem->wait);
-}
-EXPORT_SYMBOL(__up);
-
-/*
- * Note that when we come in to __down or __down_interruptible,
- * we have already decremented count, but that decrement was
- * ineffective since the result was < 0, and any negative value
- * of count is equivalent to 0.
- * Thus it is only when we decrement count from some value > 0
- * that we have actually got the semaphore.
- */
-void __sched __down(struct semaphore *sem)
-{
- struct task_struct *tsk = current;
- DECLARE_WAITQUEUE(wait, tsk);
-
- __set_task_state(tsk, TASK_UNINTERRUPTIBLE);
- add_wait_queue_exclusive(&sem->wait, &wait);
-
- /*
- * Try to get the semaphore. If the count is > 0, then we've
- * got the semaphore; we decrement count and exit the loop.
- * If the count is 0 or negative, we set it to -1, indicating
- * that we are asleep, and then sleep.
- */
- while (__sem_update_count(sem, -1) <= 0) {
- schedule();
- set_task_state(tsk, TASK_UNINTERRUPTIBLE);
- }
- remove_wait_queue(&sem->wait, &wait);
- __set_task_state(tsk, TASK_RUNNING);
-
- /*
- * If there are any more sleepers, wake one of them up so
- * that it can either get the semaphore, or set count to -1
- * indicating that there are still processes sleeping.
- */
- wake_up(&sem->wait);
-}
-EXPORT_SYMBOL(__down);
-
-int __sched __down_interruptible(struct semaphore * sem)
-{
- int retval = 0;
- struct task_struct *tsk = current;
- DECLARE_WAITQUEUE(wait, tsk);
-
- __set_task_state(tsk, TASK_INTERRUPTIBLE);
- add_wait_queue_exclusive(&sem->wait, &wait);
-
- while (__sem_update_count(sem, -1) <= 0) {
- if (signal_pending(current)) {
- /*
- * A signal is pending - give up trying.
- * Set sem->count to 0 if it is negative,
- * since we are no longer sleeping.
- */
- __sem_update_count(sem, 0);
- retval = -EINTR;
- break;
- }
- schedule();
- set_task_state(tsk, TASK_INTERRUPTIBLE);
- }
- remove_wait_queue(&sem->wait, &wait);
- __set_task_state(tsk, TASK_RUNNING);
-
- wake_up(&sem->wait);
- return retval;
-}
-EXPORT_SYMBOL(__down_interruptible);
diff --git a/trunk/arch/powerpc/kernel/traps.c b/trunk/arch/powerpc/kernel/traps.c
deleted file mode 100644
index c7afbbba0f36..000000000000
--- a/trunk/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
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-#ifdef CONFIG_PMAC_BACKLIGHT
-#include
-#endif
-#include
-
-#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(¤t->sighand->siglock);
- handler = current->sighand->action[signr-1].sa.sa_handler;
- spin_unlock_irq(¤t->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/trunk/arch/powerpc/kernel/vector.S b/trunk/arch/powerpc/kernel/vector.S
deleted file mode 100644
index 12cb90bc209c..000000000000
--- a/trunk/arch/powerpc/kernel/vector.S
+++ /dev/null
@@ -1,197 +0,0 @@
-#include
-#include
-#include
-
-/*
- * 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.
- */
-#ifdef CONFIG_PPC32
- .data
-fpzero:
- .long 0
-fpone:
- .long 0x3f800000 /* 1.0 in single-precision FP */
-fphalf:
- .long 0x3f000000 /* 0.5 in single-precision FP */
-
-#define LDCONST(fr, name) \
- lis r11,name@ha; \
- lfs fr,name@l(r11)
-#else
-
- .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 */
-
-#define LDCONST(fr, name) \
- lfd fr,name@toc(r2)
-#endif
-
- .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:
-#ifdef CONFIG_PPC32
- stwu r1,-64(r1)
-#else
- stdu r1,-64(r1)
-#endif
- mfmsr r10
- ori r11,r10,MSR_FP
- mtmsr r11
- isync
- stfd fr0,24(r1)
- stfd fr1,16(r1)
- stfd fr31,8(r1)
- LDCONST(fr1, fpzero)
- mffs fr31
- mtfsf 0xff,fr1
- blr
-
-fpdisable:
- mtlr r12
- mtfsf 0xff,fr31
- lfd fr31,8(r1)
- lfd fr1,16(r1)
- lfd fr0,24(r1)
- mtmsr r10
- isync
- addi r1,r1,64
- 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
- LDCONST(fr1, fpone)
- 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
- LDCONST(fr4, fpone)
- LDCONST(fr5, fphalf)
- 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
diff --git a/trunk/arch/powerpc/kernel/vmlinux.lds b/trunk/arch/powerpc/kernel/vmlinux.lds
deleted file mode 100644
index d62c288a81d0..000000000000
--- a/trunk/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/trunk/arch/powerpc/kernel/vmlinux.lds.S b/trunk/arch/powerpc/kernel/vmlinux.lds.S
deleted file mode 100644
index 09c6525cfa61..000000000000
--- a/trunk/arch/powerpc/kernel/vmlinux.lds.S
+++ /dev/null
@@ -1,172 +0,0 @@
-#include
-
-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)
- SCHED_TEXT
- LOCK_TEXT
- *(.fixup)
- *(.got1)
- __got2_start = .;
- *(.got2)
- __got2_end = .;
- }
- _etext = .;
- PROVIDE (etext = .);
-
- RODATA
- .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_INIT
-
- __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/trunk/arch/powerpc/lib/Makefile b/trunk/arch/powerpc/lib/Makefile
deleted file mode 100644
index 347f9798e433..000000000000
--- a/trunk/arch/powerpc/lib/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-#
-# Makefile for ppc-specific library files..
-#
-
-obj-y := strcase.o string.o
-obj-$(CONFIG_PPC32) += div64.o copy32.o checksum.o
-obj-$(CONFIG_PPC64) += copypage.o copyuser.o memcpy.o usercopy.o \
- sstep.o checksum64.o
-obj-$(CONFIG_PPC_ISERIES) += e2a.o
diff --git a/trunk/arch/powerpc/lib/checksum.S b/trunk/arch/powerpc/lib/checksum.S
deleted file mode 100644
index 7874e8a80455..000000000000
--- a/trunk/arch/powerpc/lib/checksum.S
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * This file contains assembly-language implementations
- * of IP-style 1's complement checksum routines.
- *
- * 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.
- *
- * Severely hacked about by Paul Mackerras (paulus@cs.anu.edu.au).
- */
-
-#include
-#include
-#include
-#include
-
- .text
-
-/*
- * ip_fast_csum(buf, len) -- Optimized for IP header
- * len is in words and is always >= 5.
- */
-_GLOBAL(ip_fast_csum)
- lwz r0,0(r3)
- lwzu r5,4(r3)
- addic. r4,r4,-2
- addc r0,r0,r5
- mtctr r4
- blelr-
-1: lwzu r4,4(r3)
- adde r0,r0,r4
- bdnz 1b
- addze r0,r0 /* add in final carry */
- rlwinm r3,r0,16,0,31 /* fold two halves together */
- add r3,r0,r3
- not r3,r3
- srwi r3,r3,16
- blr
-
-/*
- * Compute checksum of TCP or UDP pseudo-header:
- * csum_tcpudp_magic(saddr, daddr, len, proto, sum)
- */
-_GLOBAL(csum_tcpudp_magic)
- rlwimi r5,r6,16,0,15 /* put proto in upper half of len */
- addc r0,r3,r4 /* add 4 32-bit words together */
- adde r0,r0,r5
- adde r0,r0,r7
- addze r0,r0 /* add in final carry */
- rlwinm r3,r0,16,0,31 /* fold two halves together */
- add r3,r0,r3
- not r3,r3
- srwi r3,r3,16
- blr
-
-/*
- * computes the checksum of a memory block at buff, length len,
- * and adds in "sum" (32-bit)
- *
- * csum_partial(buff, len, sum)
- */
-_GLOBAL(csum_partial)
- addic r0,r5,0
- subi r3,r3,4
- srwi. r6,r4,2
- beq 3f /* if we're doing < 4 bytes */
- andi. r5,r3,2 /* Align buffer to longword boundary */
- beq+ 1f
- lhz r5,4(r3) /* do 2 bytes to get aligned */
- addi r3,r3,2
- subi r4,r4,2
- addc r0,r0,r5
- srwi. r6,r4,2 /* # words to do */
- beq 3f
-1: mtctr r6
-2: lwzu r5,4(r3) /* the bdnz has zero overhead, so it should */
- adde r0,r0,r5 /* be unnecessary to unroll this loop */
- bdnz 2b
- andi. r4,r4,3
-3: cmpwi 0,r4,2
- blt+ 4f
- lhz r5,4(r3)
- addi r3,r3,2
- subi r4,r4,2
- adde r0,r0,r5
-4: cmpwi 0,r4,1
- bne+ 5f
- lbz r5,4(r3)
- slwi r5,r5,8 /* Upper byte of word */
- adde r0,r0,r5
-5: addze r3,r0 /* add in final carry */
- blr
-
-/*
- * Computes the checksum of a memory block at src, length len,
- * and adds in "sum" (32-bit), while copying the block to dst.
- * If an access exception occurs on src or dst, it stores -EFAULT
- * to *src_err or *dst_err respectively, and (for an error on
- * src) zeroes the rest of dst.
- *
- * csum_partial_copy_generic(src, dst, len, sum, src_err, dst_err)
- */
-_GLOBAL(csum_partial_copy_generic)
- addic r0,r6,0
- subi r3,r3,4
- subi r4,r4,4
- srwi. r6,r5,2
- beq 3f /* if we're doing < 4 bytes */
- andi. r9,r4,2 /* Align dst to longword boundary */
- beq+ 1f
-81: lhz r6,4(r3) /* do 2 bytes to get aligned */
- addi r3,r3,2
- subi r5,r5,2
-91: sth r6,4(r4)
- addi r4,r4,2
- addc r0,r0,r6
- srwi. r6,r5,2 /* # words to do */
- beq 3f
-1: srwi. r6,r5,4 /* # groups of 4 words to do */
- beq 10f
- mtctr r6
-71: lwz r6,4(r3)
-72: lwz r9,8(r3)
-73: lwz r10,12(r3)
-74: lwzu r11,16(r3)
- adde r0,r0,r6
-75: stw r6,4(r4)
- adde r0,r0,r9
-76: stw r9,8(r4)
- adde r0,r0,r10
-77: stw r10,12(r4)
- adde r0,r0,r11
-78: stwu r11,16(r4)
- bdnz 71b
-10: rlwinm. r6,r5,30,30,31 /* # words left to do */
- beq 13f
- mtctr r6
-82: lwzu r9,4(r3)
-92: stwu r9,4(r4)
- adde r0,r0,r9
- bdnz 82b
-13: andi. r5,r5,3
-3: cmpwi 0,r5,2
- blt+ 4f
-83: lhz r6,4(r3)
- addi r3,r3,2
- subi r5,r5,2
-93: sth r6,4(r4)
- addi r4,r4,2
- adde r0,r0,r6
-4: cmpwi 0,r5,1
- bne+ 5f
-84: lbz r6,4(r3)
-94: stb r6,4(r4)
- slwi r6,r6,8 /* Upper byte of word */
- adde r0,r0,r6
-5: addze r3,r0 /* add in final carry */
- blr
-
-/* These shouldn't go in the fixup section, since that would
- cause the ex_table addresses to get out of order. */
-
-src_error_4:
- mfctr r6 /* update # bytes remaining from ctr */
- rlwimi r5,r6,4,0,27
- b 79f
-src_error_1:
- li r6,0
- subi r5,r5,2
-95: sth r6,4(r4)
- addi r4,r4,2
-79: srwi. r6,r5,2
- beq 3f
- mtctr r6
-src_error_2:
- li r6,0
-96: stwu r6,4(r4)
- bdnz 96b
-3: andi. r5,r5,3
- beq src_error
-src_error_3:
- li r6,0
- mtctr r5
- addi r4,r4,3
-97: stbu r6,1(r4)
- bdnz 97b
-src_error:
- cmpwi 0,r7,0
- beq 1f
- li r6,-EFAULT
- stw r6,0(r7)
-1: addze r3,r0
- blr
-
-dst_error:
- cmpwi 0,r8,0
- beq 1f
- li r6,-EFAULT
- stw r6,0(r8)
-1: addze r3,r0
- blr
-
-.section __ex_table,"a"
- .long 81b,src_error_1
- .long 91b,dst_error
- .long 71b,src_error_4
- .long 72b,src_error_4
- .long 73b,src_error_4
- .long 74b,src_error_4
- .long 75b,dst_error
- .long 76b,dst_error
- .long 77b,dst_error
- .long 78b,dst_error
- .long 82b,src_error_2
- .long 92b,dst_error
- .long 83b,src_error_3
- .long 93b,dst_error
- .long 84b,src_error_3
- .long 94b,dst_error
- .long 95b,dst_error
- .long 96b,dst_error
- .long 97b,dst_error
diff --git a/trunk/arch/powerpc/lib/checksum64.S b/trunk/arch/powerpc/lib/checksum64.S
deleted file mode 100644
index ef96c6c58efc..000000000000
--- a/trunk/arch/powerpc/lib/checksum64.S
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * This file contains assembly-language implementations
- * of IP-style 1's complement checksum routines.
- *
- * 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.
- *
- * Severely hacked about by Paul Mackerras (paulus@cs.anu.edu.au).
- */
-
-#include
-#include
-#include
-#include
-
-/*
- * ip_fast_csum(r3=buf, r4=len) -- Optimized for IP header
- * len is in words and is always >= 5.
- *
- * In practice len == 5, but this is not guaranteed. So this code does not
- * attempt to use doubleword instructions.
- */
-_GLOBAL(ip_fast_csum)
- lwz r0,0(r3)
- lwzu r5,4(r3)
- addic. r4,r4,-2
- addc r0,r0,r5
- mtctr r4
- blelr-
-1: lwzu r4,4(r3)
- adde r0,r0,r4
- bdnz 1b
- addze r0,r0 /* add in final carry */
- rldicl r4,r0,32,0 /* fold two 32-bit halves together */
- add r0,r0,r4
- srdi r0,r0,32
- rlwinm r3,r0,16,0,31 /* fold two halves together */
- add r3,r0,r3
- not r3,r3
- srwi r3,r3,16
- blr
-
-/*
- * Compute checksum of TCP or UDP pseudo-header:
- * csum_tcpudp_magic(r3=saddr, r4=daddr, r5=len, r6=proto, r7=sum)
- * No real gain trying to do this specially for 64 bit, but
- * the 32 bit addition may spill into the upper bits of
- * the doubleword so we still must fold it down from 64.
- */
-_GLOBAL(csum_tcpudp_magic)
- rlwimi r5,r6,16,0,15 /* put proto in upper half of len */
- addc r0,r3,r4 /* add 4 32-bit words together */
- adde r0,r0,r5
- adde r0,r0,r7
- rldicl r4,r0,32,0 /* fold 64 bit value */
- add r0,r4,r0
- srdi r0,r0,32
- rlwinm r3,r0,16,0,31 /* fold two halves together */
- add r3,r0,r3
- not r3,r3
- srwi r3,r3,16
- blr
-
-/*
- * Computes the checksum of a memory block at buff, length len,
- * and adds in "sum" (32-bit).
- *
- * This code assumes at least halfword alignment, though the length
- * can be any number of bytes. The sum is accumulated in r5.
- *
- * csum_partial(r3=buff, r4=len, r5=sum)
- */
-_GLOBAL(csum_partial)
- subi r3,r3,8 /* we'll offset by 8 for the loads */
- srdi. r6,r4,3 /* divide by 8 for doubleword count */
- addic r5,r5,0 /* clear carry */
- beq 3f /* if we're doing < 8 bytes */
- andi. r0,r3,2 /* aligned on a word boundary already? */
- beq+ 1f
- lhz r6,8(r3) /* do 2 bytes to get aligned */
- addi r3,r3,2
- subi r4,r4,2
- addc r5,r5,r6
- srdi. r6,r4,3 /* recompute number of doublewords */
- beq 3f /* any left? */
-1: mtctr r6
-2: ldu r6,8(r3) /* main sum loop */
- adde r5,r5,r6
- bdnz 2b
- andi. r4,r4,7 /* compute bytes left to sum after doublewords */
-3: cmpwi 0,r4,4 /* is at least a full word left? */
- blt 4f
- lwz r6,8(r3) /* sum this word */
- addi r3,r3,4
- subi r4,r4,4
- adde r5,r5,r6
-4: cmpwi 0,r4,2 /* is at least a halfword left? */
- blt+ 5f
- lhz r6,8(r3) /* sum this halfword */
- addi r3,r3,2
- subi r4,r4,2
- adde r5,r5,r6
-5: cmpwi 0,r4,1 /* is at least a byte left? */
- bne+ 6f
- lbz r6,8(r3) /* sum this byte */
- slwi r6,r6,8 /* this byte is assumed to be the upper byte of a halfword */
- adde r5,r5,r6
-6: addze r5,r5 /* add in final carry */
- rldicl r4,r5,32,0 /* fold two 32-bit halves together */
- add r3,r4,r5
- srdi r3,r3,32
- blr
-
-/*
- * Computes the checksum of a memory block at src, length len,
- * and adds in "sum" (32-bit), while copying the block to dst.
- * If an access exception occurs on src or dst, it stores -EFAULT
- * to *src_err or *dst_err respectively, and (for an error on
- * src) zeroes the rest of dst.
- *
- * This code needs to be reworked to take advantage of 64 bit sum+copy.
- * However, due to tokenring halfword alignment problems this will be very
- * tricky. For now we'll leave it until we instrument it somehow.
- *
- * csum_partial_copy_generic(r3=src, r4=dst, r5=len, r6=sum, r7=src_err, r8=dst_err)
- */
-_GLOBAL(csum_partial_copy_generic)
- addic r0,r6,0
- subi r3,r3,4
- subi r4,r4,4
- srwi. r6,r5,2
- beq 3f /* if we're doing < 4 bytes */
- andi. r9,r4,2 /* Align dst to longword boundary */
- beq+ 1f
-81: lhz r6,4(r3) /* do 2 bytes to get aligned */
- addi r3,r3,2
- subi r5,r5,2
-91: sth r6,4(r4)
- addi r4,r4,2
- addc r0,r0,r6
- srwi. r6,r5,2 /* # words to do */
- beq 3f
-1: mtctr r6
-82: lwzu r6,4(r3) /* the bdnz has zero overhead, so it should */
-92: stwu r6,4(r4) /* be unnecessary to unroll this loop */
- adde r0,r0,r6
- bdnz 82b
- andi. r5,r5,3
-3: cmpwi 0,r5,2
- blt+ 4f
-83: lhz r6,4(r3)
- addi r3,r3,2
- subi r5,r5,2
-93: sth r6,4(r4)
- addi r4,r4,2
- adde r0,r0,r6
-4: cmpwi 0,r5,1
- bne+ 5f
-84: lbz r6,4(r3)
-94: stb r6,4(r4)
- slwi r6,r6,8 /* Upper byte of word */
- adde r0,r0,r6
-5: addze r3,r0 /* add in final carry (unlikely with 64-bit regs) */
- rldicl r4,r3,32,0 /* fold 64 bit value */
- add r3,r4,r3
- srdi r3,r3,32
- blr
-
-/* These shouldn't go in the fixup section, since that would
- cause the ex_table addresses to get out of order. */
-
- .globl src_error_1
-src_error_1:
- li r6,0
- subi r5,r5,2
-95: sth r6,4(r4)
- addi r4,r4,2
- srwi. r6,r5,2
- beq 3f
- mtctr r6
- .globl src_error_2
-src_error_2:
- li r6,0
-96: stwu r6,4(r4)
- bdnz 96b
-3: andi. r5,r5,3
- beq src_error
- .globl src_error_3
-src_error_3:
- li r6,0
- mtctr r5
- addi r4,r4,3
-97: stbu r6,1(r4)
- bdnz 97b
- .globl src_error
-src_error:
- cmpdi 0,r7,0
- beq 1f
- li r6,-EFAULT
- stw r6,0(r7)
-1: addze r3,r0
- blr
-
- .globl dst_error
-dst_error:
- cmpdi 0,r8,0
- beq 1f
- li r6,-EFAULT
- stw r6,0(r8)
-1: addze r3,r0
- blr
-
-.section __ex_table,"a"
- .align 3
- .llong 81b,src_error_1
- .llong 91b,dst_error
- .llong 82b,src_error_2
- .llong 92b,dst_error
- .llong 83b,src_error_3
- .llong 93b,dst_error
- .llong 84b,src_error_3
- .llong 94b,dst_error
- .llong 95b,dst_error
- .llong 96b,dst_error
- .llong 97b,dst_error
diff --git a/trunk/arch/powerpc/lib/copy32.S b/trunk/arch/powerpc/lib/copy32.S
deleted file mode 100644
index 420a912198a2..000000000000
--- a/trunk/arch/powerpc/lib/copy32.S
+++ /dev/null
@@ -1,543 +0,0 @@
-/*
- * Memory copy functions for 32-bit PowerPC.
- *
- * Copyright (C) 1996-2005 Paul Mackerras.
- *
- * 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
-#include
-#include
-#include
-#include
-
-#define COPY_16_BYTES \
- lwz r7,4(r4); \
- lwz r8,8(r4); \
- lwz r9,12(r4); \
- lwzu r10,16(r4); \
- stw r7,4(r6); \
- stw r8,8(r6); \
- stw r9,12(r6); \
- stwu r10,16(r6)
-
-#define COPY_16_BYTES_WITHEX(n) \
-8 ## n ## 0: \
- lwz r7,4(r4); \
-8 ## n ## 1: \
- lwz r8,8(r4); \
-8 ## n ## 2: \
- lwz r9,12(r4); \
-8 ## n ## 3: \
- lwzu r10,16(r4); \
-8 ## n ## 4: \
- stw r7,4(r6); \
-8 ## n ## 5: \
- stw r8,8(r6); \
-8 ## n ## 6: \
- stw r9,12(r6); \
-8 ## n ## 7: \
- stwu r10,16(r6)
-
-#define COPY_16_BYTES_EXCODE(n) \
-9 ## n ## 0: \
- addi r5,r5,-(16 * n); \
- b 104f; \
-9 ## n ## 1: \
- addi r5,r5,-(16 * n); \
- b 105f; \
-.section __ex_table,"a"; \
- .align 2; \
- .long 8 ## n ## 0b,9 ## n ## 0b; \
- .long 8 ## n ## 1b,9 ## n ## 0b; \
- .long 8 ## n ## 2b,9 ## n ## 0b; \
- .long 8 ## n ## 3b,9 ## n ## 0b; \
- .long 8 ## n ## 4b,9 ## n ## 1b; \
- .long 8 ## n ## 5b,9 ## n ## 1b; \
- .long 8 ## n ## 6b,9 ## n ## 1b; \
- .long 8 ## n ## 7b,9 ## n ## 1b; \
- .text
-
- .text
- .stabs "arch/powerpc/lib/",N_SO,0,0,0f
- .stabs "copy32.S",N_SO,0,0,0f
-0:
-
-CACHELINE_BYTES = L1_CACHE_LINE_SIZE
-LG_CACHELINE_BYTES = LG_L1_CACHE_LINE_SIZE
-CACHELINE_MASK = (L1_CACHE_LINE_SIZE-1)
-
-/*
- * Use dcbz on the complete cache lines in the destination
- * to set them to zero. This requires that the destination
- * area is cacheable. -- paulus
- */
-_GLOBAL(cacheable_memzero)
- mr r5,r4
- li r4,0
- addi r6,r3,-4
- cmplwi 0,r5,4
- blt 7f
- stwu r4,4(r6)
- beqlr
- andi. r0,r6,3
- add r5,r0,r5
- subf r6,r0,r6
- clrlwi r7,r6,32-LG_CACHELINE_BYTES
- add r8,r7,r5
- srwi r9,r8,LG_CACHELINE_BYTES
- addic. r9,r9,-1 /* total number of complete cachelines */
- ble 2f
- xori r0,r7,CACHELINE_MASK & ~3
- srwi. r0,r0,2
- beq 3f
- mtctr r0
-4: stwu r4,4(r6)
- bdnz 4b
-3: mtctr r9
- li r7,4
-#if !defined(CONFIG_8xx)
-10: dcbz r7,r6
-#else
-10: stw r4, 4(r6)
- stw r4, 8(r6)
- stw r4, 12(r6)
- stw r4, 16(r6)
-#if CACHE_LINE_SIZE >= 32
- stw r4, 20(r6)
- stw r4, 24(r6)
- stw r4, 28(r6)
- stw r4, 32(r6)
-#endif /* CACHE_LINE_SIZE */
-#endif
- addi r6,r6,CACHELINE_BYTES
- bdnz 10b
- clrlwi r5,r8,32-LG_CACHELINE_BYTES
- addi r5,r5,4
-2: srwi r0,r5,2
- mtctr r0
- bdz 6f
-1: stwu r4,4(r6)
- bdnz 1b
-6: andi. r5,r5,3
-7: cmpwi 0,r5,0
- beqlr
- mtctr r5
- addi r6,r6,3
-8: stbu r4,1(r6)
- bdnz 8b
- blr
-
-_GLOBAL(memset)
- rlwimi r4,r4,8,16,23
- rlwimi r4,r4,16,0,15
- addi r6,r3,-4
- cmplwi 0,r5,4
- blt 7f
- stwu r4,4(r6)
- beqlr
- andi. r0,r6,3
- add r5,r0,r5
- subf r6,r0,r6
- srwi r0,r5,2
- mtctr r0
- bdz 6f
-1: stwu r4,4(r6)
- bdnz 1b
-6: andi. r5,r5,3
-7: cmpwi 0,r5,0
- beqlr
- mtctr r5
- addi r6,r6,3
-8: stbu r4,1(r6)
- bdnz 8b
- blr
-
-/*
- * This version uses dcbz on the complete cache lines in the
- * destination area to reduce memory traffic. This requires that
- * the destination area is cacheable.
- * We only use this version if the source and dest don't overlap.
- * -- paulus.
- */
-_GLOBAL(cacheable_memcpy)
- add r7,r3,r5 /* test if the src & dst overlap */
- add r8,r4,r5
- cmplw 0,r4,r7
- cmplw 1,r3,r8
- crand 0,0,4 /* cr0.lt &= cr1.lt */
- blt memcpy /* if regions overlap */
-
- addi r4,r4,-4
- addi r6,r3,-4
- neg r0,r3
- andi. r0,r0,CACHELINE_MASK /* # bytes to start of cache line */
- beq 58f
-
- cmplw 0,r5,r0 /* is this more than total to do? */
- blt 63f /* if not much to do */
- andi. r8,r0,3 /* get it word-aligned first */
- subf r5,r0,r5
- mtctr r8
- beq+ 61f
-70: lbz r9,4(r4) /* do some bytes */
- stb r9,4(r6)
- addi r4,r4,1
- addi r6,r6,1
- bdnz 70b
-61: srwi. r0,r0,2
- mtctr r0
- beq 58f
-72: lwzu r9,4(r4) /* do some words */
- stwu r9,4(r6)
- bdnz 72b
-
-58: srwi. r0,r5,LG_CACHELINE_BYTES /* # complete cachelines */
- clrlwi r5,r5,32-LG_CACHELINE_BYTES
- li r11,4
- mtctr r0
- beq 63f
-53:
-#if !defined(CONFIG_8xx)
- dcbz r11,r6
-#endif
- COPY_16_BYTES
-#if L1_CACHE_LINE_SIZE >= 32
- COPY_16_BYTES
-#if L1_CACHE_LINE_SIZE >= 64
- COPY_16_BYTES
- COPY_16_BYTES
-#if L1_CACHE_LINE_SIZE >= 128
- COPY_16_BYTES
- COPY_16_BYTES
- COPY_16_BYTES
- COPY_16_BYTES
-#endif
-#endif
-#endif
- bdnz 53b
-
-63: srwi. r0,r5,2
- mtctr r0
- beq 64f
-30: lwzu r0,4(r4)
- stwu r0,4(r6)
- bdnz 30b
-
-64: andi. r0,r5,3
- mtctr r0
- beq+ 65f
-40: lbz r0,4(r4)
- stb r0,4(r6)
- addi r4,r4,1
- addi r6,r6,1
- bdnz 40b
-65: blr
-
-_GLOBAL(memmove)
- cmplw 0,r3,r4
- bgt backwards_memcpy
- /* fall through */
-
-_GLOBAL(memcpy)
- srwi. r7,r5,3
- addi r6,r3,-4
- addi r4,r4,-4
- beq 2f /* if less than 8 bytes to do */
- andi. r0,r6,3 /* get dest word aligned */
- mtctr r7
- bne 5f
-1: lwz r7,4(r4)
- lwzu r8,8(r4)
- stw r7,4(r6)
- stwu r8,8(r6)
- bdnz 1b
- andi. r5,r5,7
-2: cmplwi 0,r5,4
- blt 3f
- lwzu r0,4(r4)
- addi r5,r5,-4
- stwu r0,4(r6)
-3: cmpwi 0,r5,0
- beqlr
- mtctr r5
- addi r4,r4,3
- addi r6,r6,3
-4: lbzu r0,1(r4)
- stbu r0,1(r6)
- bdnz 4b
- blr
-5: subfic r0,r0,4
- mtctr r0
-6: lbz r7,4(r4)
- addi r4,r4,1
- stb r7,4(r6)
- addi r6,r6,1
- bdnz 6b
- subf r5,r0,r5
- rlwinm. r7,r5,32-3,3,31
- beq 2b
- mtctr r7
- b 1b
-
-_GLOBAL(backwards_memcpy)
- rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */
- add r6,r3,r5
- add r4,r4,r5
- beq 2f
- andi. r0,r6,3
- mtctr r7
- bne 5f
-1: lwz r7,-4(r4)
- lwzu r8,-8(r4)
- stw r7,-4(r6)
- stwu r8,-8(r6)
- bdnz 1b
- andi. r5,r5,7
-2: cmplwi 0,r5,4
- blt 3f
- lwzu r0,-4(r4)
- subi r5,r5,4
- stwu r0,-4(r6)
-3: cmpwi 0,r5,0
- beqlr
- mtctr r5
-4: lbzu r0,-1(r4)
- stbu r0,-1(r6)
- bdnz 4b
- blr
-5: mtctr r0
-6: lbzu r7,-1(r4)
- stbu r7,-1(r6)
- bdnz 6b
- subf r5,r0,r5
- rlwinm. r7,r5,32-3,3,31
- beq 2b
- mtctr r7
- b 1b
-
-_GLOBAL(__copy_tofrom_user)
- addi r4,r4,-4
- addi r6,r3,-4
- neg r0,r3
- andi. r0,r0,CACHELINE_MASK /* # bytes to start of cache line */
- beq 58f
-
- cmplw 0,r5,r0 /* is this more than total to do? */
- blt 63f /* if not much to do */
- andi. r8,r0,3 /* get it word-aligned first */
- mtctr r8
- beq+ 61f
-70: lbz r9,4(r4) /* do some bytes */
-71: stb r9,4(r6)
- addi r4,r4,1
- addi r6,r6,1
- bdnz 70b
-61: subf r5,r0,r5
- srwi. r0,r0,2
- mtctr r0
- beq 58f
-72: lwzu r9,4(r4) /* do some words */
-73: stwu r9,4(r6)
- bdnz 72b
-
- .section __ex_table,"a"
- .align 2
- .long 70b,100f
- .long 71b,101f
- .long 72b,102f
- .long 73b,103f
- .text
-
-58: srwi. r0,r5,LG_CACHELINE_BYTES /* # complete cachelines */
- clrlwi r5,r5,32-LG_CACHELINE_BYTES
- li r11,4
- beq 63f
-
-#ifdef CONFIG_8xx
- /* Don't use prefetch on 8xx */
- mtctr r0
- li r0,0
-53: COPY_16_BYTES_WITHEX(0)
- bdnz 53b
-
-#else /* not CONFIG_8xx */
- /* Here we decide how far ahead to prefetch the source */
- li r3,4
- cmpwi r0,1
- li r7,0
- ble 114f
- li r7,1
-#if MAX_COPY_PREFETCH > 1
- /* Heuristically, for large transfers we prefetch
- MAX_COPY_PREFETCH cachelines ahead. For small transfers
- we prefetch 1 cacheline ahead. */
- cmpwi r0,MAX_COPY_PREFETCH
- ble 112f
- li r7,MAX_COPY_PREFETCH
-112: mtctr r7
-111: dcbt r3,r4
- addi r3,r3,CACHELINE_BYTES
- bdnz 111b
-#else
- dcbt r3,r4
- addi r3,r3,CACHELINE_BYTES
-#endif /* MAX_COPY_PREFETCH > 1 */
-
-114: subf r8,r7,r0
- mr r0,r7
- mtctr r8
-
-53: dcbt r3,r4
-54: dcbz r11,r6
- .section __ex_table,"a"
- .align 2
- .long 54b,105f
- .text
-/* the main body of the cacheline loop */
- COPY_16_BYTES_WITHEX(0)
-#if L1_CACHE_LINE_SIZE >= 32
- COPY_16_BYTES_WITHEX(1)
-#if L1_CACHE_LINE_SIZE >= 64
- COPY_16_BYTES_WITHEX(2)
- COPY_16_BYTES_WITHEX(3)
-#if L1_CACHE_LINE_SIZE >= 128
- COPY_16_BYTES_WITHEX(4)
- COPY_16_BYTES_WITHEX(5)
- COPY_16_BYTES_WITHEX(6)
- COPY_16_BYTES_WITHEX(7)
-#endif
-#endif
-#endif
- bdnz 53b
- cmpwi r0,0
- li r3,4
- li r7,0
- bne 114b
-#endif /* CONFIG_8xx */
-
-63: srwi. r0,r5,2
- mtctr r0
- beq 64f
-30: lwzu r0,4(r4)
-31: stwu r0,4(r6)
- bdnz 30b
-
-64: andi. r0,r5,3
- mtctr r0
- beq+ 65f
-40: lbz r0,4(r4)
-41: stb r0,4(r6)
- addi r4,r4,1
- addi r6,r6,1
- bdnz 40b
-65: li r3,0
- blr
-
-/* read fault, initial single-byte copy */
-100: li r9,0
- b 90f
-/* write fault, initial single-byte copy */
-101: li r9,1
-90: subf r5,r8,r5
- li r3,0
- b 99f
-/* read fault, initial word copy */
-102: li r9,0
- b 91f
-/* write fault, initial word copy */
-103: li r9,1
-91: li r3,2
- b 99f
-
-/*
- * this stuff handles faults in the cacheline loop and branches to either
- * 104f (if in read part) or 105f (if in write part), after updating r5
- */
- COPY_16_BYTES_EXCODE(0)
-#if L1_CACHE_LINE_SIZE >= 32
- COPY_16_BYTES_EXCODE(1)
-#if L1_CACHE_LINE_SIZE >= 64
- COPY_16_BYTES_EXCODE(2)
- COPY_16_BYTES_EXCODE(3)
-#if L1_CACHE_LINE_SIZE >= 128
- COPY_16_BYTES_EXCODE(4)
- COPY_16_BYTES_EXCODE(5)
- COPY_16_BYTES_EXCODE(6)
- COPY_16_BYTES_EXCODE(7)
-#endif
-#endif
-#endif
-
-/* read fault in cacheline loop */
-104: li r9,0
- b 92f
-/* fault on dcbz (effectively a write fault) */
-/* or write fault in cacheline loop */
-105: li r9,1
-92: li r3,LG_CACHELINE_BYTES
- mfctr r8
- add r0,r0,r8
- b 106f
-/* read fault in final word loop */
-108: li r9,0
- b 93f
-/* write fault in final word loop */
-109: li r9,1
-93: andi. r5,r5,3
- li r3,2
- b 99f
-/* read fault in final byte loop */
-110: li r9,0
- b 94f
-/* write fault in final byte loop */
-111: li r9,1
-94: li r5,0
- li r3,0
-/*
- * At this stage the number of bytes not copied is
- * r5 + (ctr << r3), and r9 is 0 for read or 1 for write.
- */
-99: mfctr r0
-106: slw r3,r0,r3
- add. r3,r3,r5
- beq 120f /* shouldn't happen */
- cmpwi 0,r9,0
- bne 120f
-/* for a read fault, first try to continue the copy one byte at a time */
- mtctr r3
-130: lbz r0,4(r4)
-131: stb r0,4(r6)
- addi r4,r4,1
- addi r6,r6,1
- bdnz 130b
-/* then clear out the destination: r3 bytes starting at 4(r6) */
-132: mfctr r3
- srwi. r0,r3,2
- li r9,0
- mtctr r0
- beq 113f
-112: stwu r9,4(r6)
- bdnz 112b
-113: andi. r0,r3,3
- mtctr r0
- beq 120f
-114: stb r9,4(r6)
- addi r6,r6,1
- bdnz 114b
-120: blr
-
- .section __ex_table,"a"
- .align 2
- .long 30b,108b
- .long 31b,109b
- .long 40b,110b
- .long 41b,111b
- .long 130b,132b
- .long 131b,120b
- .long 112b,120b
- .long 114b,120b
- .text
diff --git a/trunk/arch/powerpc/lib/copypage.S b/trunk/arch/powerpc/lib/copypage.S
deleted file mode 100644
index 733d61618bbf..000000000000
--- a/trunk/arch/powerpc/lib/copypage.S
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * arch/ppc64/lib/copypage.S
- *
- * Copyright (C) 2002 Paul Mackerras, 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
-#include
-
-_GLOBAL(copy_page)
- std r31,-8(1)
- std r30,-16(1)
- std r29,-24(1)
- std r28,-32(1)
- std r27,-40(1)
- std r26,-48(1)
- std r25,-56(1)
- std r24,-64(1)
- std r23,-72(1)
- std r22,-80(1)
- std r21,-88(1)
- std r20,-96(1)
- li r5,4096/32 - 1
- addi r3,r3,-8
- li r12,5
-0: addi r5,r5,-24
- mtctr r12
- ld r22,640(4)
- ld r21,512(4)
- ld r20,384(4)
- ld r11,256(4)
- ld r9,128(4)
- ld r7,0(4)
- ld r25,648(4)
- ld r24,520(4)
- ld r23,392(4)
- ld r10,264(4)
- ld r8,136(4)
- ldu r6,8(4)
- cmpwi r5,24
-1: std r22,648(3)
- std r21,520(3)
- std r20,392(3)
- std r11,264(3)
- std r9,136(3)
- std r7,8(3)
- ld r28,648(4)
- ld r27,520(4)
- ld r26,392(4)
- ld r31,264(4)
- ld r30,136(4)
- ld r29,8(4)
- std r25,656(3)
- std r24,528(3)
- std r23,400(3)
- std r10,272(3)
- std r8,144(3)
- std r6,16(3)
- ld r22,656(4)
- ld r21,528(4)
- ld r20,400(4)
- ld r11,272(4)
- ld r9,144(4)
- ld r7,16(4)
- std r28,664(3)
- std r27,536(3)
- std r26,408(3)
- std r31,280(3)
- std r30,152(3)
- stdu r29,24(3)
- ld r25,664(4)
- ld r24,536(4)
- ld r23,408(4)
- ld r10,280(4)
- ld r8,152(4)
- ldu r6,24(4)
- bdnz 1b
- std r22,648(3)
- std r21,520(3)
- std r20,392(3)
- std r11,264(3)
- std r9,136(3)
- std r7,8(3)
- addi r4,r4,640
- addi r3,r3,648
- bge 0b
- mtctr r5
- ld r7,0(4)
- ld r8,8(4)
- ldu r9,16(4)
-3: ld r10,8(4)
- std r7,8(3)
- ld r7,16(4)
- std r8,16(3)
- ld r8,24(4)
- std r9,24(3)
- ldu r9,32(4)
- stdu r10,32(3)
- bdnz 3b
-4: ld r10,8(4)
- std r7,8(3)
- std r8,16(3)
- std r9,24(3)
- std r10,32(3)
-9: ld r20,-96(1)
- ld r21,-88(1)
- ld r22,-80(1)
- ld r23,-72(1)
- ld r24,-64(1)
- ld r25,-56(1)
- ld r26,-48(1)
- ld r27,-40(1)
- ld r28,-32(1)
- ld r29,-24(1)
- ld r30,-16(1)
- ld r31,-8(1)
- blr
diff --git a/trunk/arch/powerpc/lib/copyuser.S b/trunk/arch/powerpc/lib/copyuser.S
deleted file mode 100644
index a0b3fbbd6fb1..000000000000
--- a/trunk/arch/powerpc/lib/copyuser.S
+++ /dev/null
@@ -1,576 +0,0 @@
-/*
- * arch/ppc64/lib/copyuser.S
- *
- * Copyright (C) 2002 Paul Mackerras, 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
-#include
-
- .align 7
-_GLOBAL(__copy_tofrom_user)
- /* first check for a whole page copy on a page boundary */
- cmpldi cr1,r5,16
- cmpdi cr6,r5,4096
- or r0,r3,r4
- neg r6,r3 /* LS 3 bits = # bytes to 8-byte dest bdry */
- andi. r0,r0,4095
- std r3,-24(r1)
- crand cr0*4+2,cr0*4+2,cr6*4+2
- std r4,-16(r1)
- std r5,-8(r1)
- dcbt 0,r4
- beq .Lcopy_page
- andi. r6,r6,7
- mtcrf 0x01,r5
- blt cr1,.Lshort_copy
- bne .Ldst_unaligned
-.Ldst_aligned:
- andi. r0,r4,7
- addi r3,r3,-16
- bne .Lsrc_unaligned
- srdi r7,r5,4
-20: ld r9,0(r4)
- addi r4,r4,-8
- mtctr r7
- andi. r5,r5,7
- bf cr7*4+0,22f
- addi r3,r3,8
- addi r4,r4,8
- mr r8,r9
- blt cr1,72f
-21: ld r9,8(r4)
-70: std r8,8(r3)
-22: ldu r8,16(r4)
-71: stdu r9,16(r3)
- bdnz 21b
-72: std r8,8(r3)
- beq+ 3f
- addi r3,r3,16
-23: ld r9,8(r4)
-.Ldo_tail:
- bf cr7*4+1,1f
- rotldi r9,r9,32
-73: stw r9,0(r3)
- addi r3,r3,4
-1: bf cr7*4+2,2f
- rotldi r9,r9,16
-74: sth r9,0(r3)
- addi r3,r3,2
-2: bf cr7*4+3,3f
- rotldi r9,r9,8
-75: stb r9,0(r3)
-3: li r3,0
- blr
-
-.Lsrc_unaligned:
- srdi r6,r5,3
- addi r5,r5,-16
- subf r4,r0,r4
- srdi r7,r5,4
- sldi r10,r0,3
- cmpldi cr6,r6,3
- andi. r5,r5,7
- mtctr r7
- subfic r11,r10,64
- add r5,r5,r0
- bt cr7*4+0,28f
-
-24: ld r9,0(r4) /* 3+2n loads, 2+2n stores */
-25: ld r0,8(r4)
- sld r6,r9,r10
-26: ldu r9,16(r4)
- srd r7,r0,r11
- sld r8,r0,r10
- or r7,r7,r6
- blt cr6,79f
-27: ld r0,8(r4)
- b 2f
-
-28: ld r0,0(r4) /* 4+2n loads, 3+2n stores */
-29: ldu r9,8(r4)
- sld r8,r0,r10
- addi r3,r3,-8
- blt cr6,5f
-30: ld r0,8(r4)
- srd r12,r9,r11
- sld r6,r9,r10
-31: ldu r9,16(r4)
- or r12,r8,r12
- srd r7,r0,r11
- sld r8,r0,r10
- addi r3,r3,16
- beq cr6,78f
-
-1: or r7,r7,r6
-32: ld r0,8(r4)
-76: std r12,8(r3)
-2: srd r12,r9,r11
- sld r6,r9,r10
-33: ldu r9,16(r4)
- or r12,r8,r12
-77: stdu r7,16(r3)
- srd r7,r0,r11
- sld r8,r0,r10
- bdnz 1b
-
-78: std r12,8(r3)
- or r7,r7,r6
-79: std r7,16(r3)
-5: srd r12,r9,r11
- or r12,r8,r12
-80: std r12,24(r3)
- bne 6f
- li r3,0
- blr
-6: cmpwi cr1,r5,8
- addi r3,r3,32
- sld r9,r9,r10
- ble cr1,.Ldo_tail
-34: ld r0,8(r4)
- srd r7,r0,r11
- or r9,r7,r9
- b .Ldo_tail
-
-.Ldst_unaligned:
- mtcrf 0x01,r6 /* put #bytes to 8B bdry into cr7 */
- subf r5,r6,r5
- li r7,0
- cmpldi r1,r5,16
- bf cr7*4+3,1f
-35: lbz r0,0(r4)
-81: stb r0,0(r3)
- addi r7,r7,1
-1: bf cr7*4+2,2f
-36: lhzx r0,r7,r4
-82: sthx r0,r7,r3
- addi r7,r7,2
-2: bf cr7*4+1,3f
-37: lwzx r0,r7,r4
-83: stwx r0,r7,r3
-3: mtcrf 0x01,r5
- add r4,r6,r4
- add r3,r6,r3
- b .Ldst_aligned
-
-.Lshort_copy:
- bf cr7*4+0,1f
-38: lwz r0,0(r4)
-39: lwz r9,4(r4)
- addi r4,r4,8
-84: stw r0,0(r3)
-85: stw r9,4(r3)
- addi r3,r3,8
-1: bf cr7*4+1,2f
-40: lwz r0,0(r4)
- addi r4,r4,4
-86: stw r0,0(r3)
- addi r3,r3,4
-2: bf cr7*4+2,3f
-41: lhz r0,0(r4)
- addi r4,r4,2
-87: sth r0,0(r3)
- addi r3,r3,2
-3: bf cr7*4+3,4f
-42: lbz r0,0(r4)
-88: stb r0,0(r3)
-4: li r3,0
- blr
-
-/*
- * exception handlers follow
- * we have to return the number of bytes not copied
- * for an exception on a load, we set the rest of the destination to 0
- */
-
-136:
-137:
- add r3,r3,r7
- b 1f
-130:
-131:
- addi r3,r3,8
-120:
-122:
-124:
-125:
-126:
-127:
-128:
-129:
-133:
- addi r3,r3,8
-121:
-132:
- addi r3,r3,8
-123:
-134:
-135:
-138:
-139:
-140:
-141:
-142:
-
-/*
- * here we have had a fault on a load and r3 points to the first
- * unmodified byte of the destination
- */
-1: ld r6,-24(r1)
- ld r4,-16(r1)
- ld r5,-8(r1)
- subf r6,r6,r3
- add r4,r4,r6
- subf r5,r6,r5 /* #bytes left to go */
-
-/*
- * first see if we can copy any more bytes before hitting another exception
- */
- mtctr r5
-43: lbz r0,0(r4)
- addi r4,r4,1
-89: stb r0,0(r3)
- addi r3,r3,1
- bdnz 43b
- li r3,0 /* huh? all copied successfully this time? */
- blr
-
-/*
- * here we have trapped again, need to clear ctr bytes starting at r3
- */
-143: mfctr r5
- li r0,0
- mr r4,r3
- mr r3,r5 /* return the number of bytes not copied */
-1: andi. r9,r4,7
- beq 3f
-90: stb r0,0(r4)
- addic. r5,r5,-1
- addi r4,r4,1
- bne 1b
- blr
-3: cmpldi cr1,r5,8
- srdi r9,r5,3
- andi. r5,r5,7
- blt cr1,93f
- mtctr r9
-91: std r0,0(r4)
- addi r4,r4,8
- bdnz 91b
-93: beqlr
- mtctr r5
-92: stb r0,0(r4)
- addi r4,r4,1
- bdnz 92b
- blr
-
-/*
- * exception handlers for stores: we just need to work
- * out how many bytes weren't copied
- */
-182:
-183:
- add r3,r3,r7
- b 1f
-180:
- addi r3,r3,8
-171:
-177:
- addi r3,r3,8
-170:
-172:
-176:
-178:
- addi r3,r3,4
-185:
- addi r3,r3,4
-173:
-174:
-175:
-179:
-181:
-184:
-186:
-187:
-188:
-189:
-1:
- ld r6,-24(r1)
- ld r5,-8(r1)
- add r6,r6,r5
- subf r3,r3,r6 /* #bytes not copied */
-190:
-191:
-192:
- blr /* #bytes not copied in r3 */
-
- .section __ex_table,"a"
- .align 3
- .llong 20b,120b
- .llong 21b,121b
- .llong 70b,170b
- .llong 22b,122b
- .llong 71b,171b
- .llong 72b,172b
- .llong 23b,123b
- .llong 73b,173b
- .llong 74b,174b
- .llong 75b,175b
- .llong 24b,124b
- .llong 25b,125b
- .llong 26b,126b
- .llong 27b,127b
- .llong 28b,128b
- .llong 29b,129b
- .llong 30b,130b
- .llong 31b,131b
- .llong 32b,132b
- .llong 76b,176b
- .llong 33b,133b
- .llong 77b,177b
- .llong 78b,178b
- .llong 79b,179b
- .llong 80b,180b
- .llong 34b,134b
- .llong 35b,135b
- .llong 81b,181b
- .llong 36b,136b
- .llong 82b,182b
- .llong 37b,137b
- .llong 83b,183b
- .llong 38b,138b
- .llong 39b,139b
- .llong 84b,184b
- .llong 85b,185b
- .llong 40b,140b
- .llong 86b,186b
- .llong 41b,141b
- .llong 87b,187b
- .llong 42b,142b
- .llong 88b,188b
- .llong 43b,143b
- .llong 89b,189b
- .llong 90b,190b
- .llong 91b,191b
- .llong 92b,192b
-
- .text
-
-/*
- * Routine to copy a whole page of data, optimized for POWER4.
- * On POWER4 it is more than 50% faster than the simple loop
- * above (following the .Ldst_aligned label) but it runs slightly
- * slower on POWER3.
- */
-.Lcopy_page:
- std r31,-32(1)
- std r30,-40(1)
- std r29,-48(1)
- std r28,-56(1)
- std r27,-64(1)
- std r26,-72(1)
- std r25,-80(1)
- std r24,-88(1)
- std r23,-96(1)
- std r22,-104(1)
- std r21,-112(1)
- std r20,-120(1)
- li r5,4096/32 - 1
- addi r3,r3,-8
- li r0,5
-0: addi r5,r5,-24
- mtctr r0
-20: ld r22,640(4)
-21: ld r21,512(4)
-22: ld r20,384(4)
-23: ld r11,256(4)
-24: ld r9,128(4)
-25: ld r7,0(4)
-26: ld r25,648(4)
-27: ld r24,520(4)
-28: ld r23,392(4)
-29: ld r10,264(4)
-30: ld r8,136(4)
-31: ldu r6,8(4)
- cmpwi r5,24
-1:
-32: std r22,648(3)
-33: std r21,520(3)
-34: std r20,392(3)
-35: std r11,264(3)
-36: std r9,136(3)
-37: std r7,8(3)
-38: ld r28,648(4)
-39: ld r27,520(4)
-40: ld r26,392(4)
-41: ld r31,264(4)
-42: ld r30,136(4)
-43: ld r29,8(4)
-44: std r25,656(3)
-45: std r24,528(3)
-46: std r23,400(3)
-47: std r10,272(3)
-48: std r8,144(3)
-49: std r6,16(3)
-50: ld r22,656(4)
-51: ld r21,528(4)
-52: ld r20,400(4)
-53: ld r11,272(4)
-54: ld r9,144(4)
-55: ld r7,16(4)
-56: std r28,664(3)
-57: std r27,536(3)
-58: std r26,408(3)
-59: std r31,280(3)
-60: std r30,152(3)
-61: stdu r29,24(3)
-62: ld r25,664(4)
-63: ld r24,536(4)
-64: ld r23,408(4)
-65: ld r10,280(4)
-66: ld r8,152(4)
-67: ldu r6,24(4)
- bdnz 1b
-68: std r22,648(3)
-69: std r21,520(3)
-70: std r20,392(3)
-71: std r11,264(3)
-72: std r9,136(3)
-73: std r7,8(3)
-74: addi r4,r4,640
-75: addi r3,r3,648
- bge 0b
- mtctr r5
-76: ld r7,0(4)
-77: ld r8,8(4)
-78: ldu r9,16(4)
-3:
-79: ld r10,8(4)
-80: std r7,8(3)
-81: ld r7,16(4)
-82: std r8,16(3)
-83: ld r8,24(4)
-84: std r9,24(3)
-85: ldu r9,32(4)
-86: stdu r10,32(3)
- bdnz 3b
-4:
-87: ld r10,8(4)
-88: std r7,8(3)
-89: std r8,16(3)
-90: std r9,24(3)
-91: std r10,32(3)
-9: ld r20,-120(1)
- ld r21,-112(1)
- ld r22,-104(1)
- ld r23,-96(1)
- ld r24,-88(1)
- ld r25,-80(1)
- ld r26,-72(1)
- ld r27,-64(1)
- ld r28,-56(1)
- ld r29,-48(1)
- ld r30,-40(1)
- ld r31,-32(1)
- li r3,0
- blr
-
-/*
- * on an exception, reset to the beginning and jump back into the
- * standard __copy_tofrom_user
- */
-100: ld r20,-120(1)
- ld r21,-112(1)
- ld r22,-104(1)
- ld r23,-96(1)
- ld r24,-88(1)
- ld r25,-80(1)
- ld r26,-72(1)
- ld r27,-64(1)
- ld r28,-56(1)
- ld r29,-48(1)
- ld r30,-40(1)
- ld r31,-32(1)
- ld r3,-24(r1)
- ld r4,-16(r1)
- li r5,4096
- b .Ldst_aligned
-
- .section __ex_table,"a"
- .align 3
- .llong 20b,100b
- .llong 21b,100b
- .llong 22b,100b
- .llong 23b,100b
- .llong 24b,100b
- .llong 25b,100b
- .llong 26b,100b
- .llong 27b,100b
- .llong 28b,100b
- .llong 29b,100b
- .llong 30b,100b
- .llong 31b,100b
- .llong 32b,100b
- .llong 33b,100b
- .llong 34b,100b
- .llong 35b,100b
- .llong 36b,100b
- .llong 37b,100b
- .llong 38b,100b
- .llong 39b,100b
- .llong 40b,100b
- .llong 41b,100b
- .llong 42b,100b
- .llong 43b,100b
- .llong 44b,100b
- .llong 45b,100b
- .llong 46b,100b
- .llong 47b,100b
- .llong 48b,100b
- .llong 49b,100b
- .llong 50b,100b
- .llong 51b,100b
- .llong 52b,100b
- .llong 53b,100b
- .llong 54b,100b
- .llong 55b,100b
- .llong 56b,100b
- .llong 57b,100b
- .llong 58b,100b
- .llong 59b,100b
- .llong 60b,100b
- .llong 61b,100b
- .llong 62b,100b
- .llong 63b,100b
- .llong 64b,100b
- .llong 65b,100b
- .llong 66b,100b
- .llong 67b,100b
- .llong 68b,100b
- .llong 69b,100b
- .llong 70b,100b
- .llong 71b,100b
- .llong 72b,100b
- .llong 73b,100b
- .llong 74b,100b
- .llong 75b,100b
- .llong 76b,100b
- .llong 77b,100b
- .llong 78b,100b
- .llong 79b,100b
- .llong 80b,100b
- .llong 81b,100b
- .llong 82b,100b
- .llong 83b,100b
- .llong 84b,100b
- .llong 85b,100b
- .llong 86b,100b
- .llong 87b,100b
- .llong 88b,100b
- .llong 89b,100b
- .llong 90b,100b
- .llong 91b,100b
diff --git a/trunk/arch/powerpc/lib/div64.S b/trunk/arch/powerpc/lib/div64.S
deleted file mode 100644
index 3527569e9926..000000000000
--- a/trunk/arch/powerpc/lib/div64.S
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Divide a 64-bit unsigned number by a 32-bit unsigned number.
- * This routine assumes that the top 32 bits of the dividend are
- * non-zero to start with.
- * On entry, r3 points to the dividend, which get overwritten with
- * the 64-bit quotient, and r4 contains the divisor.
- * On exit, r3 contains the remainder.
- *
- * Copyright (C) 2002 Paul Mackerras, 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
-#include
-
-_GLOBAL(__div64_32)
- lwz r5,0(r3) # get the dividend into r5/r6
- lwz r6,4(r3)
- cmplw r5,r4
- li r7,0
- li r8,0
- blt 1f
- divwu r7,r5,r4 # if dividend.hi >= divisor,
- mullw r0,r7,r4 # quotient.hi = dividend.hi / divisor
- subf. r5,r0,r5 # dividend.hi %= divisor
- beq 3f
-1: mr r11,r5 # here dividend.hi != 0
- andis. r0,r5,0xc000
- bne 2f
- cntlzw r0,r5 # we are shifting the dividend right
- li r10,-1 # to make it < 2^32, and shifting
- srw r10,r10,r0 # the divisor right the same amount,
- add r9,r4,r10 # rounding up (so the estimate cannot
- andc r11,r6,r10 # ever be too large, only too small)
- andc r9,r9,r10
- or r11,r5,r11
- rotlw r9,r9,r0
- rotlw r11,r11,r0
- divwu r11,r11,r9 # then we divide the shifted quantities
-2: mullw r10,r11,r4 # to get an estimate of the quotient,
- mulhwu r9,r11,r4 # multiply the estimate by the divisor,
- subfc r6,r10,r6 # take the product from the divisor,
- add r8,r8,r11 # and add the estimate to the accumulated
- subfe. r5,r9,r5 # quotient
- bne 1b
-3: cmplw r6,r4
- blt 4f
- divwu r0,r6,r4 # perform the remaining 32-bit division
- mullw r10,r0,r4 # and get the remainder
- add r8,r8,r0
- subf r6,r10,r6
-4: stw r7,0(r3) # return the quotient in *r3
- stw r8,4(r3)
- mr r3,r6 # return the remainder in r3
- blr
diff --git a/trunk/arch/powerpc/lib/e2a.c b/trunk/arch/powerpc/lib/e2a.c
deleted file mode 100644
index d2b834887920..000000000000
--- a/trunk/arch/powerpc/lib/e2a.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * arch/ppc64/lib/e2a.c
- *
- * EBCDIC to ASCII conversion
- *
- * This function moved here from arch/ppc64/kernel/viopath.c
- *
- * (C) Copyright 2000-2004 IBM Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) anyu later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include
-
-unsigned char e2a(unsigned char x)
-{
- switch (x) {
- case 0xF0:
- return '0';
- case 0xF1:
- return '1';
- case 0xF2:
- return '2';
- case 0xF3:
- return '3';
- case 0xF4:
- return '4';
- case 0xF5:
- return '5';
- case 0xF6:
- return '6';
- case 0xF7:
- return '7';
- case 0xF8:
- return '8';
- case 0xF9:
- return '9';
- case 0xC1:
- return 'A';
- case 0xC2:
- return 'B';
- case 0xC3:
- return 'C';
- case 0xC4:
- return 'D';
- case 0xC5:
- return 'E';
- case 0xC6:
- return 'F';
- case 0xC7:
- return 'G';
- case 0xC8:
- return 'H';
- case 0xC9:
- return 'I';
- case 0xD1:
- return 'J';
- case 0xD2:
- return 'K';
- case 0xD3:
- return 'L';
- case 0xD4:
- return 'M';
- case 0xD5:
- return 'N';
- case 0xD6:
- return 'O';
- case 0xD7:
- return 'P';
- case 0xD8:
- return 'Q';
- case 0xD9:
- return 'R';
- case 0xE2:
- return 'S';
- case 0xE3:
- return 'T';
- case 0xE4:
- return 'U';
- case 0xE5:
- return 'V';
- case 0xE6:
- return 'W';
- case 0xE7:
- return 'X';
- case 0xE8:
- return 'Y';
- case 0xE9:
- return 'Z';
- }
- return ' ';
-}
-EXPORT_SYMBOL(e2a);
-
-
diff --git a/trunk/arch/powerpc/lib/memcpy.S b/trunk/arch/powerpc/lib/memcpy.S
deleted file mode 100644
index 9ccacdf5bcb9..000000000000
--- a/trunk/arch/powerpc/lib/memcpy.S
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * arch/ppc64/lib/memcpy.S
- *
- * Copyright (C) 2002 Paul Mackerras, 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
-#include
-
- .align 7
-_GLOBAL(memcpy)
- mtcrf 0x01,r5
- cmpldi cr1,r5,16
- neg r6,r3 # LS 3 bits = # bytes to 8-byte dest bdry
- andi. r6,r6,7
- dcbt 0,r4
- blt cr1,.Lshort_copy
- bne .Ldst_unaligned
-.Ldst_aligned:
- andi. r0,r4,7
- addi r3,r3,-16
- bne .Lsrc_unaligned
- srdi r7,r5,4
- ld r9,0(r4)
- addi r4,r4,-8
- mtctr r7
- andi. r5,r5,7
- bf cr7*4+0,2f
- addi r3,r3,8
- addi r4,r4,8
- mr r8,r9
- blt cr1,3f
-1: ld r9,8(r4)
- std r8,8(r3)
-2: ldu r8,16(r4)
- stdu r9,16(r3)
- bdnz 1b
-3: std r8,8(r3)
- beqlr
- addi r3,r3,16
- ld r9,8(r4)
-.Ldo_tail:
- bf cr7*4+1,1f
- rotldi r9,r9,32
- stw r9,0(r3)
- addi r3,r3,4
-1: bf cr7*4+2,2f
- rotldi r9,r9,16
- sth r9,0(r3)
- addi r3,r3,2
-2: bf cr7*4+3,3f
- rotldi r9,r9,8
- stb r9,0(r3)
-3: blr
-
-.Lsrc_unaligned:
- srdi r6,r5,3
- addi r5,r5,-16
- subf r4,r0,r4
- srdi r7,r5,4
- sldi r10,r0,3
- cmpdi cr6,r6,3
- andi. r5,r5,7
- mtctr r7
- subfic r11,r10,64
- add r5,r5,r0
-
- bt cr7*4+0,0f
-
- ld r9,0(r4) # 3+2n loads, 2+2n stores
- ld r0,8(r4)
- sld r6,r9,r10
- ldu r9,16(r4)
- srd r7,r0,r11
- sld r8,r0,r10
- or r7,r7,r6
- blt cr6,4f
- ld r0,8(r4)
- # s1<< in r8, d0=(s0<<|s1>>) in r7, s3 in r0, s2 in r9, nix in r6 & r12
- b 2f
-
-0: ld r0,0(r4) # 4+2n loads, 3+2n stores
- ldu r9,8(r4)
- sld r8,r0,r10
- addi r3,r3,-8
- blt cr6,5f
- ld r0,8(r4)
- srd r12,r9,r11
- sld r6,r9,r10
- ldu r9,16(r4)
- or r12,r8,r12
- srd r7,r0,r11
- sld r8,r0,r10
- addi r3,r3,16
- beq cr6,3f
-
- # d0=(s0<<|s1>>) in r12, s1<< in r6, s2>> in r7, s2<< in r8, s3 in r9
-1: or r7,r7,r6
- ld r0,8(r4)
- std r12,8(r3)
-2: srd r12,r9,r11
- sld r6,r9,r10
- ldu r9,16(r4)
- or r12,r8,r12
- stdu r7,16(r3)
- srd r7,r0,r11
- sld r8,r0,r10
- bdnz 1b
-
-3: std r12,8(r3)
- or r7,r7,r6
-4: std r7,16(r3)
-5: srd r12,r9,r11
- or r12,r8,r12
- std r12,24(r3)
- beqlr
- cmpwi cr1,r5,8
- addi r3,r3,32
- sld r9,r9,r10
- ble cr1,.Ldo_tail
- ld r0,8(r4)
- srd r7,r0,r11
- or r9,r7,r9
- b .Ldo_tail
-
-.Ldst_unaligned:
- mtcrf 0x01,r6 # put #bytes to 8B bdry into cr7
- subf r5,r6,r5
- li r7,0
- cmpldi r1,r5,16
- bf cr7*4+3,1f
- lbz r0,0(r4)
- stb r0,0(r3)
- addi r7,r7,1
-1: bf cr7*4+2,2f
- lhzx r0,r7,r4
- sthx r0,r7,r3
- addi r7,r7,2
-2: bf cr7*4+1,3f
- lwzx r0,r7,r4
- stwx r0,r7,r3
-3: mtcrf 0x01,r5
- add r4,r6,r4
- add r3,r6,r3
- b .Ldst_aligned
-
-.Lshort_copy:
- bf cr7*4+0,1f
- lwz r0,0(r4)
- lwz r9,4(r4)
- addi r4,r4,8
- stw r0,0(r3)
- stw r9,4(r3)
- addi r3,r3,8
-1: bf cr7*4+1,2f
- lwz r0,0(r4)
- addi r4,r4,4
- stw r0,0(r3)
- addi r3,r3,4
-2: bf cr7*4+2,3f
- lhz r0,0(r4)
- addi r4,r4,2
- sth r0,0(r3)
- addi r3,r3,2
-3: bf cr7*4+3,4f
- lbz r0,0(r4)
- stb r0,0(r3)
-4: blr
diff --git a/trunk/arch/powerpc/lib/rheap.c b/trunk/arch/powerpc/lib/rheap.c
deleted file mode 100644
index 42c5de2c898f..000000000000
--- a/trunk/arch/powerpc/lib/rheap.c
+++ /dev/null
@@ -1,693 +0,0 @@
-/*
- * arch/ppc/syslib/rheap.c
- *
- * A Remote Heap. Remote means that we don't touch the memory that the
- * heap points to. Normal heap implementations use the memory they manage
- * to place their list. We cannot do that because the memory we manage may
- * have special properties, for example it is uncachable or of different
- * endianess.
- *
- * Author: Pantelis Antoniou
- *
- * 2004 (c) INTRACOM S.A. Greece. This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-#include
-#include
-#include
-#include
-
-#include
-
-/*
- * Fixup a list_head, needed when copying lists. If the pointers fall
- * between s and e, apply the delta. This assumes that
- * sizeof(struct list_head *) == sizeof(unsigned long *).
- */
-static inline void fixup(unsigned long s, unsigned long e, int d,
- struct list_head *l)
-{
- unsigned long *pp;
-
- pp = (unsigned long *)&l->next;
- if (*pp >= s && *pp < e)
- *pp += d;
-
- pp = (unsigned long *)&l->prev;
- if (*pp >= s && *pp < e)
- *pp += d;
-}
-
-/* Grow the allocated blocks */
-static int grow(rh_info_t * info, int max_blocks)
-{
- rh_block_t *block, *blk;
- int i, new_blocks;
- int delta;
- unsigned long blks, blke;
-
- if (max_blocks <= info->max_blocks)
- return -EINVAL;
-
- new_blocks = max_blocks - info->max_blocks;
-
- block = kmalloc(sizeof(rh_block_t) * max_blocks, GFP_KERNEL);
- if (block == NULL)
- return -ENOMEM;
-
- if (info->max_blocks > 0) {
-
- /* copy old block area */
- memcpy(block, info->block,
- sizeof(rh_block_t) * info->max_blocks);
-
- delta = (char *)block - (char *)info->block;
-
- /* and fixup list pointers */
- blks = (unsigned long)info->block;
- blke = (unsigned long)(info->block + info->max_blocks);
-
- for (i = 0, blk = block; i < info->max_blocks; i++, blk++)
- fixup(blks, blke, delta, &blk->list);
-
- fixup(blks, blke, delta, &info->empty_list);
- fixup(blks, blke, delta, &info->free_list);
- fixup(blks, blke, delta, &info->taken_list);
-
- /* free the old allocated memory */
- if ((info->flags & RHIF_STATIC_BLOCK) == 0)
- kfree(info->block);
- }
-
- info->block = block;
- info->empty_slots += new_blocks;
- info->max_blocks = max_blocks;
- info->flags &= ~RHIF_STATIC_BLOCK;
-
- /* add all new blocks to the free list */
- for (i = 0, blk = block + info->max_blocks; i < new_blocks; i++, blk++)
- list_add(&blk->list, &info->empty_list);
-
- return 0;
-}
-
-/*
- * Assure at least the required amount of empty slots. If this function
- * causes a grow in the block area then all pointers kept to the block
- * area are invalid!
- */
-static int assure_empty(rh_info_t * info, int slots)
-{
- int max_blocks;
-
- /* This function is not meant to be used to grow uncontrollably */
- if (slots >= 4)
- return -EINVAL;
-
- /* Enough space */
- if (info->empty_slots >= slots)
- return 0;
-
- /* Next 16 sized block */
- max_blocks = ((info->max_blocks + slots) + 15) & ~15;
-
- return grow(info, max_blocks);
-}
-
-static rh_block_t *get_slot(rh_info_t * info)
-{
- rh_block_t *blk;
-
- /* If no more free slots, and failure to extend. */
- /* XXX: You should have called assure_empty before */
- if (info->empty_slots == 0) {
- printk(KERN_ERR "rh: out of slots; crash is imminent.\n");
- return NULL;
- }
-
- /* Get empty slot to use */
- blk = list_entry(info->empty_list.next, rh_block_t, list);
- list_del_init(&blk->list);
- info->empty_slots--;
-
- /* Initialize */
- blk->start = NULL;
- blk->size = 0;
- blk->owner = NULL;
-
- return blk;
-}
-
-static inline void release_slot(rh_info_t * info, rh_block_t * blk)
-{
- list_add(&blk->list, &info->empty_list);
- info->empty_slots++;
-}
-
-static void attach_free_block(rh_info_t * info, rh_block_t * blkn)
-{
- rh_block_t *blk;
- rh_block_t *before;
- rh_block_t *after;
- rh_block_t *next;
- int size;
- unsigned long s, e, bs, be;
- struct list_head *l;
-
- /* We assume that they are aligned properly */
- size = blkn->size;
- s = (unsigned long)blkn->start;
- e = s + size;
-
- /* Find the blocks immediately before and after the given one
- * (if any) */
- before = NULL;
- after = NULL;
- next = NULL;
-
- list_for_each(l, &info->free_list) {
- blk = list_entry(l, rh_block_t, list);
-
- bs = (unsigned long)blk->start;
- be = bs + blk->size;
-
- if (next == NULL && s >= bs)
- next = blk;
-
- if (be == s)
- before = blk;
-
- if (e == bs)
- after = blk;
-
- /* If both are not null, break now */
- if (before != NULL && after != NULL)
- break;
- }
-
- /* Now check if they are really adjacent */
- if (before != NULL && s != (unsigned long)before->start + before->size)
- before = NULL;
-
- if (after != NULL && e != (unsigned long)after->start)
- after = NULL;
-
- /* No coalescing; list insert and return */
- if (before == NULL && after == NULL) {
-
- if (next != NULL)
- list_add(&blkn->list, &next->list);
- else
- list_add(&blkn->list, &info->free_list);
-
- return;
- }
-
- /* We don't need it anymore */
- release_slot(info, blkn);
-
- /* Grow the before block */
- if (before != NULL && after == NULL) {
- before->size += size;
- return;
- }
-
- /* Grow the after block backwards */
- if (before == NULL && after != NULL) {
- after->start = (int8_t *)after->start - size;
- after->size += size;
- return;
- }
-
- /* Grow the before block, and release the after block */
- before->size += size + after->size;
- list_del(&after->list);
- release_slot(info, after);
-}
-
-static void attach_taken_block(rh_info_t * info, rh_block_t * blkn)
-{
- rh_block_t *blk;
- struct list_head *l;
-
- /* Find the block immediately before the given one (if any) */
- list_for_each(l, &info->taken_list) {
- blk = list_entry(l, rh_block_t, list);
- if (blk->start > blkn->start) {
- list_add_tail(&blkn->list, &blk->list);
- return;
- }
- }
-
- list_add_tail(&blkn->list, &info->taken_list);
-}
-
-/*
- * Create a remote heap dynamically. Note that no memory for the blocks
- * are allocated. It will upon the first allocation
- */
-rh_info_t *rh_create(unsigned int alignment)
-{
- rh_info_t *info;
-
- /* Alignment must be a power of two */
- if ((alignment & (alignment - 1)) != 0)
- return ERR_PTR(-EINVAL);
-
- info = kmalloc(sizeof(*info), GFP_KERNEL);
- if (info == NULL)
- return ERR_PTR(-ENOMEM);
-
- info->alignment = alignment;
-
- /* Initially everything as empty */
- info->block = NULL;
- info->max_blocks = 0;
- info->empty_slots = 0;
- info->flags = 0;
-
- INIT_LIST_HEAD(&info->empty_list);
- INIT_LIST_HEAD(&info->free_list);
- INIT_LIST_HEAD(&info->taken_list);
-
- return info;
-}
-
-/*
- * Destroy a dynamically created remote heap. Deallocate only if the areas
- * are not static
- */
-void rh_destroy(rh_info_t * info)
-{
- if ((info->flags & RHIF_STATIC_BLOCK) == 0 && info->block != NULL)
- kfree(info->block);
-
- if ((info->flags & RHIF_STATIC_INFO) == 0)
- kfree(info);
-}
-
-/*
- * Initialize in place a remote heap info block. This is needed to support
- * operation very early in the startup of the kernel, when it is not yet safe
- * to call kmalloc.
- */
-void rh_init(rh_info_t * info, unsigned int alignment, int max_blocks,
- rh_block_t * block)
-{
- int i;
- rh_block_t *blk;
-
- /* Alignment must be a power of two */
- if ((alignment & (alignment - 1)) != 0)
- return;
-
- info->alignment = alignment;
-
- /* Initially everything as empty */
- info->block = block;
- info->max_blocks = max_blocks;
- info->empty_slots = max_blocks;
- info->flags = RHIF_STATIC_INFO | RHIF_STATIC_BLOCK;
-
- INIT_LIST_HEAD(&info->empty_list);
- INIT_LIST_HEAD(&info->free_list);
- INIT_LIST_HEAD(&info->taken_list);
-
- /* Add all new blocks to the free list */
- for (i = 0, blk = block; i < max_blocks; i++, blk++)
- list_add(&blk->list, &info->empty_list);
-}
-
-/* Attach a free memory region, coalesces regions if adjuscent */
-int rh_attach_region(rh_info_t * info, void *start, int size)
-{
- rh_block_t *blk;
- unsigned long s, e, m;
- int r;
-
- /* The region must be aligned */
- s = (unsigned long)start;
- e = s + size;
- m = info->alignment - 1;
-
- /* Round start up */
- s = (s + m) & ~m;
-
- /* Round end down */
- e = e & ~m;
-
- /* Take final values */
- start = (void *)s;
- size = (int)(e - s);
-
- /* Grow the blocks, if needed */
- r = assure_empty(info, 1);
- if (r < 0)
- return r;
-
- blk = get_slot(info);
- blk->start = start;
- blk->size = size;
- blk->owner = NULL;
-
- attach_free_block(info, blk);
-
- return 0;
-}
-
-/* Detatch given address range, splits free block if needed. */
-void *rh_detach_region(rh_info_t * info, void *start, int size)
-{
- struct list_head *l;
- rh_block_t *blk, *newblk;
- unsigned long s, e, m, bs, be;
-
- /* Validate size */
- if (size <= 0)
- return ERR_PTR(-EINVAL);
-
- /* The region must be aligned */
- s = (unsigned long)start;
- e = s + size;
- m = info->alignment - 1;
-
- /* Round start up */
- s = (s + m) & ~m;
-
- /* Round end down */
- e = e & ~m;
-
- if (assure_empty(info, 1) < 0)
- return ERR_PTR(-ENOMEM);
-
- blk = NULL;
- list_for_each(l, &info->free_list) {
- blk = list_entry(l, rh_block_t, list);
- /* The range must lie entirely inside one free block */
- bs = (unsigned long)blk->start;
- be = (unsigned long)blk->start + blk->size;
- if (s >= bs && e <= be)
- break;
- blk = NULL;
- }
-
- if (blk == NULL)
- return ERR_PTR(-ENOMEM);
-
- /* Perfect fit */
- if (bs == s && be == e) {
- /* Delete from free list, release slot */
- list_del(&blk->list);
- release_slot(info, blk);
- return (void *)s;
- }
-
- /* blk still in free list, with updated start and/or size */
- if (bs == s || be == e) {
- if (bs == s)
- blk->start = (int8_t *)blk->start + size;
- blk->size -= size;
-
- } else {
- /* The front free fragment */
- blk->size = s - bs;
-
- /* the back free fragment */
- newblk = get_slot(info);
- newblk->start = (void *)e;
- newblk->size = be - e;
-
- list_add(&newblk->list, &blk->list);
- }
-
- return (void *)s;
-}
-
-void *rh_alloc(rh_info_t * info, int size, const char *owner)
-{
- struct list_head *l;
- rh_block_t *blk;
- rh_block_t *newblk;
- void *start;
-
- /* Validate size */
- if (size <= 0)
- return ERR_PTR(-EINVAL);
-
- /* Align to configured alignment */
- size = (size + (info->alignment - 1)) & ~(info->alignment - 1);
-
- if (assure_empty(info, 1) < 0)
- return ERR_PTR(-ENOMEM);
-
- blk = NULL;
- list_for_each(l, &info->free_list) {
- blk = list_entry(l, rh_block_t, list);
- if (size <= blk->size)
- break;
- blk = NULL;
- }
-
- if (blk == NULL)
- return ERR_PTR(-ENOMEM);
-
- /* Just fits */
- if (blk->size == size) {
- /* Move from free list to taken list */
- list_del(&blk->list);
- blk->owner = owner;
- start = blk->start;
-
- attach_taken_block(info, blk);
-
- return start;
- }
-
- newblk = get_slot(info);
- newblk->start = blk->start;
- newblk->size = size;
- newblk->owner = owner;
-
- /* blk still in free list, with updated start, size */
- blk->start = (int8_t *)blk->start + size;
- blk->size -= size;
-
- start = newblk->start;
-
- attach_taken_block(info, newblk);
-
- return start;
-}
-
-/* allocate at precisely the given address */
-void *rh_alloc_fixed(rh_info_t * info, void *start, int size, const char *owner)
-{
- struct list_head *l;
- rh_block_t *blk, *newblk1, *newblk2;
- unsigned long s, e, m, bs, be;
-
- /* Validate size */
- if (size <= 0)
- return ERR_PTR(-EINVAL);
-
- /* The region must be aligned */
- s = (unsigned long)start;
- e = s + size;
- m = info->alignment - 1;
-
- /* Round start up */
- s = (s + m) & ~m;
-
- /* Round end down */
- e = e & ~m;
-
- if (assure_empty(info, 2) < 0)
- return ERR_PTR(-ENOMEM);
-
- blk = NULL;
- list_for_each(l, &info->free_list) {
- blk = list_entry(l, rh_block_t, list);
- /* The range must lie entirely inside one free block */
- bs = (unsigned long)blk->start;
- be = (unsigned long)blk->start + blk->size;
- if (s >= bs && e <= be)
- break;
- }
-
- if (blk == NULL)
- return ERR_PTR(-ENOMEM);
-
- /* Perfect fit */
- if (bs == s && be == e) {
- /* Move from free list to taken list */
- list_del(&blk->list);
- blk->owner = owner;
-
- start = blk->start;
- attach_taken_block(info, blk);
-
- return start;
-
- }
-
- /* blk still in free list, with updated start and/or size */
- if (bs == s || be == e) {
- if (bs == s)
- blk->start = (int8_t *)blk->start + size;
- blk->size -= size;
-
- } else {
- /* The front free fragment */
- blk->size = s - bs;
-
- /* The back free fragment */
- newblk2 = get_slot(info);
- newblk2->start = (void *)e;
- newblk2->size = be - e;
-
- list_add(&newblk2->list, &blk->list);
- }
-
- newblk1 = get_slot(info);
- newblk1->start = (void *)s;
- newblk1->size = e - s;
- newblk1->owner = owner;
-
- start = newblk1->start;
- attach_taken_block(info, newblk1);
-
- return start;
-}
-
-int rh_free(rh_info_t * info, void *start)
-{
- rh_block_t *blk, *blk2;
- struct list_head *l;
- int size;
-
- /* Linear search for block */
- blk = NULL;
- list_for_each(l, &info->taken_list) {
- blk2 = list_entry(l, rh_block_t, list);
- if (start < blk2->start)
- break;
- blk = blk2;
- }
-
- if (blk == NULL || start > (blk->start + blk->size))
- return -EINVAL;
-
- /* Remove from taken list */
- list_del(&blk->list);
-
- /* Get size of freed block */
- size = blk->size;
- attach_free_block(info, blk);
-
- return size;
-}
-
-int rh_get_stats(rh_info_t * info, int what, int max_stats, rh_stats_t * stats)
-{
- rh_block_t *blk;
- struct list_head *l;
- struct list_head *h;
- int nr;
-
- switch (what) {
-
- case RHGS_FREE:
- h = &info->free_list;
- break;
-
- case RHGS_TAKEN:
- h = &info->taken_list;
- break;
-
- default:
- return -EINVAL;
- }
-
- /* Linear search for block */
- nr = 0;
- list_for_each(l, h) {
- blk = list_entry(l, rh_block_t, list);
- if (stats != NULL && nr < max_stats) {
- stats->start = blk->start;
- stats->size = blk->size;
- stats->owner = blk->owner;
- stats++;
- }
- nr++;
- }
-
- return nr;
-}
-
-int rh_set_owner(rh_info_t * info, void *start, const char *owner)
-{
- rh_block_t *blk, *blk2;
- struct list_head *l;
- int size;
-
- /* Linear search for block */
- blk = NULL;
- list_for_each(l, &info->taken_list) {
- blk2 = list_entry(l, rh_block_t, list);
- if (start < blk2->start)
- break;
- blk = blk2;
- }
-
- if (blk == NULL || start > (blk->start + blk->size))
- return -EINVAL;
-
- blk->owner = owner;
- size = blk->size;
-
- return size;
-}
-
-void rh_dump(rh_info_t * info)
-{
- static rh_stats_t st[32]; /* XXX maximum 32 blocks */
- int maxnr;
- int i, nr;
-
- maxnr = sizeof(st) / sizeof(st[0]);
-
- printk(KERN_INFO
- "info @0x%p (%d slots empty / %d max)\n",
- info, info->empty_slots, info->max_blocks);
-
- printk(KERN_INFO " Free:\n");
- nr = rh_get_stats(info, RHGS_FREE, maxnr, st);
- if (nr > maxnr)
- nr = maxnr;
- for (i = 0; i < nr; i++)
- printk(KERN_INFO
- " 0x%p-0x%p (%u)\n",
- st[i].start, (int8_t *) st[i].start + st[i].size,
- st[i].size);
- printk(KERN_INFO "\n");
-
- printk(KERN_INFO " Taken:\n");
- nr = rh_get_stats(info, RHGS_TAKEN, maxnr, st);
- if (nr > maxnr)
- nr = maxnr;
- for (i = 0; i < nr; i++)
- printk(KERN_INFO
- " 0x%p-0x%p (%u) %s\n",
- st[i].start, (int8_t *) st[i].start + st[i].size,
- st[i].size, st[i].owner != NULL ? st[i].owner : "");
- printk(KERN_INFO "\n");
-}
-
-void rh_dump_blk(rh_info_t * info, rh_block_t * blk)
-{
- printk(KERN_INFO
- "blk @0x%p: 0x%p-0x%p (%u)\n",
- blk, blk->start, (int8_t *) blk->start + blk->size, blk->size);
-}
diff --git a/trunk/arch/powerpc/lib/sstep.c b/trunk/arch/powerpc/lib/sstep.c
deleted file mode 100644
index e79123d1485c..000000000000
--- a/trunk/arch/powerpc/lib/sstep.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Single-step support.
- *
- * Copyright (C) 2004 Paul Mackerras , IBM
- *
- * 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
-#include