summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/alpha/kernel/alpha_ksyms.c6
-rw-r--r--arch/alpha/kernel/entry.S5
-rw-r--r--arch/alpha/kernel/head.S5
-rw-r--r--arch/alpha/kernel/irq.c4
-rw-r--r--arch/alpha/kernel/pci.c140
-rw-r--r--arch/alpha/kernel/process.c8
-rw-r--r--arch/alpha/kernel/proto.h3
-rw-r--r--arch/alpha/kernel/setup.c4
-rw-r--r--arch/alpha/kernel/time.c7
-rw-r--r--arch/alpha/kernel/traps.c2
-rw-r--r--arch/alpha/mm/fault.c5
-rw-r--r--arch/alpha/mm/init.c2
-rw-r--r--arch/arm/boot/compressed/head.S271
-rw-r--r--arch/arm/config.in4
-rw-r--r--arch/arm/def-configs/ebsa110248
-rw-r--r--arch/arm/defconfig4
-rw-r--r--arch/arm/kernel/arch.c496
-rw-r--r--arch/arm/kernel/arch.h58
-rw-r--r--arch/arm/kernel/armksyms.c1
-rw-r--r--arch/arm/kernel/arthur.c6
-rw-r--r--arch/arm/kernel/bios32.c55
-rw-r--r--arch/arm/kernel/debug-armv.S13
-rw-r--r--arch/arm/kernel/dec21285.c37
-rw-r--r--arch/arm/kernel/entry-common.S2
-rw-r--r--arch/arm/kernel/head-armv.S165
-rw-r--r--arch/arm/kernel/irq.c6
-rw-r--r--arch/arm/kernel/setup.c145
-rw-r--r--arch/arm/kernel/time.c45
-rw-r--r--arch/arm/lib/csumpartialcopy.S157
-rw-r--r--arch/arm/lib/csumpartialcopyuser.S30
-rw-r--r--arch/arm/mm/consistent.c29
-rw-r--r--arch/arm/mm/fault-common.c2
-rw-r--r--arch/arm/mm/init.c295
-rw-r--r--arch/arm/mm/map.h6
-rw-r--r--arch/arm/mm/mm-armo.c4
-rw-r--r--arch/arm/mm/mm-armv.c22
-rw-r--r--arch/arm/mm/mm-ebsa110.c3
-rw-r--r--arch/arm/mm/mm-rpc.c2
-rw-r--r--arch/arm/mm/mm-sa1100.c162
-rw-r--r--arch/arm/mm/proc-sa110.S59
-rw-r--r--arch/i386/config.in34
-rw-r--r--arch/i386/defconfig11
-rw-r--r--arch/i386/kernel/acpi.c3
-rw-r--r--arch/i386/kernel/apic.c271
-rw-r--r--arch/i386/kernel/entry.S5
-rw-r--r--arch/i386/kernel/head.S16
-rw-r--r--arch/i386/kernel/i386_ksyms.c7
-rw-r--r--arch/i386/kernel/i8259.c2
-rw-r--r--arch/i386/kernel/io_apic.c242
-rw-r--r--arch/i386/kernel/irq.c8
-rw-r--r--arch/i386/kernel/mca.c12
-rw-r--r--arch/i386/kernel/mpparse.c239
-rw-r--r--arch/i386/kernel/mtrr.c34
-rw-r--r--arch/i386/kernel/pci-irq.c7
-rw-r--r--arch/i386/kernel/process.c1
-rw-r--r--arch/i386/kernel/setup.c8
-rw-r--r--arch/i386/kernel/signal.c4
-rw-r--r--arch/i386/kernel/smp.c114
-rw-r--r--arch/i386/kernel/smpboot.c135
-rw-r--r--arch/i386/kernel/traps.c2
-rw-r--r--arch/i386/kernel/visws_apic.c2
-rw-r--r--arch/i386/lib/delay.c3
-rw-r--r--arch/i386/mm/fault.c4
-rw-r--r--arch/ia64/Makefile20
-rw-r--r--arch/ia64/config.in9
-rw-r--r--arch/ia64/defconfig4
-rw-r--r--arch/ia64/dig/Makefile2
-rw-r--r--arch/ia64/dig/iosapic.c453
-rw-r--r--arch/ia64/dig/setup.c12
-rw-r--r--arch/ia64/hp/Makefile2
-rw-r--r--arch/ia64/ia32/Makefile2
-rw-r--r--arch/ia64/ia32/binfmt_elf32.c13
-rw-r--r--arch/ia64/ia32/ia32_entry.S63
-rw-r--r--arch/ia64/ia32/ia32_signal.c27
-rw-r--r--arch/ia64/ia32/ia32_traps.c47
-rw-r--r--arch/ia64/ia32/sys_ia32.c1096
-rw-r--r--arch/ia64/kdb/Makefile21
-rw-r--r--arch/ia64/kdb/kdb_bt.c104
-rw-r--r--arch/ia64/kdb/kdb_io.c350
-rw-r--r--arch/ia64/kdb/kdb_traps.c55
-rw-r--r--arch/ia64/kdb/kdbsupport.c1329
-rw-r--r--arch/ia64/kdb/pc_keyb.h127
-rw-r--r--arch/ia64/kernel/Makefile12
-rw-r--r--arch/ia64/kernel/acpi.c55
-rw-r--r--arch/ia64/kernel/efi.c22
-rw-r--r--arch/ia64/kernel/entry.S155
-rw-r--r--arch/ia64/kernel/gate.S36
-rw-r--r--arch/ia64/kernel/irq.c63
-rw-r--r--arch/ia64/kernel/irq_ia64.c93
-rw-r--r--arch/ia64/kernel/irq_internal.c36
-rw-r--r--arch/ia64/kernel/irq_lock.c287
-rw-r--r--arch/ia64/kernel/irq_sapic.c38
-rw-r--r--arch/ia64/kernel/ivt.S373
-rw-r--r--arch/ia64/kernel/mca.c251
-rw-r--r--arch/ia64/kernel/mca_asm.S176
-rw-r--r--arch/ia64/kernel/minstate.h205
-rw-r--r--arch/ia64/kernel/ptrace.c214
-rw-r--r--arch/ia64/kernel/sal.c32
-rw-r--r--arch/ia64/kernel/sal_stub.S24
-rw-r--r--arch/ia64/kernel/semaphore.c2
-rw-r--r--arch/ia64/kernel/setup.c40
-rw-r--r--arch/ia64/kernel/signal.c19
-rw-r--r--arch/ia64/kernel/smp.c176
-rw-r--r--arch/ia64/kernel/smpboot.c2
-rw-r--r--arch/ia64/kernel/time.c24
-rw-r--r--arch/ia64/kernel/traps.c37
-rw-r--r--arch/ia64/kernel/unaligned.c105
-rw-r--r--arch/ia64/lib/clear_user.S1
-rw-r--r--arch/ia64/lib/strlen.S1
-rw-r--r--arch/ia64/mm/fault.c2
-rw-r--r--arch/ia64/mm/init.c1
-rw-r--r--arch/ia64/mm/tlb.c2
-rw-r--r--arch/ia64/tools/Makefile2
-rw-r--r--arch/ia64/tools/print_offsets.c7
-rw-r--r--arch/ia64/vmlinux.lds.S17
-rw-r--r--arch/m68k/mm/fault.c2
-rw-r--r--arch/mips/baget/vacserial.c2
-rw-r--r--arch/mips/defconfig1
-rw-r--r--arch/mips/defconfig-ip221
-rw-r--r--arch/mips/kernel/irixelf.c12
-rw-r--r--arch/mips/kernel/sysirix.c6
-rw-r--r--arch/mips/mm/fault.c2
-rw-r--r--arch/mips64/defconfig1
-rw-r--r--arch/mips64/defconfig-ip271
-rw-r--r--arch/mips64/mm/fault.c2
-rw-r--r--arch/ppc/8xx_io/uart.c2
-rw-r--r--arch/ppc/defconfig4
-rw-r--r--arch/ppc/kernel/apus_setup.c12
-rw-r--r--arch/ppc/kernel/chrp_setup.c4
-rw-r--r--arch/ppc/kernel/gemini_prom.S7
-rw-r--r--arch/ppc/kernel/gemini_setup.c6
-rw-r--r--arch/ppc/kernel/hashtable.S32
-rw-r--r--arch/ppc/kernel/head.S30
-rw-r--r--arch/ppc/kernel/head_8xx.S14
-rw-r--r--arch/ppc/kernel/idle.c8
-rw-r--r--arch/ppc/kernel/irq.c14
-rw-r--r--arch/ppc/kernel/misc.S4
-rw-r--r--arch/ppc/kernel/open_pic.c4
-rw-r--r--arch/ppc/kernel/pmac_pic.c4
-rw-r--r--arch/ppc/kernel/ppc_ksyms.c10
-rw-r--r--arch/ppc/kernel/prep_setup.c6
-rw-r--r--arch/ppc/kernel/process.c30
-rw-r--r--arch/ppc/kernel/ptrace.c18
-rw-r--r--arch/ppc/kernel/setup.c6
-rw-r--r--arch/ppc/kernel/time.c8
-rw-r--r--arch/ppc/mm/fault.c2
-rw-r--r--arch/ppc/mm/init.c22
-rw-r--r--arch/sh/defconfig12
-rw-r--r--arch/sh/kernel/Makefile1
-rw-r--r--arch/sh/kernel/entry.S442
-rw-r--r--arch/sh/kernel/fpu.c49
-rw-r--r--arch/sh/kernel/head.S16
-rw-r--r--arch/sh/kernel/irq.c2
-rw-r--r--arch/sh/kernel/irq_imask.c12
-rw-r--r--arch/sh/kernel/irq_onchip.c4
-rw-r--r--arch/sh/kernel/process.c31
-rw-r--r--arch/sh/kernel/setup.c19
-rw-r--r--arch/sh/kernel/signal.c30
-rw-r--r--arch/sh/kernel/time.c41
-rw-r--r--arch/sh/kernel/traps.c10
-rw-r--r--arch/sh/mm/cache.c9
-rw-r--r--arch/sh/mm/fault.c4
-rw-r--r--arch/sparc/kernel/Makefile2
-rw-r--r--arch/sparc/kernel/cpu.c2
-rw-r--r--arch/sparc/kernel/ptrace.c12
-rw-r--r--arch/sparc/kernel/signal.c2
-rw-r--r--arch/sparc/kernel/sun4d_smp.c39
-rw-r--r--arch/sparc/kernel/sun4m_smp.c25
-rw-r--r--arch/sparc/kernel/sys_solaris.c4
-rw-r--r--arch/sparc/kernel/sys_sunos.c29
-rw-r--r--arch/sparc/kernel/systbls.S4
-rw-r--r--arch/sparc/kernel/time.c38
-rw-r--r--arch/sparc/lib/Makefile2
-rw-r--r--arch/sparc/lib/atomic.S6
-rw-r--r--arch/sparc/lib/bitops.S6
-rw-r--r--arch/sparc/lib/copy_user.S6
-rw-r--r--arch/sparc/mm/Makefile2
-rw-r--r--arch/sparc/mm/fault.c6
-rw-r--r--arch/sparc/mm/sun4c.c2
-rw-r--r--arch/sparc64/config.in3
-rw-r--r--arch/sparc64/defconfig42
-rw-r--r--arch/sparc64/kernel/Makefile2
-rw-r--r--arch/sparc64/kernel/binfmt_aout32.c20
-rw-r--r--arch/sparc64/kernel/ioctl32.c8
-rw-r--r--arch/sparc64/kernel/irq.c109
-rw-r--r--arch/sparc64/kernel/pci_common.c85
-rw-r--r--arch/sparc64/kernel/pci_psycho.c24
-rw-r--r--arch/sparc64/kernel/pci_sabre.c48
-rw-r--r--arch/sparc64/kernel/power.c5
-rw-r--r--arch/sparc64/kernel/process.c7
-rw-r--r--arch/sparc64/kernel/ptrace.c10
-rw-r--r--arch/sparc64/kernel/sbus.c16
-rw-r--r--arch/sparc64/kernel/signal.c2
-rw-r--r--arch/sparc64/kernel/signal32.c8
-rw-r--r--arch/sparc64/kernel/smp.c61
-rw-r--r--arch/sparc64/kernel/sparc64_ksyms.c14
-rw-r--r--arch/sparc64/kernel/sys_sparc.c32
-rw-r--r--arch/sparc64/kernel/sys_sparc32.c93
-rw-r--r--arch/sparc64/kernel/sys_sunos32.c18
-rw-r--r--arch/sparc64/kernel/systbls.S10
-rw-r--r--arch/sparc64/kernel/time.c34
-rw-r--r--arch/sparc64/lib/Makefile2
-rw-r--r--arch/sparc64/lib/blockops.S14
-rw-r--r--arch/sparc64/mm/Makefile2
-rw-r--r--arch/sparc64/mm/fault.c7
-rw-r--r--arch/sparc64/mm/init.c222
-rw-r--r--arch/sparc64/prom/Makefile2
-rw-r--r--arch/sparc64/prom/misc.c8
-rw-r--r--arch/sparc64/solaris/fs.c4
-rw-r--r--arch/sparc64/solaris/misc.c11
210 files changed, 5686 insertions, 6311 deletions
diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c
index 0001799db..078aa7d3d 100644
--- a/arch/alpha/kernel/alpha_ksyms.c
+++ b/arch/alpha/kernel/alpha_ksyms.c
@@ -174,7 +174,7 @@ EXPORT_SYMBOL_NOVERS(__rwsem_wake);
* SMP-specific symbols.
*/
-#ifdef __SMP__
+#ifdef CONFIG_SMP
EXPORT_SYMBOL(kernel_flag);
EXPORT_SYMBOL(synchronize_irq);
EXPORT_SYMBOL(flush_tlb_all);
@@ -199,10 +199,10 @@ EXPORT_SYMBOL(debug_spin_trylock);
EXPORT_SYMBOL(write_lock);
EXPORT_SYMBOL(read_lock);
#endif
-#else /* __SMP__ */
+#else /* CONFIG_SMP */
EXPORT_SYMBOL(__local_bh_count);
EXPORT_SYMBOL(__local_irq_count);
-#endif /* __SMP__ */
+#endif /* CONFIG_SMP */
EXPORT_SYMBOL(rtc_lock);
diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S
index 55e622d66..33d5eead1 100644
--- a/arch/alpha/kernel/entry.S
+++ b/arch/alpha/kernel/entry.S
@@ -4,6 +4,7 @@
* kernel entry-points
*/
+#include <linux/config.h>
#include <asm/system.h>
#define SIGCHLD 20
@@ -706,7 +707,7 @@ signal_return:
br restore_all
.end entSys
-#ifdef __SMP__
+#ifdef CONFIG_SMP
.globl ret_from_smp_fork
.align 3
.ent ret_from_smp_fork
@@ -715,7 +716,7 @@ ret_from_smp_fork:
mov $17,$16
jsr $31,schedule_tail
.end ret_from_smp_fork
-#endif /* __SMP__ */
+#endif /* CONFIG_SMP */
.align 3
.ent reschedule
diff --git a/arch/alpha/kernel/head.S b/arch/alpha/kernel/head.S
index 3b004b7f6..4c87ee3a7 100644
--- a/arch/alpha/kernel/head.S
+++ b/arch/alpha/kernel/head.S
@@ -7,6 +7,7 @@
* the kernel global pointer and jump to the kernel entry-point.
*/
+#include <linux/config.h>
#include <asm/system.h>
.globl swapper_pg_dir
@@ -30,7 +31,7 @@ __start:
call_pal PAL_halt
.end __start
-#ifdef __SMP__
+#ifdef CONFIG_SMP
.align 3
.globl __smp_callin
.ent __smp_callin
@@ -52,7 +53,7 @@ __smp_callin:
jsr $26,smp_callin
call_pal PAL_halt
.end __smp_callin
-#endif /* __SMP__ */
+#endif /* CONFIG_SMP */
#
# The following two functions are needed for supporting SRM PALcode
diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c
index 1f454cf48..e47fcd3ca 100644
--- a/arch/alpha/kernel/irq.c
+++ b/arch/alpha/kernel/irq.c
@@ -373,7 +373,7 @@ register_irq_proc (unsigned int irq)
#ifdef CONFIG_SMP
/* create /proc/irq/1234/smp_affinity */
- entry = create_proc_entry("smp_affinity", 0700, irq_dir[irq]);
+ entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]);
entry->nlink = 1;
entry->data = (void *)(long)irq;
@@ -397,7 +397,7 @@ init_irq_proc (void)
#ifdef CONFIG_SMP
/* create /proc/irq/prof_cpu_mask */
- entry = create_proc_entry("prof_cpu_mask", 0700, root_irq_dir);
+ entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir);
entry->nlink = 1;
entry->data = (void *)&prof_cpu_mask;
diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c
index 81178976a..f9a79c1d6 100644
--- a/arch/alpha/kernel/pci.c
+++ b/arch/alpha/kernel/pci.c
@@ -110,10 +110,15 @@ void
pcibios_align_resource(void *data, struct resource *res, unsigned long size)
{
struct pci_dev *dev = data;
+ struct pci_controler *hose = dev->sysdata;
unsigned long alignto;
unsigned long start = res->start;
if (res->flags & IORESOURCE_IO) {
+ /* Make sure we start at our min on all hoses */
+ if (start - hose->io_space->start < PCIBIOS_MIN_IO)
+ start = PCIBIOS_MIN_IO + hose->io_space->start;
+
/*
* Aligning to 0x800 rather than the minimum base of
* 0x400 is an attempt to avoid having devices in
@@ -121,11 +126,18 @@ pcibios_align_resource(void *data, struct resource *res, unsigned long size)
* probes for EISA cards.
*
* Adaptecs, especially, resent such intrusions.
+ *
+ * The de4x5 driver has the eisa probe conditionalized
+ * out for Alpha, so lower the minimum base back to 0x400.
*/
- alignto = MAX(0x800, size);
+ alignto = MAX(0x400, size);
start = ALIGN(start, alignto);
}
else if (res->flags & IORESOURCE_MEM) {
+ /* Make sure we start at our min on all hoses */
+ if (start - hose->mem_space->start < PCIBIOS_MIN_MEM)
+ start = PCIBIOS_MIN_MEM + hose->io_space->start;
+
/*
* The following holds at least for the Low Cost
* Alpha implementation of the PCI interface:
@@ -230,7 +242,7 @@ void __init
pcibios_fixup_device_resources(struct pci_dev *dev, struct pci_bus *bus)
{
/* Update device resources. */
-
+ struct pci_controler *hose = (struct pci_controler *)bus->sysdata;
int i;
for (i = 0; i < PCI_NUM_RESOURCES; i++) {
@@ -238,10 +250,10 @@ pcibios_fixup_device_resources(struct pci_dev *dev, struct pci_bus *bus)
continue;
if (dev->resource[i].flags & IORESOURCE_IO)
pcibios_fixup_resource(&dev->resource[i],
- bus->resource[0]);
+ hose->io_space);
else if (dev->resource[i].flags & IORESOURCE_MEM)
pcibios_fixup_resource(&dev->resource[i],
- bus->resource[1]);
+ hose->mem_space);
}
pcibios_assign_special(dev);
}
@@ -257,6 +269,12 @@ pcibios_fixup_bus(struct pci_bus *bus)
bus->resource[0] = hose->io_space;
bus->resource[1] = hose->mem_space;
+ /* If this is a bridge, get the current bases */
+ if (bus->self) {
+ pci_read_bridge_bases(bus);
+ pcibios_fixup_device_resources(bus->self, bus->parent);
+ }
+
for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
struct pci_dev *dev = pci_dev_b(ln);
if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
@@ -268,10 +286,25 @@ void __init
pcibios_update_resource(struct pci_dev *dev, struct resource *root,
struct resource *res, int resource)
{
+ struct pci_controler *hose = dev->sysdata;
int where;
u32 reg;
+ if (resource < PCI_ROM_RESOURCE)
where = PCI_BASE_ADDRESS_0 + (resource * 4);
+ else if (resource == PCI_ROM_RESOURCE)
+ where = dev->rom_base_reg;
+ else {
+ /* Don't update non-standard resources here */
+ return;
+ }
+
+ /* Point root at the hose root */
+ if (res->flags & IORESOURCE_IO)
+ root = hose->io_space;
+ if (res->flags & IORESOURCE_MEM)
+ root = hose->mem_space;
+
reg = (res->start - root->start) | (res->flags & 0xf);
pci_write_config_dword(dev, where, reg);
if ((res->flags & (PCI_BASE_ADDRESS_SPACE
@@ -319,10 +352,12 @@ void __init
pcibios_fixup_pbus_ranges(struct pci_bus * bus,
struct pbus_set_ranges_data * ranges)
{
- ranges->io_start -= bus->resource[0]->start;
- ranges->io_end -= bus->resource[0]->start;
- ranges->mem_start -= bus->resource[1]->start;
- ranges->mem_end -= bus->resource[1]->start;
+ struct pci_controler *hose = (struct pci_controler *)bus->sysdata;
+
+ ranges->io_start -= hose->io_space->start;
+ ranges->io_end -= hose->io_space->start;
+ ranges->mem_start -= hose->mem_space->start;
+ ranges->mem_end -= hose->mem_space->start;
}
int
@@ -332,6 +367,94 @@ pcibios_enable_device(struct pci_dev *dev)
return 0;
}
+#define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1))
+
+static void __init
+pcibios_size_bridge(struct pci_bus *bus, struct pbus_set_ranges_data *outer)
+{
+ struct pbus_set_ranges_data inner;
+ struct pci_dev *dev;
+ struct pci_dev *bridge = bus->self;
+ struct pci_controler *hose = bus->sysdata;
+ struct list_head *ln;
+
+ if (!bridge)
+ return; /* host bridge, nothing to do */
+
+ /* set reasonable default locations for pcibios_align_resource */
+ inner.io_start = hose->io_space->start + PCIBIOS_MIN_IO;
+ inner.mem_start = hose->mem_space->start + PCIBIOS_MIN_MEM;
+ inner.io_end = inner.io_start;
+ inner.mem_end = inner.mem_start;
+
+ /* Collect information about how our direct children are layed out. */
+ for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
+ int i;
+ dev = pci_dev_b(ln);
+
+ /* Skip bridges for now */
+ if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI)
+ continue;
+
+ for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+ struct resource res;
+ unsigned long size;
+
+ memcpy(&res, &dev->resource[i], sizeof(res));
+ size = res.end - res.start + 1;
+
+ if (res.flags & IORESOURCE_IO) {
+ res.start = inner.io_end;
+ pcibios_align_resource(dev, &res, size);
+ inner.io_end = res.start + size;
+ } else if (res.flags & IORESOURCE_MEM) {
+ res.start = inner.mem_end;
+ pcibios_align_resource(dev, &res, size);
+ inner.mem_end = res.start + size;
+ }
+ }
+ }
+
+ /* And for all of the subordinate busses. */
+ for (ln=bus->children.next; ln != &bus->children; ln=ln->next)
+ pcibios_size_bridge(pci_bus_b(ln), &inner);
+
+ /* turn the ending locations into sizes (subtract start) */
+ inner.io_end -= inner.io_start;
+ inner.mem_end -= inner.mem_start;
+
+ /* Align the sizes up by bridge rules */
+ inner.io_end = ROUND_UP(inner.io_end, 4*1024);
+ inner.mem_end = ROUND_UP(inner.mem_end, 1*1024*1024);
+
+ /* Adjust the bridge's allocation requirements */
+ bridge->resource[0].end = bridge->resource[0].start + inner.io_end;
+ bridge->resource[1].end = bridge->resource[1].start + inner.mem_end;
+
+ /* adjust parent's resource requirements */
+ if (outer) {
+ outer->io_end = ROUND_UP(outer->io_end, 4*1024);
+ outer->io_end += inner.io_end;
+
+ outer->mem_end = ROUND_UP(outer->mem_end, 1*1024*1024);
+ outer->mem_end += inner.mem_end;
+ }
+}
+
+#undef ROUND_UP
+
+static void __init
+pcibios_size_bridges(void)
+{
+ struct list_head *ln1, *ln2;
+
+ for(ln1=pci_root_buses.next; ln1 != &pci_root_buses; ln1=ln1->next)
+ for(ln2 = pci_bus_b(ln1)->children.next;
+ ln2 != &pci_bus_b(ln1)->children;
+ ln2 = ln2->next)
+ pcibios_size_bridge(pci_bus_b(ln2), NULL);
+}
+
void __init
common_init_pci(void)
{
@@ -349,6 +472,7 @@ common_init_pci(void)
next_busno += 1;
}
+ pcibios_size_bridges();
pci_assign_unassigned_resources();
pci_fixup_irqs(alpha_mv.pci_swizzle, alpha_mv.pci_map_irq);
pci_set_bus_ranges();
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
index aa9dfbf64..27b042777 100644
--- a/arch/alpha/kernel/process.c
+++ b/arch/alpha/kernel/process.c
@@ -116,7 +116,7 @@ common_shutdown_1(void *generic_ptr)
/* Clear reason to "default"; clear "bootstrap in progress". */
flags &= ~0x00ff0001UL;
-#ifdef __SMP__
+#ifdef CONFIG_SMP
/* Secondaries halt here. */
if (cpuid != boot_cpuid) {
flags |= 0x00040000UL; /* "remain halted" */
@@ -145,7 +145,7 @@ common_shutdown_1(void *generic_ptr)
}
*pflags = flags;
-#ifdef __SMP__
+#ifdef CONFIG_SMP
/* Wait for the secondaries to halt. */
clear_bit(boot_cpuid, &cpu_present_mask);
while (cpu_present_mask)
@@ -184,7 +184,7 @@ common_shutdown(int mode, char *restart_cmd)
struct halt_info args;
args.mode = mode;
args.restart_cmd = restart_cmd;
-#ifdef __SMP__
+#ifdef CONFIG_SMP
smp_call_function(common_shutdown_1, &args, 1, 0);
#endif
common_shutdown_1(&args);
@@ -321,7 +321,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
stack = ((struct switch_stack *) regs) - 1;
childstack = ((struct switch_stack *) childregs) - 1;
*childstack = *stack;
-#ifdef __SMP__
+#ifdef CONFIG_SMP
childstack->r26 = (unsigned long) ret_from_smp_fork;
#else
childstack->r26 = (unsigned long) ret_from_sys_call;
diff --git a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h
index f13edeebf..e141df202 100644
--- a/arch/alpha/kernel/proto.h
+++ b/arch/alpha/kernel/proto.h
@@ -1,3 +1,4 @@
+#include <linux/config.h>
/* Prototypes of functions used across modules here in this directory. */
#define vucp volatile unsigned char *
@@ -132,7 +133,7 @@ void srm_paging_stop(void);
/* irq.c */
-#ifdef __SMP__
+#ifdef CONFIG_SMP
#define mcheck_expected(cpu) (cpu_data[cpu].mcheck_expected)
#define mcheck_taken(cpu) (cpu_data[cpu].mcheck_taken)
#define mcheck_extra(cpu) (cpu_data[cpu].mcheck_extra)
diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c
index 49ddca2e4..1eab8fc5b 100644
--- a/arch/alpha/kernel/setup.c
+++ b/arch/alpha/kernel/setup.c
@@ -484,7 +484,7 @@ setup_arch(char **cmdline_p)
* Identify the flock of penguins.
*/
-#ifdef __SMP__
+#ifdef CONFIG_SMP
setup_smp();
#endif
paging_init();
@@ -930,7 +930,7 @@ int get_cpuinfo(char *buffer)
unaligned[1].count, unaligned[1].pc, unaligned[1].va,
platform_string(), nr_processors);
-#ifdef __SMP__
+#ifdef CONFIG_SMP
len += smp_info(buffer+len);
#endif
diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c
index 6119ea371..8cac7f240 100644
--- a/arch/alpha/kernel/time.c
+++ b/arch/alpha/kernel/time.c
@@ -22,6 +22,7 @@
* fixed algorithm in do_gettimeofday() for calculating the precise time
* from processor cycle counter (now taking lost_ticks into account)
*/
+#include <linux/config.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
@@ -90,7 +91,7 @@ void timer_interrupt(int irq, void *dev, struct pt_regs * regs)
__u32 now;
long nticks;
-#ifndef __SMP__
+#ifndef CONFIG_SMP
/* Not SMP, do kernel PC profiling here. */
if (!user_mode(regs))
alpha_do_profile(regs->pc);
@@ -315,7 +316,7 @@ do_gettimeofday(struct timeval *tv)
read_unlock_irqrestore(&xtime_lock, flags);
-#ifdef __SMP__
+#ifdef CONFIG_SMP
/* Until and unless we figure out how to get cpu cycle counters
in sync and keep them there, we can't use the rpcc tricks. */
delta_usec = lost * (1000000 / HZ);
@@ -361,7 +362,7 @@ do_settimeofday(struct timeval *tv)
must be subtracted out here to keep a coherent view of the
time. Without this, a full-tick error is possible. */
-#ifdef __SMP__
+#ifdef CONFIG_SMP
delta_usec = lost_ticks * (1000000 / HZ);
#else
delta_usec = rpcc() - state.last_time;
diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c
index 76504a1ef..8edfef27d 100644
--- a/arch/alpha/kernel/traps.c
+++ b/arch/alpha/kernel/traps.c
@@ -95,7 +95,7 @@ die_if_kernel(char * str, struct pt_regs *regs, long err, unsigned long *r9_15)
{
if (regs->ps & 8)
return;
-#ifdef __SMP__
+#ifdef CONFIG_SMP
printk("CPU %d ", hard_smp_processor_id());
#endif
printk("%s(%d): %s %ld\n", current->comm, current->pid, str, err);
diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c
index 3d9c8e75e..1639972db 100644
--- a/arch/alpha/mm/fault.c
+++ b/arch/alpha/mm/fault.c
@@ -4,6 +4,7 @@
* Copyright (C) 1995 Linus Torvalds
*/
+#include <linux/config.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
@@ -34,7 +35,7 @@ extern void die_if_kernel(char *,struct pt_regs *,long, unsigned long *);
* Force a new ASN for a task.
*/
-#ifndef __SMP__
+#ifndef CONFIG_SMP
unsigned long last_asn = ASN_FIRST_VERSION;
#endif
@@ -139,7 +140,7 @@ good_area:
* make sure we exit gracefully rather than endlessly redo
* the fault.
*/
- fault = handle_mm_fault(current, vma, address, cause > 0);
+ fault = handle_mm_fault(mm, vma, address, cause > 0);
up(&mm->mmap_sem);
if (fault < 0)
diff --git a/arch/alpha/mm/init.c b/arch/alpha/mm/init.c
index e2142b63c..2cbe9bb0f 100644
--- a/arch/alpha/mm/init.c
+++ b/arch/alpha/mm/init.c
@@ -37,7 +37,7 @@ extern void die_if_kernel(char *,struct pt_regs *,long);
struct thread_struct original_pcb;
-#ifndef __SMP__
+#ifndef CONFIG_SMP
struct pgtable_cache_struct quicklists;
#endif
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 796f812ab..f60dc3564 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -6,6 +6,66 @@
#include <linux/linkage.h>
.section ".start", #alloc, #execinstr
+
+/*
+ * Debugging stuff
+ */
+ .macro kputc,val
+ mov r0, \val
+ bl putc
+ .endm
+
+ .macro kphex,val,len
+ mov r0, \val
+ mov r1, #\len
+ bl phex
+ .endm
+
+ .macro debug_reloc_start
+#ifdef DEBUG
+ kputc #'\n'
+ kphex r6, 8
+ kputc #':'
+ kphex r5, 8
+ kputc #'-'
+ kphex r8, 8
+ kputc #'>'
+ kphex r4, 8
+ kputc #'\n'
+#endif
+ .endm
+
+ .macro debug_reloc_end
+#ifdef DEBUG
+ mov r8, r0
+ kphex r5, 8
+ kputc #'-'
+ kphex r8, 8
+ kputc #'\n'
+ mov r0, r4
+ bl memdump
+#endif
+ .endm
+
+#if 0
+ .macro loadsp, rb
+ mov \rb, #0x7c000000
+ .endm
+
+ .macro writeb, rb
+ strb \rb, [r3, #0x3f8]
+ .endm
+#else
+ .macro loadsp, rb
+ mov \rb, #0x03000000
+ orr \rb, \rb, #0x00010000
+ .endm
+
+ .macro writeb, rb
+ strb \rb, [r3, #0x3f8 << 2]
+ .endm
+#endif
+
/*
* sort out different calling conventions
*/
@@ -42,6 +102,8 @@ start:
cmp r2, r3
blt 1b
+ bl cache_on
+
mov r1, sp @ malloc space above stack
add r2, sp, #0x10000 @ 64k max
@@ -77,15 +139,87 @@ start:
cmp r2, r3
blt 1b
- eor r1, r6, #0x44 << 24 @ SA-110 or SA-1100?
- eor r1, r1, #0x01 << 16
- eor r1, r1, #0xa1 << 8
- movs r1, r1, lsr #5
- mcreq p15, 0, r1, c7, c7, 0 @ flush I & D-cache
- mcreq p15, 0, r1, c7, c10, 4 @ drain WB
+ bl cache_clean_flush
add pc, r5, r0 @ call relocation code
/*
+ * Page table physical address list
+ */
+ .align 5
+ .type pgtable,#object
+pgtable: .word 0x00004000 @ 0x00
+ .word 0x10004000 @ 0x01
+ .word 0x00000000 @ 0x02
+ .word 0x40004000 @ 0x03
+ .word 0x00004000 @ 0x04
+ .word 0x00004000 @ 0x05
+ .word 0x00004000 @ 0x06
+ .word 0x80004000 @ 0x07
+ .word 0x00004000 @ 0x08
+ .word 0x00000000 @ 0x09
+ .word 0x00000000 @ 0x0a
+ .word 0x00000000 @ 0x0b
+ .word 0x00000000 @ 0x0c
+ .word 0x00000000 @ 0x0d
+ .word 0x10004000 @ 0x0e
+ .word 0x08004000 @ 0x0f
+ .word 0xc0004000 @ 0x10
+ .size pgtable,. - pgtable
+1:
+
+ .type LC0, #object
+LC0: .word __bss_start
+ .word _end
+ .word _load_addr
+ .word _start
+ .word user_stack+4096
+ .size LC0, . - LC0
+
+ .align 5
+cache_on: ldr r1, proc_sa110_type
+ eor r1, r1, r6
+ movs r1, r1, lsr #5
+ movne pc, lr
+ cmp r7, #(1b - pgtable) >> 2
+ movge pc, lr
+ adr r3, pgtable
+ ldr r3, [r3, r7, lsl #2]
+ teq r3, #0
+ moveq pc, lr
+/*
+ * Initialise the page tables
+ */
+ mov r0, r3
+ mov r8, r0, lsr #18
+ mov r8, r8, lsl #18 @ start of RAM
+ add r9, r8, #0x20000000 @ the maximum RAM size
+ mov r1, #0x12
+ orr r1, r1, #3 << 10
+ add r2, r3, #16384
+1: cmp r1, r8 @ if virt > start of RAM
+ orrge r1, r1, #0x0c @ set cacheable, bufferable
+ cmp r1, r9 @ if virt > end of RAM
+ bicge r1, r1, #0x0c @ clear cacheable, bufferable
+ str r1, [r0], #4 @ 1:1 mapping
+ add r1, r1, #1048576
+ teq r0, r2
+ bne 1b
+
+ mov r0, #0
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
+ mcr p15, 0, r0, c8, c7 @ flush I,D TLBs
+ mcr p15, 0, r3, c2, c0 @ load page table pointer
+ mov r0, #-1
+ mcr p15, 0, r0, c3, c0 @ load domain access register
+ mrc p15, 0, r0, c1, c0
+ orr r0, r0, #0x1000 @ I-cache enable
+#ifndef DEBUG
+ orr r0, r0, #0x003d @ Write buffer, mmu
+#endif
+ mcr p15, 0, r0, c1, c0
+ mov pc, lr
+
+/*
* r0 = decompressed kernel length
* r1-r3 = unused
* r4 = kernel execution address
@@ -94,87 +228,68 @@ start:
* r7 = architecture ID
* r8-r14 = unused
*/
+ .align 5
reloc_start: add r8, r5, r0
-#if 0
- mov r0, #'\n'
- bl putc
- mov r0, r6
- mov r1, #8
- bl phex
- mov r0, #':'
- bl putc
- mov r0, r5
- mov r1, #8
- bl phex
- mov r0, #'-'
- bl putc
- mov r0, r8
- mov r1, #8
- bl phex
- mov r0, #'>'
- bl putc
- mov r0, r4
- mov r1, #8
- bl phex
- mov r0, #'\n'
- bl putc
-#endif
- mov r0, r8
+ debug_reloc_start
mov r1, r4
1:
.rept 4
- ldmia r5!, {r2, r3, r8 - r13} @ relocate kernel
- stmia r1!, {r2, r3, r8 - r13}
+ ldmia r5!, {r0, r2, r3, r9 - r13} @ relocate kernel
+ stmia r1!, {r0, r2, r3, r9 - r13}
.endr
- cmp r5, r0
+ cmp r5, r8
blt 1b
-#if 0
- mov r8, r0
- mov r0, r5
- mov r1, #8
- bl phex
- mov r0, #'-'
- bl putc
- mov r0, r8
- mov r1, #8
- bl phex
- mov r0, #'\n'
- bl putc
- mov r0, r4
- bl memdump
-#endif
- eor r0, r6, #0x44 << 24 @ SA-110 or SA-1100?
- eor r0, r0, #0x01 << 16
- eor r0, r0, #0xa1 << 8
- movs r0, r0, lsr #5
- mcreq p15, 0, r0, c7, c7, 0 @ flush I cache
- mcreq p15, 0, r1, c7, c10, 4 @ drain WB
-
-call_kernel: mov r0, #0
+ debug_reloc_end
+
+call_kernel: bl cache_clean_flush
+ bl cache_off
+ mov r0, #0
mov r1, r7 @ restore architecture number
mov pc, r4 @ call kernel
-phexbuf: .space 12
+ .type proc_sa110_type,#object
+proc_sa110_type:
+ .word 0x4401a100
+ .size proc_sa110_type, . - proc_sa110_type
-#if 0
- .macro loadsp, rb
- mov \rb, #0x7c000000
- .endm
+/*
+ * Turn off StrongARM cache and MMU
+ */
+ .align 5
+cache_off: ldr r1, proc_sa110_type
+ eor r1, r1, r6
+ movs r1, r1, lsr #5
+ movne pc, lr
+ mrc p15, 0, r0, c1, c0
+ bic r0, r0, #0x000d
+ mcr p15, 0, r0, c1, c0
+ mov pc, lr
- .macro writeb, rb
- strb \rb, [r3, #0x3f8]
- .endm
-#else
- .macro loadsp, rb
- mov \rb, #0x03000000
- orr \rb, \rb, #0x00010000
- .endm
+/*
+ * Clean and flush the cache to maintain consistency.
+ */
+ .align 5
+cache_clean_flush:
+ ldr r1, proc_sa110_type @ SA-110 or SA-1100?
+ eor r1, r1, r6
+ movs r1, r1, lsr #5
+ movne pc, lr
- .macro writeb, rb
- strb \rb, [r3, #0x3f8 << 2]
- .endm
-#endif
+ bic r1, pc, #31
+ add r2, r1, #32768
+1: ldr r12, [r1], #32
+ teq r1, r2
+ bne 1b
+
+ mcr p15, 0, r1, c7, c7, 0 @ flush I cache
+ mcr p15, 0, r1, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+#ifdef DEBUG
+ .type phexbuf,#object
+phexbuf: .space 12
+ .size phexbuf, . - phexbuf
phex: adr r3, phexbuf
mov r2, #0
@@ -240,14 +355,10 @@ memdump: mov r12, r0
cmp r11, #64
blt 2b
mov pc, r10
+#endif
+
reloc_end:
-LC0: .word __bss_start
- .word _end
- .word _load_addr
- .word _start
- .word user_stack+4096
.align
-
.section ".stack"
user_stack: .space 4096
diff --git a/arch/arm/config.in b/arch/arm/config.in
index fa124b5fd..f00835051 100644
--- a/arch/arm/config.in
+++ b/arch/arm/config.in
@@ -137,9 +137,6 @@ else
define_bool CONFIG_ISA_DMA n
fi
-define_bool CONFIG_SBUS n
-define_bool CONFIG_PCMCIA n
-
if [ "$CONFIG_CPU_32" = "y" -a "$CONFIG_ARCH_EBSA110" != "y" ]; then
bool 'Kernel-mode alignment trap handler' CONFIG_ALIGNMENT_TRAP
fi
@@ -222,7 +219,6 @@ if [ "$CONFIG_ARCH_ACORN" = "y" ]; then
fi
fi
-
#source drivers/misc/Config.in
if [ "$CONFIG_VT" = "y" ]; then
diff --git a/arch/arm/def-configs/ebsa110 b/arch/arm/def-configs/ebsa110
index 0e4acdebc..09fff229c 100644
--- a/arch/arm/def-configs/ebsa110
+++ b/arch/arm/def-configs/ebsa110
@@ -2,6 +2,12 @@
# Automatically generated make config: don't edit
#
CONFIG_ARM=y
+CONFIG_UID16=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
#
# System and processor type
@@ -12,20 +18,13 @@ CONFIG_ARM=y
CONFIG_ARCH_EBSA110=y
# CONFIG_FOOTBRIDGE is not set
# CONFIG_ARCH_ACORN is not set
-# CONFIG_ISA_DMA is not set
CONFIG_CPU_32=y
# CONFIG_CPU_26 is not set
-# CONFIG_CPU_ARM2 is not set
-# CONFIG_CPU_ARM3 is not set
-# CONFIG_CPU_ARM6 is not set
-# CONFIG_CPU_ARM7 is not set
+CONFIG_CPU_32v4=y
CONFIG_CPU_SA110=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-# CONFIG_TEXT_SECTIONS is not set
+# CONFIG_PCI is not set
+# CONFIG_ISA is not set
+# CONFIG_ISA_DMA is not set
#
# Loadable module support
@@ -42,29 +41,52 @@ CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_NWFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
CONFIG_BINFMT_AOUT=y
-CONFIG_BINFMT_ELF=m
+CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
+# CONFIG_ARTHUR is not set
+
+#
+# Parallel port support
+#
CONFIG_PARPORT=y
CONFIG_PARPORT_PC=y
+CONFIG_PARPORT_PC_FIFO=y
+CONFIG_PARPORT_PC_SUPERIO=y
+# CONFIG_PARPORT_ARC is not set
+# CONFIG_PARPORT_AMIGA is not set
+# CONFIG_PARPORT_MFC3 is not set
+# CONFIG_PARPORT_ATARI is not set
+# CONFIG_PARPORT_SUNBPP is not set
+# CONFIG_PARPORT_OTHER is not set
+CONFIG_PARPORT_1284=y
CONFIG_CMDLINE="root=/dev/nfs rw mem=16M console=ttyS1,38400n8"
CONFIG_LEDS=y
#
-# Plug and Play support
+# I2O device support
#
-# CONFIG_PNP is not set
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
#
-# Block devices
+# Plug and Play configuration
#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_IDE is not set
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
#
-# Please see Documentation/ide.txt for help/info on IDE drives
+# Block devices
#
-# CONFIG_BLK_DEV_HD_ONLY is not set
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
#
# Additional Block Devices
@@ -74,10 +96,6 @@ CONFIG_BLK_DEV_NBD=m
# CONFIG_BLK_DEV_MD is not set
CONFIG_BLK_DEV_RAM=y
# CONFIG_BLK_DEV_INITRD is not set
-# CONFIG_BLK_DEV_XD is not set
-CONFIG_PARIDE_PARPORT=y
-# CONFIG_PARIDE is not set
-# CONFIG_BLK_DEV_HD is not set
#
# Character devices
@@ -94,29 +112,39 @@ CONFIG_SERIAL_EXTENDED=y
# CONFIG_SERIAL_NONSTANDARD is not set
# CONFIG_UNIX98_PTYS is not set
CONFIG_PRINTER=m
-CONFIG_PRINTER_READBACK=y
-CONFIG_MOUSE=y
+# CONFIG_LP_CONSOLE is not set
+# CONFIG_PPDEV is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
#
# Mice
#
-# CONFIG_ATIXL_BUSMOUSE is not set
# CONFIG_BUSMOUSE is not set
-# CONFIG_MS_BUSMOUSE is not set
+CONFIG_MOUSE=y
# CONFIG_PSMOUSE is not set
# CONFIG_82C710_MOUSE is not set
# CONFIG_PC110_PAD is not set
+
+#
+# Joysticks
+#
+# CONFIG_JOYSTICK is not set
# CONFIG_QIC02_TAPE is not set
-CONFIG_WATCHDOG=y
#
# Watchdog Cards
#
+CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
# CONFIG_WDT is not set
CONFIG_SOFT_WATCHDOG=y
# CONFIG_PCWATCHDOG is not set
# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_MIXCOMWD is not set
# CONFIG_NVRAM is not set
# CONFIG_RTC is not set
@@ -124,64 +152,92 @@ CONFIG_SOFT_WATCHDOG=y
# Video For Linux
#
# CONFIG_VIDEO_DEV is not set
-
-#
-# Joystick support
-#
-# CONFIG_JOYSTICK is not set
# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
#
# Ftape, the floppy tape device driver
#
# CONFIG_FTAPE is not set
+# CONFIG_DRM is not set
+# CONFIG_DRM_TDFX is not set
+# CONFIG_AGP is not set
#
# Networking options
#
CONFIG_PACKET=m
-# CONFIG_NETLINK is not set
-CONFIG_FIREWALL=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK=y
+CONFIG_RTNETLINK=y
+# CONFIG_NETLINK_DEV is not set
+CONFIG_NETFILTER=y
# CONFIG_FILTER is not set
CONFIG_UNIX=y
CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_RTNETLINK=y
+CONFIG_NETLINK=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_FWMARK=y
+CONFIG_IP_ROUTE_NAT=y
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_TOS is not set
+# CONFIG_IP_ROUTE_VERBOSE is not set
+# CONFIG_IP_ROUTE_LARGE_TABLES is not set
CONFIG_IP_PNP=y
CONFIG_IP_PNP_BOOTP=y
# CONFIG_IP_PNP_RARP is not set
-CONFIG_IP_FIREWALL=y
-CONFIG_IP_ALWAYS_DEFRAG=y
-# CONFIG_IP_TRANSPARENT_PROXY is not set
-CONFIG_IP_MASQUERADE=y
-
-#
-# Protocol-specific masquerading support will be built as modules.
-#
-CONFIG_IP_MASQUERADE_ICMP=y
-
-#
-# Protocol-specific masquerading support will be built as modules.
-#
-# CONFIG_IP_MASQUERADE_MOD is not set
# CONFIG_IP_ROUTER is not set
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_ALIAS is not set
+# CONFIG_IP_MROUTE is not set
+CONFIG_IP_ALIAS=y
+# CONFIG_ARPD is not set
CONFIG_SYN_COOKIES=y
#
# (it is safe to leave these untouched)
#
-# CONFIG_INET_RARP is not set
# CONFIG_SKB_LARGE is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=y
+CONFIG_IP_NF_FTP=y
+# CONFIG_IP_NF_QUEUE is not set
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MATCH_LIMIT=y
+# CONFIG_IP_NF_MATCH_MAC is not set
+CONFIG_IP_NF_MATCH_MARK=y
+CONFIG_IP_NF_MATCH_MULTIPORT=y
+CONFIG_IP_NF_MATCH_TOS=y
+CONFIG_IP_NF_MATCH_STATE=y
+# CONFIG_IP_NF_MATCH_UNCLEAN is not set
+# CONFIG_IP_NF_MATCH_OWNER is not set
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+# CONFIG_IP_NF_TARGET_MIRROR is not set
+CONFIG_IP_NF_NAT=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_TARGET_TOS=y
+CONFIG_IP_NF_TARGET_MARK=y
+CONFIG_IP_NF_TARGET_LOG=y
# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
#
#
#
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
# CONFIG_BRIDGE is not set
@@ -190,7 +246,6 @@ CONFIG_SYN_COOKIES=y
# CONFIG_WAN_ROUTER is not set
# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
-# CONFIG_CPU_IS_SLOW is not set
#
# QoS and/or fair queueing
@@ -203,7 +258,7 @@ CONFIG_SYN_COOKIES=y
# CONFIG_HAMRADIO is not set
#
-# IrDA subsystem support
+# IrDA (infrared) support
#
# CONFIG_IRDA is not set
@@ -211,37 +266,72 @@ CONFIG_SYN_COOKIES=y
# Network device support
#
CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
# CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
+CONFIG_DUMMY=m
+# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
+# CONFIG_ETHERTAP is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
CONFIG_NET_ETHERNET=y
CONFIG_ARM_AM79C961A=y
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_LANCE is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_RTL8139 is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_ACENIC is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
# CONFIG_NET_ISA is not set
-# CONFIG_NET_EISA is not set
+# CONFIG_NET_PCI is not set
# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_YELLOWFIN is not set
+# CONFIG_ACENIC is not set
+# CONFIG_SK98LIN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
-# CONFIG_DLCI is not set
# CONFIG_PLIP is not set
CONFIG_PPP=y
+CONFIG_PPP_ASYNC=y
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+# CONFIG_SLIP is not set
#
-# CCP compressors for PPP are only built as modules.
+# Wireless LAN (non-hamradio)
#
-# CONFIG_SLIP is not set
# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
# CONFIG_TR is not set
-# CONFIG_SHAPER is not set
-# CONFIG_HOSTESS_SV11 is not set
-# CONFIG_COSA is not set
+# CONFIG_NET_FC is not set
# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
#
# SCSI support
@@ -249,27 +339,35 @@ CONFIG_PPP=y
# CONFIG_SCSI is not set
#
-# Filesystems
+# File systems
#
# CONFIG_QUOTA is not set
-CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
# CONFIG_FAT_FS is not set
# CONFIG_MSDOS_FS is not set
# CONFIG_UMSDOS_FS is not set
# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
# CONFIG_ISO9660_FS is not set
# CONFIG_JOLIET is not set
CONFIG_MINIX_FS=y
# CONFIG_NTFS_FS is not set
# CONFIG_HPFS_FS is not set
CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS is not set
# CONFIG_QNX4FS_FS is not set
# CONFIG_ROMFS_FS is not set
# CONFIG_EXT2_FS is not set
# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
# CONFIG_UFS_FS is not set
#
@@ -287,22 +385,28 @@ CONFIG_LOCKD=y
#
# Partition Types
#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
# CONFIG_MAC_PARTITION is not set
# CONFIG_MSDOS_PARTITION is not set
# CONFIG_SGI_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ACORN_PARTITION is not set
# CONFIG_NLS is not set
#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
# Kernel hacking
#
-CONFIG_FRAME_POINTER=y
+# CONFIG_FRAME_POINTER is not set
CONFIG_DEBUG_ERRORS=y
# CONFIG_DEBUG_USER is not set
# CONFIG_DEBUG_INFO is not set
# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_ARTHUR is not set
# CONFIG_DEBUG_LL is not set
diff --git a/arch/arm/defconfig b/arch/arm/defconfig
index c5b389476..077eef8b3 100644
--- a/arch/arm/defconfig
+++ b/arch/arm/defconfig
@@ -536,8 +536,8 @@ CONFIG_BLK_DEV_IDEDMA=y
CONFIG_IDEDMA_PCI_EXPERIMENTAL=y
# CONFIG_IDEDMA_PCI_WIP is not set
# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
-# CONFIG_BLK_DEV_AEC6210 is not set
-# CONFIG_AEC6210_TUNING is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_AEC62XX_TUNING is not set
# CONFIG_BLK_DEV_ALI15X3 is not set
# CONFIG_WDC_ALI15X3 is not set
# CONFIG_BLK_DEV_AMD7409 is not set
diff --git a/arch/arm/kernel/arch.c b/arch/arm/kernel/arch.c
index e9cca7748..717ba4ca9 100644
--- a/arch/arm/kernel/arch.c
+++ b/arch/arm/kernel/arch.c
@@ -1,45 +1,39 @@
/*
* linux/arch/arm/kernel/arch.c
*
- * Architecture specifics
+ * Architecture specific fixups. This is where any
+ * parameters in the params struct are fixed up, or
+ * any additional architecture specific information
+ * is pulled from the params struct.
*/
#include <linux/config.h>
#include <linux/tty.h>
#include <linux/init.h>
+#include <asm/dec21285.h>
#include <asm/elf.h>
#include <asm/setup.h>
#include <asm/system.h>
#include "arch.h"
-extern unsigned int system_rev;
-extern unsigned int system_serial_low;
-extern unsigned int system_serial_high;
-
unsigned int vram_size;
-#ifdef CONFIG_ARCH_ACORN
-unsigned int memc_ctrl_reg;
-unsigned int number_mfm_drives;
-#endif
extern void setup_initrd(unsigned int start, unsigned int size);
extern void setup_ramdisk(int doload, int prompt, int start, unsigned int rd_sz);
-/*
- * Architecture specific fixups. This is where any
- * parameters in the params struct are fixed up, or
- * any additional architecture specific information
- * is pulled from the params struct.
- */
+#ifdef CONFIG_ARCH_ACORN
+
+unsigned int memc_ctrl_reg;
+unsigned int number_mfm_drives;
+
static void __init
fixup_acorn(struct machine_desc *desc, struct param_struct *params,
char **cmdline, struct meminfo *mi)
{
-#ifdef CONFIG_ARCH_ACORN
- int i;
-
if (machine_is_riscpc()) {
+ int i;
+
/*
* RiscPC can't handle half-word loads and stores
*/
@@ -69,9 +63,36 @@ fixup_acorn(struct machine_desc *desc, struct param_struct *params,
}
memc_ctrl_reg = params->u1.s.memc_control_reg;
number_mfm_drives = (params->u1.s.adfsdrives >> 3) & 3;
-#endif
}
+#ifdef CONFIG_ARCH_RPC
+MACHINE_START(RISCPC, "Acorn-RiscPC")
+ MAINTAINER("Russell King")
+ BOOT_MEM(0x10000000, 0x03000000, 0xe0000000)
+ BOOT_PARAMS(0x10000100)
+ DISABLE_PARPORT(0)
+ DISABLE_PARPORT(1)
+ FIXUP(fixup_acorn)
+MACHINE_END
+#endif
+#ifdef CONFIG_ARCH_ARC
+MACHINE_START(ARCHIMEDES, "Acorn-Archimedes")
+ MAINTAINER("Dave Gilbert")
+ BOOT_PARAMS(0x0207c000)
+ FIXUP(fixup_acorn)
+MACHINE_END
+#endif
+#ifdef CONFIG_ARCH_A5K
+MACHINE_START(A5K, "Acorn-A5000")
+ MAINTAINER("Russell King")
+ BOOT_PARAMS(0x0207c000)
+ FIXUP(fixup_acorn)
+MACHINE_END
+#endif
+#endif
+
+#ifdef CONFIG_ARCH_EBSA285
+
static void __init
fixup_ebsa285(struct machine_desc *desc, struct param_struct *params,
char **cmdline, struct meminfo *mi)
@@ -82,6 +103,16 @@ fixup_ebsa285(struct machine_desc *desc, struct param_struct *params,
ORIG_VIDEO_LINES = params->u1.s.video_num_rows;
}
+MACHINE_START(EBSA285, "EBSA285")
+ MAINTAINER("Russell King")
+ BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000)
+ BOOT_PARAMS(0x00000100)
+ VIDEO(0x000a0000, 0x000bffff)
+ FIXUP(fixup_ebsa285)
+MACHINE_END
+#endif
+
+#ifdef CONFIG_ARCH_NETWINDER
/*
* Older NeTTroms either do not provide a parameters
* page, or they don't supply correct information in
@@ -105,6 +136,18 @@ fixup_netwinder(struct machine_desc *desc, struct param_struct *params,
}
}
+MACHINE_START(NETWINDER, "Rebel-NetWinder")
+ MAINTAINER("Russell King/Rebel.com")
+ BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000)
+ BOOT_PARAMS(0x00000100)
+ VIDEO(0x000a0000, 0x000bffff)
+ DISABLE_PARPORT(0)
+ DISABLE_PARPORT(2)
+ FIXUP(fixup_netwinder)
+MACHINE_END
+#endif
+
+#ifdef CONFIG_ARCH_CATS
/*
* CATS uses soft-reboot by default, since
* hard reboots fail on early boards.
@@ -118,11 +161,20 @@ fixup_cats(struct machine_desc *desc, struct param_struct *params,
ORIG_Y = 24;
}
+MACHINE_START(CATS, "Chalice-CATS")
+ MAINTAINER("Philip Blundell")
+ BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000)
+ SOFT_REBOOT
+ FIXUP(fixup_cats)
+MACHINE_END
+#endif
+
+#ifdef CONFIG_ARCH_CO285
+
static void __init
fixup_coebsa285(struct machine_desc *desc, struct param_struct *params,
char **cmdline, struct meminfo *mi)
{
-#if 0
extern unsigned long boot_memory_end;
extern char boot_command_line[];
@@ -131,242 +183,228 @@ fixup_coebsa285(struct machine_desc *desc, struct param_struct *params,
mi->bank[0].size = boot_memory_end;
*cmdline = boot_command_line;
-#endif
}
+MACHINE_START(CO285, "co-EBSA285")
+ MAINTAINER("Mark van Doesburg")
+ BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0x7cf00000)
+ FIXUP(fixup_coebsa285)
+MACHINE_END
+#endif
+
+#ifdef CONFIG_ARCH_SA1100
+
+extern void select_sa1100_io_desc(void);
+#define SET_BANK(__nr,__start,__size) \
+ mi->bank[__nr].start = (__start), \
+ mi->bank[__nr].size = (__size)
static void __init
fixup_sa1100(struct machine_desc *desc, struct param_struct *params,
char **cmdline, struct meminfo *mi)
{
-#ifdef CONFIG_ARCH_SA1100
- int i;
- extern struct mem_desc {
- unsigned long phys_start;
- unsigned long length;
- } mem_desc[];
- extern unsigned int mem_desc_size;
-
- for( i = 0; i < mem_desc_size; i++ ) {
- if( i >= NR_BANKS ) {
- printk( __FUNCTION__
- ": mem_desc too large for meminfo structure\n");
- break;
- }
- mi->bank[i].start = mem_desc[i].phys_start;
- mi->bank[i].size = mem_desc[i].length;
+ select_sa1100_io_desc();
+
+ if (machine_is_assabet()) {
+ SET_BANK( 0, 0xc0000000, 32*1024*1024 );
+ mi->nr_banks = 1;
+
+ ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+ setup_ramdisk( 1, 0, 0, 8192 );
+ setup_initrd( 0xc0800000, 3*1024*1024 );
}
- mi->nr_banks = i;
-
-#if defined(CONFIG_SA1100_BRUTUS)
- ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
- setup_ramdisk( 1, 0, 0, 8192 );
- setup_initrd( __phys_to_virt(0xd8000000), 3*1024*1024 );
-#elif defined(CONFIG_SA1100_EMPEG)
- ROOT_DEV = MKDEV( 3, 1 ); /* /dev/hda1 */
- setup_ramdisk( 1, 0, 0, 4096 );
- setup_initrd( 0xd0000000+((1024-320)*1024), (320*1024) );
-#elif defined(CONFIG_SA1100_THINCLIENT)
- ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
- setup_ramdisk( 1, 0, 0, 8192 );
- setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 );
-#elif defined(CONFIG_SA1100_TIFON)
- ROOT_DEV = MKDEV(UNNAMED_MAJOR, 0);
- setup_ramdisk(1, 0, 0, 4096);
- setup_initrd( 0xd0000000 + 0x1100004, 0x140000 );
-#elif defined(CONFIG_SA1100_VICTOR)
- ROOT_DEV = MKDEV( 60, 2 );
-
- /* Get command line parameters passed from the loader (if any) */
- if( *((char*)0xc0000000) )
- strcpy( default_command_line, ((char *)0xc0000000) );
-
- /* power off if any problem */
- strcat( default_command_line, " panic=1" );
-#elif defined(CONFIG_SA1100_LART)
- ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
- setup_ramdisk(1, 0, 0, 8192);
- setup_initrd(0xc0400000, 0x00400000);
-#endif
-#endif
-}
-#define NO_PARAMS 0
-#define NO_VIDEO 0, 0
+ else if (machine_is_brutus()) {
+ SET_BANK( 0, 0xc0000000, 4*1024*1024 );
+ SET_BANK( 1, 0xc8000000, 4*1024*1024 );
+ SET_BANK( 2, 0xd0000000, 4*1024*1024 );
+ SET_BANK( 3, 0xd8000000, 4*1024*1024 );
+ mi->nr_banks = 4;
-/*
- * This is the list of all architectures supported by
- * this kernel. This should be integrated with the list
- * in head-armv.S.
- */
-static struct machine_desc machine_desc[] __attribute__ ((__section__ (".arch.info"))) = {
-#ifdef CONFIG_ARCH_EBSA110
- {
- MACH_TYPE_EBSA110,
- "EBSA110", /* RMK */
- 0x00000400,
- NO_VIDEO,
- 1, 0, 1, 0, 1,
- NULL
- },
+ ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+ setup_ramdisk( 1, 0, 0, 8192 );
+ setup_initrd( __phys_to_virt(0xd8000000), 3*1024*1024 );
+ }
+
+ else if (machine_is_empeg()) {
+ SET_BANK( 0, 0xc0000000, 4*1024*1024 );
+ SET_BANK( 1, 0xc8000000, 4*1024*1024 );
+ mi->nr_banks = 2;
+
+ ROOT_DEV = MKDEV( 3, 1 ); /* /dev/hda1 */
+ setup_ramdisk( 1, 0, 0, 4096 );
+ setup_initrd( 0xd0000000+((1024-320)*1024), (320*1024) );
+ }
+
+ else if (machine_is_lart()) {
+ /*
+ * Note that LART is a special case - it doesn't use physical
+ * address line A23 on the DRAM, so we effectively have 4 * 8MB
+ * in two SA1100 banks.
+ */
+ SET_BANK( 0, 0xc0000000, 8*1024*1024 );
+ SET_BANK( 1, 0xc1000000, 8*1024*1024 );
+ SET_BANK( 2, 0xc8000000, 8*1024*1024 );
+ SET_BANK( 3, 0xc9000000, 8*1024*1024 );
+ mi->nr_banks = 4;
+
+ ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+ setup_ramdisk(1, 0, 0, 8192);
+ setup_initrd(0xc0400000, 4*1024*1024);
+ }
+
+ else if (machine_is_thinclient()) {
+ SET_BANK( 0, 0xc0000000, 16*1024*1024 );
+ mi->nr_banks = 1;
+
+ ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+ setup_ramdisk( 1, 0, 0, 8192 );
+ setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 );
+ }
+
+ else if (machine_is_tifon()) {
+ SET_BANK( 0, 0xc0000000, 16*1024*1024 );
+ SET_BANK( 1, 0xc8000000, 16*1024*1024 );
+ mi->nr_banks = 2;
+
+ ROOT_DEV = MKDEV(UNNAMED_MAJOR, 0);
+ setup_ramdisk(1, 0, 0, 4096);
+ setup_initrd( 0xd0000000 + 0x1100004, 0x140000 );
+ }
+
+ else if (machine_is_victor()) {
+ SET_BANK( 0, 0xc0000000, 4*1024*1024 );
+ mi->nr_banks = 1;
+
+ ROOT_DEV = MKDEV( 60, 2 );
+
+ /* Get command line parameters passed from the loader (if any) */
+ if( *((char*)0xc0000000) )
+ strcpy( *cmdline, ((char *)0xc0000000) );
+
+ /* power off if any problem */
+ strcat( *cmdline, " panic=1" );
+ }
+
+}
+
+#ifdef CONFIG_SA1100_ASSABET
+MACHINE_START(ASSABET, "Intel-Assabet")
+ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+ FIXUP(fixup_sa1100)
+MACHINE_END
#endif
-#ifdef CONFIG_ARCH_RPC
- {
- MACH_TYPE_RISCPC,
- "Acorn-RiscPC", /* RMK */
- 0x10000100,
- NO_VIDEO,
- 1, 1, 0, 0, 0,
- fixup_acorn
- },
+#ifdef CONFIG_SA1100_BITSY
+MACHINE_START(BITSY, "Compaq Bitsy")
+ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+ BOOT_PARAMS(0xc0000100)
+ FIXUP(fixup_sa1100)
+MACHINE_END
#endif
-#ifdef CONFIG_ARCH_NEXUSPCI
- {
- MACH_TYPE_NEXUSPCI,
- "FTV/PCI", /* Philip Blundell */
- NO_PARAMS,
- NO_VIDEO,
- 0, 0, 0, 0, 0,
- NULL
- },
+#ifdef CONFIG_SA1100_BRUTUS
+MACHINE_START(BRUTUS, "Intel Brutus (SA1100 eval board)")
+ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+ FIXUP(fixup_sa1100)
+MACHINE_END
#endif
-#ifdef CONFIG_ARCH_EBSA285
- {
- MACH_TYPE_EBSA285,
- "EBSA285", /* RMK */
- 0x00000100,
- 0x000a0000, 0x000bffff,
- 0, 0, 0, 0, 0,
- fixup_ebsa285
- },
+#ifdef CONFIG_SA1100_EMPEG
+MACHINE_START(EMPEG, "empeg MP3 Car Audio Player")
+ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+ FIXUP(fixup_sa1100)
+MACHINE_END
#endif
-#ifdef CONFIG_ARCH_NETWINDER
- {
- MACH_TYPE_NETWINDER,
- "Rebel-NetWinder", /* RMK */
- 0x00000100,
- 0x000a0000, 0x000bffff,
- 1, 0, 1, 0, 0,
- fixup_netwinder
- },
+#ifdef CONFIG_SA1100_ITSY
+MACHINE_START(ITSY, "Compaq Itsy")
+ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+ BOOT_PARAMS(0xc0000100
+ FIXUP(fixup_sa1100)
+MACHINE_END
#endif
-#ifdef CONFIG_ARCH_CATS
- {
- MACH_TYPE_CATS,
- "Chalice-CATS", /* Philip Blundell */
- NO_PARAMS,
- 0x000a0000, 0x000bffff,
- 0, 0, 0, 0, 1,
- fixup_cats
- },
+#ifdef CONFIG_SA1100_LART
+MACHINE_START(LART, "LART")
+ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+ FIXUP(fixup_sa1100)
+MACHINE_END
#endif
-#ifdef CONFIG_ARCH_TBOX
- {
- MACH_TYPE_TBOX,
- "unknown-TBOX", /* Philip Blundell */
- NO_PARAMS,
- NO_VIDEO,
- 0, 0, 0, 0, 0,
- NULL
- },
+#ifdef CONFIG_SA1100_PLEB
+MACHINE_START(PLEB, "PLEB")
+ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+ FIXUP(fixup_sa1100)
+MACHINE_END
#endif
-#ifdef CONFIG_ARCH_CO285
- {
- MACH_TYPE_CO285,
- "co-EBSA285", /* Mark van Doesburg */
- NO_PARAMS,
- NO_VIDEO,
- 0, 0, 0, 0, 0,
- fixup_coebsa285
- },
+#ifdef CONFIG_SA1100_THINCLIENT
+MACHINE_START(THINCLIENT, "ADS ThinClient")
+ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+ FIXUP(fixup_sa1100)
+MACHINE_END
#endif
-#ifdef CONFIG_ARCH_CLPS7110
- {
- MACH_TYPE_CLPS7110,
- "CL-PS7110", /* Werner Almesberger */
- NO_PARAMS,
- NO_VIDEO,
- 0, 0, 0, 0, 0,
- NULL
- },
+#ifdef CONFIG_SA1100_TIFON
+MACHINE_START(TIFON, "Tifon")
+ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+ FIXUP(fixup_sa1100)
+MACHINE_END
#endif
-#ifdef CONFIG_ARCH_ARC
- {
- MACH_TYPE_ARCHIMEDES,
- "Acorn-Archimedes",/* RMK/DAG */
- 0x0207c000,
- NO_VIDEO,
- 0, 0, 0, 0, 0,
- fixup_acorn
- },
+#ifdef CONFIG_SA1100_VICTOR
+MACHINE_START(VICTOR, "VisuAide Victor")
+ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+ FIXUP(fixup_sa1100)
+MACHINE_END
#endif
-#ifdef CONFIG_ARCH_A5K
- {
- MACH_TYPE_A5K,
- "Acorn-A5000", /* RMK/PB */
- 0x0207c000,
- NO_VIDEO,
- 0, 0, 0, 0, 0,
- fixup_acorn
- },
+#endif
+
+#ifdef CONFIG_ARCH_EBSA110
+MACHINE_START(EBSA110, "EBSA110")
+ MAINTAINER("Russell King")
+ BOOT_MEM(0x00000000, 0xe0000000, 0xe0000000)
+ BOOT_PARAMS(0x00000400)
+ DISABLE_PARPORT(0)
+ DISABLE_PARPORT(2)
+ SOFT_REBOOT
+MACHINE_END
+#endif
+#ifdef CONFIG_ARCH_NEXUSPCI
+MACHINE_START(NEXUSPCI, "FTV/PCI")
+ MAINTAINER("Philip Blundell")
+ BOOT_MEM(0x40000000, 0x10000000, 0xe0000000)
+MACHINE_END
+#endif
+#ifdef CONFIG_ARCH_TBOX
+MACHINE_START(TBOX, "unknown-TBOX")
+ MAINTAINER("Philip Blundell")
+ BOOT_MEM(0x80000000, 0x00400000, 0xe0000000)
+MACHINE_END
+#endif
+#ifdef CONFIG_ARCH_CLPS7110
+MACHINE_START(CLPS7110, "CL-PS7110")
+ MAINTAINER("Werner Almesberger")
+MACHINE_END
#endif
#ifdef CONFIG_ARCH_ETOILE
- {
- MACH_TYPE_ETOILE,
- "Etoile", /* Alex de Vries */
- NO_PARAMS,
- NO_VIDEO,
- 0, 0, 0, 0, 0,
- NULL
- },
+MACHINE_START(ETOILE, "Etoile")
+ MAINTAINER("Alex de Vries")
+MACHINE_END
#endif
#ifdef CONFIG_ARCH_LACIE_NAS
- {
- MACH_TYPE_LACIE_NAS,
- "LaCie_NAS", /* Benjamin Herrenschmidt */
- NO_PARAMS,
- NO_VIDEO,
- 0, 0, 0, 0, 0,
- NULL
- },
+MACHINE_START(LACIE_NAS, "LaCie_NAS")
+ MAINTAINER("Benjamin Herrenschmidt")
+MACHINE_END
#endif
#ifdef CONFIG_ARCH_CLPS7500
- {
- MACH_TYPE_CLPS7500,
- "CL-PS7500", /* Philip Blundell */
- NO_PARAMS,
- NO_VIDEO,
- 0, 0, 0, 0, 0,
- NULL
- },
+MACHINE_START(CLPS7500, "CL-PS7500")
+ MAINTAINER("Philip Blundell")
+ BOOT_MEM(0x10000000, 0x03000000, 0xe0000000)
+MACHINE_END
#endif
#ifdef CONFIG_ARCH_SHARK
- {
- MACH_TYPE_SHARK,
- "Shark", /* Alexander Schulz */
- NO_PARAMS,
- 0x06000000, 0x06000000+0x001fffff,
- 0, 0, 0, 0, 0,
- NULL
- },
-#endif
-#ifdef CONFIG_ARCH_SA1100
- {
- MACH_TYPE_SA1100,
- "SA1100-based", /* Nicolas Pitre */
- NO_PARAMS,
- NO_VIDEO,
- 0, 0, 0, 0, 0,
- fixup_sa1100
- },
+MACHINE_START(SHARK, "Shark")
+ MAINTAINER("Alexander Schulz")
+ BOOT_MEM(0x08000000, 0x40000000, 0xe0000000)
+ VIDEO(0x06000000, 0x061fffff)
+MACHINE_END
#endif
#ifdef CONFIG_ARCH_PERSONAL_SERVER
- {
- MACH_TYPE_PERSONAL_SERVER,
- "Compaq Personal Server",
- NO_PARAMS,
- NO_VIDEO,
- 0, 0, 0, 0, 0,
- NULL
- }
+MACHINE_START(PERSONAL_SERVER, "Compaq Personal Server")
+ MAINTAINER("Jamey Hicks / George France")
+ BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000)
+ BOOT_PARAMS(0x00000100)
+MACHINE_END
#endif
-};
diff --git a/arch/arm/kernel/arch.h b/arch/arm/kernel/arch.h
index b7635b11e..91de77772 100644
--- a/arch/arm/kernel/arch.h
+++ b/arch/arm/kernel/arch.h
@@ -1,9 +1,27 @@
+/*
+ * The size of struct machine_desc
+ * (for assembler code)
+ */
+#define SIZEOF_MACHINE_DESC 40
+
+#ifndef __ASSEMBLY__
+
struct machine_desc {
+ /*
+ * Note! The first four elements are used
+ * by assembler code in head-armv.S
+ */
unsigned int nr; /* architecture number */
+ unsigned int phys_ram; /* start of physical ram */
+ unsigned int phys_io; /* start of physical io */
+ unsigned int virt_io; /* start of virtual io */
+
const char *name; /* architecture name */
unsigned int param_offset; /* parameter page */
+
unsigned int video_start; /* start of video RAM */
unsigned int video_end; /* end of video RAM */
+
unsigned int reserve_lp0 :1; /* never has lp0 */
unsigned int reserve_lp1 :1; /* never has lp1 */
unsigned int reserve_lp2 :1; /* never has lp2 */
@@ -13,3 +31,43 @@ struct machine_desc {
struct param_struct *, char **,
struct meminfo *);
};
+
+/*
+ * Set of macros to define architecture features
+ */
+#define MACHINE_START(_type,_name) \
+const struct machine_desc __mach_desc_##_type \
+ __attribute__((__section__(".arch.info"))) = { \
+ nr: MACH_TYPE_##_type##, \
+ name: _name,
+
+#define MAINTAINER(n)
+
+#define BOOT_MEM(_pram,_pio,_vio) \
+ phys_ram: _pram, \
+ phys_io: _pio, \
+ virt_io: _vio,
+
+#define BOOT_PARAMS(_params) \
+ param_offset: _params,
+
+#define VIDEO(_start,_end) \
+ video_start: _start, \
+ video_end: _end,
+
+#define DISABLE_PARPORT(_n) \
+ reserve_lp##_n##: 1,
+
+#define BROKEN_HLT \
+ broken_hlt: 1,
+
+#define SOFT_REBOOT \
+ soft_reboot: 1,
+
+#define FIXUP(_func) \
+ fixup: _func,
+
+#define MACHINE_END \
+};
+
+#endif
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index 02a4f6cf0..ffd0f1b5e 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -101,6 +101,7 @@ EXPORT_SYMBOL(kernel_thread);
EXPORT_SYMBOL(system_rev);
EXPORT_SYMBOL(system_serial_low);
EXPORT_SYMBOL(system_serial_high);
+EXPORT_SYMBOL(mem_fclk_21285);
EXPORT_SYMBOL(__bug);
EXPORT_SYMBOL(__readwrite_bug);
EXPORT_SYMBOL(enable_irq);
diff --git a/arch/arm/kernel/arthur.c b/arch/arm/kernel/arthur.c
index 77c7d7396..8a8a5510d 100644
--- a/arch/arm/kernel/arthur.c
+++ b/arch/arm/kernel/arthur.c
@@ -59,11 +59,7 @@ static struct exec_domain arthur_exec_domain = {
PER_RISCOS, PER_RISCOS,
arthur_to_linux_signals,
linux_to_arthur_signals,
-#ifdef MODULE
- &__this_module, /* No usage counter. */
-#else
- NULL,
-#endif
+ THIS_MODULE,
NULL /* Nothing after this in the list. */
};
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index c4ccd64e3..835bce140 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -21,7 +21,7 @@ int have_isa_bridge;
extern void hw_init(void);
-void pcibios_report_device_errors(void)
+void pcibios_report_device_errors(int warn)
{
struct pci_dev *dev;
@@ -34,8 +34,11 @@ void pcibios_report_device_errors(void)
continue;
pci_write_config_word(dev, PCI_STATUS, status & 0xf900);
- printk(KERN_DEBUG "PCI: %02X:%02X: status %04X on %s\n",
- dev->bus->number, dev->devfn, status, dev->name);
+
+ if (warn)
+ printk(KERN_DEBUG "PCI: %02X:%02X: status %04X "
+ "on %s\n", dev->bus->number, dev->devfn,
+ status, dev->name);
}
}
@@ -48,10 +51,6 @@ void pcibios_report_device_errors(void)
* - (0x48) enable all memory requests from ISA to be channeled to PCI
* - (0x42) disable ping-pong (as per errata)
* - (0x40) enable PCI packet retry
- * - (0x44) Route INTA to IRQ11
- * - (0x83) don't use CPU park enable, park on last master, disable GAT bit
- * - (0x80) default rotating priorities
- * - (0x81) rotate bank 4
*/
static void __init pci_fixup_83c553(struct pci_dev *dev)
{
@@ -64,10 +63,26 @@ static void __init pci_fixup_83c553(struct pci_dev *dev)
pci_write_config_byte(dev, 0x48, 0xff);
pci_write_config_byte(dev, 0x42, 0x00);
pci_write_config_byte(dev, 0x40, 0x22);
- pci_write_config_word(dev, 0x44, 0xb000);
- pci_write_config_byte(dev, 0x83, 0x02);
+
+ /*
+ * We used to set the arbiter to "park on last master"
+ * (bit 1 set), but unfortunately the CyberPro does not
+ * park the bus. We must therefore park on CPU.
+ */
+ pci_write_config_byte(dev, 0x83, 0x00);
+
+ /*
+ * Rotate priorities of each PCI request
+ */
pci_write_config_byte(dev, 0x80, 0xe0);
pci_write_config_byte(dev, 0x81, 0x01);
+
+ /*
+ * Route INTA input to IRQ 11, and set
+ * IRQ11 to be level sensitive.
+ */
+ pci_write_config_word(dev, 0x44, 0xb000);
+ outb(0x08, 0x4d1);
}
static void __init pci_fixup_unassign(struct pci_dev *dev)
@@ -77,6 +92,23 @@ static void __init pci_fixup_unassign(struct pci_dev *dev)
}
/*
+ * Prevent the PCI layer from seeing the resources
+ * allocated to this device. These resources are
+ * of no consequence to the PCI layer (they are
+ * handled elsewhere).
+ */
+static void __init pci_fixup_disable(struct pci_dev *dev)
+{
+ int i;
+
+ for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+ dev->resource[i].start = 0;
+ dev->resource[i].end = 0;
+ dev->resource[i].flags = 0;
+ }
+}
+
+/*
* PCI IDE controllers use non-standard I/O port
* decoding, respect it.
*/
@@ -100,6 +132,10 @@ static void __init pci_fixup_ide_bases(struct pci_dev *dev)
struct pci_fixup pcibios_fixups[] = {
{
PCI_FIXUP_HEADER,
+ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285,
+ pci_fixup_disable
+ }, {
+ PCI_FIXUP_HEADER,
PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_83C553,
pci_fixup_83c553
}, {
@@ -339,6 +375,7 @@ static int __init netwinder_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
case DEV(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2000):
case DEV(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2010):
+ case DEV(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_5000):
return IRQ_NETWINDER_VGA;
default:
diff --git a/arch/arm/kernel/debug-armv.S b/arch/arm/kernel/debug-armv.S
index 5802dac70..ce7f2f94c 100644
--- a/arch/arm/kernel/debug-armv.S
+++ b/arch/arm/kernel/debug-armv.S
@@ -68,7 +68,10 @@
#ifndef CONFIG_DEBUG_DC21285_PORT
/* For NetWinder debugging */
.macro addruart,rx
- mov \rx, #0xff000000
+ mrc p15, 0, \rx, c1, c0
+ tst \rx, #1 @ MMU enabled?
+ moveq \rx, #0x7c000000 @ physical
+ movne \rx, #0xff000000 @ virtual
orr \rx, \rx, #0x000003f8
.endm
@@ -133,7 +136,10 @@
#elif defined(CONFIG_ARCH_SA1100)
.macro addruart,rx
- mov \rx, #0xf8000000
+ mrc p15, 0, \rx, c1, c0
+ tst \rx, #1 @ MMU enabled?
+ moveq \rx, #0x80000000 @ physical base address
+ movne \rx, #0xf8000000 @ virtual address
add \rx, \rx, #0x00050000 @ Ser3
@add \rx, \rx, #0x00010000 @ Ser1
.endm
@@ -171,7 +177,7 @@ ENTRY(printhex4)
ENTRY(printhex2)
mov r1, #2
-printhex: ldr r2, =hexbuf
+printhex: adr r2, hexbuf
add r3, r2, r1
mov r1, #0
strb r1, [r3]
@@ -209,5 +215,4 @@ ENTRY(printch)
mov r0, #0
b 1b
- .bss
hexbuf: .space 16
diff --git a/arch/arm/kernel/dec21285.c b/arch/arm/kernel/dec21285.c
index 64c5861f0..bc8a951e2 100644
--- a/arch/arm/kernel/dec21285.c
+++ b/arch/arm/kernel/dec21285.c
@@ -23,18 +23,28 @@
#define MAX_SLOTS 21
extern int setup_arm_irq(int, struct irqaction *);
-extern void pcibios_report_device_errors(void);
+extern void pcibios_report_device_errors(int warn);
static unsigned long
-dc21285_base_address(struct pci_dev *dev, int where)
+dc21285_base_address(struct pci_dev *dev)
{
unsigned long addr = 0;
unsigned int devfn = dev->devfn;
- if (dev->bus->number != 0)
+ if (dev->bus->number == 0) {
+ if (PCI_SLOT(devfn) == 0)
+ /*
+ * For devfn 0, point at the 21285
+ */
+ addr = ARMCSR_BASE;
+ else {
+ devfn -= 1 << 3;
+
+ if (devfn < PCI_DEVFN(MAX_SLOTS, 0))
+ addr = PCICFG0_BASE | 0xc00000 | (devfn << 8);
+ }
+ } else
addr = PCICFG1_BASE | (dev->bus->number << 16) | (devfn << 8);
- else if (devfn < PCI_DEVFN(MAX_SLOTS, 0))
- addr = PCICFG0_BASE | 0xc00000 | (devfn << 8);
return addr;
}
@@ -42,7 +52,7 @@ dc21285_base_address(struct pci_dev *dev, int where)
static int
dc21285_read_config_byte(struct pci_dev *dev, int where, u8 *value)
{
- unsigned long addr = dc21285_base_address(dev, where);
+ unsigned long addr = dc21285_base_address(dev);
u8 v;
if (addr)
@@ -59,7 +69,7 @@ dc21285_read_config_byte(struct pci_dev *dev, int where, u8 *value)
static int
dc21285_read_config_word(struct pci_dev *dev, int where, u16 *value)
{
- unsigned long addr = dc21285_base_address(dev, where);
+ unsigned long addr = dc21285_base_address(dev);
u16 v;
if (addr)
@@ -76,7 +86,7 @@ dc21285_read_config_word(struct pci_dev *dev, int where, u16 *value)
static int
dc21285_read_config_dword(struct pci_dev *dev, int where, u32 *value)
{
- unsigned long addr = dc21285_base_address(dev, where);
+ unsigned long addr = dc21285_base_address(dev);
u32 v;
if (addr)
@@ -93,7 +103,7 @@ dc21285_read_config_dword(struct pci_dev *dev, int where, u32 *value)
static int
dc21285_write_config_byte(struct pci_dev *dev, int where, u8 value)
{
- unsigned long addr = dc21285_base_address(dev, where);
+ unsigned long addr = dc21285_base_address(dev);
if (addr)
asm("str%?b %0, [%1, %2]"
@@ -105,7 +115,7 @@ dc21285_write_config_byte(struct pci_dev *dev, int where, u8 value)
static int
dc21285_write_config_word(struct pci_dev *dev, int where, u16 value)
{
- unsigned long addr = dc21285_base_address(dev, where);
+ unsigned long addr = dc21285_base_address(dev);
if (addr)
asm("str%?h %0, [%1, %2]"
@@ -117,7 +127,7 @@ dc21285_write_config_word(struct pci_dev *dev, int where, u16 value)
static int
dc21285_write_config_dword(struct pci_dev *dev, int where, u32 value)
{
- unsigned long addr = dc21285_base_address(dev, where);
+ unsigned long addr = dc21285_base_address(dev);
if (addr)
asm("str%? %0, [%1, %2]"
@@ -147,6 +157,9 @@ dc21285_error(int irq, void *dev_id, struct pt_regs *regs)
unsigned long irqstatus = *CSR_IRQ_RAWSTATUS;
int warn = time_after_eq(jiffies, next_warn);
+ if (machine_is_netwinder())
+ warn = 0;
+
ctrl |= SA110_CNTL_DISCARDTIMER;
if (warn) {
@@ -193,7 +206,7 @@ dc21285_error(int irq, void *dev_id, struct pt_regs *regs)
if (warn)
printk("pc=[<%08lX>]\n", instruction_pointer(regs));
- pcibios_report_device_errors();
+ pcibios_report_device_errors(warn);
*CSR_PCICMD = cmd;
*CSR_SA110_CNTL = ctrl;
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 97dfef0c1..97fcfc522 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -6,7 +6,7 @@
#define S_OFF 8
.macro get_softirq, rd
-#ifdef __SMP__
+#ifdef CONFIG_SMP
#error SMP not supported
#else
ldr \rd, __softirq_state
diff --git a/arch/arm/kernel/head-armv.S b/arch/arm/kernel/head-armv.S
index 27a280b8b..956d9ccd2 100644
--- a/arch/arm/kernel/head-armv.S
+++ b/arch/arm/kernel/head-armv.S
@@ -12,6 +12,8 @@
#include <asm/hardware.h>
#include <asm/dec21285.h>
+#include "arch.h"
+
#if (TEXTADDR & 0xffff) != 0x8000
#error TEXTADDR must start at 0xXXXX8000
#endif
@@ -231,6 +233,13 @@ __create_page_tables:
* Generally, only serious errors cause this.
*/
__error:
+#ifdef CONFIG_DEBUG_LL
+ mov r8, r0 @ preserve r0
+ adr r0, err_str
+ bl printascii
+ mov r0, r8
+ bl printch
+#endif
#ifdef CONFIG_ARCH_RPC
/*
* Turn the screen red on a error - RiscPC only.
@@ -247,7 +256,10 @@ __error:
1: mov r0, r0
b 1b
-
+#ifdef CONFIG_DEBUG_LL
+err_str: .asciz "\nError: "
+ .align
+#endif
/*
* Read processor ID register (CP#15, CR0), and determine
@@ -262,9 +274,9 @@ __error:
__lookup_processor_type:
adr r5, 2f
ldmia r5, {r7, r9, r10}
- sub r5, r5, r9
+ sub r5, r5, r10
add r7, r7, r5
- add r10, r10, r5
+ add r10, r9, r5
mrc p15, 0, r9, c0, c0 @ get processor id
1: ldmia r10, {r5, r6, r8} @ value, mask, mmuflags
eor r5, r5, r9
@@ -277,8 +289,10 @@ __lookup_processor_type:
mov pc, lr
2: .long __proc_info_end
- .long 2b
.long __proc_info_begin
+ .long 2b
+ .long __arch_info_begin
+ .long __arch_info_end
/*
* Lookup machine architecture
@@ -290,135 +304,18 @@ __lookup_processor_type:
* r7 = byte offset into page tables for IO
*/
__lookup_architecture_type:
- cmp r1, #(__arch_types_end - __arch_types_start) / 16
- bge 1f
- adr r4, __arch_types_start
- add r4, r4, r1, lsl #4
- ldmia r4, {r4, r5, r6, r7}
- mov r7, r7, lsr #18
+ adr r4, 2b
+ ldmia r4, {r2, r3, r5, r6, r7} @ throw away r2, r3
+ sub r5, r4, r5
+ add r4, r6, r5
+ add r7, r7, r5
+1: ldr r5, [r4]
+ teq r5, r1
+ beq 2f
+ add r4, r4, #SIZEOF_MACHINE_DESC
+ cmp r4, r7
+ blt 1b
+ mov r7, #0
mov pc, lr
-1: mov r7, #0
+2: ldmib r4, {r5, r6, r7}
mov pc, lr
-
-/*
- * Machine parameters. Each machine requires 4 words, which are:
- *
- * word0: unused
- * word1: physical start address of RAM
- * word2: physical start address of IO
- * word3: virtual start address of IO
- *
- * The IO mappings entered here are used to set up mappings
- * required for debugging information to be shown to the user.
- * paging_init() does the real page table initialisation.
- */
- .type __arch_types_start, #object
- @ 0x00 - DEC EBSA110
-__arch_types_start:
- .long 0
- .long 0
- .long 0xe0000000
- .long 0xe0000000
-
- @ 0x01 - Acorn RiscPC
- .long 0
- .long 0x10000000
- .long 0x03000000
- .long 0xe0000000
-
- @ 0x02 - Unused
- .long 0
- .long 0
- .long 0xe0000000
- .long 0xe0000000
-
- @ 0x03 - NexusPCI
- .long 0
- .long 0x40000000
- .long 0x10000000
- .long 0xe0000000
-
- @ 0x04 - DEC EBSA285
- .long 0
- .long 0
- .long DC21285_ARMCSR_BASE
- .long 0xfe000000
-
- @ 0x05 - Rebel.com NetWinder
- .long 0
- .long 0
- .long DC21285_ARMCSR_BASE
- .long 0xfe000000
-
- @ 0x06 - CATS
- .long 0
- .long 0
- .long DC21285_ARMCSR_BASE
- .long 0xfe000000
-
- @ 0x07 - tbox
- .long 0
- .long 0x80000000
- .long 0x00400000 @ Uart
- .long 0xe0000000
-
- @ 0x08 - DEC EBSA285 as co-processor
- .long 0
- .long 0
- .long DC21285_ARMCSR_BASE @ Physical I/O base address
- .long 0x7cf00000 @ Virtual I/O base address
-
- @ 0x09 - CL-PS7110
- .long 0
- .long 0
- .long 0
- .long 0
-
- @ 0x0a - Acorn Archimedes
- .long 0
- .long 0
- .long 0
- .long 0
-
- @ 0x0b - Acorn A5000
- .long 0
- .long 0
- .long 0
- .long 0
-
- @ 0x0c - Etoile
- .long 0
- .long 0
- .long 0
- .long 0
-
- @ 0x0d - LaCie_NAS
- .long 0
- .long 0
- .long 0
- .long 0
-
- @ 0x0e - CL-PS7500
- .long 0
- .long 0x10000000
- .long 0x03000000
- .long 0xe0000000
-
- @ 0x0f - Digital Shark (DNARD)
- .long 0
- .long 0x08000000
- .long 0x40000000
- .long 0xe0000000
-
- @ 0x10 - SA1100
- .long 0
- .long 0xc0000000
- .long 0x80000000
- .long 0xf8000000
-
- /*
- * Don't add anything here unless you have an
- * architecture number allocated - see
- * Documentation/arm/README
- */
-__arch_types_end:
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 699cea4ab..1b26ced94 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -118,10 +118,8 @@ void enable_irq(unsigned int irq)
cliIF();
irq_desc[irq].probing = 0;
irq_desc[irq].triggered = 0;
- if (!irq_desc[irq].noautoenable) {
- irq_desc[irq].enabled = 1;
- irq_desc[irq].unmask(irq);
- }
+ irq_desc[irq].enabled = 1;
+ irq_desc[irq].unmask(irq);
spin_unlock_irqrestore(&irq_controller_lock, flags);
}
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index f04b422b4..ec67dcbd0 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -5,15 +5,14 @@
*/
#include <linux/config.h>
#include <linux/kernel.h>
-#include <linux/mm.h>
#include <linux/stddef.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/utsname.h>
#include <linux/blk.h>
#include <linux/console.h>
-#include <linux/init.h>
#include <linux/bootmem.h>
+#include <linux/init.h>
#include <asm/elf.h>
#include <asm/hardware.h>
@@ -33,6 +32,7 @@
#endif
extern void paging_init(struct meminfo *);
+extern void bootmem_init(struct meminfo *);
extern void reboot_setup(char *str);
extern void disable_hlt(void);
extern int root_mountflags;
@@ -43,6 +43,7 @@ unsigned int __machine_arch_type;
unsigned int system_rev;
unsigned int system_serial_low;
unsigned int system_serial_high;
+unsigned int mem_fclk_21285 = 50000000;
unsigned int elf_hwcap;
#ifdef MULTI_CPU
@@ -199,7 +200,8 @@ parse_cmdline(struct meminfo *mi, char **cmdline_p, char *from)
if (to != command_line)
to -= 1;
- /* If the user specifies memory size, we
+ /*
+ * If the user specifies memory size, we
* blow away any automatically generated
* size.
*/
@@ -256,137 +258,6 @@ void __init setup_initrd(unsigned int start, unsigned int size)
#endif
}
-#define O_PFN_DOWN(x) ((x) >> PAGE_SHIFT)
-#define V_PFN_DOWN(x) O_PFN_DOWN(__pa(x))
-
-#define O_PFN_UP(x) (PAGE_ALIGN(x) >> PAGE_SHIFT)
-#define V_PFN_UP(x) O_PFN_UP(__pa(x))
-
-#define PFN_SIZE(x) ((x) >> PAGE_SHIFT)
-#define PFN_RANGE(s,e) PFN_SIZE(PAGE_ALIGN((unsigned long)(e)) - \
- (((unsigned long)(s)) & PAGE_MASK))
-
-/*
- * FIXME: These can be removed when Ingo's cleanup patch goes in
- */
-#define free_bootmem(s,sz) free_bootmem((s)<<PAGE_SHIFT, (sz)<<PAGE_SHIFT)
-#define reserve_bootmem(s,sz) reserve_bootmem((s)<<PAGE_SHIFT, (sz)<<PAGE_SHIFT)
-
-static unsigned int __init
-find_bootmap_pfn(struct meminfo *mi, unsigned int bootmap_pages)
-{
- unsigned int start_pfn, bank, bootmap_pfn;
-
- start_pfn = V_PFN_UP(&_end);
- bootmap_pfn = 0;
-
- /*
- * FIXME: We really want to avoid allocating the bootmap
- * over the top of the initrd.
- */
-#ifdef CONFIG_BLK_DEV_INITRD
- if (initrd_start) {
- if (__pa(initrd_end) > mi->end) {
- printk ("initrd extends beyond end of memory "
- "(0x%08lx > 0x%08lx) - disabling initrd\n",
- __pa(initrd_end), mi->end);
- initrd_start = 0;
- initrd_end = 0;
- }
- }
-#endif
-
- for (bank = 0; bank < mi->nr_banks; bank ++) {
- unsigned int start, end;
-
- if (mi->bank[bank].size == 0)
- continue;
-
- start = O_PFN_UP(mi->bank[bank].start);
- end = O_PFN_DOWN(mi->bank[bank].size +
- mi->bank[bank].start);
-
- if (end < start_pfn)
- continue;
-
- if (start < start_pfn)
- start = start_pfn;
-
- if (end <= start)
- continue;
-
- if (end - start >= bootmap_pages) {
- bootmap_pfn = start;
- break;
- }
- }
-
- if (bootmap_pfn == 0)
- BUG();
-
- return bootmap_pfn;
-}
-
-/*
- * Initialise the bootmem allocator.
- */
-static void __init setup_bootmem(struct meminfo *mi)
-{
- unsigned int end_pfn, start_pfn, bootmap_pages, bootmap_pfn;
- unsigned int i;
-
- /*
- * Calculate the physical address of the top of memory.
- */
- mi->end = 0;
- for (i = 0; i < mi->nr_banks; i++) {
- unsigned long end;
-
- if (mi->bank[i].size != 0) {
- end = mi->bank[i].start + mi->bank[i].size;
- if (mi->end < end)
- mi->end = end;
- }
- }
-
- start_pfn = O_PFN_UP(PHYS_OFFSET);
- end_pfn = O_PFN_DOWN(mi->end);
- bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn);
- bootmap_pfn = find_bootmap_pfn(mi, bootmap_pages);
-
- /*
- * Initialise the boot-time allocator
- */
- init_bootmem_start(bootmap_pfn, start_pfn, end_pfn);
-
- /*
- * Register all available RAM with the bootmem allocator.
- */
- for (i = 0; i < mi->nr_banks; i++)
- if (mi->bank[i].size)
- free_bootmem(O_PFN_UP(mi->bank[i].start),
- PFN_SIZE(mi->bank[i].size));
-
- /*
- * Register the reserved regions with bootmem
- */
- reserve_bootmem(bootmap_pfn, bootmap_pages);
- reserve_bootmem(V_PFN_DOWN(&_stext), PFN_RANGE(&_stext, &_end));
-
-#ifdef CONFIG_CPU_32
- /*
- * Reserve the page tables. These are already in use.
- */
- reserve_bootmem(V_PFN_DOWN(swapper_pg_dir),
- PFN_SIZE(PTRS_PER_PGD * sizeof(void *)));
-#endif
-#ifdef CONFIG_BLK_DEV_INITRD
- if (initrd_start)
- reserve_bootmem(V_PFN_DOWN(initrd_start),
- PFN_RANGE(initrd_start, initrd_end));
-#endif
-}
-
static void __init
request_standard_resources(struct meminfo *mi, struct machine_desc *mdesc)
{
@@ -487,6 +358,9 @@ void __init setup_arch(char **cmdline_p)
system_serial_low = params->u1.s.system_serial_low;
system_serial_high = params->u1.s.system_serial_high;
+ if (params->u1.s.mem_fclk_21285 > 0)
+ mem_fclk_21285 = params->u1.s.mem_fclk_21285;
+
setup_ramdisk((params->u1.s.flags & FLAG_RDLOAD) == 0,
(params->u1.s.flags & FLAG_RDPROMPT) == 0,
params->u1.s.rd_start,
@@ -518,9 +392,8 @@ void __init setup_arch(char **cmdline_p)
memcpy(saved_command_line, from, COMMAND_LINE_SIZE);
saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
parse_cmdline(&meminfo, cmdline_p, from);
- setup_bootmem(&meminfo);
+ bootmem_init(&meminfo);
request_standard_resources(&meminfo, mdesc);
-
paging_init(&meminfo);
#ifdef CONFIG_VT
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index 0fcad67c0..c79b323a9 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -30,6 +30,7 @@
extern int setup_arm_irq(int, struct irqaction *);
extern void setup_timer(void);
+extern rwlock_t xtime_lock;
extern volatile unsigned long lost_ticks;
/* change this if you have some constant time drift */
@@ -59,7 +60,8 @@ static unsigned long dummy_gettimeoffset(void)
}
/*
- * hook for getting the time offset
+ * hook for getting the time offset. Note that it is
+ * always called with interrupts disabled.
*/
unsigned long (*gettimeoffset)(void) = dummy_gettimeoffset;
@@ -175,29 +177,33 @@ static void do_leds(void)
void do_gettimeofday(struct timeval *tv)
{
unsigned long flags;
+ unsigned long usec, sec;
- save_flags_cli (flags);
- *tv = xtime;
- tv->tv_usec += gettimeoffset();
+ read_lock_irqsave(&xtime_lock, flags);
+ usec = gettimeoffset();
+ {
+ unsigned long lost = lost_ticks;
- /*
- * xtime is atomically updated in timer_bh. lost_ticks is
- * nonzero if the timer bottom half hasnt executed yet.
- */
- if (lost_ticks)
- tv->tv_usec += USECS_PER_JIFFY;
-
- restore_flags(flags);
-
- if (tv->tv_usec >= 1000000) {
- tv->tv_usec -= 1000000;
- tv->tv_sec++;
+ if (lost)
+ usec += lost * USECS_PER_JIFFY;
}
+ sec = xtime.tv_sec;
+ usec += xtime.tv_usec;
+ read_unlock_irqrestore(&xtime_lock, flags);
+
+ /* usec may have gone up a lot: be safe */
+ while (usec >= 1000000) {
+ usec -= 1000000;
+ sec++;
+ }
+
+ tv->tv_sec = sec;
+ tv->tv_usec = usec;
}
void do_settimeofday(struct timeval *tv)
{
- cli ();
+ write_lock_irq(&xtime_lock);
/* This is revolting. We need to set the xtime.tv_usec
* correctly. However, the value in this location is
* is value at the last tick.
@@ -205,8 +211,9 @@ void do_settimeofday(struct timeval *tv)
* would have done, and then undo it!
*/
tv->tv_usec -= gettimeoffset();
+ tv->tv_usec -= lost_ticks * USECS_PER_JIFFY;
- if (tv->tv_usec < 0) {
+ while (tv->tv_usec < 0) {
tv->tv_usec += 1000000;
tv->tv_sec--;
}
@@ -216,7 +223,7 @@ void do_settimeofday(struct timeval *tv)
time_status |= STA_UNSYNC;
time_maxerror = NTP_PHASE_LIMIT;
time_esterror = NTP_PHASE_LIMIT;
- sti();
+ write_unlock_irq(&xtime_lock);
}
static struct irqaction timer_irq = {
diff --git a/arch/arm/lib/csumpartialcopy.S b/arch/arm/lib/csumpartialcopy.S
index 7289619da..fc52662a8 100644
--- a/arch/arm/lib/csumpartialcopy.S
+++ b/arch/arm/lib/csumpartialcopy.S
@@ -12,16 +12,46 @@
* Params : r0 = src, r1 = dst, r2 = len, r3 = checksum
* Returns : r0 = new checksum
*/
+
+ .macro save_regs
+ stmfd sp!, {r4 - r8, fp, ip, lr, pc}
+ .endm
+
+ .macro load_regs,flags
+ LOADREGS(\flags,fp,{r4 - r8, fp, sp, pc})
+ .endm
+
+ .macro load1b, reg1
+ ldrb \reg1, [r0], #1
+ .endm
+
+ .macro load2b, reg1, reg2
+ ldrb \reg1, [r0], #1
+ ldrb \reg2, [r0], #1
+ .endm
+
+ .macro load1l, reg1
+ ldr \reg1, [r0], #4
+ .endm
+
+ .macro load2l, reg1, reg2
+ ldr \reg1, [r0], #4
+ ldr \reg2, [r0], #4
+ .endm
+
+ .macro load4l, reg1, reg2, reg3, reg4
+ ldmia r0!, {\reg1, \reg2, \reg3, \reg4}
+ .endm
+
ENTRY(csum_partial_copy_nocheck)
mov ip, sp
- stmfd sp!, {r4 - r8, fp, ip, lr, pc}
+ save_regs
sub fp, ip, #4
cmp r2, #4
- blt Ltoo_small
+ blt .too_small
tst r1, #2 @ Test destination alignment
- beq Ldst_aligned
- ldrb ip, [r0], #1
- ldrb r8, [r0], #1
+ beq .dst_aligned
+ load2b ip, r8
subs r2, r2, #2 @ We do not know if SRC is aligned...
orr ip, ip, r8, lsl #8
adds r3, r3, ip
@@ -29,12 +59,12 @@ ENTRY(csum_partial_copy_nocheck)
strb ip, [r1], #1
mov ip, ip, lsr #8
strb ip, [r1], #1 @ Destination now aligned
-Ldst_aligned: tst r0, #3
- bne Lsrc_not_aligned
+.dst_aligned: tst r0, #3
+ bne .src_not_aligned
adds r3, r3, #0
bics ip, r2, #15 @ Routine for src & dst aligned
- beq 3f
-1: ldmia r0!, {r4, r5, r6, r7}
+ beq 2f
+1: load4l r4, r5, r6, r7
stmia r1!, {r4, r5, r6, r7}
adcs r3, r3, r4
adcs r3, r3, r5
@@ -43,65 +73,69 @@ Ldst_aligned: tst r0, #3
sub ip, ip, #16
teq ip, #0
bne 1b
-3: ands ip, r2, #12
- beq 5f
- tst ip, #8
+2: ands ip, r2, #12
beq 4f
- ldmia r0!, {r4, r5}
+ tst ip, #8
+ beq 3f
+ load2l r4, r5
stmia r1!, {r4, r5}
adcs r3, r3, r4
adcs r3, r3, r5
tst ip, #4
- beq 5f
-4: ldr r4, [r0], #4
+ beq 4f
+3: load1l r4
str r4, [r1], #4
adcs r3, r3, r4
-5: ands r2, r2, #3
+4: ands r2, r2, #3
adceq r0, r3, #0
- LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc})
- ldr r4, [r0], #4
+ load_regs eqea
+ load1l r4
tst r2, #2
- beq Lexit_r4
+ beq .exit
adcs r3, r3, r4, lsl #16
strb r4, [r1], #1
mov r4, r4, lsr #8
strb r4, [r1], #1
mov r4, r4, lsr #8
- b Lexit_r4
+.exit: tst r2, #1
+ strneb r4, [r1], #1
+ andne r4, r4, #255
+ adcnes r3, r3, r4
+ adcs r0, r3, #0
+ load_regs ea
-Ltoo_small: teq r2, #0
- LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc})
+.too_small: teq r2, #0
+ load_regs eqea
cmp r2, #2
- blt Ltoo_small1
- ldrb ip, [r0], #1
- ldrb r8, [r0], #1
+ blt .too_small1
+ load2b ip, r8
orr ip, ip, r8, lsl #8
adds r3, r3, ip
strb ip, [r1], #1
strb r8, [r1], #1
tst r2, #1
-Ltoo_small1: ldrneb r4, [r0], #1
-Lexit_r4: tst r2, #1
- strneb r4, [r1], #1
- andne r4, r4, #255
- adcnes r3, r3, r4
- adcs r0, r3, #0
- LOADREGS(ea,fp,{r4 - r8, fp, sp, pc})
+.too_small1: @ C = 0
+ beq .csum_exit
+ load1b ip
+ strb ip, [r1], #1
+ adcs r3, r3, ip
+.csum_exit: adc r0, r3, #0
+ load_regs ea
-Lsrc_not_aligned:
+.src_not_aligned:
cmp r2, #4
- blt Ltoo_small
+ blt .too_small
and ip, r0, #3
bic r0, r0, #3
- ldr r4, [r0], #4
+ load1l r4
cmp ip, #2
- beq Lsrc2_aligned
- bhi Lsrc3_aligned
+ beq .src2_aligned
+ bhi .src3_aligned
mov r4, r4, lsr #8
adds r3, r3, #0
bics ip, r2, #15
beq 2f
-1: ldmia r0!, {r5, r6, r7, r8}
+1: load4l r5, r6, r7, r8
orr r4, r4, r5, lsl #24
mov r5, r5, lsr #8
orr r5, r5, r6, lsl #24
@@ -122,7 +156,7 @@ Lsrc_not_aligned:
beq 4f
tst ip, #8
beq 3f
- ldmia r0!, {r5, r6}
+ load2l r5, r6
orr r4, r4, r5, lsl #24
mov r5, r5, lsr #8
orr r5, r5, r6, lsl #24
@@ -132,28 +166,28 @@ Lsrc_not_aligned:
mov r4, r6, lsr #8
tst ip, #4
beq 4f
-3: ldr r5, [r0], #4
+3: load1l r5
orr r4, r4, r5, lsl #24
str r4, [r1], #4
adcs r3, r3, r4
mov r4, r5, lsr #8
4: ands r2, r2, #3
adceq r0, r3, #0
- LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc})
+ load_regs eqea
tst r2, #2
- beq Lexit_r4
+ beq .exit
adcs r3, r3, r4, lsl #16
strb r4, [r1], #1
mov r4, r4, lsr #8
strb r4, [r1], #1
mov r4, r4, lsr #8
- b Lexit_r4
+ b .exit
-Lsrc2_aligned: mov r4, r4, lsr #16
+.src2_aligned: mov r4, r4, lsr #16
adds r3, r3, #0
bics ip, r2, #15
beq 2f
-1: ldmia r0!, {r5, r6, r7, r8}
+1: load4l r5, r6, r7, r8
orr r4, r4, r5, lsl #16
mov r5, r5, lsr #16
orr r5, r5, r6, lsl #16
@@ -174,7 +208,7 @@ Lsrc2_aligned: mov r4, r4, lsr #16
beq 4f
tst ip, #8
beq 3f
- ldmia r0!, {r5, r6}
+ load2l r5, r6
orr r4, r4, r5, lsl #16
mov r5, r5, lsr #16
orr r5, r5, r6, lsl #16
@@ -184,28 +218,31 @@ Lsrc2_aligned: mov r4, r4, lsr #16
mov r4, r6, lsr #16
tst ip, #4
beq 4f
-3: ldr r5, [r0], #4
+3: load1l r5
orr r4, r4, r5, lsl #16
str r4, [r1], #4
adcs r3, r3, r4
mov r4, r5, lsr #16
4: ands r2, r2, #3
adceq r0, r3, #0
- LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc})
+ load_regs eqea
tst r2, #2
- beq Lexit_r4
+ beq .exit
adcs r3, r3, r4, lsl #16
strb r4, [r1], #1
mov r4, r4, lsr #8
strb r4, [r1], #1
- ldrb r4, [r0], #1
- b Lexit_r4
+ tst r2, #1
+ adceq r0, r3, #0
+ load_regs eqea
+ load1b r4
+ b .exit
-Lsrc3_aligned: mov r4, r4, lsr #24
+.src3_aligned: mov r4, r4, lsr #24
adds r3, r3, #0
bics ip, r2, #15
beq 2f
-1: ldmia r0!, {r5, r6, r7, r8}
+1: load4l r5, r6, r7, r8
orr r4, r4, r5, lsl #8
mov r5, r5, lsr #24
orr r5, r5, r6, lsl #8
@@ -226,7 +263,7 @@ Lsrc3_aligned: mov r4, r4, lsr #24
beq 4f
tst ip, #8
beq 3f
- ldmia r0!, {r5, r6}
+ load2l r5, r6
orr r4, r4, r5, lsl #8
mov r5, r5, lsr #24
orr r5, r5, r6, lsl #8
@@ -236,22 +273,20 @@ Lsrc3_aligned: mov r4, r4, lsr #24
mov r4, r6, lsr #24
tst ip, #4
beq 4f
-3: ldr r5, [r0], #4
+3: load1l r5
orr r4, r4, r5, lsl #8
str r4, [r1], #4
adcs r3, r3, r4
mov r4, r5, lsr #24
4: ands r2, r2, #3
adceq r0, r3, #0
- LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc})
+ load_regs eqea
tst r2, #2
- beq Lexit_r4
+ beq .exit
adcs r3, r3, r4, lsl #16
strb r4, [r1], #1
- ldr r4, [r0], #4
+ load1l r4
strb r4, [r1], #1
adcs r3, r3, r4, lsl #24
mov r4, r4, lsr #8
- b Lexit_r4
-
-
+ b .exit
diff --git a/arch/arm/lib/csumpartialcopyuser.S b/arch/arm/lib/csumpartialcopyuser.S
index f698c0d26..cde500440 100644
--- a/arch/arm/lib/csumpartialcopyuser.S
+++ b/arch/arm/lib/csumpartialcopyuser.S
@@ -153,9 +153,9 @@ ENTRY(csum_partial_copy_from_user)
save_regs
sub fp, ip, #4
cmp r2, #4
- blt .too_small_user
+ blt .too_small
tst r1, #2 @ Test destination alignment
- beq .dst_aligned_user
+ beq .dst_aligned
load2b ip, r8
subs r2, r2, #2 @ We do not know if SRC is aligned...
orr ip, ip, r8, lsl #8
@@ -164,9 +164,8 @@ ENTRY(csum_partial_copy_from_user)
strb ip, [r1], #1
mov ip, ip, lsr #8
strb ip, [r1], #1 @ Destination now aligned
-.dst_aligned_user:
- tst r0, #3
- bne .src_not_aligned_user
+.dst_aligned: tst r0, #3
+ bne .src_not_aligned
adds r3, r3, #0
bics ip, r2, #15 @ Routine for src & dst aligned
beq 2f
@@ -210,18 +209,17 @@ ENTRY(csum_partial_copy_from_user)
adcs r0, r3, #0
load_regs ea
-.too_small_user:
- teq r2, #0
+.too_small: teq r2, #0
load_regs eqea
cmp r2, #2
- blt .too_small_user1
+ blt .too_small1
load2b ip, r8
orr ip, ip, r8, lsl #8
adds r3, r3, ip
strb ip, [r1], #1
strb r8, [r1], #1
tst r2, #1
-.too_small_user1: @ C = 0
+.too_small1: @ C = 0
beq .csum_exit
load1b ip
strb ip, [r1], #1
@@ -229,15 +227,15 @@ ENTRY(csum_partial_copy_from_user)
.csum_exit: adc r0, r3, #0
load_regs ea
-.src_not_aligned_user:
+.src_not_aligned:
cmp r2, #4
- blt .too_small_user
+ blt .too_small
and ip, r0, #3
bic r0, r0, #3
load1l r4
cmp ip, #2
- beq .src2_aligned_user
- bhi .src3_aligned_user
+ beq .src2_aligned
+ bhi .src3_aligned
mov r4, r4, lsr #8
adds r3, r3, #0
bics ip, r2, #15
@@ -290,8 +288,7 @@ ENTRY(csum_partial_copy_from_user)
mov r4, r4, lsr #8
b .exit
-.src2_aligned_user:
- mov r4, r4, lsr #16
+.src2_aligned: mov r4, r4, lsr #16
adds r3, r3, #0
bics ip, r2, #15
beq 2f
@@ -346,8 +343,7 @@ ENTRY(csum_partial_copy_from_user)
load1b r4
b .exit
-.src3_aligned_user:
- mov r4, r4, lsr #24
+.src3_aligned: mov r4, r4, lsr #24
adds r3, r3, #0
bics ip, r2, #15
beq 2f
diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c
index 76d1a5c74..310107678 100644
--- a/arch/arm/mm/consistent.c
+++ b/arch/arm/mm/consistent.c
@@ -29,20 +29,29 @@ void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle)
if (in_interrupt())
BUG();
+ size = PAGE_ALIGN(size);
order = get_order(size);
page = __get_free_pages(gfp, order);
if (!page)
goto no_page;
- memset((void *)page, 0, PAGE_SIZE << order);
- clean_cache_area(page, PAGE_SIZE << order);
+ memset((void *)page, 0, size);
+ clean_cache_area(page, size);
*dma_handle = virt_to_bus((void *)page);
- ret = __ioremap(virt_to_phys((void *)page), PAGE_SIZE << order, 0);
- if (ret)
+ ret = __ioremap(virt_to_phys((void *)page), size, 0);
+ if (ret) {
+ /* free wasted pages */
+ unsigned long end = page + (PAGE_SIZE << order);
+ page += size;
+ while (page < end) {
+ free_page(page);
+ page += PAGE_SIZE;
+ }
return ret;
+ }
free_pages(page, order);
no_page:
@@ -81,18 +90,18 @@ void consistent_free(void *vaddr)
/*
* make an area consistent.
*/
-void consistent_sync(void *vaddr, size_t size, int rw)
+void consistent_sync(void *vaddr, size_t size, int direction)
{
- switch (rw) {
- case 0:
+ switch (direction) {
+ case PCI_DMA_NONE:
BUG();
- case 1: /* invalidate only */
+ case PCI_DMA_FROMDEVICE: /* invalidate only */
dma_cache_inv(vaddr, size);
break;
- case 2: /* writeback only */
+ case PCI_DMA_TODEVICE: /* writeback only */
dma_cache_wback(vaddr, size);
break;
- case 3: /* writeback and invalidate */
+ case PCI_DMA_BIDIRECTIONAL: /* writeback and invalidate */
dma_cache_wback_inv(vaddr, size);
break;
}
diff --git a/arch/arm/mm/fault-common.c b/arch/arm/mm/fault-common.c
index c34c37203..14cf5a925 100644
--- a/arch/arm/mm/fault-common.c
+++ b/arch/arm/mm/fault-common.c
@@ -123,7 +123,7 @@ good_area:
* make sure we exit gracefully rather than endlessly redo
* the fault.
*/
- if (!handle_mm_fault(tsk, vma, addr & PAGE_MASK, DO_COW(mode)))
+ if (!handle_mm_fault(mm, vma, addr & PAGE_MASK, DO_COW(mode)))
goto do_sigbus;
up(&mm->mmap_sem);
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index e7b8c8bb9..61feb6a55 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -1,9 +1,8 @@
/*
* linux/arch/arm/mm/init.c
*
- * Copyright (C) 1995-1999 Russell King
+ * Copyright (C) 1995-2000 Russell King
*/
-
#include <linux/config.h>
#include <linux/signal.h>
#include <linux/sched.h>
@@ -32,9 +31,22 @@
#include "map.h"
+#ifdef CONFIG_CPU_32
+#define TABLE_OFFSET (PTRS_PER_PTE)
+#else
+#define TABLE_OFFSET 0
+#endif
+#define TABLE_SIZE ((TABLE_OFFSET + PTRS_PER_PTE) * sizeof(void *))
+
static unsigned long totalram_pages;
-struct meminfo meminfo;
pgd_t swapper_pg_dir[PTRS_PER_PGD];
+extern int _stext, _text, _etext, _edata, _end;
+
+/*
+ * The sole use of this is to pass memory configuration
+ * data from paging_init to mem_init.
+ */
+static struct meminfo __initdata meminfo;
/*
* empty_bad_page is the page that is used for page faults when
@@ -119,33 +131,36 @@ int do_check_pgt_cache(int low, int high)
void show_mem(void)
{
int free = 0, total = 0, reserved = 0;
- int shared = 0, cached = 0;
- struct page *page, *end;
+ int shared = 0, cached = 0, node;
printk("Mem-info:\n");
show_free_areas();
printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
- page = mem_map;
- end = mem_map + max_mapnr;
+ for (node = 0; node < numnodes; node++) {
+ struct page *page, *end;
- do {
- if (PageSkip(page)) {
- page = page->next_hash;
- if (page == NULL)
- break;
- }
- total++;
- if (PageReserved(page))
- reserved++;
- else if (PageSwapCache(page))
- cached++;
- else if (!page_count(page))
- free++;
- else
- shared += atomic_read(&page->count) - 1;
- page++;
- } while (page < end);
+ page = NODE_MEM_MAP(node);
+ end = page + NODE_DATA(node)->node_size;
+
+ do {
+ if (PageSkip(page)) {
+ page = page->next_hash;
+ if (page == NULL)
+ break;
+ }
+ total++;
+ if (PageReserved(page))
+ reserved++;
+ else if (PageSwapCache(page))
+ cached++;
+ else if (!page_count(page))
+ free++;
+ else
+ shared += atomic_read(&page->count) - 1;
+ page++;
+ } while (page < end);
+ }
printk("%d pages of RAM\n", total);
printk("%d free pages\n", free);
@@ -158,24 +173,173 @@ void show_mem(void)
show_buffers();
}
+#define O_PFN_DOWN(x) ((x) >> PAGE_SHIFT)
+#define V_PFN_DOWN(x) O_PFN_DOWN(__pa(x))
+
+#define O_PFN_UP(x) (PAGE_ALIGN(x) >> PAGE_SHIFT)
+#define V_PFN_UP(x) O_PFN_UP(__pa(x))
+
+#define PFN_SIZE(x) ((x) >> PAGE_SHIFT)
+#define PFN_RANGE(s,e) PFN_SIZE(PAGE_ALIGN((unsigned long)(e)) - \
+ (((unsigned long)(s)) & PAGE_MASK))
+
+static unsigned int __init
+find_bootmap_pfn(struct meminfo *mi, unsigned int bootmap_pages)
+{
+ unsigned int start_pfn, bank, bootmap_pfn;
+
+ start_pfn = V_PFN_UP(&_end);
+ bootmap_pfn = 0;
+
+ /*
+ * FIXME: We really want to avoid allocating the bootmap
+ * over the top of the initrd.
+ */
+#ifdef CONFIG_BLK_DEV_INITRD
+ if (initrd_start) {
+ if (__pa(initrd_end) > mi->end) {
+ printk ("initrd extends beyond end of memory "
+ "(0x%08lx > 0x%08lx) - disabling initrd\n",
+ __pa(initrd_end), mi->end);
+ initrd_start = 0;
+ initrd_end = 0;
+ }
+ }
+#endif
+
+ for (bank = 0; bank < mi->nr_banks; bank ++) {
+ unsigned int start, end;
+
+ if (mi->bank[bank].size == 0)
+ continue;
+
+ start = O_PFN_UP(mi->bank[bank].start);
+ end = O_PFN_DOWN(mi->bank[bank].size +
+ mi->bank[bank].start);
+
+ if (end < start_pfn)
+ continue;
+
+ if (start < start_pfn)
+ start = start_pfn;
+
+ if (end <= start)
+ continue;
+
+ if (end - start >= bootmap_pages) {
+ bootmap_pfn = start;
+ break;
+ }
+ }
+
+ if (bootmap_pfn == 0)
+ BUG();
+
+ return bootmap_pfn;
+}
+
+/*
+ * Initialise one node of the bootmem allocator. For now, we
+ * only initialise node 0. Notice that we have a bootmem
+ * bitmap per node.
+ */
+static void __init setup_bootmem_node(int node, struct meminfo *mi)
+{
+ unsigned int end_pfn, start_pfn, bootmap_pages, bootmap_pfn;
+ unsigned int i;
+
+ if (node != 0) /* only initialise node 0 for now */
+ return;
+
+ start_pfn = O_PFN_UP(PHYS_OFFSET);
+ end_pfn = O_PFN_DOWN(mi->end);
+ bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn);
+ bootmap_pfn = find_bootmap_pfn(mi, bootmap_pages);
+
+ /*
+ * Initialise the boot-time allocator
+ */
+ init_bootmem_node(node, bootmap_pfn, start_pfn, end_pfn);
+
+ /*
+ * Register all available RAM with the bootmem allocator.
+ */
+ for (i = 0; i < mi->nr_banks; i++)
+ if (mi->bank[i].size)
+ free_bootmem_node(node, mi->bank[i].start,
+ PFN_SIZE(mi->bank[i].size) << PAGE_SHIFT);
+
+ reserve_bootmem_node(node, bootmap_pfn << PAGE_SHIFT,
+ bootmap_pages << PAGE_SHIFT);
+}
+
+/*
+ * Initialise the bootmem allocator.
+ */
+void __init bootmem_init(struct meminfo *mi)
+{
+ unsigned int i, node;
+
+ /*
+ * Calculate the physical address of the top of memory.
+ * Note that there are no guarantees assumed about the
+ * ordering of the bank information.
+ */
+ mi->end = 0;
+ for (i = 0; i < mi->nr_banks; i++) {
+ unsigned long end;
+
+ if (mi->bank[i].size != 0) {
+ end = mi->bank[i].start + mi->bank[i].size;
+ if (mi->end < end)
+ mi->end = end;
+ }
+ }
+
+ max_low_pfn = O_PFN_DOWN(mi->end - PHYS_OFFSET);
+
+ /*
+ * Setup each node
+ */
+ for (node = 0; node < numnodes; node++)
+ setup_bootmem_node(node, mi);
+
+ /*
+ * Register the kernel text and data with bootmem.
+ * Note that this can only be in node 0.
+ */
+ reserve_bootmem_node(0, V_PFN_DOWN(&_stext) << PAGE_SHIFT,
+ PFN_RANGE(&_stext, &_end) << PAGE_SHIFT);
+
+#ifdef CONFIG_CPU_32
+ /*
+ * Reserve the page tables. These are already in use,
+ * and can only be in node 0.
+ */
+ reserve_bootmem_node(0, V_PFN_DOWN(swapper_pg_dir) << PAGE_SHIFT,
+ PFN_SIZE(PTRS_PER_PGD * sizeof(void *)) << PAGE_SHIFT);
+#endif
+#ifdef CONFIG_BLK_DEV_INITRD
+ /*
+ * This may be in any bank. Currently, we assume that
+ * it is in bank 0.
+ */
+ if (initrd_start)
+ reserve_bootmem_node(0, V_PFN_DOWN(initrd_start) << PAGE_SHIFT,
+ PFN_RANGE(initrd_start, initrd_end) << PAGE_SHIFT);
+#endif
+}
+
/*
* paging_init() sets up the page tables...
*/
void __init paging_init(struct meminfo *mi)
{
void *zero_page, *bad_page, *bad_table;
- unsigned long zone_size[MAX_NR_ZONES];
- int i;
+ int node;
memcpy(&meminfo, mi, sizeof(meminfo));
-#ifdef CONFIG_CPU_32
-#define TABLE_OFFSET (PTRS_PER_PTE)
-#else
-#define TABLE_OFFSET 0
-#endif
-#define TABLE_SIZE ((TABLE_OFFSET + PTRS_PER_PTE) * sizeof(void *))
-
/*
* allocate what we need for the bad pages
*/
@@ -186,31 +350,42 @@ void __init paging_init(struct meminfo *mi)
/*
* initialise the page tables
*/
- pagetable_init();
+ pagetable_init(mi);
flush_tlb_all();
/*
- * Initialise the zones and mem_map
+ * initialise the zones within each node
*/
- for (i = 0; i < MAX_NR_ZONES; i++)
- zone_size[i] = 0;
+ for (node = 0; node < numnodes; node++) {
+ unsigned long zone_size[MAX_NR_ZONES];
+ unsigned long zhole_size[MAX_NR_ZONES];
+ struct bootmem_data *bdata;
+ pg_data_t *pgdat;
+ int i;
- /*
- * Calculate the size of the zones. On ARM, we don't have
- * any problems with DMA or highmem, so all memory is
- * allocated to the DMA zone.
- */
- for (i = 0; i < mi->nr_banks; i++) {
- if (mi->bank[i].size) {
- unsigned int end;
-
- end = (mi->bank[i].start - PHYS_OFFSET +
- mi->bank[i].size) >> PAGE_SHIFT;
- if (zone_size[0] < end)
- zone_size[0] = end;
+ /*
+ * Initialise the zone size information.
+ */
+ for (i = 0; i < MAX_NR_ZONES; i++) {
+ zone_size[i] = 0;
+ zhole_size[i] = 0;
}
+
+ pgdat = NODE_DATA(node);
+ bdata = pgdat->bdata;
+
+ /*
+ * The size of this node has already been determined.
+ * If we need to do anything fancy with the allocation
+ * of this memory to the zones, now is the time to do
+ * it. For now, we don't touch zhole_size.
+ */
+ zone_size[0] = bdata->node_low_pfn -
+ (bdata->node_boot_start >> PAGE_SHIFT);
+
+ free_area_init_node(node, pgdat, zone_size,
+ bdata->node_boot_start, zhole_size);
}
- free_area_init(zone_size);
/*
* finish off the bad pages once
@@ -256,32 +431,33 @@ static inline void free_unused_mem_map(void)
*/
void __init mem_init(void)
{
- extern char __init_begin, __init_end, _text, _etext, _end;
+ extern char __init_begin, __init_end;
unsigned int codepages, datapages, initpages;
- int i;
+ int i, node;
codepages = &_etext - &_text;
datapages = &_end - &_etext;
initpages = &__init_end - &__init_begin;
- max_mapnr = max_low_pfn;
- high_memory = (void *)__va(PHYS_OFFSET + max_low_pfn * PAGE_SIZE);
+ high_memory = (void *)__va(meminfo.end);
+ max_mapnr = MAP_NR(high_memory);
/*
* We may have non-contiguous memory. Setup the PageSkip stuff,
* and mark the areas of mem_map which can be freed
*/
if (meminfo.nr_banks != 1)
- create_memmap_holes();
+ create_memmap_holes(&meminfo);
/* this will put all unused low memory onto the freelists */
- totalram_pages += free_all_bootmem();
+ for (node = 0; node < numnodes; node++)
+ totalram_pages += free_all_bootmem_node(node);
/*
* Since our memory may not be contiguous, calculate the
* real number of pages we have in this system
*/
- printk("Memory:");
+ printk(KERN_INFO "Memory:");
num_physpages = 0;
for (i = 0; i < meminfo.nr_banks; i++) {
@@ -290,7 +466,8 @@ void __init mem_init(void)
}
printk(" = %luMB total\n", num_physpages >> (20 - PAGE_SHIFT));
- printk("Memory: %luKB available (%dK code, %dK data, %dK init)\n",
+ printk(KERN_NOTICE "Memory: %luKB available (%dK code, "
+ "%dK data, %dK init)\n",
(unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
codepages >> 10, datapages >> 10, initpages >> 10);
diff --git a/arch/arm/mm/map.h b/arch/arm/mm/map.h
index b596c6479..1d071748d 100644
--- a/arch/arm/mm/map.h
+++ b/arch/arm/mm/map.h
@@ -19,7 +19,7 @@ struct map_desc {
extern struct map_desc io_desc[];
extern unsigned int io_desc_size;
-extern void zonesize_init(unsigned int *);
-extern void create_memmap_holes(void);
-extern void pagetable_init(void);
+struct meminfo;
+extern void create_memmap_holes(struct meminfo *);
+extern void pagetable_init(struct meminfo *);
diff --git a/arch/arm/mm/mm-armo.c b/arch/arm/mm/mm-armo.c
index f4bf7cad5..dc1647a2d 100644
--- a/arch/arm/mm/mm-armo.c
+++ b/arch/arm/mm/mm-armo.c
@@ -147,7 +147,7 @@ void setup_mm_for_reboot(char mode)
* some more work to get it to fit into our separate processor and
* architecture structure.
*/
-void __init pagetable_init(void)
+void __init pagetable_init(struct meminfo *mi)
{
pte_t *pte;
int i;
@@ -165,6 +165,6 @@ void __init pagetable_init(void)
/*
* We never have holes in the memmap
*/
-void __init create_memmap_holes(void)
+void __init create_memmap_holes(struct meminfo *mi)
{
}
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
index 5d46369eb..f58bc66f5 100644
--- a/arch/arm/mm/mm-armv.c
+++ b/arch/arm/mm/mm-armv.c
@@ -310,7 +310,7 @@ void setup_mm_for_reboot(char mode)
}
}
-void __init pagetable_init(void)
+void __init pagetable_init(struct meminfo *mi)
{
struct map_desc *init_maps, *p, *q;
unsigned long address = 0;
@@ -335,13 +335,13 @@ void __init pagetable_init(void)
p ++;
- for (i = 0; i < meminfo.nr_banks; i++) {
- if (meminfo.bank[i].size == 0)
+ for (i = 0; i < mi->nr_banks; i++) {
+ if (mi->bank[i].size == 0)
continue;
- p->physical = meminfo.bank[i].start;
+ p->physical = mi->bank[i].start;
p->virtual = __phys_to_virt(p->physical);
- p->length = meminfo.bank[i].size;
+ p->length = mi->bank[i].size;
p->domain = DOMAIN_KERNEL;
p->prot_read = 0;
p->prot_write = 1;
@@ -414,7 +414,7 @@ void __init pagetable_init(void)
* The mem_map array can get very big. Mark the end of the valid mem_map
* banks with PG_skip, and setup the address validity bitmap.
*/
-void __init create_memmap_holes(void)
+void __init create_memmap_holes(struct meminfo *mi)
{
unsigned int start_pfn, end_pfn = -1;
struct page *pg = NULL;
@@ -423,11 +423,11 @@ void __init create_memmap_holes(void)
#define PFN(x) (((x) - PHYS_OFFSET) >> PAGE_SHIFT)
#define free_bootmem(s,sz) free_bootmem(((s)<<PAGE_SHIFT)+PHYS_OFFSET, (sz)<<PAGE_SHIFT)
- for (i = 0; i < meminfo.nr_banks; i++) {
- if (meminfo.bank[i].size == 0)
+ for (i = 0; i < mi->nr_banks; i++) {
+ if (mi->bank[i].size == 0)
continue;
- start_pfn = PFN(meminfo.bank[i].start);
+ start_pfn = PFN(mi->bank[i].start);
/*
* subtle here - if we have a full bank, then
@@ -447,9 +447,9 @@ void __init create_memmap_holes(void)
pg = NULL;
}
- end_pfn = PFN(meminfo.bank[i].start + meminfo.bank[i].size);
+ end_pfn = PFN(mi->bank[i].start + mi->bank[i].size);
- if (end_pfn != PFN(meminfo.end))
+ if (end_pfn != PFN(mi->end))
pg = mem_map + end_pfn;
}
diff --git a/arch/arm/mm/mm-ebsa110.c b/arch/arm/mm/mm-ebsa110.c
index a1172b1f1..f16c93793 100644
--- a/arch/arm/mm/mm-ebsa110.c
+++ b/arch/arm/mm/mm-ebsa110.c
@@ -8,6 +8,7 @@
#include <linux/mm.h>
#include <linux/init.h>
+#include <asm/hardware.h>
#include <asm/pgtable.h>
#include <asm/page.h>
@@ -15,7 +16,7 @@
#define SIZE(x) (sizeof(x) / sizeof(x[0]))
-const struct map_desc io_desc[] __initdata = {
+struct map_desc io_desc[] __initdata = {
{ IO_BASE - PGDIR_SIZE, 0xc0000000, PGDIR_SIZE, DOMAIN_IO, 0, 1, 0, 0 },
{ IO_BASE , IO_START , IO_SIZE , DOMAIN_IO, 0, 1, 0, 0 }
};
diff --git a/arch/arm/mm/mm-rpc.c b/arch/arm/mm/mm-rpc.c
index 0490cbdd0..494a61988 100644
--- a/arch/arm/mm/mm-rpc.c
+++ b/arch/arm/mm/mm-rpc.c
@@ -18,7 +18,7 @@
struct map_desc io_desc[] __initdata = {
/* VRAM */
- { SCREEN2_BASE, SCREEN_START, 2*1048576, DOMAIN_IO, 0, 1, 0, 0 },
+ { SCREEN_BASE, SCREEN_START, 2*1048576, DOMAIN_IO, 0, 1, 0, 0 },
/* IO space */
{ IO_BASE, IO_START, IO_SIZE , DOMAIN_IO, 0, 1, 0, 0 },
/* EASI space */
diff --git a/arch/arm/mm/mm-sa1100.c b/arch/arm/mm/mm-sa1100.c
index 1cb1a3b58..5674dbe37 100644
--- a/arch/arm/mm/mm-sa1100.c
+++ b/arch/arm/mm/mm-sa1100.c
@@ -9,6 +9,10 @@
* 1999/12/04 Nicolas Pitre <nico@cam.org>
* Converted memory definition for struct meminfo initialisations.
* Memory is listed physically now.
+ *
+ * 2000/04/07 Nicolas Pitre <nico@cam.org>
+ * Reworked for real-time selection of memory definitions
+ *
*/
#include <linux/config.h>
@@ -23,79 +27,109 @@
#define SIZE(x) (sizeof(x) / sizeof(x[0]))
-/*
- * These are the RAM memory mappings for SA1100 implementations.
- * Note that LART is a special case - it doesn't use physical
- * address line A23 on the DRAM, so we effectively have 4 * 8MB
- * in two banks.
- */
-struct mem_desc {
- unsigned long phys_start;
- unsigned long length;
-} mem_desc[] __initdata = {
-#if defined(CONFIG_SA1100_BRUTUS)
- { 0xc0000000, 0x00400000 }, /* 4MB */
- { 0xc8000000, 0x00400000 }, /* 4MB */
- { 0xd0000000, 0x00400000 }, /* 4MB */
- { 0xd8000000, 0x00400000 } /* 4MB */
-#elif defined(CONFIG_SA1100_EMPEG)
- { 0xc0000000, 0x00400000 }, /* 4MB */
- { 0xc8000000, 0x00400000 } /* 4MB */
-#elif defined(CONFIG_SA1100_LART)
- { 0xc0000000, 0x00800000 }, /* 8MB */
- { 0xc1000000, 0x00800000 }, /* 8MB */
- { 0xc8000000, 0x00800000 }, /* 8MB */
- { 0xc9000000, 0x00800000 } /* 8MB */
-#elif defined(CONFIG_SA1100_VICTOR)
- { 0xc0000000, 0x00400000 } /* 4MB */
-#elif defined(CONFIG_SA1100_THINCLIENT)
- { 0xc0000000, 0x01000000 } /* 16MB */
-#elif defined(CONFIG_SA1100_TIFON)
- { 0xc0000000, 0x01000000 }, /* 16MB */
- { 0xc8000000, 0x01000000 } /* 16MB */
-#else
-#error missing memory configuration
+#define SA1100_STD_IO_MAPPING \
+ /* virtual physical length domain r w c b */ \
+ { 0xe0000000, 0x20000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCMCIA0 IO */ \
+ { 0xe4000000, 0x30000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCMCIA1 IO */ \
+ { 0xe8000000, 0x28000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCMCIA0 attr */ \
+ { 0xec000000, 0x38000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCMCIA1 attr */ \
+ { 0xf0000000, 0x2c000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCMCIA0 mem */ \
+ { 0xf4000000, 0x3c000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCMCIA1 mem */ \
+ { 0xf8000000, 0x80000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCM */ \
+ { 0xfa000000, 0x90000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* SCM */ \
+ { 0xfc000000, 0xa0000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* MER */ \
+ { 0xfe000000, 0xb0000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 } /* LCD + DMA */
+
+
+static struct map_desc assabet_io_desc[] __initdata = {
+#ifdef CONFIG_SA1100_ASSABET
+ { 0xd0000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */
+ { 0xdc000000, 0x12000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* Board Control Register */
+ SA1100_STD_IO_MAPPING
#endif
};
-unsigned int __initdata mem_desc_size = SIZE(mem_desc);
+static struct map_desc bitsy_io_desc[] __initdata = {
+#ifdef CONFIG_SA1100_BITSY
+ { 0xd0000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */
+ SA1100_STD_IO_MAPPING
+#endif
+};
+static struct map_desc empeg_io_desc[] __initdata = {
+#ifdef CONFIG_SA1100_EMPEG
+ { EMPEG_FLASHBASE, 0x00000000, 0x00200000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash */
+ SA1100_STD_IO_MAPPING
+#endif
+};
-struct map_desc io_desc[] __initdata = {
- /* virtual physical length domain r w c b */
-#if defined(CONFIG_SA1100_VICTOR)
- { 0xd0000000, 0x00000000, 0x00200000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash */
-#elif defined(CONFIG_SA1100_EMPEG)
- { EMPEG_FLASHBASE, 0x00000000, 0x00200000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash */
-#elif defined(CONFIG_SA1100_THINCLIENT)
+static struct map_desc thinclient_io_desc[] __initdata = {
+#ifdef CONFIG_SA1100_THINCLIENT
#if 1
- /* ThinClient: only one of those... */
-// { 0xd0000000, 0x00000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 when JP1 2-4 */
- { 0xd0000000, 0x08000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 when JP1 3-4 */
+ /* ThinClient: only one of those... */
+// { 0xd0000000, 0x00000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 when JP1 2-4 */
+ { 0xd0000000, 0x08000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 when JP1 3-4 */
#else
- /* GraphicsClient: */
- { 0xd0000000, 0x08000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 */
- { 0xd0800000, 0x18000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 3 */
+ /* GraphicsClient: */
+ { 0xd0000000, 0x08000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 */
+ { 0xd0800000, 0x18000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 3 */
+#endif
+ { 0xdc000000, 0x10000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* CPLD */
+ SA1100_STD_IO_MAPPING
#endif
-#elif defined(CONFIG_SA1100_TIFON)
- { 0xd0000000, 0x00000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 */
- { 0xd0800000, 0x08000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 2 */
+};
+
+static struct map_desc tifon_io_desc[] __initdata = {
+#ifdef CONFIG_SA1100_TIFON
+ { 0xd0000000, 0x00000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 */
+ { 0xd0800000, 0x08000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 2 */
+ SA1100_STD_IO_MAPPING
#endif
-#if defined( CONFIG_SA1101 )
- { 0xdc000000, SA1101_BASE, 0x00400000, DOMAIN_IO, 1, 1, 0, 0 }, /* SA1101 */
-#elif defined( CONFIG_SA1100_THINCLIENT )
- { 0xdc000000, 0x10000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* CPLD */
+};
+
+static struct map_desc victor_io_desc[] __initdata = {
+#ifdef CONFIG_SA1100_VICTOR
+ { 0xd0000000, 0x00000000, 0x00200000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash */
+ SA1100_STD_IO_MAPPING
#endif
- { 0xe0000000, 0x20000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCMCIA0 IO */
- { 0xe4000000, 0x30000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCMCIA1 IO */
- { 0xe8000000, 0x28000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCMCIA0 attr */
- { 0xec000000, 0x38000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCMCIA1 attr */
- { 0xf0000000, 0x2c000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCMCIA0 mem */
- { 0xf4000000, 0x3c000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCMCIA1 mem */
- { 0xf8000000, 0x80000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCM */
- { 0xfa000000, 0x90000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* SCM */
- { 0xfc000000, 0xa0000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* MER */
- { 0xfe000000, 0xb0000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 } /* LCD + DMA */
};
-unsigned int __initdata io_desc_size = SIZE(io_desc);
+
+static struct map_desc default_io_desc[] __initdata = {
+ SA1100_STD_IO_MAPPING
+};
+
+
+/*
+ * Here it would be wiser to simply assign a pointer to the appropriate
+ * list, but io_desc is already declared as an array in "map.h".
+ */
+struct map_desc io_desc[20] __initdata = { { 0, }, };
+unsigned int io_desc_size;
+
+void __init select_sa1100_io_desc(void)
+{
+ if( machine_is_assabet() ) {
+ memcpy( io_desc, assabet_io_desc, sizeof(assabet_io_desc) );
+ io_desc_size = SIZE(assabet_io_desc);
+ } else if( machine_is_bitsy() ) {
+ memcpy( io_desc, bitsy_io_desc, sizeof(bitsy_io_desc) );
+ io_desc_size = SIZE(bitsy_io_desc);
+ } else if( machine_is_empeg() ) {
+ memcpy( io_desc, empeg_io_desc, sizeof(empeg_io_desc) );
+ io_desc_size = SIZE(empeg_io_desc);
+ } else if( machine_is_thinclient() ) {
+ memcpy( io_desc, thinclient_io_desc, sizeof(thinclient_io_desc) );
+ io_desc_size = SIZE(thinclient_io_desc);
+ } else if( machine_is_tifon() ) {
+ memcpy( io_desc, tifon_io_desc, sizeof(tifon_io_desc) );
+ io_desc_size = SIZE(tifon_io_desc);
+ } else if( machine_is_victor() ) {
+ memcpy( io_desc, victor_io_desc, sizeof(victor_io_desc) );
+ io_desc_size = SIZE(victor_io_desc);
+ } else {
+ memcpy( io_desc, default_io_desc, sizeof(default_io_desc) );
+ io_desc_size = SIZE(default_io_desc);
+ }
+}
+
diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S
index 13c1f2773..9ae5fb9d6 100644
--- a/arch/arm/mm/proc-sa110.S
+++ b/arch/arm/mm/proc-sa110.S
@@ -4,7 +4,9 @@
* (C) 1997-2000 Russell King
*
* These are the low level assembler for performing cache and TLB
- * functions on the StrongARM-110 and StrongARM-1100
+ * functions on the StrongARM-110, StrongARM-1100 and StrongARM-1110.
+ *
+ * Note that SA1100 and SA1110 share everything but their name and CPU ID.
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
@@ -420,13 +422,12 @@ ENTRY(cpu_sa1100_proc_init)
mov pc, lr
ENTRY(cpu_sa110_proc_fin)
-ENTRY(cpu_sa1100_proc_fin)
stmfd sp!, {r1, lr}
mrs r0, cpsr
orr r0, r0, #F_BIT | I_BIT
msr cpsr, r0
bl cpu_sa110_flush_cache_all @ clean caches
- mov r0, #0
+1: mov r0, #0
mcr p15, 0, r0, c15, c2, 2 @ Disable clock switching
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x1000 @ ...i............
@@ -434,8 +435,17 @@ ENTRY(cpu_sa1100_proc_fin)
mcr p15, 0, r0, c1, c0, 0 @ disable caches
ldmfd sp!, {r1, pc}
+ENTRY(cpu_sa1100_proc_fin)
+ stmfd sp!, {r1, lr}
+ mrs r0, cpsr
+ orr r0, r0, #F_BIT | I_BIT
+ msr cpsr, r0
+ bl cpu_sa1100_flush_cache_all @ clean caches
+ b 1b
+
+
.align 5
-idle: mcr p15, 0, r0, c15, c8, 2 @ Wait for interrupt
+idle: mcr p15, 0, r0, c15, c8, 2 @ Wait for interrupt, cache aligned
mov r0, r0 @ safety
mov pc, lr
/*
@@ -483,16 +493,14 @@ ENTRY(cpu_sa1100_reset)
bic ip, ip, #0x1100 @ ...i...s........
mcr p15, 0, ip, c1, c0, 0 @ ctrl register
mov pc, r0
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
+
cpu_manu_name: .asciz "Intel"
-ENTRY(cpu_sa110_name)
- .asciz "StrongARM-110"
-ENTRY(cpu_sa1100_name)
+cpu_sa110_name: .asciz "StrongARM-110"
+cpu_sa1100_name:
.asciz "StrongARM-1100"
+cpu_sa1110_name:
+ .asciz "StrongARM-1110"
.align
.section ".text.init", #alloc, #execinstr
@@ -511,6 +519,13 @@ __sa110_setup: mov r0, #0
orr r0, r0, #0x1100 @ ...I...S........
mov pc, lr
+ .text
+
+/*
+ * Purpose : Function pointers used to access above functions - all calls
+ * come through these
+ */
+
.type sa110_processor_functions, #object
ENTRY(sa110_processor_functions)
.word cpu_sa110_data_abort
@@ -543,6 +558,9 @@ cpu_sa110_info:
.size cpu_sa110_info, . - cpu_sa110_info
+/*
+ * SA1100 and SA1110 share the same function calls
+ */
.type sa1100_processor_functions, #object
ENTRY(sa1100_processor_functions)
.word cpu_sa1100_data_abort
@@ -573,6 +591,12 @@ cpu_sa1100_info:
.long cpu_sa1100_name
.size cpu_sa1100_info, . - cpu_sa1100_info
+cpu_sa1110_info:
+ .long cpu_manu_name
+ .long cpu_sa1110_name
+ .size cpu_sa1110_info, . - cpu_sa1110_info
+
+
.type cpu_arch_name, #object
cpu_arch_name: .asciz "armv4"
.size cpu_arch_name, . - cpu_arch_name
@@ -610,4 +634,17 @@ __sa1100_proc_info:
.long sa1100_processor_functions
.size __sa1100_proc_info, . - __sa1100_proc_info
+ .type __sa1110_proc_info,#object
+__sa1110_proc_info:
+ .long 0x6901b110
+ .long 0xfffffff0
+ .long 0x00000c02
+ b __sa110_setup
+ .long cpu_arch_name
+ .long cpu_elf_name
+ .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT
+ .long cpu_sa1110_info
+ .long sa1100_processor_functions
+ .size __sa1110_proc_info, . - __sa1110_proc_info
+
diff --git a/arch/i386/config.in b/arch/i386/config.in
index 664b77800..589c34730 100644
--- a/arch/i386/config.in
+++ b/arch/i386/config.in
@@ -20,48 +20,54 @@ comment 'Processor type and features'
choice 'Processor family' \
"386 CONFIG_M386 \
486/Cx486 CONFIG_M486 \
- 586/K5/5x86/6x86 CONFIG_M586 \
+ 586/K5/5x86/6x86/6x86MX CONFIG_M586 \
Pentium/TSC CONFIG_M586TSC \
- PPro/6x86MX CONFIG_M686 \
+ PPro CONFIG_M686 \
K6/II/III CONFIG_MK6 \
Athlon CONFIG_MK7" PPro
#
# Define implied options from the CPU selection here
#
-if [ "$CONFIG_M386" != "y" ]; then
+if [ "$CONFIG_M386" = "y" ]; then
+ define_int CONFIG_X86_L1_CACHE_BYTES 16
+else
define_bool CONFIG_X86_WP_WORKS_OK y
define_bool CONFIG_X86_INVLPG y
define_bool CONFIG_X86_CMPXCHG y
define_bool CONFIG_X86_BSWAP y
define_bool CONFIG_X86_POPAD_OK y
fi
-if [ "$CONFIG_M386" = "y" -o "$CONFIG_M486" = "y" ]; then
- define_int CONFIG_X86_L1_CACHE_BYTES 16
-else
- define_int CONFIG_X86_L1_CACHE_BYTES 32
+if [ "$CONFIG_M486" = "y" ]; then
+ define_int CONFIG_X86_L1_CACHE_BYTES 16
+ define_bool CONFIG_X86_USE_STRING_486 y
+ define_bool CONFIG_X86_ALIGNMENT_16 y
fi
-if [ "$CONFIG_M486" = "y" -o "$CONFIG_M586" = "y" ]; then
+if [ "$CONFIG_M586" = "y" ]; then
+ define_int CONFIG_X86_L1_CACHE_BYTES 32
define_bool CONFIG_X86_USE_STRING_486 y
define_bool CONFIG_X86_ALIGNMENT_16 y
fi
if [ "$CONFIG_M586TSC" = "y" ]; then
+ define_int CONFIG_X86_L1_CACHE_BYTES 32
define_bool CONFIG_X86_USE_STRING_486 y
define_bool CONFIG_X86_ALIGNMENT_16 y
define_bool CONFIG_X86_TSC y
fi
-if [ "$CONFIG_MK6" = "y" ]; then
- define_bool CONFIG_X86_ALIGNMENT_16 y
- define_bool CONFIG_X86_TSC y
- define_bool CONFIG_X86_USE_3DNOW y
- define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
-fi
if [ "$CONFIG_M686" = "y" ]; then
+ define_int CONFIG_X86_L1_CACHE_BYTES 32
define_bool CONFIG_X86_TSC y
define_bool CONFIG_X86_GOOD_APIC y
define_bool CONFIG_X86_PGE y
define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
fi
+if [ "$CONFIG_MK6" = "y" ]; then
+ define_int CONFIG_X86_L1_CACHE_BYTES 32
+ define_bool CONFIG_X86_ALIGNMENT_16 y
+ define_bool CONFIG_X86_TSC y
+ define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
+fi
if [ "$CONFIG_MK7" = "y" ]; then
+ define_int CONFIG_X86_L1_CACHE_BYTES 64
define_bool CONFIG_X86_TSC y
define_bool CONFIG_X86_GOOD_APIC y
define_bool CONFIG_X86_USE_3DNOW y
diff --git a/arch/i386/defconfig b/arch/i386/defconfig
index 80f68ec31..3a8d743f7 100644
--- a/arch/i386/defconfig
+++ b/arch/i386/defconfig
@@ -107,6 +107,7 @@ CONFIG_BLK_DEV_FD=y
#
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_LVM is not set
# CONFIG_BLK_DEV_MD is not set
# CONFIG_MD_LINEAR is not set
# CONFIG_MD_STRIPED is not set
@@ -189,8 +190,8 @@ CONFIG_IDEPCI_SHARE_IRQ=y
# CONFIG_IDEDMA_PCI_EXPERIMENTAL is not set
# CONFIG_IDEDMA_PCI_WIP is not set
# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
-# CONFIG_BLK_DEV_AEC6210 is not set
-# CONFIG_AEC6210_TUNING is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_AEC62XX_TUNING is not set
# CONFIG_BLK_DEV_ALI15X3 is not set
# CONFIG_WDC_ALI15X3 is not set
# CONFIG_BLK_DEV_AMD7409 is not set
@@ -214,6 +215,7 @@ CONFIG_IDEPCI_SHARE_IRQ=y
# CONFIG_BLK_DEV_SIS5513 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_VIA82CXXX_TUNING is not set
# CONFIG_IDE_CHIPSETS is not set
# CONFIG_IDEDMA_AUTO is not set
CONFIG_BLK_DEV_IDE_MODES=y
@@ -385,7 +387,10 @@ CONFIG_PCMCIA_PCNET=y
# CONFIG_PCMCIA_XIRC2PS is not set
# CONFIG_ARCNET_COM20020_CS is not set
# CONFIG_PCMCIA_IBMTR is not set
-# CONFIG_PCMCIA_3C575 is not set
+
+#
+# 3Com 3c575 moved to Ethernet 10/100 menu
+#
# CONFIG_PCMCIA_XIRTULIP is not set
CONFIG_NET_PCMCIA_RADIO=y
CONFIG_PCMCIA_RAYCS=y
diff --git a/arch/i386/kernel/acpi.c b/arch/i386/kernel/acpi.c
index aa09400fc..e63a45e66 100644
--- a/arch/i386/kernel/acpi.c
+++ b/arch/i386/kernel/acpi.c
@@ -583,6 +583,8 @@ static int __init acpi_find_tables(void)
dt = acpi_map_table(facp->dsdt);
if (acpi_init_table(&acpi_dsdt, dt, 1))
acpi_unmap_table(dt);
+
+ break;
}
else {
acpi_unmap_table(dt);
@@ -1127,6 +1129,7 @@ static int acpi_enter_sx(acpi_sstate_t state)
// finished sleeping, update system time
acpi_update_clock();
acpi_enter_dx(ACPI_D0);
+ acpi_sleep_state = ACPI_S0;
return 0;
}
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index a5f72548f..d4c35fdf0 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -4,7 +4,9 @@
* (c) 1999, 2000 Ingo Molnar <mingo@redhat.com>
*
* Fixes
- * Maciej W. Rozycki : Bits for genuine 82489DX timers
+ * Maciej W. Rozycki : Bits for genuine 82489DX APICs;
+ * thanks to Eric Gilmore for
+ * testing these extensively
*/
#include <linux/config.h>
@@ -44,32 +46,96 @@ int get_maxlvt(void)
return maxlvt;
}
-void disable_local_APIC (void)
+static void clear_local_APIC(void)
{
- unsigned long value;
- int maxlvt;
+ int maxlvt;
+ unsigned long v;
+
+ maxlvt = get_maxlvt();
/*
- * Disable APIC
+ * Careful: we have to set masks only first to deassert
+ * any level-triggered sources.
*/
- value = apic_read(APIC_SPIV);
- value &= ~(1<<8);
- apic_write(APIC_SPIV,value);
+ v = apic_read(APIC_LVTT);
+ apic_write_around(APIC_LVTT, v | APIC_LVT_MASKED);
+ v = apic_read(APIC_LVT0);
+ apic_write_around(APIC_LVT0, v | APIC_LVT_MASKED);
+ v = apic_read(APIC_LVT1);
+ apic_write_around(APIC_LVT1, v | APIC_LVT_MASKED);
+ if (maxlvt >= 3) {
+ v = apic_read(APIC_LVTERR);
+ apic_write_around(APIC_LVTERR, v | APIC_LVT_MASKED);
+ }
+ if (maxlvt >= 4) {
+ v = apic_read(APIC_LVTPC);
+ apic_write_around(APIC_LVTPC, v | APIC_LVT_MASKED);
+ }
/*
* Clean APIC state for other OSs:
*/
- value = apic_read(APIC_SPIV);
- value &= ~(1<<8);
- apic_write(APIC_SPIV,value);
- maxlvt = get_maxlvt();
- apic_write_around(APIC_LVTT, 0x00010000);
- apic_write_around(APIC_LVT0, 0x00010000);
- apic_write_around(APIC_LVT1, 0x00010000);
+ apic_write_around(APIC_LVTT, APIC_LVT_MASKED);
+ apic_write_around(APIC_LVT0, APIC_LVT_MASKED);
+ apic_write_around(APIC_LVT1, APIC_LVT_MASKED);
if (maxlvt >= 3)
- apic_write_around(APIC_LVTERR, 0x00010000);
+ apic_write_around(APIC_LVTERR, APIC_LVT_MASKED);
if (maxlvt >= 4)
- apic_write_around(APIC_LVTPC, 0x00010000);
+ apic_write_around(APIC_LVTPC, APIC_LVT_MASKED);
+}
+
+void __init connect_bsp_APIC(void)
+{
+ if (pic_mode) {
+ /*
+ * Do not trust the local APIC being empty at bootup.
+ */
+ clear_local_APIC();
+ /*
+ * PIC mode, enable symmetric IO mode in the IMCR,
+ * i.e. connect BSP's local APIC to INT and NMI lines.
+ */
+ printk("leaving PIC mode, enabling symmetric IO mode.\n");
+ outb(0x70, 0x22);
+ outb(0x01, 0x23);
+ }
+}
+
+void disconnect_bsp_APIC(void)
+{
+ if (pic_mode) {
+ /*
+ * Put the board back into PIC mode (has an effect
+ * only on certain older boards). Note that APIC
+ * interrupts, including IPIs, won't work beyond
+ * this point! The only exception are INIT IPIs.
+ */
+ printk("disabling symmetric IO mode, entering PIC mode.\n");
+ outb(0x70, 0x22);
+ outb(0x00, 0x23);
+ }
+}
+
+void disable_local_APIC(void)
+{
+ unsigned long value;
+
+ clear_local_APIC();
+
+ /*
+ * Disable APIC (implies clearing of registers
+ * for 82489DX!).
+ */
+ value = apic_read(APIC_SPIV);
+ value &= ~(1<<8);
+ apic_write_around(APIC_SPIV, value);
+}
+
+void __init sync_Arb_IDs(void)
+{
+ Dprintk("Synchronizing Arb IDs.\n");
+ apic_write_around(APIC_ICR, APIC_DEST_ALLINC | APIC_INT_LEVELTRIG
+ | APIC_DM_INIT);
}
extern void __error_in_apic_c (void);
@@ -78,6 +144,9 @@ void __init setup_local_APIC (void)
{
unsigned long value, ver, maxlvt;
+ value = apic_read(APIC_LVR);
+ ver = GET_APIC_VERSION(value);
+
if ((SPURIOUS_APIC_VECTOR & 0x0f) != 0x0f)
__error_in_apic_c();
@@ -87,11 +156,12 @@ void __init setup_local_APIC (void)
if (!test_bit(GET_APIC_ID(apic_read(APIC_ID)), &phys_cpu_present_map))
BUG();
- value = apic_read(APIC_SPIV);
+ value = apic_read(APIC_SPIV);
+ value &= ~APIC_VECTOR_MASK;
/*
* Enable APIC
*/
- value |= (1<<8);
+ value |= (1<<8);
/*
* Some unknown Intel IO/APIC (or APIC) errata is biting us with
@@ -108,7 +178,7 @@ void __init setup_local_APIC (void)
*/
#if 0
/* Enable focus processor (bit==0) */
- value &= ~(1<<9);
+ value &= ~(1<<9);
#else
/* Disable focus processor (bit==1) */
value |= (1<<9);
@@ -117,7 +187,7 @@ void __init setup_local_APIC (void)
* Set spurious IRQ vector
*/
value |= SPURIOUS_APIC_VECTOR;
- apic_write(APIC_SPIV,value);
+ apic_write_around(APIC_SPIV, value);
/*
* Set up LVT0, LVT1:
@@ -126,48 +196,44 @@ void __init setup_local_APIC (void)
* strictly necessery in pure symmetric-IO mode, but sometimes
* we delegate interrupts to the 8259A.
*/
- if (!smp_processor_id()) {
- value = 0x00000700;
+ /*
+ * TODO: set up through-local-APIC from through-I/O-APIC? --macro
+ */
+ value = apic_read(APIC_LVT0) & APIC_LVT_MASKED;
+ if (!smp_processor_id() && (pic_mode || !value)) {
+ value = APIC_DM_EXTINT;
printk("enabled ExtINT on CPU#%d\n", smp_processor_id());
} else {
- value = 0x00010700;
+ value = APIC_DM_EXTINT | APIC_LVT_MASKED;
printk("masked ExtINT on CPU#%d\n", smp_processor_id());
}
- apic_write_around(APIC_LVT0,value);
+ apic_write_around(APIC_LVT0, value);
/*
* only the BP should see the LINT1 NMI signal, obviously.
*/
if (!smp_processor_id())
- value = 0x00000400; // unmask NMI
+ value = APIC_DM_NMI;
else
- value = 0x00010400; // mask NMI
- apic_write_around(APIC_LVT1,value);
+ value = APIC_DM_NMI | APIC_LVT_MASKED;
+ if (!APIC_INTEGRATED(ver)) /* 82489DX */
+ value |= APIC_LVT_LEVEL_TRIGGER;
+ apic_write_around(APIC_LVT1, value);
- value = apic_read(APIC_LVR);
- ver = GET_APIC_VERSION(value);
if (APIC_INTEGRATED(ver)) { /* !82489DX */
maxlvt = get_maxlvt();
- /*
- * Due to the Pentium erratum 3AP.
- */
- if (maxlvt > 3) {
- apic_readaround(APIC_SPIV); // not strictly necessery
+ if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */
apic_write(APIC_ESR, 0);
- }
value = apic_read(APIC_ESR);
printk("ESR value before enabling vector: %08lx\n", value);
- value = apic_read(APIC_LVTERR);
value = ERROR_APIC_VECTOR; // enables sending errors
- apic_write(APIC_LVTERR,value);
+ apic_write_around(APIC_LVTERR, value);
/*
* spec says clear errors after enabling vector.
*/
- if (maxlvt != 3) {
- apic_readaround(APIC_SPIV);
+ if (maxlvt > 3)
apic_write(APIC_ESR, 0);
- }
value = apic_read(APIC_ESR);
printk("ESR value after enabling vector: %08lx\n", value);
} else
@@ -177,22 +243,23 @@ void __init setup_local_APIC (void)
* Set Task Priority to 'accept all'. We never change this
* later on.
*/
- value = apic_read(APIC_TASKPRI);
- value &= ~APIC_TPRI_MASK;
- apic_write(APIC_TASKPRI,value);
+ value = apic_read(APIC_TASKPRI);
+ value &= ~APIC_TPRI_MASK;
+ apic_write_around(APIC_TASKPRI, value);
/*
* Set up the logical destination ID and put the
* APIC into flat delivery mode.
*/
- value = apic_read(APIC_LDR);
+ value = apic_read(APIC_LDR);
value &= ~APIC_LDR_MASK;
value |= (1<<(smp_processor_id()+24));
- apic_write(APIC_LDR,value);
+ apic_write_around(APIC_LDR, value);
- value = apic_read(APIC_DFR);
- value |= SET_APIC_DFR(0xf);
- apic_write(APIC_DFR, value);
+ /*
+ * Must be "all ones" explicitly for 82489DX.
+ */
+ apic_write_around(APIC_DFR, 0xffffffff);
}
void __init init_apic_mappings(void)
@@ -214,6 +281,13 @@ void __init init_apic_mappings(void)
set_fixmap_nocache(FIX_APIC_BASE, apic_phys);
Dprintk("mapped APIC to %08lx (%08lx)\n", APIC_BASE, apic_phys);
+ /*
+ * Fetch the APIC ID of the BSP in case we have a
+ * default configuration (or the MP table is broken).
+ */
+ if (boot_cpu_id == -1U)
+ boot_cpu_id = GET_APIC_ID(apic_read(APIC_ID));
+
#ifdef CONFIG_X86_IO_APIC
{
unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0;
@@ -285,7 +359,7 @@ void __init wait_8254_wraparound(void)
* chipset timer can cause.
*/
- } while (delta<300);
+ } while (delta < 300);
}
/*
@@ -305,21 +379,19 @@ void __setup_APIC_LVTT(unsigned int clocks)
{
unsigned int lvtt1_value, tmp_value;
- tmp_value = apic_read(APIC_LVTT);
lvtt1_value = SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV) |
APIC_LVT_TIMER_PERIODIC | LOCAL_TIMER_VECTOR;
- apic_write(APIC_LVTT, lvtt1_value);
+ apic_write_around(APIC_LVTT, lvtt1_value);
/*
* Divide PICLK by 16
*/
tmp_value = apic_read(APIC_TDCR);
- apic_write(APIC_TDCR, (tmp_value
+ apic_write_around(APIC_TDCR, (tmp_value
& ~(APIC_TDR_DIV_1 | APIC_TDR_DIV_TMBASE))
| APIC_TDR_DIV_16);
- tmp_value = apic_read(APIC_TMICT);
- apic_write(APIC_TMICT, clocks/APIC_DIVISOR);
+ apic_write_around(APIC_TMICT, clocks/APIC_DIVISOR);
}
void setup_APIC_timer(void * data)
@@ -353,6 +425,12 @@ void setup_APIC_timer(void * data)
t0 = apic_read(APIC_TMCCT)*APIC_DIVISOR;
do {
+ /*
+ * It looks like the 82489DX cannot handle
+ * consecutive reads of the TMCCT register well;
+ * this dummy read prevents it from a lockup.
+ */
+ apic_read(APIC_SPIV);
t1 = apic_read(APIC_TMCCT)*APIC_DIVISOR;
delta = (int)(t0 - t1 - slice*(smp_processor_id()+1));
} while (delta < 0);
@@ -490,6 +568,41 @@ int setup_profiling_timer(unsigned int multiplier)
#undef APIC_DIVISOR
+#ifdef CONFIG_SMP
+static inline void handle_smp_time (int user, int cpu)
+{
+ int system = !user;
+ struct task_struct * p = current;
+ /*
+ * After doing the above, we need to make like
+ * a normal interrupt - otherwise timer interrupts
+ * ignore the global interrupt lock, which is the
+ * WrongThing (tm) to do.
+ */
+
+ irq_enter(cpu, 0);
+ update_one_process(p, 1, user, system, cpu);
+ if (p->pid) {
+ p->counter -= 1;
+ if (p->counter <= 0) {
+ p->counter = 0;
+ p->need_resched = 1;
+ }
+ if (p->priority < DEF_PRIORITY) {
+ kstat.cpu_nice += user;
+ kstat.per_cpu_nice[cpu] += user;
+ } else {
+ kstat.cpu_user += user;
+ kstat.per_cpu_user[cpu] += user;
+ }
+ kstat.cpu_system += system;
+ kstat.per_cpu_system[cpu] += system;
+
+ }
+ irq_exit(cpu, 0);
+}
+#endif
+
/*
* Local timer interrupt handler. It does both profiling and
* process statistics/rescheduling.
@@ -502,7 +615,6 @@ int setup_profiling_timer(unsigned int multiplier)
inline void smp_local_timer_interrupt(struct pt_regs * regs)
{
- int user = (user_mode(regs) != 0);
int cpu = smp_processor_id();
/*
@@ -511,13 +623,8 @@ inline void smp_local_timer_interrupt(struct pt_regs * regs)
* updated with atomic operations). This is especially
* useful with a profiling multiplier != 1
*/
- if (!user)
- x86_do_profile(regs->eip);
if (--prof_counter[cpu] <= 0) {
- int system = 1 - user;
- struct task_struct * p = current;
-
/*
* The multiplier may have changed since the last time we got
* to this point as a result of the user writing to
@@ -532,33 +639,9 @@ inline void smp_local_timer_interrupt(struct pt_regs * regs)
prof_old_multiplier[cpu] = prof_counter[cpu];
}
- /*
- * After doing the above, we need to make like
- * a normal interrupt - otherwise timer interrupts
- * ignore the global interrupt lock, which is the
- * WrongThing (tm) to do.
- */
-
- irq_enter(cpu, 0);
- update_one_process(p, 1, user, system, cpu);
- if (p->pid) {
- p->counter -= 1;
- if (p->counter <= 0) {
- p->counter = 0;
- p->need_resched = 1;
- }
- if (p->priority < DEF_PRIORITY) {
- kstat.cpu_nice += user;
- kstat.per_cpu_nice[cpu] += user;
- } else {
- kstat.cpu_user += user;
- kstat.per_cpu_user[cpu] += user;
- }
- kstat.cpu_system += system;
- kstat.per_cpu_system[cpu] += system;
-
- }
- irq_exit(cpu, 0);
+#ifdef CONFIG_SMP
+ handle_smp_time(user_mode(regs), cpu);
+#endif
}
/*
@@ -603,7 +686,17 @@ void smp_apic_timer_interrupt(struct pt_regs * regs)
*/
asmlinkage void smp_spurious_interrupt(void)
{
- ack_APIC_irq();
+ unsigned long v;
+
+ /*
+ * Check if this really is a spurious interrupt and ACK it
+ * if it is a vectored one. Just in case...
+ * Spurious interrupts should not be ACKed.
+ */
+ v = apic_read(APIC_ISR + ((SPURIOUS_APIC_VECTOR & ~0x1f) >> 1));
+ if (v & (1 << (SPURIOUS_APIC_VECTOR & 0x1f)))
+ ack_APIC_irq();
+
/* see sw-dev-man vol 3, chapter 7.4.13.5 */
printk("spurious APIC interrupt on CPU#%d, should never happen.\n",
smp_processor_id());
diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
index b488d97a8..50887c15c 100644
--- a/arch/i386/kernel/entry.S
+++ b/arch/i386/kernel/entry.S
@@ -40,6 +40,7 @@
* "current" is in register %ebx during any slow entries.
*/
+#include <linux/config.h>
#include <linux/sys.h>
#include <linux/linkage.h>
#include <asm/segment.h>
@@ -201,7 +202,7 @@ ENTRY(system_call)
call *SYMBOL_NAME(sys_call_table)(,%eax,4)
movl %eax,EAX(%esp) # save the return value
ENTRY(ret_from_sys_call)
-#ifdef __SMP__
+#ifdef CONFIG_SMP
movl processor(%ebx),%eax
shll $5,%eax
movl SYMBOL_NAME(softirq_state)(,%eax),%ecx
@@ -256,7 +257,7 @@ badsys:
ALIGN
ret_from_exception:
-#ifdef __SMP__
+#ifdef CONFIG_SMP
GET_CURRENT(%ebx)
movl processor(%ebx),%eax
shll $5,%eax
diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S
index ee759f2bc..51ab1c8ca 100644
--- a/arch/i386/kernel/head.S
+++ b/arch/i386/kernel/head.S
@@ -51,7 +51,7 @@ startup_32:
movl %eax,%es
movl %eax,%fs
movl %eax,%gs
-#ifdef __SMP__
+#ifdef CONFIG_SMP
orw %bx,%bx
jz 1f
/*
@@ -105,14 +105,14 @@ startup_32:
/* Set up the stack pointer */
lss stack_start,%esp
-#ifdef __SMP__
+#ifdef CONFIG_SMP
orw %bx,%bx
jz 1f /* Initial CPU cleans BSS */
pushl $0
popfl
jmp checkCPUtype
1:
-#endif __SMP__
+#endif CONFIG_SMP
/*
* Clear BSS first so that there are no surprises...
*/
@@ -159,7 +159,7 @@ startup_32:
rep
movsl
1:
-#ifdef __SMP__
+#ifdef CONFIG_SMP
checkCPUtype:
#endif
@@ -234,7 +234,7 @@ is386: pushl %ecx # restore original EFLAGS
orl $2,%eax # set MP
2: movl %eax,%cr0
call check_x87
-#ifdef __SMP__
+#ifdef CONFIG_SMP
incb ready
#endif
lgdt gdt_descr
@@ -245,7 +245,7 @@ is386: pushl %ecx # restore original EFLAGS
movl %eax,%es
movl %eax,%fs
movl %eax,%gs
-#ifdef __SMP__
+#ifdef CONFIG_SMP
movl $(__KERNEL_DS), %eax
movl %eax,%ss # Reload the stack pointer (segment only)
#else
@@ -254,7 +254,7 @@ is386: pushl %ecx # restore original EFLAGS
xorl %eax,%eax
lldt %ax
cld # gcc2 wants the direction flag cleared at all times
-#ifdef __SMP__
+#ifdef CONFIG_SMP
movb ready, %cl
cmpb $1,%cl
je 1f # the first CPU calls start_kernel
@@ -268,7 +268,7 @@ L6:
jmp L6 # main should never return here, but
# just in case, we know what happens.
-#ifdef __SMP__
+#ifdef CONFIG_SMP
ready: .byte 0
#endif
diff --git a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c
index 5327f24a4..584caa9c1 100644
--- a/arch/i386/kernel/i386_ksyms.c
+++ b/arch/i386/kernel/i386_ksyms.c
@@ -27,6 +27,11 @@ extern void dump_thread(struct pt_regs *, struct user *);
extern int dump_fpu(elf_fpregset_t *);
extern spinlock_t rtc_lock;
+#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
+extern void machine_real_restart(unsigned char *, int);
+EXPORT_SYMBOL(machine_real_restart);
+#endif
+
#ifdef CONFIG_SMP
extern void FASTCALL( __write_lock_failed(rwlock_t *rw));
extern void FASTCALL( __read_lock_failed(rwlock_t *rw));
@@ -68,7 +73,6 @@ EXPORT_SYMBOL_NOVERS(__down_write_failed);
EXPORT_SYMBOL_NOVERS(__down_read_failed);
EXPORT_SYMBOL_NOVERS(__rwsem_wake);
/* Networking helper routines. */
-EXPORT_SYMBOL(csum_partial_copy);
EXPORT_SYMBOL(csum_partial_copy_generic);
/* Delay loops */
EXPORT_SYMBOL(__udelay);
@@ -84,7 +88,6 @@ EXPORT_SYMBOL_NOVERS(__put_user_4);
EXPORT_SYMBOL(strtok);
EXPORT_SYMBOL(strpbrk);
-EXPORT_SYMBOL(strstr);
EXPORT_SYMBOL(strncpy_from_user);
EXPORT_SYMBOL(__strncpy_from_user);
diff --git a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c
index 61571ab59..334a75f88 100644
--- a/arch/i386/kernel/i8259.c
+++ b/arch/i386/kernel/i8259.c
@@ -415,7 +415,7 @@ void __init init_ISA_irqs (void)
for (i = 0; i < NR_IRQS; i++) {
irq_desc[i].status = IRQ_DISABLED;
irq_desc[i].action = 0;
- irq_desc[i].depth = 0;
+ irq_desc[i].depth = 1;
if (i < 16) {
/*
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index 1d4445669..dfee6e4d5 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -13,7 +13,9 @@
* and Ingo Molnar <mingo@redhat.com>
*
* Fixes
- * Maciej W. Rozycki : Bits for genuine 82489DX APICs
+ * Maciej W. Rozycki : Bits for genuine 82489DX APICs;
+ * thanks to Eric Gilmore for
+ * testing these extensively
*/
#include <linux/mm.h>
@@ -46,9 +48,6 @@ struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
/* MP IRQ source entries */
int mp_irq_entries = 0;
-/* non-0 if default (table-less) MP configuration */
-int mpc_default_type = 0;
-
/*
* Rough estimation of how many shared IRQs there are, can
* be changed anytime.
@@ -166,7 +165,7 @@ static void clear_IO_APIC (void)
#define MAX_PIRQS 8
int pirq_entries [MAX_PIRQS];
-int pirqs_enabled;
+int pirqs_enabled = 0;
int skip_ioapic_setup = 0;
static int __init ioapic_setup(char *str)
@@ -235,7 +234,8 @@ static int __init find_timer_pin(int type)
int lbus = mp_irqs[i].mpc_srcbus;
if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA ||
- mp_bus_id_to_type[lbus] == MP_BUS_EISA) &&
+ mp_bus_id_to_type[lbus] == MP_BUS_EISA ||
+ mp_bus_id_to_type[lbus] == MP_BUS_MCA) &&
(mp_irqs[i].mpc_irqtype == type) &&
(mp_irqs[i].mpc_srcbusirq == 0x00))
@@ -260,13 +260,15 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pci_pin)
if (mp_ioapics[apic].mpc_apicid == mp_irqs[i].mpc_dstapic)
break;
- if ((apic || IO_APIC_IRQ(mp_irqs[i].mpc_dstirq)) &&
- (mp_bus_id_to_type[lbus] == MP_BUS_PCI) &&
+ if ((mp_bus_id_to_type[lbus] == MP_BUS_PCI) &&
!mp_irqs[i].mpc_irqtype &&
(bus == mp_bus_id_to_pci_bus[mp_irqs[i].mpc_srcbus]) &&
(slot == ((mp_irqs[i].mpc_srcbusirq >> 2) & 0x1f))) {
int irq = pin_2_irq(i,apic,mp_irqs[i].mpc_dstirq);
+ if (!(apic || IO_APIC_IRQ(irq)))
+ continue;
+
if (pci_pin == (mp_irqs[i].mpc_srcbusirq & 3))
return irq;
/*
@@ -298,15 +300,27 @@ static int __init EISA_ELCR(unsigned int irq)
* EISA conforming in the MP table, that means its trigger type must
* be read in from the ELCR */
-#define default_EISA_trigger(idx) (EISA_ELCR(mp_irqs[idx].mpc_dstirq))
+#define default_EISA_trigger(idx) (EISA_ELCR(mp_irqs[idx].mpc_srcbusirq))
#define default_EISA_polarity(idx) (0)
-/* ISA interrupts are always polarity zero edge triggered, even when
- * listed as conforming in the MP table. */
+/* ISA interrupts are always polarity zero edge triggered,
+ * when listed as conforming in the MP table. */
#define default_ISA_trigger(idx) (0)
#define default_ISA_polarity(idx) (0)
+/* PCI interrupts are always polarity one level triggered,
+ * when listed as conforming in the MP table. */
+
+#define default_PCI_trigger(idx) (1)
+#define default_PCI_polarity(idx) (1)
+
+/* MCA interrupts are always polarity zero level triggered,
+ * when listed as conforming in the MP table. */
+
+#define default_MCA_trigger(idx) (1)
+#define default_MCA_polarity(idx) (0)
+
static int __init MPBIOS_polarity(int idx)
{
int bus = mp_irqs[idx].mpc_srcbus;
@@ -326,14 +340,19 @@ static int __init MPBIOS_polarity(int idx)
polarity = default_ISA_polarity(idx);
break;
}
- case MP_BUS_EISA:
+ case MP_BUS_EISA: /* EISA pin */
{
polarity = default_EISA_polarity(idx);
break;
}
case MP_BUS_PCI: /* PCI pin */
{
- polarity = 1;
+ polarity = default_PCI_polarity(idx);
+ break;
+ }
+ case MP_BUS_MCA: /* MCA pin */
+ {
+ polarity = default_MCA_polarity(idx);
break;
}
default:
@@ -385,19 +404,24 @@ static int __init MPBIOS_trigger(int idx)
{
switch (mp_bus_id_to_type[bus])
{
- case MP_BUS_ISA:
+ case MP_BUS_ISA: /* ISA pin */
{
trigger = default_ISA_trigger(idx);
break;
}
- case MP_BUS_EISA:
+ case MP_BUS_EISA: /* EISA pin */
{
trigger = default_EISA_trigger(idx);
break;
}
- case MP_BUS_PCI: /* PCI pin, level */
+ case MP_BUS_PCI: /* PCI pin */
{
- trigger = 1;
+ trigger = default_PCI_trigger(idx);
+ break;
+ }
+ case MP_BUS_MCA: /* MCA pin */
+ {
+ trigger = default_MCA_trigger(idx);
break;
}
default:
@@ -460,6 +484,7 @@ static int __init pin_2_irq(int idx, int apic, int pin)
{
case MP_BUS_ISA: /* ISA pin */
case MP_BUS_EISA:
+ case MP_BUS_MCA:
{
irq = mp_irqs[idx].mpc_srcbusirq;
break;
@@ -624,8 +649,8 @@ void __init setup_ExtINT_IRQ0_pin(unsigned int pin, int vector)
disable_8259A_irq(0);
- apic_readaround(APIC_LVT0);
- apic_write(APIC_LVT0, 0x00010700); // mask LVT0
+ /* mask LVT0 */
+ apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
init_8259A(1);
@@ -650,8 +675,8 @@ void __init setup_ExtINT_IRQ0_pin(unsigned int pin, int vector)
/*
* Add it to the IO-APIC irq-routing table:
*/
- io_apic_write(0, 0x10+2*pin, *(((int *)&entry)+0));
io_apic_write(0, 0x11+2*pin, *(((int *)&entry)+1));
+ io_apic_write(0, 0x10+2*pin, *(((int *)&entry)+0));
enable_8259A_irq(0);
}
@@ -725,8 +750,8 @@ void __init print_IO_APIC(void)
printk(KERN_DEBUG ".... IRQ redirection table:\n");
- printk(KERN_DEBUG " NR Log Phy ");
- printk(KERN_DEBUG "Mask Trig IRR Pol Stat Dest Deli Vect: \n");
+ printk(KERN_DEBUG " NR Log Phy Mask Trig IRR Pol"
+ " Stat Dest Deli Vect: \n");
for (i = 0; i <= reg_01.entries; i++) {
struct IO_APIC_route_entry entry;
@@ -831,13 +856,8 @@ void /*__init*/ print_local_APIC(void * dummy)
print_APIC_bitfield(APIC_IRR);
if (APIC_INTEGRATED(ver)) { /* !82489DX */
- /*
- * Due to the Pentium erratum 3AP.
- */
- if (maxlvt > 3) {
- apic_readaround(APIC_SPIV); // not strictly necessery
+ if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */
apic_write(APIC_ESR, 0);
- }
v = apic_read(APIC_ESR);
printk(KERN_DEBUG "... APIC ESR: %08x\n", v);
}
@@ -879,6 +899,32 @@ void print_all_local_APICs (void)
print_local_APIC(NULL);
}
+void /*__init*/ print_PIC(void)
+{
+ unsigned int v, flags;
+
+ printk(KERN_DEBUG "\nprinting PIC contents\n");
+
+ v = inb(0xa1) << 8 | inb(0x21);
+ printk(KERN_DEBUG "... PIC IMR: %04x\n", v);
+
+ v = inb(0xa0) << 8 | inb(0x20);
+ printk(KERN_DEBUG "... PIC IRR: %04x\n", v);
+
+ __save_flags(flags);
+ __cli();
+ outb(0x0b,0xa0);
+ outb(0x0b,0x20);
+ v = inb(0xa0) << 8 | inb(0x20);
+ outb(0x0a,0xa0);
+ outb(0x0a,0x20);
+ __restore_flags(flags);
+ printk(KERN_DEBUG "... PIC ISR: %04x\n", v);
+
+ v = inb(0x4d1) << 8 | inb(0x4d0);
+ printk(KERN_DEBUG "... PIC ELCR: %04x\n", v);
+}
+
static void __init enable_IO_APIC(void)
{
struct IO_APIC_reg_01 reg_01;
@@ -890,16 +936,7 @@ static void __init enable_IO_APIC(void)
}
if (!pirqs_enabled)
for (i = 0; i < MAX_PIRQS; i++)
- pirq_entries[i] =- 1;
-
- if (pic_mode) {
- /*
- * PIC mode, enable symmetric IO mode in the IMCR.
- */
- printk("leaving PIC mode, enabling symmetric IO mode.\n");
- outb(0x70, 0x22);
- outb(0x01, 0x23);
- }
+ pirq_entries[i] = -1;
/*
* The number of IO-APIC IRQ registers (== #pins):
@@ -925,15 +962,7 @@ void disable_IO_APIC(void)
*/
clear_IO_APIC();
- /*
- * Put it back into PIC mode (has an effect only on
- * certain older boards)
- */
- if (pic_mode) {
- printk("disabling symmetric IO mode, entering PIC mode.\n");
- outb_p(0x70, 0x22);
- outb_p(0x00, 0x23);
- }
+ disconnect_bsp_APIC();
}
/*
@@ -986,48 +1015,6 @@ static void __init setup_ioapic_ids_from_mpc (void)
}
}
-static void __init construct_default_ISA_mptable(void)
-{
- int i, pos = 0;
- const int bus_type = (mpc_default_type == 2 || mpc_default_type == 3 ||
- mpc_default_type == 6) ? MP_BUS_EISA : MP_BUS_ISA;
-
- for (i = 0; i < 16; i++) {
- if (!IO_APIC_IRQ(i))
- continue;
-
- mp_irqs[pos].mpc_irqtype = mp_INT;
- mp_irqs[pos].mpc_irqflag = 0; /* default */
- mp_irqs[pos].mpc_srcbus = 0;
- mp_irqs[pos].mpc_srcbusirq = i;
- mp_irqs[pos].mpc_dstapic = 0;
- mp_irqs[pos].mpc_dstirq = i;
- pos++;
- }
- mp_irq_entries = pos;
- mp_bus_id_to_type[0] = bus_type;
-
- /*
- * MP specification 1.4 defines some extra rules for default
- * configurations, fix them up here:
- */
- switch (mpc_default_type)
- {
- case 2:
- /*
- * IRQ0 is not connected:
- */
- mp_irqs[0].mpc_irqtype = mp_ExtINT;
- break;
- default:
- /*
- * pin 2 is IRQ0:
- */
- mp_irqs[0].mpc_dstirq = 2;
- }
-
-}
-
/*
* There is a nasty bug in some older SMP boards, their mptable lies
* about the timer IRQ. We do the following to work around the situation:
@@ -1041,9 +1028,17 @@ static int __init timer_irq_works(void)
unsigned int t1 = jiffies;
sti();
- mdelay(40);
+ /* Let ten ticks pass... */
+ mdelay((10 * 1000) / HZ);
- if (jiffies-t1>1)
+ /*
+ * Expect a few ticks at least, to be sure some possible
+ * glue logic does not lock up after one or two first
+ * ticks in a non-ExtINT mode. Also the local APIC
+ * might have cached one ExtINT interrupt. Finally, at
+ * least one tick may be lost due to delays.
+ */
+ if (jiffies - t1 > 4)
return 1;
return 0;
@@ -1257,8 +1252,14 @@ static struct hw_interrupt_type lapic_irq_type = {
static void enable_NMI_through_LVT0 (void * dummy)
{
- apic_readaround(APIC_LVT0);
- apic_write(APIC_LVT0, 0x00000400); // unmask and set to NMI
+ unsigned int v, ver;
+
+ ver = apic_read(APIC_LVR);
+ ver = GET_APIC_VERSION(ver);
+ v = APIC_DM_NMI; /* unmask and set to NMI */
+ if (!APIC_INTEGRATED(ver)) /* 82489DX */
+ v |= APIC_LVT_LEVEL_TRIGGER;
+ apic_write_around(APIC_LVT0, v);
}
static void setup_nmi (void)
@@ -1303,24 +1304,23 @@ static inline void check_timer(void)
printk(KERN_INFO "..TIMER: vector=%d pin1=%d pin2=%d\n", vector, pin1, pin2);
- /*
- * Ok, does IRQ0 through the IOAPIC work?
- */
- if (timer_irq_works()) {
- if (nmi_watchdog) {
- disable_8259A_irq(0);
- init_8259A(1);
- setup_nmi();
- enable_8259A_irq(0);
- if (nmi_irq_works())
- return;
- } else
- return;
- }
-
if (pin1 != -1) {
- printk(KERN_ERR "..MP-BIOS bug: 8254 timer not connected to IO-APIC\n");
+ /*
+ * Ok, does IRQ0 through the IOAPIC work?
+ */
+ unmask_IO_APIC_irq(0);
+ if (timer_irq_works()) {
+ if (nmi_watchdog) {
+ disable_8259A_irq(0);
+ init_8259A(1);
+ setup_nmi();
+ enable_8259A_irq(0);
+ nmi_irq_works();
+ }
+ return;
+ }
clear_IO_APIC_pin(0, pin1);
+ printk(KERN_ERR "..MP-BIOS bug: 8254 timer not connected to IO-APIC\n");
}
printk(KERN_INFO "...trying to set up timer (IRQ0) through the 8259A ... ");
@@ -1334,10 +1334,9 @@ static inline void check_timer(void)
printk("works.\n");
if (nmi_watchdog) {
setup_nmi();
- if (nmi_irq_works())
- return;
- } else
- return;
+ nmi_irq_works();
+ }
+ return;
}
/*
* Cleanup, just in case ...
@@ -1355,9 +1354,8 @@ static inline void check_timer(void)
disable_8259A_irq(0);
irq_desc[0].handler = &lapic_irq_type;
- init_8259A(1); // AEOI mode
- apic_readaround(APIC_LVT0);
- apic_write(APIC_LVT0, 0x00000000 | vector); // Fixed mode
+ init_8259A(1); /* AEOI mode */
+ apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */
enable_8259A_irq(0);
if (timer_irq_works()) {
@@ -1392,20 +1390,11 @@ void __init setup_IO_APIC(void)
printk("ENABLING IO-APIC IRQs\n");
/*
- * If there are no explicit MP IRQ entries, it's either one of the
- * default configuration types or we are broken. In both cases it's
- * fine to set up most of the low 16 IO-APIC pins to ISA defaults.
- */
- if (!mp_irq_entries) {
- printk("no explicit IRQ entries, using default mptable\n");
- construct_default_ISA_mptable();
- }
-
- /*
* Set up the IO-APIC IRQ routing table by parsing the MP-BIOS
* mptable:
*/
setup_ioapic_ids_from_mpc();
+ sync_Arb_IDs();
setup_IO_APIC_irqs();
init_IO_APIC_traps();
check_timer();
@@ -1421,6 +1410,7 @@ void IO_APIC_init_uniprocessor (void)
{
if (!smp_found_config)
return;
+ connect_bsp_APIC();
setup_local_APIC();
setup_IO_APIC();
setup_APIC_clocks();
diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c
index a96540d6e..79155a326 100644
--- a/arch/i386/kernel/irq.c
+++ b/arch/i386/kernel/irq.c
@@ -462,8 +462,8 @@ int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, struct irqaction *
* @irq: Interrupt to disable
*
* Disable the selected interrupt line. Disables of an interrupt
- * stack. Unlike disable_irq, this function does not ensure existing
- * instances of the irq handler have completed before returning.
+ * stack. Unlike disable_irq(), this function does not ensure existing
+ * instances of the IRQ handler have completed before returning.
*
* This function may be called from IRQ context.
*/
@@ -1127,7 +1127,7 @@ static void register_irq_proc (unsigned int irq)
irq_dir[irq] = proc_mkdir(name, root_irq_dir);
/* create /proc/irq/1234/smp_affinity */
- entry = create_proc_entry("smp_affinity", 0700, irq_dir[irq]);
+ entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]);
entry->nlink = 1;
entry->data = (void *)(long)irq;
@@ -1148,7 +1148,7 @@ void init_irq_proc (void)
root_irq_dir = proc_mkdir("irq", 0);
/* create /proc/irq/prof_cpu_mask */
- entry = create_proc_entry("prof_cpu_mask", 0700, root_irq_dir);
+ entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir);
entry->nlink = 1;
entry->data = (void *)&prof_cpu_mask;
diff --git a/arch/i386/kernel/mca.c b/arch/i386/kernel/mca.c
index f0f0f9f37..6c6053bf7 100644
--- a/arch/i386/kernel/mca.c
+++ b/arch/i386/kernel/mca.c
@@ -366,12 +366,12 @@ void mca_handle_nmi(void)
/**
* mca_find_adapter - scan for adapters
* @id: MCA identification to search for
- * @start: Starting slot
+ * @start: starting slot
*
* Search the MCA configuration for adapters matching the 16bit
* ID given. The first time it should be called with start as zero
* and then further calls made passing the return value of the
- * previous call until MCA_NOTFOUND is returned.
+ * previous call until %MCA_NOTFOUND is returned.
*
* Disabled adapters are not reported.
*/
@@ -411,12 +411,12 @@ EXPORT_SYMBOL(mca_find_adapter);
/**
* mca_find_unused_adapter - scan for unused adapters
* @id: MCA identification to search for
- * @start: Starting slot
+ * @start: starting slot
*
* Search the MCA configuration for adapters matching the 16bit
* ID given. The first time it should be called with start as zero
* and then further calls made passing the return value of the
- * previous call until MCA_NOTFOUND is returned.
+ * previous call until %MCA_NOTFOUND is returned.
*
* Adapters that have been claimed by drivers and those that
* are disabled are not reported. This function thus allows a driver
@@ -647,10 +647,10 @@ EXPORT_SYMBOL(mca_set_adapter_name);
* function is called with the buffer, slot, and device pointer (or
* some equally informative context information, or nothing, if you
* prefer), and is expected to put useful information into the
- * buffer. The adapter name, id, and POS registers get printed
+ * buffer. The adapter name, ID, and POS registers get printed
* before this is called though, so don't do it again.
*
- * This should be called with a NULL procfn when a module
+ * This should be called with a %NULL @procfn when a module
* unregisters, thus preventing kernel crashes and other such
* nastiness.
*/
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
index 030b31647..5df83a10a 100644
--- a/arch/i386/kernel/mpparse.c
+++ b/arch/i386/kernel/mpparse.c
@@ -9,7 +9,7 @@
* Erich Boleyn : MP v1.4 and additional changes.
* Alan Cox : Added EBDA scanning
* Ingo Molnar : various cleanups and rewrites
- * Maciej W. Rozycki : Bits for genuine 82489DX APICs
+ * Maciej W. Rozycki : Bits for default MP configurations
*/
#include <linux/mm.h>
@@ -34,7 +34,7 @@ int smp_found_config = 0;
* Various Linux-internal data structures created from the
* MP-table.
*/
-int apic_version [NR_CPUS];
+int apic_version [MAX_APICS];
int mp_bus_id_to_type [MAX_MP_BUSSES] = { -1, };
int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { -1, };
int mp_current_pci_id = 0;
@@ -42,9 +42,9 @@ int pic_mode;
unsigned long mp_lapic_addr = 0;
/* Processor that is doing the boot up */
-unsigned int boot_cpu_id = 0;
+unsigned int boot_cpu_id = -1U;
/* Internal processor count */
-static unsigned int num_processors = 1;
+static unsigned int num_processors = 0;
/* Bitmask of physically existing CPUs */
unsigned long phys_cpu_present_map = 0;
@@ -132,13 +132,12 @@ static void __init MP_processor_info (struct mpc_config_processor *m)
if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) {
Dprintk(" Bootup CPU\n");
boot_cpu_id = m->mpc_apicid;
- } else
- /* Boot CPU already counted */
- num_processors++;
+ }
+ num_processors++;
- if (m->mpc_apicid > NR_CPUS) {
- printk("Processor #%d unused. (Max %d processors).\n",
- m->mpc_apicid, NR_CPUS);
+ if (m->mpc_apicid > MAX_APICS) {
+ printk("Processor #%d INVALID. (Max ID: %d).\n",
+ m->mpc_apicid, MAX_APICS);
return;
}
ver = m->mpc_apicver;
@@ -164,18 +163,18 @@ static void __init MP_bus_info (struct mpc_config_bus *m)
if (strncmp(str, "ISA", 3) == 0) {
mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA;
- } else {
- if (strncmp(str, "EISA", 4) == 0) {
+ } else if (strncmp(str, "EISA", 4) == 0) {
mp_bus_id_to_type[m->mpc_busid] = MP_BUS_EISA;
- } else {
- if (strncmp(str, "PCI", 3) == 0) {
+ } else if (strncmp(str, "PCI", 3) == 0) {
mp_bus_id_to_type[m->mpc_busid] = MP_BUS_PCI;
mp_bus_id_to_pci_bus[m->mpc_busid] = mp_current_pci_id;
mp_current_pci_id++;
+ } else if (strncmp(str, "MCA", 3) == 0) {
+ mp_bus_id_to_type[m->mpc_busid] = MP_BUS_MCA;
} else {
printk("Unknown bustype %s\n", str);
panic("cannot handle bus - mail to linux-smp@vger.rutgers.edu");
- } } }
+ }
}
static void __init MP_ioapic_info (struct mpc_config_ioapic *m)
@@ -197,12 +196,22 @@ static void __init MP_ioapic_info (struct mpc_config_ioapic *m)
static void __init MP_intsrc_info (struct mpc_config_intsrc *m)
{
mp_irqs [mp_irq_entries] = *m;
+ Dprintk("Int: type %d, pol %d, trig %d, bus %d,"
+ " IRQ %02x, APIC ID %x, APIC INT %02x\n",
+ m->mpc_irqtype, m->mpc_irqflag & 3,
+ (m->mpc_irqflag >> 2) & 3, m->mpc_srcbus,
+ m->mpc_srcbusirq, m->mpc_dstapic, m->mpc_dstirq);
if (++mp_irq_entries == MAX_IRQ_SOURCES)
panic("Max # of irq sources exceeded!!\n");
}
static void __init MP_lintsrc_info (struct mpc_config_lintsrc *m)
{
+ Dprintk("Lint: type %d, pol %d, trig %d, bus %d,"
+ " IRQ %02x, APIC ID %x, APIC LINT %02x\n",
+ m->mpc_irqtype, m->mpc_irqflag & 3,
+ (m->mpc_irqflag >> 2) &3, m->mpc_srcbusid,
+ m->mpc_srcbusirq, m->mpc_destapic, m->mpc_destapiclint);
/*
* Well it seems all SMP boards in existence
* use ExtINT/LVT1 == LINT0 and
@@ -316,6 +325,122 @@ static int __init smp_read_mpc(struct mp_config_table *mpc)
return num_processors;
}
+static void __init construct_default_ioirq_mptable(int mpc_default_type)
+{
+ struct mpc_config_intsrc intsrc;
+ int i;
+
+ intsrc.mpc_type = MP_INTSRC;
+ intsrc.mpc_irqflag = 0; /* conforming */
+ intsrc.mpc_srcbus = 0;
+ intsrc.mpc_dstapic = mp_ioapics[0].mpc_apicid;
+
+ intsrc.mpc_irqtype = mp_INT;
+ for (i = 0; i < 16; i++) {
+ switch (mpc_default_type) {
+ case 2:
+ if (i == 0 || i == 13)
+ continue; /* IRQ0 & IRQ13 not connected */
+ /* fall through */
+ default:
+ if (i == 2)
+ continue; /* IRQ2 is never connected */
+ }
+
+ intsrc.mpc_srcbusirq = i;
+ intsrc.mpc_dstirq = i ? i : 2; /* IRQ0 to INTIN2 */
+ MP_intsrc_info(&intsrc);
+ }
+
+ intsrc.mpc_irqtype = mp_ExtINT;
+ intsrc.mpc_srcbusirq = 0;
+ intsrc.mpc_dstirq = 0; /* 8259A to INTIN0 */
+ MP_intsrc_info(&intsrc);
+}
+
+static inline void __init construct_default_ISA_mptable(int mpc_default_type)
+{
+ struct mpc_config_processor processor;
+ struct mpc_config_bus bus;
+ struct mpc_config_ioapic ioapic;
+ struct mpc_config_lintsrc lintsrc;
+ int linttypes[2] = { mp_ExtINT, mp_NMI };
+ int i;
+
+ /*
+ * local APIC has default address
+ */
+ mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
+
+ /*
+ * 2 CPUs, numbered 0 & 1.
+ */
+ processor.mpc_type = MP_PROCESSOR;
+ /* Either an integrated APIC or a discrete 82489DX. */
+ processor.mpc_apicver = mpc_default_type > 4 ? 0x10 : 0x01;
+ processor.mpc_cpuflag = CPU_ENABLED;
+ processor.mpc_cpufeature = (boot_cpu_data.x86 << 8) |
+ (boot_cpu_data.x86_model << 4) |
+ boot_cpu_data.x86_mask;
+ processor.mpc_featureflag = boot_cpu_data.x86_capability;
+ processor.mpc_reserved[0] = 0;
+ processor.mpc_reserved[1] = 0;
+ for (i = 0; i < 2; i++) {
+ processor.mpc_apicid = i;
+ MP_processor_info(&processor);
+ }
+
+ bus.mpc_type = MP_BUS;
+ bus.mpc_busid = 0;
+ switch (mpc_default_type) {
+ default:
+ printk("???\nUnknown standard configuration %d\n",
+ mpc_default_type);
+ /* fall through */
+ case 1:
+ case 5:
+ memcpy(bus.mpc_bustype, "ISA ", 6);
+ break;
+ case 2:
+ case 6:
+ case 3:
+ memcpy(bus.mpc_bustype, "EISA ", 6);
+ break;
+ case 4:
+ case 7:
+ memcpy(bus.mpc_bustype, "MCA ", 6);
+ }
+ MP_bus_info(&bus);
+ if (mpc_default_type > 4) {
+ bus.mpc_busid = 1;
+ memcpy(bus.mpc_bustype, "PCI ", 6);
+ MP_bus_info(&bus);
+ }
+
+ ioapic.mpc_type = MP_IOAPIC;
+ ioapic.mpc_apicid = 2;
+ ioapic.mpc_apicver = mpc_default_type > 4 ? 0x10 : 0x01;
+ ioapic.mpc_flags = MPC_APIC_USABLE;
+ ioapic.mpc_apicaddr = 0xFEC00000;
+ MP_ioapic_info(&ioapic);
+
+ /*
+ * We set up most of the low 16 IO-APIC pins according to MPS rules.
+ */
+ construct_default_ioirq_mptable(mpc_default_type);
+
+ lintsrc.mpc_type = MP_LINTSRC;
+ lintsrc.mpc_irqflag = 0; /* conforming */
+ lintsrc.mpc_srcbusid = 0;
+ lintsrc.mpc_srcbusirq = 0;
+ lintsrc.mpc_destapic = MP_APIC_ALL;
+ for (i = 0; i < 2; i++) {
+ lintsrc.mpc_irqtype = linttypes[i];
+ lintsrc.mpc_destapiclint = i;
+ MP_lintsrc_info(&lintsrc);
+ }
+}
+
static struct intel_mp_floating *mpf_found;
/*
@@ -332,83 +457,43 @@ void __init get_smp_config (void)
printk(" Virtual Wire compatibility mode.\n");
pic_mode = 0;
}
- /*
- * default CPU id - if it's different in the mptable
- * then we change it before first using it.
- */
- boot_cpu_id = 0;
+
/*
* Now see if we need to read further.
*/
if (mpf->mpf_feature1 != 0) {
+
printk("Default MP configuration #%d\n", mpf->mpf_feature1);
+ construct_default_ISA_mptable(mpf->mpf_feature1);
- /*
- * local APIC has default address
- */
- mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
+ } else if (mpf->mpf_physptr) {
/*
- * 2 CPUs, numbered 0 & 1.
+ * Read the physical hardware table. Anything here will
+ * override the defaults.
*/
- phys_cpu_present_map = 3;
- num_processors = 2;
+ smp_read_mpc((void *)mpf->mpf_physptr);
- nr_ioapics = 1;
- mp_ioapics[0].mpc_apicaddr = 0xFEC00000;
- mp_ioapics[0].mpc_apicid = 2;
/*
- * Save the default type number, we
- * need it later to set the IO-APIC
- * up properly:
+ * If there are no explicit MP IRQ entries, then we are
+ * broken. We set up most of the low 16 IO-APIC pins to
+ * ISA defaults and hope it will work.
*/
- mpc_default_type = mpf->mpf_feature1;
+ if (!mp_irq_entries) {
+ struct mpc_config_bus bus;
- printk("Bus #0 is ");
- }
+ printk("BIOS bug, no explicit IRQ entries, using default mptable. (tell your hw vendor)\n");
- switch (mpf->mpf_feature1) {
- case 1:
- case 5:
- printk("ISA\n");
- break;
- case 2:
- printk("EISA with no IRQ0 and no IRQ13 DMA chaining\n");
- break;
- case 6:
- case 3:
- printk("EISA\n");
- break;
- case 4:
- case 7:
- printk("MCA\n");
- break;
- case 0:
- if (!mpf->mpf_physptr)
- BUG();
- break;
- default:
- printk("???\nUnknown standard configuration %d\n",
- mpf->mpf_feature1);
- return;
- }
- if (mpf->mpf_feature1 > 4) {
- printk("Bus #1 is PCI\n");
+ bus.mpc_type = MP_BUS;
+ bus.mpc_busid = 0;
+ memcpy(bus.mpc_bustype, "ISA ", 6);
+ MP_bus_info(&bus);
- /*
- * Set local APIC version to the integrated form.
- * It's initialized to zero otherwise, representing
- * a discrete 82489DX.
- */
- apic_version[0] = 0x10;
- apic_version[1] = 0x10;
- }
- /*
- * Read the physical hardware table. Anything here will override the
- * defaults.
- */
- if (mpf->mpf_physptr)
- smp_read_mpc((void *)mpf->mpf_physptr);
+ construct_default_ioirq_mptable(0);
+ }
+
+ } else
+ BUG();
printk("Processors: %d\n", num_processors);
/*
diff --git a/arch/i386/kernel/mtrr.c b/arch/i386/kernel/mtrr.c
index f5a035cc7..fb066f051 100644
--- a/arch/i386/kernel/mtrr.c
+++ b/arch/i386/kernel/mtrr.c
@@ -289,7 +289,7 @@
#define MTRRfix4K_F0000_MSR 0x26e
#define MTRRfix4K_F8000_MSR 0x26f
-#ifdef __SMP__
+#ifdef CONFIG_SMP
# define MTRR_CHANGE_MASK_FIXED 0x01
# define MTRR_CHANGE_MASK_VARIABLE 0x02
# define MTRR_CHANGE_MASK_DEFTYPE 0x04
@@ -302,7 +302,7 @@ typedef u8 mtrr_type;
#define LINE_SIZE 80
#define JIFFIE_TIMEOUT 100
-#ifdef __SMP__
+#ifdef CONFIG_SMP
# define set_mtrr(reg,base,size,type) set_mtrr_smp (reg, base, size, type)
#else
# define set_mtrr(reg,base,size,type) (*set_mtrr_up) (reg, base, size, type, \
@@ -767,7 +767,7 @@ static void (*set_mtrr_up) (unsigned int reg, unsigned long base,
unsigned long size, mtrr_type type,
int do_safe) = NULL;
-#ifdef __SMP__
+#ifdef CONFIG_SMP
struct mtrr_var_range
{
@@ -1015,7 +1015,7 @@ static void __init mtrr_state_warn(unsigned long mask)
printk ("mtrr: probably your BIOS does not setup all CPUs\n");
} /* End Function mtrr_state_warn */
-#endif /* __SMP__ */
+#endif /* CONFIG_SMP */
static char *attrib_to_str (int x)
{
@@ -1110,7 +1110,7 @@ static int (*get_free_region) (unsigned long base,
*
* Memory type region registers control the caching on newer Intel and
* non Intel processors. This function allows drivers to request an
- * MTRR is added. The details and hardware specifics of each processors
+ * MTRR is added. The details and hardware specifics of each processor's
* implementation are hidden from the caller, but nevertheless the
* caller should expect to need to provide a power of two size on an
* equivalent power of two boundary.
@@ -1125,13 +1125,13 @@ static int (*get_free_region) (unsigned long base,
*
* The available types are
*
- * MTRR_TYPE_UNCACHEABLE - No caching
+ * %MTRR_TYPE_UNCACHEABLE - No caching
*
- * MTRR_TYPE_WRITEBACK - Write data back in bursts whenever
+ * %MTRR_TYPE_WRITEBACK - Write data back in bursts whenever
*
- * MTRR_TYPE_WRCOMB - Write data back soon but allow bursts
+ * %MTRR_TYPE_WRCOMB - Write data back soon but allow bursts
*
- * MTRR_TYPE_WRTHROUGH - Cache reads but not writes
+ * %MTRR_TYPE_WRTHROUGH - Cache reads but not writes
*
* BUGS: Needs a quiet flag for the cases where drivers do not mind
* failures and do not wish system log messages to be sent.
@@ -1608,7 +1608,7 @@ static void compute_ascii (void)
EXPORT_SYMBOL(mtrr_add);
EXPORT_SYMBOL(mtrr_del);
-#ifdef __SMP__
+#ifdef CONFIG_SMP
typedef struct
{
@@ -1663,7 +1663,7 @@ static void __init cyrix_arr_init(void)
struct set_mtrr_context ctxt;
unsigned char ccr[7];
int ccrc[7] = { 0, 0, 0, 0, 0, 0, 0 };
-#ifdef __SMP__
+#ifdef CONFIG_SMP
int i;
#endif
@@ -1709,7 +1709,7 @@ static void __init cyrix_arr_init(void)
setCx86 (CX86_CCR5, ccr[5]);
}
-#ifdef __SMP__
+#ifdef CONFIG_SMP
for(i=0; i<7; i++) ccr_state[i] = ccr[i];
for(i=0; i<8; i++)
cyrix_get_arr(i,
@@ -1782,7 +1782,7 @@ static void __init mtrr_setup(void)
}
} /* End Function mtrr_setup */
-#ifdef __SMP__
+#ifdef CONFIG_SMP
static volatile unsigned long smp_changes_mask __initdata = 0;
static struct mtrr_state smp_mtrr_state __initdata = {0, 0};
@@ -1851,12 +1851,12 @@ void __init mtrr_init_secondary_cpu(void)
break;
}
} /* End Function mtrr_init_secondary_cpu */
-#endif /* __SMP__ */
+#endif /* CONFIG_SMP */
int __init mtrr_init(void)
{
if ( !(boot_cpu_data.x86_capability & X86_FEATURE_MTRR) ) return 0;
-#ifdef __SMP__
+#ifdef CONFIG_SMP
switch (boot_cpu_data.x86_vendor)
{
case X86_VENDOR_AMD:
@@ -1866,7 +1866,7 @@ int __init mtrr_init(void)
mtrr_state_warn (smp_changes_mask);
break;
}
-#else /* __SMP__ */
+#else /* CONFIG_SMP */
mtrr_setup ();
switch (boot_cpu_data.x86_vendor)
{
@@ -1877,7 +1877,7 @@ int __init mtrr_init(void)
centaur_mcr_init ();
break;
}
-#endif /* !__SMP__ */
+#endif /* !CONFIG_SMP */
#ifdef CONFIG_PROC_FS
proc_root_mtrr = create_proc_entry ("mtrr", S_IWUSR | S_IRUGO, &proc_root);
diff --git a/arch/i386/kernel/pci-irq.c b/arch/i386/kernel/pci-irq.c
index 8dd3f5c82..4695abdf4 100644
--- a/arch/i386/kernel/pci-irq.c
+++ b/arch/i386/kernel/pci-irq.c
@@ -29,7 +29,7 @@ static struct irq_routing_table *pirq_table;
* Avoid using: 13, 14 and 15 (FP error and IDE).
* Penalize: 3, 4, 7, 12 (known ISA uses: serial, parallel and mouse)
*/
-unsigned int pcibios_irq_mask = ~0;
+unsigned int pcibios_irq_mask = 0xfff8;
static unsigned pirq_penalty[16] = {
10000, 10000, 10000, 100, 100, 0, 0, 100,
@@ -305,10 +305,7 @@ int pcibios_lookup_irq(struct pci_dev *dev, int assign)
return 0;
}
DBG(" -> PIRQ %02x, mask %04x, excl %04x", pirq, mask, pirq_table->exclusive_irqs);
- if (pcibios_irq_mask != ~0)
- mask &= pcibios_irq_mask;
- else
- mask &= pirq_table->exclusive_irqs;
+ mask &= pcibios_irq_mask;
/* Find the best IRQ to assign */
newirq = 0;
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 3ba1d8257..96eedb519 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -589,7 +589,6 @@ void dump_thread(struct pt_regs * regs, struct user * dump)
* More important, however, is the fact that this allows us much
* more flexibility.
*/
-extern int cpus_initialized;
void __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
{
struct thread_struct *prev = &prev_p->thread,
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index 71407c0ea..ac088253f 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -495,6 +495,10 @@ static inline void parse_mem_cmdline (char ** cmdline_p)
if (!memcmp(from+4, "nopentium", 9)) {
from += 9+4;
boot_cpu_data.x86_capability &= ~X86_FEATURE_PSE;
+ } else if (!memcmp(from+4, "exactmap", 8)) {
+ from += 8+4;
+ e820.nr_map = 0;
+ usermem = 1;
} else {
/* If the user specifies memory size, we
* blow away any automatically generated
@@ -1531,8 +1535,7 @@ int get_cpuinfo(char * buffer)
return p - buffer;
}
-int cpus_initialized = 0;
-unsigned long cpu_initialized = 0;
+static unsigned long cpu_initialized __initdata = 0;
/*
* cpu_init() initializes state that is per-CPU. Some data is already
@@ -1549,7 +1552,6 @@ void __init cpu_init (void)
printk("CPU#%d already initialized!\n", nr);
for (;;) __sti();
}
- cpus_initialized++;
printk("Initializing CPU#%d\n", nr);
if (cpu_has_vme || cpu_has_tsc || cpu_has_de)
diff --git a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c
index c7c079194..4e813fac7 100644
--- a/arch/i386/kernel/signal.c
+++ b/arch/i386/kernel/signal.c
@@ -339,9 +339,9 @@ setup_sigcontext(struct sigcontext *sc, struct _fpstate *fpstate,
int tmp, err = 0;
tmp = 0;
- __asm__("movl %%gs,%w0" : "=r"(tmp): "0"(tmp));
+ __asm__("movl %%gs,%0" : "=r"(tmp): "0"(tmp));
err |= __put_user(tmp, (unsigned int *)&sc->gs);
- __asm__("movl %%fs,%w0" : "=r"(tmp): "0"(tmp));
+ __asm__("movl %%fs,%0" : "=r"(tmp): "0"(tmp));
err |= __put_user(tmp, (unsigned int *)&sc->fs);
err |= __put_user(regs->xes, (unsigned int *)&sc->es);
diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c
index 12f193c71..94ba5c49f 100644
--- a/arch/i386/kernel/smp.c
+++ b/arch/i386/kernel/smp.c
@@ -111,108 +111,26 @@ struct tlb_state cpu_tlbstate[NR_CPUS] = {[0 ... NR_CPUS-1] = { &init_mm, 0 }};
* We use 'broadcast', CPU->CPU IPIs and self-IPIs too.
*/
-static unsigned int cached_APIC_ICR;
-static unsigned int cached_APIC_ICR2;
-
-/*
- * Caches reserved bits, APIC reads are (mildly) expensive
- * and force otherwise unnecessary CPU synchronization.
- *
- * (We could cache other APIC registers too, but these are the
- * main ones used in RL.)
- */
-#define slow_ICR (apic_read(APIC_ICR) & ~0xFDFFF)
-#define slow_ICR2 (apic_read(APIC_ICR2) & 0x00FFFFFF)
-
-void cache_APIC_registers (void)
-{
- cached_APIC_ICR = slow_ICR;
- cached_APIC_ICR2 = slow_ICR2;
- mb();
-}
-
-static inline unsigned int __get_ICR (void)
-{
-#if FORCE_READ_AROUND_WRITE
- /*
- * Wait for the APIC to become ready - this should never occur. It's
- * a debugging check really.
- */
- int count = 0;
- unsigned int cfg;
-
- while (count < 1000)
- {
- cfg = slow_ICR;
- if (!(cfg&(1<<12)))
- return cfg;
- printk("CPU #%d: ICR still busy [%08x]\n",
- smp_processor_id(), cfg);
- irq_err_count++;
- count++;
- udelay(10);
- }
- printk("CPU #%d: previous IPI still not cleared after 10mS\n",
- smp_processor_id());
- return cfg;
-#else
- return cached_APIC_ICR;
-#endif
-}
-
-static inline unsigned int __get_ICR2 (void)
-{
-#if FORCE_READ_AROUND_WRITE
- return slow_ICR2;
-#else
- return cached_APIC_ICR2;
-#endif
-}
-
-#define LOGICAL_DELIVERY 1
-
static inline int __prepare_ICR (unsigned int shortcut, int vector)
{
- unsigned int cfg;
-
- cfg = __get_ICR();
- cfg |= APIC_DEST_DM_FIXED|shortcut|vector
-#if LOGICAL_DELIVERY
- |APIC_DEST_LOGICAL
-#endif
- ;
-
- return cfg;
+ return APIC_DM_FIXED | shortcut | vector | APIC_DEST_LOGICAL;
}
static inline int __prepare_ICR2 (unsigned int mask)
{
- unsigned int cfg;
-
- cfg = __get_ICR2();
-#if LOGICAL_DELIVERY
- cfg |= SET_APIC_DEST_FIELD(mask);
-#else
- cfg |= SET_APIC_DEST_FIELD(mask);
-#endif
-
- return cfg;
+ return SET_APIC_DEST_FIELD(mask);
}
static inline void __send_IPI_shortcut(unsigned int shortcut, int vector)
{
+ /*
+ * Subtle. In the case of the 'never do double writes' workaround
+ * we have to lock out interrupts to be safe. As we don't care
+ * of the value read we use an atomic rmw access to avoid costly
+ * cli/sti. Otherwise we use an even cheaper single atomic write
+ * to the APIC.
+ */
unsigned int cfg;
-/*
- * Subtle. In the case of the 'never do double writes' workaround we
- * have to lock out interrupts to be safe. Otherwise it's just one
- * single atomic write to the APIC, no need for cli/sti.
- */
-#if FORCE_READ_AROUND_WRITE
- unsigned long flags;
-
- __save_flags(flags);
- __cli();
-#endif
/*
* No need to touch the target chip field
@@ -222,10 +140,7 @@ static inline void __send_IPI_shortcut(unsigned int shortcut, int vector)
/*
* Send the IPI. The write to APIC_ICR fires this off.
*/
- apic_write(APIC_ICR, cfg);
-#if FORCE_READ_AROUND_WRITE
- __restore_flags(flags);
-#endif
+ apic_write_around(APIC_ICR, cfg);
}
static inline void send_IPI_allbutself(int vector)
@@ -252,19 +167,16 @@ void send_IPI_self(int vector)
static inline void send_IPI_mask(int mask, int vector)
{
unsigned long cfg;
-#if FORCE_READ_AROUND_WRITE
unsigned long flags;
__save_flags(flags);
__cli();
-#endif
/*
* prepare target chip field
*/
-
cfg = __prepare_ICR2(mask);
- apic_write(APIC_ICR2, cfg);
+ apic_write_around(APIC_ICR2, cfg);
/*
* program the ICR
@@ -274,10 +186,8 @@ static inline void send_IPI_mask(int mask, int vector)
/*
* Send the IPI. The write to APIC_ICR fires this off.
*/
- apic_write(APIC_ICR, cfg);
-#if FORCE_READ_AROUND_WRITE
+ apic_write_around(APIC_ICR, cfg);
__restore_flags(flags);
-#endif
}
/*
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index 50b743a99..ae84ff2b5 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -28,6 +28,7 @@
* from Jose Renau
* Ingo Molnar : various cleanups and rewrites
* Tigran Aivazian : fixed "0.00 in /proc/uptime on SMP" bug.
+ * Maciej W. Rozycki : Bits for genuine 82489DX APICs
*/
#include <linux/config.h>
@@ -489,11 +490,43 @@ static int __init fork_by_hand(void)
return do_fork(CLONE_VM|CLONE_PID, 0, &regs);
}
+#if APIC_DEBUG
+static inline void inquire_remote_apic(int apicid)
+{
+ int i, regs[] = { APIC_ID >> 4, APIC_LVR >> 4, APIC_SPIV >> 4 };
+ char *names[] = { "ID", "VERSION", "SPIV" };
+ int timeout, status;
+
+ printk("Inquiring remote APIC #%d...\n", apicid);
+
+ for (i = 0; i < sizeof(regs) / sizeof(*regs); i++) {
+ printk("... APIC #%d %s: ", apicid, names[i]);
+
+ apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(apicid));
+ apic_write_around(APIC_ICR, APIC_DM_REMRD | regs[i]);
+
+ timeout = 0;
+ do {
+ udelay(100);
+ status = apic_read(APIC_ICR) & APIC_ICR_RR_MASK;
+ } while (status == APIC_ICR_RR_INPROG && timeout++ < 1000);
+
+ switch (status) {
+ case APIC_ICR_RR_VALID:
+ status = apic_read(APIC_RRR);
+ printk("%08x\n", status);
+ break;
+ default:
+ printk("failed\n");
+ }
+ }
+}
+#endif
+
static void __init do_boot_cpu (int apicid)
{
- unsigned long cfg;
struct task_struct *idle;
- unsigned long send_status, accept_status;
+ unsigned long send_status, accept_status, boot_status, maxlvt;
int timeout, num_starts, j, cpu;
unsigned long start_eip;
@@ -527,7 +560,7 @@ static void __init do_boot_cpu (int apicid)
start_eip = setup_trampoline();
/* So we see what's up */
- printk("Booting processor %d eip %lx\n", cpu, start_eip);
+ printk("Booting processor %d/%d eip %lx\n", cpu, apicid, start_eip);
stack_start.esp = (void *) (1024 + PAGE_SIZE + (char *)idle);
/*
@@ -549,16 +582,17 @@ static void __init do_boot_cpu (int apicid)
* Be paranoid about clearing APIC errors.
*/
if (APIC_INTEGRATED(apic_version[apicid])) {
- apic_readaround(APIC_SPIV);
+ apic_read_around(APIC_SPIV);
apic_write(APIC_ESR, 0);
- accept_status = (apic_read(APIC_ESR) & 0xEF);
+ apic_read(APIC_ESR);
}
/*
* Status is now clean
*/
- send_status = 0;
+ send_status = 0;
accept_status = 0;
+ boot_status = 0;
/*
* Starting actual IPI sequence...
@@ -567,37 +601,41 @@ static void __init do_boot_cpu (int apicid)
Dprintk("Asserting INIT.\n");
/*
- * Turn INIT on
- */
- cfg = apic_read(APIC_ICR2);
- cfg &= 0x00FFFFFF;
-
- /*
- * Target chip
+ * Turn INIT on target chip
*/
- apic_write(APIC_ICR2, cfg | SET_APIC_DEST_FIELD(apicid));
+ apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(apicid));
/*
* Send IPI
*/
- cfg = apic_read(APIC_ICR);
- cfg &= ~0xCDFFF;
- cfg |= (APIC_DEST_LEVELTRIG | APIC_DEST_ASSERT | APIC_DEST_DM_INIT);
- apic_write(APIC_ICR, cfg);
+ apic_write_around(APIC_ICR, APIC_INT_LEVELTRIG | APIC_INT_ASSERT
+ | APIC_DM_INIT);
+
+ Dprintk("Waiting for send to finish...\n");
+ timeout = 0;
+ do {
+ Dprintk("+");
+ udelay(100);
+ send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY;
+ } while (send_status && (timeout++ < 1000));
+
+ mdelay(10);
- udelay(200);
Dprintk("Deasserting INIT.\n");
/* Target chip */
- cfg = apic_read(APIC_ICR2);
- cfg &= 0x00FFFFFF;
- apic_write(APIC_ICR2, cfg|SET_APIC_DEST_FIELD(apicid));
+ apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(apicid));
/* Send IPI */
- cfg = apic_read(APIC_ICR);
- cfg &= ~0xCDFFF;
- cfg |= (APIC_DEST_LEVELTRIG | APIC_DEST_DM_INIT);
- apic_write(APIC_ICR, cfg);
+ apic_write_around(APIC_ICR, APIC_INT_LEVELTRIG | APIC_DM_INIT);
+
+ Dprintk("Waiting for send to finish...\n");
+ timeout = 0;
+ do {
+ Dprintk("+");
+ udelay(100);
+ send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY;
+ } while (send_status && (timeout++ < 1000));
/*
* Should we send STARTUP IPIs ?
@@ -616,9 +654,11 @@ static void __init do_boot_cpu (int apicid)
*/
Dprintk("#startup loops: %d.\n", num_starts);
+ maxlvt = get_maxlvt();
+
for (j = 1; j <= num_starts; j++) {
Dprintk("Sending STARTUP #%d.\n",j);
- apic_readaround(APIC_SPIV);
+ apic_read_around(APIC_SPIV);
apic_write(APIC_ESR, 0);
apic_read(APIC_ESR);
Dprintk("After apic_write.\n");
@@ -628,17 +668,12 @@ static void __init do_boot_cpu (int apicid)
*/
/* Target chip */
- cfg = apic_read(APIC_ICR2);
- cfg &= 0x00FFFFFF;
- apic_write(APIC_ICR2, cfg | SET_APIC_DEST_FIELD(apicid));
+ apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(apicid));
/* Boot on the stack */
- cfg = apic_read(APIC_ICR);
- cfg &= ~0xCDFFF;
- cfg |= (APIC_DEST_DM_STARTUP | (start_eip >> 12));
-
/* Kick the second */
- apic_write(APIC_ICR, cfg);
+ apic_write_around(APIC_ICR, APIC_DM_STARTUP
+ | (start_eip >> 12));
Dprintk("Startup point 1.\n");
@@ -647,13 +682,20 @@ static void __init do_boot_cpu (int apicid)
do {
Dprintk("+");
udelay(100);
- send_status = apic_read(APIC_ICR) & 0x1000;
+ send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY;
} while (send_status && (timeout++ < 1000));
/*
* Give the other CPU some time to accept the IPI.
*/
udelay(200);
+ /*
+ * Due to the Pentium erratum 3AP.
+ */
+ if (maxlvt > 3) {
+ apic_read_around(APIC_SPIV);
+ apic_write(APIC_ESR, 0);
+ }
accept_status = (apic_read(APIC_ESR) & 0xEF);
if (send_status || accept_status)
break;
@@ -676,7 +718,7 @@ static void __init do_boot_cpu (int apicid)
/*
* Wait 5s total for a response
*/
- for (timeout = 0; timeout < 1000000000; timeout++) {
+ for (timeout = 0; timeout < 50000; timeout++) {
if (test_bit(cpu, &cpu_callin_map))
break; /* It has booted */
udelay(100);
@@ -687,15 +729,22 @@ static void __init do_boot_cpu (int apicid)
Dprintk("OK.\n");
printk("CPU%d: ", cpu);
print_cpu_info(&cpu_data[cpu]);
+ Dprintk("CPU has booted.\n");
} else {
+ boot_status = 1;
if (*((volatile unsigned char *)phys_to_virt(8192))
- == 0xA5) /* trampoline code not run */
+ == 0xA5)
+ /* trampoline started but...? */
printk("Stuck ??\n");
else
- printk("CPU booted but not responding.\n");
+ /* trampoline code not run */
+ printk("Not responding.\n");
+#if APIC_DEBUG
+ inquire_remote_apic(apicid);
+#endif
}
- Dprintk("CPU has booted.\n");
- } else {
+ }
+ if (send_status || accept_status || boot_status) {
x86_cpu_to_apicid[cpu] = -1;
x86_apicid_to_cpu[apicid] = -1;
cpucount--;
@@ -858,6 +907,7 @@ void __init smp_boot_cpus(void)
Dprintk("Getting LVT1: %x\n", reg);
}
+ connect_bsp_APIC();
setup_local_APIC();
if (GET_APIC_ID(apic_read(APIC_ID)) != boot_cpu_id)
@@ -877,7 +927,7 @@ void __init smp_boot_cpus(void)
if (!(phys_cpu_present_map & (1 << apicid)))
continue;
- if ((max_cpus >= 0) && (max_cpus < cpucount+1))
+ if ((max_cpus >= 0) && (max_cpus <= cpucount+1))
continue;
do_boot_cpu(apicid);
@@ -934,7 +984,6 @@ void __init smp_boot_cpus(void)
printk(KERN_WARNING "WARNING: SMP operation may be unreliable with B stepping processors.\n");
Dprintk("Boot done.\n");
- cache_APIC_registers();
#ifndef CONFIG_VISWS
/*
* Here we can be sure that there is an IO-APIC in the system. Let's
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index 3a7004970..e25f50cfd 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -696,7 +696,7 @@ static void __init set_call_gate(void *a, void *addr)
((limit) & 0x0ffff); }
#define _set_tssldt_desc(n,addr,limit,type) \
-__asm__ __volatile__ ("movw %3,0(%2)\n\t" \
+__asm__ __volatile__ ("movw %w3,0(%2)\n\t" \
"movw %%ax,2(%2)\n\t" \
"rorl $16,%%eax\n\t" \
"movb %%al,4(%2)\n\t" \
diff --git a/arch/i386/kernel/visws_apic.c b/arch/i386/kernel/visws_apic.c
index be80cd628..288f83e8f 100644
--- a/arch/i386/kernel/visws_apic.c
+++ b/arch/i386/kernel/visws_apic.c
@@ -376,7 +376,7 @@ void init_VISWS_APIC_irqs(void)
for (i = 0; i < 16; i++) {
irq_desc[i].status = IRQ_DISABLED;
irq_desc[i].action = 0;
- irq_desc[i].depth = 0;
+ irq_desc[i].depth = 1;
/*
* Cobalt IRQs are mapped to standard ISA
diff --git a/arch/i386/lib/delay.c b/arch/i386/lib/delay.c
index ca5eeb796..89e7940ad 100644
--- a/arch/i386/lib/delay.c
+++ b/arch/i386/lib/delay.c
@@ -10,11 +10,12 @@
* we have to worry about.
*/
+#include <linux/config.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <asm/delay.h>
-#ifdef __SMP__
+#ifdef CONFIG_SMP
#include <asm/smp.h>
#endif
diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c
index 21c9cadff..2f030f306 100644
--- a/arch/i386/mm/fault.c
+++ b/arch/i386/mm/fault.c
@@ -51,7 +51,7 @@ good_area:
start &= PAGE_MASK;
for (;;) {
- if (handle_mm_fault(current, vma, start, 1) <= 0)
+ if (handle_mm_fault(current->mm, vma, start, 1) <= 0)
goto bad_area;
if (!size)
break;
@@ -193,7 +193,7 @@ good_area:
* the fault.
*/
{
- int fault = handle_mm_fault(tsk, vma, address, write);
+ int fault = handle_mm_fault(mm, vma, address, write);
if (fault < 0)
goto out_of_memory;
if (!fault)
diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile
index 3ace288ef..897bca8e7 100644
--- a/arch/ia64/Makefile
+++ b/arch/ia64/Makefile
@@ -9,6 +9,7 @@
#
NM := $(CROSS_COMPILE)nm -B
+AWK := awk
LINKFLAGS = -static -T arch/$(ARCH)/vmlinux.lds
# next line is for HP compiler backend:
@@ -16,10 +17,10 @@ LINKFLAGS = -static -T arch/$(ARCH)/vmlinux.lds
# The next line is needed when compiling with the July snapshot of the Cygnus compiler:
#EXTRA = -D__GCC_DOESNT_KNOW_IN_REGS__
# next two lines are for the September snapshot of the Cygnus compiler:
-AFLAGS += -D__GCC_MULTIREG_RETVALS__
+AFLAGS += -D__GCC_MULTIREG_RETVALS__ -Wa,-x
EXTRA = -D__GCC_MULTIREG_RETVALS__
-CFLAGS := $(CFLAGS) -pipe $(EXTRA) -ffixed-r13 -mfixed-range=f10-f15,f32-f127
+CFLAGS := $(CFLAGS) -pipe $(EXTRA) -Wa,-x -ffixed-r13 -mfixed-range=f10-f15,f32-f127
ifdef CONFIG_IA64_GENERIC
CORE_FILES := arch/$(ARCH)/hp/hp.a \
@@ -34,14 +35,14 @@ ifdef CONFIG_IA64_GENERIC
else # !GENERIC
-ifeq ($(CONFIG_IA64_HP_SIM),y)
+ifdef CONFIG_IA64_HP_SIM
SUBDIRS := arch/$(ARCH)/hp \
$(SUBDIRS)
CORE_FILES := arch/$(ARCH)/hp/hp.a \
$(CORE_FILES)
endif
-ifeq ($(CONFIG_IA64_SGI_SN1_SIM),y)
+ifdef CONFIG_IA64_SGI_SN1_SIM
SUBDIRS := arch/$(ARCH)/sn/sn1 \
arch/$(ARCH)/sn \
$(SUBDIRS)
@@ -49,14 +50,14 @@ ifeq ($(CONFIG_IA64_SGI_SN1_SIM),y)
$(CORE_FILES)
endif
-ifeq ($(CONFIG_IA64_SOFTSDV),y)
+ifdef CONFIG_IA64_SOFTSDV
SUBDIRS := arch/$(ARCH)/dig \
$(SUBDIRS)
CORE_FILES := arch/$(ARCH)/dig/dig.a \
$(CORE_FILES)
endif
-ifeq ($(CONFIG_IA64_DIG),y)
+ifdef CONFIG_IA64_DIG
SUBDIRS := arch/$(ARCH)/dig \
$(SUBDIRS)
CORE_FILES := arch/$(ARCH)/dig/dig.a \
@@ -65,16 +66,11 @@ endif
endif # !GENERIC
-ifeq ($(CONFIG_IA32_SUPPORT),y)
+ifdef CONFIG_IA32_SUPPORT
SUBDIRS := arch/$(ARCH)/ia32 $(SUBDIRS)
CORE_FILES := arch/$(ARCH)/ia32/ia32.o $(CORE_FILES)
endif
-ifdef CONFIG_KDB
- LIBS := $(LIBS) $(TOPDIR)/arch/$(ARCH)/kdb/kdb.a
- SUBDIRS := $(SUBDIRS) arch/$(ARCH)/kdb
-endif
-
HEAD := arch/$(ARCH)/kernel/head.o arch/ia64/kernel/init_task.o
SUBDIRS := arch/$(ARCH)/tools arch/$(ARCH)/kernel arch/$(ARCH)/mm arch/$(ARCH)/lib $(SUBDIRS)
diff --git a/arch/ia64/config.in b/arch/ia64/config.in
index b7cce3d73..2d1a11980 100644
--- a/arch/ia64/config.in
+++ b/arch/ia64/config.in
@@ -4,6 +4,8 @@ mainmenu_option next_comment
comment 'General setup'
define_bool CONFIG_IA64 y
+define_bool CONFIG_ITANIUM y # easy choice for now... ;-)
+
define_bool CONFIG_ISA n
define_bool CONFIG_SBUS n
@@ -25,7 +27,7 @@ if [ "$CONFIG_IA64_DIG" = "y" ]; then
bool ' Enable BigSur hacks' CONFIG_IA64_BIGSUR_HACKS
bool ' Enable Lion hacks' CONFIG_IA64_LION_HACKS
bool ' Emulate PAL/SAL/EFI firmware' CONFIG_IA64_FW_EMU
- bool ' Get PCI IRQ routing from firmware/ACPI' CONFIG_IA64_IRQ_ACPI
+ bool ' Enable IA64 Machine Check Abort' CONFIG_IA64_MCA
fi
if [ "$CONFIG_IA64_GENERIC" = "y" ]; then
@@ -185,10 +187,5 @@ bool 'Early printk support (requires VGA!)' CONFIG_IA64_EARLY_PRINTK
bool 'Turn on compare-and-exchange bug checking (slow!)' CONFIG_IA64_DEBUG_CMPXCHG
bool 'Turn on irq debug checks (slow!)' CONFIG_IA64_DEBUG_IRQ
bool 'Print possible IA64 hazards to console' CONFIG_IA64_PRINT_HAZARDS
-bool 'Built-in Kernel Debugger support' CONFIG_KDB
-if [ "$CONFIG_KDB" = "y" ]; then
- bool 'Compile the kernel with frame pointers' CONFIG_KDB_FRAMEPTR
- int 'KDB Kernel Symbol Table size?' CONFIG_KDB_STBSIZE 10000
-fi
endmenu
diff --git a/arch/ia64/defconfig b/arch/ia64/defconfig
index 12854f121..00a0e05b7 100644
--- a/arch/ia64/defconfig
+++ b/arch/ia64/defconfig
@@ -115,8 +115,8 @@ CONFIG_BLK_DEV_IDEDMA=y
CONFIG_IDEDMA_PCI_EXPERIMENTAL=y
# CONFIG_IDEDMA_PCI_WIP is not set
# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
-# CONFIG_BLK_DEV_AEC6210 is not set
-# CONFIG_AEC6210_TUNING is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_AEC62XX_TUNING is not set
# CONFIG_BLK_DEV_ALI15X3 is not set
# CONFIG_WDC_ALI15X3 is not set
# CONFIG_BLK_DEV_AMD7409 is not set
diff --git a/arch/ia64/dig/Makefile b/arch/ia64/dig/Makefile
index 8d0544ee5..f067606ee 100644
--- a/arch/ia64/dig/Makefile
+++ b/arch/ia64/dig/Makefile
@@ -15,7 +15,7 @@ all: dig.a
O_TARGET = dig.a
O_OBJS = iosapic.o setup.o
-ifeq ($(CONFIG_IA64_GENERIC),y)
+ifdef CONFIG_IA64_GENERIC
O_OBJS += machvec.o
endif
diff --git a/arch/ia64/dig/iosapic.c b/arch/ia64/dig/iosapic.c
index 4861aa2d9..9fd01063e 100644
--- a/arch/ia64/dig/iosapic.c
+++ b/arch/ia64/dig/iosapic.c
@@ -7,16 +7,20 @@
* Copyright (C) 1999-2000 David Mosberger-Tang <davidm@hpl.hp.com>
* Copyright (C) 1999 VA Linux Systems
* Copyright (C) 1999,2000 Walt Drummond <drummond@valinux.com>
+ *
+ * 00/04/19 D. Mosberger Rewritten to mirror more closely the x86 I/O APIC code.
+ * In particular, we now have separate handlers for edge
+ * and level triggered interrupts.
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/irq.h>
#include <linux/pci.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/string.h>
+#include <linux/irq.h>
#include <asm/io.h>
#include <asm/iosapic.h>
@@ -27,172 +31,19 @@
#undef DEBUG_IRQ_ROUTING
-/*
- * IRQ vectors 0..15 are treated as the legacy interrupts of the PC-AT
- * platform. No new drivers should ever ask for specific irqs, but we
- * provide compatibility here in case there is an old driver that does
- * ask for specific irqs (serial, keyboard, stuff like that). Since
- * IA-64 doesn't allow irq 0..15 to be used for external interrupts
- * anyhow, this in no way prevents us from doing the Right Thing
- * with new drivers.
- */
+static spinlock_t iosapic_lock = SPIN_LOCK_UNLOCKED;
+
struct iosapic_vector iosapic_vector[NR_IRQS] = {
[0 ... NR_IRQS-1] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }
};
-#ifndef CONFIG_IA64_IRQ_ACPI
-/*
- * Defines the default interrupt routing information for the LION platform
- * XXX - this information should be obtained from the ACPI and hardcoded since
- * we do not have ACPI AML support.
- */
-
-struct intr_routing_entry intr_routing[] = {
- {0,0,0,2,0,0,0,0},
- {0,0,1,1,0,0,0,0},
- {0,0,2,0xff,0,0,0,0},
- {0,0,3,3,0,0,0,0},
- {0,0,4,4,0,0,0,0},
- {0,0,5,5,0,0,0,0},
- {0,0,6,6,0,0,0,0},
- {0,0,7,7,0,0,0,0},
- {0,0,8,8,0,0,0,0},
- {0,0,9,9,0,0,0,0},
- {0,0,10,10,0,0,0,0},
- {0,0,11,11,0,0,0,0},
- {0,0,12,12,0,0,0,0},
- {0,0,13,13,0,0,0,0},
- {0,0,14,14,0,0,0,0},
- {0,0,15,15,0,0,0,0},
-#ifdef CONFIG_IA64_LION_HACKS
- {1, 0, 0x04, 16, 0, 0, 1, 1}, /* bus 0, device id 1, INTA */
- {1, 0, 0x05, 26, 0, 0, 1, 1}, /* bus 0, device id 1, INTB */
- {1, 0, 0x06, 36, 0, 0, 1, 1}, /* bus 0, device id 1, INTC */
- {1, 0, 0x07, 42, 0, 0, 1, 1}, /* bus 0, device id 1, INTD */
-
- {1, 0, 0x08, 17, 0, 0, 1, 1}, /* bus 0, device id 2, INTA */
- {1, 0, 0x09, 27, 0, 0, 1, 1}, /* bus 0, device id 2, INTB */
- {1, 0, 0x0a, 37, 0, 0, 1, 1}, /* bus 0, device id 2, INTC */
- {1, 0, 0x0b, 42, 0, 0, 1, 1}, /* bus 0, device id 2, INTD */
-
- {1, 0, 0x0f, 50, 0, 0, 1, 1}, /* bus 0, device id 3, INTD */
-
- {1, 0, 0x14, 51, 0, 0, 1, 1}, /* bus 0, device id 5, INTA */
-
- {1, 0, 0x18, 49, 0, 0, 1, 1}, /* bus 0, device id 6, INTA */
-
- {1, 1, 0x04, 18, 0, 0, 1, 1}, /* bus 1, device id 1, INTA */
- {1, 1, 0x05, 28, 0, 0, 1, 1}, /* bus 1, device id 1, INTB */
- {1, 1, 0x06, 38, 0, 0, 1, 1}, /* bus 1, device id 1, INTC */
- {1, 1, 0x07, 43, 0, 0, 1, 1}, /* bus 1, device id 1, INTD */
-
- {1, 1, 0x08, 48, 0, 0, 1, 1}, /* bus 1, device id 2, INTA */
-
- {1, 1, 0x0c, 19, 0, 0, 1, 1}, /* bus 1, device id 3, INTA */
- {1, 1, 0x0d, 29, 0, 0, 1, 1}, /* bus 1, device id 3, INTB */
- {1, 1, 0x0e, 38, 0, 0, 1, 1}, /* bus 1, device id 3, INTC */
- {1, 1, 0x0f, 44, 0, 0, 1, 1}, /* bus 1, device id 3, INTD */
-
- {1, 1, 0x10, 20, 0, 0, 1, 1}, /* bus 1, device id 4, INTA */
- {1, 1, 0x11, 30, 0, 0, 1, 1}, /* bus 1, device id 4, INTB */
- {1, 1, 0x12, 39, 0, 0, 1, 1}, /* bus 1, device id 4, INTC */
- {1, 1, 0x13, 45, 0, 0, 1, 1}, /* bus 1, device id 4, INTD */
-
- {1, 2, 0x04, 21, 0, 0, 1, 1}, /* bus 2, device id 1, INTA */
- {1, 2, 0x05, 31, 0, 0, 1, 1}, /* bus 2, device id 1, INTB */
- {1, 2, 0x06, 39, 0, 0, 1, 1}, /* bus 2, device id 1, INTC */
- {1, 2, 0x07, 45, 0, 0, 1, 1}, /* bus 2, device id 1, INTD */
-
- {1, 2, 0x08, 22, 0, 0, 1, 1}, /* bus 2, device id 2, INTA */
- {1, 2, 0x09, 32, 0, 0, 1, 1}, /* bus 2, device id 2, INTB */
- {1, 2, 0x0a, 40, 0, 0, 1, 1}, /* bus 2, device id 2, INTC */
- {1, 2, 0x0b, 46, 0, 0, 1, 1}, /* bus 2, device id 2, INTD */
-
- {1, 2, 0x0c, 23, 0, 0, 1, 1}, /* bus 2, device id 3, INTA */
- {1, 2, 0x0d, 33, 0, 0, 1, 1}, /* bus 2, device id 3, INTB */
- {1, 2, 0x0e, 40, 0, 0, 1, 1}, /* bus 2, device id 3, INTC */
- {1, 2, 0x0f, 46, 0, 0, 1, 1}, /* bus 2, device id 3, INTD */
-
- {1, 3, 0x04, 24, 0, 0, 1, 1}, /* bus 3, device id 1, INTA */
- {1, 3, 0x05, 34, 0, 0, 1, 1}, /* bus 3, device id 1, INTB */
- {1, 3, 0x06, 41, 0, 0, 1, 1}, /* bus 3, device id 1, INTC */
- {1, 3, 0x07, 47, 0, 0, 1, 1}, /* bus 3, device id 1, INTD */
-
- {1, 3, 0x08, 25, 0, 0, 1, 1}, /* bus 3, device id 2, INTA */
- {1, 3, 0x09, 35, 0, 0, 1, 1}, /* bus 3, device id 2, INTB */
- {1, 3, 0x0a, 41, 0, 0, 1, 1}, /* bus 3, device id 2, INTC */
- {1, 3, 0x0b, 47, 0, 0, 1, 1}, /* bus 3, device id 2, INTD */
-#else
- /*
- * BigSur platform, bus 0, device 1,2,4 and bus 1 device 0-3
- */
- {1,1,0x0,19,0,0,1,1}, /* bus 1, device id 0, INTA */
- {1,1,0x1,18,0,0,1,1}, /* bus 1, device id 0, INTB */
- {1,1,0x2,17,0,0,1,1}, /* bus 1, device id 0, INTC */
- {1,1,0x3,16,0,0,1,1}, /* bus 1, device id 0, INTD */
-
- {1,1,0x4,23,0,0,1,1}, /* bus 1, device id 1, INTA */
- {1,1,0x5,22,0,0,1,1}, /* bus 1, device id 1, INTB */
- {1,1,0x6,21,0,0,1,1}, /* bus 1, device id 1, INTC */
- {1,1,0x7,20,0,0,1,1}, /* bus 1, device id 1, INTD */
-
- {1,1,0x8,27,0,0,1,1}, /* bus 1, device id 2, INTA */
- {1,1,0x9,26,0,0,1,1}, /* bus 1, device id 2, INTB */
- {1,1,0xa,25,0,0,1,1}, /* bus 1, device id 2, INTC */
- {1,1,0xb,24,0,0,1,1}, /* bus 1, device id 2, INTD */
-
- {1,1,0xc,31,0,0,1,1}, /* bus 1, device id 3, INTA */
- {1,1,0xd,30,0,0,1,1}, /* bus 1, device id 3, INTB */
- {1,1,0xe,29,0,0,1,1}, /* bus 1, device id 3, INTC */
- {1,1,0xf,28,0,0,1,1}, /* bus 1, device id 3, INTD */
-
- {1,0,0x4,35,0,0,1,1}, /* bus 0, device id 1, INTA */
- {1,0,0x5,34,0,0,1,1}, /* bus 0, device id 1, INTB */
- {1,0,0x6,33,0,0,1,1}, /* bus 0, device id 1, INTC */
- {1,0,0x7,32,0,0,1,1}, /* bus 0, device id 1, INTD */
-
- {1,0,0x8,39,0,0,1,1}, /* bus 0, device id 2, INTA */
- {1,0,0x9,38,0,0,1,1}, /* bus 0, device id 2, INTB */
- {1,0,0xa,37,0,0,1,1}, /* bus 0, device id 2, INTC */
- {1,0,0xb,36,0,0,1,1}, /* bus 0, device id 2, INTD */
-
- {1,0,0x10,43,0,0,1,1}, /* bus 0, device id 4, INTA */
- {1,0,0x11,42,0,0,1,1}, /* bus 0, device id 4, INTB */
- {1,0,0x12,41,0,0,1,1}, /* bus 0, device id 4, INTC */
- {1,0,0x13,40,0,0,1,1}, /* bus 0, device id 4, INTD */
-
- {1,0,0x14,17,0,0,1,1}, /* bus 0, device id 5, INTA */
- {1,0,0x18,18,0,0,1,1}, /* bus 0, device id 6, INTA */
- {1,0,0x1c,19,0,0,1,1}, /* bus 0, device id 7, INTA */
-#endif
- {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
-};
-
-int
-iosapic_get_PCI_irq_vector(int bus, int slot, int pci_pin)
-{
- int i = -1;
-
- while (intr_routing[++i].srcbus != 0xff) {
- if (intr_routing[i].srcbus == BUS_PCI) {
- if ((intr_routing[i].srcbusirq == ((slot << 2) | pci_pin))
- && (intr_routing[i].srcbusno == bus)) {
- return(intr_routing[i].iosapic_pin);
- }
- }
- }
- return -1;
-}
-
-#else /* CONFIG_IA64_IRQ_ACPI */
-
/*
* find the IRQ in the IOSAPIC map for the PCI device on bus/slot/pin
*/
int
-iosapic_get_PCI_irq_vector(int bus, int slot, int pci_pin)
+iosapic_get_PCI_irq_vector (int bus, int slot, int pci_pin)
{
- int i;
+ int i;
for (i = 0; i < NR_IRQS; i++) {
if ((iosapic_bustype(i) == BUS_PCI) &&
@@ -201,17 +52,15 @@ iosapic_get_PCI_irq_vector(int bus, int slot, int pci_pin)
return i;
}
}
-
return -1;
}
-#endif /* !CONFIG_IA64_IRQ_ACPI */
static void
set_rte (unsigned long iosapic_addr, int entry, int pol, int trigger, int delivery,
long dest, int vector)
{
- int low32;
- int high32;
+ u32 low32;
+ u32 high32;
low32 = ((pol << IO_SAPIC_POLARITY_SHIFT) |
(trigger << IO_SAPIC_TRIGGER_SHIFT) |
@@ -221,81 +70,137 @@ set_rte (unsigned long iosapic_addr, int entry, int pol, int trigger, int delive
/* dest contains both id and eid */
high32 = (dest << IO_SAPIC_DEST_SHIFT);
- /*
- * program the rte
- */
writel(IO_SAPIC_RTE_HIGH(entry), iosapic_addr + IO_SAPIC_REG_SELECT);
writel(high32, iosapic_addr + IO_SAPIC_WINDOW);
writel(IO_SAPIC_RTE_LOW(entry), iosapic_addr + IO_SAPIC_REG_SELECT);
writel(low32, iosapic_addr + IO_SAPIC_WINDOW);
}
+static void
+nop (unsigned int irq)
+{
+ /* do nothing... */
+}
static void
-enable_pin (unsigned int pin, unsigned long iosapic_addr)
+mask_irq (unsigned int irq)
{
- int low32;
+ unsigned long flags, iosapic_addr = iosapic_addr(irq);
+ u32 low32;
- writel(IO_SAPIC_RTE_LOW(pin), iosapic_addr + IO_SAPIC_REG_SELECT);
- low32 = readl(iosapic_addr + IO_SAPIC_WINDOW);
+ spin_lock_irqsave(&iosapic_lock, flags);
+ {
+ writel(IO_SAPIC_RTE_LOW(iosapic_pin(irq)), iosapic_addr + IO_SAPIC_REG_SELECT);
+ low32 = readl(iosapic_addr + IO_SAPIC_WINDOW);
- low32 &= ~(1 << IO_SAPIC_MASK_SHIFT); /* Zero only the mask bit */
- writel(low32, iosapic_addr + IO_SAPIC_WINDOW);
+ low32 |= (1 << IO_SAPIC_MASK_SHIFT); /* Zero only the mask bit */
+ writel(low32, iosapic_addr + IO_SAPIC_WINDOW);
+ }
+ spin_unlock_irqrestore(&iosapic_lock, flags);
}
-
static void
-disable_pin (unsigned int pin, unsigned long iosapic_addr)
+unmask_irq (unsigned int irq)
{
- int low32;
+ unsigned long flags, iosapic_addr = iosapic_addr(irq);
+ u32 low32;
- writel(IO_SAPIC_RTE_LOW(pin), iosapic_addr + IO_SAPIC_REG_SELECT);
- low32 = readl(iosapic_addr + IO_SAPIC_WINDOW);
+ spin_lock_irqsave(&iosapic_lock, flags);
+ {
+ writel(IO_SAPIC_RTE_LOW(iosapic_pin(irq)), iosapic_addr + IO_SAPIC_REG_SELECT);
+ low32 = readl(iosapic_addr + IO_SAPIC_WINDOW);
- low32 |= (1 << IO_SAPIC_MASK_SHIFT); /* Set only the mask bit */
- writel(low32, iosapic_addr + IO_SAPIC_WINDOW);
+ low32 &= ~(1 << IO_SAPIC_MASK_SHIFT); /* Zero only the mask bit */
+ writel(low32, iosapic_addr + IO_SAPIC_WINDOW);
+ }
+ spin_unlock_irqrestore(&iosapic_lock, flags);
+}
+
+
+static void
+iosapic_set_affinity (unsigned int irq, unsigned long mask)
+{
+ printk("iosapic_set_affinity: not implemented yet\n");
}
-#define iosapic_shutdown_irq iosapic_disable_irq
+/*
+ * Handlers for level-triggered interrupts.
+ */
static unsigned int
-iosapic_startup_irq (unsigned int irq)
+iosapic_startup_level_irq (unsigned int irq)
{
- int pin;
-
- pin = iosapic_pin(irq);
- if (pin < 0)
- /* happens during irq auto probing... */
- return 0;
- set_rte(iosapic_addr(irq), pin, iosapic_polarity(irq), iosapic_trigger(irq),
- iosapic_dmode(irq), (ia64_get_lid() >> 16) & 0xffff, irq);
- enable_pin(pin, iosapic_addr(irq));
+ unmask_irq(irq);
return 0;
}
static void
-iosapic_enable_irq (unsigned int irq)
+iosapic_end_level_irq (unsigned int irq)
{
- int pin = iosapic_pin(irq);
+ writel(irq, iosapic_addr(irq) + IO_SAPIC_EOI);
+}
- if (pin < 0)
- /* happens during irq auto probing... */
- return;
- enable_pin(pin, iosapic_addr(irq));
+#define iosapic_shutdown_level_irq mask_irq
+#define iosapic_enable_level_irq unmask_irq
+#define iosapic_disable_level_irq mask_irq
+#define iosapic_ack_level_irq nop
+
+struct hw_interrupt_type irq_type_iosapic_level = {
+ typename: "IO-SAPIC-level",
+ startup: iosapic_startup_level_irq,
+ shutdown: iosapic_shutdown_level_irq,
+ enable: iosapic_enable_level_irq,
+ disable: iosapic_disable_level_irq,
+ ack: iosapic_ack_level_irq,
+ end: iosapic_end_level_irq,
+ set_affinity: iosapic_set_affinity
+};
+
+/*
+ * Handlers for edge-triggered interrupts.
+ */
+
+static unsigned int
+iosapic_startup_edge_irq (unsigned int irq)
+{
+ unmask_irq(irq);
+ /*
+ * IOSAPIC simply drops interrupts pended while the
+ * corresponding pin was masked, so we can't know if an
+ * interrupt is pending already. Let's hope not...
+ */
+ return 0;
}
static void
-iosapic_disable_irq (unsigned int irq)
+iosapic_ack_edge_irq (unsigned int irq)
{
- int pin = iosapic_pin(irq);
-
- if (pin < 0)
- return;
- disable_pin(pin, iosapic_addr(irq));
+ /*
+ * Once we have recorded IRQ_PENDING already, we can mask the
+ * interrupt for real. This prevents IRQ storms from unhandled
+ * devices.
+ */
+ if ((irq_desc[irq].status & (IRQ_PENDING | IRQ_DISABLED)) == (IRQ_PENDING | IRQ_DISABLED))
+ mask_irq(irq);
}
+#define iosapic_enable_edge_irq unmask_irq
+#define iosapic_disable_edge_irq nop
+#define iosapic_end_edge_irq nop
+
+struct hw_interrupt_type irq_type_iosapic_edge = {
+ typename: "IO-SAPIC-edge",
+ startup: iosapic_startup_edge_irq,
+ shutdown: iosapic_disable_edge_irq,
+ enable: iosapic_enable_edge_irq,
+ disable: iosapic_disable_edge_irq,
+ ack: iosapic_ack_edge_irq,
+ end: iosapic_end_edge_irq,
+ set_affinity: iosapic_set_affinity
+};
+
unsigned int
-iosapic_version(unsigned long base_addr)
+iosapic_version (unsigned long base_addr)
{
/*
* IOSAPIC Version Register return 32 bit structure like:
@@ -310,99 +215,19 @@ iosapic_version(unsigned long base_addr)
return readl(IO_SAPIC_WINDOW + base_addr);
}
-static void
-iosapic_ack_irq (unsigned int irq)
-{
-}
-
-static void
-iosapic_end_irq (unsigned int irq)
-{
- if (iosapic_trigger(irq) == IO_SAPIC_LEVEL) /* ACK Level trigger interrupts */
- writel(irq, iosapic_addr(irq) + IO_SAPIC_EOI);
-}
-
-static void
-iosapic_set_affinity (unsigned int irq, unsigned long mask)
-{
- printk("iosapic_set_affinity: not implemented yet\n");
-}
-
void
iosapic_init (unsigned long address)
{
- int i;
-#ifdef CONFIG_IA64_IRQ_ACPI
+ struct hw_interrupt_type *irq_type;
struct pci_vector_struct *vectors;
- int irq;
-#else
- int vector;
-#endif
+ int i, irq;
- /*
- * Disable the compatibility mode interrupts (8259 style), needs IN/OUT support
- * enabled.
- */
- outb(0xff, 0xA1);
- outb(0xff, 0x21);
-
-#if defined(CONFIG_IA64_SOFTSDV_HACKS)
- memset(iosapic_vector, 0x0, sizeof(iosapic_vector));
- for (i = 0; i < NR_IRQS; i++) {
- iosapic_pin(i) = 0xff;
- iosapic_addr(i) = (unsigned long) ioremap(address, 0);
- }
- /* XXX this should come from systab or some such: */
-# if 0
- /* this doesn't look right --davidm 00/03/07 */
- iosapic_pin(TIMER_IRQ) = 5; /* System Clock Interrupt */
-# endif
- iosapic_pin(0x40) = 3; /* Keyboard */
- iosapic_pin(0x92) = 9; /* COM1 Serial Port */
- iosapic_pin(0x80) = 4; /* Periodic Interrupt */
- iosapic_pin(0xc0) = 2; /* Mouse */
- iosapic_pin(0xe0) = 1; /* IDE Disk */
- iosapic_pin(0xf0) = 6; /* E-IDE CDROM */
- iosapic_pin(0xa0) = 10; /* Real PCI Interrupt */
-#elif !defined(CONFIG_IA64_IRQ_ACPI)
- /*
- * For systems where the routing info in ACPI is
- * unavailable/wrong, use the intr_routing information to
- * initialize the iosapic array
- */
- i = -1;
- while (intr_routing[++i].srcbus != 0xff) {
- if (intr_routing[i].srcbus == BUS_ISA) {
- vector = isa_irq_to_vector(intr_routing[i].srcbusirq);
- } else if (intr_routing[i].srcbus == BUS_PCI) {
- vector = intr_routing[i].iosapic_pin;
- } else {
- printk("unknown bus type %d for intr_routing[%d]\n",
- intr_routing[i].srcbus, i);
- continue;
- }
- iosapic_pin(vector) = intr_routing[i].iosapic_pin;
- iosapic_dmode(vector) = intr_routing[i].mode;
- iosapic_polarity(vector) = intr_routing[i].polarity;
- iosapic_trigger(vector) = intr_routing[i].trigger;
-# ifdef DEBUG_IRQ_ROUTING
- printk("irq[0x%x(0x%x)]:0x%x, %d, %d, %d\n", vector, intr_routing[i].srcbusirq,
- iosapic_pin(vector), iosapic_dmode(vector), iosapic_polarity(vector),
- iosapic_trigger(vector));
-# endif
- }
-#else /* !defined(CONFIG_IA64_SOFTSDV_HACKS) && defined(CONFIG_IA64_IRQ_ACPI) */
/*
- * Map the legacy ISA devices into the IOAPIC data; We'll override these
- * later with data from the ACPI Interrupt Source Override table.
- *
- * Huh, the Lion w/ FPSWA firmware has entries for _all_ of the legacy IRQs,
- * including those that are not different from PC/AT standard. I don't know
- * if this is a bug in the other firmware or not. I'm going to leave this code
- * here, so that this works on BigSur but will go ask Intel. --wfd 2000-Jan-19
- *
+ * Map the legacy ISA devices into the IOSAPIC data. Some of
+ * these may get reprogrammed later on with data from the ACPI
+ * Interrupt Source Override table.
*/
- for (i =0 ; i < 16; i++) {
+ for (i = 0; i < 16; i++) {
irq = isa_irq_to_vector(i);
iosapic_pin(irq) = i;
iosapic_bus(irq) = BUS_ISA;
@@ -445,41 +270,37 @@ iosapic_init (unsigned long address)
irq, iosapic_pin(irq));
#endif
}
-#endif /* !CONFIG_IA64_IRQ_ACPI */
-}
-struct hw_interrupt_type irq_type_iosapic = {
- typename: "IOSAPIC",
- startup: iosapic_startup_irq,
- shutdown: iosapic_shutdown_irq,
- enable: iosapic_enable_irq,
- disable: iosapic_disable_irq,
- ack: iosapic_ack_irq,
- end: iosapic_end_irq,
- set_affinity: iosapic_set_affinity
-};
+ for (i = 0; i < NR_IRQS; ++i) {
+ if (iosapic_pin(i) != -1) {
+ if (iosapic_trigger(i) == IO_SAPIC_LEVEL)
+ irq_type = &irq_type_iosapic_level;
+ else
+ irq_type = &irq_type_iosapic_edge;
+ if (irq_desc[i].handler != &no_irq_type)
+ printk("dig_irq_init: warning: changing vector %d from %s to %s\n",
+ i, irq_desc[i].handler->typename,
+ irq_type->typename);
+ irq_desc[i].handler = irq_type;
+
+ /* program the IOSAPIC routing table: */
+ set_rte(iosapic_addr(i), iosapic_pin(i), iosapic_polarity(i),
+ iosapic_trigger(i), iosapic_dmode(i),
+ (ia64_get_lid() >> 16) & 0xffff, i);
+ }
+ }
+}
void
dig_irq_init (void)
{
- int i;
-
/*
- * Claim all non-legacy irq vectors as ours unless they're
- * claimed by someone else already (e.g., timer or IPI are
- * handled internally).
+ * Disable the compatibility mode interrupts (8259 style), needs IN/OUT support
+ * enabled.
*/
-#if 0
- for (i = IA64_MIN_VECTORED_IRQ; i <= IA64_MAX_VECTORED_IRQ; ++i) {
- if (irq_desc[i].handler == &no_irq_type)
- irq_desc[i].handler = &irq_type_iosapic;
- }
-#else
- for (i = 0; i <= IA64_MAX_VECTORED_IRQ; ++i) {
- if (irq_desc[i].handler == &no_irq_type)
- irq_desc[i].handler = &irq_type_iosapic;
- }
-#endif
+ outb(0xff, 0xA1);
+ outb(0xff, 0x21);
+
#ifndef CONFIG_IA64_DIG
iosapic_init(IO_SAPIC_DEFAULT_ADDR);
#endif
diff --git a/arch/ia64/dig/setup.c b/arch/ia64/dig/setup.c
index 6ae40319d..133f817a1 100644
--- a/arch/ia64/dig/setup.c
+++ b/arch/ia64/dig/setup.c
@@ -47,17 +47,11 @@ dig_setup (char **cmdline_p)
unsigned int orig_x, orig_y, num_cols, num_rows, font_height;
/*
- * This assumes that the EFI partition is physical disk 1
- * partition 1 and the Linux root disk is physical disk 1
- * partition 2.
+ * Default to /dev/sda2. This assumes that the EFI partition
+ * is physical disk 1 partition 1 and the Linux root disk is
+ * physical disk 1 partition 2.
*/
-#ifdef CONFIG_IA64_LION_HACKS
- /* default to /dev/sda2 on Lion... */
ROOT_DEV = to_kdev_t(0x0802); /* default to second partition on first drive */
-#else
- /* default to /dev/dha2 on BigSur... */
- ROOT_DEV = to_kdev_t(0x0302); /* default to second partition on first drive */
-#endif
#ifdef CONFIG_SMP
init_smp_config();
diff --git a/arch/ia64/hp/Makefile b/arch/ia64/hp/Makefile
index 64899f4be..458269e0a 100644
--- a/arch/ia64/hp/Makefile
+++ b/arch/ia64/hp/Makefile
@@ -10,7 +10,7 @@ all: hp.a
O_TARGET = hp.a
O_OBJS = hpsim_console.o hpsim_irq.o hpsim_setup.o
-ifeq ($(CONFIG_IA64_GENERIC),y)
+ifdef CONFIG_IA64_GENERIC
O_OBJS += hpsim_machvec.o
endif
diff --git a/arch/ia64/ia32/Makefile b/arch/ia64/ia32/Makefile
index 82017941c..1b18cca58 100644
--- a/arch/ia64/ia32/Makefile
+++ b/arch/ia64/ia32/Makefile
@@ -10,7 +10,7 @@
all: ia32.o
O_TARGET := ia32.o
-O_OBJS := ia32_entry.o ia32_signal.o sys_ia32.o ia32_support.o binfmt_elf32.o
+O_OBJS := ia32_entry.o sys_ia32.o ia32_signal.o ia32_support.o ia32_traps.o binfmt_elf32.o
clean::
diff --git a/arch/ia64/ia32/binfmt_elf32.c b/arch/ia64/ia32/binfmt_elf32.c
index a99983681..6f702df14 100644
--- a/arch/ia64/ia32/binfmt_elf32.c
+++ b/arch/ia64/ia32/binfmt_elf32.c
@@ -134,6 +134,19 @@ void ia64_elf32_init(struct pt_regs *regs)
regs->cr_ipsr &= ~IA64_PSR_AC;
regs->loadrs = 0;
+ /*
+ * According to the ABI %edx points to an `atexit' handler.
+ * Since we don't have one we'll set it to 0 and initialize
+ * all the other registers just to make things more deterministic,
+ * ala the i386 implementation.
+ */
+ regs->r8 = 0; /* %eax */
+ regs->r11 = 0; /* %ebx */
+ regs->r9 = 0; /* %ecx */
+ regs->r10 = 0; /* %edx */
+ regs->r13 = 0; /* %ebp */
+ regs->r14 = 0; /* %esi */
+ regs->r15 = 0; /* %edi */
}
#undef STACK_TOP
diff --git a/arch/ia64/ia32/ia32_entry.S b/arch/ia64/ia32/ia32_entry.S
index bd7b0517b..ff27a02ce 100644
--- a/arch/ia64/ia32/ia32_entry.S
+++ b/arch/ia64/ia32/ia32_entry.S
@@ -1,14 +1,55 @@
#include <asm/offsets.h>
#include <asm/signal.h>
+ //
+ // Get possibly unaligned sigmask argument into an aligned
+ // kernel buffer
+ .text
+ .proc ia32_rt_sigsuspend
+ .global ia32_rt_sigsuspend
+ia32_rt_sigsuspend:
+
+ // We'll cheat and not do an alloc here since we are ultimately
+ // going to do a simple branch to the IA64 sys_rt_sigsuspend.
+ // r32 is still the first argument which is the signal mask.
+ // We copy this 4-byte aligned value to an 8-byte aligned buffer
+ // in the task structure and then jump to the IA64 code.
+
+ mov r8=r0 // no memory access errors yet
+ add r10=4,r32
+ ;;
+1:
+ ld4 r2=[r32] // get first half of sigmask
+ ld4 r3=[r10] // get second half of sigmask
+2:
+ cmp.lt p6,p0=r8,r0 // check memory access
+ ;;
+(p6) br.ret.sptk.many rp // it failed
+
+ adds r32=IA64_TASK_THREAD_SIGMASK_OFFSET,r13
+ adds r10=IA64_TASK_THREAD_SIGMASK_OFFSET+4,r13
+ ;;
+ st4 [r32]=r2
+ st4 [r10]=r3
+ br.cond.sptk.many sys_rt_sigsuspend
+
+ .section __ex_table,"a"
+ data4 @gprel(1b)
+ data4 (2b-1b)|1
+ .previous
+
+
+ .endp ia32_rt_sigsuspend
+
.global ia32_ret_from_syscall
- .proc ia64_ret_from_syscall
+ .proc ia32_ret_from_syscall
ia32_ret_from_syscall:
cmp.ge p6,p7=r8,r0 // syscall executed successfully?
adds r2=IA64_PT_REGS_R8_OFFSET+16,sp // r2 = &pt_regs.r8
;;
st8 [r2]=r8 // store return value in slot for r8
br.cond.sptk.few ia64_leave_kernel
+ .endp ia32_ret_from_syscall
//
// Invoke a system call, but do some tracing before and after the call.
@@ -35,10 +76,21 @@ ia32_trace_syscall:
.endp ia32_trace_syscall
.align 16
+ .global sys32_vfork
+ .proc sys32_vfork
+sys32_vfork:
+ alloc r16=ar.pfs,2,2,3,0;;
+ mov out0=IA64_CLONE_VFORK|IA64_CLONE_VM|SIGCHLD // out0 = clone_flags
+ br.cond.sptk.few .fork1 // do the work
+ .endp sys32_vfork
+
+ .align 16
.global sys32_fork
.proc sys32_fork
sys32_fork:
alloc r16=ar.pfs,2,2,3,0;;
+ mov out0=SIGCHLD // out0 = clone_flags
+.fork1:
movl r28=1f
mov loc1=rp
br.cond.sptk.many save_switch_stack
@@ -46,7 +98,6 @@ sys32_fork:
mov loc0=r16 // save ar.pfs across do_fork
adds out2=IA64_SWITCH_STACK_SIZE+16,sp
adds r2=IA64_SWITCH_STACK_SIZE+IA64_PT_REGS_R12_OFFSET+16,sp
- mov out0=SIGCHLD // out0 = clone_flags
;;
ld8 out1=[r2] // fetch usp from pt_regs.r12
br.call.sptk.few rp=do_fork
@@ -88,7 +139,7 @@ ia32_syscall_table:
data8 sys_setuid
data8 sys_getuid
data8 sys_ni_syscall /* sys_stime is not supported on IA64 */ /* 25 */
- data8 sys_ptrace
+ data8 sys32_ptrace
data8 sys32_alarm
data8 sys_ni_syscall
data8 sys_ni_syscall
@@ -105,7 +156,7 @@ ia32_syscall_table:
data8 sys_rmdir /* 40 */
data8 sys_dup
data8 sys32_pipe
- data8 sys_times
+ data8 sys32_times
data8 sys_ni_syscall /* old prof syscall holder */
data8 sys_brk /* 45 */
data8 sys_setgid
@@ -139,7 +190,7 @@ ia32_syscall_table:
data8 sys_sethostname
data8 sys32_setrlimit /* 75 */
data8 sys32_getrlimit
- data8 sys_getrusage
+ data8 sys32_getrusage
data8 sys32_gettimeofday
data8 sys32_settimeofday
data8 sys_getgroups /* 80 */
@@ -241,7 +292,7 @@ ia32_syscall_table:
data8 sys_rt_sigpending
data8 sys_rt_sigtimedwait
data8 sys_rt_sigqueueinfo
- data8 sys_rt_sigsuspend
+ data8 ia32_rt_sigsuspend
data8 sys_pread /* 180 */
data8 sys_pwrite
data8 sys_chown
diff --git a/arch/ia64/ia32/ia32_signal.c b/arch/ia64/ia32/ia32_signal.c
index 2c2c53741..83e6c9e61 100644
--- a/arch/ia64/ia32/ia32_signal.c
+++ b/arch/ia64/ia32/ia32_signal.c
@@ -94,7 +94,9 @@ setup_sigcontext_ia32(struct sigcontext_ia32 *sc, struct _fpstate_ia32 *fpstate,
err |= __put_user(tmp ? fpstate : NULL, &sc->fpstate);
/* non-iBCS2 extensions.. */
+#endif
err |= __put_user(mask, &sc->oldmask);
+#if 0
err |= __put_user(current->tss.cr2, &sc->cr2);
#endif
@@ -196,7 +198,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
return (void *)((esp - frame_size) & -8ul);
}
-static void
+static int
setup_frame_ia32(int sig, struct k_sigaction *ka, sigset_t *set,
struct pt_regs * regs)
{
@@ -247,20 +249,21 @@ setup_frame_ia32(int sig, struct k_sigaction *ka, sigset_t *set,
regs->eflags &= ~TF_MASK;
#endif
-#if 1
- printk("SIG deliver (%s:%d): sp=%p pc=%lx ra=%x\n",
- current->comm, current->pid, frame, regs->cr_iip, frame->pretcode);
+#if 0
+ printk("SIG deliver (%s:%d): sig=%d sp=%p pc=%lx ra=%x\n",
+ current->comm, current->pid, sig, frame, regs->cr_iip, frame->pretcode);
#endif
- return;
+ return 1;
give_sigsegv:
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
+ return 0;
}
-static void
+static int
setup_rt_frame_ia32(int sig, struct k_sigaction *ka, siginfo_t *info,
sigset_t *set, struct pt_regs * regs)
{
@@ -316,29 +319,29 @@ setup_rt_frame_ia32(int sig, struct k_sigaction *ka, siginfo_t *info,
regs->eflags &= ~TF_MASK;
#endif
-#if 1
+#if 0
printk("SIG deliver (%s:%d): sp=%p pc=%lx ra=%x\n",
current->comm, current->pid, frame, regs->cr_iip, frame->pretcode);
#endif
- return;
+ return 1;
give_sigsegv:
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
+ return 0;
}
-long
+int
ia32_setup_frame1 (int sig, struct k_sigaction *ka, siginfo_t *info,
sigset_t *set, struct pt_regs *regs)
{
/* Set up the stack frame */
if (ka->sa.sa_flags & SA_SIGINFO)
- setup_rt_frame_ia32(sig, ka, info, set, regs);
+ return(setup_rt_frame_ia32(sig, ka, info, set, regs));
else
- setup_frame_ia32(sig, ka, set, regs);
-
+ return(setup_frame_ia32(sig, ka, set, regs));
}
asmlinkage int
diff --git a/arch/ia64/ia32/ia32_traps.c b/arch/ia64/ia32/ia32_traps.c
new file mode 100644
index 000000000..de99a65b3
--- /dev/null
+++ b/arch/ia64/ia32/ia32_traps.c
@@ -0,0 +1,47 @@
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/ia32.h>
+#include <asm/ptrace.h>
+
+int
+ia32_exception (struct pt_regs *regs, unsigned long isr)
+{
+ struct siginfo siginfo;
+
+ switch ((isr >> 16) & 0xff) {
+ case 1:
+ case 2:
+ if (isr == 0)
+ siginfo.si_code = TRAP_TRACE;
+ else if (isr & 0x4)
+ siginfo.si_code = TRAP_BRANCH;
+ else
+ siginfo.si_code = TRAP_BRKPT;
+ break;
+
+ case 3:
+ siginfo.si_code = TRAP_BRKPT;
+ break;
+
+ case 0: /* Divide fault */
+ case 4: /* Overflow */
+ case 5: /* Bounds fault */
+ case 6: /* Invalid Op-code */
+ case 7: /* FP DNA */
+ case 8: /* Double Fault */
+ case 9: /* Invalid TSS */
+ case 11: /* Segment not present */
+ case 12: /* Stack fault */
+ case 13: /* General Protection Fault */
+ case 16: /* Pending FP error */
+ case 17: /* Alignment check */
+ case 19: /* SSE Numeric error */
+ default:
+ return -1;
+ }
+ siginfo.si_signo = SIGTRAP;
+ siginfo.si_errno = 0;
+ send_sig_info(SIGTRAP, &siginfo, current);
+ return 0;
+}
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c
index 00eca716d..2077abe93 100644
--- a/arch/ia64/ia32/sys_ia32.c
+++ b/arch/ia64/ia32/sys_ia32.c
@@ -58,32 +58,6 @@
#define A(__x) ((unsigned long)(__x))
#define AA(__x) ((unsigned long)(__x))
-/*
- * This is trivial, and on the face of it looks like it
- * could equally well be done in user mode.
- *
- * Not so, for quite unobvious reasons - register pressure.
- * In user mode vfork() cannot have a stack frame, and if
- * done by calling the "clone()" system call directly, you
- * do not have enough call-clobbered registers to hold all
- * the information you need.
- */
-asmlinkage int sys32_vfork(
-int dummy0,
-int dummy1,
-int dummy2,
-int dummy3,
-int dummy4,
-int dummy5,
-int dummy6,
-int dummy7,
-int stack)
-{
- struct pt_regs *regs = (struct pt_regs *)&stack;
-
- return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->r12, regs);
-}
-
static int
nargs(unsigned int arg, char **ap)
{
@@ -842,82 +816,6 @@ asmlinkage int old_select(struct sel_arg_struct *arg)
return sys32_select(a.n, a.inp, a.outp, a.exp, a.tvp);
}
-struct rusage32 {
- struct timeval32 ru_utime;
- struct timeval32 ru_stime;
- int ru_maxrss;
- int ru_ixrss;
- int ru_idrss;
- int ru_isrss;
- int ru_minflt;
- int ru_majflt;
- int ru_nswap;
- int ru_inblock;
- int ru_oublock;
- int ru_msgsnd;
- int ru_msgrcv;
- int ru_nsignals;
- int ru_nvcsw;
- int ru_nivcsw;
-};
-
-static int
-put_rusage (struct rusage32 *ru, struct rusage *r)
-{
- int err;
-
- err = put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec);
- err |= __put_user (r->ru_utime.tv_usec, &ru->ru_utime.tv_usec);
- err |= __put_user (r->ru_stime.tv_sec, &ru->ru_stime.tv_sec);
- err |= __put_user (r->ru_stime.tv_usec, &ru->ru_stime.tv_usec);
- err |= __put_user (r->ru_maxrss, &ru->ru_maxrss);
- err |= __put_user (r->ru_ixrss, &ru->ru_ixrss);
- err |= __put_user (r->ru_idrss, &ru->ru_idrss);
- err |= __put_user (r->ru_isrss, &ru->ru_isrss);
- err |= __put_user (r->ru_minflt, &ru->ru_minflt);
- err |= __put_user (r->ru_majflt, &ru->ru_majflt);
- err |= __put_user (r->ru_nswap, &ru->ru_nswap);
- err |= __put_user (r->ru_inblock, &ru->ru_inblock);
- err |= __put_user (r->ru_oublock, &ru->ru_oublock);
- err |= __put_user (r->ru_msgsnd, &ru->ru_msgsnd);
- err |= __put_user (r->ru_msgrcv, &ru->ru_msgrcv);
- err |= __put_user (r->ru_nsignals, &ru->ru_nsignals);
- err |= __put_user (r->ru_nvcsw, &ru->ru_nvcsw);
- err |= __put_user (r->ru_nivcsw, &ru->ru_nivcsw);
- return err;
-}
-
-extern asmlinkage int sys_wait4(pid_t pid,unsigned int * stat_addr,
- int options, struct rusage * ru);
-
-asmlinkage int
-sys32_wait4(__kernel_pid_t32 pid, unsigned int *stat_addr, int options,
- struct rusage32 *ru)
-{
- if (!ru)
- return sys_wait4(pid, stat_addr, options, NULL);
- else {
- struct rusage r;
- int ret;
- unsigned int status;
- mm_segment_t old_fs = get_fs();
-
- set_fs (KERNEL_DS);
- ret = sys_wait4(pid, stat_addr ? &status : NULL, options, &r);
- set_fs (old_fs);
- if (put_rusage (ru, &r)) return -EFAULT;
- if (stat_addr && put_user (status, stat_addr))
- return -EFAULT;
- return ret;
- }
-}
-
-asmlinkage int
-sys32_waitpid(__kernel_pid_t32 pid, unsigned int *stat_addr, int options)
-{
- return sys32_wait4(pid, stat_addr, options, NULL);
-}
-
struct timespec32 {
int tv_sec;
int tv_nsec;
@@ -1586,65 +1484,63 @@ do_sys32_semctl(int first, int second, int third, void *uptr)
{
union semun fourth;
u32 pad;
- int err = -EINVAL;
+ int err, err2;
+ struct semid64_ds s;
+ struct semid_ds32 *usp;
+ mm_segment_t old_fs;
if (!uptr)
- goto out;
+ return -EINVAL;
err = -EFAULT;
if (get_user (pad, (u32 *)uptr))
- goto out;
+ return err;
if(third == SETVAL)
fourth.val = (int)pad;
else
fourth.__pad = (void *)A(pad);
- if (IPCOP_MASK (third) &
- (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (SEM_INFO) |
- IPCOP_MASK (GETVAL) | IPCOP_MASK (GETPID) |
- IPCOP_MASK (GETNCNT) | IPCOP_MASK (GETZCNT) |
- IPCOP_MASK (GETALL) | IPCOP_MASK (SETALL) |
- IPCOP_MASK (IPC_RMID))) {
+ switch (third) {
+
+ case IPC_INFO:
+ case IPC_RMID:
+ case IPC_SET:
+ case SEM_INFO:
+ case GETVAL:
+ case GETPID:
+ case GETNCNT:
+ case GETZCNT:
+ case GETALL:
+ case SETVAL:
+ case SETALL:
err = sys_semctl (first, second, third, fourth);
- } else {
- struct semid_ds s;
- struct semid_ds32 *usp = (struct semid_ds32 *)A(pad);
- mm_segment_t old_fs;
- int need_back_translation;
-
- if (third == IPC_SET) {
- err = get_user (s.sem_perm.uid, &usp->sem_perm.uid);
- err |= __get_user(s.sem_perm.gid, &usp->sem_perm.gid);
- err |= __get_user(s.sem_perm.mode, &usp->sem_perm.mode);
- if (err)
- goto out;
- fourth.__pad = &s;
- }
- need_back_translation =
- (IPCOP_MASK (third) &
- (IPCOP_MASK (SEM_STAT) | IPCOP_MASK (IPC_STAT))) != 0;
- if (need_back_translation)
- fourth.__pad = &s;
+ break;
+
+ case IPC_STAT:
+ case SEM_STAT:
+ usp = (struct semid_ds32 *)A(pad);
+ fourth.__pad = &s;
old_fs = get_fs ();
set_fs (KERNEL_DS);
err = sys_semctl (first, second, third, fourth);
set_fs (old_fs);
- if (need_back_translation) {
- int err2 = put_user(s.sem_perm.key, &usp->sem_perm.key);
- err2 |= __put_user(s.sem_perm.uid, &usp->sem_perm.uid);
- err2 |= __put_user(s.sem_perm.gid, &usp->sem_perm.gid);
- err2 |= __put_user(s.sem_perm.cuid,
- &usp->sem_perm.cuid);
- err2 |= __put_user (s.sem_perm.cgid,
- &usp->sem_perm.cgid);
- err2 |= __put_user (s.sem_perm.mode,
- &usp->sem_perm.mode);
- err2 |= __put_user (s.sem_perm.seq, &usp->sem_perm.seq);
- err2 |= __put_user (s.sem_otime, &usp->sem_otime);
- err2 |= __put_user (s.sem_ctime, &usp->sem_ctime);
- err2 |= __put_user (s.sem_nsems, &usp->sem_nsems);
- if (err2) err = -EFAULT;
- }
+ err2 = put_user(s.sem_perm.key, &usp->sem_perm.key);
+ err2 |= __put_user(s.sem_perm.uid, &usp->sem_perm.uid);
+ err2 |= __put_user(s.sem_perm.gid, &usp->sem_perm.gid);
+ err2 |= __put_user(s.sem_perm.cuid,
+ &usp->sem_perm.cuid);
+ err2 |= __put_user (s.sem_perm.cgid,
+ &usp->sem_perm.cgid);
+ err2 |= __put_user (s.sem_perm.mode,
+ &usp->sem_perm.mode);
+ err2 |= __put_user (s.sem_perm.seq, &usp->sem_perm.seq);
+ err2 |= __put_user (s.sem_otime, &usp->sem_otime);
+ err2 |= __put_user (s.sem_ctime, &usp->sem_ctime);
+ err2 |= __put_user (s.sem_nsems, &usp->sem_nsems);
+ if (err2)
+ err = -EFAULT;
+ break;
+
}
-out:
+
return err;
}
@@ -1717,52 +1613,60 @@ out:
static int
do_sys32_msgctl (int first, int second, void *uptr)
{
- int err;
+ int err, err2;
+ struct msqid_ds m;
+ struct msqid64_ds m64;
+ struct msqid_ds32 *up = (struct msqid_ds32 *)uptr;
+ mm_segment_t old_fs;
+
+ switch (second) {
- if (IPCOP_MASK (second) &
- (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (MSG_INFO) |
- IPCOP_MASK (IPC_RMID))) {
+ case IPC_INFO:
+ case IPC_RMID:
+ case MSG_INFO:
err = sys_msgctl (first, second, (struct msqid_ds *)uptr);
- } else {
- struct msqid_ds m;
- struct msqid_ds32 *up = (struct msqid_ds32 *)uptr;
- mm_segment_t old_fs;
-
- if (second == IPC_SET) {
- err = get_user (m.msg_perm.uid, &up->msg_perm.uid);
- err |= __get_user (m.msg_perm.gid, &up->msg_perm.gid);
- err |= __get_user (m.msg_perm.mode, &up->msg_perm.mode);
- err |= __get_user (m.msg_qbytes, &up->msg_qbytes);
- if (err)
- goto out;
- }
+ break;
+
+ case IPC_SET:
+ err = get_user (m.msg_perm.uid, &up->msg_perm.uid);
+ err |= __get_user (m.msg_perm.gid, &up->msg_perm.gid);
+ err |= __get_user (m.msg_perm.mode, &up->msg_perm.mode);
+ err |= __get_user (m.msg_qbytes, &up->msg_qbytes);
+ if (err)
+ break;
old_fs = get_fs ();
set_fs (KERNEL_DS);
err = sys_msgctl (first, second, &m);
set_fs (old_fs);
- if (IPCOP_MASK (second) &
- (IPCOP_MASK (MSG_STAT) | IPCOP_MASK (IPC_STAT))) {
- int err2 = put_user (m.msg_perm.key, &up->msg_perm.key);
- err2 |= __put_user(m.msg_perm.uid, &up->msg_perm.uid);
- err2 |= __put_user(m.msg_perm.gid, &up->msg_perm.gid);
- err2 |= __put_user(m.msg_perm.cuid, &up->msg_perm.cuid);
- err2 |= __put_user(m.msg_perm.cgid, &up->msg_perm.cgid);
- err2 |= __put_user(m.msg_perm.mode, &up->msg_perm.mode);
- err2 |= __put_user(m.msg_perm.seq, &up->msg_perm.seq);
- err2 |= __put_user(m.msg_stime, &up->msg_stime);
- err2 |= __put_user(m.msg_rtime, &up->msg_rtime);
- err2 |= __put_user(m.msg_ctime, &up->msg_ctime);
- err2 |= __put_user(m.msg_cbytes, &up->msg_cbytes);
- err2 |= __put_user(m.msg_qnum, &up->msg_qnum);
- err2 |= __put_user(m.msg_qbytes, &up->msg_qbytes);
- err2 |= __put_user(m.msg_lspid, &up->msg_lspid);
- err2 |= __put_user(m.msg_lrpid, &up->msg_lrpid);
- if (err2)
- err = -EFAULT;
- }
+ break;
+
+ case IPC_STAT:
+ case MSG_STAT:
+ old_fs = get_fs ();
+ set_fs (KERNEL_DS);
+ err = sys_msgctl (first, second, &m64);
+ set_fs (old_fs);
+ err2 = put_user (m64.msg_perm.key, &up->msg_perm.key);
+ err2 |= __put_user(m64.msg_perm.uid, &up->msg_perm.uid);
+ err2 |= __put_user(m64.msg_perm.gid, &up->msg_perm.gid);
+ err2 |= __put_user(m64.msg_perm.cuid, &up->msg_perm.cuid);
+ err2 |= __put_user(m64.msg_perm.cgid, &up->msg_perm.cgid);
+ err2 |= __put_user(m64.msg_perm.mode, &up->msg_perm.mode);
+ err2 |= __put_user(m64.msg_perm.seq, &up->msg_perm.seq);
+ err2 |= __put_user(m64.msg_stime, &up->msg_stime);
+ err2 |= __put_user(m64.msg_rtime, &up->msg_rtime);
+ err2 |= __put_user(m64.msg_ctime, &up->msg_ctime);
+ err2 |= __put_user(m64.msg_cbytes, &up->msg_cbytes);
+ err2 |= __put_user(m64.msg_qnum, &up->msg_qnum);
+ err2 |= __put_user(m64.msg_qbytes, &up->msg_qbytes);
+ err2 |= __put_user(m64.msg_lspid, &up->msg_lspid);
+ err2 |= __put_user(m64.msg_lrpid, &up->msg_lrpid);
+ if (err2)
+ err = -EFAULT;
+ break;
+
}
-out:
return err;
}
@@ -1774,85 +1678,98 @@ do_sys32_shmat (int first, int second, int third, int version, void *uptr)
int err = -EINVAL;
if (version == 1)
- goto out;
+ return err;
err = sys_shmat (first, uptr, second, &raddr);
if (err)
- goto out;
+ return err;
err = put_user (raddr, uaddr);
-out:
return err;
}
static int
do_sys32_shmctl (int first, int second, void *uptr)
{
- int err;
-
- if (IPCOP_MASK (second) &
- (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (SHM_LOCK)
- | IPCOP_MASK (SHM_UNLOCK) | IPCOP_MASK (IPC_RMID))) {
+ int err = -EFAULT, err2;
+ struct shmid_ds s;
+ struct shmid64_ds s64;
+ struct shmid_ds32 *up = (struct shmid_ds32 *)uptr;
+ mm_segment_t old_fs;
+ struct shm_info32 {
+ int used_ids;
+ u32 shm_tot, shm_rss, shm_swp;
+ u32 swap_attempts, swap_successes;
+ } *uip = (struct shm_info32 *)uptr;
+ struct shm_info si;
+
+ switch (second) {
+
+ case IPC_INFO:
+ case IPC_RMID:
+ case SHM_LOCK:
+ case SHM_UNLOCK:
err = sys_shmctl (first, second, (struct shmid_ds *)uptr);
- } else {
- struct shmid_ds s;
- struct shmid_ds32 *up = (struct shmid_ds32 *)uptr;
- mm_segment_t old_fs;
-
- if (second == IPC_SET) {
- err = get_user (s.shm_perm.uid, &up->shm_perm.uid);
- err |= __get_user (s.shm_perm.gid, &up->shm_perm.gid);
- err |= __get_user (s.shm_perm.mode, &up->shm_perm.mode);
- if (err)
- goto out;
- }
+ break;
+ case IPC_SET:
+ err = get_user (s.shm_perm.uid, &up->shm_perm.uid);
+ err |= __get_user (s.shm_perm.gid, &up->shm_perm.gid);
+ err |= __get_user (s.shm_perm.mode, &up->shm_perm.mode);
+ if (err)
+ break;
old_fs = get_fs ();
set_fs (KERNEL_DS);
err = sys_shmctl (first, second, &s);
set_fs (old_fs);
+ break;
+
+ case IPC_STAT:
+ case SHM_STAT:
+ old_fs = get_fs ();
+ set_fs (KERNEL_DS);
+ err = sys_shmctl (first, second, &s64);
+ set_fs (old_fs);
if (err < 0)
- goto out;
+ break;
+ err2 = put_user (s64.shm_perm.key, &up->shm_perm.key);
+ err2 |= __put_user (s64.shm_perm.uid, &up->shm_perm.uid);
+ err2 |= __put_user (s64.shm_perm.gid, &up->shm_perm.gid);
+ err2 |= __put_user (s64.shm_perm.cuid,
+ &up->shm_perm.cuid);
+ err2 |= __put_user (s64.shm_perm.cgid,
+ &up->shm_perm.cgid);
+ err2 |= __put_user (s64.shm_perm.mode,
+ &up->shm_perm.mode);
+ err2 |= __put_user (s64.shm_perm.seq, &up->shm_perm.seq);
+ err2 |= __put_user (s64.shm_atime, &up->shm_atime);
+ err2 |= __put_user (s64.shm_dtime, &up->shm_dtime);
+ err2 |= __put_user (s64.shm_ctime, &up->shm_ctime);
+ err2 |= __put_user (s64.shm_segsz, &up->shm_segsz);
+ err2 |= __put_user (s64.shm_nattch, &up->shm_nattch);
+ err2 |= __put_user (s64.shm_cpid, &up->shm_cpid);
+ err2 |= __put_user (s64.shm_lpid, &up->shm_lpid);
+ if (err2)
+ err = -EFAULT;
+ break;
+
+ case SHM_INFO:
+ old_fs = get_fs ();
+ set_fs (KERNEL_DS);
+ err = sys_shmctl (first, second, &si);
+ set_fs (old_fs);
+ if (err < 0)
+ break;
+ err2 = put_user (si.used_ids, &uip->used_ids);
+ err2 |= __put_user (si.shm_tot, &uip->shm_tot);
+ err2 |= __put_user (si.shm_rss, &uip->shm_rss);
+ err2 |= __put_user (si.shm_swp, &uip->shm_swp);
+ err2 |= __put_user (si.swap_attempts,
+ &uip->swap_attempts);
+ err2 |= __put_user (si.swap_successes,
+ &uip->swap_successes);
+ if (err2)
+ err = -EFAULT;
+ break;
- /* Mask it even in this case so it becomes a CSE. */
- if (second == SHM_INFO) {
- struct shm_info32 {
- int used_ids;
- u32 shm_tot, shm_rss, shm_swp;
- u32 swap_attempts, swap_successes;
- } *uip = (struct shm_info32 *)uptr;
- struct shm_info *kp = (struct shm_info *)&s;
- int err2 = put_user (kp->used_ids, &uip->used_ids);
- err2 |= __put_user (kp->shm_tot, &uip->shm_tot);
- err2 |= __put_user (kp->shm_rss, &uip->shm_rss);
- err2 |= __put_user (kp->shm_swp, &uip->shm_swp);
- err2 |= __put_user (kp->swap_attempts,
- &uip->swap_attempts);
- err2 |= __put_user (kp->swap_successes,
- &uip->swap_successes);
- if (err2)
- err = -EFAULT;
- } else if (IPCOP_MASK (second) &
- (IPCOP_MASK (SHM_STAT) | IPCOP_MASK (IPC_STAT))) {
- int err2 = put_user (s.shm_perm.key, &up->shm_perm.key);
- err2 |= __put_user (s.shm_perm.uid, &up->shm_perm.uid);
- err2 |= __put_user (s.shm_perm.gid, &up->shm_perm.gid);
- err2 |= __put_user (s.shm_perm.cuid,
- &up->shm_perm.cuid);
- err2 |= __put_user (s.shm_perm.cgid,
- &up->shm_perm.cgid);
- err2 |= __put_user (s.shm_perm.mode,
- &up->shm_perm.mode);
- err2 |= __put_user (s.shm_perm.seq, &up->shm_perm.seq);
- err2 |= __put_user (s.shm_atime, &up->shm_atime);
- err2 |= __put_user (s.shm_dtime, &up->shm_dtime);
- err2 |= __put_user (s.shm_ctime, &up->shm_ctime);
- err2 |= __put_user (s.shm_segsz, &up->shm_segsz);
- err2 |= __put_user (s.shm_nattch, &up->shm_nattch);
- err2 |= __put_user (s.shm_cpid, &up->shm_cpid);
- err2 |= __put_user (s.shm_lpid, &up->shm_lpid);
- if (err2)
- err = -EFAULT;
- }
}
-out:
return err;
}
@@ -1865,67 +1782,54 @@ sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
version = call >> 16; /* hack for backward compatibility */
call &= 0xffff;
- if (call <= SEMCTL)
- switch (call) {
- case SEMOP:
- /* struct sembuf is the same on 32 and 64bit :)) */
- err = sys_semop (first, (struct sembuf *)AA(ptr),
- second);
- goto out;
- case SEMGET:
- err = sys_semget (first, second, third);
- goto out;
- case SEMCTL:
- err = do_sys32_semctl (first, second, third,
- (void *)AA(ptr));
- goto out;
- default:
- err = -EINVAL;
- goto out;
- };
- if (call <= MSGCTL)
- switch (call) {
- case MSGSND:
- err = do_sys32_msgsnd (first, second, third,
- (void *)AA(ptr));
- goto out;
- case MSGRCV:
- err = do_sys32_msgrcv (first, second, fifth, third,
- version, (void *)AA(ptr));
- goto out;
- case MSGGET:
- err = sys_msgget ((key_t) first, second);
- goto out;
- case MSGCTL:
- err = do_sys32_msgctl (first, second, (void *)AA(ptr));
- goto out;
- default:
- err = -EINVAL;
- goto out;
- }
- if (call <= SHMCTL)
- switch (call) {
- case SHMAT:
- err = do_sys32_shmat (first, second, third,
- version, (void *)AA(ptr));
- goto out;
- case SHMDT:
- err = sys_shmdt ((char *)AA(ptr));
- goto out;
- case SHMGET:
- err = sys_shmget (first, second, third);
- goto out;
- case SHMCTL:
- err = do_sys32_shmctl (first, second, (void *)AA(ptr));
- goto out;
- default:
- err = -EINVAL;
- goto out;
- }
+ switch (call) {
- err = -EINVAL;
+ case SEMOP:
+ /* struct sembuf is the same on 32 and 64bit :)) */
+ err = sys_semop (first, (struct sembuf *)AA(ptr),
+ second);
+ break;
+ case SEMGET:
+ err = sys_semget (first, second, third);
+ break;
+ case SEMCTL:
+ err = do_sys32_semctl (first, second, third,
+ (void *)AA(ptr));
+ break;
+
+ case MSGSND:
+ err = do_sys32_msgsnd (first, second, third,
+ (void *)AA(ptr));
+ break;
+ case MSGRCV:
+ err = do_sys32_msgrcv (first, second, fifth, third,
+ version, (void *)AA(ptr));
+ break;
+ case MSGGET:
+ err = sys_msgget ((key_t) first, second);
+ break;
+ case MSGCTL:
+ err = do_sys32_msgctl (first, second, (void *)AA(ptr));
+ break;
+
+ case SHMAT:
+ err = do_sys32_shmat (first, second, third,
+ version, (void *)AA(ptr));
+ break;
+ case SHMDT:
+ err = sys_shmdt ((char *)AA(ptr));
+ break;
+ case SHMGET:
+ err = sys_shmget (first, second, third);
+ break;
+ case SHMCTL:
+ err = do_sys32_shmctl (first, second, (void *)AA(ptr));
+ break;
+ default:
+ err = -EINVAL;
+ break;
+ }
-out:
unlock_kernel();
return err;
}
@@ -1949,6 +1853,537 @@ asmlinkage long sys32_time(int * tloc)
return i;
}
+struct rusage32 {
+ struct timeval32 ru_utime;
+ struct timeval32 ru_stime;
+ int ru_maxrss;
+ int ru_ixrss;
+ int ru_idrss;
+ int ru_isrss;
+ int ru_minflt;
+ int ru_majflt;
+ int ru_nswap;
+ int ru_inblock;
+ int ru_oublock;
+ int ru_msgsnd;
+ int ru_msgrcv;
+ int ru_nsignals;
+ int ru_nvcsw;
+ int ru_nivcsw;
+};
+
+static int
+put_rusage (struct rusage32 *ru, struct rusage *r)
+{
+ int err;
+
+ err = put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec);
+ err |= __put_user (r->ru_utime.tv_usec, &ru->ru_utime.tv_usec);
+ err |= __put_user (r->ru_stime.tv_sec, &ru->ru_stime.tv_sec);
+ err |= __put_user (r->ru_stime.tv_usec, &ru->ru_stime.tv_usec);
+ err |= __put_user (r->ru_maxrss, &ru->ru_maxrss);
+ err |= __put_user (r->ru_ixrss, &ru->ru_ixrss);
+ err |= __put_user (r->ru_idrss, &ru->ru_idrss);
+ err |= __put_user (r->ru_isrss, &ru->ru_isrss);
+ err |= __put_user (r->ru_minflt, &ru->ru_minflt);
+ err |= __put_user (r->ru_majflt, &ru->ru_majflt);
+ err |= __put_user (r->ru_nswap, &ru->ru_nswap);
+ err |= __put_user (r->ru_inblock, &ru->ru_inblock);
+ err |= __put_user (r->ru_oublock, &ru->ru_oublock);
+ err |= __put_user (r->ru_msgsnd, &ru->ru_msgsnd);
+ err |= __put_user (r->ru_msgrcv, &ru->ru_msgrcv);
+ err |= __put_user (r->ru_nsignals, &ru->ru_nsignals);
+ err |= __put_user (r->ru_nvcsw, &ru->ru_nvcsw);
+ err |= __put_user (r->ru_nivcsw, &ru->ru_nivcsw);
+ return err;
+}
+
+extern asmlinkage int sys_wait4(pid_t pid,unsigned int * stat_addr,
+ int options, struct rusage * ru);
+
+asmlinkage int
+sys32_wait4(__kernel_pid_t32 pid, unsigned int *stat_addr, int options,
+ struct rusage32 *ru)
+{
+ if (!ru)
+ return sys_wait4(pid, stat_addr, options, NULL);
+ else {
+ struct rusage r;
+ int ret;
+ unsigned int status;
+ mm_segment_t old_fs = get_fs();
+
+ set_fs (KERNEL_DS);
+ ret = sys_wait4(pid, stat_addr ? &status : NULL, options, &r);
+ set_fs (old_fs);
+ if (put_rusage (ru, &r)) return -EFAULT;
+ if (stat_addr && put_user (status, stat_addr))
+ return -EFAULT;
+ return ret;
+ }
+}
+
+asmlinkage int
+sys32_waitpid(__kernel_pid_t32 pid, unsigned int *stat_addr, int options)
+{
+ return sys32_wait4(pid, stat_addr, options, NULL);
+}
+
+
+extern asmlinkage int
+sys_getrusage(int who, struct rusage *ru);
+
+asmlinkage int
+sys32_getrusage(int who, struct rusage32 *ru)
+{
+ struct rusage r;
+ int ret;
+ mm_segment_t old_fs = get_fs();
+
+ set_fs (KERNEL_DS);
+ ret = sys_getrusage(who, &r);
+ set_fs (old_fs);
+ if (put_rusage (ru, &r)) return -EFAULT;
+ return ret;
+}
+
+struct tms32 {
+ __kernel_clock_t32 tms_utime;
+ __kernel_clock_t32 tms_stime;
+ __kernel_clock_t32 tms_cutime;
+ __kernel_clock_t32 tms_cstime;
+};
+
+extern asmlinkage long sys_times(struct tms * tbuf);
+
+asmlinkage long
+sys32_times(struct tms32 *tbuf)
+{
+ struct tms t;
+ long ret;
+ mm_segment_t old_fs = get_fs ();
+ int err;
+
+ set_fs (KERNEL_DS);
+ ret = sys_times(tbuf ? &t : NULL);
+ set_fs (old_fs);
+ if (tbuf) {
+ err = put_user (t.tms_utime, &tbuf->tms_utime);
+ err |= __put_user (t.tms_stime, &tbuf->tms_stime);
+ err |= __put_user (t.tms_cutime, &tbuf->tms_cutime);
+ err |= __put_user (t.tms_cstime, &tbuf->tms_cstime);
+ if (err)
+ ret = -EFAULT;
+ }
+ return ret;
+}
+
+unsigned int
+ia32_peek (struct pt_regs *regs, struct task_struct *child, unsigned long addr, unsigned int *val)
+{
+ size_t copied;
+ unsigned int ret;
+
+ copied = access_process_vm(child, addr, val, sizeof(*val), 0);
+ return(copied != sizeof(ret) ? -EIO : 0);
+}
+
+unsigned int
+ia32_poke (struct pt_regs *regs, struct task_struct *child, unsigned long addr, unsigned int val)
+{
+
+ if (access_process_vm(child, addr, &val, sizeof(val), 1) != sizeof(val))
+ return -EIO;
+ return 0;
+}
+
+/*
+ * The order in which registers are stored in the ptrace regs structure
+ */
+#define PT_EBX 0
+#define PT_ECX 1
+#define PT_EDX 2
+#define PT_ESI 3
+#define PT_EDI 4
+#define PT_EBP 5
+#define PT_EAX 6
+#define PT_DS 7
+#define PT_ES 8
+#define PT_FS 9
+#define PT_GS 10
+#define PT_ORIG_EAX 11
+#define PT_EIP 12
+#define PT_CS 13
+#define PT_EFL 14
+#define PT_UESP 15
+#define PT_SS 16
+
+unsigned int
+getreg(struct task_struct *child, int regno)
+{
+ struct pt_regs *child_regs;
+
+ child_regs = ia64_task_regs(child);
+ switch (regno / sizeof(int)) {
+
+ case PT_EBX:
+ return(child_regs->r11);
+ case PT_ECX:
+ return(child_regs->r9);
+ case PT_EDX:
+ return(child_regs->r10);
+ case PT_ESI:
+ return(child_regs->r14);
+ case PT_EDI:
+ return(child_regs->r15);
+ case PT_EBP:
+ return(child_regs->r13);
+ case PT_EAX:
+ case PT_ORIG_EAX:
+ return(child_regs->r8);
+ case PT_EIP:
+ return(child_regs->cr_iip);
+ case PT_UESP:
+ return(child_regs->r12);
+ case PT_EFL:
+ return(child->thread.eflag);
+ case PT_DS:
+ case PT_ES:
+ case PT_FS:
+ case PT_GS:
+ case PT_SS:
+ return((unsigned int)__USER_DS);
+ case PT_CS:
+ return((unsigned int)__USER_CS);
+ default:
+ printk("getregs:unknown register %d\n", regno);
+ break;
+
+ }
+ return(0);
+}
+
+void
+putreg(struct task_struct *child, int regno, unsigned int value)
+{
+ struct pt_regs *child_regs;
+
+ child_regs = ia64_task_regs(child);
+ switch (regno / sizeof(int)) {
+
+ case PT_EBX:
+ child_regs->r11 = value;
+ break;
+ case PT_ECX:
+ child_regs->r9 = value;
+ break;
+ case PT_EDX:
+ child_regs->r10 = value;
+ break;
+ case PT_ESI:
+ child_regs->r14 = value;
+ break;
+ case PT_EDI:
+ child_regs->r15 = value;
+ break;
+ case PT_EBP:
+ child_regs->r13 = value;
+ break;
+ case PT_EAX:
+ case PT_ORIG_EAX:
+ child_regs->r8 = value;
+ break;
+ case PT_EIP:
+ child_regs->cr_iip = value;
+ break;
+ case PT_UESP:
+ child_regs->r12 = value;
+ break;
+ case PT_EFL:
+ child->thread.eflag = value;
+ break;
+ case PT_DS:
+ case PT_ES:
+ case PT_FS:
+ case PT_GS:
+ case PT_SS:
+ if (value != __USER_DS)
+ printk("setregs:try to set invalid segment register %d = %x\n", regno, value);
+ break;
+ case PT_CS:
+ if (value != __USER_CS)
+ printk("setregs:try to set invalid segment register %d = %x\n", regno, value);
+ break;
+ default:
+ printk("getregs:unknown register %d\n", regno);
+ break;
+
+ }
+}
+
+static inline void
+ia32f2ia64f(void *dst, void *src)
+{
+
+ __asm__ ("ldfe f6=[%1] ;;\n\t"
+ "stf.spill [%0]=f6"
+ :
+ : "r"(dst), "r"(src));
+ return;
+}
+
+static inline void
+ia64f2ia32f(void *dst, void *src)
+{
+
+ __asm__ ("ldf.fill f6=[%1] ;;\n\t"
+ "stfe [%0]=f6"
+ :
+ : "r"(dst), "r"(src));
+ return;
+}
+
+void
+put_fpreg(int regno, struct _fpreg_ia32 *reg, struct pt_regs *ptp, struct switch_stack *swp, int tos)
+{
+ struct _fpreg_ia32 *f;
+ char buf[32];
+
+ f = (struct _fpreg_ia32 *)(((unsigned long)buf + 15) & ~15);
+ if ((regno += tos) >= 8)
+ regno -= 8;
+ switch (regno) {
+
+ case 0:
+ ia64f2ia32f(f, &ptp->f8);
+ break;
+ case 1:
+ ia64f2ia32f(f, &ptp->f9);
+ break;
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ ia64f2ia32f(f, &swp->f10 + (regno - 2));
+ break;
+
+ }
+ __copy_to_user(reg, f, sizeof(*reg));
+ return;
+}
+
+void
+get_fpreg(int regno, struct _fpreg_ia32 *reg, struct pt_regs *ptp, struct switch_stack *swp, int tos)
+{
+
+ if ((regno += tos) >= 8)
+ regno -= 8;
+ switch (regno) {
+
+ case 0:
+ __copy_from_user(&ptp->f8, reg, sizeof(*reg));
+ break;
+ case 1:
+ __copy_from_user(&ptp->f9, reg, sizeof(*reg));
+ break;
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ __copy_from_user(&swp->f10 + (regno - 2), reg, sizeof(*reg));
+ break;
+
+ }
+ return;
+}
+
+int
+save_ia32_fpstate(struct task_struct *tsk, struct _fpstate_ia32 *save)
+{
+ struct switch_stack *swp;
+ struct pt_regs *ptp;
+ int i, tos;
+
+ if (!access_ok(VERIFY_WRITE, save, sizeof(*save)))
+ return(-EIO);
+ __put_user(tsk->thread.fcr, &save->cw);
+ __put_user(tsk->thread.fsr, &save->sw);
+ __put_user(tsk->thread.fsr >> 32, &save->tag);
+ __put_user(tsk->thread.fir, &save->ipoff);
+ __put_user(__USER_CS, &save->cssel);
+ __put_user(tsk->thread.fdr, &save->dataoff);
+ __put_user(__USER_DS, &save->datasel);
+ /*
+ * Stack frames start with 16-bytes of temp space
+ */
+ swp = (struct switch_stack *)(tsk->thread.ksp + 16);
+ ptp = ia64_task_regs(tsk);
+ tos = (tsk->thread.fsr >> 11) & 3;
+ for (i = 0; i < 8; i++)
+ put_fpreg(i, &save->_st[i], ptp, swp, tos);
+ return(0);
+}
+
+int
+restore_ia32_fpstate(struct task_struct *tsk, struct _fpstate_ia32 *save)
+{
+ struct switch_stack *swp;
+ struct pt_regs *ptp;
+ int i, tos;
+ int fsrlo, fsrhi;
+
+ if (!access_ok(VERIFY_READ, save, sizeof(*save)))
+ return(-EIO);
+ __get_user(tsk->thread.fcr, (unsigned int *)&save->cw);
+ __get_user(fsrlo, (unsigned int *)&save->sw);
+ __get_user(fsrhi, (unsigned int *)&save->tag);
+ tsk->thread.fsr = ((long)fsrhi << 32) | (long)fsrlo;
+ __get_user(tsk->thread.fir, (unsigned int *)&save->ipoff);
+ __get_user(tsk->thread.fdr, (unsigned int *)&save->dataoff);
+ /*
+ * Stack frames start with 16-bytes of temp space
+ */
+ swp = (struct switch_stack *)(tsk->thread.ksp + 16);
+ ptp = ia64_task_regs(tsk);
+ tos = (tsk->thread.fsr >> 11) & 3;
+ for (i = 0; i < 8; i++)
+ get_fpreg(i, &save->_st[i], ptp, swp, tos);
+ return(0);
+}
+
+asmlinkage long sys_ptrace(long, pid_t, unsigned long, unsigned long, long, long, long, long, long);
+
+/*
+ * Note that the IA32 version of `ptrace' calls the IA64 routine for
+ * many of the requests. This will only work for requests that do
+ * not need access to the calling processes `pt_regs' which is located
+ * at the address of `stack'. Once we call the IA64 `sys_ptrace' then
+ * the address of `stack' will not be the address of the `pt_regs'.
+ */
+asmlinkage long
+sys32_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data,
+ long arg4, long arg5, long arg6, long arg7, long stack)
+{
+ struct pt_regs *regs = (struct pt_regs *) &stack;
+ struct task_struct *child;
+ long i, ret;
+ unsigned int value;
+
+ lock_kernel();
+ if (request == PTRACE_TRACEME) {
+ ret = sys_ptrace(request, pid, addr, data,
+ arg4, arg5, arg6, arg7, stack);
+ goto out;
+ }
+
+ ret = -ESRCH;
+ read_lock(&tasklist_lock);
+ child = find_task_by_pid(pid);
+ read_unlock(&tasklist_lock);
+ if (!child)
+ goto out;
+ ret = -EPERM;
+ if (pid == 1) /* no messing around with init! */
+ goto out;
+
+ if (request == PTRACE_ATTACH) {
+ ret = sys_ptrace(request, pid, addr, data,
+ arg4, arg5, arg6, arg7, stack);
+ goto out;
+ }
+ ret = -ESRCH;
+ if (!(child->flags & PF_PTRACED))
+ goto out;
+ if (child->state != TASK_STOPPED) {
+ if (request != PTRACE_KILL)
+ goto out;
+ }
+ if (child->p_pptr != current)
+ goto out;
+
+ switch (request) {
+ case PTRACE_PEEKTEXT:
+ case PTRACE_PEEKDATA: /* read word at location addr */
+ ret = ia32_peek(regs, child, addr, &value);
+ if (ret == 0)
+ ret = put_user(value, (unsigned int *)data);
+ else
+ ret = -EIO;
+ goto out;
+
+ case PTRACE_POKETEXT:
+ case PTRACE_POKEDATA: /* write the word at location addr */
+ ret = ia32_poke(regs, child, addr, (unsigned int)data);
+ goto out;
+
+ case PTRACE_PEEKUSR: /* read word at addr in USER area */
+ ret = 0;
+ break;
+
+ case PTRACE_POKEUSR: /* write word at addr in USER area */
+ ret = 0;
+ break;
+
+ case IA32_PTRACE_GETREGS:
+ if (!access_ok(VERIFY_WRITE, (int *)data, 17*sizeof(int))) {
+ ret = -EIO;
+ break;
+ }
+ for ( i = 0; i < 17*sizeof(int); i += sizeof(int) ) {
+ __put_user(getreg(child, i),(unsigned int *) data);
+ data += sizeof(int);
+ }
+ ret = 0;
+ break;
+
+ case IA32_PTRACE_SETREGS:
+ {
+ unsigned int tmp;
+ if (!access_ok(VERIFY_READ, (int *)data, 17*sizeof(int))) {
+ ret = -EIO;
+ break;
+ }
+ for ( i = 0; i < 17*sizeof(int); i += sizeof(int) ) {
+ __get_user(tmp, (unsigned int *) data);
+ putreg(child, i, tmp);
+ data += sizeof(int);
+ }
+ ret = 0;
+ break;
+ }
+
+ case IA32_PTRACE_GETFPREGS:
+ ret = save_ia32_fpstate(child, (struct _fpstate_ia32 *)data);
+ break;
+
+ case IA32_PTRACE_SETFPREGS:
+ ret = restore_ia32_fpstate(child, (struct _fpstate_ia32 *)data);
+ break;
+
+ case PTRACE_SYSCALL: /* continue, stop after next syscall */
+ case PTRACE_CONT: /* restart after signal. */
+ case PTRACE_KILL:
+ case PTRACE_SINGLESTEP: /* execute chile for one instruction */
+ case PTRACE_DETACH: /* detach a process */
+ unlock_kernel();
+ ret = sys_ptrace(request, pid, addr, data,
+ arg4, arg5, arg6, arg7, stack);
+ return(ret);
+
+ default:
+ ret = -EIO;
+ break;
+
+ }
+ out:
+ unlock_kernel();
+ return ret;
+}
+
#ifdef NOTYET /* UNTESTED FOR IA64 FROM HERE DOWN */
/* In order to reduce some races, while at the same time doing additional
@@ -2719,37 +3154,6 @@ sys32_getresgid(__kernel_gid_t32 *rgid, __kernel_gid_t32 *egid,
return ret;
}
-struct tms32 {
- __kernel_clock_t32 tms_utime;
- __kernel_clock_t32 tms_stime;
- __kernel_clock_t32 tms_cutime;
- __kernel_clock_t32 tms_cstime;
-};
-
-extern asmlinkage long sys_times(struct tms * tbuf);
-
-asmlinkage long
-sys32_times(struct tms32 *tbuf)
-{
- struct tms t;
- long ret;
- mm_segment_t old_fs = get_fs ();
- int err;
-
- set_fs (KERNEL_DS);
- ret = sys_times(tbuf ? &t : NULL);
- set_fs (old_fs);
- if (tbuf) {
- err = put_user (t.tms_utime, &tbuf->tms_utime);
- err |= __put_user (t.tms_stime, &tbuf->tms_stime);
- err |= __put_user (t.tms_cutime, &tbuf->tms_cutime);
- err |= __put_user (t.tms_cstime, &tbuf->tms_cstime);
- if (err)
- ret = -EFAULT;
- }
- return ret;
-}
-
extern asmlinkage int sys_getgroups(int gidsetsize, gid_t *grouplist);
asmlinkage int
@@ -2789,23 +3193,6 @@ sys32_setgroups(int gidsetsize, __kernel_gid_t32 *grouplist)
return ret;
}
-extern asmlinkage int
-sys_getrusage(int who, struct rusage *ru);
-
-asmlinkage int
-sys32_getrusage(int who, struct rusage32 *ru)
-{
- struct rusage r;
- int ret;
- mm_segment_t old_fs = get_fs();
-
- set_fs (KERNEL_DS);
- ret = sys_getrusage(who, &r);
- set_fs (old_fs);
- if (put_rusage (ru, &r)) return -EFAULT;
- return ret;
-}
-
/* XXX These as well... */
extern __inline__ struct socket *
@@ -4355,4 +4742,3 @@ sys32_adjtimex(struct timex32 *utp)
return ret;
}
#endif // NOTYET
-
diff --git a/arch/ia64/kdb/Makefile b/arch/ia64/kdb/Makefile
deleted file mode 100644
index 2e8db3fc4..000000000
--- a/arch/ia64/kdb/Makefile
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# Makefile for ia64-specific kdb files..
-#
-# Copyright 1999, Silicon Graphics Inc.
-#
-# Written March 1999 by Scott Lurndal at Silicon Graphics, Inc.
-# Code for IA64 written by Goutham Rao <goutham.rao@intel.com> and
-# Sreenivas Subramoney <sreenivas.subramoney@intel.com>
-#
-
-SUB_DIRS :=
-MOD_SUB_DIRS := $(SUB_DIRS)
-ALL_SUB_DIRS := $(SUB_DIRS)
-
-.S.o:
- $(CC) $(AFLAGS) -traditional -c $< -o $*.o
-
-L_TARGET = kdb.a
-L_OBJS = kdbsupport.o kdb_io.o kdb_bt.o kdb_traps.o
-
-include $(TOPDIR)/Rules.make
diff --git a/arch/ia64/kdb/kdb_bt.c b/arch/ia64/kdb/kdb_bt.c
deleted file mode 100644
index dbcb7a575..000000000
--- a/arch/ia64/kdb/kdb_bt.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/**
- * Minimalist Kernel Debugger
- * Machine dependent stack traceback code for IA-64.
- *
- * Copyright (C) 1999 Goutham Rao <goutham.rao@intel.com>
- * Copyright (C) 1999 Sreenivas Subramoney <sreenivas.subramoney@intel.com>
- * Intel Corporation, August 1999.
- * Copyright (C) 1999 Hewlett-Packard Co
- * Copyright (C) 1999 David Mosberger-Tang <davidm@hpl.hp.com>
- *
- * 99/12/03 D. Mosberger Reimplemented based on <asm-ia64/unwind.h> API.
- * 99/12/06 D. Mosberger Added support for backtracing other processes.
- */
-
-#include <linux/ctype.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/kdb.h>
-#include <asm/system.h>
-#include <asm/current.h>
-#include <asm/kdbsupport.h>
-
-/*
- * Minimal stack back trace functionality.
- */
-int
-kdb_bt (int argc, const char **argv, const char **envp, struct pt_regs *regs)
-{
- struct task_struct *task = current;
- struct ia64_frame_info info;
- char *name;
- int diag;
-
- if (strcmp(argv[0], "btp") == 0) {
- unsigned long pid;
-
- diag = kdbgetularg(argv[1], &pid);
- if (diag)
- return diag;
-
- task = find_task_by_pid(pid);
- if (!task) {
- kdb_printf("No process with pid == %d found\n", pid);
- return 0;
- }
- regs = ia64_task_regs(task);
- } else if (argc) {
- kdb_printf("bt <address> is unsupported for IA-64\n");
- return 0;
- }
-
- if (task == current) {
- /*
- * Upon entering kdb, the stack frame looks like this:
- *
- * +---------------------+
- * | struct pt_regs |
- * +---------------------+
- * | |
- * | kernel stack |
- * | |
- * +=====================+ <--- top of stack upon entering kdb
- * | struct pt_regs |
- * +---------------------+
- * | struct switch_stack |
- * +---------------------+
- */
- if (user_mode(regs)) {
- /* We are not implementing stack backtrace from user mode code */
- kdb_printf ("Not in Kernel\n");
- return 0;
- }
- ia64_unwind_init_from_current(&info, regs);
- } else {
- /*
- * For a blocked task, the stack frame looks like this:
- *
- * +---------------------+
- * | struct pt_regs |
- * +---------------------+
- * | |
- * | kernel stack |
- * | |
- * +---------------------+
- * | struct switch_stack |
- * +=====================+ <--- task->thread.ksp
- */
- ia64_unwind_init_from_blocked_task(&info, task);
- }
-
- kdb_printf("Ret Address Reg Stack base Name\n\n") ;
- do {
- unsigned long ip = ia64_unwind_get_ip(&info);
-
- name = kdbnearsym(ip);
- if (!name) {
- kdb_printf("Interrupt\n");
- return 0;
- }
- kdb_printf("0x%016lx: [0x%016lx] %s\n", ip, ia64_unwind_get_bsp(&info), name);
- } while (ia64_unwind_to_previous_frame(&info) >= 0);
- return 0;
-}
diff --git a/arch/ia64/kdb/kdb_io.c b/arch/ia64/kdb/kdb_io.c
deleted file mode 100644
index 0b5c6fd44..000000000
--- a/arch/ia64/kdb/kdb_io.c
+++ /dev/null
@@ -1,350 +0,0 @@
-/*
- * Kernel Debugger Console I/O handler
- *
- * Copyright (C) 1999 Silicon Graphics, Inc.
- * Copyright (C) Scott Lurndal (slurn@engr.sgi.com)
- * Copyright (C) Scott Foehner (sfoehner@engr.sgi.com)
- * Copyright (C) Srinivasa Thirumalachar (sprasad@engr.sgi.com)
- *
- * Written March 1999 by Scott Lurndal at Silicon Graphics, Inc.
- *
- * Modifications from:
- * Chuck Fleckenstein 1999/07/20
- * Move kdb_info struct declaration to this file
- * for cases where serial support is not compiled into
- * the kernel.
- *
- * Masahiro Adegawa 1999/07/20
- * Handle some peculiarities of japanese 86/106
- * keyboards.
- *
- * marc@mucom.co.il 1999/07/20
- * Catch buffer overflow for serial input.
- *
- * Scott Foehner
- * Port to ia64
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/console.h>
-#include <linux/serial_reg.h>
-#include <linux/spinlock.h>
-
-#include <asm/io.h>
-
-#include "pc_keyb.h"
-
-int kdb_port = 0;
-
-/*
- * This module contains code to read characters from the keyboard or a serial
- * port.
- *
- * It is used by the kernel debugger, and is polled, not interrupt driven.
- *
- */
-
-/*
- * send: Send a byte to the keyboard controller. Used primarily to
- * alter LED settings.
- */
-
-static void
-kdb_kbdsend(unsigned char byte)
-{
- while (inb(KBD_STATUS_REG) & KBD_STAT_IBF)
- ;
- outb(KBD_DATA_REG, byte);
-}
-
-static void
-kdb_kbdsetled(int leds)
-{
- kdb_kbdsend(KBD_CMD_SET_LEDS);
- kdb_kbdsend((unsigned char)leds);
-}
-
-static void
-console_read (char *buffer, size_t bufsize)
-{
- struct console *in;
- struct console *out;
- char *cp, ch;
-
- for (in = console_drivers; in; in = in->next) {
- if ((in->flags & CON_ENABLED) && (in->read || in->wait_key))
- break;
- }
- for (out = console_drivers; out; out = out->next) {
- if ((out->flags & CON_ENABLED) && out->write)
- break;
- }
-
- if ((!in->read && !in->wait_key) || !out->write) {
- panic("kdb_io: can't do console i/o!");
- }
-
- if (in->read) {
- /* this is untested... */
- (*in->read)(in, buffer, bufsize);
- return;
- }
-
- bufsize -= 2; /* leave room for CR & NUL terminator */
- cp = buffer;
- while (1) {
- ch = (*in->wait_key)(in);
- switch (ch) {
- case '\b':
- if (cp > buffer) {
- --cp, ++bufsize;
- (*out->write)(out, "\b \b", 3);
- }
- break;
-
- case '\025':
- while (cp > buffer) {
- --cp, ++bufsize;
- (*out->write)(out, "\b \b", 3);
- }
- break;
-
- case '\r':
- case '\n':
- (*out->write)(out, "\r\n", 2);
- *cp++ = '\n';
- *cp++ = '\0';
- return;
-
- default:
- if (bufsize > 0) {
- (*out->write)(out, &ch, 1);
- --bufsize;
- *cp++ = ch;
- }
- break;
- }
- }
-}
-
-char *
-kdb_getscancode(char *buffer, size_t bufsize)
-{
- /*
- * XXX Shouldn't kdb _always_ use console based I/O? That's what the console
- * abstraction is for, after all... ---davidm
- */
-#ifdef CONFIG_IA64_HP_SIM
- extern spinlock_t console_lock;
- unsigned long flags;
-
- spin_lock_irqsave(&console_lock, flags);
- console_read(buffer, bufsize);
- spin_unlock_irqrestore(&console_lock, flags);
- return buffer;
-#else /* !CONFIG_IA64_HP_SIM */
- char *cp = buffer;
- int scancode, scanstatus;
- static int shift_lock = 0; /* CAPS LOCK state (0-off, 1-on) */
- static int shift_key = 0; /* Shift next keypress */
- static int ctrl_key = 0;
- static int leds = 2; /* Num lock */
- u_short keychar;
- extern u_short plain_map[], shift_map[], ctrl_map[];
-
- bufsize -= 2; /* Reserve space for newline and null byte */
-
- /*
- * If we came in via a serial console, we allow that to
- * be the input window for kdb.
- */
- if (kdb_port != 0) {
- char ch;
- int status;
-#define serial_inp(info, offset) inb((info) + (offset))
-#define serial_out(info, offset, v) outb((v), (info) + (offset))
-
- while(1) {
- while ((status = serial_inp(kdb_port, UART_LSR))
- & UART_LSR_DR) {
-readchar:
- ch = serial_inp(kdb_port, UART_RX);
- if (ch == 8) { /* BS */
- if (cp > buffer) {
- --cp, bufsize++;
- printk("%c %c", 0x08, 0x08);
- }
- continue;
- }
- serial_out(kdb_port, UART_TX, ch);
- if (ch == 13) { /* CR */
- *cp++ = '\n';
- *cp++ = '\0';
- serial_out(kdb_port, UART_TX, 10);
- return(buffer);
- }
- /*
- * Discard excess characters
- */
- if (bufsize > 0) {
- *cp++ = ch;
- bufsize--;
- }
- }
- while (((status = serial_inp(kdb_port, UART_LSR))
- & UART_LSR_DR) == 0);
- }
- }
-
- while (1) {
-
- /*
- * Wait for a valid scancode
- */
-
- while ((inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0)
- ;
-
- /*
- * Fetch the scancode
- */
- scancode = inb(KBD_DATA_REG);
- scanstatus = inb(KBD_STATUS_REG);
-
- /*
- * Ignore mouse events.
- */
- if (scanstatus & KBD_STAT_MOUSE_OBF)
- continue;
-
- /*
- * Ignore release, trigger on make
- * (except for shift keys, where we want to
- * keep the shift state so long as the key is
- * held down).
- */
-
- if (((scancode&0x7f) == 0x2a)
- || ((scancode&0x7f) == 0x36)) {
- /*
- * Next key may use shift table
- */
- if ((scancode & 0x80) == 0) {
- shift_key=1;
- } else {
- shift_key=0;
- }
- continue;
- }
-
- if ((scancode&0x7f) == 0x1d) {
- /*
- * Left ctrl key
- */
- if ((scancode & 0x80) == 0) {
- ctrl_key = 1;
- } else {
- ctrl_key = 0;
- }
- continue;
- }
-
- if ((scancode & 0x80) != 0)
- continue;
-
- scancode &= 0x7f;
-
- /*
- * Translate scancode
- */
-
- if (scancode == 0x3a) {
- /*
- * Toggle caps lock
- */
- shift_lock ^= 1;
- leds ^= 0x4; /* toggle caps lock led */
-
- kdb_kbdsetled(leds);
- continue;
- }
-
- if (scancode == 0x0e) {
- /*
- * Backspace
- */
- if (cp > buffer) {
- --cp, bufsize++;
-
- /*
- * XXX - erase character on screen
- */
- printk("%c %c", 0x08, 0x08);
- }
- continue;
- }
-
- if (scancode == 0xe0) {
- continue;
- }
-
- /*
- * For Japanese 86/106 keyboards
- * See comment in drivers/char/pc_keyb.c.
- * - Masahiro Adegawa
- */
- if (scancode == 0x73) {
- scancode = 0x59;
- } else if (scancode == 0x7d) {
- scancode = 0x7c;
- }
-
- if (!shift_lock && !shift_key) {
- keychar = plain_map[scancode];
- } else if (shift_lock || shift_key) {
- keychar = shift_map[scancode];
- } else if (ctrl_key) {
- keychar = ctrl_map[scancode];
- } else {
- keychar = 0x0020;
- printk("Unknown state/scancode (%d)\n", scancode);
- }
-
- if ((scancode & 0x7f) == 0x1c) {
- /*
- * enter key. All done.
- */
- printk("\n");
- break;
- }
-
- /*
- * echo the character.
- */
- printk("%c", keychar&0xff);
-
- if (bufsize) {
- --bufsize;
- *cp++ = keychar&0xff;
- } else {
- printk("buffer overflow\n");
- break;
- }
-
- }
-
- *cp++ = '\n'; /* White space for parser */
- *cp++ = '\0'; /* String termination */
-
-#if defined(NOTNOW)
- cp = buffer;
- while (*cp) {
- printk("char 0x%x\n", *cp++);
- }
-#endif
-
- return buffer;
-#endif /* !CONFIG_IA64_HP_SIM */
-}
-
diff --git a/arch/ia64/kdb/kdb_traps.c b/arch/ia64/kdb/kdb_traps.c
deleted file mode 100644
index 6358f7a30..000000000
--- a/arch/ia64/kdb/kdb_traps.c
+++ /dev/null
@@ -1,55 +0,0 @@
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/kdb.h>
-
-static struct kdb_bp_support {
- unsigned long addr ;
- int slot ;
-} kdb_bp_info[NR_CPUS] ;
-
-
-extern void kdb_bp_install (void);
-
-/*
- * This gets invoked right before a call to ia64_fault().
- * Returns zero the normal fault handler should be invoked.
- */
-long
-ia64_kdb_fault_handler (unsigned long vector, unsigned long isr, unsigned long ifa,
- unsigned long iim, unsigned long itir, unsigned long arg5,
- unsigned long arg6, unsigned long arg7, unsigned long stack)
-{
- struct switch_stack *sw = (struct switch_stack *) &stack;
- struct pt_regs *regs = (struct pt_regs *) (sw + 1);
- int bundle_slot;
-
- /*
- * TBD
- * If KDB is configured, enter KDB for any fault.
- */
- if ((vector == 29) || (vector == 35) || (vector == 36)) {
- if (!user_mode(regs)) {
- bundle_slot = ia64_psr(regs)->ri;
- if (vector == 29) {
- if (bundle_slot == 0) {
- kdb_bp_info[0].addr = regs->cr_iip;
- kdb_bp_info[0].slot = bundle_slot;
- kdb(KDB_REASON_FLTDBG, 0, regs);
- } else {
- if ((bundle_slot < 3) &&
- (kdb_bp_info[0].addr == regs->cr_iip))
- {
- ia64_psr(regs)->id = 1;
- ia64_psr(regs)->db = 1;
- kdb_bp_install() ;
- } else /* some error ?? */
- kdb(KDB_REASON_FLTDBG, 0, regs);
- }
- } else /* single step or taken branch */
- kdb(KDB_REASON_DEBUG, 0, regs);
- return 1;
- }
- }
- return 0;
-}
diff --git a/arch/ia64/kdb/kdbsupport.c b/arch/ia64/kdb/kdbsupport.c
deleted file mode 100644
index d074a01a3..000000000
--- a/arch/ia64/kdb/kdbsupport.c
+++ /dev/null
@@ -1,1329 +0,0 @@
-/*
- * Minimalist Kernel Debugger
- *
- * Copyright (C) 1999 Silicon Graphics, Inc.
- * Copyright (C) Scott Lurndal (slurn@engr.sgi.com)
- * Copyright (C) Scott Foehner (sfoehner@engr.sgi.com)
- * Copyright (C) Srinivasa Thirumalachar (sprasad@engr.sgi.com)
- * Copyright (C) David Mosberger-Tang <davidm@hpl.hp.com>
- *
- * Written March 1999 by Scott Lurndal at Silicon Graphics, Inc.
- *
- * Modifications from:
- * Richard Bass 1999/07/20
- * Many bug fixes and enhancements.
- * Scott Foehner
- * Port to ia64
- * Srinivasa Thirumalachar
- * RSE support for ia64
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/kdb.h>
-#include <linux/stddef.h>
-#include <linux/vmalloc.h>
-
-#include <asm/delay.h>
-#include <asm/kdbsupport.h>
-#include <asm/rse.h>
-#include <asm/uaccess.h>
-
-extern kdb_state_t kdb_state ;
-k_machreg_t dbregs[KDB_DBREGS];
-
-static int __init
-kdb_setup (char *str)
-{
- kdb_flags |= KDB_FLAG_EARLYKDB;
- return 1;
-}
-
-__setup("kdb", kdb_setup);
-
-static int
-kdb_ia64_itm (int argc, const char **argv, const char **envp, struct pt_regs *regs)
-{
- int diag;
- unsigned long val;
-
- diag = kdbgetularg(argv[1], &val);
- if (diag)
- return diag;
- kdb_printf("new itm=%0xlx\n", val);
-
- ia64_set_itm(val);
- return 0;
-}
-
-static int
-kdb_ia64_sir (int argc, const char **argv, const char **envp, struct pt_regs *regs)
-{
- u64 lid, tpr, lrr0, lrr1, itv, pmv, cmcv;
-
- asm ("mov %0=cr.lid" : "=r"(lid));
- asm ("mov %0=cr.tpr" : "=r"(tpr));
- asm ("mov %0=cr.lrr0" : "=r"(lrr0));
- asm ("mov %0=cr.lrr1" : "=r"(lrr1));
- printk("lid=0x%lx, tpr=0x%lx, lrr0=0x%lx, llr1=0x%lx\n", lid, tpr, lrr0, lrr1);
-
- asm ("mov %0=cr.itv" : "=r"(itv));
- asm ("mov %0=cr.pmv" : "=r"(pmv));
- asm ("mov %0=cr.cmcv" : "=r"(cmcv));
- printk("itv=0x%lx, pmv=0x%lx, cmcv=0x%lx\n", itv, pmv, cmcv);
-
- printk("irr=0x%016lx,0x%016lx,0x%016lx,0x%016lx\n",
- ia64_get_irr0(), ia64_get_irr1(), ia64_get_irr2(), ia64_get_irr3());
-
- printk("itc=0x%016lx, itm=0x%016lx\n", ia64_get_itc(), ia64_get_itm());
- return 0;
-}
-
-void __init
-kdb_init (void)
-{
- extern void kdb_inittab(void);
- unsigned long reg;
-
- kdb_inittab();
- kdb_initbptab();
-#if 0
- kdb_disinit();
-#endif
- kdb_printf("kdb version %d.%d by Scott Lurndal. "\
- "Copyright SGI, All Rights Reserved\n",
- KDB_MAJOR_VERSION, KDB_MINOR_VERSION);
-
- /* Enable debug registers */
- __asm__ ("mov %0=psr":"=r"(reg));
- reg |= IA64_PSR_DB;
- __asm__ ("mov psr.l=%0"::"r"(reg));
- ia64_srlz_d();
-
- /* Init kdb state */
- kdb_state.bkpt_handling_state = BKPTSTATE_NOT_HANDLED ;
-
- kdb_register("irr", kdb_ia64_sir, "", "Show interrupt registers", 0);
- kdb_register("itm", kdb_ia64_itm, "", "Set new ITM value", 0);
-}
-
-/*
- * kdbprintf
- * kdbgetword
- * kdb_getstr
- */
-
-char *
-kbd_getstr(char *buffer, size_t bufsize, char *prompt)
-{
- extern char* kdb_getscancode(char *, size_t);
-
-#if defined(CONFIG_SMP)
- kdb_printf(prompt, smp_processor_id());
-#else
- kdb_printf("%s", prompt);
-#endif
-
- return kdb_getscancode(buffer, bufsize);
-
-}
-
-int
-kdb_printf(const char *fmt, ...)
-{
- char buffer[256];
- va_list ap;
- int diag;
- int linecount;
-
- diag = kdbgetintenv("LINES", &linecount);
- if (diag)
- linecount = 22;
-
- va_start(ap, fmt);
- vsprintf(buffer, fmt, ap);
- va_end(ap);
-
- printk("%s", buffer);
-#if 0
- if (strchr(buffer, '\n') != NULL) {
- kdb_nextline++;
- }
-
- if (kdb_nextline == linecount) {
- char buf1[16];
- char buf2[32];
- extern char* kdb_getscancode(char *, size_t);
- char *moreprompt;
-
- /*
- * Pause until cr.
- */
- moreprompt = kdbgetenv("MOREPROMPT");
- if (moreprompt == NULL) {
- moreprompt = "more> ";
- }
-
-#if defined(CONFIG_SMP)
- if (strchr(moreprompt, '%')) {
- sprintf(buf2, moreprompt, smp_processor_id());
- moreprompt = buf2;
- }
-#endif
-
- printk(moreprompt);
- (void) kdb_getscancode(buf1, sizeof(buf1));
-
- kdb_nextline = 1;
-
- if ((buf1[0] == 'q')
- || (buf1[0] == 'Q')) {
- kdb_longjmp(&kdbjmpbuf, 1);
- }
- }
-#endif
- return 0;
-}
-
-unsigned long
-kdbgetword(unsigned long addr, int width)
-{
- /*
- * This function checks the address for validity. Any address
- * in the range PAGE_OFFSET to high_memory is legal, any address
- * which maps to a vmalloc region is legal, and any address which
- * is a user address, we use get_user() to verify validity.
- */
-
- if (addr < PAGE_OFFSET) {
- /*
- * Usermode address.
- */
- unsigned long diag;
- unsigned long ulval;
-
- switch (width) {
- case 8:
- { unsigned long *lp;
-
- lp = (unsigned long *) addr;
- diag = get_user(ulval, lp);
- break;
- }
- case 4:
- { unsigned int *ip;
-
- ip = (unsigned int *) addr;
- diag = get_user(ulval, ip);
- break;
- }
- case 2:
- { unsigned short *sp;
-
- sp = (unsigned short *) addr;
- diag = get_user(ulval, sp);
- break;
- }
- case 1:
- { unsigned char *cp;
-
- cp = (unsigned char *) addr;
- diag = get_user(ulval, cp);
- break;
- }
- default:
- printk("kdbgetword: Bad width\n");
- return 0L;
- }
-
- if (diag) {
- if ((kdb_flags & KDB_FLAG_SUPRESS) == 0) {
- printk("kdb: Bad user address 0x%lx\n", addr);
- kdb_flags |= KDB_FLAG_SUPRESS;
- }
- return 0L;
- }
- kdb_flags &= ~KDB_FLAG_SUPRESS;
- return ulval;
- }
-
- if (addr > (unsigned long)high_memory) {
- extern int kdb_vmlist_check(unsigned long, unsigned long);
-
- if (!kdb_vmlist_check(addr, addr+width)) {
- /*
- * Would appear to be an illegal kernel address;
- * Print a message once, and don't print again until
- * a legal address is used.
- */
- if ((kdb_flags & KDB_FLAG_SUPRESS) == 0) {
- printk("kdb: Bad kernel address 0x%lx\n", addr);
- kdb_flags |= KDB_FLAG_SUPRESS;
- }
- return 0L;
- }
- }
-
- /*
- * A good address. Reset error flag.
- */
- kdb_flags &= ~KDB_FLAG_SUPRESS;
-
- switch (width) {
- case 8:
- { unsigned long *lp;
-
- lp = (unsigned long *)(addr);
- return *lp;
- }
- case 4:
- { unsigned int *ip;
-
- ip = (unsigned int *)(addr);
- return *ip;
- }
- case 2:
- { unsigned short *sp;
-
- sp = (unsigned short *)(addr);
- return *sp;
- }
- case 1:
- { unsigned char *cp;
-
- cp = (unsigned char *)(addr);
- return *cp;
- }
- }
-
- printk("kdbgetword: Bad width\n");
- return 0L;
-}
-
-/*
- * Start of breakpoint management routines
- */
-
-/*
- * Arg: bp structure
- */
-
-int
-kdb_allocdbreg(kdb_bp_t *bp)
-{
- int i=0;
-
- /* For inst bkpt, just return. No hw reg alloc to be done. */
-
- if (bp->bp_mode == BKPTMODE_INST) {
- return i;
- } else if (bp->bp_mode == BKPTMODE_DATAW) {
- for(i=0; i<KDB_DBREGS; i++) {
- if (dbregs[i] == 0xffffffff) {
- dbregs[i] = 0;
- return i;
- }
- }
- }
-
- return -1;
-}
-
-void
-kdb_freedbreg(kdb_bp_t *bp)
-{
- if (bp->bp_mode == BKPTMODE_DATAW)
- dbregs[bp->bp_reg] = 0xffffffff;
-}
-
-void
-kdb_initdbregs(void)
-{
- int i;
-
- for(i=0; i<KDB_DBREGS; i++) {
- dbregs[i] = 0xffffffff;
- }
-}
-int
-kdbinstalltrap(int type, handler_t newh, handler_t *oldh)
-{
- /*
- * Usurp INTn. XXX - TBD.
- */
-
- return 0;
-}
-
-int
-install_instbkpt(kdb_bp_t *bp)
-{
- unsigned long *addr = (unsigned long *)bp->bp_addr ;
- bundle_t *bundle = (bundle_t *)bp->bp_longinst;
-
- /* save current bundle */
- *bundle = *(bundle_t *)addr ;
-
- /* Set the break point! */
- ((bundle_t *)addr)->lform.low8 = (
- (((bundle_t *)addr)->lform.low8 & ~INST_SLOT0_MASK) |
- BREAK_INSTR);
-
- /* set flag */
- bp->bp_instvalid = 1 ;
-
- /* flush icache as it is stale now */
- ia64_flush_icache_page((unsigned long)addr) ;
-
-#ifdef KDB_DEBUG
- kdb_printf ("[0x%016lx]: install 0x%016lx with 0x%016lx\n",
- addr, bundle->lform.low8, addr[0]) ;
-#endif
- return 0 ;
-}
-
-int
-install_databkpt(kdb_bp_t *bp)
-{
- unsigned long dbreg_addr = bp->bp_reg * 2;
- unsigned long dbreg_cond = dbreg_addr + 1;
- unsigned long value = 0x8fffffffffffffff;
- unsigned long addr = (unsigned long)bp->bp_addr;
- __asm__ ("mov dbr[%0]=%1"::"r"(dbreg_cond),"r"(value));
-// __asm__ ("movl %0,%%db0\n\t"::"r"(contents));
- __asm__ ("mov dbr[%0]=%1"::"r"(dbreg_addr),"r"(addr));
- ia64_insn_group_barrier();
- ia64_srlz_i();
- ia64_insn_group_barrier();
-
-#ifdef KDB_DEBUG
- kdb_printf("installed dbkpt at 0x%016lx\n", addr) ;
-#endif
- return 0;
-}
-
-int
-kdbinstalldbreg(kdb_bp_t *bp)
-{
- if (bp->bp_mode == BKPTMODE_INST) {
- return install_instbkpt(bp) ;
- } else if (bp->bp_mode == BKPTMODE_DATAW) {
- return install_databkpt(bp) ;
- }
- return 0;
-}
-
-void
-remove_instbkpt(kdb_bp_t *bp)
-{
- unsigned long *addr = (unsigned long *)bp->bp_addr ;
- bundle_t *bundle = (bundle_t *)bp->bp_longinst;
-
- if (!bp->bp_instvalid)
- /* Nothing to remove. If we just alloced the bkpt
- * but never resumed, the bp_inst will not be valid. */
- return ;
-
-#ifdef KDB_DEBUG
- kdb_printf ("[0x%016lx]: remove 0x%016lx with 0x%016lx\n",
- addr, addr[0], bundle->lform.low8) ;
-#endif
-
- /* restore current bundle */
- *(bundle_t *)addr = *bundle ;
- /* reset the flag */
- bp->bp_instvalid = 0 ;
- ia64_flush_icache_page((unsigned long)addr) ;
-}
-
-void
-remove_databkpt(kdb_bp_t *bp)
-{
- int regnum = bp->bp_reg ;
- unsigned long dbreg_addr = regnum * 2;
- unsigned long dbreg_cond = dbreg_addr + 1;
- unsigned long value = 0x0fffffffffffffff;
- __asm__ ("mov dbr[%0]=%1"::"r"(dbreg_cond),"r"(value));
-// __asm__ ("movl %0,%%db0\n\t"::"r"(contents));
- ia64_insn_group_barrier();
- ia64_srlz_i();
- ia64_insn_group_barrier();
-
-#ifdef KDB_DEBUG
- kdb_printf("removed dbkpt at 0x%016lx\n", bp->bp_addr) ;
-#endif
-}
-
-void
-kdbremovedbreg(kdb_bp_t *bp)
-{
- if (bp->bp_mode == BKPTMODE_INST) {
- remove_instbkpt(bp) ;
- } else if (bp->bp_mode == BKPTMODE_DATAW) {
- remove_databkpt(bp) ;
- }
-}
-
-k_machreg_t
-kdb_getdr6(void)
-{
- return kdb_getdr(6);
-}
-
-k_machreg_t
-kdb_getdr7(void)
-{
- return kdb_getdr(7);
-}
-
-k_machreg_t
-kdb_getdr(int regnum)
-{
- k_machreg_t contents = 0;
- unsigned long reg = (unsigned long)regnum;
-
- __asm__ ("mov %0=ibr[%1]"::"r"(contents),"r"(reg));
-// __asm__ ("mov ibr[%0]=%1"::"r"(dbreg_cond),"r"(value));
-
- return contents;
-}
-
-
-k_machreg_t
-kdb_getcr(int regnum)
-{
- k_machreg_t contents = 0;
- return contents;
-}
-
-void
-kdb_putdr6(k_machreg_t contents)
-{
- kdb_putdr(6, contents);
-}
-
-void
-kdb_putdr7(k_machreg_t contents)
-{
- kdb_putdr(7, contents);
-}
-
-void
-kdb_putdr(int regnum, k_machreg_t contents)
-{
-}
-
-void
-get_fault_regs(fault_regs_t *fr)
-{
- fr->ifa = 0 ;
- fr->isr = 0 ;
-
- __asm__ ("rsm psr.ic;;") ;
- ia64_srlz_d();
- __asm__ ("mov %0=cr.ifa" : "=r"(fr->ifa));
- __asm__ ("mov %0=cr.isr" : "=r"(fr->isr));
- __asm__ ("ssm psr.ic;;") ;
- ia64_srlz_d();
-}
-
-/*
- * kdb_db_trap
- *
- * Perform breakpoint processing upon entry to the
- * processor debugger fault. Determine and print
- * the active breakpoint.
- *
- * Parameters:
- * ef Exception frame containing machine register state
- * reason Why did we enter kdb - fault or break
- * Outputs:
- * None.
- * Returns:
- * 0 Standard instruction or data breakpoint encountered
- * 1 Single Step fault ('ss' command)
- * 2 Single Step fault, caller should continue ('ssb' command)
- * Locking:
- * None.
- * Remarks:
- * Yup, there be goto's here.
- */
-
-int
-kdb_db_trap(struct pt_regs *ef, int reason)
-{
- int i, rv=0;
-
- /* Trying very hard to not change the interface to kdb.
- * So, eventhough we have these values in the fault function
- * it is not passed in but read again.
- */
- fault_regs_t faultregs ;
-
- if (reason == KDB_REASON_FLTDBG)
- get_fault_regs(&faultregs) ;
-
- /* NOTE : XXX: This has to be done only for data bkpts */
- /* Prevent it from continuously faulting */
- ef->cr_ipsr |= 0x0000002000000000;
-
- if (ef->cr_ipsr & 0x0000010000000000) {
- /* single step */
- ef->cr_ipsr &= 0xfffffeffffffffff;
- if ((kdb_state.bkpt_handling_state == BKPTSTATE_HANDLED)
- && (kdb_state.cmd_given == CMDGIVEN_GO))
- ;
- else
- kdb_printf("SS trap at 0x%lx\n", ef->cr_iip + ia64_psr(ef)->ri);
- rv = 1;
- kdb_state.reason_for_entry = ENTRYREASON_SSTEP ;
- goto handled;
- } else
- kdb_state.reason_for_entry = ENTRYREASON_GO ;
-
- /*
- * Determine which breakpoint was encountered.
- */
- for(i=0; i<KDB_MAXBPT; i++) {
- if ((breakpoints[i].bp_enabled)
- && ((breakpoints[i].bp_addr == ef->cr_iip) ||
- ((faultregs.ifa) &&
- (breakpoints[i].bp_addr == faultregs.ifa)))) {
- /*
- * Hit this breakpoint. Remove it while we are
- * handling hit to avoid recursion. XXX ??
- */
- if (breakpoints[i].bp_addr == faultregs.ifa)
- kdb_printf("Data breakpoint #%d for 0x%lx at 0x%lx\n",
- i, breakpoints[i].bp_addr, ef->cr_iip + ia64_psr(ef)->ri);
- else
- kdb_printf("%s breakpoint #%d at 0x%lx\n",
- rwtypes[0],
- i, breakpoints[i].bp_addr);
-
- /*
- * For an instruction breakpoint, disassemble
- * the current instruction.
- */
-#if 0
- if (rw == 0) {
- kdb_id1(ef->eip);
- }
-#endif
-
- goto handled;
- }
- }
-
-#if 0
-unknown:
-#endif
- kdb_printf("Unknown breakpoint. Should forward. \n");
- /* Need a flag for this. The skip should be done XXX
- * when a go or single step command is done for this session.
- * For now it is here.
- */
- ia64_increment_ip(ef) ;
- return rv ;
-
-handled:
-
- /* We are here after handling a break inst/data bkpt */
- if (kdb_state.bkpt_handling_state == BKPTSTATE_NOT_HANDLED) {
- kdb_state.bkpt_handling_state = BKPTSTATE_HANDLED ;
- if (kdb_state.reason_for_entry == ENTRYREASON_GO) {
- kdb_setsinglestep(ef) ;
- kdb_state.kdb_action = ACTION_NOBPINSTALL;
- /* We dont want bp install just this once */
- kdb_state.cmd_given = CMDGIVEN_UNKNOWN ;
- }
- } else if (kdb_state.bkpt_handling_state == BKPTSTATE_HANDLED) {
- kdb_state.bkpt_handling_state = BKPTSTATE_NOT_HANDLED ;
- if (kdb_state.reason_for_entry == ENTRYREASON_SSTEP) {
- if (kdb_state.cmd_given == CMDGIVEN_GO)
- kdb_state.kdb_action = ACTION_NOPROMPT ;
- kdb_state.cmd_given = CMDGIVEN_UNKNOWN ;
- }
- } else
- kdb_printf("Unknown value of bkpt state\n") ;
-
- return rv;
-
-}
-
-void
-kdb_setsinglestep(struct pt_regs *regs)
-{
- regs->cr_ipsr |= 0x0000010000000000;
-#if 0
- regs->eflags |= EF_TF;
-#endif
-}
-
-/*
- * Symbol table functions.
- */
-
-/*
- * kdbgetsym
- *
- * Return the symbol table entry for the given symbol
- *
- * Parameters:
- * symname Character string containing symbol name
- * Outputs:
- * Returns:
- * NULL Symbol doesn't exist
- * ksp Pointer to symbol table entry
- * Locking:
- * None.
- * Remarks:
- */
-
-__ksymtab_t *
-kdbgetsym(const char *symname)
-{
- __ksymtab_t *ksp = __kdbsymtab;
- int i;
-
- if (symname == NULL)
- return NULL;
-
- for (i=0; i<__kdbsymtabsize; i++, ksp++) {
- if (ksp->name && (strcmp(ksp->name, symname)==0)) {
- return ksp;
- }
- }
-
- return NULL;
-}
-
-/*
- * kdbgetsymval
- *
- * Return the address of the given symbol.
- *
- * Parameters:
- * symname Character string containing symbol name
- * Outputs:
- * Returns:
- * 0 Symbol name is NULL
- * addr Address corresponding to symname
- * Locking:
- * None.
- * Remarks:
- */
-
-unsigned long
-kdbgetsymval(const char *symname)
-{
- __ksymtab_t *ksp = kdbgetsym(symname);
-
- return (ksp?ksp->value:0);
-}
-
-/*
- * kdbaddmodsym
- *
- * Add a symbol to the kernel debugger symbol table. Called when
- * a new module is loaded into the kernel.
- *
- * Parameters:
- * symname Character string containing symbol name
- * value Value of symbol
- * Outputs:
- * Returns:
- * 0 Successfully added to table.
- * 1 Duplicate symbol
- * 2 Symbol table full
- * Locking:
- * None.
- * Remarks:
- */
-
-int
-kdbaddmodsym(char *symname, unsigned long value)
-{
-
- /*
- * Check for duplicate symbols.
- */
- if (kdbgetsym(symname)) {
- printk("kdb: Attempt to register duplicate symbol '%s' @ 0x%lx\n",
- symname, value);
- return 1;
- }
-
- if (__kdbsymtabsize < __kdbmaxsymtabsize) {
- __ksymtab_t *ksp = &__kdbsymtab[__kdbsymtabsize++];
-
- ksp->name = symname;
- ksp->value = value;
- return 0;
- }
-
- /*
- * No room left in kernel symbol table.
- */
- {
- static int __kdbwarn = 0;
-
- if (__kdbwarn == 0) {
- __kdbwarn++;
- printk("kdb: Exceeded symbol table size. Increase CONFIG_KDB_SYMTAB_SIZE in kernel configuration\n");
- }
- }
-
- return 2;
-}
-
-/*
- * kdbdelmodsym
- *
- * Add a symbol to the kernel debugger symbol table. Called when
- * a new module is loaded into the kernel.
- *
- * Parameters:
- * symname Character string containing symbol name
- * value Value of symbol
- * Outputs:
- * Returns:
- * 0 Successfully added to table.
- * 1 Symbol not found
- * Locking:
- * None.
- * Remarks:
- */
-
-int
-kdbdelmodsym(const char *symname)
-{
- __ksymtab_t *ksp, *endksp;
-
- if (symname == NULL)
- return 1;
-
- /*
- * Search for the symbol. If found, move
- * all successive symbols down one position
- * in the symbol table to avoid leaving holes.
- */
- endksp = &__kdbsymtab[__kdbsymtabsize];
- for (ksp = __kdbsymtab; ksp < endksp; ksp++) {
- if (ksp->name && (strcmp(ksp->name, symname) == 0)) {
- endksp--;
- for ( ; ksp < endksp; ksp++) {
- *ksp = *(ksp + 1);
- }
- __kdbsymtabsize--;
- return 0;
- }
- }
-
- return 1;
-}
-
-/*
- * kdbnearsym
- *
- * Return the name of the symbol with the nearest address
- * less than 'addr'.
- *
- * Parameters:
- * addr Address to check for symbol near
- * Outputs:
- * Returns:
- * NULL No symbol with address less than 'addr'
- * symbol Returns the actual name of the symbol.
- * Locking:
- * None.
- * Remarks:
- */
-
-char *
-kdbnearsym(unsigned long addr)
-{
- __ksymtab_t *ksp = __kdbsymtab;
- __ksymtab_t *kpp = NULL;
- int i;
-
- for(i=0; i<__kdbsymtabsize; i++, ksp++) {
- if (!ksp->name)
- continue;
-
- if (addr == ksp->value) {
- kpp = ksp;
- break;
- }
- if (addr > ksp->value) {
- if ((kpp == NULL)
- || (ksp->value > kpp->value)) {
- kpp = ksp;
- }
- }
- }
-
- /*
- * If more than 128k away, don't bother.
- */
- if ((kpp == NULL)
- || ((addr - kpp->value) > 0x20000)) {
- return NULL;
- }
-
- return kpp->name;
-}
-
-/*
- * kdbgetregcontents
- *
- * Return the contents of the register specified by the
- * input string argument. Return an error if the string
- * does not match a machine register.
- *
- * The following pseudo register names are supported:
- * &regs - Prints address of exception frame
- * kesp - Prints kernel stack pointer at time of fault
- * sstk - Prints switch stack for ia64
- * %<regname> - Uses the value of the registers at the
- * last time the user process entered kernel
- * mode, instead of the registers at the time
- * kdb was entered.
- *
- * Parameters:
- * regname Pointer to string naming register
- * regs Pointer to structure containing registers.
- * Outputs:
- * *contents Pointer to unsigned long to recieve register contents
- * Returns:
- * 0 Success
- * KDB_BADREG Invalid register name
- * Locking:
- * None.
- * Remarks:
- *
- * Note that this function is really machine independent. The kdb
- * register list is not, however.
- */
-
-static struct kdbregs {
- char *reg_name;
- size_t reg_offset;
-} kdbreglist[] = {
- { " psr", offsetof(struct pt_regs, cr_ipsr) },
- { " ifs", offsetof(struct pt_regs, cr_ifs) },
- { " ip", offsetof(struct pt_regs, cr_iip) },
-
- { "unat", offsetof(struct pt_regs, ar_unat) },
- { " pfs", offsetof(struct pt_regs, ar_pfs) },
- { " rsc", offsetof(struct pt_regs, ar_rsc) },
-
- { "rnat", offsetof(struct pt_regs, ar_rnat) },
- { "bsps", offsetof(struct pt_regs, ar_bspstore) },
- { " pr", offsetof(struct pt_regs, pr) },
-
- { "ldrs", offsetof(struct pt_regs, loadrs) },
- { " ccv", offsetof(struct pt_regs, ar_ccv) },
- { "fpsr", offsetof(struct pt_regs, ar_fpsr) },
-
- { " b0", offsetof(struct pt_regs, b0) },
- { " b6", offsetof(struct pt_regs, b6) },
- { " b7", offsetof(struct pt_regs, b7) },
-
- { " r1",offsetof(struct pt_regs, r1) },
- { " r2",offsetof(struct pt_regs, r2) },
- { " r3",offsetof(struct pt_regs, r3) },
-
- { " r8",offsetof(struct pt_regs, r8) },
- { " r9",offsetof(struct pt_regs, r9) },
- { " r10",offsetof(struct pt_regs, r10) },
-
- { " r11",offsetof(struct pt_regs, r11) },
- { " r12",offsetof(struct pt_regs, r12) },
- { " r13",offsetof(struct pt_regs, r13) },
-
- { " r14",offsetof(struct pt_regs, r14) },
- { " r15",offsetof(struct pt_regs, r15) },
- { " r16",offsetof(struct pt_regs, r16) },
-
- { " r17",offsetof(struct pt_regs, r17) },
- { " r18",offsetof(struct pt_regs, r18) },
- { " r19",offsetof(struct pt_regs, r19) },
-
- { " r20",offsetof(struct pt_regs, r20) },
- { " r21",offsetof(struct pt_regs, r21) },
- { " r22",offsetof(struct pt_regs, r22) },
-
- { " r23",offsetof(struct pt_regs, r23) },
- { " r24",offsetof(struct pt_regs, r24) },
- { " r25",offsetof(struct pt_regs, r25) },
-
- { " r26",offsetof(struct pt_regs, r26) },
- { " r27",offsetof(struct pt_regs, r27) },
- { " r28",offsetof(struct pt_regs, r28) },
-
- { " r29",offsetof(struct pt_regs, r29) },
- { " r30",offsetof(struct pt_regs, r30) },
- { " r31",offsetof(struct pt_regs, r31) },
-
-};
-
-static const int nkdbreglist = sizeof(kdbreglist) / sizeof(struct kdbregs);
-
-int
-kdbgetregcontents(const char *regname,
- struct pt_regs *regs,
- unsigned long *contents)
-{
- int i;
-
- if (strcmp(regname, "&regs") == 0) {
- *contents = (unsigned long)regs;
- return 0;
- }
-
- if (strcmp(regname, "sstk") == 0) {
- *contents = (unsigned long)getprsregs(regs) ;
- return 0;
- }
-
- if (strcmp(regname, "isr") == 0) {
- fault_regs_t fr ;
- get_fault_regs(&fr) ;
- *contents = fr.isr ;
- return 0 ;
- }
-
-#if 0
- /* XXX need to verify this */
- if (strcmp(regname, "kesp") == 0) {
- *contents = (unsigned long)regs + sizeof(struct pt_regs);
- return 0;
- }
-
- if (regname[0] == '%') {
- /* User registers: %%e[a-c]x, etc */
- regname++;
- regs = (struct pt_regs *)
- (current->thread.ksp - sizeof(struct pt_regs));
- }
-#endif
-
- for (i=0; i<nkdbreglist; i++) {
- if (strstr(kdbreglist[i].reg_name, regname))
- break;
- }
-
- if (i == nkdbreglist) {
- /* Lets check the rse maybe */
- if (regname[0] == 'r')
- if (show_cur_stack_frame(regs, simple_strtoul(regname+1, 0, 0) - 31,
- contents))
- return 0 ;
- return KDB_BADREG;
- }
-
- *contents = *(unsigned long *)((unsigned long)regs +
- kdbreglist[i].reg_offset);
-
- return 0;
-}
-
-/*
- * kdbsetregcontents
- *
- * Set the contents of the register specified by the
- * input string argument. Return an error if the string
- * does not match a machine register.
- *
- * Supports modification of user-mode registers via
- * %<register-name>
- *
- * Parameters:
- * regname Pointer to string naming register
- * regs Pointer to structure containing registers.
- * contents Unsigned long containing new register contents
- * Outputs:
- * Returns:
- * 0 Success
- * KDB_BADREG Invalid register name
- * Locking:
- * None.
- * Remarks:
- */
-
-int
-kdbsetregcontents(const char *regname,
- struct pt_regs *regs,
- unsigned long contents)
-{
- int i;
-
- if (regname[0] == '%') {
- regname++;
- regs = (struct pt_regs *)
- (current->thread.ksp - sizeof(struct pt_regs));
- }
-
- for (i=0; i<nkdbreglist; i++) {
- if (strnicmp(kdbreglist[i].reg_name,
- regname,
- strlen(regname)) == 0)
- break;
- }
-
- if ((i == nkdbreglist)
- || (strlen(kdbreglist[i].reg_name) != strlen(regname))) {
- return KDB_BADREG;
- }
-
- *(unsigned long *)((unsigned long)regs + kdbreglist[i].reg_offset) =
- contents;
-
- return 0;
-}
-
-/*
- * kdbdumpregs
- *
- * Dump the specified register set to the display.
- *
- * Parameters:
- * regs Pointer to structure containing registers.
- * type Character string identifying register set to dump
- * extra string further identifying register (optional)
- * Outputs:
- * Returns:
- * 0 Success
- * Locking:
- * None.
- * Remarks:
- * This function will dump the general register set if the type
- * argument is NULL (struct pt_regs). The alternate register
- * set types supported by this function:
- *
- * d Debug registers
- * c Control registers
- * u User registers at most recent entry to kernel
- * Following not yet implemented:
- * m Model Specific Registers (extra defines register #)
- * r Memory Type Range Registers (extra defines register)
- *
- * For now, all registers are covered as follows:
- *
- * rd - dumps all regs
- * rd %isr - current interrupt status reg, read freshly
- * rd s - valid stacked regs
- * rd %sstk - gets switch stack addr. dump memory and search
- * rd d - debug regs, may not be too useful
- *
- * ARs TB Done
- * Interrupt regs TB Done ??
- * OTHERS TB Decided ??
- *
- * Intel wish list
- * These will be implemented later - Srinivasa
- *
- * type action
- * ---- ------
- * g dump all General static registers
- * s dump all general Stacked registers
- * f dump all Floating Point registers
- * p dump all Predicate registers
- * b dump all Branch registers
- * a dump all Application registers
- * c dump all Control registers
- *
- */
-
-int
-kdbdumpregs(struct pt_regs *regs,
- const char *type,
- const char *extra)
-
-{
- int i;
- int count = 0;
-
- if (type
- && (type[0] == 'u')) {
- type = NULL;
- regs = (struct pt_regs *)
- (current->thread.ksp - sizeof(struct pt_regs));
- }
-
- if (type == NULL) {
- for (i=0; i<nkdbreglist; i++) {
- kdb_printf("%s: 0x%16.16lx ",
- kdbreglist[i].reg_name,
- *(unsigned long *)((unsigned long)regs +
- kdbreglist[i].reg_offset));
-
- if ((++count % 3) == 0)
- kdb_printf("\n");
- }
-
- kdb_printf("&regs = 0x%16.16lx\n", regs);
-
- return 0;
- }
-
- switch (type[0]) {
- case 'd':
- {
- for(i=0; i<8; i+=2) {
- kdb_printf("idr%d: 0x%16.16lx idr%d: 0x%16.16lx\n", i,
- kdb_getdr(i), i+1, kdb_getdr(i+1));
-
- }
- return 0;
- }
-#if 0
- case 'c':
- {
- unsigned long cr[5];
-
- for (i=0; i<5; i++) {
- cr[i] = kdb_getcr(i);
- }
- kdb_printf("cr0 = 0x%8.8x cr1 = 0x%8.8x cr2 = 0x%8.8x cr3 = 0x%8.8x\ncr4 = 0x%8.8x\n",
- cr[0], cr[1], cr[2], cr[3], cr[4]);
- return 0;
- }
-#endif
- case 'm':
- break;
- case 'r':
- break;
-
- case 's':
- {
- show_cur_stack_frame(regs, 0, NULL) ;
-
- return 0 ;
- }
-
- case '%':
- {
- unsigned long contents ;
-
- if (!kdbgetregcontents(type+1, regs, &contents))
- kdb_printf("%s = 0x%16.16lx\n", type+1, contents) ;
- else
- kdb_printf("diag: Invalid register %s\n", type+1) ;
-
- return 0 ;
- }
-
- default:
- return KDB_BADREG;
- }
-
- /* NOTREACHED */
- return 0;
-}
-
-k_machreg_t
-kdb_getpc(struct pt_regs *regs)
-{
- return regs->cr_iip + ia64_psr(regs)->ri;
-}
-
-int
-kdb_setpc(struct pt_regs *regs, k_machreg_t newpc)
-{
- regs->cr_iip = newpc & ~0xf;
- ia64_psr(regs)->ri = newpc & 0x3;
- return 0;
-}
-
-void
-kdb_disableint(kdbintstate_t *state)
-{
- int *fp = (int *)state;
- int flags;
-
- __save_flags(flags);
- __cli();
-
- *fp = flags;
-}
-
-void
-kdb_restoreint(kdbintstate_t *state)
-{
- int flags = *(int *)state;
- __restore_flags(flags);
-}
-
-int
-kdb_putword(unsigned long addr, unsigned long contents)
-{
- *(unsigned long *)addr = contents;
- return 0;
-}
-
-int
-kdb_getcurrentframe(struct pt_regs *regs)
-{
-#if 0
- regs->xcs = 0;
-#if defined(CONFIG_KDB_FRAMEPTR)
- asm volatile("movl %%ebp,%0":"=m" (*(int *)&regs->ebp));
-#endif
- asm volatile("movl %%esp,%0":"=m" (*(int *)&regs->esp));
-#endif
- return 0;
-}
-
-unsigned long
-show_cur_stack_frame(struct pt_regs *regs, int regno, unsigned long *contents)
-{
- long sof = regs->cr_ifs & ((1<<7)-1) ; /* size of frame */
- unsigned long i ;
- int j;
- struct switch_stack *prs_regs = getprsregs(regs) ;
- unsigned long *sofptr = (prs_regs? ia64_rse_skip_regs(
- (unsigned long *)prs_regs->ar_bspstore, -sof) : NULL) ;
-
- if (!sofptr) {
- printk("Unable to display Current Stack Frame\n") ;
- return 0 ;
- }
-
- if (regno < 0)
- return 0 ;
-
- for (i=sof, j=0;i;i--,j++) {
- /* remember to skip the nat collection dword */
- if ((((unsigned long)sofptr>>3) & (((1<<6)-1)))
- == ((1<<6)-1))
- sofptr++ ;
-
- /* return the value in the reg if regno is non zero */
-
- if (regno) {
- if ((j+1) == regno) {
- if (contents)
- *contents = *sofptr ;
- return -1;
- }
- sofptr++ ;
- } else {
- printk(" r%d: %016lx ", 32+j, *sofptr++) ;
- if (!((j+1)%3)) printk("\n") ;
- }
- }
-
- if (regno) {
- if (!i) /* bogus rse number */
- return 0 ;
- } else
- printk("\n") ;
-
- return 0 ;
-}
diff --git a/arch/ia64/kdb/pc_keyb.h b/arch/ia64/kdb/pc_keyb.h
deleted file mode 100644
index 3d4831a80..000000000
--- a/arch/ia64/kdb/pc_keyb.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * linux/drivers/char/pc_keyb.h
- *
- * PC Keyboard And Keyboard Controller
- *
- * (c) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
- */
-
-/*
- * Configuration Switches
- */
-
-#undef KBD_REPORT_ERR /* Report keyboard errors */
-#define KBD_REPORT_UNKN /* Report unknown scan codes */
-#define KBD_REPORT_TIMEOUTS /* Report keyboard timeouts */
-#undef KBD_IS_FOCUS_9000 /* We have the brain-damaged FOCUS-9000 keyboard */
-#undef INITIALIZE_MOUSE /* Define if your PS/2 mouse needs initialization. */
-
-
-
-#define KBD_INIT_TIMEOUT 1000 /* Timeout in ms for initializing the keyboard */
-#define KBC_TIMEOUT 250 /* Timeout in ms for sending to keyboard controller */
-#define KBD_TIMEOUT 1000 /* Timeout in ms for keyboard command acknowledge */
-
-/*
- * Internal variables of the driver
- */
-
-extern unsigned char pckbd_read_mask;
-extern unsigned char aux_device_present;
-
-/*
- * Keyboard Controller Registers
- */
-
-#define KBD_STATUS_REG 0x64 /* Status register (R) */
-#define KBD_CNTL_REG 0x64 /* Controller command register (W) */
-#define KBD_DATA_REG 0x60 /* Keyboard data register (R/W) */
-
-/*
- * Keyboard Controller Commands
- */
-
-#define KBD_CCMD_READ_MODE 0x20 /* Read mode bits */
-#define KBD_CCMD_WRITE_MODE 0x60 /* Write mode bits */
-#define KBD_CCMD_GET_VERSION 0xA1 /* Get controller version */
-#define KBD_CCMD_MOUSE_DISABLE 0xA7 /* Disable mouse interface */
-#define KBD_CCMD_MOUSE_ENABLE 0xA8 /* Enable mouse interface */
-#define KBD_CCMD_TEST_MOUSE 0xA9 /* Mouse interface test */
-#define KBD_CCMD_SELF_TEST 0xAA /* Controller self test */
-#define KBD_CCMD_KBD_TEST 0xAB /* Keyboard interface test */
-#define KBD_CCMD_KBD_DISABLE 0xAD /* Keyboard interface disable */
-#define KBD_CCMD_KBD_ENABLE 0xAE /* Keyboard interface enable */
-#define KBD_CCMD_WRITE_AUX_OBUF 0xD3 /* Write to output buffer as if
- initiated by the auxiliary device */
-#define KBD_CCMD_WRITE_MOUSE 0xD4 /* Write the following byte to the mouse */
-
-/*
- * Keyboard Commands
- */
-
-#define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
-#define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */
-#define KBD_CMD_ENABLE 0xF4 /* Enable scanning */
-#define KBD_CMD_DISABLE 0xF5 /* Disable scanning */
-#define KBD_CMD_RESET 0xFF /* Reset */
-
-/*
- * Keyboard Replies
- */
-
-#define KBD_REPLY_POR 0xAA /* Power on reset */
-#define KBD_REPLY_ACK 0xFA /* Command ACK */
-#define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */
-
-/*
- * Status Register Bits
- */
-
-#define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */
-#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */
-#define KBD_STAT_SELFTEST 0x04 /* Self test successful */
-#define KBD_STAT_CMD 0x08 /* Last write was a command write (0=data) */
-#define KBD_STAT_UNLOCKED 0x10 /* Zero if keyboard locked */
-#define KBD_STAT_MOUSE_OBF 0x20 /* Mouse output buffer full */
-#define KBD_STAT_GTO 0x40 /* General receive/xmit timeout */
-#define KBD_STAT_PERR 0x80 /* Parity error */
-
-#define AUX_STAT_OBF (KBD_STAT_OBF | KBD_STAT_MOUSE_OBF)
-
-/*
- * Controller Mode Register Bits
- */
-
-#define KBD_MODE_KBD_INT 0x01 /* Keyboard data generate IRQ1 */
-#define KBD_MODE_MOUSE_INT 0x02 /* Mouse data generate IRQ12 */
-#define KBD_MODE_SYS 0x04 /* The system flag (?) */
-#define KBD_MODE_NO_KEYLOCK 0x08 /* The keylock doesn't affect the keyboard if set */
-#define KBD_MODE_DISABLE_KBD 0x10 /* Disable keyboard interface */
-#define KBD_MODE_DISABLE_MOUSE 0x20 /* Disable mouse interface */
-#define KBD_MODE_KCC 0x40 /* Scan code conversion to PC format */
-#define KBD_MODE_RFU 0x80
-
-/*
- * Mouse Commands
- */
-
-#define AUX_SET_RES 0xE8 /* Set resolution */
-#define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */
-#define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */
-#define AUX_GET_SCALE 0xE9 /* Get scaling factor */
-#define AUX_SET_STREAM 0xEA /* Set stream mode */
-#define AUX_SET_SAMPLE 0xF3 /* Set sample rate */
-#define AUX_ENABLE_DEV 0xF4 /* Enable aux device */
-#define AUX_DISABLE_DEV 0xF5 /* Disable aux device */
-#define AUX_RESET 0xFF /* Reset aux device */
-
-#define AUX_BUF_SIZE 2048
-
-struct aux_queue {
- unsigned long head;
- unsigned long tail;
- struct wait_queue *proc_list;
- struct fasync_struct *fasync;
- unsigned char buf[AUX_BUF_SIZE];
-};
-
diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile
index 6631d33c3..225cbec5d 100644
--- a/arch/ia64/kernel/Makefile
+++ b/arch/ia64/kernel/Makefile
@@ -15,13 +15,13 @@
all: kernel.o head.o init_task.o
O_TARGET := kernel.o
-O_OBJS := acpi.o entry.o gate.o efi.o efi_stub.o irq.o irq_ia64.o irq_internal.o ivt.o \
- pal.o pci-dma.o process.o perfmon.o ptrace.o sal.o sal_stub.o semaphore.o setup.o signal.o \
- sys_ia64.o traps.o time.o unaligned.o unwind.o
+O_OBJS := acpi.o entry.o gate.o efi.o efi_stub.o irq.o irq_ia64.o irq_sapic.o ivt.o \
+ pal.o pci-dma.o process.o perfmon.o ptrace.o sal.o sal_stub.o semaphore.o setup.o \
+ signal.o sys_ia64.o traps.o time.o unaligned.o unwind.o
#O_OBJS := fpreg.o
#OX_OBJS := ia64_ksyms.o
-ifeq ($(CONFIG_IA64_GENERIC),y)
+ifdef CONFIG_IA64_GENERIC
O_OBJS += machvec.o
endif
@@ -30,10 +30,10 @@ O_OBJS += pci.o
endif
ifdef CONFIG_SMP
-O_OBJS += smp.o irq_lock.o
+O_OBJS += smp.o
endif
-ifeq ($(CONFIG_MCA),y)
+ifdef CONFIG_IA64_MCA
O_OBJS += mca.o mca_asm.o
endif
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
index 078d908c8..72e10a683 100644
--- a/arch/ia64/kernel/acpi.c
+++ b/arch/ia64/kernel/acpi.c
@@ -11,12 +11,12 @@
#include <linux/config.h>
#include <linux/init.h>
-#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/smp.h>
#include <linux/string.h>
#include <linux/types.h>
+#include <linux/irq.h>
#include <asm/acpi-ext.h>
#include <asm/page.h>
@@ -27,13 +27,12 @@
#undef ACPI_DEBUG /* Guess what this does? */
#ifdef CONFIG_SMP
-extern unsigned long ipi_base_addr;
+extern struct smp_boot_data smp;
#endif
/* These are ugly but will be reclaimed by the kernel */
-int __initdata acpi_cpus = 0;
-int __initdata acpi_apic_map[32];
-int __initdata cpu_cnt = 0;
+int __initdata available_cpus = 0;
+int __initdata total_cpus = 0;
void (*pm_idle) (void);
@@ -50,7 +49,7 @@ acpi_lsapic(char *p)
if ((lsapic->flags & LSAPIC_PRESENT) == 0)
return;
- printk(" CPU %d (%.04x:%.04x): ", cpu_cnt, lsapic->eid, lsapic->id);
+ printk(" CPU %d (%.04x:%.04x): ", total_cpus, lsapic->eid, lsapic->id);
if ((lsapic->flags & LSAPIC_ENABLED) == 0) {
printk("Disabled.\n");
@@ -62,11 +61,17 @@ acpi_lsapic(char *p)
if (add) {
printk("Available.\n");
- acpi_cpus++;
- acpi_apic_map[cpu_cnt] = (lsapic->id << 8) | lsapic->eid;
+ available_cpus++;
+#ifdef CONFIG_SMP
+# if LARGE_CPU_ID_OK
+ smp.cpu_map[total_cpus] = (lsapic->id << 8) | lsapic->eid;
+# else
+ smp.cpu_map[total_cpus] = lsapic->id;
+# endif
+#endif
}
- cpu_cnt++;
+ total_cpus++;
}
/*
@@ -174,7 +179,7 @@ acpi_legacy_irq(char *p)
break;
}
-#ifdef ACPI_DEBUG
+#if 1/*def ACPI_DEBUG*/
printk("Legacy ISA IRQ %x -> IA64 Vector %x IOSAPIC Pin %x Active %s %s Trigger\n",
legacy->isa_irq, vector, iosapic_pin(vector),
((iosapic_polarity(vector) == IO_SAPIC_POL_LOW) ? "Low" : "High"),
@@ -204,11 +209,11 @@ acpi_parse_msapic(acpi_sapic_t *msapic)
{
char *p, *end;
- memset(&acpi_apic_map, -1, sizeof(acpi_apic_map));
+ /* Base address of IPI Message Block */
+ ipi_base_addr = (unsigned long) ioremap(msapic->interrupt_block, 0);
#ifdef CONFIG_SMP
- /* Base address of IPI Message Block */
- ipi_base_addr = ioremap(msapic->interrupt_block, 0);
+ memset(&smp, -1, sizeof(smp));
#endif
p = (char *) (msapic + 1);
@@ -238,11 +243,22 @@ acpi_parse_msapic(acpi_sapic_t *msapic)
}
/* Move to next table entry. */
- p += *(p + 1);
+#define BAD_ACPI_TABLE
+#ifdef BAD_ACPI_TABLE
+ /*
+ * Some prototype Lion's have a bad ACPI table
+ * requiring this fix. Without this fix, those
+ * machines crash during bootup.
+ */
+ if (p[1] == 0)
+ p = end;
+ else
+#endif
+ p += p[1];
}
/* Make bootup pretty */
- printk(" %d CPUs available, %d CPUs total\n", acpi_cpus, cpu_cnt);
+ printk(" %d CPUs available, %d CPUs total\n", available_cpus, total_cpus);
}
int __init
@@ -281,12 +297,15 @@ acpi_parse(acpi_rsdp_t *rsdp)
continue;
acpi_parse_msapic((acpi_sapic_t *) hdrp);
- } /* while() */
+ }
- if (acpi_cpus == 0) {
+#ifdef CONFIG_SMP
+ if (available_cpus == 0) {
printk("ACPI: Found 0 CPUS; assuming 1\n");
- acpi_cpus = 1; /* We've got at least one of these, no? */
+ available_cpus = 1; /* We've got at least one of these, no? */
}
+ smp.cpu_count = available_cpus;
+#endif
return 1;
}
diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
index fc2d50558..0ce1db504 100644
--- a/arch/ia64/kernel/efi.c
+++ b/arch/ia64/kernel/efi.c
@@ -24,7 +24,7 @@
#include <asm/io.h>
#include <asm/processor.h>
-#define EFI_DEBUG
+#define EFI_DEBUG 0
extern efi_status_t efi_call_phys (void *, ...);
@@ -210,9 +210,8 @@ efi_memmap_walk (efi_freemem_callback_t callback, void *arg)
void __init
efi_init (void)
{
- void *efi_map_start, *efi_map_end, *p;
+ void *efi_map_start, *efi_map_end;
efi_config_table_t *config_tables;
- efi_memory_desc_t *md;
efi_char16_t *c16;
u64 efi_desc_size;
char vendor[100] = "unknown";
@@ -278,13 +277,18 @@ efi_init (void)
efi_map_end = efi_map_start + ia64_boot_param.efi_memmap_size;
efi_desc_size = ia64_boot_param.efi_memdesc_size;
-#ifdef EFI_DEBUG
+#if EFI_DEBUG
/* print EFI memory map: */
- for (i = 0, p = efi_map_start; p < efi_map_end; ++i, p += efi_desc_size) {
- md = p;
- printk("mem%02u: type=%u, attr=0x%lx, range=[0x%016lx-0x%016lx) (%luMB)\n",
- i, md->type, md->attribute,
- md->phys_addr, md->phys_addr + (md->num_pages<<12) - 1, md->num_pages >> 8);
+ {
+ efi_memory_desc_t *md = p;
+ void *p;
+
+ for (i = 0, p = efi_map_start; p < efi_map_end; ++i, p += efi_desc_size) {
+ md = p;
+ printk("mem%02u: type=%u, attr=0x%lx, range=[0x%016lx-0x%016lx) (%luMB)\n",
+ i, md->type, md->attribute, md->phys_addr,
+ md->phys_addr + (md->num_pages<<12) - 1, md->num_pages >> 8);
+ }
}
#endif
}
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
index eb575a39c..755e3a0c1 100644
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -25,6 +25,7 @@
#include <linux/config.h>
+#include <asm/cache.h>
#include <asm/errno.h>
#include <asm/offsets.h>
#include <asm/processor.h>
@@ -228,11 +229,11 @@ save_switch_stack:
stf.spill [r2]=f30,32
stf.spill [r3]=f31,24
;;
- st8.spill [r2]=r4,16
- st8.spill [r3]=r5,16
+.mem.offset 0,0; st8.spill [r2]=r4,16
+.mem.offset 8,0; st8.spill [r3]=r5,16
;;
- st8.spill [r2]=r6,16
- st8.spill [r3]=r7,16
+.mem.offset 0,0; st8.spill [r2]=r6,16
+.mem.offset 8,0; st8.spill [r3]=r7,16
;;
st8 [r2]=r21,16 // save b0
st8 [r3]=r22,16 // save b1
@@ -437,8 +438,8 @@ strace_check_retval:
(p6) br.cond.sptk.few strace_error // syscall failed ->
;; // avoid RAW on r10
strace_save_retval:
- st8.spill [r2]=r8 // store return value in slot for r8
- st8.spill [r3]=r10 // clear error indication in slot for r10
+.mem.offset 0,0; st8.spill [r2]=r8 // store return value in slot for r8
+.mem.offset 8,0; st8.spill [r3]=r10 // clear error indication in slot for r10
ia64_strace_leave_kernel:
br.call.sptk.few rp=invoke_syscall_trace // give parent a chance to catch return value
.ret6: br.cond.sptk.many ia64_leave_kernel
@@ -491,7 +492,9 @@ ia64_ret_from_syscall:
adds r2=IA64_PT_REGS_R8_OFFSET+16,sp // r2 = &pt_regs.r8
adds r3=IA64_PT_REGS_R8_OFFSET+32,sp // r3 = &pt_regs.r10
;;
+ .mem.offset 0,0
(p6) st8.spill [r2]=r8 // store return value in slot for r8 and set unat bit
+ .mem.offset 8,0
(p6) st8.spill [r3]=r0 // clear error indication in slot for r10 and set unat bit
(p7) br.cond.spnt.few handle_syscall_error // handle potential syscall failure
@@ -504,7 +507,9 @@ ia64_leave_kernel:
;;
ld4 r2=[r2]
;;
- shladd r3=r2,3,r3
+ shl r2=r2,SMP_LOG_CACHE_BYTES // can't use shladd here...
+ ;;
+ add r3=r2,r3
#else
movl r3=softirq_state
#endif
@@ -550,6 +555,16 @@ back_from_resched:
2:
// check & deliver pending signals:
(p2) br.call.spnt.few rp=handle_signal_delivery
+#if defined(CONFIG_SMP) || defined(CONFIG_IA64_SOFTSDV_HACKS)
+ // Check for lost ticks
+ mov r2 = ar.itc
+ mov r3 = cr.itm
+ ;;
+ sub r2 = r2, r3
+ ;;
+ cmp.ge p6,p7 = r2, r0
+(p6) br.call.spnt.few rp=invoke_ia64_reset_itm
+#endif
restore_all:
// start restoring the state saved on the kernel stack (struct pt_regs):
@@ -735,8 +750,8 @@ handle_syscall_error:
(p6) mov r9=r8
(p6) mov r10=0
;;
- st8.spill [r2]=r9 // store errno in pt_regs.r8 and set unat bit
- st8.spill [r3]=r10 // store error indication in pt_regs.r10 and set unat bit
+.mem.offset 0,0; st8.spill [r2]=r9 // store errno in pt_regs.r8 and set unat bit
+.mem.offset 8,0; st8.spill [r3]=r10 // store error indication in pt_regs.r10 and set unat bit
br.cond.sptk.many ia64_leave_kernel
.endp handle_syscall_error
@@ -757,6 +772,19 @@ invoke_schedule_tail:
mov rp=loc1
br.ret.sptk.many rp
.endp invoke_schedule_tail
+
+ .proc invoke_ia64_reset_itm
+invoke_ia64_reset_itm:
+ alloc loc0=ar.pfs,8,2,0,0
+ mov loc1=rp
+ ;;
+ br.call.sptk.many rp=ia64_reset_itm
+ ;;
+ mov ar.pfs=loc0
+ mov rp=loc1
+ br.ret.sptk.many rp
+ .endp invoke_ia64_reset_itm
+
#endif /* CONFIG_SMP */
/*
@@ -855,26 +883,22 @@ setup_switch_stack:
.global sys_rt_sigsuspend
sys_rt_sigsuspend:
alloc loc0=ar.pfs,2,2,3,0
- mov r9=ar.unat
// If the process is being ptraced, the signal may not actually be delivered to
// the process. Instead, SIGCHLD will be sent to the parent. We need to
// setup a switch_stack so ptrace can inspect the processes state if necessary.
- adds r2=IA64_TASK_FLAGS_OFFSET,r13
- ;;
- ld8 r2=[r2]
+ // Also, the process might not ptraced until stopped in sigsuspend, so this
+ // isn't something that we can do conditionally based upon the value of
+ // PF_PTRACED_BIT.
mov out0=in0 // mask
mov out1=in1 // sigsetsize
;;
adds out2=16,sp // out1=&pt_regs
- tbit.nz p16,p17=r2,PF_PTRACED_BIT
-(p16) br.cond.spnt.many sigsuspend_setup_switch_stack
+ movl r28=back_from_sigsuspend_setup_switch_stack
+ mov r16=loc0
+ br.cond.sptk.many save_switch_stack
;;
back_from_sigsuspend_setup_switch_stack:
- adds r3=-IA64_SWITCH_STACK_SIZE+IA64_SWITCH_STACK_CALLER_UNAT_OFFSET+16,sp
-(p17) adds sp=-IA64_SWITCH_STACK_SIZE,sp // make space for (dummy) switch_stack
- ;;
-(p17) st8 [r3]=r9 // save ar.unat in sw->caller_unat
mov loc1=rp // save return address
br.call.sptk.many rp=ia64_rt_sigsuspend
.ret12:
@@ -883,32 +907,22 @@ back_from_sigsuspend_setup_switch_stack:
ld8 r9=[r3] // load new unat from sw->caller_unat
mov rp=loc1
;;
-(p17) adds sp=IA64_SWITCH_STACK_SIZE,sp // drop (dummy) switch_stack
-(p17) mov ar.unat=r9
-(p17) mov ar.pfs=loc0
-(p17) br.ret.sptk.many rp
// restore the switch stack (ptrace may have modified it):
movl r28=1f
br.cond.sptk.many load_switch_stack
1: br.ret.sptk.many rp
// NOT REACHED
-
-sigsuspend_setup_switch_stack:
- movl r28=back_from_sigsuspend_setup_switch_stack
- mov r16=loc0
- br.cond.sptk.many save_switch_stack
- // NOT REACHED
-
.endp sys_rt_sigsuspend
.align 16
.proc sys_rt_sigreturn
sys_rt_sigreturn:
- alloc loc0=ar.pfs,8,1,1,0 // preserve all eight input regs in case of syscall restart!
+ .regstk 0,0,3,0 // inherited from gate.s:invoke_sighandler()
adds out0=16,sp // out0 = &pt_regs
- ;;
adds sp=-IA64_SWITCH_STACK_SIZE,sp // make space for unat and padding
+ ;;
+ cmp.eq pNonSys,p0=r0,r0 // sigreturn isn't a normal syscall...
br.call.sptk.few rp=ia64_rt_sigreturn
.ret13:
adds r3=IA64_SWITCH_STACK_CALLER_UNAT_OFFSET+16,sp
@@ -918,8 +932,7 @@ sys_rt_sigreturn:
;;
adds sp=IA64_SWITCH_STACK_SIZE,sp // drop (dummy) switch-stack frame
mov ar.unat=r9
- mov ar.pfs=loc0
- br.ret.sptk.many rp
+ br rp
.endp sys_rt_sigreturn
.align 16
@@ -940,76 +953,6 @@ ia64_prepare_handle_unaligned:
2: br.cond.sptk.many rp // goes to ia64_leave_kernel
.endp ia64_prepare_handle_unaligned
-#ifdef CONFIG_KDB
- //
- // This gets called from ivt.S with:
- // SAVE MIN with cover done
- // SAVE REST done
- // no parameters
- // r15 has return value = ia64_leave_kernel
- //
- .align 16
- .global ia64_invoke_kdb
- .proc ia64_invoke_kdb
-ia64_invoke_kdb:
- alloc r16=ar.pfs,0,0,4,0
- movl r28=1f // save_switch_stack protocol
- ;; // avoid WAW on CFM
- br.cond.sptk.many save_switch_stack // to flushrs
-1: mov out0=4 // kdb entry reason
- mov out1=0 // err number
- adds out2=IA64_SWITCH_STACK_SIZE+16,sp // pt_regs
- add out3=16,sp // switch_stack
- br.call.sptk.few rp=kdb
-.ret15:
- movl r28=1f // load_switch_stack proto
- br.cond.sptk.many load_switch_stack
-1: br.ret.sptk.many rp
- .endp ia64_invoke_kdb
-
- //
- // When KDB is compiled in, we intercept each fault and give
- // kdb a chance to run before calling the normal fault handler.
- //
- .align 16
- .global ia64_invoke_kdb_fault_handler
- .proc ia64_invoke_kdb_fault_handler
-ia64_invoke_kdb_fault_handler:
- alloc r16=ar.pfs,5,1,5,0
- movl r28=1f
- mov loc0=rp // save this
- br.cond.sptk.many save_switch_stack // to flushrs
- ;; // avoid WAW on CFM
-1: mov out0=in0 // vector number
- mov out1=in1 // cr.isr
- mov out2=in2 // cr.ifa
- mov out3=in3 // cr.iim
- mov out4=in4 // cr.itir
- br.call.sptk.few rp=ia64_kdb_fault_handler
-.ret16:
-
- movl r28=1f
- br.cond.sptk.many load_switch_stack
-1: cmp.ne p6,p0=r8,r0 // did ia64_kdb_fault_handler return 0?
- mov rp=loc0
-(p6) br.ret.spnt.many rp // no, we're done
- ;; // avoid WAW on rp
- mov out0=in0 // vector number
- mov out1=in1 // cr.isr
- mov out2=in2 // cr.ifa
- mov out3=in3 // cr.iim
- mov out4=in4 // cr.itir
- mov in0=ar.pfs // preserve ar.pfs returned by load_switch_stack
- br.call.sptk.few rp=ia64_fault // yup -> we need to invoke normal fault handler now
-.ret17:
- mov ar.pfs=in0
- mov rp=loc0
- br.ret.sptk.many rp
-
- .endp ia64_invoke_kdb_fault_handler
-
-#endif /* CONFIG_KDB */
-
.rodata
.align 8
.globl sys_call_table
@@ -1198,8 +1141,8 @@ sys_call_table:
data8 sys_sendmsg // 1205
data8 sys_recvmsg
data8 sys_pivot_root
- data8 ia64_ni_syscall
- data8 ia64_ni_syscall
+ data8 sys_mincore
+ data8 sys_madvise
data8 ia64_ni_syscall // 1210
data8 ia64_ni_syscall
data8 ia64_ni_syscall
diff --git a/arch/ia64/kernel/gate.S b/arch/ia64/kernel/gate.S
index a710870c0..8eabe53d1 100644
--- a/arch/ia64/kernel/gate.S
+++ b/arch/ia64/kernel/gate.S
@@ -80,8 +80,6 @@
ia64_sigtramp:
ld8 r10=[r3],8 // get signal handler entry point
br.call.sptk.many rp=invoke_sighandler
-.ret0: mov r15=__NR_rt_sigreturn
- break __BREAK_SYSCALL
.endp ia64_sigtramp
.proc invoke_sighandler
@@ -90,10 +88,9 @@ invoke_sighandler:
mov b6=r10
cover // push args in interrupted frame onto backing store
;;
- alloc r8=ar.pfs,0,1,3,0 // get CFM0, EC0, and CPL0 into r8
- mov r17=ar.bsp // fetch ar.bsp
- mov loc0=rp // save return pointer
+ alloc r8=ar.pfs,0,0,3,0 // get CFM0, EC0, and CPL0 into r8
;;
+ mov r17=ar.bsp // fetch ar.bsp
cmp.ne p8,p0=r15,r0 // do we need to switch the rbs?
mov out0=r2 // signal number
(p8) br.cond.spnt.few setup_rbs // yup -> (clobbers r14 and r16)
@@ -101,10 +98,11 @@ back_from_setup_rbs:
adds base0=(BSP_OFF+SIGCONTEXT_OFF),sp
;;
st8 [base0]=r17,(CFM_OFF-BSP_OFF) // save sc_ar_bsp
+ dep r8=0,r8,38,26 // clear EC0, CPL0 and reserved bits
adds base1=(FR6_OFF+16+SIGCONTEXT_OFF),sp
;;
- st8 [base0]=r8 // save CFM0, EC0, and CPL0
+ st8 [base0]=r8 // save CFM0
adds base0=(FR6_OFF+SIGCONTEXT_OFF),sp
;;
stf.spill [base0]=f6,32
@@ -124,7 +122,8 @@ back_from_setup_rbs:
stf.spill [base0]=f14,32
stf.spill [base1]=f15,32
br.call.sptk.few rp=b6 // call the signal handler
-.ret2: adds base0=(BSP_OFF+SIGCONTEXT_OFF),sp
+.ret2:
+ adds base0=(BSP_OFF+SIGCONTEXT_OFF),sp
;;
ld8 r15=[base0],(CFM_OFF-BSP_OFF) // fetch sc_ar_bsp and advance to CFM_OFF
mov r14=ar.bsp
@@ -134,23 +133,11 @@ back_from_setup_rbs:
(p8) br.cond.spnt.few restore_rbs // yup -> (clobbers r14 and r16)
;;
back_from_restore_rbs:
- {
- and r9=0x7f,r8 // r9 <- CFM0.sof
- extr.u r10=r8,7,7 // r10 <- CFM0.sol
- mov r11=ip
- }
- ;;
adds base0=(FR6_OFF+SIGCONTEXT_OFF),sp
- adds r11=(cont-back_from_restore_rbs),r11
- sub r9=r9,r10 // r9 <- CFM0.sof - CFM0.sol == CFM0.nout
- ;;
adds base1=(FR6_OFF+16+SIGCONTEXT_OFF),sp
- dep r9=r9,r9,7,7 // r9.sol = r9.sof
- mov b6=r11
;;
ldf.fill f6=[base0],32
ldf.fill f7=[base1],32
- mov rp=loc0 // copy return pointer out of stacked register
;;
ldf.fill f8=[base0],32
ldf.fill f9=[base1],32
@@ -160,26 +147,23 @@ back_from_restore_rbs:
;;
ldf.fill f12=[base0],32
ldf.fill f13=[base1],32
- mov ar.pfs=r9
;;
ldf.fill f14=[base0],32
ldf.fill f15=[base1],32
- br.ret.sptk.few b6
-cont: mov ar.pfs=r8 // ar.pfs = CFM0
- br.ret.sptk.few rp // re-establish CFM0
+ mov r15=__NR_rt_sigreturn
+ break __BREAK_SYSCALL
.endp invoke_sighandler
.proc setup_rbs
setup_rbs:
flushrs // must be first in insn
- ;;
mov ar.rsc=r0 // put RSE into enforced lazy mode
adds r16=(RNAT_OFF+SIGCONTEXT_OFF),sp
- mov r14=ar.rnat // get rnat as updated by flushrs
;;
+ mov r14=ar.rnat // get rnat as updated by flushrs
mov ar.bspstore=r15 // set new register backing store area
- st8 [r16]=r14 // save sc_ar_rnat
;;
+ st8 [r16]=r14 // save sc_ar_rnat
mov ar.rsc=0xf // set RSE into eager mode, pl 3
invala // invalidate ALAT
br.cond.sptk.many back_from_setup_rbs
diff --git a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c
index 0ddfe3f05..a01432a60 100644
--- a/arch/ia64/kernel/irq.c
+++ b/arch/ia64/kernel/irq.c
@@ -66,7 +66,7 @@ irq_cpustat_t irq_stat [NR_CPUS];
* Controller mappings for all interrupt sources:
*/
irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned =
- { [0 ... NR_IRQS-1] = { 0, &no_irq_type, NULL, 0, SPIN_LOCK_UNLOCKED}};
+ { [0 ... NR_IRQS-1] = { IRQ_DISABLED, &no_irq_type, NULL, 0, SPIN_LOCK_UNLOCKED}};
static void register_irq_proc (unsigned int irq);
@@ -164,7 +164,7 @@ int get_irq_list(char *buf)
p += sprintf(p, "%10u ",
atomic_read(&nmi_counter(cpu_logical_map(j))));
p += sprintf(p, "\n");
-#if CONFIG_SMP
+#if defined(CONFIG_SMP) && defined(__i386__)
p += sprintf(p, "LOC: ");
for (j = 0; j < smp_num_cpus; j++)
p += sprintf(p, "%10u ",
@@ -182,8 +182,8 @@ int get_irq_list(char *buf)
*/
#ifdef CONFIG_SMP
-unsigned char global_irq_holder = NO_PROC_ID;
-unsigned volatile int global_irq_lock;
+unsigned int global_irq_holder = NO_PROC_ID;
+volatile unsigned int global_irq_lock;
extern void show_stack(unsigned long* esp);
@@ -201,6 +201,10 @@ static void show(char * str)
printk(" %d",local_bh_count(i));
printk(" ]\nStack dumps:");
+#ifdef __ia64__
+ printk(" ]\nStack dumps: <unimplemented on IA-64---please fix me>");
+ /* for now we don't have stack dumping support... */
+#elif __i386__
for(i=0;i< smp_num_cpus;i++) {
unsigned long esp;
if(i==cpu)
@@ -219,8 +223,13 @@ static void show(char * str)
esp += sizeof(struct task_struct);
show_stack((void*)esp);
}
+#else
+ You lose...
+#endif
printk("\nCPU %d:",cpu);
+#ifdef __i386__
show_stack(NULL);
+#endif
printk("\n");
}
@@ -250,7 +259,11 @@ static void show(char * str)
/*
* We have to allow irqs to arrive between __sti and __cli
*/
-# define SYNC_OTHER_CORES(x) __asm__ __volatile__ ("nop")
+# ifdef __ia64__
+# define SYNC_OTHER_CORES(x) __asm__ __volatile__ ("nop 0")
+# else
+# define SYNC_OTHER_CORES(x) __asm__ __volatile__ ("nop")
+# endif
#endif
static inline void wait_on_irq(int cpu)
@@ -311,7 +324,7 @@ static inline void get_irqlock(int cpu)
{
if (test_and_set_bit(0,&global_irq_lock)) {
/* do we already hold the lock? */
- if ((unsigned char) cpu == global_irq_holder)
+ if (cpu == global_irq_holder)
return;
/* Uhhuh.. Somebody else got it. Wait.. */
do {
@@ -349,6 +362,15 @@ void __global_cli(void)
{
unsigned int flags;
+#ifdef __ia64__
+ __save_flags(flags);
+ if (flags & IA64_PSR_I) {
+ int cpu = smp_processor_id();
+ __cli();
+ if (!local_irq_count(cpu))
+ get_irqlock(cpu);
+ }
+#else
__save_flags(flags);
if (flags & (1 << EFLAGS_IF_SHIFT)) {
int cpu = smp_processor_id();
@@ -356,6 +378,7 @@ void __global_cli(void)
if (!local_irq_count(cpu))
get_irqlock(cpu);
}
+#endif
}
void __global_sti(void)
@@ -382,7 +405,11 @@ unsigned long __global_save_flags(void)
int cpu = smp_processor_id();
__save_flags(flags);
+#ifdef __ia64__
+ local_enabled = (flags & IA64_PSR_I) != 0;
+#else
local_enabled = (flags >> EFLAGS_IF_SHIFT) & 1;
+#endif
/* default to local */
retval = 2 + local_enabled;
@@ -479,11 +506,13 @@ void disable_irq(unsigned int irq)
{
disable_irq_nosync(irq);
+#ifdef CONFIG_SMP
if (!local_irq_count(smp_processor_id())) {
do {
barrier();
} while (irq_desc[irq].status & IRQ_INPROGRESS);
}
+#endif
}
void enable_irq(unsigned int irq)
@@ -559,15 +588,12 @@ unsigned int do_IRQ(unsigned long irq, struct pt_regs *regs)
/*
* If there is no IRQ handler or it was disabled, exit early.
- Since we set PENDING, if another processor is handling
- a different instance of this same irq, the other processor
- will take care of it.
+ * Since we set PENDING, if another processor is handling
+ * a different instance of this same irq, the other processor
+ * will take care of it.
*/
if (!action)
-{
- desc->status = status & ~IRQ_INPROGRESS;
goto out;
-}
/*
* Edge triggered interrupts need to remember
@@ -597,15 +623,6 @@ out:
desc->handler->end(irq);
spin_unlock(&desc->lock);
-#if 0
- /*
- * let kernel exit path take care of this; we want to do the
- * CPU EOI before doing softirq() so a new interrupt can come
- * through
- */
- if (softirq_state[cpu].active & softirq_state[cpu].mask)
- do_softirq();
-#endif
return 1;
}
@@ -1019,7 +1036,7 @@ static void register_irq_proc (unsigned int irq)
irq_dir[irq] = proc_mkdir(name, root_irq_dir);
/* create /proc/irq/1234/smp_affinity */
- entry = create_proc_entry("smp_affinity", 0700, irq_dir[irq]);
+ entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]);
entry->nlink = 1;
entry->data = (void *)(long)irq;
@@ -1040,7 +1057,7 @@ void init_irq_proc (void)
root_irq_dir = proc_mkdir("irq", 0);
/* create /proc/irq/prof_cpu_mask */
- entry = create_proc_entry("prof_cpu_mask", 0700, root_irq_dir);
+ entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir);
entry->nlink = 1;
entry->data = (void *)&prof_cpu_mask;
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c
index a2c493ba5..1a8398f85 100644
--- a/arch/ia64/kernel/irq_ia64.c
+++ b/arch/ia64/kernel/irq_ia64.c
@@ -25,10 +25,6 @@
#include <linux/smp_lock.h>
#include <linux/threads.h>
-#ifdef CONFIG_KDB
-# include <linux/kdb.h>
-#endif
-
#include <asm/bitops.h>
#include <asm/delay.h>
#include <asm/io.h>
@@ -41,13 +37,15 @@
spinlock_t ivr_read_lock;
#endif
+unsigned long ipi_base_addr = IPI_DEFAULT_BASE_ADDR; /* default base addr of IPI table */
+
/*
* Legacy IRQ to IA-64 vector translation table. Any vector not in
* this table maps to itself (ie: irq 0x30 => IA64 vector 0x30)
*/
-__u8 isa_irq_to_vector_map[IA64_MIN_VECTORED_IRQ] = {
+__u8 isa_irq_to_vector_map[16] = {
/* 8259 IRQ translation, first 16 entries */
- 0x60, 0x50, 0x0f, 0x51, 0x52, 0x53, 0x43, 0x54,
+ 0x60, 0x50, 0x10, 0x51, 0x52, 0x53, 0x43, 0x54,
0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x40, 0x41
};
@@ -80,8 +78,8 @@ ia64_handle_irq (unsigned long vector, struct pt_regs *regs)
#ifdef CONFIG_ITANIUM_ASTEP_SPECIFIC
# ifndef CONFIG_SMP
static unsigned int max_prio = 0;
-# endif
unsigned int prev_prio;
+# endif
unsigned long eoi_ptr;
# ifdef CONFIG_USB
@@ -95,21 +93,25 @@ ia64_handle_irq (unsigned long vector, struct pt_regs *regs)
* Stop IPIs by getting the ivr_read_lock
*/
spin_lock(&ivr_read_lock);
+ {
+ unsigned int tmp;
- /*
- * Disable PCI writes
- */
- outl(0x80ff81c0, 0xcf8);
- outl(0x73002188, 0xcfc);
- eoi_ptr = inl(0xcfc);
+ /*
+ * Disable PCI writes
+ */
+ outl(0x80ff81c0, 0xcf8);
+ tmp = inl(0xcfc);
+ outl(tmp | 0x400, 0xcfc);
- vector = ia64_get_ivr();
+ eoi_ptr = inl(0xcfc);
- /*
- * Enable PCI writes
- */
- outl(0x73182188, 0xcfc);
+ vector = ia64_get_ivr();
+ /*
+ * Enable PCI writes
+ */
+ outl(tmp, 0xcfc);
+ }
spin_unlock(&ivr_read_lock);
# ifdef CONFIG_USB
@@ -152,9 +154,6 @@ ia64_handle_irq (unsigned long vector, struct pt_regs *regs)
printk("ia64_handle_irq: DANGER: less than 1KB of free stack space!!\n"
"(bsp=0x%lx, sp=%lx)\n", bsp, sp);
}
-#ifdef CONFIG_KDB
- kdb(KDB_REASON_PANIC, 0, regs);
-#endif
}
/*
@@ -175,9 +174,6 @@ ia64_handle_irq (unsigned long vector, struct pt_regs *regs)
if (!pEOI) {
printk("Yikes: ia64_handle_irq() without pEOI!!\n");
asm volatile ("cmp.eq p1,p0=r0,r0" : "=r"(pEOI));
-# ifdef CONFIG_KDB
- kdb(KDB_REASON_PANIC, 0, regs);
-# endif
}
}
@@ -195,13 +191,13 @@ ia64_handle_irq (unsigned long vector, struct pt_regs *regs)
#ifdef CONFIG_SMP
-void __init
-init_IRQ_SMP (void)
-{
- if (request_irq(IPI_IRQ, handle_IPI, 0, "IPI", NULL))
- panic("Could not allocate IPI Interrupt Handler!");
-}
+extern void handle_IPI (int irq, void *dev_id, struct pt_regs *regs);
+static struct irqaction ipi_irqaction = {
+ handler: handle_IPI,
+ flags: SA_INTERRUPT,
+ name: "IPI"
+};
#endif
void __init
@@ -214,13 +210,14 @@ init_IRQ (void)
ia64_set_lrr0(0, 1);
ia64_set_lrr1(0, 1);
- irq_desc[TIMER_IRQ].handler = &irq_type_ia64_internal;
+ irq_desc[TIMER_IRQ].handler = &irq_type_ia64_sapic;
+ irq_desc[IA64_SPURIOUS_INT].handler = &irq_type_ia64_sapic;
#ifdef CONFIG_SMP
/*
* Configure the IPI vector and handler
*/
- irq_desc[IPI_IRQ].handler = &irq_type_ia64_internal;
- init_IRQ_SMP();
+ irq_desc[IPI_IRQ].handler = &irq_type_ia64_sapic;
+ setup_irq(IPI_IRQ, &ipi_irqaction);
#endif
ia64_set_pmv(1 << 16);
@@ -232,16 +229,26 @@ init_IRQ (void)
ia64_set_tpr(0);
}
-/* TBD:
- * Certain IA64 platforms can have inter-processor interrupt support.
- * This interface is supposed to default to the IA64 IPI block-based
- * mechanism if the platform doesn't provide a separate mechanism
- * for IPIs.
- * Choices : (1) Extend hw_interrupt_type interfaces
- * (2) Use machine vector mechanism
- * For now defining the following interface as a place holder.
- */
void
-ipi_send (int cpu, int vector, int delivery_mode)
+ipi_send (int cpu, int vector, int delivery_mode, int redirect)
{
+ unsigned long ipi_addr;
+ unsigned long ipi_data;
+#ifdef CONFIG_ITANIUM_ASTEP_SPECIFIC
+ unsigned long flags;
+#endif
+# define EID 0
+
+ ipi_data = (delivery_mode << 8) | (vector & 0xff);
+ ipi_addr = ipi_base_addr | ((cpu << 8 | EID) << 4) | ((redirect & 1) << 3);
+
+#ifdef CONFIG_ITANIUM_ASTEP_SPECIFIC
+ spin_lock_irqsave(&ivr_read_lock, flags);
+#endif /* CONFIG_ITANIUM_ASTEP_SPECIFIC */
+
+ writeq(ipi_data, ipi_addr);
+
+#ifdef CONFIG_ITANIUM_ASTEP_SPECIFIC
+ spin_unlock_irqrestore(&ivr_read_lock, flags);
+#endif
}
diff --git a/arch/ia64/kernel/irq_internal.c b/arch/ia64/kernel/irq_internal.c
deleted file mode 100644
index 2b768cec1..000000000
--- a/arch/ia64/kernel/irq_internal.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Internal Interrupt Vectors
- *
- * This takes care of interrupts that are generated by the CPU
- * internally, such as the ITC and IPI interrupts.
- *
- * Copyright (C) 1999 VA Linux Systems
- * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
- * Copyright (C) 2000 Hewlett-Packard Co
- * Copyright (C) 2000 David Mosberger-Tang <davidm@hpl.hp.com>
- */
-
-#include <linux/irq.h>
-
-static unsigned int
-internal_noop_startup (unsigned int irq)
-{
- return 0;
-}
-
-static void
-internal_noop (unsigned int irq)
-{
- /* nuthing to do... */
-}
-
-struct hw_interrupt_type irq_type_ia64_internal = {
- typename: "IA64-internal",
- startup: internal_noop_startup,
- shutdown: internal_noop,
- enable: internal_noop,
- disable: internal_noop,
- ack: internal_noop,
- end: internal_noop,
- set_affinity: (void (*)(unsigned int, unsigned long)) internal_noop
-};
diff --git a/arch/ia64/kernel/irq_lock.c b/arch/ia64/kernel/irq_lock.c
deleted file mode 100644
index 43afeac60..000000000
--- a/arch/ia64/kernel/irq_lock.c
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * SMP IRQ Lock support
- *
- * Global interrupt locks for SMP. Allow interrupts to come in on any
- * CPU, yet make cli/sti act globally to protect critical regions..
- * These function usually appear in irq.c, but I think it's cleaner this way.
- *
- * Copyright (C) 1999 VA Linux Systems
- * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
- */
-
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/smp.h>
-#include <linux/threads.h>
-#include <linux/init.h>
-
-#include <asm/system.h>
-#include <asm/processor.h>
-#include <asm/irq.h>
-#include <asm/bitops.h>
-#include <asm/pgtable.h>
-#include <asm/delay.h>
-
-int global_irq_holder = NO_PROC_ID;
-spinlock_t global_irq_lock;
-atomic_t global_irq_count;
-atomic_t global_bh_count;
-spinlock_t global_bh_lock;
-
-#define INIT_STUCK (1<<26)
-
-void
-irq_enter(int cpu, int irq)
-{
- int stuck = INIT_STUCK;
-
- hardirq_enter(cpu, irq);
- barrier();
- while (global_irq_lock.lock) {
- if (cpu == global_irq_holder) {
- break;
- }
-
- if (!--stuck) {
- printk("irq_enter stuck (irq=%d, cpu=%d, global=%d)\n",
- irq, cpu,global_irq_holder);
- stuck = INIT_STUCK;
- }
- barrier();
- }
-}
-
-void
-irq_exit(int cpu, int irq)
-{
- hardirq_exit(cpu, irq);
- release_irqlock(cpu);
-}
-
-static void
-show(char * str)
-{
- int i;
- unsigned long *stack;
- int cpu = smp_processor_id();
-
- printk("\n%s, CPU %d:\n", str, cpu);
- printk("irq: %d [%d %d]\n",
- atomic_read(&global_irq_count), local_irq_count[0], local_irq_count[1]);
- printk("bh: %d [%d %d]\n",
- atomic_read(&global_bh_count), local_bh_count[0], local_bh_count[1]);
-
- stack = (unsigned long *) &stack;
- for (i = 40; i ; i--) {
- unsigned long x = *++stack;
- if (x > (unsigned long) &get_options && x < (unsigned long) &vsprintf) {
- printk("<[%08lx]> ", x);
- }
- }
-}
-
-#define MAXCOUNT 100000000
-
-static inline void
-wait_on_bh(void)
-{
- int count = MAXCOUNT;
- do {
- if (!--count) {
- show("wait_on_bh");
- count = ~0;
- }
- /* nothing .. wait for the other bh's to go away */
- } while (atomic_read(&global_bh_count) != 0);
-}
-
-static inline void
-wait_on_irq(int cpu)
-{
- int count = MAXCOUNT;
-
- for (;;) {
-
- /*
- * Wait until all interrupts are gone. Wait
- * for bottom half handlers unless we're
- * already executing in one..
- */
- if (!atomic_read(&global_irq_count)) {
- if (local_bh_count[cpu] || !atomic_read(&global_bh_count))
- break;
- }
-
- /* Duh, we have to loop. Release the lock to avoid deadlocks */
- spin_unlock(&global_irq_lock);
- mb();
-
- for (;;) {
- if (!--count) {
- show("wait_on_irq");
- count = ~0;
- }
- __sti();
- udelay(cpu + 1);
- __cli();
- if (atomic_read(&global_irq_count))
- continue;
- if (global_irq_lock.lock)
- continue;
- if (!local_bh_count[cpu] && atomic_read(&global_bh_count))
- continue;
- if (spin_trylock(&global_irq_lock))
- break;
- }
- }
-}
-
-/*
- * This is called when we want to synchronize with
- * bottom half handlers. We need to wait until
- * no other CPU is executing any bottom half handler.
- *
- * Don't wait if we're already running in an interrupt
- * context or are inside a bh handler.
- */
-void
-synchronize_bh(void)
-{
- if (atomic_read(&global_bh_count)) {
- int cpu = smp_processor_id();
- if (!local_irq_count[cpu] && !local_bh_count[cpu]) {
- wait_on_bh();
- }
- }
-}
-
-
-/*
- * This is called when we want to synchronize with
- * interrupts. We may for example tell a device to
- * stop sending interrupts: but to make sure there
- * are no interrupts that are executing on another
- * CPU we need to call this function.
- */
-void
-synchronize_irq(void)
-{
- int cpu = smp_processor_id();
- int local_count;
- int global_count;
-
- mb();
- do {
- local_count = local_irq_count[cpu];
- global_count = atomic_read(&global_irq_count);
- } while (global_count != local_count);
-}
-
-static inline void
-get_irqlock(int cpu)
-{
- if (!spin_trylock(&global_irq_lock)) {
- /* do we already hold the lock? */
- if ((unsigned char) cpu == global_irq_holder)
- return;
- /* Uhhuh.. Somebody else got it. Wait.. */
- spin_lock(&global_irq_lock);
- }
- /*
- * We also to make sure that nobody else is running
- * in an interrupt context.
- */
- wait_on_irq(cpu);
-
- /*
- * Ok, finally..
- */
- global_irq_holder = cpu;
-}
-
-/*
- * A global "cli()" while in an interrupt context
- * turns into just a local cli(). Interrupts
- * should use spinlocks for the (very unlikely)
- * case that they ever want to protect against
- * each other.
- *
- * If we already have local interrupts disabled,
- * this will not turn a local disable into a
- * global one (problems with spinlocks: this makes
- * save_flags+cli+sti usable inside a spinlock).
- */
-void
-__global_cli(void)
-{
- unsigned long flags;
-
- __save_flags(flags);
- if (flags & IA64_PSR_I) {
- int cpu = smp_processor_id();
- __cli();
- if (!local_irq_count[cpu])
- get_irqlock(cpu);
- }
-}
-
-void
-__global_sti(void)
-{
- int cpu = smp_processor_id();
-
- if (!local_irq_count[cpu])
- release_irqlock(cpu);
- __sti();
-}
-
-/*
- * SMP flags value to restore to:
- * 0 - global cli
- * 1 - global sti
- * 2 - local cli
- * 3 - local sti
- */
-unsigned long
-__global_save_flags(void)
-{
- int retval;
- int local_enabled;
- unsigned long flags;
-
- __save_flags(flags);
- local_enabled = flags & IA64_PSR_I;
- /* default to local */
- retval = 2 + local_enabled;
-
- /* check for global flags if we're not in an interrupt */
- if (!local_irq_count[smp_processor_id()]) {
- if (local_enabled)
- retval = 1;
- if (global_irq_holder == (unsigned char) smp_processor_id())
- retval = 0;
- }
- return retval;
-}
-
-void
-__global_restore_flags(unsigned long flags)
-{
- switch (flags) {
- case 0:
- __global_cli();
- break;
- case 1:
- __global_sti();
- break;
- case 2:
- __cli();
- break;
- case 3:
- __sti();
- break;
- default:
- printk("global_restore_flags: %08lx (%08lx) from %p\n",
- flags, (&flags)[-1], __builtin_return_address(0));
- }
-}
diff --git a/arch/ia64/kernel/irq_sapic.c b/arch/ia64/kernel/irq_sapic.c
new file mode 100644
index 000000000..a431275a8
--- /dev/null
+++ b/arch/ia64/kernel/irq_sapic.c
@@ -0,0 +1,38 @@
+/*
+ * SAPIC Interrupt Controller
+ *
+ * This takes care of interrupts that are generated by the CPU's
+ * internal Streamlined Advanced Programmable Interrupt Controller
+ * (SAPIC), such as the ITC and IPI interrupts.
+ *
+ * Copyright (C) 1999 VA Linux Systems
+ * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
+ * Copyright (C) 2000 Hewlett-Packard Co
+ * Copyright (C) 2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ */
+
+#include <linux/sched.h>
+#include <linux/irq.h>
+
+static unsigned int
+sapic_noop_startup (unsigned int irq)
+{
+ return 0;
+}
+
+static void
+sapic_noop (unsigned int irq)
+{
+ /* nuthing to do... */
+}
+
+struct hw_interrupt_type irq_type_ia64_sapic = {
+ typename: "SAPIC",
+ startup: sapic_noop_startup,
+ shutdown: sapic_noop,
+ enable: sapic_noop,
+ disable: sapic_noop,
+ ack: sapic_noop,
+ end: sapic_noop,
+ set_affinity: (void (*)(unsigned int, unsigned long)) sapic_noop
+};
diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S
index b4592999f..56dd2a333 100644
--- a/arch/ia64/kernel/ivt.S
+++ b/arch/ia64/kernel/ivt.S
@@ -5,213 +5,6 @@
* Copyright (C) 1998, 1999 Stephane Eranian <eranian@hpl.hp.com>
* Copyright (C) 1998-2000 David Mosberger <davidm@hpl.hp.com>
*/
-
-#include <linux/config.h>
-
-#include <asm/break.h>
-#include <asm/offsets.h>
-#include <asm/pgtable.h>
-#include <asm/processor.h>
-#include <asm/ptrace.h>
-#include <asm/system.h>
-#include <asm/unistd.h>
-
-#include "entry.h"
-
-/*
- * A couple of convenience macros that make writing and reading
- * SAVE_MIN and SAVE_REST easier.
- */
-#define rARPR r31
-#define rCRIFS r30
-#define rCRIPSR r29
-#define rCRIIP r28
-#define rARRSC r27
-#define rARPFS r26
-#define rARUNAT r25
-#define rARRNAT r24
-#define rARBSPSTORE r23
-#define rKRBS r22
-#define rB6 r21
-#define rR1 r20
-
-/*
- * DO_SAVE_MIN switches to the kernel stacks (if necessary) and saves
- * the minimum state necessary that allows us to turn psr.ic back
- * on.
- *
- * Assumed state upon entry:
- * psr.ic: off
- * psr.dt: off
- * r31: contains saved predicates (pr)
- *
- * Upon exit, the state is as follows:
- * psr.ic: off
- * psr.dt: off
- * r2 = points to &pt_regs.r16
- * r12 = kernel sp (kernel virtual address)
- * r13 = points to current task_struct (kernel virtual address)
- * p15 = TRUE if psr.i is set in cr.ipsr
- * predicate registers (other than p6, p7, and p15), b6, r3, r8, r9, r10, r11, r14, r15:
- * preserved
- *
- * Note that psr.ic is NOT turned on by this macro. This is so that
- * we can pass interruption state as arguments to a handler.
- */
-#define DO_SAVE_MIN(COVER,EXTRA) \
- mov rARRSC=ar.rsc; \
- mov rARPFS=ar.pfs; \
- mov rR1=r1; \
- mov rARUNAT=ar.unat; \
- mov rCRIPSR=cr.ipsr; \
- mov rB6=b6; /* rB6 = branch reg 6 */ \
- mov rCRIIP=cr.iip; \
- mov r1=ar.k6; /* r1 = current */ \
- ;; \
- invala; \
- extr.u r16=rCRIPSR,32,2; /* extract psr.cpl */ \
- ;; \
- cmp.eq pKern,p7=r0,r16; /* are we in kernel mode already? (psr.cpl==0) */ \
- /* switch from user to kernel RBS: */ \
- COVER; \
- ;; \
-(p7) mov ar.rsc=r0; /* set enforced lazy mode, pl 0, little-endian, loadrs=0 */ \
-(p7) addl rKRBS=IA64_RBS_OFFSET,r1; /* compute base of register backing store */ \
- ;; \
-(p7) mov rARRNAT=ar.rnat; \
-(pKern) dep r1=0,sp,61,3; /* compute physical addr of sp */ \
-(p7) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1; /* compute base of memory stack */ \
-(p7) mov rARBSPSTORE=ar.bspstore; /* save ar.bspstore */ \
-(p7) dep rKRBS=-1,rKRBS,61,3; /* compute kernel virtual addr of RBS */ \
- ;; \
-(pKern) addl r1=-IA64_PT_REGS_SIZE,r1; /* if in kernel mode, use sp (r12) */ \
-(p7) mov ar.bspstore=rKRBS; /* switch to kernel RBS */ \
- ;; \
-(p7) mov r18=ar.bsp; \
-(p7) mov ar.rsc=0x3; /* set eager mode, pl 0, little-endian, loadrs=0 */ \
- \
- mov r16=r1; /* initialize first base pointer */ \
- adds r17=8,r1; /* initialize second base pointer */ \
- ;; \
- st8 [r16]=rCRIPSR,16; /* save cr.ipsr */ \
- st8 [r17]=rCRIIP,16; /* save cr.iip */ \
-(pKern) mov r18=r0; /* make sure r18 isn't NaT */ \
- ;; \
- st8 [r16]=rCRIFS,16; /* save cr.ifs */ \
- st8 [r17]=rARUNAT,16; /* save ar.unat */ \
-(p7) sub r18=r18,rKRBS; /* r18=RSE.ndirty*8 */ \
- ;; \
- st8 [r16]=rARPFS,16; /* save ar.pfs */ \
- st8 [r17]=rARRSC,16; /* save ar.rsc */ \
- tbit.nz p15,p0=rCRIPSR,IA64_PSR_I_BIT \
- ;; /* avoid RAW on r16 & r17 */ \
-(pKern) adds r16=16,r16; /* skip over ar_rnat field */ \
-(pKern) adds r17=16,r17; /* skip over ar_bspstore field */ \
-(p7) st8 [r16]=rARRNAT,16; /* save ar.rnat */ \
-(p7) st8 [r17]=rARBSPSTORE,16; /* save ar.bspstore */ \
- ;; \
- st8 [r16]=rARPR,16; /* save predicates */ \
- st8 [r17]=rB6,16; /* save b6 */ \
- shl r18=r18,16; /* compute ar.rsc to be used for "loadrs" */ \
- ;; \
- st8 [r16]=r18,16; /* save ar.rsc value for "loadrs" */ \
- st8.spill [r17]=rR1,16; /* save original r1 */ \
- cmp.ne pEOI,p0=r0,r0 /* clear pEOI by default */ \
- ;; \
- st8.spill [r16]=r2,16; \
- st8.spill [r17]=r3,16; \
- adds r2=IA64_PT_REGS_R16_OFFSET,r1; \
- ;; \
- st8.spill [r16]=r12,16; \
- st8.spill [r17]=r13,16; \
- cmp.eq pNonSys,pSys=r0,r0 /* initialize pSys=0, pNonSys=1 */ \
- ;; \
- st8.spill [r16]=r14,16; \
- st8.spill [r17]=r15,16; \
- dep r14=-1,r0,61,3; \
- ;; \
- st8.spill [r16]=r8,16; \
- st8.spill [r17]=r9,16; \
- adds r12=-16,r1; /* switch to kernel memory stack (with 16 bytes of scratch) */ \
- ;; \
- st8.spill [r16]=r10,16; \
- st8.spill [r17]=r11,16; \
- mov r13=ar.k6; /* establish `current' */ \
- ;; \
- or r2=r2,r14; /* make first base a kernel virtual address */ \
- EXTRA; \
- movl r1=__gp; /* establish kernel global pointer */ \
- ;; \
- or r12=r12,r14; /* make sp a kernel virtual address */ \
- or r13=r13,r14; /* make `current' a kernel virtual address */ \
- bsw.1;; /* switch back to bank 1 (must be last in insn group) */
-
-#ifdef CONFIG_ITANIUM_ASTEP_SPECIFIC
-# define STOPS nop.i 0x0;; nop.i 0x0;; nop.i 0x0;;
-#else
-# define STOPS
-#endif
-
-#define SAVE_MIN_WITH_COVER DO_SAVE_MIN(cover;; mov rCRIFS=cr.ifs,) STOPS
-#define SAVE_MIN_WITH_COVER_R19 DO_SAVE_MIN(cover;; mov rCRIFS=cr.ifs, mov r15=r19) STOPS
-#define SAVE_MIN DO_SAVE_MIN(mov rCRIFS=r0,) STOPS
-
-/*
- * SAVE_REST saves the remainder of pt_regs (with psr.ic on). This
- * macro guarantees to preserve all predicate registers, r8, r9, r10,
- * r11, r14, and r15.
- *
- * Assumed state upon entry:
- * psr.ic: on
- * psr.dt: on
- * r2: points to &pt_regs.r16
- * r3: points to &pt_regs.r17
- */
-#define SAVE_REST \
- st8.spill [r2]=r16,16; \
- st8.spill [r3]=r17,16; \
- ;; \
- st8.spill [r2]=r18,16; \
- st8.spill [r3]=r19,16; \
- ;; \
- mov r16=ar.ccv; /* M-unit */ \
- movl r18=FPSR_DEFAULT /* L-unit */ \
- ;; \
- mov r17=ar.fpsr; /* M-unit */ \
- mov ar.fpsr=r18; /* M-unit */ \
- ;; \
- st8.spill [r2]=r20,16; \
- st8.spill [r3]=r21,16; \
- mov r18=b0; \
- ;; \
- st8.spill [r2]=r22,16; \
- st8.spill [r3]=r23,16; \
- mov r19=b7; \
- ;; \
- st8.spill [r2]=r24,16; \
- st8.spill [r3]=r25,16; \
- ;; \
- st8.spill [r2]=r26,16; \
- st8.spill [r3]=r27,16; \
- ;; \
- st8.spill [r2]=r28,16; \
- st8.spill [r3]=r29,16; \
- ;; \
- st8.spill [r2]=r30,16; \
- st8.spill [r3]=r31,16; \
- ;; \
- st8 [r2]=r16,16; /* ar.ccv */ \
- st8 [r3]=r17,16; /* ar.fpsr */ \
- ;; \
- st8 [r2]=r18,16; /* b0 */ \
- st8 [r3]=r19,16+8; /* b7 */ \
- ;; \
- stf.spill [r2]=f6,32; \
- stf.spill [r3]=f7,32; \
- ;; \
- stf.spill [r2]=f8,32; \
- stf.spill [r3]=f9,32
-
/*
* This file defines the interrupt vector table used by the CPU.
* It does not include one entry per possible cause of interruption.
@@ -236,9 +29,29 @@
* The table is 32KB in size and must be aligned on 32KB boundary.
* (The CPU ignores the 15 lower bits of the address)
*
- * Table is based upon EAS2.4 (June 1998)
+ * Table is based upon EAS2.6 (Oct 1999)
*/
+#include <linux/config.h>
+
+#include <asm/break.h>
+#include <asm/offsets.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/unistd.h>
+
+#define MINSTATE_START_SAVE_MIN /* no special action needed */
+#define MINSTATE_END_SAVE_MIN \
+ or r2=r2,r14; /* make first base a kernel virtual address */ \
+ or r12=r12,r14; /* make sp a kernel virtual address */ \
+ or r13=r13,r14; /* make `current' a kernel virtual address */ \
+ bsw.1; /* switch back to bank 1 (must be last in insn group) */ \
+ ;;
+
+#include "minstate.h"
+
#define FAULT(n) \
rsm psr.dt; /* avoid nested faults due to TLB misses... */ \
;; \
@@ -336,8 +149,8 @@ ia64_ivt:
(p7) tbit.nz.unc p10,p11=r19,32 // is it an instruction TLB miss?
dep r17=0,r17,0,PAGE_SHIFT // clear low bits to get page address
;;
-(p10) itc.i r18;; // insert the instruction TLB entry (EAS2.6: must be last in insn group!)
-(p11) itc.d r18;; // insert the data TLB entry (EAS2.6: must be last in insn group!)
+(p10) itc.i r18 // insert the instruction TLB entry
+(p11) itc.d r18 // insert the data TLB entry
(p6) br.spnt.few page_fault // handle bad address/page not present (page fault)
mov cr.ifa=r21
@@ -346,9 +159,9 @@ ia64_ivt:
// the exception deferral bit.
adds r16=__DIRTY_BITS_NO_ED|_PAGE_PL_0|_PAGE_AR_RW,r17
;;
-(p7) itc.d r16;; // EAS2.6: must be last in insn group!
+(p7) itc.d r16
mov pr=r31,-1 // restore predicate registers
- rfi;; // must be last insn in an insn group
+ rfi
.align 1024
/////////////////////////////////////////////////////////////////////////////////////////
@@ -395,11 +208,11 @@ ia64_ivt:
;;
(p7) tbit.z p6,p7=r18,0 // page present bit cleared?
;;
-(p7) itc.i r18;; // insert the instruction TLB entry (EAS2.6: must be last in insn group!)
+(p7) itc.i r18 // insert the instruction TLB entry
(p6) br.spnt.few page_fault // handle bad address/page not present (page fault)
;;
mov pr=r31,-1 // restore predicate registers
- rfi;; // must be last insn in an insn group
+ rfi
.align 1024
/////////////////////////////////////////////////////////////////////////////////////////
@@ -446,11 +259,11 @@ ia64_ivt:
;;
(p7) tbit.z p6,p7=r18,0 // page present bit cleared?
;;
-(p7) itc.d r18;; // insert the instruction TLB entry (EAS2.6: must be last in insn group!)
+(p7) itc.d r18 // insert the instruction TLB entry
(p6) br.spnt.few page_fault // handle bad address/page not present (page fault)
;;
mov pr=r31,-1 // restore predicate registers
- rfi;; // must be last insn in an insn group
+ rfi
//-----------------------------------------------------------------------------------
// call do_page_fault (predicates are in r31, psr.dt is off, r16 is faulting address)
@@ -468,10 +281,9 @@ page_fault:
;;
ssm psr.ic | psr.dt
;;
- srlz.d // guarantee that interrupt collection is enabled
-(p15) ssm psr.i // restore psr.i
+ srlz.i // guarantee that interrupt collection is enabled
;;
- srlz.i // must precede "alloc"! (srlz.i implies srlz.d)
+(p15) ssm psr.i // restore psr.i
movl r14=ia64_leave_kernel
;;
alloc r15=ar.pfs,0,0,3,0 // must be first in insn group
@@ -491,15 +303,15 @@ page_fault:
movl r17=__DIRTY_BITS|_PAGE_PL_0|_PAGE_AR_RX
;;
shr.u r18=r16,57 // move address bit 61 to bit 4
- dep r16=0,r16,52,12 // clear top 12 bits of address
+ dep r16=0,r16,IA64_PHYS_BITS,(64-IA64_PHYS_BITS) // clear ed, resvd, and unimpl. phys bits
;;
andcm r18=0x10,r18 // bit 4=~address-bit(61)
dep r16=r17,r16,0,12 // insert PTE control bits into r16
;;
or r16=r16,r18 // set bit 4 (uncached) if the access was to region 6
;;
- itc.i r16;; // insert the TLB entry(EAS2.6: must be last in insn group!)
- rfi;; // must be last insn in an insn group
+ itc.i r16 // insert the TLB entry
+ rfi
.align 1024
/////////////////////////////////////////////////////////////////////////////////////////
@@ -508,15 +320,15 @@ page_fault:
movl r17=__DIRTY_BITS|_PAGE_PL_0|_PAGE_AR_RW
;;
shr.u r18=r16,57 // move address bit 61 to bit 4
- dep r16=0,r16,52,12 // clear top 12 bits of address
+ dep r16=0,r16,IA64_PHYS_BITS,(64-IA64_PHYS_BITS) // clear ed, resvd, and unimpl. phys bits
;;
andcm r18=0x10,r18 // bit 4=~address-bit(61)
dep r16=r17,r16,0,12 // insert PTE control bits into r16
;;
or r16=r16,r18 // set bit 4 (uncached) if the access was to region 6
;;
- itc.d r16;; // insert the TLB entry (EAS2.6: must be last in insn group!)
- rfi;; // must be last insn in an insn group
+ itc.d r16 // insert the TLB entry
+ rfi
.align 1024
/////////////////////////////////////////////////////////////////////////////////////////
@@ -609,27 +421,31 @@ page_fault:
mov b0=r29 // restore b0
;;
st8 [r17]=r18 // store back updated PTE
- itc.d r18;; // install updated PTE (EAS2.6: must be last in insn group!)
- rfi;; // must be last insn in an insn group
+ itc.d r18 // install updated PTE
+ rfi
.align 1024
/////////////////////////////////////////////////////////////////////////////////////////
// 0x2400 Entry 9 (size 64 bundles) Instruction Access-bit (27)
// Like Entry 8, except for instruction access
mov r16=cr.ifa // get the address that caused the fault
-#ifdef CONFIG_ITANIUM_ASTEP_SPECIFIC
+#ifdef CONFIG_ITANIUM
+ /*
+ * Erratum 10 (IFA may contain incorrect address) now has
+ * "NoFix" status. There are no plans for fixing this.
+ */
+ mov r17=cr.ipsr
mov r31=pr // save predicates
- mov r30=cr.ipsr
;;
- extr.u r17=r30,IA64_PSR_IS_BIT,1 // get instruction arch. indicator
+ mov r18=cr.iip
+ tbit.z p6,p0=r17,IA64_PSR_IS_BIT // IA64 instruction set?
;;
- cmp.eq p6,p0 = r17,r0 // check if IA64 instruction set
+(p6) mov r16=r18 // if so, use cr.iip instead of cr.ifa
+#if 0
;;
-(p6) mov r16=cr.iip // get real faulting address
- ;;
-(p6) mov cr.ifa=r16 // reset IFA
+#endif
mov pr=r31,-1
-#endif /* CONFIG_ITANIUM_ASTEP_SPECIFIC */
+#endif /* CONFIG_ITANIUM */
movl r30=1f // load continuation point in case of nested fault
;;
thash r17=r16 // compute virtual address of L3 PTE
@@ -641,8 +457,8 @@ page_fault:
mov b0=r29 // restore b0
;;
st8 [r17]=r18 // store back updated PTE
- itc.i r18;; // install updated PTE (EAS2.6: must be last in insn group!)
- rfi;; // must be last insn in an insn group
+ itc.i r18 // install updated PTE
+ rfi
.align 1024
/////////////////////////////////////////////////////////////////////////////////////////
@@ -660,8 +476,8 @@ page_fault:
mov b0=r29 // restore b0
;;
st8 [r17]=r18 // store back updated PTE
- itc.d r18;; // install updated PTE (EAS2.6: must be last in insn group!)
- rfi;; // must be last insn in an insn group
+ itc.d r18 // install updated PTE
+ rfi
.align 1024
/////////////////////////////////////////////////////////////////////////////////////////
@@ -689,12 +505,11 @@ page_fault:
// turn interrupt collection and data translation back on:
ssm psr.ic | psr.dt
- srlz.d // guarantee that interrupt collection is enabled
+ ;;
+ srlz.i // guarantee that interrupt collection is enabled
cmp.eq pSys,pNonSys=r0,r0 // set pSys=1, pNonSys=0
;;
(p15) ssm psr.i // restore psr.i
- ;;
- srlz.i // ensure everybody knows psr.ic and psr.dt are back on
adds r8=(IA64_PT_REGS_R8_OFFSET-IA64_PT_REGS_R16_OFFSET),r2
;;
stf8 [r8]=f1 // ensure pt_regs.r8 != 0 (see handle_syscall_error)
@@ -813,11 +628,10 @@ dispatch_to_ia32_handler:
;;
mov r14=cr.isr
ssm psr.ic | psr.dt
- srlz.d // guarantee that interrupt collection is enabled
;;
-(p15) ssm psr.i
+ srlz.i // guarantee that interrupt collection is enabled
;;
- srlz.d
+(p15) ssm psr.i
adds r3=8,r2 // Base pointer for SAVE_REST
;;
SAVE_REST
@@ -858,12 +672,13 @@ dispatch_to_ia32_handler:
ld8 r16=[r16]
tbit.z p8,p0=r2,5 // (current->flags & PF_TRACESYS) == 0?
;;
- movl r15=ia32_ret_from_syscall
mov b6=r16
+ movl r15=ia32_ret_from_syscall
;;
mov rp=r15
-(p8) br.call.sptk.few b6=b6
- br.call.sptk.few rp=ia32_trace_syscall // rp will be overwritten (ignored)
+(p8) br.call.sptk.many b6=b6
+ ;;
+ br.call.sptk.many rp=ia32_trace_syscall // rp will be overwritten (ignored)
non_ia32_syscall:
alloc r15=ar.pfs,0,0,2,0
@@ -885,13 +700,6 @@ non_ia32_syscall:
FAULT(17)
non_syscall:
-
-#ifdef CONFIG_KDB
- mov r17=__IA64_BREAK_KDB
- ;;
- cmp.eq p8,p0=r16,r17 // is this a kernel breakpoint?
-#endif
-
SAVE_MIN_WITH_COVER
// There is no particular reason for this code to be here, other than that
@@ -904,11 +712,10 @@ non_syscall:
// turn interrupt collection and data translation back on:
ssm psr.ic | psr.dt
- srlz.d // guarantee that interrupt collection is enabled
;;
-(p15) ssm psr.i // restore psr.i
+ srlz.i // guarantee that interrupt collection is enabled
;;
- srlz.i // ensure everybody knows psr.ic and psr.dt are back on
+(p15) ssm psr.i // restore psr.i
movl r15=ia64_leave_kernel
;;
alloc r14=ar.pfs,0,0,2,0
@@ -918,9 +725,6 @@ non_syscall:
SAVE_REST
mov rp=r15
;;
-#ifdef CONFIG_KDB
-(p8) br.call.sptk.few b6=ia64_invoke_kdb
-#endif
br.call.sptk.few b6=ia64_bad_break // avoid WAW on CFM and ignore return addr
.align 1024
@@ -945,11 +749,10 @@ dispatch_unaligned_handler:
//
mov r15=cr.ifa
ssm psr.ic | psr.dt
- srlz.d // guarantee that interrupt collection is enabled
;;
-(p15) ssm psr.i // restore psr.i
+ srlz.i // guarantee that interrupt collection is enabled
;;
- srlz.i
+(p15) ssm psr.i // restore psr.i
adds r3=8,r2 // set up second base pointer
;;
SAVE_REST
@@ -994,13 +797,12 @@ dispatch_to_fault_handler:
mov r11=cr.itir
;;
ssm psr.ic | psr.dt
- srlz.d // guarantee that interrupt collection is enabled
+ ;;
+ srlz.i // guarantee that interrupt collection is enabled
;;
(p15) ssm psr.i // restore psr.i
adds r3=8,r2 // set up second base pointer for SAVE_REST
;;
- srlz.i // must precede "alloc"!
- ;;
alloc r14=ar.pfs,0,0,5,0 // must be first in insn group
mov out0=r15
mov out1=r8
@@ -1012,11 +814,7 @@ dispatch_to_fault_handler:
movl r14=ia64_leave_kernel
;;
mov rp=r14
-#ifdef CONFIG_KDB
- br.call.sptk.few b6=ia64_invoke_kdb_fault_handler
-#else
br.call.sptk.few b6=ia64_fault
-#endif
//
// --- End of long entries, Beginning of short entries
//
@@ -1121,7 +919,7 @@ dispatch_to_fault_handler:
mov cr.ipsr=r16
;;
- rfi;; // and go back (must be last insn in group)
+ rfi // and go back
.align 256
/////////////////////////////////////////////////////////////////////////////////////////
@@ -1142,11 +940,7 @@ dispatch_to_fault_handler:
;;
srlz.d // ensure everyone knows psr.dt is off
mov r19=30 // error vector for fault_handler (when kernel)
- extr.u r16=r16,32,2 // extract psr.cpl
- ;;
- cmp.eq p6,p7=r0,r16 // if kernel cpl then fault else emulate
-(p7) br.cond.sptk.many dispatch_unaligned_handler
-(p6) br.cond.sptk.many dispatch_to_fault_handler
+ br.cond.sptk.many dispatch_unaligned_handler
.align 256
/////////////////////////////////////////////////////////////////////////////////////////
@@ -1226,6 +1020,31 @@ dispatch_to_fault_handler:
.align 256
/////////////////////////////////////////////////////////////////////////////////////////
// 0x6a00 Entry 46 (size 16 bundles) IA-32 Intercept (30,31,59,70,71)
+#ifdef CONFIG_IA32_SUPPORT
+ rsm psr.dt
+ ;;
+ srlz.d
+ mov r31=pr
+ mov r16=cr.isr
+ ;;
+ extr.u r17=r16,16,8 // get ISR.code
+ mov r18=ar.eflag
+ mov r19=cr.iim // old eflag value
+ ;;
+ cmp.ne p2,p0=2,r17
+(p2) br.cond.spnt 1f // not a system flag fault
+ xor r16=r18,r19
+ ;;
+ extr.u r17=r16,18,1 // get the eflags.ac bit
+ ;;
+ cmp.eq p2,p0=0,r17
+(p2) br.cond.spnt 1f // eflags.ac bit didn't change
+ ;;
+ mov pr=r31,-1 // restore predicate registers
+ rfi
+
+1:
+#endif // CONFIG_IA32_SUPPORT
FAULT(46)
.align 256
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
index 320c56ebc..150feac03 100644
--- a/arch/ia64/kernel/mca.c
+++ b/arch/ia64/kernel/mca.c
@@ -2,21 +2,37 @@
* File: mca.c
* Purpose: Generic MCA handling layer
*
+ * Updated for latest kernel
+ * Copyright (C) 2000 Intel
+ * Copyright (C) Chuck Fleckenstein (cfleck@co.intel.com)
+ *
* Copyright (C) 1999 Silicon Graphics, Inc.
* Copyright (C) Vijay Chander(vijay@engr.sgi.com)
+ *
+ * 00/03/29 C. Fleckenstein Fixed PAL/SAL update issues, began MCA bug fixes, logging issues,
+ * added min save state dump, added INIT handler.
*/
#include <linux/types.h>
#include <linux/init.h>
#include <linux/sched.h>
+#include <linux/irq.h>
+#include <linux/smp_lock.h>
+#include <linux/config.h>
+
#include <asm/page.h>
#include <asm/ptrace.h>
#include <asm/system.h>
#include <asm/sal.h>
#include <asm/mca.h>
-#include <asm/spinlock.h>
+
#include <asm/irq.h>
#include <asm/machvec.h>
+
+typedef struct ia64_fptr {
+ unsigned long fp;
+ unsigned long gp;
+} ia64_fptr_t;
ia64_mc_info_t ia64_mc_info;
ia64_mca_sal_to_os_state_t ia64_sal_to_os_handoff_state;
@@ -25,6 +41,11 @@ u64 ia64_mca_proc_state_dump[256];
u64 ia64_mca_stack[1024];
u64 ia64_mca_stackframe[32];
u64 ia64_mca_bspstore[1024];
+u64 ia64_init_stack[INIT_TASK_SIZE] __attribute__((aligned(16)));
+
+#if defined(SAL_MPINIT_WORKAROUND) && !defined(CONFIG_SMP)
+int bootstrap_processor = -1;
+#endif
static void ia64_mca_cmc_vector_setup(int enable,
int_vector_t cmc_vector);
@@ -34,7 +55,98 @@ static void ia64_mca_wakeup_all(void);
static void ia64_log_init(int,int);
static void ia64_log_get(int,int, prfunc_t);
static void ia64_log_clear(int,int,int, prfunc_t);
+extern void ia64_monarch_init_handler (void);
+extern void ia64_slave_init_handler (void);
+
+/*
+ * hack for now, add platform dependent handlers
+ * here
+ */
+#ifndef PLATFORM_MCA_HANDLERS
+void
+mca_handler_platform (void)
+{
+
+}
+
+void
+cmci_handler_platform (int cmc_irq, void *arg, struct pt_regs *ptregs)
+{
+
+}
+/*
+ * This routine will be used to deal with platform specific handling
+ * of the init, i.e. drop into the kernel debugger on server machine,
+ * or if the processor is part of some parallel machine without a
+ * console, then we would call the appropriate debug hooks here.
+ */
+void
+init_handler_platform (struct pt_regs *regs)
+{
+ /* if a kernel debugger is available call it here else just dump the registers */
+ show_regs(regs); /* dump the state info */
+}
+
+void
+log_print_platform ( void *cur_buff_ptr, prfunc_t prfunc)
+{
+}
+
+void
+ia64_mca_init_platform (void)
+{
+}
+
+#endif /* PLATFORM_MCA_HANDLERS */
+
+static char *min_state_labels[] = {
+ "nat",
+ "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8",
+ "r9", "r10","r11", "r12","r13","r14", "r15",
+ "b0r16","b0r17", "b0r18", "b0r19", "b0r20",
+ "b0r21", "b0r22","b0r23", "b0r24", "b0r25",
+ "b0r26", "b0r27", "b0r28","b0r29", "b0r30", "b0r31",
+ "r16", "r17", "r18","r19", "r20", "r21","r22",
+ "r23", "r24","r25", "r26", "r27","r28", "r29", "r30","r31",
+ "preds", "br0", "rsc",
+ "iip", "ipsr", "ifs",
+ "xip", "xpsr", "xfs"
+};
+
+int ia64_pmss_dump_bank0=0; /* dump bank 0 ? */
+
+/*
+ * routine to process and prepare to dump min_state_save
+ * information for debugging purposes.
+ *
+ */
+void
+ia64_process_min_state_save (pal_min_state_area_t *pmss, struct pt_regs *ptregs)
+{
+ int i, max=57;
+ u64 *tpmss_ptr=(u64 *)pmss;
+
+ /* dump out the min_state_area information */
+ for (i=0;i<max;i++) {
+
+ if(!ia64_pmss_dump_bank0) {
+ if(strncmp("B0",min_state_labels[i],2)==0) {
+ tpmss_ptr++; /* skip to next entry */
+ continue;
+ }
+ }
+
+ printk("%5s=0x%16.16lx ",min_state_labels[i],*tpmss_ptr++);
+
+ if (((i+1)%3)==0 || ((!strcmp("GR16",min_state_labels[i]))
+ && !ia64_pmss_dump_bank0))
+ printk("\n");
+ }
+ /* hang city for now, until we include debugger or copy to ptregs to show: */
+ while (1);
+}
+
/*
* ia64_mca_cmc_vector_setup
* Setup the correctable machine check vector register in the processor
@@ -83,7 +195,7 @@ mca_test(void)
#endif /* #if defined(MCA_TEST) */
/*
- * mca_init
+ * ia64_mca_init
* Do all the mca specific initialization on a per-processor basis.
*
* 1. Register spinloop and wakeup request interrupt vectors
@@ -93,7 +205,7 @@ mca_test(void)
* 3. Register OS_INIT handler entry point
*
* 4. Initialize CMCV register to enable/disable CMC interrupt on the
- * processor and hook a handler in the platform-specific mca_init.
+ * processor and hook a handler in the platform-specific ia64_mca_init.
*
* 5. Initialize MCA/CMC/INIT related log buffers maintained by the OS.
*
@@ -103,11 +215,20 @@ mca_test(void)
* None
*/
void __init
-mca_init(void)
+ia64_mca_init(void)
{
- int i;
+ ia64_fptr_t *mon_init_ptr = (ia64_fptr_t *)ia64_monarch_init_handler;
+ ia64_fptr_t *slave_init_ptr = (ia64_fptr_t *)ia64_slave_init_handler;
+ int i;
+
+ IA64_MCA_DEBUG("ia64_mca_init : begin\n");
+
+#if defined(SAL_MPINIT_WORKAROUND) && !defined(CONFIG_SMP)
+ /* XXX -- workaround for SAL bug for running on MP system, but UP kernel */
+
+ bootstrap_processor = hard_smp_processor_id();
+#endif
- MCA_DEBUG("mca_init : begin\n");
/* Clear the Rendez checkin flag for all cpus */
for(i = 0 ; i < IA64_MAXCPUS; i++)
ia64_mc_info.imi_rendez_checkin[i] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE;
@@ -134,14 +255,14 @@ mca_init(void)
0))
return;
- MCA_DEBUG("mca_init : registered mca rendezvous spinloop and wakeup mech.\n");
+ IA64_MCA_DEBUG("ia64_mca_init : registered mca rendezvous spinloop and wakeup mech.\n");
/*
* Setup the correctable machine check vector
*/
ia64_mca_cmc_vector_setup(IA64_CMC_INT_ENABLE,
IA64_MCA_CMC_INT_VECTOR);
- MCA_DEBUG("mca_init : correctable mca vector setup done\n");
+ IA64_MCA_DEBUG("ia64_mca_init : correctable mca vector setup done\n");
ia64_mc_info.imi_mca_handler = __pa(ia64_os_mca_dispatch);
ia64_mc_info.imi_mca_handler_size =
@@ -155,12 +276,15 @@ mca_init(void)
return;
- MCA_DEBUG("mca_init : registered os mca handler with SAL\n");
+ IA64_MCA_DEBUG("ia64_mca_init : registered os mca handler with SAL\n");
- ia64_mc_info.imi_monarch_init_handler = __pa(ia64_monarch_init_handler);
+ ia64_mc_info.imi_monarch_init_handler = __pa(mon_init_ptr->fp);
ia64_mc_info.imi_monarch_init_handler_size = IA64_INIT_HANDLER_SIZE;
- ia64_mc_info.imi_slave_init_handler = __pa(ia64_slave_init_handler);
+ ia64_mc_info.imi_slave_init_handler = __pa(slave_init_ptr->fp);
ia64_mc_info.imi_slave_init_handler_size = IA64_INIT_HANDLER_SIZE;
+
+ IA64_MCA_DEBUG("ia64_mca_init : os init handler at %lx\n",ia64_mc_info.imi_monarch_init_handler);
+
/* Register the os init handler with SAL */
if (ia64_sal_set_vectors(SAL_VECTOR_OS_INIT,
ia64_mc_info.imi_monarch_init_handler,
@@ -173,7 +297,7 @@ mca_init(void)
return;
- MCA_DEBUG("mca_init : registered os init handler with SAL\n");
+ IA64_MCA_DEBUG("ia64_mca_init : registered os init handler with SAL\n");
/* Initialize the areas set aside by the OS to buffer the
* platform/processor error states for MCA/INIT/CMC
@@ -186,9 +310,9 @@ mca_init(void)
ia64_log_init(SAL_INFO_TYPE_CMC, SAL_SUB_INFO_TYPE_PROCESSOR);
ia64_log_init(SAL_INFO_TYPE_CMC, SAL_SUB_INFO_TYPE_PLATFORM);
- mca_init_platform();
+ ia64_mca_init_platform();
- MCA_DEBUG("mca_init : platform-specific mca handling setup done\n");
+ IA64_MCA_DEBUG("ia64_mca_init : platform-specific mca handling setup done\n");
#if defined(MCA_TEST)
mca_test();
@@ -244,7 +368,7 @@ ia64_mca_wakeup_ipi_wait(void)
void
ia64_mca_wakeup(int cpu)
{
- ipi_send(cpu, IA64_MCA_WAKEUP_INT_VECTOR, IA64_IPI_DM_INT);
+ ipi_send(cpu, IA64_MCA_WAKEUP_INT_VECTOR, IA64_IPI_DM_INT, 0);
ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE;
}
@@ -396,25 +520,6 @@ ia64_mca_ucmc_handler(void)
ia64_return_to_sal_check();
}
-/*
- * SAL to OS entry point for INIT on the monarch processor
- * This has been defined for registration purposes with SAL
- * as a part of mca_init.
- */
-void
-ia64_monarch_init_handler()
-{
-}
-/*
- * SAL to OS entry point for INIT on the slave processor
- * This has been defined for registration purposes with SAL
- * as a part of mca_init.
- */
-
-void
-ia64_slave_init_handler()
-{
-}
/*
* ia64_mca_cmc_int_handler
* This is correctable machine check interrupt handler.
@@ -450,10 +555,9 @@ ia64_mca_cmc_int_handler(int cmc_irq, void *arg, struct pt_regs *ptregs)
#define IA64_MAX_LOG_SUBTYPES 2 /* Processor, Platform */
typedef struct ia64_state_log_s {
- spinlock_t isl_lock;
- int isl_index;
- sal_log_header_t isl_log[IA64_MAX_LOGS];
-
+ spinlock_t isl_lock;
+ int isl_index;
+ ia64_psilog_t isl_log[IA64_MAX_LOGS]; /* need space to store header + error log */
} ia64_state_log_t;
static ia64_state_log_t ia64_state_log[IA64_MAX_LOG_TYPES][IA64_MAX_LOG_SUBTYPES];
@@ -472,6 +576,53 @@ static ia64_state_log_t ia64_state_log[IA64_MAX_LOG_TYPES][IA64_MAX_LOG_SUBTYPES
#define IA64_LOG_CURR_BUFFER(it, sit) (void *)(&(ia64_state_log[it][sit].isl_log[IA64_LOG_CURR_INDEX(it,sit)]))
/*
+ * C portion of the OS INIT handler
+ *
+ * Called from ia64_<monarch/slave>_init_handler
+ *
+ * Inputs: pointer to pt_regs where processor info was saved.
+ *
+ * Returns:
+ * 0 if SAL must warm boot the System
+ * 1 if SAL must retrun to interrupted context using PAL_MC_RESUME
+ *
+ */
+
+void
+ia64_init_handler (struct pt_regs *regs)
+{
+ sal_log_processor_info_t *proc_ptr;
+ ia64_psilog_t *plog_ptr;
+
+ printk("Entered OS INIT handler\n");
+
+ /* Get the INIT processor log */
+ ia64_log_get(SAL_INFO_TYPE_INIT, SAL_SUB_INFO_TYPE_PROCESSOR, (prfunc_t)printk);
+ /* Get the INIT platform log */
+ ia64_log_get(SAL_INFO_TYPE_INIT, SAL_SUB_INFO_TYPE_PLATFORM, (prfunc_t)printk);
+
+#ifdef IA64_DUMP_ALL_PROC_INFO
+ ia64_log_print(SAL_INFO_TYPE_INIT, SAL_SUB_INFO_TYPE_PROCESSOR, (prfunc_t)printk);
+#endif
+
+ /*
+ * get pointer to min state save area
+ *
+ */
+ plog_ptr=(ia64_psilog_t *)IA64_LOG_CURR_BUFFER(SAL_INFO_TYPE_INIT,
+ SAL_SUB_INFO_TYPE_PROCESSOR);
+ proc_ptr = &plog_ptr->devlog.proclog;
+
+ ia64_process_min_state_save(&proc_ptr->slpi_min_state_area,regs);
+
+ init_handler_platform(regs); /* call platform specific routines */
+
+ /* Clear the INIT SAL logs now that they have been saved in the OS buffer */
+ ia64_sal_clear_state_info(SAL_INFO_TYPE_INIT, SAL_SUB_INFO_TYPE_PROCESSOR);
+ ia64_sal_clear_state_info(SAL_INFO_TYPE_INIT, SAL_SUB_INFO_TYPE_PLATFORM);
+}
+
+/*
* ia64_log_init
* Reset the OS ia64 log buffer
* Inputs : info_type (SAL_INFO_TYPE_{MCA,INIT,CMC})
@@ -484,7 +635,7 @@ ia64_log_init(int sal_info_type, int sal_sub_info_type)
IA64_LOG_LOCK_INIT(sal_info_type, sal_sub_info_type);
IA64_LOG_NEXT_INDEX(sal_info_type, sal_sub_info_type) = 0;
memset(IA64_LOG_NEXT_BUFFER(sal_info_type, sal_sub_info_type), 0,
- sizeof(sal_log_header_t) * IA64_MAX_LOGS);
+ sizeof(ia64_psilog_t) * IA64_MAX_LOGS);
}
/*
@@ -499,7 +650,7 @@ void
ia64_log_get(int sal_info_type, int sal_sub_info_type, prfunc_t prfunc)
{
sal_log_header_t *log_buffer;
- int s;
+ int s,total_len=0;
IA64_LOG_LOCK(sal_info_type, sal_sub_info_type);
@@ -507,9 +658,11 @@ ia64_log_get(int sal_info_type, int sal_sub_info_type, prfunc_t prfunc)
/* Get the process state information */
log_buffer = IA64_LOG_NEXT_BUFFER(sal_info_type, sal_sub_info_type);
- if (ia64_sal_get_state_info(sal_info_type, sal_sub_info_type ,(u64 *)log_buffer))
+ if (!(total_len=ia64_sal_get_state_info(sal_info_type, sal_sub_info_type ,(u64 *)log_buffer)))
prfunc("ia64_mca_log_get : Getting processor log failed\n");
+ IA64_MCA_DEBUG("ia64_log_get: retrieved %d bytes of error information\n",total_len);
+
IA64_LOG_INDEX_INC(sal_info_type, sal_sub_info_type);
IA64_LOG_UNLOCK(sal_info_type, sal_sub_info_type);
@@ -542,7 +695,7 @@ ia64_log_clear(int sal_info_type, int sal_sub_info_type, int clear_os_buffer, pr
/* Get the process state information */
log_buffer = IA64_LOG_CURR_BUFFER(sal_info_type, sal_sub_info_type);
- memset(log_buffer, 0, sizeof(sal_log_header_t));
+ memset(log_buffer, 0, sizeof(ia64_psilog_t));
IA64_LOG_INDEX_DEC(sal_info_type, sal_sub_info_type);
@@ -731,11 +884,7 @@ ia64_log_processor_info_print(sal_log_header_t *lh, prfunc_t prfunc)
if (lh->slh_log_type != SAL_SUB_INFO_TYPE_PROCESSOR)
return;
-#if defined(MCA_TEST)
- slpi = &slpi_buf;
-#else
- slpi = (sal_log_processor_info_t *)lh->slh_log_dev_spec_info;
-#endif /#if defined(MCA_TEST) */
+ slpi = (sal_log_processor_info_t *)((char *)lh+sizeof(sal_log_header_t)); /* point to proc info */
if (!slpi) {
prfunc("No Processor Error Log found\n");
@@ -763,14 +912,6 @@ ia64_log_processor_info_print(sal_log_header_t *lh, prfunc_t prfunc)
ia64_log_processor_regs_print(slpi->slpi_fr, 128, "Floating-point", "fr",
prfunc);
- /* Print bank1-gr NAT register contents if valid */
- ia64_log_processor_regs_print(&slpi->slpi_bank1_nat_bits, 1, "NAT", "nat", prfunc);
-
- /* Print bank 1 register contents if valid */
- if (slpi->slpi_valid.slpi_bank1_gr)
- ia64_log_processor_regs_print(slpi->slpi_bank1_gr, 16, "Bank1-General", "gr",
- prfunc);
-
/* Print the cache check information if any*/
for (i = 0 ; i < MAX_CACHE_ERRORS; i++)
ia64_log_cache_check_info_print(i,
diff --git a/arch/ia64/kernel/mca_asm.S b/arch/ia64/kernel/mca_asm.S
index 3d49ac06e..81966bb99 100644
--- a/arch/ia64/kernel/mca_asm.S
+++ b/arch/ia64/kernel/mca_asm.S
@@ -1,7 +1,31 @@
+//
+// assembly portion of the IA64 MCA handling
+//
+// Mods by cfleck to integrate into kernel build
+// 00/03/15 davidm Added various stop bits to get a clean compile
+// 00/03/29 cfleck Added code to save INIT handoff state in pt_regs format, switch to temp kstack,
+// switch modes, jump to C INIT handler
+//
+#include <asm/offsets.h>
+#include <asm/pgtable.h>
#include <asm/processor.h>
-#include <asm/mcaasm.h>
-#include <asm/page.h>
+#include <asm/mca_asm.h>
#include <asm/mca.h>
+
+/*
+ * When we get an machine check, the kernel stack pointer is no longer
+ * valid, so we need to set a new stack pointer.
+ */
+#define MINSTATE_START_SAVE_MIN \
+(pKern) movl sp=ia64_init_stack+IA64_STK_OFFSET-IA64_PT_REGS_SIZE; \
+ ;;
+
+#define MINSTATE_END_SAVE_MIN \
+ or r12=r12,r14; /* make sp a kernel virtual address */ \
+ or r13=r13,r14; /* make `current' a kernel virtual address */ \
+ ;;
+
+#include "minstate.h"
.psr abi64
.psr lsb
@@ -54,7 +78,9 @@
100: (p) mov temp=ip; \
;; \
(p) adds temp=to_label-100b,temp;\
+ ;; \
(p) adds temp=adjust,temp; \
+ ;; \
(p) mov b1=temp ; \
(p) br b1
@@ -68,6 +94,7 @@
.global ia64_mca_stack
.global ia64_mca_stackframe
.global ia64_mca_bspstore
+ .global ia64_init_stack
.text
.align 16
@@ -341,6 +368,7 @@ cSaveARs:
mov r3=ar16 // ar.rsc
mov ar16=r0 // put RSE in enforced lazy mode
mov r5=ar17 // ar.bsp
+ ;;
mov r7=ar18;; // ar.bspstore
st8 [r2]=r3,3*8
st8 [r4]=r5,3*8
@@ -575,6 +603,7 @@ restore_ARs:
// mov ar16=r3 // ar.rsc
// mov ar17=r5 // ar.bsp is read only
mov ar16=r0 // make sure that RSE is in enforced lazy mode
+ ;;
mov ar18=r7;; // ar.bspstore
ld8 r9=[r2],8*13;;
@@ -619,3 +648,146 @@ end_os_mca_restore:
BRANCH(ia64_os_mca_done_restore, r2, p0, -0x20)
;;
//EndStub//////////////////////////////////////////////////////////////////////
+
+// ok, the issue here is that we need to save state information so
+// it can be useable by the kernel debugger and show regs routines.
+// In order to do this, our best bet is save the current state (plus
+// the state information obtain from the MIN_STATE_AREA) into a pt_regs
+// format. This way we can pass it on in a useable format.
+//
+
+//
+// SAL to OS entry point for INIT on the monarch processor
+// This has been defined for registration purposes with SAL
+// as a part of ia64_mca_init.
+//
+// When we get here, the follow registers have been
+// set by the SAL for our use
+//
+// 1. GR1 = OS INIT GP
+// 2. GR8 = PAL_PROC physical address
+// 3. GR9 = SAL_PROC physical address
+// 4. GR10 = SAL GP (physical)
+// 5. GR11 = Init Reason
+// 0 = Received INIT for event other than crash dump switch
+// 1 = Received wakeup at the end of an OS_MCA corrected machine check
+// 2 = Received INIT dude to CrashDump switch assertion
+//
+// 6. GR12 = Return address to location within SAL_INIT procedure
+
+
+ .text
+ .align 16
+.global ia64_monarch_init_handler
+.proc ia64_monarch_init_handler
+ia64_monarch_init_handler:
+
+#if defined(SAL_MPINIT_WORKAROUND)
+ //
+ // work around SAL bug that sends all processors to monarch entry
+ //
+ .global bootstrap_processor
+
+ movl r21=24
+ movl r20=16
+ mov r17=cr.lid
+ movl r18=bootstrap_processor
+ ;;
+ dep r18=0,r18,61,3 // convert bsp to physical address
+ ;;
+ shr r19=r17,r20
+ shr r22=r17,r21
+ ld4 r18=[r18] // get the BSP ID
+ ;;
+ and r19=0xf, r19
+ and r22=0xf, r22
+ ;;
+ shl r19=r19,8 // get them in the right order
+ ;;
+ or r22=r22,r19 // combine EID and LID
+ ;;
+ cmp.eq p6,p7=r22,r18 // Am I the BSP ?
+(p7) br.cond.spnt slave_init_spin_me
+ ;;
+#endif
+
+
+//
+// ok, the first thing we do is stash the information
+// the SAL passed to os
+//
+_tmp = r2
+ movl _tmp=ia64_sal_to_os_handoff_state
+ ;;
+ dep _tmp=0,_tmp, 61, 3 // get physical address
+ ;;
+ st8 [_tmp]=r1,0x08;;
+ st8 [_tmp]=r8,0x08;;
+ st8 [_tmp]=r9,0x08;;
+ st8 [_tmp]=r10,0x08;;
+ st8 [_tmp]=r11,0x08;;
+ st8 [_tmp]=r12,0x08;;
+
+// now we want to save information so we can dump registers
+ SAVE_MIN_WITH_COVER
+ ;;
+ mov r8=cr.ifa
+ mov r9=cr.isr
+ adds r3=8,r2 // set up second base pointer
+ ;;
+ SAVE_REST
+
+// ok, enough should be saved at this point to be dangerous, and supply
+// information for a dump
+// We need to switch to Virtual mode before hitting the C functions.
+//
+//
+//
+ movl r2=IA64_PSR_IT|IA64_PSR_IC|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_DFH|IA64_PSR_BN
+ mov r3=psr // get the current psr, minimum enabled at this point
+ ;;
+ or r2=r2,r3
+ ;;
+ movl r3=IVirtual_Switch
+ ;;
+ mov cr.iip=r3 // short return to set the appropriate bits
+ mov cr.ipsr=r2 // need to do an rfi to set appropriate bits
+ ;;
+ rfi
+ ;;
+IVirtual_Switch:
+ //
+ // We should now be running virtual
+ //
+ // Lets call the C handler to get the rest of the state info
+ //
+ alloc r14=ar.pfs,0,0,1,0 // now it's safe (must be first in insn group!)
+ ;; //
+ adds out0=16,sp // out0 = pointer to pt_regs
+ ;;
+
+ br.call.sptk.few rp=ia64_init_handler
+ ;;
+
+return_from_init:
+ br.sptk return_from_init
+
+ .endp
+
+//
+// SAL to OS entry point for INIT on the slave processor
+// This has been defined for registration purposes with SAL
+// as a part of ia64_mca_init.
+//
+
+ .text
+ .align 16
+.global ia64_slave_init_handler
+.proc ia64_slave_init_handler
+ia64_slave_init_handler:
+
+
+slave_init_spin_me:
+ br.sptk slave_init_spin_me
+ ;;
+ .endp
diff --git a/arch/ia64/kernel/minstate.h b/arch/ia64/kernel/minstate.h
new file mode 100644
index 000000000..bcfe1659c
--- /dev/null
+++ b/arch/ia64/kernel/minstate.h
@@ -0,0 +1,205 @@
+#include <linux/config.h>
+
+#include "entry.h"
+
+/*
+ * A couple of convenience macros that make writing and reading
+ * SAVE_MIN and SAVE_REST easier.
+ */
+#define rARPR r31
+#define rCRIFS r30
+#define rCRIPSR r29
+#define rCRIIP r28
+#define rARRSC r27
+#define rARPFS r26
+#define rARUNAT r25
+#define rARRNAT r24
+#define rARBSPSTORE r23
+#define rKRBS r22
+#define rB6 r21
+#define rR1 r20
+
+/*
+ * DO_SAVE_MIN switches to the kernel stacks (if necessary) and saves
+ * the minimum state necessary that allows us to turn psr.ic back
+ * on.
+ *
+ * Assumed state upon entry:
+ * psr.ic: off
+ * psr.dt: off
+ * r31: contains saved predicates (pr)
+ *
+ * Upon exit, the state is as follows:
+ * psr.ic: off
+ * psr.dt: off
+ * r2 = points to &pt_regs.r16
+ * r12 = kernel sp (kernel virtual address)
+ * r13 = points to current task_struct (kernel virtual address)
+ * p15 = TRUE if psr.i is set in cr.ipsr
+ * predicate registers (other than p6, p7, and p15), b6, r3, r8, r9, r10, r11, r14, r15:
+ * preserved
+ *
+ * Note that psr.ic is NOT turned on by this macro. This is so that
+ * we can pass interruption state as arguments to a handler.
+ */
+#define DO_SAVE_MIN(COVER,EXTRA) \
+ mov rARRSC=ar.rsc; \
+ mov rARPFS=ar.pfs; \
+ mov rR1=r1; \
+ mov rARUNAT=ar.unat; \
+ mov rCRIPSR=cr.ipsr; \
+ mov rB6=b6; /* rB6 = branch reg 6 */ \
+ mov rCRIIP=cr.iip; \
+ mov r1=ar.k6; /* r1 = current */ \
+ ;; \
+ invala; \
+ extr.u r16=rCRIPSR,32,2; /* extract psr.cpl */ \
+ ;; \
+ cmp.eq pKern,p7=r0,r16; /* are we in kernel mode already? (psr.cpl==0) */ \
+ /* switch from user to kernel RBS: */ \
+ COVER; \
+ ;; \
+ MINSTATE_START_SAVE_MIN \
+(p7) mov ar.rsc=r0; /* set enforced lazy mode, pl 0, little-endian, loadrs=0 */ \
+(p7) addl rKRBS=IA64_RBS_OFFSET,r1; /* compute base of register backing store */ \
+ ;; \
+(p7) mov rARRNAT=ar.rnat; \
+(pKern) dep r1=0,sp,61,3; /* compute physical addr of sp */ \
+(p7) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1; /* compute base of memory stack */ \
+(p7) mov rARBSPSTORE=ar.bspstore; /* save ar.bspstore */ \
+(p7) dep rKRBS=-1,rKRBS,61,3; /* compute kernel virtual addr of RBS */ \
+ ;; \
+(pKern) addl r1=-IA64_PT_REGS_SIZE,r1; /* if in kernel mode, use sp (r12) */ \
+(p7) mov ar.bspstore=rKRBS; /* switch to kernel RBS */ \
+ ;; \
+(p7) mov r18=ar.bsp; \
+(p7) mov ar.rsc=0x3; /* set eager mode, pl 0, little-endian, loadrs=0 */ \
+ \
+ mov r16=r1; /* initialize first base pointer */ \
+ adds r17=8,r1; /* initialize second base pointer */ \
+ ;; \
+ st8 [r16]=rCRIPSR,16; /* save cr.ipsr */ \
+ st8 [r17]=rCRIIP,16; /* save cr.iip */ \
+(pKern) mov r18=r0; /* make sure r18 isn't NaT */ \
+ ;; \
+ st8 [r16]=rCRIFS,16; /* save cr.ifs */ \
+ st8 [r17]=rARUNAT,16; /* save ar.unat */ \
+(p7) sub r18=r18,rKRBS; /* r18=RSE.ndirty*8 */ \
+ ;; \
+ st8 [r16]=rARPFS,16; /* save ar.pfs */ \
+ st8 [r17]=rARRSC,16; /* save ar.rsc */ \
+ tbit.nz p15,p0=rCRIPSR,IA64_PSR_I_BIT \
+ ;; /* avoid RAW on r16 & r17 */ \
+(pKern) adds r16=16,r16; /* skip over ar_rnat field */ \
+(pKern) adds r17=16,r17; /* skip over ar_bspstore field */ \
+(p7) st8 [r16]=rARRNAT,16; /* save ar.rnat */ \
+(p7) st8 [r17]=rARBSPSTORE,16; /* save ar.bspstore */ \
+ ;; \
+ st8 [r16]=rARPR,16; /* save predicates */ \
+ st8 [r17]=rB6,16; /* save b6 */ \
+ shl r18=r18,16; /* compute ar.rsc to be used for "loadrs" */ \
+ ;; \
+ st8 [r16]=r18,16; /* save ar.rsc value for "loadrs" */ \
+ st8.spill [r17]=rR1,16; /* save original r1 */ \
+ cmp.ne pEOI,p0=r0,r0 /* clear pEOI by default */ \
+ ;; \
+.mem.offset 0,0; st8.spill [r16]=r2,16; \
+.mem.offset 8,0; st8.spill [r17]=r3,16; \
+ adds r2=IA64_PT_REGS_R16_OFFSET,r1; \
+ ;; \
+.mem.offset 0,0; st8.spill [r16]=r12,16; \
+.mem.offset 8,0; st8.spill [r17]=r13,16; \
+ cmp.eq pNonSys,pSys=r0,r0 /* initialize pSys=0, pNonSys=1 */ \
+ ;; \
+.mem.offset 0,0; st8.spill [r16]=r14,16; \
+.mem.offset 8,0; st8.spill [r17]=r15,16; \
+ dep r14=-1,r0,61,3; \
+ ;; \
+.mem.offset 0,0; st8.spill [r16]=r8,16; \
+.mem.offset 8,0; st8.spill [r17]=r9,16; \
+ adds r12=-16,r1; /* switch to kernel memory stack (with 16 bytes of scratch) */ \
+ ;; \
+.mem.offset 0,0; st8.spill [r16]=r10,16; \
+.mem.offset 8,0; st8.spill [r17]=r11,16; \
+ mov r13=ar.k6; /* establish `current' */ \
+ ;; \
+ EXTRA; \
+ movl r1=__gp; /* establish kernel global pointer */ \
+ ;; \
+ MINSTATE_END_SAVE_MIN
+
+/*
+ * SAVE_REST saves the remainder of pt_regs (with psr.ic on). This
+ * macro guarantees to preserve all predicate registers, r8, r9, r10,
+ * r11, r14, and r15.
+ *
+ * Assumed state upon entry:
+ * psr.ic: on
+ * psr.dt: on
+ * r2: points to &pt_regs.r16
+ * r3: points to &pt_regs.r17
+ */
+#define SAVE_REST \
+.mem.offset 0,0; st8.spill [r2]=r16,16; \
+.mem.offset 8,0; st8.spill [r3]=r17,16; \
+ ;; \
+.mem.offset 0,0; st8.spill [r2]=r18,16; \
+.mem.offset 8,0; st8.spill [r3]=r19,16; \
+ ;; \
+ mov r16=ar.ccv; /* M-unit */ \
+ movl r18=FPSR_DEFAULT /* L-unit */ \
+ ;; \
+ mov r17=ar.fpsr; /* M-unit */ \
+ mov ar.fpsr=r18; /* M-unit */ \
+ ;; \
+.mem.offset 0,0; st8.spill [r2]=r20,16; \
+.mem.offset 8,0; st8.spill [r3]=r21,16; \
+ mov r18=b0; \
+ ;; \
+.mem.offset 0,0; st8.spill [r2]=r22,16; \
+.mem.offset 8,0; st8.spill [r3]=r23,16; \
+ mov r19=b7; \
+ ;; \
+.mem.offset 0,0; st8.spill [r2]=r24,16; \
+.mem.offset 8,0; st8.spill [r3]=r25,16; \
+ ;; \
+.mem.offset 0,0; st8.spill [r2]=r26,16; \
+.mem.offset 8,0; st8.spill [r3]=r27,16; \
+ ;; \
+.mem.offset 0,0; st8.spill [r2]=r28,16; \
+.mem.offset 8,0; st8.spill [r3]=r29,16; \
+ ;; \
+.mem.offset 0,0; st8.spill [r2]=r30,16; \
+.mem.offset 8,0; st8.spill [r3]=r31,16; \
+ ;; \
+ st8 [r2]=r16,16; /* ar.ccv */ \
+ st8 [r3]=r17,16; /* ar.fpsr */ \
+ ;; \
+ st8 [r2]=r18,16; /* b0 */ \
+ st8 [r3]=r19,16+8; /* b7 */ \
+ ;; \
+ stf.spill [r2]=f6,32; \
+ stf.spill [r3]=f7,32; \
+ ;; \
+ stf.spill [r2]=f8,32; \
+ stf.spill [r3]=f9,32
+
+#ifdef CONFIG_ITANIUM_ASTEP_SPECIFIC
+# define STOPS nop.i 0x0;; nop.i 0x0;; nop.i 0x0;;
+#else
+# define STOPS
+#endif
+
+#define SAVE_MIN_WITH_COVER DO_SAVE_MIN(cover;; mov rCRIFS=cr.ifs,) STOPS
+#define SAVE_MIN_WITH_COVER_R19 DO_SAVE_MIN(cover;; mov rCRIFS=cr.ifs, mov r15=r19) STOPS
+#define SAVE_MIN DO_SAVE_MIN(mov rCRIFS=r0,) STOPS
+
+#ifdef CONFIG_ITANIUM_ASTEP_SPECIFIC
+# define STOPS nop.i 0x0;; nop.i 0x0;; nop.i 0x0;;
+#else
+# define STOPS
+#endif
+
+#define SAVE_MIN_WITH_COVER DO_SAVE_MIN(cover;; mov rCRIFS=cr.ifs,) STOPS
+#define SAVE_MIN_WITH_COVER_R19 DO_SAVE_MIN(cover;; mov rCRIFS=cr.ifs, mov r15=r19) STOPS
+#define SAVE_MIN DO_SAVE_MIN(mov rCRIFS=r0,) STOPS
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
index 18a8e342e..22ed4f569 100644
--- a/arch/ia64/kernel/ptrace.c
+++ b/arch/ia64/kernel/ptrace.c
@@ -23,6 +23,16 @@
#include <asm/uaccess.h>
/*
+ * Bits in the PSR that we allow ptrace() to change:
+ * be, up, ac, mfl, mfh (the user mask; five bits total)
+ * db (debug breakpoint fault; one bit)
+ * id (instruction debug fault disable; one bit)
+ * dd (data debug fault disable; one bit)
+ * ri (restart instruction; two bits)
+ */
+#define CR_IPSR_CHANGE_MASK 0x06a00100003eUL
+
+/*
* Collect the NaT bits for r1-r31 from sw->caller_unat and
* sw->ar_unat and return a NaT bitset where bit i is set iff the NaT
* bit of register i is set.
@@ -352,6 +362,94 @@ ia64_poke (struct pt_regs *regs, struct task_struct *child, unsigned long addr,
}
/*
+ * Synchronize (i.e, write) the RSE backing store living in kernel
+ * space to the VM of the indicated child process.
+ *
+ * If new_bsp is non-zero, the bsp will (effectively) be updated to
+ * the new value upon resumption of the child process. This is
+ * accomplished by setting the loadrs value to zero and the bspstore
+ * value to the new bsp value.
+ *
+ * When new_bsp and force_loadrs_to_zero are both 0, the register
+ * backing store in kernel space is written to user space and the
+ * loadrs and bspstore values are left alone.
+ *
+ * When new_bsp is zero and force_loadrs_to_zero is 1 (non-zero),
+ * loadrs is set to 0, and the bspstore value is set to the old bsp
+ * value. This will cause the stacked registers (r32 and up) to be
+ * obtained entirely from the the child's memory space rather than
+ * from the kernel. (This makes it easier to write code for
+ * modifying the stacked registers in multi-threaded programs.)
+ *
+ * Note: I had originally written this function without the
+ * force_loadrs_to_zero parameter; it was written so that loadrs would
+ * always be set to zero. But I had problems with certain system
+ * calls apparently causing a portion of the RBS to be zeroed. (I
+ * still don't understand why this was happening.) Anyway, it'd
+ * definitely less intrusive to leave loadrs and bspstore alone if
+ * possible.
+ */
+static long
+sync_kernel_register_backing_store (struct task_struct *child,
+ long new_bsp,
+ int force_loadrs_to_zero)
+{
+ unsigned long *krbs, bspstore, bsp, krbs_num_regs, rbs_end, addr, val;
+ long ndirty, ret;
+ struct pt_regs *child_regs;
+ struct switch_stack *child_stack;
+
+ ret = 0;
+ child_regs = ia64_task_regs(child);
+ child_stack = (struct switch_stack *) child_regs - 1;
+
+ krbs = (unsigned long *) child + IA64_RBS_OFFSET/8;
+ ndirty = ia64_rse_num_regs(krbs, krbs + (child_regs->loadrs >> 19));
+ bspstore = child_regs->ar_bspstore;
+ bsp = (long) ia64_rse_skip_regs((long *)bspstore, ndirty);
+ krbs_num_regs = ia64_rse_num_regs(krbs, (unsigned long *) child_stack->ar_bspstore);
+ rbs_end = (long) ia64_rse_skip_regs((long *)bspstore, krbs_num_regs);
+
+ /* Return early if nothing to do */
+ if (bsp == new_bsp)
+ return 0;
+
+ /* Write portion of backing store living on kernel stack to the child's VM. */
+ for (addr = bspstore; addr < rbs_end; addr += 8) {
+ ret = ia64_peek(child_regs, child, addr, &val);
+ if (ret != 0)
+ return ret;
+ if (access_process_vm(child, addr, &val, sizeof(val), 1) != sizeof(val))
+ return -EIO;
+ }
+
+ if (new_bsp != 0) {
+ force_loadrs_to_zero = 1;
+ bsp = new_bsp;
+ }
+
+ if (force_loadrs_to_zero) {
+ child_regs->loadrs = 0;
+ child_regs->ar_bspstore = bsp;
+ }
+
+ return ret;
+}
+
+static void
+sync_thread_rbs (struct task_struct *child, int make_writable)
+{
+ struct task_struct *p;
+ read_lock(&tasklist_lock);
+ for_each_task(p) {
+ if (p->mm == child->mm && p->state != TASK_RUNNING)
+ sync_kernel_register_backing_store(p, 0, make_writable);
+ }
+ read_unlock(&tasklist_lock);
+ child->thread.flags |= IA64_THREAD_KRBS_SYNCED;
+}
+
+/*
* Ensure the state in child->thread.fph is up-to-date.
*/
static void
@@ -375,8 +473,8 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data,
struct switch_stack *child_stack;
struct pt_regs *child_regs;
struct task_struct *child;
- unsigned long flags, *base;
- long ret, regnum;
+ unsigned long flags, regnum, *base;
+ long ret;
lock_kernel();
ret = -EPERM;
@@ -441,6 +539,9 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data,
switch (request) {
case PTRACE_PEEKTEXT:
case PTRACE_PEEKDATA: /* read word at location addr */
+ if (!(child->thread.flags & IA64_THREAD_KRBS_SYNCED)
+ && atomic_read(&child->mm->mm_users) > 1)
+ sync_thread_rbs(child, 0);
ret = ia64_peek(regs, child, addr, &data);
if (ret == 0) {
ret = data;
@@ -450,6 +551,9 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data,
case PTRACE_POKETEXT:
case PTRACE_POKEDATA: /* write the word at location addr */
+ if (!(child->thread.flags & IA64_THREAD_KRBS_SYNCED)
+ && atomic_read(&child->mm->mm_users) > 1)
+ sync_thread_rbs(child, 1);
ret = ia64_poke(regs, child, addr, data);
goto out;
@@ -477,8 +581,35 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data,
bspstore = (unsigned long *) child_regs->ar_bspstore;
ndirty = ia64_rse_num_regs(rbs, rbs + (ret >> 19));
ret = (unsigned long) ia64_rse_skip_regs(bspstore, ndirty);
+
+ /*
+ * If we're in a system call, no ``cover'' was done. So
+ * to make things uniform, we'll add the appropriate
+ * displacement onto bsp if we're in a system call.
+ *
+ * Note: It may be better to leave the system call case
+ * alone and subtract the amount of the cover for the
+ * non-syscall case. That way the reported bsp value
+ * would actually be the correct bsp for the child
+ * process.
+ */
+ if (!(child_regs->cr_ifs & (1UL << 63))) {
+ ret = (unsigned long)
+ ia64_rse_skip_regs((unsigned long *) ret,
+ child_stack->ar_pfs & 0x7f);
+ }
+ } else if (addr == PT_CFM) {
+ /* ret currently contains pt_regs.cr_ifs */
+ if ((ret & (1UL << 63)) == 0)
+ ret = child_stack->ar_pfs;
+ ret &= 0x3fffffffffUL; /* return only the CFM */
}
} else {
+ if (!(child->thread.flags & IA64_THREAD_DBG_VALID)) {
+ child->thread.flags |= IA64_THREAD_DBG_VALID;
+ memset(child->thread.dbr, 0, sizeof child->thread.dbr);
+ memset(child->thread.ibr, 0, sizeof child->thread.ibr);
+ }
if (addr >= PT_IBR) {
regnum = (addr - PT_IBR) >> 3;
base = &child->thread.ibr[0];
@@ -488,7 +619,7 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data,
}
if (regnum >= 8)
goto out;
- data = base[regnum];
+ ret = base[regnum];
}
regs->r8 = 0; /* ensure "ret" is not mistaken as an error code */
goto out;
@@ -503,29 +634,47 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data,
sync_fph(child);
addr += (unsigned long) &child->thread.fph;
*(unsigned long *) addr = data;
- if (ret < 0)
- goto out;
+ } else if (addr == PT_AR_BSPSTORE || addr == PT_CALLER_UNAT
+ || addr == PT_KERNEL_FPSR || addr == PT_K_B0 || addr == PT_K_AR_PFS
+ || (PT_K_AR_UNAT <= addr && addr <= PT_K_PR)) {
+ /*
+ * Don't permit changes to certain registers.
+ *
+ * We don't allow bspstore to be modified because doing
+ * so would mess up any modifications to bsp. (See
+ * sync_kernel_register_backing_store for the details.)
+ */
+ goto out;
+ } else if (addr == PT_AR_BSP) {
+ /* FIXME? Account for lack of ``cover'' in the syscall case */
+ ret = sync_kernel_register_backing_store(child, data, 1);
+ goto out;
+ } else if (addr == PT_CFM) {
+ child_regs = ia64_task_regs(child);
+ child_stack = (struct switch_stack *) child_regs - 1;
+
+ if (child_regs->cr_ifs & (1UL << 63)) {
+ child_regs->cr_ifs = (child_regs->cr_ifs & ~0x3fffffffffUL)
+ | (data & 0x3fffffffffUL);
+ } else {
+ child_stack->ar_pfs = (child_stack->ar_pfs & ~0x3fffffffffUL)
+ | (data & 0x3fffffffffUL);
+ }
} else if (addr < PT_F9+16) {
/* accessing switch_stack or pt_regs */
child_regs = ia64_task_regs(child);
child_stack = (struct switch_stack *) child_regs - 1;
- if (addr == PT_AR_BSP) {
- /* compute the loadrs value based on bsp and bspstore: */
- unsigned long *rbs, *bspstore, ndirty, *kbsp;
-
- bspstore = (unsigned long *) child_regs->ar_bspstore;
- ndirty = ia64_rse_num_regs(bspstore, (unsigned long *) data);
- rbs = (unsigned long *) child + IA64_RBS_OFFSET/8;
- kbsp = ia64_rse_skip_regs(rbs, ndirty);
- data = (kbsp - rbs) << 19;
- }
+ if (addr == PT_CR_IPSR)
+ data = (data & CR_IPSR_CHANGE_MASK)
+ | (child_regs->cr_ipsr & ~CR_IPSR_CHANGE_MASK);
+
*(unsigned long *) ((long) child_stack + addr - PT_CALLER_UNAT) = data;
} else {
if (!(child->thread.flags & IA64_THREAD_DBG_VALID)) {
child->thread.flags |= IA64_THREAD_DBG_VALID;
- memset(current->thread.dbr, 0, sizeof current->thread.dbr);
- memset(current->thread.ibr, 0, sizeof current->thread.ibr);
+ memset(child->thread.dbr, 0, sizeof child->thread.dbr);
+ memset(child->thread.ibr, 0, sizeof child->thread.ibr);
}
if (addr >= PT_IBR) {
@@ -538,7 +687,7 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data,
if (regnum >= 8)
goto out;
if (regnum & 1) {
- /* force breakpoint to be effective a most for user-level: */
+ /* force breakpoint to be effective only for user-level: */
data &= ~(0x7UL << 56);
}
base[regnum] = data;
@@ -546,6 +695,23 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data,
ret = 0;
goto out;
+ case PTRACE_GETSIGINFO:
+ ret = -EIO;
+ if (!access_ok(VERIFY_WRITE, data, sizeof (siginfo_t))
+ || child->thread.siginfo == 0)
+ goto out;
+ copy_to_user((siginfo_t *) data, child->thread.siginfo, sizeof (siginfo_t));
+ ret = 0;
+ goto out;
+ break;
+ case PTRACE_SETSIGINFO:
+ ret = -EIO;
+ if (!access_ok(VERIFY_READ, data, sizeof (siginfo_t))
+ || child->thread.siginfo == 0)
+ goto out;
+ copy_from_user(child->thread.siginfo, (siginfo_t *) data, sizeof (siginfo_t));
+ ret = 0;
+ goto out;
case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
case PTRACE_CONT: /* restart after signal. */
ret = -EIO;
@@ -561,6 +727,9 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data,
ia64_psr(ia64_task_regs(child))->ss = 0;
ia64_psr(ia64_task_regs(child))->tb = 0;
+ /* Turn off flag indicating that the KRBS is sync'd with child's VM: */
+ child->thread.flags &= ~IA64_THREAD_KRBS_SYNCED;
+
wake_up_process(child);
ret = 0;
goto out;
@@ -579,6 +748,9 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data,
ia64_psr(ia64_task_regs(child))->ss = 0;
ia64_psr(ia64_task_regs(child))->tb = 0;
+ /* Turn off flag indicating that the KRBS is sync'd with child's VM: */
+ child->thread.flags &= ~IA64_THREAD_KRBS_SYNCED;
+
wake_up_process(child);
ret = 0;
goto out;
@@ -597,6 +769,9 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data,
}
child->exit_code = data;
+ /* Turn off flag indicating that the KRBS is sync'd with child's VM: */
+ child->thread.flags &= ~IA64_THREAD_KRBS_SYNCED;
+
/* give it a chance to run. */
wake_up_process(child);
ret = 0;
@@ -619,6 +794,9 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data,
ia64_psr(ia64_task_regs(child))->ss = 0;
ia64_psr(ia64_task_regs(child))->tb = 0;
+ /* Turn off flag indicating that the KRBS is sync'd with child's VM: */
+ child->thread.flags &= ~IA64_THREAD_KRBS_SYNCED;
+
wake_up_process(child);
ret = 0;
goto out;
diff --git a/arch/ia64/kernel/sal.c b/arch/ia64/kernel/sal.c
index 8743f6588..f4b8ce9dd 100644
--- a/arch/ia64/kernel/sal.c
+++ b/arch/ia64/kernel/sal.c
@@ -139,7 +139,7 @@ ia64_sal_init (struct ia64_sal_systab *systab)
case IA64_SAL_AP_EXTERNAL_INT:
ap_wakeup_vector = ap->vector;
# ifdef SAL_DEBUG
- printk("SAL: AP wakeup using external interrupt; "
+ printk("SAL: AP wakeup using external interrupt "
"vector 0x%lx\n", ap_wakeup_vector);
# endif
break;
@@ -151,6 +151,36 @@ ia64_sal_init (struct ia64_sal_systab *systab)
break;
}
#endif
+ case SAL_DESC_PLATFORM_FEATURE:
+ {
+ struct ia64_sal_desc_platform_feature *pf = (void *) p;
+ printk("SAL: Platform features ");
+
+ if (pf->feature_mask & (1 << 0))
+ printk("BusLock ");
+
+ if (pf->feature_mask & (1 << 1)) {
+ printk("IRQ_Redirection ");
+#ifdef CONFIG_SMP
+ if (no_int_routing)
+ smp_int_redirect &= ~SMP_IRQ_REDIRECTION;
+ else
+ smp_int_redirect |= SMP_IRQ_REDIRECTION;
+#endif
+ }
+ if (pf->feature_mask & (1 << 2)) {
+ printk("IPI_Redirection ");
+#ifdef CONFIG_SMP
+ if (no_int_routing)
+ smp_int_redirect &= ~SMP_IPI_REDIRECTION;
+ else
+ smp_int_redirect |= SMP_IPI_REDIRECTION;
+#endif
+ }
+ printk("\n");
+ break;
+ }
+
}
p += SAL_DESC_SIZE(*p);
}
diff --git a/arch/ia64/kernel/sal_stub.S b/arch/ia64/kernel/sal_stub.S
index 7ab16bbcd..d73851810 100644
--- a/arch/ia64/kernel/sal_stub.S
+++ b/arch/ia64/kernel/sal_stub.S
@@ -1,17 +1,19 @@
/*
- * gcc currently does not conform to the ia-64 calling convention as far
- * as returning function values are concerned. Instead of returning
- * values up to 32 bytes in size in r8-r11, gcc returns any value
- * bigger than a doubleword via a structure that's allocated by the
- * caller and whose address is passed into the function. Since
- * SAL_PROC returns values according to the calling convention, this
- * stub takes care of copying r8-r11 to the place where gcc expects
- * them.
- *
- * Copyright (C) 1998, 1999 Hewlett-Packard Co
- * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998-2000 Hewlett-Packard Co
+ * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
*/
#ifndef __GCC_MULTIREG_RETVALS__
+ /*
+ * gcc currently does not conform to the ia-64 calling
+ * convention as far as returning function values are
+ * concerned. Instead of returning values up to 32 bytes in
+ * size in r8-r11, gcc returns any value bigger than a
+ * doubleword via a structure that's allocated by the caller
+ * and whose address is passed into the function. Since
+ * SAL_PROC returns values according to the calling
+ * convention, this stub takes care of copying r8-r11 to the
+ * place where gcc expects them.
+ */
.text
.psr abi64
.psr lsb
diff --git a/arch/ia64/kernel/semaphore.c b/arch/ia64/kernel/semaphore.c
index 980fa4329..bc55670bf 100644
--- a/arch/ia64/kernel/semaphore.c
+++ b/arch/ia64/kernel/semaphore.c
@@ -310,7 +310,7 @@ __down_write_failed (struct rw_semaphore *sem, long count)
do {
old_count = sem->count;
count = old_count - RW_LOCK_BIAS;
- } while (cmpxchg(&sem->count, old_count, count) != old_count);
+ } while (cmpxchg_acq(&sem->count, old_count, count) != old_count);
if (count == 0)
return;
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index 58ddb1fb1..80838f990 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -8,10 +8,12 @@
* Copyright (C) 1999 VA Linux Systems
* Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
*
- * 02/04/00 D.Mosberger some more get_cpuinfo fixes...
- * 02/01/00 R.Seth fixed get_cpuinfo for SMP
- * 01/07/99 S.Eranian added the support for command line argument
- * 06/24/99 W.Drummond added boot_cpu_data.
+ * 04/04/00 D.Mosberger renamed cpu_initialized to cpu_online_map
+ * 03/31/00 R.Seth cpu_initialized and current->processor fixes
+ * 02/04/00 D.Mosberger some more get_cpuinfo fixes...
+ * 02/01/00 R.Seth fixed get_cpuinfo for SMP
+ * 01/07/99 S.Eranian added the support for command line argument
+ * 06/24/99 W.Drummond added boot_cpu_data.
*/
#include <linux/config.h>
#include <linux/init.h>
@@ -32,6 +34,7 @@
#include <asm/sal.h>
#include <asm/system.h>
#include <asm/efi.h>
+#include <asm/mca.h>
extern char _end;
@@ -41,10 +44,13 @@ struct cpuinfo_ia64 cpu_data[NR_CPUS];
unsigned long ia64_cycles_per_usec;
struct ia64_boot_param ia64_boot_param;
struct screen_info screen_info;
-unsigned long cpu_initialized = 0;
/* This tells _start which CPU is booting. */
int cpu_now_booting = 0;
+#ifdef CONFIG_SMP
+volatile unsigned long cpu_online_map;
+#endif
+
#define COMMAND_LINE_SIZE 512
char saved_command_line[COMMAND_LINE_SIZE]; /* used in proc filesystem */
@@ -101,7 +107,6 @@ void __init
setup_arch (char **cmdline_p)
{
unsigned long max_pfn, bootmap_start, bootmap_size;
- u64 progress;
/*
* The secondary bootstrap loader passes us the boot
@@ -147,7 +152,10 @@ setup_arch (char **cmdline_p)
printk("args to kernel: %s\n", *cmdline_p);
-#ifndef CONFIG_SMP
+#ifdef CONFIG_SMP
+ bootstrap_processor = hard_smp_processor_id();
+ current->processor = bootstrap_processor;
+#else
cpu_init();
identify_cpu(&cpu_data[0]);
#endif
@@ -168,6 +176,11 @@ setup_arch (char **cmdline_p)
conswitchp = &dummy_con;
# endif
#endif
+
+#ifdef CONFIG_IA64_MCA
+ /* enable IA-64 Machine Check Abort Handling */
+ ia64_mca_init();
+#endif
paging_init();
platform_setup(cmdline_p);
}
@@ -183,8 +196,10 @@ get_cpuinfo (char *buffer)
unsigned long mask;
for (c = cpu_data; c < cpu_data + NR_CPUS; ++c) {
- if (!(cpu_initialized & (1UL << (c - cpu_data))))
+#ifdef CONFIG_SMP
+ if (!(cpu_online_map & (1UL << (c - cpu_data))))
continue;
+#endif
mask = c->features;
@@ -209,7 +224,7 @@ get_cpuinfo (char *buffer)
if (mask)
sprintf(cp, " 0x%lx", mask);
- p += sprintf(buffer,
+ p += sprintf(p,
"CPU# %lu\n"
"\tvendor : %s\n"
"\tfamily : %s\n"
@@ -303,8 +318,6 @@ identify_cpu (struct cpuinfo_ia64 *c)
void
cpu_init (void)
{
- int nr = smp_processor_id();
-
/* Clear the stack memory reserved for pt_regs: */
memset(ia64_task_regs(current), 0, sizeof(struct pt_regs));
@@ -318,11 +331,6 @@ cpu_init (void)
*/
ia64_set_dcr(IA64_DCR_DR | IA64_DCR_DK | IA64_DCR_DX | IA64_DCR_PP);
ia64_set_fpu_owner(0); /* initialize ar.k5 */
-
- if (test_and_set_bit(nr, &cpu_initialized)) {
- printk("CPU#%d already initialized!\n", nr);
- machine_halt();
- }
atomic_inc(&init_mm.mm_count);
current->active_mm = &init_mm;
}
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c
index 19be1f840..a0cca9da7 100644
--- a/arch/ia64/kernel/signal.c
+++ b/arch/ia64/kernel/signal.c
@@ -94,7 +94,7 @@ static long
restore_sigcontext (struct sigcontext *sc, struct pt_regs *pt)
{
struct switch_stack *sw = (struct switch_stack *) pt - 1;
- unsigned long ip, flags, nat, um;
+ unsigned long ip, flags, nat, um, cfm;
long err;
/* restore scratch that always needs gets updated during signal delivery: */
@@ -102,20 +102,24 @@ restore_sigcontext (struct sigcontext *sc, struct pt_regs *pt)
err |= __get_user(nat, &sc->sc_nat);
err |= __get_user(ip, &sc->sc_ip); /* instruction pointer */
- err |= __get_user(pt->ar_fpsr, &sc->sc_ar_fpsr);
- err |= __get_user(pt->ar_pfs, &sc->sc_ar_pfs);
+ err |= __get_user(cfm, &sc->sc_cfm);
err |= __get_user(um, &sc->sc_um); /* user mask */
err |= __get_user(pt->ar_rsc, &sc->sc_ar_rsc);
err |= __get_user(pt->ar_ccv, &sc->sc_ar_ccv);
err |= __get_user(pt->ar_unat, &sc->sc_ar_unat);
+ err |= __get_user(pt->ar_fpsr, &sc->sc_ar_fpsr);
+ err |= __get_user(pt->ar_pfs, &sc->sc_ar_pfs);
err |= __get_user(pt->pr, &sc->sc_pr); /* predicates */
err |= __get_user(pt->b0, &sc->sc_br[0]); /* b0 (rp) */
- err |= __get_user(pt->b6, &sc->sc_br[6]);
+ err |= __get_user(pt->b6, &sc->sc_br[6]); /* b6 */
+ err |= __get_user(pt->b7, &sc->sc_br[7]); /* b7 */
err |= __copy_from_user(&pt->r1, &sc->sc_gr[1], 3*8); /* r1-r3 */
err |= __copy_from_user(&pt->r8, &sc->sc_gr[8], 4*8); /* r8-r11 */
err |= __copy_from_user(&pt->r12, &sc->sc_gr[12], 4*8); /* r12-r15 */
err |= __copy_from_user(&pt->r16, &sc->sc_gr[16], 16*8); /* r16-r31 */
+ pt->cr_ifs = cfm | (1UL << 63);
+
/* establish new instruction pointer: */
pt->cr_iip = ip & ~0x3UL;
ia64_psr(pt)->ri = ip & 0x3;
@@ -240,6 +244,7 @@ setup_sigcontext (struct sigcontext *sc, sigset_t *mask, struct pt_regs *pt)
nat = ia64_get_nat_bits(pt, sw);
err = __put_user(flags, &sc->sc_flags);
+
err |= __put_user(nat, &sc->sc_nat);
err |= PUT_SIGSET(mask, &sc->sc_mask);
err |= __put_user(pt->cr_ipsr & IA64_PSR_UM, &sc->sc_um);
@@ -255,8 +260,8 @@ setup_sigcontext (struct sigcontext *sc, sigset_t *mask, struct pt_regs *pt)
err |= __copy_to_user(&sc->sc_gr[1], &pt->r1, 3*8); /* r1-r3 */
err |= __copy_to_user(&sc->sc_gr[8], &pt->r8, 4*8); /* r8-r11 */
- err |= __copy_to_user(&sc->sc_gr[12], &pt->r12, 4*8); /* r12-r15 */
- err |= __copy_to_user(&sc->sc_gr[16], &pt->r16, 16*8); /* r16-r31 */
+ err |= __copy_to_user(&sc->sc_gr[12], &pt->r12, 4*8); /* r12-r15 */
+ err |= __copy_to_user(&sc->sc_gr[16], &pt->r16, 16*8); /* r16-r31 */
err |= __put_user(pt->cr_iip + ia64_psr(pt)->ri, &sc->sc_ip);
err |= __put_user(pt->r12, &sc->sc_gr[12]); /* r12 */
@@ -415,10 +420,12 @@ ia64_do_signal (sigset_t *oldset, struct pt_regs *pt, long in_syscall)
if ((current->flags & PF_PTRACED) && signr != SIGKILL) {
/* Let the debugger run. */
current->exit_code = signr;
+ current->thread.siginfo = &info;
set_current_state(TASK_STOPPED);
notify_parent(current, SIGCHLD);
schedule();
signr = current->exit_code;
+ current->thread.siginfo = 0;
/* We're back. Did the debugger cancel the sig? */
if (!signr)
diff --git a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c
index ed5d594a6..43d9f2dde 100644
--- a/arch/ia64/kernel/smp.c
+++ b/arch/ia64/kernel/smp.c
@@ -6,6 +6,8 @@
*
* Lots of stuff stolen from arch/alpha/kernel/smp.c
*
+ * 00/03/31 Rohit Seth <rohit.seth@intel.com> Fixes for Bootstrap Processor & cpu_online_map
+ * now gets done here (instead of setup.c)
* 99/10/05 davidm Update to bring it in sync with new command-line processing scheme.
*/
#define __KERNEL_SYSCALLS__
@@ -24,15 +26,6 @@
#include <asm/bitops.h>
#include <asm/current.h>
#include <asm/delay.h>
-
-#ifdef CONFIG_KDB
-#include <linux/kdb.h>
-void smp_kdb_interrupt (struct pt_regs* regs);
-void kdb_global(int cpuid);
-extern unsigned long smp_kdb_wait;
-extern int kdb_new_cpu;
-#endif
-
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/page.h>
@@ -47,25 +40,24 @@ extern int kdb_new_cpu;
extern int cpu_idle(void * unused);
extern void _start(void);
-extern int cpu_now_booting; /* Used by head.S to find idle task */
-extern unsigned long cpu_initialized; /* Bitmap of available cpu's */
-extern struct cpuinfo_ia64 cpu_data[NR_CPUS]; /* Duh... */
+extern int cpu_now_booting; /* Used by head.S to find idle task */
+extern volatile unsigned long cpu_online_map; /* Bitmap of available cpu's */
+extern struct cpuinfo_ia64 cpu_data[NR_CPUS]; /* Duh... */
spinlock_t kernel_flag = SPIN_LOCK_UNLOCKED;
-#ifdef CONFIG_KDB
-unsigned long cpu_online_map = 1;
-#endif
+struct smp_boot_data __initdata smp;
+char __initdata no_int_routing = 0;
+unsigned char smp_int_redirect; /* are INT and IPI redirectable by the chipset? */
volatile int __cpu_number_map[NR_CPUS] = { -1, }; /* SAPIC ID -> Logical ID */
volatile int __cpu_logical_map[NR_CPUS] = { -1, }; /* logical ID -> SAPIC ID */
int smp_num_cpus = 1;
-int bootstrap_processor = -1; /* SAPIC ID of BSP */
-int smp_threads_ready = 0; /* Set when the idlers are all forked */
-unsigned long ipi_base_addr = IPI_DEFAULT_BASE_ADDR; /* Base addr of IPI table */
+int bootstrap_processor = -1; /* SAPIC ID of BSP */
+int smp_threads_ready = 0; /* Set when the idlers are all forked */
cycles_t cacheflush_time = 0;
-unsigned long ap_wakeup_vector = -1; /* External Int to use to wakeup AP's */
-static int max_cpus = -1; /* Command line */
+unsigned long ap_wakeup_vector = -1; /* External Int to use to wakeup AP's */
+static int max_cpus = -1; /* Command line */
static unsigned long ipi_op[NR_CPUS];
struct smp_call_struct {
void (*func) (void *info);
@@ -76,20 +68,13 @@ struct smp_call_struct {
};
static struct smp_call_struct *smp_call_function_data;
-#ifdef CONFIG_KDB
-unsigned long smp_kdb_wait = 0; /* Bitmask of waiters */
-#endif
-
#ifdef CONFIG_ITANIUM_ASTEP_SPECIFIC
extern spinlock_t ivr_read_lock;
#endif
-int use_xtp = 0; /* XXX */
-
#define IPI_RESCHEDULE 0
#define IPI_CALL_FUNC 1
#define IPI_CPU_STOP 2
-#define IPI_KDB_INTERRUPT 4
/*
* Setup routine for controlling SMP activation
@@ -118,13 +103,22 @@ static int __init maxcpus(char *str)
__setup("maxcpus=", maxcpus);
+static int __init
+nointroute(char *str)
+{
+ no_int_routing = 1;
+ return 1;
+}
+
+__setup("nointroute", nointroute);
+
/*
* Yoink this CPU from the runnable list...
*/
void
halt_processor(void)
{
- clear_bit(smp_processor_id(), &cpu_initialized);
+ clear_bit(smp_processor_id(), &cpu_online_map);
max_xtp();
__cli();
for (;;)
@@ -188,12 +182,6 @@ handle_IPI(int irq, void *dev_id, struct pt_regs *regs)
halt_processor();
break;
-#ifdef CONFIG_KDB
- case IPI_KDB_INTERRUPT:
- smp_kdb_interrupt(regs);
- break;
-#endif
-
default:
printk(KERN_CRIT "Unknown IPI on CPU %d: %lu\n", this_cpu, which);
break;
@@ -205,32 +193,6 @@ handle_IPI(int irq, void *dev_id, struct pt_regs *regs)
}
static inline void
-send_IPI(int dest_cpu, unsigned char vector)
-{
- unsigned long ipi_addr;
- unsigned long ipi_data;
-#ifdef CONFIG_ITANIUM_ASTEP_SPECIFIC
- unsigned long flags;
-#endif
-
- ipi_data = vector;
- ipi_addr = ipi_base_addr | ((dest_cpu << 8) << 4); /* 16-bit SAPIC ID's; assume CPU bus 0 */
- mb();
-
-#ifdef CONFIG_ITANIUM_ASTEP_SPECIFIC
- /*
- * Disable IVR reads
- */
- spin_lock_irqsave(&ivr_read_lock, flags);
- writeq(ipi_data, ipi_addr);
- spin_unlock_irqrestore(&ivr_read_lock, flags);
-#else
- writeq(ipi_data, ipi_addr);
-#endif /* CONFIG_ITANIUM_ASTEP_SPECIFIC */
-
-}
-
-static inline void
send_IPI_single(int dest_cpu, int op)
{
@@ -238,7 +200,7 @@ send_IPI_single(int dest_cpu, int op)
return;
ipi_op[dest_cpu] |= (1 << op);
- send_IPI(dest_cpu, IPI_IRQ);
+ ipi_send(dest_cpu, IPI_IRQ, IA64_IPI_DM_INT, 0);
}
static inline void
@@ -452,9 +414,11 @@ start_ap(void)
ia64_clear_ic(flags);
ia64_set_rr( 0, (0x1000 << 8) | (_PAGE_SIZE_1M << 2));
ia64_set_rr(PAGE_OFFSET, (ia64_rid(0, PAGE_OFFSET) << 8) | (_PAGE_SIZE_256M << 2));
+ ia64_srlz_d();
ia64_itr(0x3, 1, PAGE_OFFSET,
pte_val(mk_pte_phys(0, __pgprot(__DIRTY_BITS|_PAGE_PL_0|_PAGE_AR_RWX))),
_PAGE_SIZE_256M);
+ ia64_srlz_i();
flags = (IA64_PSR_IT | IA64_PSR_IC | IA64_PSR_DT | IA64_PSR_RT | IA64_PSR_DFH |
IA64_PSR_BN);
@@ -492,6 +456,10 @@ smp_callin(void)
smp_store_cpu_info(smp_processor_id());
smp_setup_percpu_timer(smp_processor_id());
+ if (test_and_set_bit(smp_processor_id(), &cpu_online_map)) {
+ printk("CPU#%d already initialized!\n", smp_processor_id());
+ machine_halt();
+ }
while (!smp_threads_ready)
mb();
@@ -505,6 +473,9 @@ smp_callin(void)
ia64_set_lrr1(0, 1);
__sti(); /* Interrupts have been off till now. */
+
+ printk("SMP: CPU %d starting idle loop\n", smp_processor_id());
+
cpu_idle(NULL);
}
@@ -565,7 +536,7 @@ smp_boot_one_cpu(int cpuid, int cpunum)
cpu_now_booting = cpunum;
/* Kick the AP in the butt */
- send_IPI(cpuid, ap_wakeup_vector);
+ ipi_send(cpuid, ap_wakeup_vector, IA64_IPI_DM_INT, 0);
ia64_srlz_i();
mb();
@@ -575,24 +546,20 @@ smp_boot_one_cpu(int cpuid, int cpunum)
* is waiting for smp_threads_ready to be 1 and we can move on.
*/
for (timeout = 0; timeout < 100000; timeout++) {
- if (test_bit(cpuid, &cpu_initialized))
+ if (test_bit(cpuid, &cpu_online_map))
goto alive;
- udelay(10);
+ udelay(100);
barrier();
}
printk(KERN_ERR "SMP: Processor %d is stuck.\n", cpuid);
- return -1;
+ return 0;
alive:
/* Remember the AP data */
__cpu_number_map[cpuid] = cpunum;
-#ifdef CONFIG_KDB
- cpu_online_map |= (1<<cpunum);
- printk ("DEBUGGER: cpu_online_map = 0x%08x\n", cpu_online_map);
-#endif
__cpu_logical_map[cpunum] = cpuid;
- return 0;
+ return 1;
}
@@ -607,9 +574,6 @@ smp_boot_cpus(void)
{
int i, cpu_count = 1;
unsigned long bogosum;
- int sapic_id;
- extern int acpi_cpus;
- extern int acpi_apic_map[32];
/* Take care of some initial bookkeeping. */
memset(&__cpu_number_map, -1, sizeof(__cpu_number_map));
@@ -634,6 +598,10 @@ smp_boot_cpus(void)
#endif
smp_setup_percpu_timer(bootstrap_processor);
+ if (test_and_set_bit(bootstrap_processor, &cpu_online_map)) {
+ printk("CPU#%d already initialized!\n", smp_processor_id());
+ machine_halt();
+ }
init_idle();
/* Nothing to do when told not to. */
@@ -642,33 +610,36 @@ smp_boot_cpus(void)
return;
}
- if (acpi_cpus > 1) {
+ if (max_cpus != -1)
+ printk("Limiting CPUs to %d\n", max_cpus);
+
+ if (smp.cpu_count > 1) {
printk(KERN_INFO "SMP: starting up secondaries.\n");
for (i = 0; i < NR_CPUS; i++) {
- if (acpi_apic_map[i] == -1 ||
- acpi_apic_map[i] == bootstrap_processor << 8) /* XXX Fix me Walt */
+ if (smp.cpu_map[i] == -1 ||
+ smp.cpu_map[i] == bootstrap_processor)
continue;
- /*
- * IA64 SAPIC ID's are 16-bits. See asm/smp.h for more info
- */
- sapic_id = acpi_apic_map[i] >> 8;
- if (smp_boot_one_cpu(sapic_id, cpu_count))
+ if (smp_boot_one_cpu(smp.cpu_map[i], cpu_count) == 0)
continue;
cpu_count++; /* Count good CPUs only... */
+ /*
+ * Bail if we've started as many CPUS as we've been told to.
+ */
+ if (cpu_count == max_cpus)
+ break;
}
}
if (cpu_count == 1) {
printk(KERN_ERR "SMP: Bootstrap processor only.\n");
- return;
}
bogosum = 0;
for (i = 0; i < NR_CPUS; i++) {
- if (cpu_initialized & (1L << i))
+ if (cpu_online_map & (1L << i))
bogosum += cpu_data[i].loops_per_sec;
}
@@ -733,45 +704,8 @@ init_smp_config(void)
if (sal_ret < 0) {
printk("SMP: Can't set SAL AP Boot Rendezvous: %s\n", ia64_sal_strerror(sal_ret));
printk(" Forcing UP mode\n");
+ max_cpus = 0;
smp_num_cpus = 1;
}
}
-
-#ifdef CONFIG_KDB
-void smp_kdb_stop (int all, struct pt_regs* regs)
-{
- if (all)
- {
- printk ("Sending IPI to all on CPU %i\n", smp_processor_id ());
- smp_kdb_wait = 0xffffffff;
- clear_bit (smp_processor_id(), &smp_kdb_wait);
- send_IPI_allbutself (IPI_KDB_INTERRUPT);
- }
- else
- {
- printk ("Sending IPI to self on CPU %i\n",
- smp_processor_id ());
- set_bit (smp_processor_id(), &smp_kdb_wait);
- clear_bit (__cpu_logical_map[kdb_new_cpu], &smp_kdb_wait);
- smp_kdb_interrupt (regs);
- }
-}
-
-void smp_kdb_interrupt (struct pt_regs* regs)
-{
- printk ("kdb: IPI on CPU %i with mask 0x%08x\n",
- smp_processor_id (), smp_kdb_wait);
-
- /* All CPUs spin here forever */
- while (test_bit (smp_processor_id(), &smp_kdb_wait));
-
- /* Enter KDB on CPU selected by KDB on the last CPU */
- if (__cpu_logical_map[kdb_new_cpu] == smp_processor_id ())
- {
- kdb (KDB_REASON_SWITCH, 0, regs);
- }
-}
-
-#endif
-
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
new file mode 100644
index 000000000..3550cc390
--- /dev/null
+++ b/arch/ia64/kernel/smpboot.c
@@ -0,0 +1,2 @@
+unsigned long cpu_online_map;
+
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index 133520b84..b88855ce4 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -9,11 +9,12 @@
* Copyright (C) 1999-2000 Walt Drummond <drummond@valinux.com>
*/
#include <linux/config.h>
+
#include <linux/init.h>
-#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/time.h>
+#include <linux/interrupt.h>
#include <asm/delay.h>
#include <asm/efi.h>
@@ -136,6 +137,7 @@ timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
static unsigned long last_time;
static unsigned char count;
int cpu = smp_processor_id();
+ int printed = 0;
/*
* Here we are in the timer irq handler. We have irqs locally
@@ -145,9 +147,14 @@ timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
*/
write_lock(&xtime_lock);
while (1) {
- /* do kernel PC profiling here. */
+ /*
+ * Do kernel PC profiling here. We multiply the
+ * instruction number by four so that we can use a
+ * prof_shift of 2 to get instruction-level instead of
+ * just bundle-level accuracy.
+ */
if (!user_mode(regs))
- do_profile(regs->cr_iip);
+ do_profile(regs->cr_iip + 4*ia64_psr(regs)->ri);
#ifdef CONFIG_SMP
smp_do_timer(regs);
@@ -172,15 +179,18 @@ timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
#if !(defined(CONFIG_IA64_SOFTSDV_HACKS) && defined(CONFIG_SMP))
/*
- * SoftSDV in SMP mode is _slow_, so we do "loose" ticks,
+ * SoftSDV in SMP mode is _slow_, so we do "lose" ticks,
* but it's really OK...
*/
if (count > 0 && jiffies - last_time > 5*HZ)
count = 0;
if (count++ == 0) {
last_time = jiffies;
- printk("Lost clock tick on CPU %d (now=%lx, next=%lx)!!\n",
- cpu, ia64_get_itc(), itm.next[cpu]);
+ if (!printed) {
+ printk("Lost clock tick on CPU %d (now=%lx, next=%lx)!!\n",
+ cpu, ia64_get_itc(), itm.next[cpu]);
+ printed = 1;
+ }
# ifdef CONFIG_IA64_DEBUG_IRQ
printk("last_cli_ip=%lx\n", last_cli_ip);
# endif
@@ -303,8 +313,6 @@ void __init
time_init (void)
{
/* we can't do request_irq() here because the kmalloc() would fail... */
- irq_desc[TIMER_IRQ].status = IRQ_DISABLED;
- irq_desc[TIMER_IRQ].handler = &irq_type_ia64_internal;
setup_irq(TIMER_IRQ, &timer_irqaction);
efi_gettimeofday(&xtime);
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c
index ddb079f13..3a7706a27 100644
--- a/arch/ia64/kernel/traps.c
+++ b/arch/ia64/kernel/traps.c
@@ -32,10 +32,7 @@ register double f30 asm ("f30"); register double f31 asm ("f31");
#include <linux/init.h>
#include <linux/sched.h>
-#ifdef CONFIG_KDB
-# include <linux/kdb.h>
-#endif
-
+#include <asm/ia32.h>
#include <asm/processor.h>
#include <asm/uaccess.h>
@@ -88,13 +85,6 @@ die_if_kernel (char *str, struct pt_regs *regs, long err)
printk("%s[%d]: %s %ld\n", current->comm, current->pid, str, err);
-#ifdef CONFIG_KDB
- while (1) {
- kdb(KDB_REASON_PANIC, 0, regs);
- printk("Cant go anywhere from Panic!\n");
- }
-#endif
-
show_regs(regs);
if (current->thread.flags & IA64_KERNEL_DEATH) {
@@ -440,7 +430,18 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
case 35: /* Taken Branch Trap */
case 36: /* Single Step Trap */
switch (vector) {
- case 29: siginfo.si_code = TRAP_BRKPT; break;
+ case 29:
+ siginfo.si_code = TRAP_HWBKPT;
+#ifdef CONFIG_ITANIUM
+ /*
+ * Erratum 10 (IFA may contain incorrect address) now has
+ * "NoFix" status. There are no plans for fixing this.
+ */
+ if (ia64_psr(regs)->is == 0)
+ ifa = regs->cr_iip;
+#endif
+ siginfo.si_addr = (void *) ifa;
+ break;
case 35: siginfo.si_code = TRAP_BRANCH; break;
case 36: siginfo.si_code = TRAP_TRACE; break;
}
@@ -479,12 +480,18 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
break;
case 45:
- printk("Unexpected IA-32 exception\n");
+#ifdef CONFIG_IA32_SUPPORT
+ if (ia32_exception(regs, isr) == 0)
+ return;
+#endif
+ printk("Unexpected IA-32 exception (Trap 45)\n");
+ printk(" iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx\n", regs->cr_iip, ifa, isr);
force_sig(SIGSEGV, current);
- return;
+ break;
case 46:
- printk("Unexpected IA-32 intercept trap\n");
+ printk("Unexpected IA-32 intercept trap (Trap 46)\n");
+ printk(" iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx\n", regs->cr_iip, ifa, isr);
force_sig(SIGSEGV, current);
return;
diff --git a/arch/ia64/kernel/unaligned.c b/arch/ia64/kernel/unaligned.c
index 014adcf35..35e8cb846 100644
--- a/arch/ia64/kernel/unaligned.c
+++ b/arch/ia64/kernel/unaligned.c
@@ -305,7 +305,7 @@ set_rse_reg(struct pt_regs *regs, unsigned long r1, unsigned long val, int nat)
DPRINT(("rnat @%p = 0x%lx nat=%d rnatval=%lx\n",
addr, rnats, nat, rnats &ia64_rse_slot_num(slot)));
- if ( nat ) {
+ if (nat) {
rnats |= __IA64_UL(1) << ia64_rse_slot_num(slot);
} else {
rnats &= ~(__IA64_UL(1) << ia64_rse_slot_num(slot));
@@ -385,7 +385,8 @@ get_rse_reg(struct pt_regs *regs, unsigned long r1, unsigned long *val, int *nat
ia64_peek(regs, current, (unsigned long)addr, &rnats);
DPRINT(("rnat @%p = 0x%lx\n", addr, rnats));
- if ( nat ) *nat = rnats >> ia64_rse_slot_num(slot) & 0x1;
+ if (nat)
+ *nat = rnats >> ia64_rse_slot_num(slot) & 0x1;
}
@@ -401,7 +402,7 @@ setreg(unsigned long regnum, unsigned long val, int nat, struct pt_regs *regs)
/*
* First takes care of stacked registers
*/
- if ( regnum >= IA64_FIRST_STACKED_GR ) {
+ if (regnum >= IA64_FIRST_STACKED_GR) {
set_rse_reg(regs, regnum, val, nat);
return;
}
@@ -414,7 +415,7 @@ setreg(unsigned long regnum, unsigned long val, int nat, struct pt_regs *regs)
/*
* Now look at registers in [0-31] range and init correct UNAT
*/
- if ( GR_IN_SW(regnum) ) {
+ if (GR_IN_SW(regnum)) {
addr = (unsigned long)sw;
unat = &sw->ar_unat;
} else {
@@ -437,7 +438,7 @@ setreg(unsigned long regnum, unsigned long val, int nat, struct pt_regs *regs)
*/
bitmask = __IA64_UL(1) << (addr >> 3 & 0x3f);
DPRINT(("*0x%lx=0x%lx NaT=%d prev_unat @%p=%lx\n", addr, val, nat, unat, *unat));
- if ( nat ) {
+ if (nat) {
*unat |= bitmask;
} else {
*unat &= ~bitmask;
@@ -465,7 +466,7 @@ setfpreg(unsigned long regnum, struct ia64_fpreg *fpval, struct pt_regs *regs)
* fly to store to the right register.
* For now, we are using the (slow) save/restore way.
*/
- if ( regnum >= IA64_FIRST_ROTATING_FR ) {
+ if (regnum >= IA64_FIRST_ROTATING_FR) {
/*
* force a save of [32-127] to tss
* we use the __() form to avoid fiddling with the dfh bit
@@ -489,7 +490,7 @@ setfpreg(unsigned long regnum, struct ia64_fpreg *fpval, struct pt_regs *regs)
/*
* pt_regs or switch_stack ?
*/
- if ( FR_IN_SW(regnum) ) {
+ if (FR_IN_SW(regnum)) {
addr = (unsigned long)sw;
} else {
addr = (unsigned long)regs;
@@ -542,7 +543,7 @@ getfpreg(unsigned long regnum, struct ia64_fpreg *fpval, struct pt_regs *regs)
* we need to force a save to the tss to get access to it.
* See discussion in setfpreg() for reasons and other ways of doing this.
*/
- if ( regnum >= IA64_FIRST_ROTATING_FR ) {
+ if (regnum >= IA64_FIRST_ROTATING_FR) {
/*
* force a save of [32-127] to tss
@@ -587,7 +588,7 @@ getreg(unsigned long regnum, unsigned long *val, int *nat, struct pt_regs *regs)
struct switch_stack *sw = (struct switch_stack *)regs -1;
unsigned long addr, *unat;
- if ( regnum >= IA64_FIRST_STACKED_GR ) {
+ if (regnum >= IA64_FIRST_STACKED_GR) {
get_rse_reg(regs, regnum, val, nat);
return;
}
@@ -595,7 +596,7 @@ getreg(unsigned long regnum, unsigned long *val, int *nat, struct pt_regs *regs)
/*
* take care of r0 (read-only always evaluate to 0)
*/
- if ( regnum == 0 ) {
+ if (regnum == 0) {
*val = 0;
*nat = 0;
return;
@@ -604,7 +605,7 @@ getreg(unsigned long regnum, unsigned long *val, int *nat, struct pt_regs *regs)
/*
* Now look at registers in [0-31] range and init correct UNAT
*/
- if ( GR_IN_SW(regnum) ) {
+ if (GR_IN_SW(regnum)) {
addr = (unsigned long)sw;
unat = &sw->ar_unat;
} else {
@@ -621,7 +622,8 @@ getreg(unsigned long regnum, unsigned long *val, int *nat, struct pt_regs *regs)
/*
* do it only when requested
*/
- if ( nat ) *nat = (*unat >> (addr >> 3 & 0x3f)) & 0x1UL;
+ if (nat)
+ *nat = (*unat >> (addr >> 3 & 0x3f)) & 0x1UL;
}
static void
@@ -633,7 +635,7 @@ emulate_load_updates(update_t type, load_store_t *ld, struct pt_regs *regs, unsi
* not get to this point in the code but we keep this sanity check,
* just in case.
*/
- if ( ld->x6_op == 1 || ld->x6_op == 3 ) {
+ if (ld->x6_op == 1 || ld->x6_op == 3) {
printk(KERN_ERR __FUNCTION__": register update on speculative load, error\n");
die_if_kernel("unaligned reference on specualtive load with register update\n",
regs, 30);
@@ -644,7 +646,7 @@ emulate_load_updates(update_t type, load_store_t *ld, struct pt_regs *regs, unsi
* at this point, we know that the base register to update is valid i.e.,
* it's not r0
*/
- if ( type == UPD_IMMEDIATE ) {
+ if (type == UPD_IMMEDIATE) {
unsigned long imm;
/*
@@ -670,7 +672,7 @@ emulate_load_updates(update_t type, load_store_t *ld, struct pt_regs *regs, unsi
DPRINT(("ld.x=%d ld.m=%d imm=%ld r3=0x%lx\n", ld->x, ld->m, imm, ifa));
- } else if ( ld->m ) {
+ } else if (ld->m) {
unsigned long r2;
int nat_r2;
@@ -719,7 +721,7 @@ emulate_load_int(unsigned long ifa, load_store_t *ld, struct pt_regs *regs)
*
* Note: the first argument is ignored
*/
- if ( access_ok(VERIFY_READ, (void *)ifa, len) < 0 ) {
+ if (access_ok(VERIFY_READ, (void *)ifa, len) < 0) {
DPRINT(("verify area failed on %lx\n", ifa));
return -1;
}
@@ -737,7 +739,7 @@ emulate_load_int(unsigned long ifa, load_store_t *ld, struct pt_regs *regs)
* invalidate the ALAT entry.
* See comment below for explanation on how we handle ldX.a
*/
- if ( ld->x6_op != 0x2 ) {
+ if (ld->x6_op != 0x2) {
/*
* we rely on the macros in unaligned.h for now i.e.,
* we let the compiler figure out how to read memory gracefully.
@@ -767,9 +769,8 @@ emulate_load_int(unsigned long ifa, load_store_t *ld, struct pt_regs *regs)
/*
* check for updates on any kind of loads
*/
- if ( ld->op == 0x5 || ld->m )
- emulate_load_updates(ld->op == 0x5 ? UPD_IMMEDIATE: UPD_REG,
- ld, regs, ifa);
+ if (ld->op == 0x5 || ld->m)
+ emulate_load_updates(ld->op == 0x5 ? UPD_IMMEDIATE: UPD_REG, ld, regs, ifa);
/*
* handling of various loads (based on EAS2.4):
@@ -882,7 +883,7 @@ emulate_store_int(unsigned long ifa, load_store_t *ld, struct pt_regs *regs)
*
* Note: the first argument is ignored
*/
- if ( access_ok(VERIFY_WRITE, (void *)ifa, len) < 0 ) {
+ if (access_ok(VERIFY_WRITE, (void *)ifa, len) < 0) {
DPRINT(("verify area failed on %lx\n",ifa));
return -1;
}
@@ -926,7 +927,7 @@ emulate_store_int(unsigned long ifa, load_store_t *ld, struct pt_regs *regs)
* ld->r3 can never be r0, because r0 would not generate an
* unaligned access.
*/
- if ( ld->op == 0x5 ) {
+ if (ld->op == 0x5) {
unsigned long imm;
/*
@@ -936,7 +937,7 @@ emulate_store_int(unsigned long ifa, load_store_t *ld, struct pt_regs *regs)
/*
* sign extend (8bits) if m set
*/
- if ( ld->m ) imm |= SIGN_EXT9;
+ if (ld->m) imm |= SIGN_EXT9;
/*
* ifa == r3 (NaT is necessarily cleared)
*/
@@ -955,7 +956,8 @@ emulate_store_int(unsigned long ifa, load_store_t *ld, struct pt_regs *regs)
/*
* stX.rel: use fence instead of release
*/
- if ( ld->x6_op == 0xd ) mb();
+ if (ld->x6_op == 0xd)
+ mb();
return 0;
}
@@ -1033,7 +1035,7 @@ emulate_load_floatpair(unsigned long ifa, load_store_t *ld, struct pt_regs *regs
struct ia64_fpreg fpr_final[2];
unsigned long len = float_fsz[ld->x6_sz];
- if ( access_ok(VERIFY_READ, (void *)ifa, len<<1) < 0 ) {
+ if (access_ok(VERIFY_READ, (void *)ifa, len<<1) < 0) {
DPRINT(("verify area failed on %lx\n", ifa));
return -1;
}
@@ -1055,7 +1057,7 @@ emulate_load_floatpair(unsigned long ifa, load_store_t *ld, struct pt_regs *regs
* ldfpX.a: we don't try to emulate anything but we must
* invalidate the ALAT entry and execute updates, if any.
*/
- if ( ld->x6_op != 0x2 ) {
+ if (ld->x6_op != 0x2) {
/*
* does the unaligned access
*/
@@ -1118,7 +1120,7 @@ emulate_load_floatpair(unsigned long ifa, load_store_t *ld, struct pt_regs *regs
* Check for updates: only immediate updates are available for this
* instruction.
*/
- if ( ld->m ) {
+ if (ld->m) {
/*
* the immediate is implicit given the ldsz of the operation:
@@ -1132,8 +1134,9 @@ emulate_load_floatpair(unsigned long ifa, load_store_t *ld, struct pt_regs *regs
* as long as we don't come here with a ldfpX.s.
* For this reason we keep this sanity check
*/
- if ( ld->x6_op == 1 || ld->x6_op == 3 ) {
- printk(KERN_ERR "%s: register update on speculative load pair, error\n", __FUNCTION__);
+ if (ld->x6_op == 1 || ld->x6_op == 3) {
+ printk(KERN_ERR "%s: register update on speculative load pair, error\n",
+ __FUNCTION__);
}
@@ -1143,7 +1146,7 @@ emulate_load_floatpair(unsigned long ifa, load_store_t *ld, struct pt_regs *regs
/*
* Invalidate ALAT entries, if any, for both registers.
*/
- if ( ld->x6_op == 0x2 ) {
+ if (ld->x6_op == 0x2) {
invala_fr(ld->r1);
invala_fr(ld->imm);
}
@@ -1160,10 +1163,10 @@ emulate_load_float(unsigned long ifa, load_store_t *ld, struct pt_regs *regs)
/*
* check for load pair because our masking scheme is not fine grain enough
- if ( ld->x == 1 ) return emulate_load_floatpair(ifa,ld,regs);
+ if (ld->x == 1) return emulate_load_floatpair(ifa,ld,regs);
*/
- if ( access_ok(VERIFY_READ, (void *)ifa, len) < 0 ) {
+ if (access_ok(VERIFY_READ, (void *)ifa, len) < 0) {
DPRINT(("verify area failed on %lx\n", ifa));
return -1;
}
@@ -1187,7 +1190,7 @@ emulate_load_float(unsigned long ifa, load_store_t *ld, struct pt_regs *regs)
* invalidate the ALAT entry.
* See comments in ldX for descriptions on how the various loads are handled.
*/
- if ( ld->x6_op != 0x2 ) {
+ if (ld->x6_op != 0x2) {
/*
* does the unaligned access
@@ -1243,7 +1246,7 @@ emulate_load_float(unsigned long ifa, load_store_t *ld, struct pt_regs *regs)
/*
* check for updates on any loads
*/
- if ( ld->op == 0x7 || ld->m )
+ if (ld->op == 0x7 || ld->m)
emulate_load_updates(ld->op == 0x7 ? UPD_IMMEDIATE: UPD_REG,
ld, regs, ifa);
@@ -1274,7 +1277,7 @@ emulate_store_float(unsigned long ifa, load_store_t *ld, struct pt_regs *regs)
*
* Note: the first argument is ignored
*/
- if ( access_ok(VERIFY_WRITE, (void *)ifa, len) < 0 ) {
+ if (access_ok(VERIFY_WRITE, (void *)ifa, len) < 0) {
DPRINT(("verify area failed on %lx\n",ifa));
return -1;
}
@@ -1342,7 +1345,7 @@ emulate_store_float(unsigned long ifa, load_store_t *ld, struct pt_regs *regs)
* ld->r3 can never be r0, because r0 would not generate an
* unaligned access.
*/
- if ( ld->op == 0x7 ) {
+ if (ld->op == 0x7) {
unsigned long imm;
/*
@@ -1352,7 +1355,8 @@ emulate_store_float(unsigned long ifa, load_store_t *ld, struct pt_regs *regs)
/*
* sign extend (8bits) if m set
*/
- if ( ld->m ) imm |= SIGN_EXT9;
+ if (ld->m)
+ imm |= SIGN_EXT9;
/*
* ifa == r3 (NaT is necessarily cleared)
*/
@@ -1384,6 +1388,28 @@ ia64_handle_unaligned(unsigned long ifa, struct pt_regs *regs)
load_store_t *insn;
int ret = -1;
+ /*
+ * Unaligned references in the kernel could come from unaligned
+ * arguments to system calls. We fault the user process in
+ * these cases and panic the kernel otherwise (the kernel should
+ * be fixed to not make unaligned accesses).
+ */
+ if (!user_mode(regs)) {
+ const struct exception_table_entry *fix;
+
+ fix = search_exception_table(regs->cr_iip);
+ if (fix) {
+ regs->r8 = -EFAULT;
+ if (fix->skip & 1) {
+ regs->r9 = 0;
+ }
+ regs->cr_iip += ((long) fix->skip) & ~15;
+ regs->cr_ipsr &= ~IA64_PSR_RI; /* clear exception slot number */
+ return;
+ }
+ die_if_kernel("Unaligned reference while in kernel\n", regs, 30);
+ /* NOT_REACHED */
+ }
if (current->thread.flags & IA64_THREAD_UAC_SIGBUS) {
struct siginfo si;
@@ -1539,7 +1565,7 @@ ia64_handle_unaligned(unsigned long ifa, struct pt_regs *regs)
}
DPRINT(("ret=%d\n", ret));
- if ( ret ) {
+ if (ret) {
lock_kernel();
force_sig(SIGSEGV, current);
unlock_kernel();
@@ -1549,7 +1575,8 @@ ia64_handle_unaligned(unsigned long ifa, struct pt_regs *regs)
* because a memory access instruction (M) can never be in the
* last slot of a bundle. But let's keep it for now.
*/
- if ( ipsr->ri == 2 ) regs->cr_iip += 16;
+ if (ipsr->ri == 2)
+ regs->cr_iip += 16;
ipsr->ri = ++ipsr->ri & 3;
}
diff --git a/arch/ia64/lib/clear_user.S b/arch/ia64/lib/clear_user.S
index 0db4a78f8..0b9a453b1 100644
--- a/arch/ia64/lib/clear_user.S
+++ b/arch/ia64/lib/clear_user.S
@@ -210,6 +210,7 @@ long_do_clear:
// if p7 -> coming from st4 or st1 : len3 contains what's left
// We must restore lc/pr even though might not have been used.
.Lexit2:
+ .pred.rel "mutex", p6, p7
(p6) mov len=len2
(p7) mov len=len3
;;
diff --git a/arch/ia64/lib/strlen.S b/arch/ia64/lib/strlen.S
index 3062716b1..22f205656 100644
--- a/arch/ia64/lib/strlen.S
+++ b/arch/ia64/lib/strlen.S
@@ -186,6 +186,7 @@ recover:
;;
cmp.eq p6,p0=8,val1 // val1==8 ?
(p6) br.wtop.dptk.few 2b // loop until p6 == 0
+ ;; // (avoid WAW on p63)
sub ret0=base,orig // distance from base
sub tmp=8,val1
mov pr=saved_pr,0xffffffffffff0000
diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c
index 99cf5048c..02c4c5792 100644
--- a/arch/ia64/mm/fault.c
+++ b/arch/ia64/mm/fault.c
@@ -94,7 +94,7 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
* sure we exit gracefully rather than endlessly redo the
* fault.
*/
- if (!handle_mm_fault(current, vma, address, (isr & IA64_ISR_W) != 0)) {
+ if (!handle_mm_fault(mm, vma, address, (isr & IA64_ISR_W) != 0)) {
/*
* We ran out of memory, or some other thing happened
* to us that made us unable to handle the page fault
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index 3a630ca8c..b3047ce34 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -237,6 +237,7 @@ put_gate_page (struct page *page, unsigned long address)
if (!PageReserved(page))
printk("put_gate_page: gate page at 0x%lx not in reserved memory\n",
page_address(page));
+
pgd = pgd_offset_k(address); /* note: this is NOT pgd_offset()! */
pmd = pmd_alloc(pgd, address);
if (!pmd) {
diff --git a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c
index 568f7a347..acad4e200 100644
--- a/arch/ia64/mm/tlb.c
+++ b/arch/ia64/mm/tlb.c
@@ -138,7 +138,7 @@ flush_tlb_range (struct mm_struct *mm, unsigned long start, unsigned long end)
*/
++nbits;
if (((1UL << nbits) & SUPPORTED_PGBITS) == 0)
- panic("flush_tlb_range: BUG: nbits=%lu\n", nbits);
+ panic("flush_tlb_range: BUG: nbits=%lu\n", nbits);
}
start &= ~((1UL << nbits) - 1);
diff --git a/arch/ia64/tools/Makefile b/arch/ia64/tools/Makefile
index 0491ca943..974634e17 100644
--- a/arch/ia64/tools/Makefile
+++ b/arch/ia64/tools/Makefile
@@ -8,6 +8,8 @@ TARGET = $(TOPDIR)/include/asm-ia64/offsets.h
all:
+mrproper:
+
clean:
rm -f print_offsets.s print_offsets offsets.h
diff --git a/arch/ia64/tools/print_offsets.c b/arch/ia64/tools/print_offsets.c
index f1b298e21..7e5901144 100644
--- a/arch/ia64/tools/print_offsets.c
+++ b/arch/ia64/tools/print_offsets.c
@@ -12,6 +12,8 @@
* file, be sure to verify that the awk procedure still works (see
* prin_offsets.awk).
*/
+#include <linux/config.h>
+
#include <linux/sched.h>
#include <asm-ia64/processor.h>
@@ -50,6 +52,9 @@ tab[] =
{ "IA64_TASK_PROCESSOR_OFFSET", offsetof (struct task_struct, processor) },
{ "IA64_TASK_THREAD_OFFSET", offsetof (struct task_struct, thread) },
{ "IA64_TASK_THREAD_KSP_OFFSET", offsetof (struct task_struct, thread.ksp) },
+#ifdef CONFIG_IA32_SUPPORT
+ { "IA64_TASK_THREAD_SIGMASK_OFFSET",offsetof (struct task_struct, thread.un.sigmask) },
+#endif
{ "IA64_TASK_PID_OFFSET", offsetof (struct task_struct, pid) },
{ "IA64_TASK_MM_OFFSET", offsetof (struct task_struct, mm) },
{ "IA64_PT_REGS_CR_IPSR_OFFSET", offsetof (struct pt_regs, cr_ipsr) },
@@ -63,6 +68,8 @@ tab[] =
{ "IA64_SIGCONTEXT_FLAGS_OFFSET", offsetof (struct sigcontext, sc_flags) },
{ "IA64_SIGCONTEXT_CFM_OFFSET", offsetof (struct sigcontext, sc_cfm) },
{ "IA64_SIGCONTEXT_FR6_OFFSET", offsetof (struct sigcontext, sc_fr[6]) },
+ { "IA64_CLONE_VFORK", CLONE_VFORK },
+ { "IA64_CLONE_VM", CLONE_VM },
};
static const char *tabs = "\t\t\t\t\t\t\t\t\t\t";
diff --git a/arch/ia64/vmlinux.lds.S b/arch/ia64/vmlinux.lds.S
index b095baeb9..08e7f9f9a 100644
--- a/arch/ia64/vmlinux.lds.S
+++ b/arch/ia64/vmlinux.lds.S
@@ -8,7 +8,7 @@ OUTPUT_ARCH(ia64)
ENTRY(_start)
SECTIONS
{
- v = PAGE_OFFSET; /* this symbol is here to make debugging with kdb easier... */
+ v = PAGE_OFFSET; /* this symbol is here to make debugging easier... */
. = KERNEL_START;
@@ -39,21 +39,6 @@ SECTIONS
{ *(__ex_table) }
__stop___ex_table = .;
-#if defined(CONFIG_KDB)
- /* Kernel symbols and strings for kdb */
-# define KDB_MEAN_SYMBOL_SIZE 48
-# define KDB_SPACE (CONFIG_KDB_STBSIZE * KDB_MEAN_SYMBOL_SIZE)
- . = ALIGN(8);
- _skdb = .;
- .kdb : AT(ADDR(.kdb) - PAGE_OFFSET)
- {
- *(kdbsymtab)
- *(kdbstrings)
- }
- _ekdb = .;
- . = _skdb + KDB_SPACE;
-#endif
-
/* Kernel symbol names for modules: */
.kstrtab : AT(ADDR(.kstrtab) - PAGE_OFFSET)
{ *(.kstrtab) }
diff --git a/arch/m68k/mm/fault.c b/arch/m68k/mm/fault.c
index c88c4c167..3eba3d13b 100644
--- a/arch/m68k/mm/fault.c
+++ b/arch/m68k/mm/fault.c
@@ -99,7 +99,7 @@ good_area:
* make sure we exit gracefully rather than endlessly redo
* the fault.
*/
- fault = handle_mm_fault(current, vma, address, write);
+ fault = handle_mm_fault(mm, vma, address, write);
if (fault < 0)
goto out_of_memory;
if (!fault)
diff --git a/arch/mips/baget/vacserial.c b/arch/mips/baget/vacserial.c
index 5090bada6..048e32ed5 100644
--- a/arch/mips/baget/vacserial.c
+++ b/arch/mips/baget/vacserial.c
@@ -2168,7 +2168,7 @@ int rs_read_proc(char *page, char **start, off_t off, int count,
done:
if (off >= len+begin)
return 0;
- *start = page + (begin-off);
+ *start = page + (off-begin);
return ((count < begin+len-off) ? count : begin+len-off);
}
diff --git a/arch/mips/defconfig b/arch/mips/defconfig
index d4570eb4e..ceeaf5015 100644
--- a/arch/mips/defconfig
+++ b/arch/mips/defconfig
@@ -78,6 +78,7 @@ CONFIG_KMOD=y
#
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_LVM is not set
# CONFIG_BLK_DEV_MD is not set
# CONFIG_MD_LINEAR is not set
# CONFIG_MD_STRIPED is not set
diff --git a/arch/mips/defconfig-ip22 b/arch/mips/defconfig-ip22
index d4570eb4e..ceeaf5015 100644
--- a/arch/mips/defconfig-ip22
+++ b/arch/mips/defconfig-ip22
@@ -78,6 +78,7 @@ CONFIG_KMOD=y
#
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_LVM is not set
# CONFIG_BLK_DEV_MD is not set
# CONFIG_MD_LINEAR is not set
# CONFIG_MD_STRIPED is not set
diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c
index 78b41c448..ddf234045 100644
--- a/arch/mips/kernel/irixelf.c
+++ b/arch/mips/kernel/irixelf.c
@@ -717,16 +717,8 @@ static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs)
set_fs(old_fs);
kfree(elf_phdata);
- current->personality = PER_IRIX32;
-
- put_exec_domain(current->exec_domain);
- if (current->binfmt && current->binfmt->module)
- __MOD_DEC_USE_COUNT(current->binfmt->module);
- current->exec_domain = lookup_exec_domain(current->personality);
- current->binfmt = &irix_format;
- if (current->binfmt && current->binfmt->module)
- __MOD_INC_USE_COUNT(current->binfmt->module);
-
+ set_personality(PER_IRIX32);
+ set_binfmt(&irix_format);
compute_creds(bprm);
current->flags &= ~PF_FORKNOEXEC;
bprm->p = (unsigned long)
diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c
index 742cc9b9d..db0229802 100644
--- a/arch/mips/kernel/sysirix.c
+++ b/arch/mips/kernel/sysirix.c
@@ -533,7 +533,7 @@ asmlinkage int irix_brk(unsigned long brk)
int ret;
lock_kernel();
- if (brk < current->mm->end_code) {
+ if (brk < mm->end_code) {
ret = -ENOMEM;
goto out;
}
@@ -549,9 +549,9 @@ asmlinkage int irix_brk(unsigned long brk)
/*
* Always allow shrinking brk
*/
- if (brk <= current->mm->brk) {
+ if (brk <= mm->brk) {
mm->brk = brk;
- do_munmap(newbrk, oldbrk-newbrk);
+ do_munmap(mm, newbrk, oldbrk-newbrk);
ret = 0;
goto out;
}
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index 263f2c919..e8c32219d 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -91,7 +91,7 @@ good_area:
* the fault.
*/
{
- int fault = handle_mm_fault(tsk, vma, address, write);
+ int fault = handle_mm_fault(mm, vma, address, write);
if (fault < 0)
goto out_of_memory;
if (!fault)
diff --git a/arch/mips64/defconfig b/arch/mips64/defconfig
index 410152c15..0b72d42c1 100644
--- a/arch/mips64/defconfig
+++ b/arch/mips64/defconfig
@@ -72,6 +72,7 @@ CONFIG_PCI_NAMES=y
#
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_LVM is not set
# CONFIG_BLK_DEV_MD is not set
# CONFIG_MD_LINEAR is not set
# CONFIG_MD_STRIPED is not set
diff --git a/arch/mips64/defconfig-ip27 b/arch/mips64/defconfig-ip27
index 410152c15..0b72d42c1 100644
--- a/arch/mips64/defconfig-ip27
+++ b/arch/mips64/defconfig-ip27
@@ -72,6 +72,7 @@ CONFIG_PCI_NAMES=y
#
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_LVM is not set
# CONFIG_BLK_DEV_MD is not set
# CONFIG_MD_LINEAR is not set
# CONFIG_MD_STRIPED is not set
diff --git a/arch/mips64/mm/fault.c b/arch/mips64/mm/fault.c
index fc69ab2c6..cb9a0e566 100644
--- a/arch/mips64/mm/fault.c
+++ b/arch/mips64/mm/fault.c
@@ -99,7 +99,7 @@ good_area:
* the fault.
*/
{
- int fault = handle_mm_fault(tsk, vma, address, write);
+ int fault = handle_mm_fault(mm, vma, address, write);
if (fault < 0)
goto out_of_memory;
if (!fault)
diff --git a/arch/ppc/8xx_io/uart.c b/arch/ppc/8xx_io/uart.c
index 575f68a28..f5088b9e4 100644
--- a/arch/ppc/8xx_io/uart.c
+++ b/arch/ppc/8xx_io/uart.c
@@ -2063,7 +2063,7 @@ int rs_8xx_read_proc(char *page, char **start, off_t off, int count,
done:
if (off >= len+begin)
return 0;
- *start = page + (begin-off);
+ *start = page + (off-begin);
return ((count < begin+len-off) ? count : begin+len-off);
}
diff --git a/arch/ppc/defconfig b/arch/ppc/defconfig
index 8717bc055..229768b9b 100644
--- a/arch/ppc/defconfig
+++ b/arch/ppc/defconfig
@@ -184,8 +184,8 @@ CONFIG_BLK_DEV_IDEPCI=y
CONFIG_IDEDMA_PCI_EXPERIMENTAL=y
# CONFIG_IDEDMA_PCI_WIP is not set
# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
-# CONFIG_BLK_DEV_AEC6210 is not set
-# CONFIG_AEC6210_TUNING is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_AEC62XX_TUNING is not set
# CONFIG_BLK_DEV_ALI15X3 is not set
# CONFIG_WDC_ALI15X3 is not set
# CONFIG_BLK_DEV_AMD7409 is not set
diff --git a/arch/ppc/kernel/apus_setup.c b/arch/ppc/kernel/apus_setup.c
index a54efc6fd..b93bd8193 100644
--- a/arch/ppc/kernel/apus_setup.c
+++ b/arch/ppc/kernel/apus_setup.c
@@ -108,18 +108,6 @@ void (*mach_floppy_eject) (void) __apusdata = NULL;
#ifdef CONFIG_HEARTBEAT
void (*mach_heartbeat) (int) __apusdata = NULL;
extern void apus_heartbeat (void);
-static int heartbeat_enabled = 1;
-
-void enable_heartbeat(void)
-{
- heartbeat_enabled = 1;
-}
-
-void disable_heartbeat(void)
-{
- heartbeat_enabled = 0;
- mach_heartbeat(0);
-}
#endif
extern unsigned long amiga_model;
diff --git a/arch/ppc/kernel/chrp_setup.c b/arch/ppc/kernel/chrp_setup.c
index 21abfc84f..3b541c26f 100644
--- a/arch/ppc/kernel/chrp_setup.c
+++ b/arch/ppc/kernel/chrp_setup.c
@@ -422,10 +422,10 @@ void __init chrp_init_IRQ(void)
request_irq(openpic_to_irq(HYDRA_INT_ADB_NMI),
xmon_irq, 0, "NMI", 0);
#endif /* CONFIG_XMON */
-#ifdef __SMP__
+#ifdef CONFIG_SMP
request_irq(openpic_to_irq(OPENPIC_VEC_IPI),
openpic_ipi_action, 0, "IPI0", 0);
-#endif /* __SMP__ */
+#endif /* CONFIG_SMP */
}
void __init
diff --git a/arch/ppc/kernel/gemini_prom.S b/arch/ppc/kernel/gemini_prom.S
index f91e992f4..0904bb0eb 100644
--- a/arch/ppc/kernel/gemini_prom.S
+++ b/arch/ppc/kernel/gemini_prom.S
@@ -10,6 +10,7 @@
#include "ppc_asm.tmpl"
#include "ppc_defs.h"
+#include <linux/config.h>
#include <asm/processor.h>
#include <asm/page.h>
#include <asm/gemini.h>
@@ -25,7 +26,7 @@
_GLOBAL(prom_init)
_GLOBAL(gemini_prom_init)
-#ifdef __SMP__
+#ifdef CONFIG_SMP
/* Since the MMU's on, get stuff in rom space that we'll need */
lis r4,GEMINI_CPUSTAT@h
ori r4,r4,GEMINI_CPUSTAT@l
@@ -74,14 +75,14 @@ prom_no_mmu:
addi r3,r3,1
bdnz 3b
-#ifdef __SMP__
+#ifdef CONFIG_SMP
/* The 750 book (and Mot/IBM support) says that this will "assist" snooping
when in SMP. Not sure yet whether this should stay or leave... */
mfspr r4,HID0
ori r4,r4,HID0_ABE
mtspr HID0,r4
sync
-#endif /* __SMP__ */
+#endif /* CONFIG_SMP */
blr
/* apparently, SMon doesn't pay attention to HID0[SRST]. Disable the MMU and
diff --git a/arch/ppc/kernel/gemini_setup.c b/arch/ppc/kernel/gemini_setup.c
index fcf3a701c..ae9a0bd5c 100644
--- a/arch/ppc/kernel/gemini_setup.c
+++ b/arch/ppc/kernel/gemini_setup.c
@@ -303,7 +303,7 @@ printk("3\n");
/* standard stuff */
cache |= ((1<<reg)<<25);
-#ifdef __SMP__
+#ifdef CONFIG_SMP
/* A couple errata for the 750's (both IBM and Motorola silicon)
note that you can get missed cache lines on MP implementations.
The workaround - if you call it that - is to make the L2
@@ -351,7 +351,7 @@ void __init gemini_init_IRQ(void)
for( i=0; i < NR_IRQS; i++ )
irq_desc[i].handler = &open_pic;
openpic_init(1);
-#ifdef __SMP__
+#ifdef CONFIG_SMP
request_irq(OPENPIC_VEC_IPI, openpic_ipi_action,
0, "IPI0", 0);
request_irq(OPENPIC_VEC_IPI+1, openpic_ipi_action,
@@ -360,7 +360,7 @@ void __init gemini_init_IRQ(void)
0, "IPI2 (stop CPU)", 0);
request_irq(OPENPIC_VEC_IPI+3, openpic_ipi_action,
0, "IPI3 (reschedule)", 0);
-#endif /* __SMP__ */
+#endif /* CONFIG_SMP */
}
#define gemini_rtc_read(x) (readb(GEMINI_RTC+(x)))
diff --git a/arch/ppc/kernel/hashtable.S b/arch/ppc/kernel/hashtable.S
index 5593ebe18..58045be1d 100644
--- a/arch/ppc/kernel/hashtable.S
+++ b/arch/ppc/kernel/hashtable.S
@@ -52,7 +52,7 @@ Hash_msk = (((1 << Hash_bits) - 1) * 64)
.globl hash_page
hash_page:
-#ifdef __SMP__
+#ifdef CONFIG_SMP
SAVE_2GPRS(7,r21)
eieio
lis r2,hash_table_lock@h
@@ -88,7 +88,7 @@ hash_page:
rlwimi r5,r3,12,20,29 /* insert top 10 bits of address */
lwz r5,0(r5) /* get pmd entry */
rlwinm. r5,r5,0,0,19 /* extract address of pte page */
-#ifdef __SMP__
+#ifdef CONFIG_SMP
beq- hash_page_out /* return if no mapping */
#else
/* XXX it seems like the 601 will give a machine fault on the
@@ -102,7 +102,7 @@ hash_page:
lwz r6,0(r2) /* get linux-style pte */
ori r4,r4,1 /* set _PAGE_PRESENT bit in access */
andc. r0,r4,r6 /* check access & ~permission */
-#ifdef __SMP__
+#ifdef CONFIG_SMP
bne- hash_page_out /* return if access not permitted */
#else
bnelr-
@@ -128,7 +128,7 @@ hash_page:
rlwinm r5,r5,7,1,24 /* put VSID in 0x7fffff80 bits */
#endif /* CONFIG_PPC64 */
-#ifndef __SMP__ /* do this later for SMP */
+#ifndef CONFIG_SMP /* do this later for SMP */
#ifdef CONFIG_PPC64
ori r5,r5,1 /* set V (valid) bit */
#else /* CONFIG_PPC64 */
@@ -280,7 +280,7 @@ hash_page_patch_C:
addi r4,r4,1
stw r4,htab_evicts@l(r2)
-#ifndef __SMP__
+#ifndef CONFIG_SMP
/* Store PTE in PTEG */
found_empty:
#ifdef CONFIG_PPC64
@@ -296,7 +296,7 @@ found_slot:
#endif
sync
-#else /* __SMP__ */
+#else /* CONFIG_SMP */
/*
* Between the tlbie above and updating the hash table entry below,
* another CPU could read the hash table entry and put it in its TLB.
@@ -324,7 +324,7 @@ found_slot:
sync
oris r5,r5,0x8000
stw r5,0(r3) /* finally set V bit in PTE */
-#endif /* __SMP__ */
+#endif /* CONFIG_SMP */
/*
* Update the hash table miss count. We only want misses here
@@ -342,7 +342,7 @@ found_slot:
addi r3,r3,1
stw r3,htab_reloads@l(r2)
-#ifdef __SMP__
+#ifdef CONFIG_SMP
lis r2,hash_table_lock@ha
tophys(r2,r2)
li r0,0
@@ -373,7 +373,7 @@ found_slot:
lwz r21,GPR21(r21)
rfi
-#ifdef __SMP__
+#ifdef CONFIG_SMP
hash_page_out:
lis r2,hash_table_lock@ha
tophys(r2,r2)
@@ -386,7 +386,7 @@ hash_page_out:
.globl hash_table_lock
hash_table_lock:
.long 0
-#endif /* __SMP__ */
+#endif /* CONFIG_SMP */
.data
next_slot:
@@ -404,13 +404,13 @@ _GLOBAL(flush_hash_segments)
bne+ 99f
tlbia
sync
-#ifdef __SMP__
+#ifdef CONFIG_SMP
tlbsync
sync
#endif
blr
99:
-#ifdef __SMP__
+#ifdef CONFIG_SMP
/* Note - we had better not do anything which could generate
a hash table miss while we have the hash table locked,
or we'll get a deadlock. -paulus */
@@ -451,7 +451,7 @@ _GLOBAL(flush_hash_segments)
sync
tlbia
sync
-#ifdef __SMP__
+#ifdef CONFIG_SMP
tlbsync
sync
lis r3,hash_table_lock@ha
@@ -473,13 +473,13 @@ _GLOBAL(flush_hash_page)
bne+ 99f
tlbie r4 /* in hw tlb too */
sync
-#ifdef __SMP__
+#ifdef CONFIG_SMP
tlbsync
sync
#endif
blr
99:
-#ifdef __SMP__
+#ifdef CONFIG_SMP
/* Note - we had better not do anything which could generate
a hash table miss while we have the hash table locked,
or we'll get a deadlock. -paulus */
@@ -531,7 +531,7 @@ _GLOBAL(flush_hash_page)
4: sync
tlbie r4 /* in hw tlb too */
sync
-#ifdef __SMP__
+#ifdef CONFIG_SMP
tlbsync
sync
li r0,0
diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S
index dab413c15..218bb4ebb 100644
--- a/arch/ppc/kernel/head.S
+++ b/arch/ppc/kernel/head.S
@@ -189,11 +189,11 @@ __after_prom_start:
#endif /* CONFIG_PPC64 */
4: tophys(r8,r11)
-#ifdef __SMP__
+#ifdef CONFIG_SMP
ori r8,r8,0x12 /* R/W access, M=1 */
#else
ori r8,r8,2 /* R/W access */
-#endif /* __SMP__ */
+#endif /* CONFIG_SMP */
#ifdef CONFIG_APUS
ori r11,r11,BL_8M<<2|0x2 /* set up 8MB BAT registers for 604 */
#else
@@ -782,7 +782,7 @@ load_up_fpu:
* horrendously complex, especially when a task switches from one CPU
* to another. Instead we call giveup_fpu in switch_to.
*/
-#ifndef __SMP__
+#ifndef CONFIG_SMP
lis r6,0 /* get __pa constant */
tophys(r6,r6)
addis r3,r6,last_task_used_math@ha
@@ -801,18 +801,18 @@ load_up_fpu:
andc r4,r4,r20 /* disable FP for previous task */
stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
1:
-#endif /* __SMP__ */
+#endif /* CONFIG_SMP */
/* enable use of FP after return */
ori r23,r23,MSR_FP|MSR_FE0|MSR_FE1
mfspr r5,SPRG3 /* current task's THREAD (phys) */
lfd fr0,THREAD_FPSCR-4(r5)
mtfsf 0xff,fr0
REST_32FPRS(0, r5)
-#ifndef __SMP__
+#ifndef CONFIG_SMP
subi r4,r5,THREAD
sub r4,r4,r6
stw r4,last_task_used_math@l(r3)
-#endif /* __SMP__ */
+#endif /* CONFIG_SMP */
/* restore registers and return */
lwz r3,_CCR(r21)
lwz r4,_LINK(r21)
@@ -868,7 +868,7 @@ load_up_altivec:
* horrendously complex, especially when a task switches from one CPU
* to another. Instead we call giveup_altivec in switch_to.
*/
-#ifndef __SMP__
+#ifndef CONFIG_SMP
#ifndef CONFIG_APUS
lis r6,-KERNELBASE@h
#else
@@ -892,7 +892,7 @@ load_up_altivec:
andc r4,r4,r20 /* disable altivec for previous task */
stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
1:
-#endif /* __SMP__ */
+#endif /* CONFIG_SMP */
/* enable use of AltiVec after return */
oris r23,r23,MSR_VEC@h
mfspr r5,SPRG3 /* current task's THREAD (phys) */
@@ -900,11 +900,11 @@ load_up_altivec:
LVX(vr0,r20,r5)
MTVSCR(vr0)
REST_32VR(0,r20,r5)
-#ifndef __SMP__
+#ifndef CONFIG_SMP
subi r4,r5,THREAD
sub r4,r4,r6
stw r4,last_task_used_altivec@l(r3)
-#endif /* __SMP__ */
+#endif /* CONFIG_SMP */
/* restore registers and return */
lwz r3,_CCR(r21)
lwz r4,_LINK(r21)
@@ -967,11 +967,11 @@ giveup_altivec:
andc r4,r4,r3 /* disable AltiVec for previous task */
stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
1:
-#ifndef __SMP__
+#ifndef CONFIG_SMP
li r5,0
lis r4,last_task_used_altivec@ha
stw r5,last_task_used_altivec@l(r4)
-#endif /* __SMP__ */
+#endif /* CONFIG_SMP */
blr
#endif /* CONFIG_ALTIVEC */
@@ -1002,11 +1002,11 @@ giveup_fpu:
andc r4,r4,r3 /* disable FP for previous task */
stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
1:
-#ifndef __SMP__
+#ifndef CONFIG_SMP
li r5,0
lis r4,last_task_used_math@ha
stw r5,last_task_used_math@l(r4)
-#endif /* __SMP__ */
+#endif /* CONFIG_SMP */
blr
/*
@@ -1432,7 +1432,7 @@ start_here:
SYNC /* Force all PTE updates to finish */
tlbia /* Clear all TLB entries */
sync /* wait for tlbia/tlbie to finish */
-#ifdef __SMP__
+#ifdef CONFIG_SMP
tlbsync /* ... on all CPUs */
sync
#endif
diff --git a/arch/ppc/kernel/head_8xx.S b/arch/ppc/kernel/head_8xx.S
index 94cd67d3b..83f276585 100644
--- a/arch/ppc/kernel/head_8xx.S
+++ b/arch/ppc/kernel/head_8xx.S
@@ -698,7 +698,7 @@ __secondary_hold:
* This is where the main kernel code starts.
*/
start_here:
-#ifdef __SMP__
+#ifdef CONFIG_SMP
/* if we're the second cpu stack and r2 are different
* and we want to not clear the bss -- Cort */
lis r5,first_cpu_booted@h
@@ -715,7 +715,7 @@ start_here:
lwz r2,0(r2)
b 10f
99:
-#endif /* __SMP__ */
+#endif /* CONFIG_SMP */
/* ptr to current */
lis r2,init_task_union@h
ori r2,r2,init_task_union@l
@@ -734,9 +734,9 @@ start_here:
3: stwu r0,4(r8)
bdnz 3b
2:
-#ifdef __SMP__
+#ifdef CONFIG_SMP
10:
-#endif /* __SMP__ */
+#endif /* CONFIG_SMP */
/* stack */
addi r1,r2,TASK_UNION_SIZE
li r0,0
@@ -779,7 +779,7 @@ start_here:
SYNC /* Force all PTE updates to finish */
tlbia /* Clear all TLB entries */
sync /* wait for tlbia/tlbie to finish */
-#ifdef __SMP__
+#ifdef CONFIG_SMP
tlbsync /* ... on all CPUs */
sync
#endif
@@ -794,7 +794,7 @@ start_here:
li r4,MSR_KERNEL
lis r3,start_kernel@h
ori r3,r3,start_kernel@l
-#ifdef __SMP__
+#ifdef CONFIG_SMP
/* the second time through here we go to
* start_secondary(). -- Cort
*/
@@ -807,7 +807,7 @@ start_here:
lis r3,start_secondary@h
ori r3,r3,start_secondary@l
10:
-#endif /* __SMP__ */
+#endif /* CONFIG_SMP */
mtspr SRR0,r3
mtspr SRR1,r4
rfi /* enable MMU and jump to start_kernel */
diff --git a/arch/ppc/kernel/idle.c b/arch/ppc/kernel/idle.c
index 7cf97b873..1d3dfd299 100644
--- a/arch/ppc/kernel/idle.c
+++ b/arch/ppc/kernel/idle.c
@@ -61,7 +61,7 @@ int idled(void)
if ( !current->need_resched && htab_reclaim_on ) htab_reclaim();
if ( !current->need_resched ) power_save();
-#ifdef __SMP__
+#ifdef CONFIG_SMP
if (current->need_resched)
#endif
schedule();
@@ -162,11 +162,11 @@ unsigned long get_zero_page_fast(void)
: "=&r" (tmp), "=&r" (page), "+m" (zero_cache)
: "r" (&zero_quicklist)
: "cc" );
-#ifdef __SMP__
+#ifdef CONFIG_SMP
/* if another cpu beat us above this can happen -- Cort */
if ( page == 0 )
return 0;
-#endif /* __SMP__ */
+#endif /* CONFIG_SMP */
/* we can update zerocount after the fact since it is not
* used for anything but control of a loop which doesn't
* matter since it won't affect anything if it zeros one
@@ -253,7 +253,7 @@ void zero_paged(void)
/* atomically add this page to the list */
asm ( "101:lwarx %0,0,%2\n" /* reserve zero_cache */
" stw %0,0(%3)\n" /* update *pageptr */
-#ifdef __SMP__
+#ifdef CONFIG_SMP
" sync\n" /* let store settle */
#endif
" stwcx. %3,0,%2\n" /* update zero_cache in mem */
diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c
index e4b279032..c0cc492ad 100644
--- a/arch/ppc/kernel/irq.c
+++ b/arch/ppc/kernel/irq.c
@@ -237,13 +237,13 @@ int get_irq_list(char *buf)
if ( !action || !action->handler )
continue;
len += sprintf(buf+len, "%3d: ", i);
-#ifdef __SMP__
+#ifdef CONFIG_SMP
for (j = 0; j < smp_num_cpus; j++)
len += sprintf(buf+len, "%10u ",
kstat.irqs[cpu_logical_map(j)][i]);
#else
len += sprintf(buf+len, "%10u ", kstat_irqs(i));
-#endif /* __SMP__ */
+#endif /* CONFIG_SMP */
if ( irq_desc[i].handler )
len += sprintf(buf+len, " %s ", irq_desc[i].handler->typename );
else
@@ -254,7 +254,7 @@ int get_irq_list(char *buf)
}
len += sprintf(buf+len, "\n");
}
-#ifdef __SMP__
+#ifdef CONFIG_SMP
/* should this be per processor send/receive? */
len += sprintf(buf+len, "IPI: %10lu\n", ipi_count);
#endif
@@ -343,7 +343,7 @@ void __init init_IRQ(void)
ppc_md.init_IRQ();
}
-#ifdef __SMP__
+#ifdef CONFIG_SMP
unsigned char global_irq_holder = NO_PROC_ID;
unsigned volatile int global_irq_lock;
atomic_t global_irq_count;
@@ -611,7 +611,7 @@ void __global_restore_flags(unsigned long flags)
}
}
}
-#endif /* __SMP__ */
+#endif /* CONFIG_SMP */
static struct proc_dir_entry * root_irq_dir;
static struct proc_dir_entry * irq_dir [NR_IRQS];
@@ -733,7 +733,7 @@ static void register_irq_proc (unsigned int irq)
irq_dir[irq] = proc_mkdir(name, root_irq_dir);
/* create /proc/irq/1234/smp_affinity */
- entry = create_proc_entry("smp_affinity", 0700, irq_dir[irq]);
+ entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]);
entry->nlink = 1;
entry->data = (void *)irq;
@@ -754,7 +754,7 @@ void init_irq_proc (void)
root_irq_dir = proc_mkdir("irq", 0);
/* create /proc/irq/prof_cpu_mask */
- entry = create_proc_entry("prof_cpu_mask", 0700, root_irq_dir);
+ entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir);
entry->nlink = 1;
entry->data = (void *)&prof_cpu_mask;
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
index 8444bb4a0..e4fbefbc3 100644
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -142,7 +142,7 @@ _GLOBAL(_tlbia)
sync
tlbia
sync
-#ifdef __SMP__
+#ifdef CONFIG_SMP
tlbsync
sync
#endif
@@ -154,7 +154,7 @@ _GLOBAL(_tlbia)
_GLOBAL(_tlbie)
tlbie r3
sync
-#ifdef __SMP__
+#ifdef CONFIG_SMP
tlbsync
sync
#endif
diff --git a/arch/ppc/kernel/open_pic.c b/arch/ppc/kernel/open_pic.c
index 9438c57ee..a3c6cc4dd 100644
--- a/arch/ppc/kernel/open_pic.c
+++ b/arch/ppc/kernel/open_pic.c
@@ -101,12 +101,12 @@ void no_action(int ir1, void *dev, struct pt_regs *regs)
{
}
-#ifdef __SMP__
+#ifdef CONFIG_SMP
void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs)
{
smp_message_recv(cpl-OPENPIC_VEC_IPI);
}
-#endif /* __SMP__ */
+#endif /* CONFIG_SMP */
#ifdef __i386__
static inline u_int in_le32(volatile u_int *addr)
diff --git a/arch/ppc/kernel/pmac_pic.c b/arch/ppc/kernel/pmac_pic.c
index f2794ae5a..b58d69fc9 100644
--- a/arch/ppc/kernel/pmac_pic.c
+++ b/arch/ppc/kernel/pmac_pic.c
@@ -183,7 +183,7 @@ pmac_get_irq(struct pt_regs *regs)
int irq;
unsigned long bits = 0;
-#ifdef __SMP__
+#ifdef CONFIG_SMP
void pmac_smp_message_recv(void);
/* IPI's are a hack on the powersurge -- Cort */
@@ -197,7 +197,7 @@ pmac_get_irq(struct pt_regs *regs)
pmac_smp_message_recv();
return -2; /* ignore, already handled */
}
-#endif /* __SMP__ */
+#endif /* CONFIG_SMP */
/* Yeah, I know, this could be a separate get_irq function */
if (has_openpic)
diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c
index 87c8d4082..7d4c038ec 100644
--- a/arch/ppc/kernel/ppc_ksyms.c
+++ b/arch/ppc/kernel/ppc_ksyms.c
@@ -35,9 +35,9 @@
#include <asm/dma.h>
#include <asm/machdep.h>
#include <asm/hw_irq.h>
-#ifdef __SMP__
+#ifdef CONFIG_SMP
#include <asm/smplock.h>
-#endif /* __SMP__ */
+#endif /* CONFIG_SMP */
#include "time.h"
/* Tell string.h we don't want memcpy etc. as cpp defines */
@@ -76,9 +76,9 @@ EXPORT_SYMBOL(disable_irq);
EXPORT_SYMBOL(disable_irq_nosync);
EXPORT_SYMBOL(local_irq_count);
EXPORT_SYMBOL(local_bh_count);
-#ifdef __SMP__
+#ifdef CONFIG_SMP
EXPORT_SYMBOL(kernel_flag);
-#endif /* __SMP__ */
+#endif /* CONFIG_SMP */
#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
EXPORT_SYMBOL(isa_io_base);
@@ -189,7 +189,7 @@ EXPORT_SYMBOL(giveup_fpu);
EXPORT_SYMBOL(enable_kernel_fp);
EXPORT_SYMBOL(flush_icache_range);
EXPORT_SYMBOL(xchg_u32);
-#ifdef __SMP__
+#ifdef CONFIG_SMP
EXPORT_SYMBOL(__global_cli);
EXPORT_SYMBOL(__global_sti);
EXPORT_SYMBOL(__global_save_flags);
diff --git a/arch/ppc/kernel/prep_setup.c b/arch/ppc/kernel/prep_setup.c
index 19ae61450..cb1110eca 100644
--- a/arch/ppc/kernel/prep_setup.c
+++ b/arch/ppc/kernel/prep_setup.c
@@ -118,7 +118,7 @@ prep_get_cpuinfo(char *buffer)
extern char *Motherboard_map_name;
int len, i;
-#ifdef __SMP__
+#ifdef CONFIG_SMP
#define CD(X) (cpu_data[n].X)
#else
#define CD(X) (X)
@@ -624,10 +624,10 @@ prep_init_IRQ(void)
for ( i = 0 ; i < 16 ; i++ )
irq_desc[i].handler = &i8259_pic;
i8259_init();
-#ifdef __SMP__
+#ifdef CONFIG_SMP
request_irq(openpic_to_irq(OPENPIC_VEC_SPURIOUS), openpic_ipi_action,
0, "IPI0", 0);
-#endif /* __SMP__ */
+#endif /* CONFIG_SMP */
}
#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
diff --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c
index 5c01d3c72..ce8e039c0 100644
--- a/arch/ppc/kernel/process.c
+++ b/arch/ppc/kernel/process.c
@@ -154,7 +154,7 @@ dump_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs)
void
enable_kernel_altivec(void)
{
-#ifdef __SMP__
+#ifdef CONFIG_SMP
if (current->thread.regs && (current->thread.regs->msr & MSR_VEC))
giveup_altivec(current);
else
@@ -169,14 +169,14 @@ enable_kernel_altivec(void)
void
enable_kernel_fp(void)
{
-#ifdef __SMP__
+#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 /* __SMP__ */
+#endif /* CONFIG_SMP */
}
int
@@ -208,7 +208,7 @@ _switch_to(struct task_struct *prev, struct task_struct *new,
new->comm,new->pid,new->thread.regs->nip,new->processor,
new->fs->root,prev->fs->root);
#endif
-#ifdef __SMP__
+#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.
@@ -236,7 +236,7 @@ _switch_to(struct task_struct *prev, struct task_struct *new,
#endif /* CONFIG_ALTIVEC */
prev->last_processor = prev->processor;
current_set[smp_processor_id()] = new;
-#endif /* __SMP__ */
+#endif /* CONFIG_SMP */
/* Avoid the trap. On smp this this never happens since
* we don't set last_task_used_altivec -- Cort
*/
@@ -265,9 +265,9 @@ void show_regs(struct pt_regs * regs)
printk("\nlast math %p last altivec %p", last_task_used_math,
last_task_used_altivec);
-#ifdef __SMP__
+#ifdef CONFIG_SMP
printk(" CPU: %d last CPU: %d", current->processor,current->last_processor);
-#endif /* __SMP__ */
+#endif /* CONFIG_SMP */
printk("\n");
for (i = 0; i < 32; i++)
@@ -319,7 +319,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
{
unsigned long msr;
struct pt_regs * childregs, *kregs;
-#ifdef __SMP__
+#ifdef CONFIG_SMP
extern void ret_from_smpfork(void);
#else
extern void ret_from_except(void);
@@ -336,7 +336,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
p->thread.ksp = (unsigned long) childregs - STACK_FRAME_OVERHEAD;
p->thread.ksp -= sizeof(struct pt_regs ) + STACK_FRAME_OVERHEAD;
kregs = (struct pt_regs *)(p->thread.ksp + STACK_FRAME_OVERHEAD);
-#ifdef __SMP__
+#ifdef CONFIG_SMP
kregs->nip = (unsigned long)ret_from_smpfork;
#else
kregs->nip = (unsigned long)ret_from_except;
@@ -378,9 +378,9 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
childregs->msr &= ~MSR_VEC;
#endif /* CONFIG_ALTIVEC */
-#ifdef __SMP__
+#ifdef CONFIG_SMP
p->last_processor = NO_PROC_ID;
-#endif /* __SMP__ */
+#endif /* CONFIG_SMP */
return 0;
}
@@ -447,14 +447,14 @@ asmlinkage int sys_clone(int p1, int p2, int p3, int p4, int p5, int p6,
int res;
lock_kernel();
res = do_fork(clone_flags, regs->gpr[1], regs);
-#ifdef __SMP__
+#ifdef CONFIG_SMP
/* When we clone the idle task we keep the same pid but
* the return value of 0 for both causes problems.
* -- Cort
*/
if ((current->pid == 0) && (current == &init_task))
res = 1;
-#endif /* __SMP__ */
+#endif /* CONFIG_SMP */
unlock_kernel();
return res;
}
@@ -466,14 +466,14 @@ asmlinkage int sys_fork(int p1, int p2, int p3, int p4, int p5, int p6,
int res;
res = do_fork(SIGCHLD, regs->gpr[1], regs);
-#ifdef __SMP__
+#ifdef CONFIG_SMP
/* When we clone the idle task we keep the same pid but
* the return value of 0 for both causes problems.
* -- Cort
*/
if ((current->pid == 0) && (current == &init_task))
res = 1;
-#endif /* __SMP__ */
+#endif /* CONFIG_SMP */
return res;
}
diff --git a/arch/ppc/kernel/ptrace.c b/arch/ppc/kernel/ptrace.c
index 3a4e3b797..fe0bfcea2 100644
--- a/arch/ppc/kernel/ptrace.c
+++ b/arch/ppc/kernel/ptrace.c
@@ -100,7 +100,7 @@ static unsigned long get_long(struct task_struct * tsk,
repeat:
pgdir = pgd_offset(vma->vm_mm, addr);
if (pgd_none(*pgdir)) {
- handle_mm_fault(tsk, vma, addr, 0);
+ handle_mm_fault(tsk->mm, vma, addr, 0);
goto repeat;
}
if (pgd_bad(*pgdir)) {
@@ -110,7 +110,7 @@ repeat:
}
pgmiddle = pmd_offset(pgdir,addr);
if (pmd_none(*pgmiddle)) {
- handle_mm_fault(tsk, vma, addr, 0);
+ handle_mm_fault(tsk->mm, vma, addr, 0);
goto repeat;
}
if (pmd_bad(*pgmiddle)) {
@@ -120,7 +120,7 @@ repeat:
}
pgtable = pte_offset(pgmiddle, addr);
if (!pte_present(*pgtable)) {
- handle_mm_fault(tsk, vma, addr, 0);
+ handle_mm_fault(tsk->mm, vma, addr, 0);
goto repeat;
}
page = pte_page(*pgtable);
@@ -151,7 +151,7 @@ static void put_long(struct task_struct * tsk, struct vm_area_struct * vma,
repeat:
pgdir = pgd_offset(vma->vm_mm, addr);
if (!pgd_present(*pgdir)) {
- handle_mm_fault(tsk, vma, addr, 1);
+ handle_mm_fault(tsk->mm, vma, addr, 1);
goto repeat;
}
if (pgd_bad(*pgdir)) {
@@ -161,7 +161,7 @@ repeat:
}
pgmiddle = pmd_offset(pgdir,addr);
if (pmd_none(*pgmiddle)) {
- handle_mm_fault(tsk, vma, addr, 1);
+ handle_mm_fault(tsk->mm, vma, addr, 1);
goto repeat;
}
if (pmd_bad(*pgmiddle)) {
@@ -171,12 +171,12 @@ repeat:
}
pgtable = pte_offset(pgmiddle, addr);
if (!pte_present(*pgtable)) {
- handle_mm_fault(tsk, vma, addr, 1);
+ handle_mm_fault(tsk->mm, vma, addr, 1);
goto repeat;
}
page = pte_page(*pgtable);
if (!pte_write(*pgtable)) {
- handle_mm_fault(tsk, vma, addr, 1);
+ handle_mm_fault(tsk->mm, vma, addr, 1);
goto repeat;
}
/* this is a hack for non-kernel-mapped video buffers and similar */
@@ -198,7 +198,7 @@ repeat:
static int read_long(struct task_struct * tsk, unsigned long addr,
unsigned long * result)
{
- struct vm_area_struct * vma = find_extend_vma(tsk, addr);
+ struct vm_area_struct * vma = find_extend_vma(tsk->mm, addr);
if (!vma)
return -EIO;
@@ -240,7 +240,7 @@ static int read_long(struct task_struct * tsk, unsigned long addr,
static int write_long(struct task_struct * tsk, unsigned long addr,
unsigned long data)
{
- struct vm_area_struct * vma = find_extend_vma(tsk, addr);
+ struct vm_area_struct * vma = find_extend_vma(tsk->mm, addr);
if (!vma)
return -EIO;
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
index 30595e694..2b771ef14 100644
--- a/arch/ppc/kernel/setup.c
+++ b/arch/ppc/kernel/setup.c
@@ -204,7 +204,7 @@ int get_cpuinfo(char *buffer)
unsigned int pvr;
unsigned short maj, min;
-#ifdef __SMP__
+#ifdef CONFIG_SMP
#define CPU_PRESENT(x) (cpu_callin_map[(x)])
#define GET_PVR ((long int)(cpu_data[i].pvr))
#define CD(x) (cpu_data[i].x)
@@ -355,13 +355,13 @@ int get_cpuinfo(char *buffer)
bogosum += CD(loops_per_sec);
}
-#ifdef __SMP__
+#ifdef CONFIG_SMP
if ( i )
len += sprintf(buffer+len, "\n");
len += sprintf(buffer+len,"total bogomips\t: %lu.%02lu\n",
(bogosum+2500)/500000,
(bogosum+2500)/5000 % 100);
-#endif /* __SMP__ */
+#endif /* CONFIG_SMP */
/*
* Ooh's and aah's info about zero'd pages in idle task
diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c
index b695da797..b821249d9 100644
--- a/arch/ppc/kernel/time.c
+++ b/arch/ppc/kernel/time.c
@@ -74,7 +74,7 @@ int timer_interrupt(struct pt_regs * regs)
unsigned long cpu = smp_processor_id();
hardirq_enter(cpu);
-#ifdef __SMP__
+#ifdef CONFIG_SMP
{
unsigned int loops = 100000000;
while (test_bit(0, &global_irq_lock)) {
@@ -93,7 +93,7 @@ int timer_interrupt(struct pt_regs * regs)
}
}
}
-#endif /* __SMP__ */
+#endif /* CONFIG_SMP */
dval = get_dec();
/*
@@ -133,7 +133,7 @@ int timer_interrupt(struct pt_regs * regs)
last_rtc_update = xtime.tv_sec;
}
}
-#ifdef __SMP__
+#ifdef CONFIG_SMP
smp_local_timer_interrupt(regs);
#endif
@@ -155,7 +155,7 @@ void do_gettimeofday(struct timeval *tv)
cli();
*tv = xtime;
/* XXX we don't seem to have the decrementers synced properly yet */
-#ifndef __SMP__
+#ifndef CONFIG_SMP
tv->tv_usec += (decrementer_count - get_dec())
* count_period_num / count_period_den;
if (tv->tv_usec >= 1000000) {
diff --git a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c
index 5fee4463b..562ce0295 100644
--- a/arch/ppc/mm/fault.c
+++ b/arch/ppc/mm/fault.c
@@ -135,7 +135,7 @@ good_area:
if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
goto bad_area;
}
- if (!handle_mm_fault(current, vma, address, is_write))
+ if (!handle_mm_fault(mm, vma, address, is_write))
goto bad_area;
up(&mm->mmap_sem);
/*
diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c
index eaa5924a2..c92abef90 100644
--- a/arch/ppc/mm/init.c
+++ b/arch/ppc/mm/init.c
@@ -87,7 +87,7 @@ unsigned long avail_start;
extern int num_memory;
extern struct mem_info memory[];
extern boot_infos_t *boot_infos;
-#ifndef __SMP__
+#ifndef CONFIG_SMP
struct pgtable_cache_struct quicklists;
#endif
@@ -278,9 +278,9 @@ void show_mem(void)
show_buffers();
printk("%-8s %3s %8s %8s %8s %9s %8s", "Process", "Pid",
"Ctx", "Ctx<<4", "Last Sys", "pc", "task");
-#ifdef __SMP__
+#ifdef CONFIG_SMP
printk(" %3s", "CPU");
-#endif /* __SMP__ */
+#endif /* CONFIG_SMP */
printk("\n");
for_each_task(p)
{
@@ -294,7 +294,7 @@ void show_mem(void)
(ulong)p);
{
int iscur = 0;
-#ifdef __SMP__
+#ifdef CONFIG_SMP
printk("%3d ", p->processor);
if ( (p->processor != NO_PROC_ID) &&
(p == current_set[p->processor]) )
@@ -315,7 +315,7 @@ void show_mem(void)
printk(",");
printk("last math");
}
-#endif /* __SMP__ */
+#endif /* CONFIG_SMP */
printk("\n");
}
}
@@ -495,7 +495,7 @@ local_flush_tlb_all(void)
{
__clear_user(Hash, Hash_size);
_tlbia();
-#ifdef __SMP__
+#ifdef CONFIG_SMP
smp_send_tlb_invalidate(0);
#endif
}
@@ -511,7 +511,7 @@ local_flush_tlb_mm(struct mm_struct *mm)
mm->context = NO_CONTEXT;
if (mm == current->mm)
activate_mm(mm, mm);
-#ifdef __SMP__
+#ifdef CONFIG_SMP
smp_send_tlb_invalidate(0);
#endif
}
@@ -523,7 +523,7 @@ local_flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
flush_hash_page(vma->vm_mm->context, vmaddr);
else
flush_hash_page(0, vmaddr);
-#ifdef __SMP__
+#ifdef CONFIG_SMP
smp_send_tlb_invalidate(0);
#endif
}
@@ -551,7 +551,7 @@ local_flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long e
{
flush_hash_page(mm->context, start);
}
-#ifdef __SMP__
+#ifdef CONFIG_SMP
smp_send_tlb_invalidate(0);
#endif
}
@@ -575,7 +575,7 @@ mmu_context_overflow(void)
}
read_unlock(&tasklist_lock);
flush_hash_segments(0x10, 0xffffff);
-#ifdef __SMP__
+#ifdef CONFIG_SMP
smp_send_tlb_invalidate(0);
#endif
atomic_set(&next_mmu_context, 0);
@@ -663,7 +663,7 @@ void __init setbat(int index, unsigned long virt, unsigned long phys,
}
#define IO_PAGE (_PAGE_NO_CACHE | _PAGE_GUARDED | _PAGE_RW)
-#ifdef __SMP__
+#ifdef CONFIG_SMP
#define RAM_PAGE (_PAGE_RW|_PAGE_COHERENT)
#else
#define RAM_PAGE (_PAGE_RW)
diff --git a/arch/sh/defconfig b/arch/sh/defconfig
index 337e46956..ef15fb104 100644
--- a/arch/sh/defconfig
+++ b/arch/sh/defconfig
@@ -54,12 +54,17 @@ CONFIG_BINFMT_ELF=y
# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_XD is not set
# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
#
# Additional Block Devices
#
# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_STRIPED is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_INITRD=y
@@ -122,6 +127,7 @@ CONFIG_SERIAL_CONSOLE=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
# CONFIG_BFS_FS is not set
@@ -135,17 +141,23 @@ CONFIG_SERIAL_CONSOLE=y
# CONFIG_JOLIET is not set
# CONFIG_MINIX_FS is not set
# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
# CONFIG_HPFS_FS is not set
CONFIG_PROC_FS=y
# CONFIG_DEVFS_FS is not set
# CONFIG_DEVFS_DEBUG is not set
# CONFIG_DEVPTS_FS is not set
# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
# CONFIG_ROMFS_FS is not set
CONFIG_EXT2_FS=y
# CONFIG_SYSV_FS is not set
+# CONFIG_SYSV_FS_WRITE is not set
# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_NCPFS_NLS is not set
#
# Partition Types
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index 8996a13dc..266aafe1f 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -29,7 +29,6 @@ all: kernel.o head.o init_task.o
entry.o: entry.S
head.o: head.S
- $(CC) $(AFLAGS) -traditional -c $*.S -o $*.o
clean:
diff --git a/arch/sh/kernel/entry.S b/arch/sh/kernel/entry.S
index 46ad20f53..00372811c 100644
--- a/arch/sh/kernel/entry.S
+++ b/arch/sh/kernel/entry.S
@@ -14,6 +14,8 @@
#include <linux/linkage.h>
#include <linux/config.h>
+#define COMPAT_OLD_SYSCALL_ABI 1
+
! NOTE:
! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address
! to be jumped is too far, but it causes illegal slot exception.
@@ -31,26 +33,24 @@
* if the order here is changed, it needs to be
* updated in ptrace.c and ptrace.h
*
- * syscall #
- * ssr
- * r0
+ * $r0
* ...
- * r15 = stack pointer
- * gbr
- * mach
- * macl
- * pr
- * spc
+ * $r15 = stack pointer
+ * $spc
+ * $pr
+ * $ssr
+ * $gbr
+ * $mach
+ * $macl
+ * syscall #
*
*/
/*
* These are offsets into the task-struct.
*/
-state = 0
flags = 4
sigpending = 8
-addr_limit = 12
need_resched = 20
PF_TRACESYS = 0x00000020
@@ -75,30 +75,35 @@ MMU_TEA = 0xff00000c ! TLB Exception Address Register
#endif
/* Offsets to the stack */
-SYSCALL_NR = 0
-SR = 4
-R0 = 8
-SP = (8+15*4)
+R0 = 0 /* Return value */
+SP = (15*4)
+SR = (16*4+8)
+SYSCALL_NR = (16*4+6*4)
+
#define k0 r0
#define k1 r1
#define k2 r2
#define k3 r3
+#define k4 r4
-#define kernel_sp r4 /* r4_bank1 */
-#define ksp r4_bank /* r4_bank1 */
+#define current r7 /* r7_bank1 */
+#define g_imask r6 /* r6_bank1 */
+#define k_current r7_bank /* r7_bank1 */
+#define k_g_imask r6_bank /* r6_bank1 */
#define k_ex_code r2_bank /* r2_bank1 */
-/* Kernel mode register usage:
- k0 scratch
- k1 scratch
- k2 scratch (Exception code)
- k3 scratch (Return address)
- k4 Stack base = current+8192
- k5 Global Interrupt Mask (0--15)
- k6 reserved
- k7 reserved
-*/
+/*
+ * Kernel mode register usage:
+ * k0 scratch
+ * k1 scratch
+ * k2 scratch (Exception code)
+ * k3 scratch (Return address)
+ * k4 scratch
+ * k5 reserved
+ * k6 Global Interrupt Mask (0--15 << 4)
+ * k7 CURRENT (pointer to current task)
+ */
!
! TLB Miss / Initial Page write exception handling
@@ -114,42 +119,60 @@ SP = (8+15*4)
! this first version depends *much* on C implementation.
!
-#define RESTORE_FLAGS() \
- mov.l @(SR,$r15), $r0; \
- and #0xf0, $r0; \
- shlr8 $r0; \
- cmp/eq #0x0f, $r0; \
- bt 9f; \
- mov.l __INV_IMASK, $r1; \
- stc $sr, $r0; \
- and $r1, $r0; \
- stc $r5_bank, $r1; \
- or $r1, $r0; \
- ldc $r0, $sr
+#define STI() \
+ mov.l __INV_IMASK, $r11; \
+ stc $sr, $r10; \
+ and $r11, $r10; \
+ stc $k_g_imask, $r11; \
+ or $r11, $r10; \
+ ldc $r10, $sr
.balign 4
-tlb_protection_violation_load:
tlb_miss_load:
- mov #-1, $r0
- mov.l $r0, @$r15 ! syscall nr = -1
mov.l 2f, $r0
mov.l @$r0, $r6
- RESTORE_FLAGS()
-9: mov $r15, $r4
+ STI()
+ mov $r15, $r4
mov.l 1f, $r0
jmp @$r0
mov #0, $r5
.balign 4
-tlb_protection_violation_store:
tlb_miss_store:
+ mov.l 2f, $r0
+ mov.l @$r0, $r6
+ STI()
+ mov $r15, $r4
+ mov.l 1f, $r0
+ jmp @$r0
+ mov #1, $r5
+
+ .balign 4
initial_page_write:
- mov #-1, $r0
- mov.l $r0, @$r15 ! syscall nr = -1
mov.l 2f, $r0
mov.l @$r0, $r6
- RESTORE_FLAGS()
-9: mov $r15, $r4
+ STI()
+ mov $r15, $r4
+ mov.l 1f, $r0
+ jmp @$r0
+ mov #1, $r5
+
+ .balign 4
+tlb_protection_violation_load:
+ mov.l 2f, $r0
+ mov.l @$r0, $r6
+ STI()
+ mov $r15, $r4
+ mov.l 1f, $r0
+ jmp @$r0
+ mov #0, $r5
+
+ .balign 4
+tlb_protection_violation_store:
+ mov.l 2f, $r0
+ mov.l @$r0, $r6
+ STI()
+ mov $r15, $r4
mov.l 1f, $r0
jmp @$r0
mov #1, $r5
@@ -162,8 +185,6 @@ initial_page_write:
.balign 4
/* Unwind the stack and jmp to the debug entry */
debug:
- add #4, $r15 ! skip syscall number
- mov.l @$r15+, $r11 ! SSR
mov.l @$r15+, $r0
mov.l @$r15+, $r1
mov.l @$r15+, $r2
@@ -172,11 +193,10 @@ debug:
mov.l @$r15+, $r5
mov.l @$r15+, $r6
mov.l @$r15+, $r7
- stc $sr, $r14
- mov.l 1f, $r9 ! BL =1, RB=1
- or $r9, $r14
- ldc $r14, $sr ! here, change the register bank
- mov $r11, $k1
+ stc $sr, $r8
+ mov.l 1f, $r9 ! BL =1, RB=1, IMASK=0x0F
+ or $r9, $r8
+ ldc $r8, $sr ! here, change the register bank
mov.l @$r15+, $r8
mov.l @$r15+, $r9
mov.l @$r15+, $r10
@@ -185,11 +205,12 @@ debug:
mov.l @$r15+, $r13
mov.l @$r15+, $r14
mov.l @$r15+, $k0
+ ldc.l @$r15+, $spc
+ lds.l @$r15+, $pr
+ mov.l @$r15+, $k1
ldc.l @$r15+, $gbr
lds.l @$r15+, $mach
lds.l @$r15+, $macl
- lds.l @$r15+, $pr
- ldc.l @$r15+, $spc
mov $k0, $r15
!
mov.l 2f, $k0
@@ -203,11 +224,10 @@ debug:
.balign 4
error:
!
- RESTORE_FLAGS()
-9: mov.l 1f, $r1
- mov #-1, $r0
- jmp @$r1
- mov.l $r0, @$r15 ! syscall nr = -1
+ STI()
+ mov.l 1f, $r0
+ jmp @$r0
+ nop
.balign 4
1: .long SYMBOL_NAME(do_exception_error)
@@ -222,76 +242,106 @@ ENTRY(ret_from_fork)
bra SYMBOL_NAME(ret_from_syscall)
add #4, $r15 ! pop down bogus r0 (see switch_to MACRO)
-!
-! The immediate value of "trapa" indicates the number of arguments
-! placed on the stack.
-!
-! Note that TRA register contains the value = Imm x 4.
-!
+/*
+ * Old syscall interface:
+ *
+ * Syscall #: R0
+ * Arguments #0 to #3: R4--R7
+ * more arguments: On the stack
+ * TRA: (number of arguments on the stack) x 4
+ *
+ * New syscall interface:
+ *
+ * Syscall #: R3
+ * Arguments #0 to #3: R4--R7
+ * Arguments #4 to #6: R0, R1, R2
+ * TRA: (number of arguments + 0x10) x 4
+ *
+ */
+
system_call:
- mov.l 1f, $r2
- mov.l @$r2, $r8
- !
- ! DEBUG DEBUG
- ! mov.l led, $r1
- ! mov $r0, $r2
- ! mov.b $r2, @$r1
+ mov.l 1f, $r9
+ mov.l @$r9, $r8
!
#ifdef CONFIG_DEBUG_KERNEL_WITH_GDB_STUB
- mov #0x20, $r1
- extu.b $r1, $r1
- shll2 $r1
- cmp/hs $r1, $r8
+ mov #0x20, $r9
+ extu.b $r9, $r9
+ shll2 $r9
+ cmp/hs $r9, $r8
bt debug
#endif
!
- mov $r0, $r2
- RESTORE_FLAGS()
-9: mov.l __n_sys, $r1
- cmp/hs $r1, $r2
+ mov #SYSCALL_NR, $r14
+ add $r15, $r14
+ !
+ mov #0x40, $r9
+#ifdef COMPAT_OLD_SYSCALL_ABI
+ cmp/hs $r9, $r8
+ mov $r0, $r10
+ bf/s 0f
+ mov $r0, $r9
+#endif
+ ! New Syscall ABI
+ sub $r9, $r8
+ shlr2 $r8
+ shll8 $r8
+ shll8 $r8
+ mov $r3, $r10
+ or $r8, $r10 ! Encode syscall # and # of arguments
+ !
+ mov $r3, $r9
+ mov #0, $r8
+0:
+ mov.l $r10, @$r14 ! set syscall_nr
+ STI()
+ mov.l __n_sys, $r10
+ cmp/hs $r10, $r9
bt badsys
!
- stc $ksp, $r1
- mov.l __tsk_flags, $r0
- add $r0, $r1 !
- mov.l @$r1, $r0 ! Is it trace?
- tst #PF_TRACESYS, $r0
+#ifdef COMPAT_OLD_SYSCALL_ABI
+ ! Build the stack frame if TRA > 0
+ mov $r8, $r10
+ cmp/pl $r10
+ bf 0f
+ mov.l @(SP,$r15), $r0 ! get original stack
+7: add #-4, $r10
+4: mov.l @($r0,$r10), $r1 ! May cause address error exception..
+ mov.l $r1, @-$r15
+ cmp/pl $r10
+ bt 7b
+#endif
+0: stc $k_current, $r11
+ mov.l @(flags,$r11), $r10 ! Is it trace?
+ mov #PF_TRACESYS, $r11
+ tst $r11, $r10
bt 5f
! Trace system call
- mov #-ENOSYS, $r1
- mov.l $r1, @(R0,$r15)
- mov.l 3f, $r1
- jsr @$r1
+ mov #-ENOSYS, $r11
+ mov.l $r11, @(R0,$r15)
+ mov.l 2f, $r11
+ jsr @$r11
nop
- mova 3f, $r0
+ mov.l __syscall_ret_trace, $r10
bra 6f
- lds $r0, $pr
+ lds $r10, $pr
!
-5: mova syscall_ret, $r0
- lds $r0, $pr
- ! Build the stack frame if TRA > 0
-6: mov $r2, $r3
- mov $r8, $r2
- cmp/pl $r8
- bf 0f
- mov #SP, $r0
- mov.l @($r0,$r15), $r0 ! get original stack
-7: add #-4, $r8
-4: mov.l @($r0,$r8), $r1 ! May cause address error exception..
- mov.l $r1, @-$r15
- cmp/pl $r8
- bt 7b
+5: mov.l __syscall_ret, $r10
+ lds $r10, $pr
!
-0: mov $r3, $r0
- shll2 $r0 ! x4
- mov.l __sct, $r1
- add $r1, $r0
- mov.l @$r0, $r1
- jmp @$r1
- mov $r2, $r8
+6: mov $r9, $r10
+ shll2 $r10 ! x4
+ mov.l __sct, $r11
+ add $r11, $r10
+ mov.l @$r10, $r11
+ jmp @$r11
+ nop
+
! In case of trace
.balign 4
-3: add $r8, $r15 ! pop off the arguments
+3:
+#ifdef COMPAT_OLD_SYSCALL_ABI
+ add $r8, $r15 ! pop off the arguments
+#endif
mov.l $r0, @(R0,$r15) ! save the return value
mov.l 2f, $r1
mova SYMBOL_NAME(ret_from_syscall), $r0
@@ -302,9 +352,12 @@ system_call:
2: .long SYMBOL_NAME(syscall_trace)
__n_sys: .long NR_syscalls
__sct: .long SYMBOL_NAME(sys_call_table)
-__tsk_flags: .long flags-8192 ! offset from stackbase to tsk->flags
-led: .long 0xa8000000 ! For my board -- gN
+__syscall_ret_trace:
+ .long 3b
+__syscall_ret:
+ .long SYMBOL_NAME(syscall_ret)
+#ifdef COMPAT_OLD_SYSCALL_ABI
.section .fixup,"ax"
fixup_syscall_argerr:
rts
@@ -316,6 +369,7 @@ fixup_syscall_argerr:
.balign 4
.long 4b,fixup_syscall_argerr
.previous
+#endif
.balign 4
reschedule:
@@ -327,23 +381,25 @@ reschedule:
1: .long SYMBOL_NAME(schedule)
ENTRY(ret_from_irq)
- mov.l @(SR,$r15), $r0 ! get status register
+ mov #SR, $r0
+ mov.l @($r0,$r15), $r0 ! get status register
shll $r0
shll $r0 ! kernel space?
bt restore_all ! Yes, it's from kernel, go back soon
!
- RESTORE_FLAGS()
-9: bra ret_with_reschedule
+ STI()
+ bra ret_with_reschedule
nop
ENTRY(ret_from_exception)
- mov.l @(SR,$r15), $r0 ! get status register
+ mov #SR, $r0
+ mov.l @($r0,$r15), $r0 ! get status register
shll $r0
shll $r0 ! kernel space?
bt restore_all ! Yes, it's from kernel, go back soon
!
- RESTORE_FLAGS()
-9: bra ret_from_syscall
+ STI()
+ bra ret_from_syscall
nop
.balign 4
__INV_IMASK:
@@ -351,7 +407,9 @@ __INV_IMASK:
.balign 4
syscall_ret:
+#ifdef COMPAT_OLD_SYSCALL_ABI
add $r8, $r15 ! pop off the arguments
+#endif
mov.l $r0, @(R0,$r15) ! save the return value
/* fall through */
@@ -366,9 +424,7 @@ handle_softirq:
jsr @$r0
nop
ret_with_reschedule:
- stc $ksp, $r1
- mov.l __minus8192, $r0
- add $r0, $r1
+ stc $k_current, $r1
mov.l @(need_resched,$r1), $r0
tst #0xff, $r0
bf reschedule
@@ -389,30 +445,14 @@ __softirq_state:
.long SYMBOL_NAME(softirq_state)
__do_softirq:
.long SYMBOL_NAME(do_softirq)
-__minus8192:
- .long -8192 ! offset from stackbase to tsk
.balign 4
restore_all:
#if defined(__SH4__)
- mov.l __fpu_prepare_fd, $r1
- jsr @$r1
+ mov.l __fpu_prepare_fd, $r0
+ jsr @$r0
stc $sr, $r4
#endif
- add #4, $r15 ! Skip syscall number
- mov.l @$r15+, $r11 ! Got SSR into R11
-#if defined(__SH4__)
- mov $r11, $r12
-#endif
- !
- mov.l 1f, $r1
- stc $sr, $r0
- and $r1, $r0 ! Get FD
- mov.l 2f, $r1
- and $r1, $r11
- or $r0, $r11 ! Inherit the FD value of SR
- stc $r5_bank, $r0
- or $r0, $r11 ! Inherit the IMASK value
!
mov.l @$r15+, $r0
mov.l @$r15+, $r1
@@ -422,14 +462,12 @@ restore_all:
mov.l @$r15+, $r5
mov.l @$r15+, $r6
mov.l @$r15+, $r7
- stc $sr, $r14
+ !
+ stc $sr, $r8
mov.l __blrb_flags, $r9 ! BL =1, RB=1
- or $r9, $r14
- ldc $r14, $sr ! here, change the register bank
- mov $r11, $k1
-#if defined(__SH4__)
- mov $r12, $k2
-#endif
+ or $r9, $r8
+ ldc $r8, $sr ! here, change the register bank
+ !
mov.l @$r15+, $r8
mov.l @$r15+, $r9
mov.l @$r15+, $r10
@@ -437,20 +475,33 @@ restore_all:
mov.l @$r15+, $r12
mov.l @$r15+, $r13
mov.l @$r15+, $r14
- mov.l @$r15+, $k0 ! original stack
+ mov.l @$r15+, $k4 ! original stack pointer
+ ldc.l @$r15+, $spc
+ lds.l @$r15+, $pr
+ mov.l @$r15+, $k3 ! original SR
ldc.l @$r15+, $gbr
lds.l @$r15+, $mach
lds.l @$r15+, $macl
- lds.l @$r15+, $pr
- ldc.l @$r15+, $spc
- ldc $k1, $ssr
+ add #4, $r15 ! Skip syscall number
+ !
+ ! Calculate new SR value
+ mov $k3, $k2 ! original SR value
+ mov.l 1f, $k1
+ stc $sr, $k0
+ and $k1, $k0 ! Get current FD-bit
+ mov.l 2f, $k1
+ and $k1, $k2 ! Mask orignal SR value
+ or $k0, $k2 ! Inherit current FD-bit
+ or $g_imask, $k2 ! Inherit the IMASK-bits
+ ldc $k2, $ssr
+ !
#if defined(__SH4__)
- shll $k1
- shll $k1
+ shll $k2
+ shll $k2
bf 9f ! user mode
/* Kernel to kernel transition */
mov.l 1f, $k1
- tst $k1, $k2
+ tst $k1, $k3
bf 9f ! it hadn't FPU
! Kernel to kernel and FPU was used
! There's the case we don't get FPU now
@@ -462,14 +513,15 @@ restore_all:
ldc $k2, $sr ! Grab FPU
mov.l __init_task_flags, $k1
mov.l @$k1, $k2
- mov.l __PF_USEDFPU, $k1
- or $k1, $k2
- mov.l __init_task_flags, $k1
+ mov.l __PF_USEDFPU, $k0
+ or $k0, $k2
mov.l $k2, @$k1 ! Set init_task.flags |= PF_USEDFPU
!
! Restoring FPU...
!
-7: fmov.s @$r15+, $fr0
+7: mov.l 3f, $k1
+ lds $k1, $fpscr
+ fmov.s @$r15+, $fr0
fmov.s @$r15+, $fr1
fmov.s @$r15+, $fr2
fmov.s @$r15+, $fr3
@@ -489,7 +541,7 @@ restore_all:
lds.l @$r15+, $fpul
9:
#endif
- mov $k0, $r15
+ mov $k4, $r15
rte
nop
@@ -505,6 +557,7 @@ __PF_USEDFPU:
#endif
1: .long 0x00008000 ! FD
2: .long 0xffff7f0f ! ~(IMASK+FD)
+3: .long 0x00080000 ! SZ=0, PR=1
! Exception Vector Base
!
@@ -569,6 +622,9 @@ handle_exception:
! /* Currently it's not the case for GCC (only udivsi3_i4, divsi3_i4) */
sts.l $fpul, @-$r15
sts.l $fpscr, @-$r15
+ mov.l 6f, $k1
+ lds $k1, $fpscr
+ mov.l 3f, $k1
fmov.s $fr15, @-$r15
fmov.s $fr14, @-$r15
fmov.s $fr13, @-$r15
@@ -584,40 +640,47 @@ handle_exception:
fmov.s $fr3, @-$r15
fmov.s $fr2, @-$r15
fmov.s $fr1, @-$r15
- fmov.s $fr0, @-$r15
bra 9f
- mov.l 3f, $k1
+ fmov.s $fr0, @-$r15
#else
mov.l 3f, $k1
bt/s 9f ! it's from kernel to kernel transition
mov $r15, $k0 ! save original stack to k0 anyway
#endif
8: /* User space to kernel */
- mov $kernel_sp, $r15 ! change to kernel stack
- mov.l 4f, $k1 ! let kernel release FPU
-9: stc.l $spc, @-$r15
- sts.l $pr, @-$r15
+ mov #0x20, $k1
+ shll8 $k1 ! $k1 <= 8192
+ add $current, $k1
+ mov $k1, $r15 ! change to kernel stack
!
- lds $k3, $pr ! Set the return address to pr
+ mov.l 4f, $k1 ! let kernel release FPU
+9: mov #-1, $k4
+ mov.l $k4, @-$r15 ! syscall_nr (default: -1)
!
sts.l $macl, @-$r15
sts.l $mach, @-$r15
stc.l $gbr, @-$r15
- mov.l $k0, @-$r15 ! save orignal stack
- mov.l $r14, @-$r15
+ stc.l $ssr, @-$r15
+ sts.l $pr, @-$r15
+ stc.l $spc, @-$r15
!
- stc $sr, $r14 ! Back to normal register bank, and
- or $k1, $r14 ! Block all interrupts, may release FPU
- mov.l 5f, $k1
- and $k1, $r14 ! ...
- ldc $r14, $sr ! ...changed here.
+ lds $k3, $pr ! Set the return address to pr
!
+ mov.l $k0, @-$r15 ! save orignal stack
+ mov.l $r14, @-$r15
mov.l $r13, @-$r15
mov.l $r12, @-$r15
mov.l $r11, @-$r15
mov.l $r10, @-$r15
mov.l $r9, @-$r15
mov.l $r8, @-$r15
+ !
+ stc $sr, $r8 ! Back to normal register bank, and
+ or $k1, $r8 ! Block all interrupts, may release FPU
+ mov.l 5f, $k1
+ and $k1, $r8 ! ...
+ ldc $r8, $sr ! ...changed here.
+ !
mov.l $r7, @-$r15
mov.l $r6, @-$r15
mov.l $r5, @-$r15
@@ -626,23 +689,22 @@ handle_exception:
mov.l $r2, @-$r15
mov.l $r1, @-$r15
mov.l $r0, @-$r15
- stc.l $ssr, @-$r15
- mov.l $r0, @-$r15 ! push $r0 again (for syscall number)
- ! Then, dispatch to the handler, according to the excepiton code.
- stc $k_ex_code, $r1
- shlr2 $r1
- shlr $r1
- mov.l 1f, $r0
- add $r1, $r0
- mov.l @$r0, $r0
- jmp @$r0
- mov.l @$r15, $r0 ! recovering $r0..
+ ! Then, dispatch to the handler, according to the exception code.
+ stc $k_ex_code, $r8
+ shlr2 $r8
+ shlr $r8
+ mov.l 1f, $r9
+ add $r8, $r9
+ mov.l @$r9, $r9
+ jmp @$r9
+ nop
.balign 4
1: .long SYMBOL_NAME(exception_handling_table)
2: .long 0x00008000 ! FD=1
3: .long 0x000000f0 ! FD=0, IMASK=15
4: .long 0x000080f0 ! FD=1, IMASK=15
5: .long 0xcfffffff ! RB=0, BL=0
+6: .long 0x00080000 ! SZ=0, PR=1
none:
rts
diff --git a/arch/sh/kernel/fpu.c b/arch/sh/kernel/fpu.c
index 5301a1333..cbeb60d31 100644
--- a/arch/sh/kernel/fpu.c
+++ b/arch/sh/kernel/fpu.c
@@ -23,6 +23,7 @@ save_fpu(struct task_struct *tsk)
{
asm volatile("sts.l $fpul, @-%0\n\t"
"sts.l $fpscr, @-%0\n\t"
+ "lds %1, $fpscr\n\t"
"frchg\n\t"
"fmov.s $fr15, @-%0\n\t"
"fmov.s $fr14, @-%0\n\t"
@@ -58,7 +59,8 @@ save_fpu(struct task_struct *tsk)
"fmov.s $fr1, @-%0\n\t"
"fmov.s $fr0, @-%0"
: /* no output */
- : "r" ((char *)(&tsk->thread.fpu.hard.status))
+ : "r" ((char *)(&tsk->thread.fpu.hard.status)),
+ "r" (FPSCR_INIT)
: "memory");
tsk->flags &= ~PF_USEDFPU;
@@ -68,7 +70,8 @@ save_fpu(struct task_struct *tsk)
static void
restore_fpu(struct task_struct *tsk)
{
- asm volatile("fmov.s @%0+, $fr0\n\t"
+ asm volatile("lds %1, $fpscr\n\t"
+ "fmov.s @%0+, $fr0\n\t"
"fmov.s @%0+, $fr1\n\t"
"fmov.s @%0+, $fr2\n\t"
"fmov.s @%0+, $fr3\n\t"
@@ -105,7 +108,7 @@ restore_fpu(struct task_struct *tsk)
"lds.l @%0+, $fpscr\n\t"
"lds.l @%0+, $fpul\n\t"
: /* no output */
- : "r" (&tsk->thread.fpu)
+ : "r" (&tsk->thread.fpu), "r" (FPSCR_INIT)
: "memory");
}
@@ -163,7 +166,6 @@ do_fpu_error(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long
{
struct task_struct *tsk = current;
- regs.syscall_nr = -1;
regs.pc += 2;
grab_fpu();
@@ -179,15 +181,34 @@ do_fpu_state_restore(unsigned long r4, unsigned long r5, unsigned long r6,
{
struct task_struct *tsk = current;
- regs.syscall_nr = -1;
-
if (!user_mode(&regs)) {
if (tsk != &init_task) {
unlazy_fpu(tsk);
}
tsk = &init_task;
- if (tsk->flags & PF_USEDFPU)
- BUG();
+ if (tsk->flags & PF_USEDFPU) {
+ /*
+ * This weird situation can be occurred.
+ *
+ * There's race condition in __cli:
+ *
+ * (1) $SR --> register
+ * (2) Set IMASK of register
+ * (3) $SR <-- register
+ *
+ * Between (1) and (2), or (2) and (3) getting
+ * interrupt, and interrupt handler (or
+ * softirq) may use FPU.
+ *
+ * Then, SR.FD is overwritten by (3).
+ *
+ * This results init_task.PF_USEDFPU is on,
+ * with SR.FD == 1.
+ *
+ */
+ release_fpu();
+ return;
+ }
}
grab_fpu();
@@ -216,8 +237,8 @@ fpu_prepare_fd(unsigned long sr, unsigned long r5, unsigned long r6,
grab_fpu();
else {
if (!(sr & SR_FD)) {
- release_fpu();
BUG();
+ release_fpu();
}
}
return;
@@ -228,16 +249,20 @@ fpu_prepare_fd(unsigned long sr, unsigned long r5, unsigned long r6,
grab_fpu();
else {
if (init_task.flags & PF_USEDFPU) {
- init_task.flags &= ~PF_USEDFPU;
- BUG();
+ /*
+ * This weird situation can be occurred.
+ * See the comment in do_fpu_state_restore.
+ */
+ grab_fpu();
+ save_fpu(&init_task);
}
}
} else {
if (init_task.flags & PF_USEDFPU)
save_fpu(&init_task);
else {
- release_fpu();
BUG();
+ release_fpu();
}
}
}
diff --git a/arch/sh/kernel/head.S b/arch/sh/kernel/head.S
index ae406d22d..db3e8b0a3 100644
--- a/arch/sh/kernel/head.S
+++ b/arch/sh/kernel/head.S
@@ -41,12 +41,21 @@ ENTRY(_stext)
ldc $r0, $sr
! Initialize global interrupt mask
mov #0, $r0
- ldc $r0, $r5_bank
+ ldc $r0, $r6_bank
!
mov.l 2f, $r0
mov $r0, $r15 ! Set initial r15 (stack pointer)
- ldc $r0, $r4_bank ! and stack base
+ mov #0x20, $r1 !
+ shll8 $r1 ! $r1 = 8192
+ sub $r1, $r0 !
+ ldc $r0, $r7_bank ! ... and init_task
!
+#if defined(__SH4__)
+ ! Initialize fpu
+ mov.l 7f, $r0
+ jsr @$r0
+ nop
+#endif
! Enable cache
mov.l 6f, $r0
jsr @$r0
@@ -71,3 +80,6 @@ ENTRY(_stext)
4: .long SYMBOL_NAME(_end)
5: .long SYMBOL_NAME(start_kernel)
6: .long SYMBOL_NAME(cache_init)
+#if defined(__SH4__)
+7: .long SYMBOL_NAME(fpu_init)
+#endif
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
index af03ef46d..c989796d7 100644
--- a/arch/sh/kernel/irq.c
+++ b/arch/sh/kernel/irq.c
@@ -235,8 +235,6 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
struct irqaction * action;
unsigned int status;
- regs.syscall_nr = -1; /* It's not system call */
-
/* Get IRQ number */
asm volatile("stc $r2_bank, %0\n\t"
"shlr2 %0\n\t"
diff --git a/arch/sh/kernel/irq_imask.c b/arch/sh/kernel/irq_imask.c
index 380acf405..7237ba3b5 100644
--- a/arch/sh/kernel/irq_imask.c
+++ b/arch/sh/kernel/irq_imask.c
@@ -43,7 +43,7 @@ static unsigned int startup_imask_irq(unsigned int irq)
}
static struct hw_interrupt_type imask_irq_type = {
- "Interrupt using IMASK of SR register",
+ "SR.IMASK",
startup_imask_irq,
shutdown_imask_irq,
enable_imask_irq,
@@ -56,13 +56,13 @@ void static inline set_interrupt_registers(int ip)
{
unsigned long __dummy;
- asm volatile("ldc %2, $r5_bank\n\t"
+ asm volatile("ldc %2, $r6_bank\n\t"
"stc $sr, %0\n\t"
"and #0xf0, %0\n\t"
- "shlr8 %0\n\t"
- "cmp/eq #0x0f, %0\n\t"
- "bt 1f ! CLI-ed\n\t"
- "stc $sr, %0\n\t"
+ "shlr2 %0\n\t"
+ "cmp/eq #0x3c, %0\n\t"
+ "bt/s 1f ! CLI-ed\n\t"
+ " stc $sr, %0\n\t"
"and %1, %0\n\t"
"or %2, %0\n\t"
"ldc %0, $sr\n"
diff --git a/arch/sh/kernel/irq_onchip.c b/arch/sh/kernel/irq_onchip.c
index 10c48fd38..36dce33fb 100644
--- a/arch/sh/kernel/irq_onchip.c
+++ b/arch/sh/kernel/irq_onchip.c
@@ -61,7 +61,7 @@ static unsigned int startup_onChip_irq(unsigned int irq)
}
static struct hw_interrupt_type onChip_irq_type = {
- "On-Chip Supporting Module",
+ "On-Chip-IPR",
startup_onChip_irq,
shutdown_onChip_irq,
enable_onChip_irq,
@@ -193,7 +193,7 @@ static unsigned int startup_onChip2_irq(unsigned int irq)
}
static struct hw_interrupt_type onChip2_irq_type = {
- "SH7709 Extended On-Chip Supporting Module",
+ "Extended-IPR",
startup_onChip2_irq,
shutdown_onChip2_irq,
enable_onChip2_irq,
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
index 97cd1fe0c..2d0f5e18a 100644
--- a/arch/sh/kernel/process.c
+++ b/arch/sh/kernel/process.c
@@ -136,20 +136,20 @@ void free_task_struct(struct task_struct *p)
*/
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
{ /* Don't use this in BL=1(cli). Or else, CPU resets! */
- register unsigned long __sc0 __asm__ ("$r0") = __NR_clone;
+ register unsigned long __sc0 __asm__ ("$r3") = __NR_clone;
register unsigned long __sc4 __asm__ ("$r4") = (long) flags | CLONE_VM;
register unsigned long __sc5 __asm__ ("$r5") = 0;
register unsigned long __sc8 __asm__ ("$r8") = (long) arg;
register unsigned long __sc9 __asm__ ("$r9") = (long) fn;
- __asm__("trapa #0\n\t" /* Linux/SH system call */
+ __asm__("trapa #0x12\n\t" /* Linux/SH system call */
"tst #0xff, $r0\n\t" /* child or parent? */
"bf 1f\n\t" /* parent - jump */
"jsr @$r9\n\t" /* call fn */
" mov $r8, $r4\n\t" /* push argument */
"mov $r0, $r4\n\t" /* return value to arg of exit */
- "mov %2, $r0\n\t" /* exit */
- "trapa #0\n"
+ "mov %2, $r3\n\t" /* exit */
+ "trapa #0x11\n"
"1:"
: "=z" (__sc0)
: "0" (__sc0), "i" (__NR_exit),
@@ -194,7 +194,11 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
fpvalid = tsk->used_math;
if (fpvalid) {
+ unsigned long flags;
+
+ save_and_cli(flags);
unlazy_fpu(tsk);
+ restore_flags(flags);
memcpy(fpu, &tsk->thread.fpu.hard, sizeof(*fpu));
}
@@ -214,7 +218,11 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
struct task_struct *tsk = current;
if (tsk != &init_task) {
+ unsigned long flags;
+
+ save_and_cli(flags);
unlazy_fpu(tsk);
+ restore_flags(flags);
p->thread.fpu = current->thread.fpu;
p->used_math = tsk->used_math;
}
@@ -263,16 +271,21 @@ void dump_thread(struct pt_regs * regs, struct user * dump)
void __switch_to(struct task_struct *prev, struct task_struct *next)
{
#if defined(__SH4__)
- if (prev != &init_task)
+ if (prev != &init_task) {
+ unsigned long flags;
+
+ save_and_cli(flags);
unlazy_fpu(prev);
+ restore_flags(flags);
+ }
#endif
/*
- * Restore the kernel stack onto kernel mode register
- * k4 (r4_bank1)
+ * Restore the kernel mode register
+ * k7 (r7_bank1)
*/
- asm volatile("ldc %0, $r4_bank"
+ asm volatile("ldc %0, $r7_bank"
: /* no output */
- :"r" ((unsigned long)next+8192));
+ :"r" (next));
}
asmlinkage int sys_fork(unsigned long r4, unsigned long r5,
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 154283571..49179f08f 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -244,7 +244,7 @@ void __init setup_arch(char **cmdline_p)
/*
* Reserve the kernel text and
- * Reserve the bootmem bitmap.We do this in two steps (first step
+ * Reserve the bootmem bitmap. We do this in two steps (first step
* was init_bootmem()), because this catches the (definitely buggy)
* case of us accidentally initializing the bootmem allocator with
* an invalid RAM area.
@@ -262,17 +262,17 @@ void __init setup_arch(char **cmdline_p)
if (LOADER_TYPE && INITRD_START) {
if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
reserve_bootmem(INITRD_START+__MEMORY_START, INITRD_SIZE);
- initrd_start =
- INITRD_START ? INITRD_START + PAGE_OFFSET + __MEMORY_START : 0;
+ initrd_start =
+ INITRD_START ? INITRD_START + PAGE_OFFSET + __MEMORY_START : 0;
initrd_end = initrd_start + INITRD_SIZE;
} else {
- printk("initrd extends beyond end of memory "
- "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
+ printk("initrd extends beyond end of memory "
+ "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
INITRD_START + INITRD_SIZE,
max_low_pfn << PAGE_SHIFT);
- initrd_start = 0;
- }
- }
+ initrd_start = 0;
+ }
+ }
#endif
#if 0
@@ -301,10 +301,9 @@ void __init setup_arch(char **cmdline_p)
#endif
#if defined(__SH4__)
+ /* We already grab/initialized FPU in head.S. Make it consisitent. */
init_task.used_math = 1;
init_task.flags |= PF_USEDFPU;
- grab_fpu();
- fpu_init();
#endif
paging_init();
}
diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c
index 4b11100ae..8751d45f5 100644
--- a/arch/sh/kernel/signal.c
+++ b/arch/sh/kernel/signal.c
@@ -152,30 +152,36 @@ struct rt_sigframe
#if defined(__SH4__)
static inline int restore_sigcontext_fpu(struct sigcontext *sc)
{
- current->used_math = 1;
+ struct task_struct *tsk = current;
+
+ tsk->used_math = 1;
return __copy_from_user(&tsk->thread.fpu.hard, &sc->sc_fpregs[0],
- sizeof(long)*(NUM_FPU_REGS*2+2));
+ sizeof(long)*(16*2+2));
}
static inline int save_sigcontext_fpu(struct sigcontext *sc)
{
struct task_struct *tsk = current;
+ unsigned long flags;
if (!tsk->used_math) {
- sc->owend_fp = 0;
+ sc->sc_ownedfp = 0;
return 0;
}
- sc->owend_fp = 1;
+ sc->sc_ownedfp = 1;
/* This will cause a "finit" to be triggered by the next
attempted FPU operation by the 'current' process.
*/
tsk->used_math = 0;
+ save_and_cli(flags);
unlazy_fpu(tsk);
+ restore_flags(flags);
+
return __copy_to_user(&sc->sc_fpregs[0], &tsk->thread.fpu.hard,
- sizeof(long)*(NUM_FPU_REGS*2+2));
+ sizeof(long)*(16*2+2));
}
#endif
@@ -206,7 +212,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc, int *r0_p)
regs->sr |= SR_FD; /* Release FPU */
clear_fpu(tsk);
current->used_math = 0;
- __get_user (owned_fp, &context->sc_ownedfp);
+ __get_user (owned_fp, &sc->sc_ownedfp);
if (owned_fp)
err |= restore_sigcontext_fpu(sc);
}
@@ -363,11 +369,11 @@ static void setup_frame(int sig, struct k_sigaction *ka,
if (ka->sa.sa_flags & SA_RESTORER) {
regs->pr = (unsigned long) ka->sa.sa_restorer;
} else {
- /* This is : mov #__NR_sigreturn,r0 ; trapa #0 */
+ /* This is : mov #__NR_sigreturn,r3 ; trapa #0x10 */
#ifdef __LITTLE_ENDIAN__
- unsigned long code = 0xc300e000 | (__NR_sigreturn);
+ unsigned long code = 0xc310e300 | (__NR_sigreturn);
#else
- unsigned long code = 0xe000c300 | (__NR_sigreturn << 16);
+ unsigned long code = 0xe300c310 | (__NR_sigreturn << 16);
#endif
regs->pr = (unsigned long) frame->retcode;
@@ -437,11 +443,11 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
if (ka->sa.sa_flags & SA_RESTORER) {
regs->pr = (unsigned long) ka->sa.sa_restorer;
} else {
- /* This is : mov #__NR_rt_sigreturn,r0 ; trapa #0 */
+ /* This is : mov #__NR_rt_sigreturn,r3 ; trapa #0x10 */
#ifdef __LITTLE_ENDIAN__
- unsigned long code = 0xc300e000 | (__NR_rt_sigreturn);
+ unsigned long code = 0xc310e300 | (__NR_rt_sigreturn);
#else
- unsigned long code = 0xe000c300 | (__NR_rt_sigreturn << 16);
+ unsigned long code = 0xe300c310 | (__NR_rt_sigreturn << 16);
#endif
regs->pr = (unsigned long) frame->retcode;
diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c
index fad3a8145..3e9cd8d28 100644
--- a/arch/sh/kernel/time.c
+++ b/arch/sh/kernel/time.c
@@ -33,6 +33,23 @@
#define TMU0_TCR_INIT 0x0020
#define TMU_TSTR_INIT 1
+/* RCR1 Bits */
+#define RCR1_CF 0x80 /* Carry Flag */
+#define RCR1_CIE 0x10 /* Carry Interrupt Enable */
+#define RCR1_AIE 0x08 /* Alarm Interrupt Enable */
+#define RCR1_AF 0x01 /* Alarm Flag */
+
+/* RCR2 Bits */
+#define RCR2_PEF 0x80 /* PEriodic interrupt Flag */
+#define RCR2_PESMASK 0x70 /* Periodic interrupt Set */
+#define RCR2_RTCEN 0x08 /* ENable RTC */
+#define RCR2_ADJ 0x04 /* ADJustment (30-second) */
+#define RCR2_RESET 0x02 /* Reset bit */
+#define RCR2_START 0x01 /* Start bit */
+
+#define RTC_IRQ 22
+#define RTC_IPR_OFFSET 0
+
#if defined(__sh3__)
#define TMU_TOCR 0xfffffe90 /* Byte access */
#define TMU_TSTR 0xfffffe92 /* Byte access */
@@ -43,9 +60,6 @@
#define FRQCR 0xffffff80
-#define RTC_IRQ 22
-#define RTC_IPR_OFFSET 0
-
/* SH-3 RTC */
#define R64CNT 0xfffffec0
#define RSECCNT 0xfffffec2
@@ -74,9 +88,6 @@
#define FRQCR 0xffc00000
-#define RTC_IRQ 22
-#define RTC_IPR_OFFSET 0
-
/* SH-4 RTC */
#define R64CNT 0xffc80000
#define RSECCNT 0xffc80004
@@ -149,7 +160,7 @@ static int set_rtc_time(unsigned long nowtime)
int retval = 0;
int real_seconds, real_minutes, cmos_minutes;
- ctrl_outb(0x02, RCR2); /* reset pre-scaler & stop RTC */
+ ctrl_outb(RCR2_RESET, RCR2); /* Reset pre-scaler & stop RTC */
cmos_minutes = ctrl_inb(RMINCNT);
BCD_TO_BIN(cmos_minutes);
@@ -178,7 +189,7 @@ static int set_rtc_time(unsigned long nowtime)
retval = -1;
}
- ctrl_outb(0x01, RCR2); /* start RTC */
+ ctrl_outb(RCR2_RTCEN|RCR2_START, RCR2); /* Start RTC */
return retval;
}
@@ -283,8 +294,8 @@ static unsigned long get_rtc_time(void)
unsigned int sec, min, hr, wk, day, mon, yr, yr100;
again:
- ctrl_outb(0x01, RCR1); /* clear CF bit */
do {
+ ctrl_outb(0, RCR1); /* Clear CF-bit */
sec = ctrl_inb(RSECCNT);
min = ctrl_inb(RMINCNT);
hr = ctrl_inb(RHRCNT);
@@ -299,7 +310,7 @@ static unsigned long get_rtc_time(void)
yr = ctrl_inb(RYRCNT);
yr100 = (yr == 0x99) ? 0x19 : 0x20;
#endif
- } while ((ctrl_inb(RCR1) & 0x80) != 0);
+ } while ((ctrl_inb(RCR1) & RCR1_CF) != 0);
BCD_TO_BIN(yr100);
BCD_TO_BIN(yr);
@@ -313,7 +324,7 @@ static unsigned long get_rtc_time(void)
hr > 23 || min > 59 || sec > 59) {
printk(KERN_ERR
"SH RTC: invalid value, resetting to 1 Jan 2000\n");
- ctrl_outb(0x02, RCR2); /* reset, stop */
+ ctrl_outb(RCR2_RESET, RCR2); /* Reset & Stop */
ctrl_outb(0, RSECCNT);
ctrl_outb(0, RMINCNT);
ctrl_outb(0, RHRCNT);
@@ -325,7 +336,7 @@ static unsigned long get_rtc_time(void)
#else
ctrl_outb(0, RYRCNT);
#endif
- ctrl_outb(0x01, RCR2); /* start */
+ ctrl_outb(RCR2_RTCEN|RCR2_START, RCR2); /* Start */
goto again;
}
@@ -339,13 +350,13 @@ static __init unsigned int get_cpu_mhz(void)
sti();
do {} while (ctrl_inb(R64CNT) != 0);
- ctrl_outb(0x11, RCR1);
+ ctrl_outb(RCR1_CIE, RCR1); /* Enable carry interrupt */
asm volatile(
"1:\t"
"tst %1,%1\n\t"
"bt/s 1b\n\t"
" add #1,%0"
- : "=&r"(count), "=&z" (__dummy)
+ : "=r"(count), "=z" (__dummy)
: "0" (0), "1" (0));
cli();
/*
@@ -373,7 +384,7 @@ static __init unsigned int get_cpu_mhz(void)
static void rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
- ctrl_outb(0x01, RCR1);
+ ctrl_outb(0, RCR1); /* Disable Carry Interrupts */
regs->regs[0] = 1;
}
diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c
index 98431cb36..a9775f306 100644
--- a/arch/sh/kernel/traps.c
+++ b/arch/sh/kernel/traps.c
@@ -43,7 +43,6 @@ asmlinkage void do_##name(unsigned long r4, unsigned long r5, \
\
asm volatile("stc $r2_bank, %0": "=r" (error_code)); \
sti(); \
- regs.syscall_nr = -1; \
tsk->thread.error_code = error_code; \
tsk->thread.trap_no = trapnr; \
force_sig(signr, tsk); \
@@ -95,9 +94,9 @@ DO_ERROR( 8, SIGSEGV, "address error (store)", address_error_store, current)
DO_ERROR(12, SIGILL, "reserved instruction", reserved_inst, current)
DO_ERROR(13, SIGILL, "illegal slot instruction", illegal_slot_inst, current)
-asmlinkage void do_exception_error (unsigned long r4, unsigned long r5,
- unsigned long r6, unsigned long r7,
- struct pt_regs regs)
+asmlinkage void do_exception_error(unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7,
+ struct pt_regs regs)
{
long ex;
asm volatile("stc $r2_bank, %0" : "=r" (ex));
@@ -131,7 +130,8 @@ void dump_stack(void)
unsigned long *p;
asm("mov $r15, %0" : "=r" (start));
- asm("stc $r4_bank, %0" : "=r" (end));
+ asm("stc $r7_bank, %0" : "=r" (end));
+ end += 8192;
printk("%08lx:%08lx\n", (unsigned long)start, (unsigned long)end);
for (p=start; p < end; p++)
diff --git a/arch/sh/mm/cache.c b/arch/sh/mm/cache.c
index 33bdf2114..5c28ea039 100644
--- a/arch/sh/mm/cache.c
+++ b/arch/sh/mm/cache.c
@@ -175,13 +175,13 @@ void cache_wback_area(unsigned long start, unsigned long end)
*
* For SH-4, flush (write back) Operand Cache, as Instruction Cache
* doesn't have "updated" data.
+ *
+ * Assumes that called in interrupt disabled.
*/
static void cache_wback_all(void)
{
- unsigned long flags;
unsigned long addr, data, i, j;
- save_and_cli(flags);
jump_to_P2();
for (i=0; i<CACHE_OC_NUM_ENTRIES; i++) {
@@ -197,7 +197,6 @@ static void cache_wback_all(void)
}
back_to_P1();
- restore_flags(flags);
}
static void
@@ -314,11 +313,11 @@ void flush_cache_all(void)
{
unsigned long flags;
+ save_and_cli(flags);
/* Write back Operand Cache */
- cache_wback_all ();
+ cache_wback_all();
/* Then, invalidate Instruction Cache and Operand Cache */
- save_and_cli(flags);
jump_to_P2();
ctrl_outl(CCR_CACHE_INIT, CCR);
back_to_P1();
diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c
index bf448bf8b..2369b3c04 100644
--- a/arch/sh/mm/fault.c
+++ b/arch/sh/mm/fault.c
@@ -55,7 +55,7 @@ good_area:
start &= PAGE_MASK;
for (;;) {
- if (handle_mm_fault(current, vma, start, 1) <= 0)
+ if (handle_mm_fault(current->mm, vma, start, 1) <= 0)
goto bad_area;
if (!size)
break;
@@ -168,7 +168,7 @@ good_area:
* the fault.
*/
{
- int fault = handle_mm_fault(tsk, vma, address, writeaccess);
+ int fault = handle_mm_fault(mm, vma, address, writeaccess);
if (fault < 0)
goto out_of_memory;
if (!fault)
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
index bd9181933..7c8998eaa 100644
--- a/arch/sparc/kernel/Makefile
+++ b/arch/sparc/kernel/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.52 1999/12/21 04:02:17 davem Exp $
+# $Id: Makefile,v 1.53 2000/03/31 04:06:19 davem Exp $
# Makefile for the linux kernel.
#
# Note! Dependencies are done automagically by 'make dep', which also
diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c
index 4a9c6cdcb..0efc28f65 100644
--- a/arch/sparc/kernel/cpu.c
+++ b/arch/sparc/kernel/cpu.c
@@ -92,7 +92,7 @@ struct cpu_iu_info linux_sparc_chips[] = {
/* Someone please write the code to support this beast! ;) */
{ 2, 0, "Bipolar Integrated Technology - B5010"},
{ 3, 0, "LSI Logic Corporation - unknown-type"},
- { 4, 0, "Texas Instruments, Inc. - SuperSparc 50"},
+ { 4, 0, "Texas Instruments, Inc. - SuperSparc-(II)"},
/* SparcClassic -- borned STP1010TAB-50*/
{ 4, 1, "Texas Instruments, Inc. - MicroSparc"},
{ 4, 2, "Texas Instruments, Inc. - MicroSparc II"},
diff --git a/arch/sparc/kernel/ptrace.c b/arch/sparc/kernel/ptrace.c
index d05153f7a..742d7db97 100644
--- a/arch/sparc/kernel/ptrace.c
+++ b/arch/sparc/kernel/ptrace.c
@@ -60,7 +60,7 @@ pt_succ_return_linux(struct pt_regs *regs, unsigned long value, long *addr)
static void
pt_os_succ_return (struct pt_regs *regs, unsigned long val, long *addr)
{
- if (current->personality & PER_BSD)
+ if (current->personality == PER_SUNOS)
pt_succ_return (regs, val);
else
pt_succ_return_linux (regs, val, addr);
@@ -155,7 +155,7 @@ static inline void read_sunos_user(struct pt_regs *regs, unsigned long offset,
pt_error_return(regs, EIO);
return;
}
- if (current->personality & PER_BSD)
+ if (current->personality == PER_SUNOS)
pt_succ_return (regs, v);
else
pt_succ_return_linux (regs, v, addr);
@@ -310,8 +310,8 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
goto out;
}
- if (((current->personality & PER_BSD) && (request == PTRACE_SUNATTACH))
- || (!(current->personality & PER_BSD) && (request == PTRACE_ATTACH))) {
+ if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
+ || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
unsigned long flags;
if(child == current) {
@@ -349,9 +349,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
pt_succ_return(regs, 0);
goto out;
}
- if (!(child->flags & PF_PTRACED)
- && ((current->personality & PER_BSD) && (request != PTRACE_SUNATTACH))
- && (!(current->personality & PER_BSD) && (request != PTRACE_ATTACH))) {
+ if (!(child->flags & PF_PTRACED)) {
pt_error_return(regs, ESRCH);
goto out;
}
diff --git a/arch/sparc/kernel/signal.c b/arch/sparc/kernel/signal.c
index 484ffac82..0af0b63d7 100644
--- a/arch/sparc/kernel/signal.c
+++ b/arch/sparc/kernel/signal.c
@@ -1,4 +1,4 @@
-/* $Id: signal.c,v 1.101 2000/01/21 11:38:38 jj Exp $
+/* $Id: signal.c,v 1.102 2000/04/08 02:11:36 davem Exp $
* linux/arch/sparc/kernel/signal.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c
index b589712aa..ac9caa27f 100644
--- a/arch/sparc/kernel/sun4d_smp.c
+++ b/arch/sparc/kernel/sun4d_smp.c
@@ -8,7 +8,6 @@
#include <asm/head.h>
-#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/threads.h>
@@ -443,38 +442,14 @@ void smp4d_message_pass(int target, int msg, unsigned long data, int wait)
panic("Bogon SMP message pass.");
}
-/* Protects counters touched during level14 ticker */
-static spinlock_t ticker_lock = SPIN_LOCK_UNLOCKED;
-
-#ifdef CONFIG_PROFILE
-
-/* 32-bit Sparc specific profiling function. */
-static inline void sparc_do_profile(unsigned long pc)
-{
- if(prof_buffer && current->pid) {
- extern int _stext;
-
- pc -= (unsigned long) &_stext;
- pc >>= prof_shift;
-
- spin_lock(&ticker_lock);
- if(pc < prof_len)
- prof_buffer[pc]++;
- else
- prof_buffer[prof_len - 1]++;
- spin_unlock(&ticker_lock);
- }
-}
-
-#endif
-
extern unsigned int prof_multiplier[NR_CPUS];
extern unsigned int prof_counter[NR_CPUS];
extern void update_one_process(struct task_struct *p, unsigned long ticks,
unsigned long user, unsigned long system,
int cpu);
-
+
+extern void sparc_do_profile(unsigned long pc, unsigned long o7);
void smp4d_percpu_timer_interrupt(struct pt_regs *regs)
{
@@ -493,12 +468,13 @@ void smp4d_percpu_timer_interrupt(struct pt_regs *regs)
show_leds(cpu);
}
-#ifdef CONFIG_PROFILE
if(!user_mode(regs))
- sparc_do_profile(regs->pc);
-#endif
+ sparc_do_profile(regs->pc, regs->u_regs[UREG_RETPC]);
+
if(!--prof_counter[cpu]) {
int user = user_mode(regs);
+
+ irq_enter(cpu, 0);
if(current->pid) {
update_one_process(current, 1, user, !user, cpu);
@@ -507,7 +483,6 @@ void smp4d_percpu_timer_interrupt(struct pt_regs *regs)
current->need_resched = 1;
}
- spin_lock(&ticker_lock);
if(user) {
if(current->priority < DEF_PRIORITY) {
kstat.cpu_nice++;
@@ -520,9 +495,9 @@ void smp4d_percpu_timer_interrupt(struct pt_regs *regs)
kstat.cpu_system++;
kstat.per_cpu_system[cpu]++;
}
- spin_unlock(&ticker_lock);
}
prof_counter[cpu] = prof_multiplier[cpu];
+ irq_exit(cpu, 0);
}
}
diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c
index 36c3d3c25..f0e046db3 100644
--- a/arch/sparc/kernel/sun4m_smp.c
+++ b/arch/sparc/kernel/sun4m_smp.c
@@ -440,27 +440,6 @@ void smp4m_cross_call_irq(void)
ccall_info.processors_out[i] = 1;
}
-/* Protects counters touched during level14 ticker */
-static spinlock_t ticker_lock = SPIN_LOCK_UNLOCKED;
-
-/* 32-bit Sparc specific profiling function. */
-static inline void sparc_do_profile(unsigned long pc)
-{
- if(prof_buffer && current->pid) {
- extern int _stext;
-
- pc -= (unsigned long) &_stext;
- pc >>= prof_shift;
-
- spin_lock(&ticker_lock);
- if(pc < prof_len)
- prof_buffer[pc]++;
- else
- prof_buffer[prof_len - 1]++;
- spin_unlock(&ticker_lock);
- }
-}
-
extern unsigned int prof_multiplier[NR_CPUS];
extern unsigned int prof_counter[NR_CPUS];
@@ -468,6 +447,8 @@ extern void update_one_process(struct task_struct *p, unsigned long ticks,
unsigned long user, unsigned long system,
int cpu);
+extern void sparc_do_profile(unsigned long pc, unsigned long o7);
+
void smp4m_percpu_timer_interrupt(struct pt_regs *regs)
{
int cpu = smp_processor_id();
@@ -475,7 +456,7 @@ void smp4m_percpu_timer_interrupt(struct pt_regs *regs)
clear_profile_irq(mid_xlate[cpu]);
if(!user_mode(regs))
- sparc_do_profile(regs->pc);
+ sparc_do_profile(regs->pc, regs->u_regs[UREG_RETPC]);
if(!--prof_counter[cpu]) {
int user = user_mode(regs);
diff --git a/arch/sparc/kernel/sys_solaris.c b/arch/sparc/kernel/sys_solaris.c
index eb79c344c..d099c4e8a 100644
--- a/arch/sparc/kernel/sys_solaris.c
+++ b/arch/sparc/kernel/sys_solaris.c
@@ -23,9 +23,7 @@ do_solaris_syscall (struct pt_regs *regs)
int ret;
lock_kernel();
- put_exec_domain(current->exec_domain);
- current->personality = PER_SVR4;
- current->exec_domain = lookup_exec_domain(PER_SVR4);
+ set_personality(PER_SVR4);
if (current->exec_domain && current->exec_domain->handler){
current->exec_domain->handler (0, regs);
diff --git a/arch/sparc/kernel/sys_sunos.c b/arch/sparc/kernel/sys_sunos.c
index 36670ab93..bb2c4b472 100644
--- a/arch/sparc/kernel/sys_sunos.c
+++ b/arch/sparc/kernel/sys_sunos.c
@@ -1,4 +1,4 @@
-/* $Id: sys_sunos.c,v 1.118 2000/03/26 11:28:56 davem Exp $
+/* $Id: sys_sunos.c,v 1.121 2000/04/13 00:55:48 davem Exp $
* sys_sunos.c: SunOS specific syscall compatibility support.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -50,6 +50,7 @@
#include <linux/socket.h>
#include <linux/in.h>
#include <linux/nfs.h>
+#include <linux/nfs2.h>
#include <linux/nfs_mount.h>
/* for sunos_select */
@@ -69,7 +70,6 @@ asmlinkage unsigned long sunos_mmap(unsigned long addr, unsigned long len,
down(&current->mm->mmap_sem);
lock_kernel();
- current->personality |= PER_BSD;
if(flags & MAP_NORESERVE) {
static int cnt;
if (cnt++ < 10)
@@ -170,7 +170,7 @@ asmlinkage int sunos_brk(unsigned long brk)
*/
if (brk <= current->mm->brk) {
current->mm->brk = brk;
- do_munmap(newbrk, oldbrk-newbrk);
+ do_munmap(current->mm, newbrk, oldbrk-newbrk);
goto out;
}
/*
@@ -582,7 +582,6 @@ asmlinkage int sunos_select(int width, fd_set *inp, fd_set *outp, fd_set *exp, s
/* SunOS binaries expect that select won't change the tvp contents */
lock_kernel();
- current->personality |= STICKY_TIMEOUTS;
ret = sys_select (width, inp, outp, exp, tvp);
if (ret == -EINTR && tvp) {
time_t sec, usec;
@@ -712,7 +711,7 @@ static int sunos_nfs_mount(char *dir_name, int linux_flags, void *data)
* address to create a socket and bind it to a reserved
* port on this system
*/
- if (copy_from_user(&sunos_mount, data, sizeof(sunos_mount))
+ if (copy_from_user(&sunos_mount, data, sizeof(sunos_mount)))
return -EFAULT;
server_fd = sys_socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
@@ -803,14 +802,14 @@ sunos_mount(char *type, char *dir, int flags, void *data)
dev_fname = getname(data);
} else if(strcmp(type_page, "nfs") == 0) {
ret = sunos_nfs_mount (dir_page, flags, data);
- goto out2
+ goto out2;
} else if(strcmp(type_page, "ufs") == 0) {
printk("Warning: UFS filesystem mounts unsupported.\n");
ret = -ENODEV;
- goto out2
+ goto out2;
} else if(strcmp(type_page, "proc")) {
ret = -ENODEV;
- goto out2
+ goto out2;
}
ret = PTR_ERR(dev_fname);
if (IS_ERR(dev_fname))
@@ -1054,18 +1053,6 @@ asmlinkage int sunos_shmsys(int op, unsigned long arg1, unsigned long arg2,
return rval;
}
-asmlinkage int sunos_open(const char *filename, int flags, int mode)
-{
- int ret;
-
- lock_kernel();
- current->personality |= PER_BSD;
- ret = sys_open (filename, flags, mode);
- unlock_kernel();
- return ret;
-}
-
-
#define SUNOS_EWOULDBLOCK 35
/* see the sunos man page read(2v) for an explanation
@@ -1200,8 +1187,6 @@ sunos_sigaction(int sig, const struct old_sigaction *act,
struct k_sigaction new_ka, old_ka;
int ret;
- current->personality |= PER_BSD;
-
if(act) {
old_sigset_t mask;
diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S
index 431f03daf..5bb551a46 100644
--- a/arch/sparc/kernel/systbls.S
+++ b/arch/sparc/kernel/systbls.S
@@ -1,4 +1,4 @@
-/* $Id: systbls.S,v 1.96 2000/03/15 02:43:32 davem Exp $
+/* $Id: systbls.S,v 1.97 2000/04/13 00:55:49 davem Exp $
* systbls.S: System call entry point tables for OS compatibility.
* The native Linux system call table lives here also.
*
@@ -79,7 +79,7 @@ sys_call_table:
.globl sunos_sys_table
sunos_sys_table:
/*0*/ .long sunos_indir, sys_exit, sys_fork
- .long sunos_read, sunos_write, sunos_open
+ .long sunos_read, sunos_write, sys_open
.long sys_close, sunos_wait4, sys_creat
.long sys_link, sys_unlink, sunos_execv
.long sys_chdir, sunos_nosys, sys_mknod
diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c
index 5a03e646b..68105c421 100644
--- a/arch/sparc/kernel/time.c
+++ b/arch/sparc/kernel/time.c
@@ -1,4 +1,4 @@
-/* $Id: time.c,v 1.53 2000/02/09 21:11:04 davem Exp $
+/* $Id: time.c,v 1.54 2000/04/13 08:14:30 anton Exp $
* linux/arch/sparc/kernel/time.c
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -70,6 +70,37 @@ struct intersil *intersil_clock;
#endif
+static spinlock_t ticker_lock = SPIN_LOCK_UNLOCKED;
+
+/* 32-bit Sparc specific profiling function. */
+void sparc_do_profile(unsigned long pc, unsigned long o7)
+{
+ if(prof_buffer && current->pid) {
+ extern int _stext;
+ extern int __copy_user_begin, __copy_user_end;
+ extern int __atomic_begin, __atomic_end;
+ extern int __bitops_begin, __bitops_end;
+
+ if ((pc >= (unsigned long) &__copy_user_begin &&
+ pc < (unsigned long) &__copy_user_end) ||
+ (pc >= (unsigned long) &__atomic_begin &&
+ pc < (unsigned long) &__atomic_end) ||
+ (pc >= (unsigned long) &__bitops_begin &&
+ pc < (unsigned long) &__bitops_end))
+ pc = o7;
+
+ pc -= (unsigned long) &_stext;
+ pc >>= prof_shift;
+
+ spin_lock(&ticker_lock);
+ if(pc < prof_len)
+ prof_buffer[pc]++;
+ else
+ prof_buffer[prof_len - 1]++;
+ spin_unlock(&ticker_lock);
+ }
+}
+
__volatile__ unsigned int *master_l10_counter;
__volatile__ unsigned int *master_l10_limit;
@@ -82,6 +113,11 @@ void timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
/* last time the cmos clock got updated */
static long last_rtc_update=0;
+#ifndef __SMP__
+ if(!user_mode(regs))
+ sparc_do_profile(regs->pc, regs->u_regs[UREG_RETPC]);
+#endif
+
#ifdef CONFIG_SUN4
if((idprom->id_machtype == (SM_SUN4 | SM_4_260)) ||
(idprom->id_machtype == (SM_SUN4 | SM_4_110))) {
diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile
index f5e316534..d7b3c7554 100644
--- a/arch/sparc/lib/Makefile
+++ b/arch/sparc/lib/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.33 2000/03/16 00:52:07 anton Exp $
+# $Id: Makefile,v 1.34 2000/03/31 04:06:20 davem Exp $
# Makefile for Sparc library files..
#
diff --git a/arch/sparc/lib/atomic.S b/arch/sparc/lib/atomic.S
index c57e61574..76c4d8164 100644
--- a/arch/sparc/lib/atomic.S
+++ b/arch/sparc/lib/atomic.S
@@ -10,6 +10,9 @@
.text
.align 4
+ .globl __atomic_begin
+__atomic_begin:
+
#ifndef __SMP__
.globl ___xchg32_sun4c
___xchg32_sun4c:
@@ -92,3 +95,6 @@ ___atomic_sub:
nop; nop; nop; ! Let the bits set
jmpl %o7, %g0 ! NOTE: not + 8, see callers in atomic.h
mov %g4, %o7 ! Restore %o7
+
+ .globl __atomic_end
+__atomic_end:
diff --git a/arch/sparc/lib/bitops.S b/arch/sparc/lib/bitops.S
index ea9ed5a6c..10fc42738 100644
--- a/arch/sparc/lib/bitops.S
+++ b/arch/sparc/lib/bitops.S
@@ -10,6 +10,9 @@
.text
.align 4
+ .globl __bitops_begin
+__bitops_begin:
+
/* Take bits in %g2 and set them in word at %g1,
* return whether bits were set in original value
* in %g2. %g4 holds value to restore into %o7
@@ -159,3 +162,6 @@ ___clear_le_bit:
nop; nop; nop
jmpl %o7, %g0
mov %g4, %o7
+
+ .globl __bitops_end
+__bitops_end:
diff --git a/arch/sparc/lib/copy_user.S b/arch/sparc/lib/copy_user.S
index 97c55f02d..239ec762d 100644
--- a/arch/sparc/lib/copy_user.S
+++ b/arch/sparc/lib/copy_user.S
@@ -112,6 +112,9 @@
.text
.align 4
+ .globl __copy_user_begin
+__copy_user_begin:
+
.globl C_LABEL(__copy_user)
dword_align:
andcc %o1, 1, %g0
@@ -482,3 +485,6 @@ fixupretl:
sub %o0, %g3, %o0
ba fixupretl
add %g3, %o2, %g3
+
+ .globl __copy_user_end
+__copy_user_end:
diff --git a/arch/sparc/mm/Makefile b/arch/sparc/mm/Makefile
index 440e4fc61..82bfaf6bf 100644
--- a/arch/sparc/mm/Makefile
+++ b/arch/sparc/mm/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.36 2000/01/29 01:09:05 anton Exp $
+# $Id: Makefile,v 1.37 2000/03/31 04:06:22 davem Exp $
# Makefile for the linux Sparc-specific parts of the memory manager.
#
# Note! Dependencies are done automagically by 'make dep', which also
diff --git a/arch/sparc/mm/fault.c b/arch/sparc/mm/fault.c
index 909c46447..a2af935cb 100644
--- a/arch/sparc/mm/fault.c
+++ b/arch/sparc/mm/fault.c
@@ -1,4 +1,4 @@
-/* $Id: fault.c,v 1.114 2000/02/14 04:52:36 jj Exp $
+/* $Id: fault.c,v 1.115 2000/04/25 04:13:25 davem Exp $
* fault.c: Page fault handlers for the Sparc.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -250,7 +250,7 @@ good_area:
* the fault.
*/
{
- int fault = handle_mm_fault(tsk, vma, address, write);
+ int fault = handle_mm_fault(mm, vma, address, write);
if (fault < 0)
goto out_of_memory;
if (!fault)
@@ -450,7 +450,7 @@ good_area:
if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
goto bad_area;
}
- if (!handle_mm_fault(current, vma, address, write))
+ if (!handle_mm_fault(mm, vma, address, write))
goto do_sigbus;
up(&mm->mmap_sem);
return;
diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c
index 3c8b079c3..24fc68c5a 100644
--- a/arch/sparc/mm/sun4c.c
+++ b/arch/sparc/mm/sun4c.c
@@ -1,4 +1,4 @@
-/* $Id: sun4c.c,v 1.190 2000/02/14 04:52:34 jj Exp $
+/* $Id: sun4c.c,v 1.191 2000/04/08 02:11:41 davem Exp $
* sun4c.c: Doing in software what should be done in hardware.
*
* Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
diff --git a/arch/sparc64/config.in b/arch/sparc64/config.in
index 27e5549c0..3ec14ec5c 100644
--- a/arch/sparc64/config.in
+++ b/arch/sparc64/config.in
@@ -1,4 +1,4 @@
-# $Id: config.in,v 1.107 2000/03/29 11:56:51 davem Exp $
+# $Id: config.in,v 1.108 2000/04/18 05:20:45 davem Exp $
# For a description of the syntax of this configuration file,
# see the Configure script.
#
@@ -187,6 +187,7 @@ if [ "$CONFIG_SCSI" != "n" ]; then
fi
fi
dep_tristate 'Qlogic ISP SCSI support' CONFIG_SCSI_QLOGIC_ISP $CONFIG_SCSI
+ dep_tristate 'Qlogic ISP FC SCSI support' CONFIG_SCSI_QLOGIC_FC $CONFIG_SCSI
fi
endmenu
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index 2f9febcbe..f969b1b5e 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -223,8 +223,8 @@ CONFIG_BLK_DEV_IDEDMA=y
CONFIG_IDEDMA_PCI_EXPERIMENTAL=y
# CONFIG_IDEDMA_PCI_WIP is not set
# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
-# CONFIG_BLK_DEV_AEC6210 is not set
-# CONFIG_AEC6210_TUNING is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_AEC62XX_TUNING is not set
# CONFIG_BLK_DEV_ALI15X3 is not set
# CONFIG_WDC_ALI15X3 is not set
# CONFIG_BLK_DEV_AMD7409 is not set
@@ -246,6 +246,7 @@ CONFIG_BLK_DEV_NS87415=y
# CONFIG_BLK_DEV_SIS5513 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_VIA82CXXX_TUNING is not set
# CONFIG_IDE_CHIPSETS is not set
CONFIG_IDEDMA_AUTO=y
CONFIG_BLK_DEV_IDE_MODES=y
@@ -293,6 +294,7 @@ CONFIG_SCSI_NCR53C8XX_SYNC=10
# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set
# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set
CONFIG_SCSI_QLOGIC_ISP=y
+CONFIG_SCSI_QLOGIC_FC=m
#
# Fibre Channel support
@@ -370,6 +372,7 @@ CONFIG_VIDEO_DEV=y
CONFIG_AUTOFS_FS=m
CONFIG_AUTOFS4_FS=m
# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
CONFIG_AFFS_FS=m
# CONFIG_HFS_FS is not set
CONFIG_BFS_FS=m
@@ -379,47 +382,52 @@ CONFIG_MSDOS_FS=m
CONFIG_VFAT_FS=m
CONFIG_EFS_FS=m
CONFIG_CRAMFS=m
+CONFIG_RAMFS=m
CONFIG_ISO9660_FS=m
-# CONFIG_JOLIET is not set
+CONFIG_JOLIET=y
CONFIG_MINIX_FS=m
# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
CONFIG_HPFS_FS=m
CONFIG_PROC_FS=y
# CONFIG_DEVFS_FS is not set
# CONFIG_DEVFS_DEBUG is not set
CONFIG_DEVPTS_FS=y
# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
CONFIG_ROMFS_FS=m
CONFIG_EXT2_FS=y
CONFIG_SYSV_FS=m
-# CONFIG_SYSV_FS_WRITE is not set
+CONFIG_SYSV_FS_WRITE=y
CONFIG_UDF_FS=m
-# CONFIG_UDF_RW is not set
+CONFIG_UDF_RW=y
CONFIG_UFS_FS=m
-# CONFIG_UFS_FS_WRITE is not set
+CONFIG_UFS_FS_WRITE=y
#
# Network File Systems
#
CONFIG_CODA_FS=m
CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
# CONFIG_ROOT_NFS is not set
CONFIG_NFSD=m
-# CONFIG_NFSD_V3 is not set
+CONFIG_NFSD_V3=y
CONFIG_SUNRPC=y
CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
CONFIG_SMB_FS=m
CONFIG_NCP_FS=m
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_MOUNT_SUBDIR is not set
-# CONFIG_NCPFS_NDS_DOMAINS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_SMALLDOS=y
+CONFIG_NCPFS_MOUNT_SUBDIR=y
+CONFIG_NCPFS_NDS_DOMAINS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
#
# Partition Types
diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile
index 5e37c94b4..5c0d38d0d 100644
--- a/arch/sparc64/kernel/Makefile
+++ b/arch/sparc64/kernel/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.52 2000/03/19 07:00:29 ecd Exp $
+# $Id: Makefile,v 1.53 2000/03/31 04:06:22 davem Exp $
# Makefile for the linux kernel.
#
# Note! Dependencies are done automagically by 'make dep', which also
diff --git a/arch/sparc64/kernel/binfmt_aout32.c b/arch/sparc64/kernel/binfmt_aout32.c
index c72f7272f..9cc240293 100644
--- a/arch/sparc64/kernel/binfmt_aout32.c
+++ b/arch/sparc64/kernel/binfmt_aout32.c
@@ -198,7 +198,6 @@ static u32 *create_aout32_tables(char * p, struct linux_binprm * bprm)
static int load_aout32_binary(struct linux_binprm * bprm, struct pt_regs * regs)
{
struct exec ex;
- int fd;
unsigned long error;
unsigned long fd_offset;
unsigned long rlim;
@@ -230,7 +229,7 @@ static int load_aout32_binary(struct linux_binprm * bprm, struct pt_regs * regs)
return retval;
/* OK, This is the point of no return */
- current->personality = PER_LINUX;
+ set_personality(PER_SUNOS);
current->mm->end_code = ex.a_text +
(current->mm->start_code = N_TXTADDR(ex));
@@ -270,15 +269,8 @@ static int load_aout32_binary(struct linux_binprm * bprm, struct pt_regs * regs)
error_time = jiffies;
}
- fd = get_unused_fd();
- if (fd < 0)
- return fd;
- get_file(bprm->file);
- fd_install(fd, bprm->file);
-
if (!bprm->file->f_op->mmap) {
loff_t pos = fd_offset;
- sys_close(fd);
do_brk(0, ex.a_text+ex.a_data);
bprm->file->f_op->read(bprm->file,(char *)N_TXTADDR(ex),
ex.a_text+ex.a_data, &pos);
@@ -291,7 +283,6 @@ static int load_aout32_binary(struct linux_binprm * bprm, struct pt_regs * regs)
fd_offset);
if (error != N_TXTADDR(ex)) {
- sys_close(fd);
send_sig(SIGKILL, current, 0);
return error;
}
@@ -300,20 +291,13 @@ static int load_aout32_binary(struct linux_binprm * bprm, struct pt_regs * regs)
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
fd_offset + ex.a_text);
- sys_close(fd);
if (error != N_DATADDR(ex)) {
send_sig(SIGKILL, current, 0);
return error;
}
}
beyond_if:
- put_exec_domain(current->exec_domain);
- if (current->binfmt && current->binfmt->module)
- __MOD_DEC_USE_COUNT(current->binfmt->module);
- current->exec_domain = lookup_exec_domain(current->personality);
- current->binfmt = &aout32_format;
- if (current->binfmt && current->binfmt->module)
- __MOD_INC_USE_COUNT(current->binfmt->module);
+ set_binfmt(&aout32_format);
set_brk(current->mm->start_brk, current->mm->brk);
diff --git a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c
index ef07fca85..c7e2fecfb 100644
--- a/arch/sparc64/kernel/ioctl32.c
+++ b/arch/sparc64/kernel/ioctl32.c
@@ -1,4 +1,4 @@
-/* $Id: ioctl32.c,v 1.87 2000/03/30 02:09:07 davem Exp $
+/* $Id: ioctl32.c,v 1.88 2000/04/14 10:10:34 davem Exp $
* ioctl32.c: Conversion between 32bit and 64bit native ioctls.
*
* Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com)
@@ -1816,6 +1816,7 @@ struct atm_iobuf32 {
#define ATM_GETSTATZ32 _IOW('a', ATMIOC_SARCOM+1, struct atmif_sioc32)
#define ATM_GETLOOP32 _IOW('a', ATMIOC_SARCOM+2, struct atmif_sioc32)
#define ATM_SETLOOP32 _IOW('a', ATMIOC_SARCOM+3, struct atmif_sioc32)
+#define ATM_QUERYLOOP32 _IOW('a', ATMIOC_SARCOM+4, struct atmif_sioc32)
static struct {
unsigned int cmd32;
@@ -1836,7 +1837,8 @@ static struct {
{ ATM_GETSTAT32, ATM_GETSTAT },
{ ATM_GETSTATZ32, ATM_GETSTATZ },
{ ATM_GETLOOP32, ATM_GETLOOP },
- { ATM_SETLOOP32, ATM_SETLOOP }
+ { ATM_SETLOOP32, ATM_SETLOOP },
+ { ATM_QUERYLOOP32, ATM_QUERYLOOP }
};
#define NR_ATM_IOCTL (sizeof(atm_ioctl_map)/sizeof(atm_ioctl_map[0]))
@@ -1996,6 +1998,7 @@ static int do_atm_ioctl(unsigned int fd, unsigned int cmd32, unsigned long arg)
case ATM_GETSTATZ:
case ATM_GETLOOP:
case ATM_SETLOOP:
+ case ATM_QUERYLOOP:
return do_atmif_sioc(fd, cmd, arg);
}
@@ -3110,6 +3113,7 @@ HANDLE_IOCTL(ATM_GETSTAT32, do_atm_ioctl)
HANDLE_IOCTL(ATM_GETSTATZ32, do_atm_ioctl)
HANDLE_IOCTL(ATM_GETLOOP32, do_atm_ioctl)
HANDLE_IOCTL(ATM_SETLOOP32, do_atm_ioctl)
+HANDLE_IOCTL(ATM_QUERYLOOP32, do_atm_ioctl)
HANDLE_IOCTL(SONET_GETSTAT, do_atm_ioctl)
HANDLE_IOCTL(SONET_GETSTATZ, do_atm_ioctl)
HANDLE_IOCTL(SONET_GETDIAG, do_atm_ioctl)
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index d2bc6baf5..6bb01d4c1 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -1,4 +1,4 @@
-/* $Id: irq.c,v 1.85 2000/03/02 02:00:24 davem Exp $
+/* $Id: irq.c,v 1.86 2000/04/15 06:02:50 davem Exp $
* irq.c: UltraSparc IRQ handling/init/registry.
*
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -538,82 +538,43 @@ out:
}
/* Only uniprocessor needs this IRQ/BH locking depth, on SMP it
- * lives in the per-cpu structure for cache reasons.
+ * lives in the brlock table for cache reasons.
*/
#ifndef __SMP__
unsigned int local_irq_count;
unsigned int local_bh_count;
-
-#define irq_enter(cpu, irq) (local_irq_count++)
-#define irq_exit(cpu, irq) (local_irq_count--)
#else
/* Who has global_irq_lock. */
unsigned char global_irq_holder = NO_PROC_ID;
-/* This protects IRQ's. */
-spinlock_t global_irq_lock = SPIN_LOCK_UNLOCKED;
-
-/* Global IRQ locking depth. */
-atomic_t global_irq_count = ATOMIC_INIT(0);
-
-#define irq_enter(cpu, irq) \
-do { hardirq_enter(cpu); \
- spin_unlock_wait(&global_irq_lock); \
-} while(0)
-#define irq_exit(cpu, irq) hardirq_exit(cpu)
-
static void show(char * str)
{
int cpu = smp_processor_id();
+ int i;
printk("\n%s, CPU %d:\n", str, cpu);
- printk("irq: %d [%u %u]\n",
- atomic_read(&global_irq_count),
- cpu_data[0].irq_count, cpu_data[1].irq_count);
- printk("bh: %d [%u %u]\n",
- (spin_is_locked(&global_bh_lock) ? 1 : 0),
- cpu_data[0].bh_count, cpu_data[1].bh_count);
+ printk("irq: %d [ ", irqs_running());
+ for (i = 0; i < smp_num_cpus; i++)
+ printk("%u ", __brlock_array[i][BR_GLOBALIRQ_LOCK]);
+ printk("]\nbh: %d [ ",
+ (spin_is_locked(&global_bh_lock) ? 1 : 0));
+ for (i = 0; i < smp_num_cpus; i++)
+ printk("%u ", cpu_data[i].bh_count);
+ printk("]\n");
}
#define MAXCOUNT 100000000
+#if 0
#define SYNC_OTHER_ULTRAS(x) udelay(x+1)
-
-static inline void wait_on_irq(int cpu)
-{
- int count = MAXCOUNT;
- for(;;) {
- membar("#LoadLoad");
- if (!atomic_read (&global_irq_count)) {
- if (local_bh_count || ! spin_is_locked(&global_bh_lock))
- break;
- }
- spin_unlock (&global_irq_lock);
- membar("#StoreLoad | #StoreStore");
- for(;;) {
- if (!--count) {
- show("wait_on_irq");
- count = ~0;
- }
- __sti();
- SYNC_OTHER_ULTRAS(cpu);
- __cli();
- if (atomic_read(&global_irq_count))
- continue;
- if (spin_is_locked (&global_irq_lock))
- continue;
- if (!local_bh_count && spin_is_locked (&global_bh_lock))
- continue;
- if (spin_trylock(&global_irq_lock))
- break;
- }
- }
-}
+#else
+#define SYNC_OTHER_ULTRAS(x) membar("#Sync");
+#endif
void synchronize_irq(void)
{
- if (atomic_read(&global_irq_count)) {
+ if (irqs_running()) {
cli();
sti();
}
@@ -621,15 +582,37 @@ void synchronize_irq(void)
static inline void get_irqlock(int cpu)
{
- if (! spin_trylock(&global_irq_lock)) {
- if ((unsigned char) cpu == global_irq_holder)
- return;
- do {
- while (spin_is_locked (&global_irq_lock))
- membar("#LoadLoad");
- } while(! spin_trylock(&global_irq_lock));
+ int count;
+
+ if ((unsigned char)cpu == global_irq_holder)
+ return;
+
+ count = MAXCOUNT;
+again:
+ br_write_lock(BR_GLOBALIRQ_LOCK);
+ for (;;) {
+ spinlock_t *lock;
+
+ if (!irqs_running() &&
+ (local_bh_count || !spin_is_locked(&global_bh_lock)))
+ break;
+
+ br_write_unlock(BR_GLOBALIRQ_LOCK);
+ lock = &__br_write_locks[BR_GLOBALIRQ_LOCK].lock;
+ while (irqs_running() ||
+ spin_is_locked(lock) ||
+ (!local_bh_count && spin_is_locked(&global_bh_lock))) {
+ if (!--count) {
+ show("wait_on_irq");
+ count = (~0 >> 1);
+ }
+ __sti();
+ SYNC_OTHER_ULTRAS(cpu);
+ __cli();
+ }
+ goto again;
}
- wait_on_irq(cpu);
+
global_irq_holder = cpu;
}
diff --git a/arch/sparc64/kernel/pci_common.c b/arch/sparc64/kernel/pci_common.c
index 98b41d079..5cd905244 100644
--- a/arch/sparc64/kernel/pci_common.c
+++ b/arch/sparc64/kernel/pci_common.c
@@ -1,4 +1,4 @@
-/* $Id: pci_common.c,v 1.7 2000/03/25 05:18:11 davem Exp $
+/* $Id: pci_common.c,v 1.11 2000/04/26 10:48:02 davem Exp $
* pci_common.c: PCI controller common support.
*
* Copyright (C) 1999 David S. Miller (davem@redhat.com)
@@ -66,6 +66,27 @@ static void pci_device_delete(struct pci_dev *pdev)
kfree(pdev);
}
+/* Older versions of OBP on PCI systems encode 64-bit MEM
+ * space assignments incorrectly, this fixes them up.
+ */
+static void __init fixup_obp_assignments(struct pcidev_cookie *pcp)
+{
+ int i;
+
+ for (i = 0; i < pcp->num_prom_assignments; i++) {
+ struct linux_prom_pci_registers *ap;
+ int space;
+
+ ap = &pcp->prom_assignments[i];
+ space = ap->phys_hi >> 24;
+ if ((space & 0x3) == 2 &&
+ (space & 0x4) != 0) {
+ ap->phys_hi &= ~(0x7 << 24);
+ ap->phys_hi |= 0x3 << 24;
+ }
+ }
+}
+
/* Fill in the PCI device cookie sysdata for the given
* PCI device. This cookie is the means by which one
* can get to OBP and PCI controller specific information
@@ -147,6 +168,8 @@ static void __init pdev_cookie_fillin(struct pci_pbm_info *pbm,
(err / sizeof(pcp->prom_assignments[0]));
}
+ fixup_obp_assignments(pcp);
+
pdev->sysdata = pcp;
}
@@ -219,10 +242,15 @@ __init get_root_resource(struct linux_prom_pci_registers *ap,
return &pbm->mem_space;
case 3:
+ /* 64-bit MEM space, these are allocated out of
+ * the 32-bit mem_space range for the PBM, ie.
+ * we just zero out the upper 32-bits.
+ */
+ return &pbm->mem_space;
+
default:
- /* 64-bit MEM space, unsupported. */
- printk("PCI: 64-bit MEM assignment??? "
- "Tell davem@redhat.com about it!\n");
+ printk("PCI: What is resource space %x? "
+ "Tell davem@redhat.com about it!\n", space);
return NULL;
};
}
@@ -231,6 +259,7 @@ static struct resource *
__init get_device_resource(struct linux_prom_pci_registers *ap,
struct pci_dev *pdev)
{
+ struct resource *res;
int breg = (ap->phys_hi & 0xff);
int space = (ap->phys_hi >> 24) & 3;
@@ -240,7 +269,8 @@ __init get_device_resource(struct linux_prom_pci_registers *ap,
if (space != 2)
bad_assignment(ap, NULL, 0);
- return &pdev->resource[PCI_ROM_RESOURCE];
+ res = &pdev->resource[PCI_ROM_RESOURCE];
+ break;
case PCI_BASE_ADDRESS_0:
case PCI_BASE_ADDRESS_1:
@@ -248,12 +278,16 @@ __init get_device_resource(struct linux_prom_pci_registers *ap,
case PCI_BASE_ADDRESS_3:
case PCI_BASE_ADDRESS_4:
case PCI_BASE_ADDRESS_5:
- return &pdev->resource[(breg - PCI_BASE_ADDRESS_0) / 4];
+ res = &pdev->resource[(breg - PCI_BASE_ADDRESS_0) / 4];
+ break;
default:
bad_assignment(ap, NULL, 0);
- return NULL;
+ res = NULL;
+ break;
};
+
+ return res;
}
static void __init pdev_record_assignments(struct pci_pbm_info *pbm,
@@ -281,6 +315,31 @@ static void __init pdev_record_assignments(struct pci_pbm_info *pbm,
if ((res->start & 0xffffffffUL) != ap->phys_lo)
bad_assignment(ap, res, 1);
+ /* If it is a 64-bit MEM space assignment, verify that
+ * the resource is too and that the upper 32-bits match.
+ */
+ if (((ap->phys_hi >> 24) & 3) == 3) {
+ if (((res->flags & IORESOURCE_MEM) == 0) ||
+ ((res->flags & PCI_BASE_ADDRESS_MEM_TYPE_MASK)
+ != PCI_BASE_ADDRESS_MEM_TYPE_64))
+ bad_assignment(ap, res, 1);
+ if ((res->start >> 32) != ap->phys_mid)
+ bad_assignment(ap, res, 1);
+
+ /* PBM cannot generate cpu initiated PIOs
+ * to the full 64-bit space. Therefore the
+ * upper 32-bits better be zero. If it is
+ * not, just skip it and we will assign it
+ * properly ourselves.
+ */
+ if ((res->start >> 32) != 0UL) {
+ printk(KERN_ERR "PCI: OBP assigns out of range MEM address "
+ "%016lx for region %ld on device %s\n",
+ res->start, (res - &pdev->resource[0]), pdev->name);
+ continue;
+ }
+ }
+
/* Adjust the resource into the physical address space
* of this PBM.
*/
@@ -425,13 +484,21 @@ static int __init pci_intmap_match(struct pci_dev *pdev, unsigned int *interrupt
return 0;
/* If we are underneath a PCI bridge, use PROM register
- * property of parent bridge.
+ * property of the parent bridge which is closest to
+ * the PBM.
*/
if (pdev->bus->number != pbm->pci_first_busno) {
struct pcidev_cookie *bus_pcp;
+ struct pci_dev *pwalk;
int offset;
- bus_pcp = pdev->bus->self->sysdata;
+ pwalk = pdev->bus->self;
+ while (pwalk->bus &&
+ pwalk->bus->number != pbm->pci_first_busno)
+ pwalk = pwalk->bus->self;
+
+ bus_pcp = pwalk->bus->self->sysdata;
+
pregs = bus_pcp->prom_regs;
offset = prom_getint(bus_pcp->prom_node,
"fcode-rom-offset");
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c
index a45fe4740..8d7db0c9b 100644
--- a/arch/sparc64/kernel/pci_psycho.c
+++ b/arch/sparc64/kernel/pci_psycho.c
@@ -1,4 +1,4 @@
-/* $Id: pci_psycho.c,v 1.15 2000/03/25 05:18:11 davem Exp $
+/* $Id: pci_psycho.c,v 1.16 2000/04/15 10:06:16 davem Exp $
* pci_psycho.c: PSYCHO/U2P specific PCI controller support.
*
* Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu)
@@ -1074,22 +1074,34 @@ static void __init psycho_base_address_update(struct pci_dev *pdev, int resource
{
struct pcidev_cookie *pcp = pdev->sysdata;
struct pci_pbm_info *pbm = pcp->pbm;
- struct resource *res = &pdev->resource[resource];
- struct resource *root;
+ struct resource *res, *root;
u32 reg;
- int where, size;
+ int where, size, is_64bit;
+ res = &pdev->resource[resource];
+ where = PCI_BASE_ADDRESS_0 + (resource * 4);
+
+ is_64bit = 0;
if (res->flags & IORESOURCE_IO)
root = &pbm->io_space;
- else
+ else {
root = &pbm->mem_space;
+ if ((res->flags & PCI_BASE_ADDRESS_MEM_TYPE_MASK)
+ == PCI_BASE_ADDRESS_MEM_TYPE_64)
+ is_64bit = 1;
+ }
- where = PCI_BASE_ADDRESS_0 + (resource * 4);
size = res->end - res->start;
pci_read_config_dword(pdev, where, &reg);
reg = ((reg & size) |
(((u32)(res->start - root->start)) & ~size));
pci_write_config_dword(pdev, where, reg);
+
+ /* This knows that the upper 32-bits of the address
+ * must be zero. Our PCI common layer enforces this.
+ */
+ if (is_64bit)
+ pci_write_config_dword(pdev, where + 4, 0);
}
/* We have to do the config space accesses by hand, thus... */
diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c
index a55772179..99f7ba8ad 100644
--- a/arch/sparc64/kernel/pci_sabre.c
+++ b/arch/sparc64/kernel/pci_sabre.c
@@ -1,4 +1,4 @@
-/* $Id: pci_sabre.c,v 1.16 2000/03/25 05:18:12 davem Exp $
+/* $Id: pci_sabre.c,v 1.19 2000/04/15 13:07:51 davem Exp $
* pci_sabre.c: Sabre specific PCI controller support.
*
* Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu)
@@ -1012,22 +1012,35 @@ static void __init sabre_base_address_update(struct pci_dev *pdev, int resource)
struct pcidev_cookie *pcp = pdev->sysdata;
struct pci_pbm_info *pbm = pcp->pbm;
struct pci_controller_info *p = pbm->parent;
- struct resource *res = &pdev->resource[resource];
+ struct resource *res;
unsigned long base;
u32 reg;
- int where, size;
+ int where, size, is_64bit;
+ res = &pdev->resource[resource];
+ where = PCI_BASE_ADDRESS_0 + (resource * 4);
+
+ is_64bit = 0;
if (res->flags & IORESOURCE_IO)
base = p->controller_regs + SABRE_IOSPACE;
- else
+ else {
base = p->controller_regs + SABRE_MEMSPACE;
+ if ((res->flags & PCI_BASE_ADDRESS_MEM_TYPE_MASK)
+ == PCI_BASE_ADDRESS_MEM_TYPE_64)
+ is_64bit = 1;
+ }
- where = PCI_BASE_ADDRESS_0 + (resource * 4);
size = res->end - res->start;
pci_read_config_dword(pdev, where, &reg);
reg = ((reg & size) |
(((u32)(res->start - base)) & ~size));
pci_write_config_dword(pdev, where, reg);
+
+ /* This knows that the upper 32-bits of the address
+ * must be zero. Our PCI common layer enforces this.
+ */
+ if (is_64bit)
+ pci_write_config_dword(pdev, where + 4, 0);
}
static void __init apb_init(struct pci_controller_info *p, struct pci_bus *sabre_bus)
@@ -1050,6 +1063,20 @@ static void __init apb_init(struct pci_controller_info *p, struct pci_bus *sabre
/* Status register bits are "write 1 to clear". */
sabre_write_word(pdev, PCI_STATUS, 0xffff);
sabre_write_word(pdev, PCI_SEC_STATUS, 0xffff);
+
+ /* Use a primary/seconday latency timer value
+ * of 64.
+ */
+ sabre_write_byte(pdev, PCI_LATENCY_TIMER, 64);
+ sabre_write_byte(pdev, PCI_SEC_LATENCY_TIMER, 64);
+
+ /* Enable reporting/forwarding of master aborts,
+ * parity, and SERR.
+ */
+ sabre_write_byte(pdev, PCI_BRIDGE_CONTROL,
+ (PCI_BRIDGE_CTL_PARITY |
+ PCI_BRIDGE_CTL_SERR |
+ PCI_BRIDGE_CTL_MASTER_ABORT));
}
}
}
@@ -1086,17 +1113,6 @@ static void __init sabre_scan_bus(struct pci_controller_info *p)
sabre_bus = pci_scan_bus(p->pci_first_busno,
p->pci_ops,
&p->pbm_A);
-
- {
- unsigned int devfn;
- u8 *addr;
-
- devfn = PCI_DEVFN(0, 0);
- addr = sabre_pci_config_mkaddr(&p->pbm_A, 0,
- devfn, PCI_LATENCY_TIMER);
- pci_config_write8(addr, 32);
- }
-
apb_init(p, sabre_bus);
walk = &sabre_bus->children;
diff --git a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c
index e612d0200..ccf0c03bf 100644
--- a/arch/sparc64/kernel/power.c
+++ b/arch/sparc64/kernel/power.c
@@ -1,4 +1,4 @@
-/* $Id: power.c,v 1.5 1999/12/19 23:28:00 davem Exp $
+/* $Id: power.c,v 1.6 2000/04/13 00:59:59 davem Exp $
* power.c: Power management driver.
*
* Copyright (C) 1999 David S. Miller (davem@redhat.com)
@@ -55,8 +55,7 @@ static int powerd(void *__unused)
static char *envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
char *argv[] = { "/usr/bin/shutdown", "-h", "now", NULL };
- current->session = 1;
- current->pgrp = 1;
+ daemonize();
sprintf(current->comm, "powerd");
again:
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index 8ac030324..fb0e8f411 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -1,4 +1,4 @@
-/* $Id: process.c,v 1.105 2000/03/26 09:13:48 davem Exp $
+/* $Id: process.c,v 1.106 2000/04/15 06:02:50 davem Exp $
* arch/sparc64/kernel/process.c
*
* Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -269,9 +269,8 @@ void __show_regs(struct pt_regs * regs)
unsigned long flags;
spin_lock_irqsave(&regdump_lock, flags);
- printk("CPU[%d]: local_irq_count[%u] global_irq_count[%d]\n",
- smp_processor_id(), local_irq_count,
- atomic_read(&global_irq_count));
+ printk("CPU[%d]: local_irq_count[%u] irqs_running[%d]\n",
+ smp_processor_id(), local_irq_count, irqs_running());
#endif
printk("TSTATE: %016lx TPC: %016lx TNPC: %016lx Y: %08x\n", regs->tstate,
regs->tpc, regs->tnpc, regs->y);
diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c
index c582be060..f061c417f 100644
--- a/arch/sparc64/kernel/ptrace.c
+++ b/arch/sparc64/kernel/ptrace.c
@@ -68,7 +68,7 @@ pt_succ_return_linux(struct pt_regs *regs, unsigned long value, long *addr)
static void
pt_os_succ_return (struct pt_regs *regs, unsigned long val, long *addr)
{
- if (current->personality & PER_BSD)
+ if (current->personality == PER_SUNOS)
pt_succ_return (regs, val);
else
pt_succ_return_linux (regs, val, addr);
@@ -164,8 +164,8 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
goto out;
}
- if (((current->personality & PER_BSD) && (request == PTRACE_SUNATTACH))
- || (!(current->personality & PER_BSD) && (request == PTRACE_ATTACH))) {
+ if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
+ || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
unsigned long flags;
if(child == current) {
@@ -203,9 +203,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
pt_succ_return(regs, 0);
goto out;
}
- if (!(child->flags & PF_PTRACED)
- && ((current->personality & PER_BSD) && (request != PTRACE_SUNATTACH))
- && (!(current->personality & PER_BSD) && (request != PTRACE_ATTACH))) {
+ if (!(child->flags & PF_PTRACED)) {
pt_error_return(regs, ESRCH);
goto out;
}
diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c
index c9a0d4a59..602ee9ca2 100644
--- a/arch/sparc64/kernel/sbus.c
+++ b/arch/sparc64/kernel/sbus.c
@@ -1,4 +1,4 @@
-/* $Id: sbus.c,v 1.10 2000/03/10 07:52:08 davem Exp $
+/* $Id: sbus.c,v 1.11 2000/04/14 09:13:04 davem Exp $
* sbus.c: UltraSparc SBUS controller support.
*
* Copyright (C) 1999 David S. Miller (davem@redhat.com)
@@ -315,7 +315,7 @@ void sbus_free_consistent(struct sbus_dev *sdev, size_t size, void *cpu, dma_add
dma_addr_t sbus_map_single(struct sbus_dev *sdev, void *ptr, size_t size, int dir)
{
struct sbus_iommu *iommu = sdev->bus->iommu;
- unsigned long npages, phys_base, flags;
+ unsigned long npages, pbase, flags;
iopte_t *iopte;
u32 dma_base, offset;
unsigned long iopte_bits;
@@ -323,10 +323,10 @@ dma_addr_t sbus_map_single(struct sbus_dev *sdev, void *ptr, size_t size, int di
if (dir == SBUS_DMA_NONE)
BUG();
- phys_base = (unsigned long) ptr;
- offset = (u32) (phys_base & ~PAGE_MASK);
- size = (PAGE_ALIGN(phys_base + size) - (phys_base & PAGE_MASK));
- phys_base = (unsigned long) __pa(phys_base & PAGE_MASK);
+ pbase = (unsigned long) ptr;
+ offset = (u32) (pbase & ~PAGE_MASK);
+ size = (PAGE_ALIGN(pbase + size) - (pbase & PAGE_MASK));
+ pbase = (unsigned long) __pa(pbase & PAGE_MASK);
spin_lock_irqsave(&iommu->lock, flags);
npages = size >> PAGE_SHIFT;
@@ -337,8 +337,8 @@ dma_addr_t sbus_map_single(struct sbus_dev *sdev, void *ptr, size_t size, int di
if (dir != SBUS_DMA_TODEVICE)
iopte_bits |= IOPTE_WRITE;
while (npages--) {
- *iopte++ = __iopte(iopte_bits | (phys_base & IOPTE_PAGE));
- phys_base += PAGE_SIZE;
+ *iopte++ = __iopte(iopte_bits | (pbase & IOPTE_PAGE));
+ pbase += PAGE_SIZE;
}
npages = size >> PAGE_SHIFT;
spin_unlock_irqrestore(&iommu->lock, flags);
diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c
index e7a50c150..efd6a64d1 100644
--- a/arch/sparc64/kernel/signal.c
+++ b/arch/sparc64/kernel/signal.c
@@ -1,4 +1,4 @@
-/* $Id: signal.c,v 1.48 1999/12/15 22:24:52 davem Exp $
+/* $Id: signal.c,v 1.49 2000/04/08 02:11:46 davem Exp $
* arch/sparc64/kernel/signal.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
index 423c5f648..1f5c03716 100644
--- a/arch/sparc64/kernel/signal32.c
+++ b/arch/sparc64/kernel/signal32.c
@@ -1,4 +1,4 @@
-/* $Id: signal32.c,v 1.60 2000/02/25 06:02:37 jj Exp $
+/* $Id: signal32.c,v 1.62 2000/04/12 08:10:19 davem Exp $
* arch/sparc64/kernel/signal32.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
@@ -750,8 +750,7 @@ static inline void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *reg
goto sigsegv;
if(pte_present(*ptep)) {
- unsigned long page = (unsigned long)
- __va(pte_pagenr(*ptep) << PAGE_SHIFT);
+ unsigned long page = page_address(pte_page(*ptep));
__asm__ __volatile__("
membar #StoreStore
@@ -1176,8 +1175,7 @@ static inline void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs
goto sigsegv;
if(pte_present(*ptep)) {
- unsigned long page = (unsigned long)
- __va(pte_pagenr(*ptep) << PAGE_SHIFT);
+ unsigned long page = page_address(pte_page(*ptep));
__asm__ __volatile__("
membar #StoreStore
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index e9a180d2a..2ef0d1004 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -87,7 +87,6 @@ void __init smp_store_cpu_info(int id)
{
int i;
- cpu_data[id].irq_count = 0;
cpu_data[id].bh_count = 0;
/* multiplier and counter set by
smp_setup_percpu_timer() */
@@ -627,33 +626,7 @@ void smp_promstop_others(void)
smp_cross_call(&xcall_promstop, 0, 0, 0);
}
-static inline void sparc64_do_profile(unsigned long pc, unsigned long o7)
-{
- if (prof_buffer && current->pid) {
- extern int _stext;
- extern int rwlock_impl_begin, rwlock_impl_end;
- extern int atomic_impl_begin, atomic_impl_end;
- extern int __memcpy_begin, __memcpy_end;
- extern int __bitops_begin, __bitops_end;
-
- if ((pc >= (unsigned long) &atomic_impl_begin &&
- pc < (unsigned long) &atomic_impl_end) ||
- (pc >= (unsigned long) &rwlock_impl_begin &&
- pc < (unsigned long) &rwlock_impl_end) ||
- (pc >= (unsigned long) &__memcpy_begin &&
- pc < (unsigned long) &__memcpy_end) ||
- (pc >= (unsigned long) &__bitops_begin &&
- pc < (unsigned long) &__bitops_end))
- pc = o7;
-
- pc -= (unsigned long) &_stext;
- pc >>= prof_shift;
-
- if(pc >= prof_len)
- pc = prof_len - 1;
- atomic_inc((atomic_t *)&prof_buffer[pc]);
- }
-}
+extern void sparc64_do_profile(unsigned long pc, unsigned long o7);
static unsigned long current_tick_offset;
@@ -682,40 +655,29 @@ void smp_percpu_timer_interrupt(struct pt_regs *regs)
clear_softint((1UL << 0));
do {
- if(!user)
+ if (!user)
sparc64_do_profile(regs->tpc, regs->u_regs[UREG_RETPC]);
- if(!--prof_counter(cpu))
- {
+ if (!--prof_counter(cpu)) {
if (cpu == boot_cpu_id) {
-/* XXX Keep this in sync with irq.c --DaveM */
-#define irq_enter(cpu, irq) \
-do { hardirq_enter(cpu); \
- spin_unlock_wait(&global_irq_lock); \
-} while(0)
-#define irq_exit(cpu, irq) hardirq_exit(cpu)
-
irq_enter(cpu, 0);
- kstat.irqs[cpu][0]++;
+ kstat.irqs[cpu][0]++;
timer_tick_interrupt(regs);
irq_exit(cpu, 0);
-
-#undef irq_enter
-#undef irq_exit
}
- if(current->pid) {
+ if (current->pid) {
unsigned int *inc, *inc2;
update_one_process(current, 1, user, !user, cpu);
- if(--current->counter <= 0) {
+ if (--current->counter <= 0) {
current->counter = 0;
current->need_resched = 1;
}
- if(user) {
- if(current->priority < DEF_PRIORITY) {
+ if (user) {
+ if (current->priority < DEF_PRIORITY) {
inc = &kstat.cpu_nice;
inc2 = &kstat.per_cpu_nice[cpu];
} else {
@@ -862,7 +824,7 @@ cycles_t cacheflush_time;
static void __init smp_tune_scheduling (void)
{
- unsigned long flush_base, flags, *p;
+ unsigned long orig_flush_base, flush_base, flags, *p;
unsigned int ecache_size, order;
cycles_t tick1, tick2, raw;
@@ -881,7 +843,8 @@ static void __init smp_tune_scheduling (void)
"ecache-size", (512 * 1024));
if (ecache_size > (4 * 1024 * 1024))
ecache_size = (4 * 1024 * 1024);
- flush_base = __get_free_pages(GFP_KERNEL, order = get_order(ecache_size));
+ orig_flush_base = flush_base =
+ __get_free_pages(GFP_KERNEL, order = get_order(ecache_size));
if (flush_base != 0UL) {
__save_and_cli(flags);
@@ -923,7 +886,7 @@ static void __init smp_tune_scheduling (void)
*/
cacheflush_time = (raw - (raw >> 2));
- free_pages(flush_base, order);
+ free_pages(orig_flush_base, order);
} else {
cacheflush_time = ((ecache_size << 2) +
(ecache_size << 1));
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
index fc7a8cfe5..f68d6ee9e 100644
--- a/arch/sparc64/kernel/sparc64_ksyms.c
+++ b/arch/sparc64/kernel/sparc64_ksyms.c
@@ -1,4 +1,4 @@
-/* $Id: sparc64_ksyms.c,v 1.80 2000/03/27 10:38:47 davem Exp $
+/* $Id: sparc64_ksyms.c,v 1.83 2000/04/19 08:38:25 davem Exp $
* arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support.
*
* Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -81,6 +81,8 @@ extern int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
extern int sys32_ioctl(unsigned int fd, unsigned int cmd, u32 arg);
extern int (*handle_mathemu)(struct pt_regs *, struct fpustate *);
extern long sparc32_open(const char * filename, int flags, int mode);
+extern int register_ioctl32_conversion(unsigned int cmd, int (*handler)(unsigned int, unsigned int, unsigned long, struct file *));
+extern int unregister_ioctl32_conversion(unsigned int cmd);
extern void bcopy (const char *, char *, int);
extern int __ashrdi3(int, int);
@@ -129,8 +131,6 @@ EXPORT_SYMBOL(kernel_flag);
/* Hard IRQ locking */
EXPORT_SYMBOL(global_irq_holder);
-EXPORT_SYMBOL(global_irq_lock);
-EXPORT_SYMBOL(global_irq_count);
EXPORT_SYMBOL(synchronize_irq);
EXPORT_SYMBOL_PRIVATE(global_cli);
EXPORT_SYMBOL_PRIVATE(global_sti);
@@ -219,6 +219,10 @@ EXPORT_SYMBOL(pci_dma_sync_sg);
EXPORT_SYMBOL(pci_dma_supported);
#endif
+/* IOCTL32 emulation hooks. */
+EXPORT_SYMBOL(register_ioctl32_conversion);
+EXPORT_SYMBOL(unregister_ioctl32_conversion);
+
/* Solaris/SunOS binary compatibility */
EXPORT_SYMBOL(_sigpause_common);
@@ -297,8 +301,8 @@ EXPORT_SYMBOL(move_addr_to_user);
/* Special internal versions of library functions. */
EXPORT_SYMBOL(__memcpy);
EXPORT_SYMBOL(__memset);
-EXPORT_SYMBOL(clear_page);
-EXPORT_SYMBOL(copy_page);
+EXPORT_SYMBOL(_clear_page);
+EXPORT_SYMBOL(_copy_page);
EXPORT_SYMBOL(clear_user_page);
EXPORT_SYMBOL(copy_user_page);
EXPORT_SYMBOL(__bzero);
diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c
index 82aedbb08..16edc28f6 100644
--- a/arch/sparc64/kernel/sys_sparc.c
+++ b/arch/sparc64/kernel/sys_sparc.c
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc.c,v 1.37 2000/03/17 05:48:46 anton Exp $
+/* $Id: sys_sparc.c,v 1.38 2000/04/13 07:30:34 jj Exp $
* linux/arch/sparc64/kernel/sys_sparc.c
*
* This file contains various random system calls that
@@ -23,6 +23,7 @@
#include <linux/smp_lock.h>
#include <linux/malloc.h>
#include <linux/ipc.h>
+#include <linux/personality.h>
#include <asm/uaccess.h>
#include <asm/ipc.h>
@@ -182,6 +183,33 @@ out:
return err;
}
+extern asmlinkage int sys_newuname(struct new_utsname * name);
+
+asmlinkage int sparc64_newuname(struct new_utsname * name)
+{
+ int ret = sys_newuname(name);
+
+ if (current->personality == PER_LINUX32 && !ret) {
+ ret = copy_to_user(name->machine, "sparc\0\0", 8);
+ }
+ return ret;
+}
+
+extern asmlinkage long sys_personality(unsigned long);
+
+asmlinkage int sparc64_personality(unsigned long personality)
+{
+ int ret;
+ lock_kernel();
+ if (current->personality == PER_LINUX32 && personality == PER_LINUX)
+ personality = PER_LINUX32;
+ ret = sys_personality(personality);
+ unlock_kernel();
+ if (ret == PER_LINUX32)
+ ret = PER_LINUX;
+ return ret;
+}
+
/* Linux version of mmap */
asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags, unsigned long fd,
@@ -232,7 +260,7 @@ asmlinkage long sys64_munmap(unsigned long addr, size_t len)
(addr < PAGE_OFFSET && addr + len > -PAGE_OFFSET))
return -EINVAL;
down(&current->mm->mmap_sem);
- ret = do_munmap(addr, len);
+ ret = do_munmap(current->mm, addr, len);
up(&current->mm->mmap_sem);
return ret;
}
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
index b1eb160ad..7bb75f4ae 100644
--- a/arch/sparc64/kernel/sys_sparc32.c
+++ b/arch/sparc64/kernel/sys_sparc32.c
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc32.c,v 1.142 2000/03/24 04:17:38 davem Exp $
+/* $Id: sys_sparc32.c,v 1.145 2000/04/13 07:30:34 jj Exp $
* sys_sparc32.c: Conversion between 32bit and 64bit native syscalls.
*
* Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -3542,6 +3542,18 @@ struct nfsctl_fhparm32 {
s32 gf32_version;
};
+struct nfsctl_fdparm32 {
+ struct sockaddr gd32_addr;
+ s8 gd32_path[NFS_MAXPATHLEN+1];
+ s32 gd32_version;
+};
+
+struct nfsctl_fsparm32 {
+ struct sockaddr gd32_addr;
+ s8 gd32_path[NFS_MAXPATHLEN+1];
+ s32 gd32_maxlen;
+};
+
struct nfsctl_arg32 {
s32 ca32_version; /* safeguard */
union {
@@ -3550,15 +3562,17 @@ struct nfsctl_arg32 {
struct nfsctl_export32 u32_export;
struct nfsctl_uidmap32 u32_umap;
struct nfsctl_fhparm32 u32_getfh;
- u32 u32_debug;
+ struct nfsctl_fdparm32 u32_getfd;
+ struct nfsctl_fsparm32 u32_getfs;
} u;
#define ca32_svc u.u32_svc
#define ca32_client u.u32_client
#define ca32_export u.u32_export
#define ca32_umap u.u32_umap
#define ca32_getfh u.u32_getfh
+#define ca32_getfd u.u32_getfd
+#define ca32_getfs u.u32_getfs
#define ca32_authd u.u32_authd
-#define ca32_debug u.u32_debug
};
union nfsctl_res32 {
@@ -3689,6 +3703,38 @@ static int nfs_getfh32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32
return err;
}
+static int nfs_getfd32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
+{
+ int err;
+
+ err = __get_user(karg->ca_version, &arg32->ca32_version);
+ err |= copy_from_user(&karg->ca_getfd.gd_addr,
+ &arg32->ca32_getfd.gd32_addr,
+ (sizeof(struct sockaddr)));
+ err |= copy_from_user(&karg->ca_getfd.gd_path,
+ &arg32->ca32_getfd.gd32_path,
+ (NFS_MAXPATHLEN+1));
+ err |= __get_user(karg->ca_getfd.gd_version,
+ &arg32->ca32_getfd.gd32_version);
+ return err;
+}
+
+static int nfs_getfs32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
+{
+ int err;
+
+ err = __get_user(karg->ca_version, &arg32->ca32_version);
+ err |= copy_from_user(&karg->ca_getfs.gd_addr,
+ &arg32->ca32_getfs.gd32_addr,
+ (sizeof(struct sockaddr)));
+ err |= copy_from_user(&karg->ca_getfs.gd_path,
+ &arg32->ca32_getfs.gd32_path,
+ (NFS_MAXPATHLEN+1));
+ err |= __get_user(karg->ca_getfs.gd_maxlen,
+ &arg32->ca32_getfs.gd32_maxlen);
+ return err;
+}
+
/* This really doesn't need translations, we are only passing
* back a union which contains opaque nfs file handle data.
*/
@@ -3727,6 +3773,7 @@ int asmlinkage sys32_nfsservctl(int cmd, struct nfsctl_arg32 *arg32, union nfsct
err = nfs_clnt32_trans(karg, arg32);
break;
case NFSCTL_EXPORT:
+ case NFSCTL_UNEXPORT:
err = nfs_exp32_trans(karg, arg32);
break;
/* This one is unimplemented, be we're ready for it. */
@@ -3736,6 +3783,12 @@ int asmlinkage sys32_nfsservctl(int cmd, struct nfsctl_arg32 *arg32, union nfsct
case NFSCTL_GETFH:
err = nfs_getfh32_trans(karg, arg32);
break;
+ case NFSCTL_GETFD:
+ err = nfs_getfd32_trans(karg, arg32);
+ break;
+ case NFSCTL_GETFS:
+ err = nfs_getfs32_trans(karg, arg32);
+ break;
default:
err = -EINVAL;
break;
@@ -3747,7 +3800,12 @@ int asmlinkage sys32_nfsservctl(int cmd, struct nfsctl_arg32 *arg32, union nfsct
err = sys_nfsservctl(cmd, karg, kres);
set_fs(oldfs);
- if(!err && cmd == NFSCTL_GETFH)
+ if (err)
+ goto done;
+
+ if((cmd == NFSCTL_GETFH) ||
+ (cmd == NFSCTL_GETFD) ||
+ (cmd == NFSCTL_GETFS))
err = nfs_getfh32_res_trans(kres, res32);
done:
@@ -3922,18 +3980,6 @@ asmlinkage int sys32_prctl(int option, u32 arg2, u32 arg3, u32 arg4, u32 arg5)
}
-extern asmlinkage int sys_newuname(struct new_utsname * name);
-
-asmlinkage int sys32_newuname(struct new_utsname * name)
-{
- int ret = sys_newuname(name);
-
- if (current->personality == PER_LINUX32 && !ret) {
- ret = copy_to_user(name->machine, "sparc\0\0", 8);
- }
- return ret;
-}
-
extern asmlinkage ssize_t sys_pread(unsigned int fd, char * buf,
size_t count, loff_t pos);
@@ -3955,21 +4001,6 @@ asmlinkage ssize_t32 sys32_pwrite(unsigned int fd, char *ubuf,
}
-extern asmlinkage long sys_personality(unsigned long);
-
-asmlinkage int sys32_personality(unsigned long personality)
-{
- int ret;
- lock_kernel();
- if (current->personality == PER_LINUX32 && personality == PER_LINUX)
- personality = PER_LINUX32;
- ret = sys_personality(personality);
- unlock_kernel();
- if (ret == PER_LINUX32)
- ret = PER_LINUX;
- return ret;
-}
-
extern asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
asmlinkage int sys32_sendfile(int out_fd, int in_fd, __kernel_off_t32 *offset, s32 count)
diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c
index 291b174ac..1370d0231 100644
--- a/arch/sparc64/kernel/sys_sunos32.c
+++ b/arch/sparc64/kernel/sys_sunos32.c
@@ -1,4 +1,4 @@
-/* $Id: sys_sunos32.c,v 1.43 2000/03/26 11:28:53 davem Exp $
+/* $Id: sys_sunos32.c,v 1.45 2000/04/13 00:55:49 davem Exp $
* sys_sunos32.c: SunOS binary compatability layer on sparc64.
*
* Copyright (C) 1995, 1996, 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -45,6 +45,7 @@
#include <linux/socket.h>
#include <linux/in.h>
#include <linux/nfs.h>
+#include <linux/nfs2.h>
#include <linux/nfs_mount.h>
/* for sunos_select */
@@ -69,7 +70,6 @@ asmlinkage u32 sunos_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u32 of
down(&current->mm->mmap_sem);
lock_kernel();
- current->personality |= PER_BSD;
if(flags & MAP_NORESERVE) {
static int cnt;
if (cnt++ < 10)
@@ -141,7 +141,7 @@ asmlinkage int sunos_brk(u32 baddr)
/* Always allow shrinking brk. */
if (brk <= current->mm->brk) {
current->mm->brk = brk;
- do_munmap(newbrk, oldbrk-newbrk);
+ do_munmap(current->mm, newbrk, oldbrk-newbrk);
goto out;
}
/* Check against rlimit and stack.. */
@@ -549,7 +549,6 @@ asmlinkage int sunos_select(int width, u32 inp, u32 outp, u32 exp, u32 tvp_x)
/* SunOS binaries expect that select won't change the tvp contents */
lock_kernel();
- current->personality |= STICKY_TIMEOUTS;
ret = sys32_select (width, inp, outp, exp, tvp_x);
if (ret == -EINTR && tvp_x) {
struct timeval32 *tvp = (struct timeval32 *)A(tvp_x);
@@ -685,7 +684,7 @@ static int sunos_nfs_mount(char *dir_name, int linux_flags, void *data)
* address to create a socket and bind it to a reserved
* port on this system
*/
- if (copy_from_user(&sunos_mount, data, sizeof(sunos_mount))
+ if (copy_from_user(&sunos_mount, data, sizeof(sunos_mount)))
return -EFAULT;
server_fd = sys_socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
@@ -776,14 +775,14 @@ sunos_mount(char *type, char *dir, int flags, void *data)
dev_fname = getname(data);
} else if(strcmp(type_page, "nfs") == 0) {
ret = sunos_nfs_mount (dir_page, flags, data);
- goto out2
+ goto out2;
} else if(strcmp(type_page, "ufs") == 0) {
printk("Warning: UFS filesystem mounts unsupported.\n");
ret = -ENODEV;
- goto out2
+ goto out2;
} else if(strcmp(type_page, "proc")) {
ret = -ENODEV;
- goto out2
+ goto out2;
}
ret = PTR_ERR(dev_fname);
if (IS_ERR(dev_fname))
@@ -1214,7 +1213,6 @@ asmlinkage int sunos_open(u32 fname, int flags, int mode)
{
const char *filename = (const char *)(long)fname;
- current->personality |= PER_BSD;
return sparc32_open(filename, flags, mode);
}
@@ -1350,8 +1348,6 @@ asmlinkage int sunos_sigaction (int sig, u32 act, u32 oact)
struct k_sigaction new_ka, old_ka;
int ret;
- current->personality |= PER_BSD;
-
if (act) {
old_sigset_t32 mask;
diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S
index d86649bf7..eb02486f5 100644
--- a/arch/sparc64/kernel/systbls.S
+++ b/arch/sparc64/kernel/systbls.S
@@ -1,4 +1,4 @@
-/* $Id: systbls.S,v 1.71 2000/03/15 02:43:36 davem Exp $
+/* $Id: systbls.S,v 1.72 2000/04/13 07:30:34 jj Exp $
* systbls.S: System call entry point tables for OS compatibility.
* The native Linux system call table lives here also.
*
@@ -56,8 +56,8 @@ sys_call_table32:
/*170*/ .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys32_getdents
.word sys_setsid, sys_fchdir, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
/*180*/ .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys32_sigpending, sys32_query_module
- .word sys_setpgid, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys32_newuname
-/*190*/ .word sys32_init_module, sys32_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
+ .word sys_setpgid, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sparc64_newuname
+/*190*/ .word sys32_init_module, sparc64_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
.word sys_nis_syscall, sys_nis_syscall, sys_getppid, sys32_sigaction, sys_sgetmask
/*200*/ .word sys_ssetmask, sys_sigsuspend, sys32_newlstat, sys_uselib, old32_readdir
.word sys_nis_syscall, sys32_socketcall, sys_syslog, sys_nis_syscall, sys_nis_syscall
@@ -115,8 +115,8 @@ sys_call_table:
/*170*/ .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_getdents
.word sys_setsid, sys_fchdir, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
/*180*/ .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_query_module
- .word sys_setpgid, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_newuname
-/*190*/ .word sys_init_module, sys_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
+ .word sys_setpgid, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sparc64_newuname
+/*190*/ .word sys_init_module, sparc64_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
.word sys_nis_syscall, sys_nis_syscall, sys_getppid, sys_nis_syscall, sys_sgetmask
/*200*/ .word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall
.word sys_nis_syscall, sys_socketcall, sys_syslog, sys_nis_syscall, sys_nis_syscall
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
index e599b48cb..a955e75df 100644
--- a/arch/sparc64/kernel/time.c
+++ b/arch/sparc64/kernel/time.c
@@ -1,4 +1,4 @@
-/* $Id: time.c,v 1.24 2000/03/02 02:00:25 davem Exp $
+/* $Id: time.c,v 1.25 2000/04/13 05:29:44 davem Exp $
* time.c: UltraSparc timer and TOD clock support.
*
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -67,6 +67,34 @@ static __inline__ void timer_check_rtc(void)
}
}
+void sparc64_do_profile(unsigned long pc, unsigned long o7)
+{
+ if (prof_buffer && current->pid) {
+ extern int _stext;
+ extern int rwlock_impl_begin, rwlock_impl_end;
+ extern int atomic_impl_begin, atomic_impl_end;
+ extern int __memcpy_begin, __memcpy_end;
+ extern int __bitops_begin, __bitops_end;
+
+ if ((pc >= (unsigned long) &atomic_impl_begin &&
+ pc < (unsigned long) &atomic_impl_end) ||
+ (pc >= (unsigned long) &rwlock_impl_begin &&
+ pc < (unsigned long) &rwlock_impl_end) ||
+ (pc >= (unsigned long) &__memcpy_begin &&
+ pc < (unsigned long) &__memcpy_end) ||
+ (pc >= (unsigned long) &__bitops_begin &&
+ pc < (unsigned long) &__bitops_end))
+ pc = o7;
+
+ pc -= (unsigned long) &_stext;
+ pc >>= prof_shift;
+
+ if(pc >= prof_len)
+ pc = prof_len - 1;
+ atomic_inc((atomic_t *)&prof_buffer[pc]);
+ }
+}
+
static void timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
{
unsigned long ticks, pstate;
@@ -74,6 +102,10 @@ static void timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
write_lock(&xtime_lock);
do {
+#ifndef __SMP__
+ if ((regs->tstate & TSTATE_PRIV) != 0)
+ sparc64_do_profile(regs->tpc, regs->u_regs[UREG_RETPC]);
+#endif
do_timer(regs);
/* Guarentee that the following sequences execute
diff --git a/arch/sparc64/lib/Makefile b/arch/sparc64/lib/Makefile
index e70e28e52..548ef0ac4 100644
--- a/arch/sparc64/lib/Makefile
+++ b/arch/sparc64/lib/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.21 2000/03/27 10:38:41 davem Exp $
+# $Id: Makefile,v 1.22 2000/03/31 04:06:23 davem Exp $
# Makefile for Sparc library files..
#
diff --git a/arch/sparc64/lib/blockops.S b/arch/sparc64/lib/blockops.S
index 9c6a8beba..9668f86d8 100644
--- a/arch/sparc64/lib/blockops.S
+++ b/arch/sparc64/lib/blockops.S
@@ -1,4 +1,4 @@
-/* $Id: blockops.S,v 1.24 2000/03/27 10:38:41 davem Exp $
+/* $Id: blockops.S,v 1.25 2000/04/13 04:45:58 davem Exp $
* blockops.S: UltraSparc block zero optimized routines.
*
* Copyright (C) 1996, 1998, 1999, 2000 David S. Miller (davem@redhat.com)
@@ -26,9 +26,9 @@
.text
.align 32
- .globl copy_page
- .type copy_page,@function
-copy_page: /* %o0=dest, %o1=src */
+ .globl _copy_page
+ .type _copy_page,@function
+_copy_page: /* %o0=dest, %o1=src */
VISEntry
membar #LoadStore | #StoreStore | #StoreLoad
ldda [%o1] ASI_BLK_P, %f0
@@ -205,9 +205,9 @@ copy_page_using_blkcommit:
stda %f16, [%o0] ASI_BLK_COMMIT_P
.align 32
- .globl clear_page
- .type clear_page,@function
-clear_page: /* %o0=dest */
+ .globl _clear_page
+ .type _clear_page,@function
+_clear_page: /* %o0=dest */
VISEntryHalf
ba,pt %xcc, clear_page_common
clr %o4
diff --git a/arch/sparc64/mm/Makefile b/arch/sparc64/mm/Makefile
index 039195944..36b871af5 100644
--- a/arch/sparc64/mm/Makefile
+++ b/arch/sparc64/mm/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.6 2000/01/31 01:30:49 davem Exp $
+# $Id: Makefile,v 1.7 2000/03/31 04:06:24 davem Exp $
# Makefile for the linux Sparc64-specific parts of the memory manager.
#
# Note! Dependencies are done automagically by 'make dep', which also
diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c
index 0d8152887..37b07d605 100644
--- a/arch/sparc64/mm/fault.c
+++ b/arch/sparc64/mm/fault.c
@@ -1,4 +1,4 @@
-/* $Id: fault.c,v 1.45 2000/03/27 10:38:51 davem Exp $
+/* $Id: fault.c,v 1.47 2000/04/25 04:13:25 davem Exp $
* arch/sparc64/mm/fault.c: Page fault handlers for the 64-bit Sparc.
*
* Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -110,7 +110,8 @@ static unsigned int get_user_insn(unsigned long tpc)
if(!pte_present(pte))
goto out;
- pa = (pte_pagenr(pte) << PAGE_SHIFT) + (tpc & ~PAGE_MASK);
+ pa = phys_base + (pte_pagenr(pte) << PAGE_SHIFT);
+ pa += (tpc & ~PAGE_MASK);
/* Use phys bypass so we don't pollute dtlb/dcache. */
__asm__ __volatile__("lduwa [%1] %2, %0"
@@ -295,7 +296,7 @@ good_area:
}
{
- int fault = handle_mm_fault(current, vma,
+ int fault = handle_mm_fault(mm, vma,
address, (fault_code & FAULT_CODE_WRITE));
if (fault < 0)
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
index 1d2049b5f..bef1c3fac 100644
--- a/arch/sparc64/mm/init.c
+++ b/arch/sparc64/mm/init.c
@@ -1,4 +1,4 @@
-/* $Id: init.c,v 1.149 2000/03/15 14:42:58 jj Exp $
+/* $Id: init.c,v 1.151 2000/04/26 17:09:32 davem Exp $
* arch/sparc64/mm/init.c
*
* Copyright (C) 1996-1999 David S. Miller (davem@caip.rutgers.edu)
@@ -738,22 +738,17 @@ pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long offset)
*/
pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset, unsigned long color)
{
- unsigned long paddr = __get_free_pages(GFP_KERNEL, 1);
+ struct page *page = alloc_pages(GFP_KERNEL, 1);
- if (paddr) {
- struct page *page2 = mem_map + MAP_NR(paddr + PAGE_SIZE);
+ if (page) {
unsigned long *to_free;
+ unsigned long paddr;
pte_t *pte;
- /* Set count of second page, so we can free it
- * seperately later on.
- */
- atomic_set(&page2->count, 1);
-
- /* Clear out both pages now. */
+ set_page_count((page + 1), 1);
+ paddr = page_address(page);
memset((char *)paddr, 0, (PAGE_SIZE << 1));
- /* Determine which page we give to this request. */
if (!color) {
pte = (pte_t *) paddr;
to_free = (unsigned long *) (paddr + PAGE_SIZE);
@@ -804,50 +799,42 @@ void sparc_ultra_dump_dtlb(void)
}
}
-#undef DEBUG_BOOTMEM
-
extern unsigned long cmdline_memory_size;
-unsigned long __init bootmem_init(void)
+unsigned long __init bootmem_init(unsigned long *pages_avail)
{
unsigned long bootmap_size, start_pfn, end_pfn;
unsigned long end_of_phys_memory = 0UL;
- unsigned long bootmap_pfn;
+ unsigned long bootmap_pfn, bytes_avail, size;
int i;
- /* XXX It is a bit ambiguous here, whether we should
- * XXX treat the user specified mem=xxx as total wanted
- * XXX physical memory, or as a limit to the upper
- * XXX physical address we allow. For now it is the
- * XXX latter. -DaveM
- */
-#ifdef DEBUG_BOOTMEM
- prom_printf("bootmem_init: Scan sp_banks, ");
-#endif
+
+ bytes_avail = 0UL;
for (i = 0; sp_banks[i].num_bytes != 0; i++) {
end_of_phys_memory = sp_banks[i].base_addr +
sp_banks[i].num_bytes;
+ bytes_avail += sp_banks[i].num_bytes;
if (cmdline_memory_size) {
- if (end_of_phys_memory > cmdline_memory_size) {
- if (cmdline_memory_size < sp_banks[i].base_addr) {
- end_of_phys_memory =
- sp_banks[i-1].base_addr +
- sp_banks[i-1].num_bytes;
+ if (bytes_avail > cmdline_memory_size) {
+ unsigned long slack = bytes_avail - cmdline_memory_size;
+
+ bytes_avail -= slack;
+ end_of_phys_memory -= slack;
+
+ sp_banks[i].num_bytes -= slack;
+ if (sp_banks[i].num_bytes == 0) {
sp_banks[i].base_addr = 0xdeadbeef;
- sp_banks[i].num_bytes = 0;
} else {
- sp_banks[i].num_bytes -=
- (end_of_phys_memory -
- cmdline_memory_size);
- end_of_phys_memory = cmdline_memory_size;
- sp_banks[++i].base_addr = 0xdeadbeef;
- sp_banks[i].num_bytes = 0;
+ sp_banks[i+1].num_bytes = 0;
+ sp_banks[i+1].base_addr = 0xdeadbeef;
}
break;
}
}
}
+ *pages_avail = bytes_avail >> PAGE_SHIFT;
+
/* Start with page aligned address of last symbol in kernel
* image. The kernel is hard mapped below PAGE_OFFSET in a
* 4MB locked TLB translation.
@@ -886,50 +873,40 @@ unsigned long __init bootmem_init(void)
}
#endif
/* Initialize the boot-time allocator. */
-#ifdef DEBUG_BOOTMEM
- prom_printf("init_bootmem(spfn[%lx],bpfn[%lx],epfn[%lx])\n",
- start_pfn, bootmap_pfn, end_pfn);
-#endif
- bootmap_size = init_bootmem(bootmap_pfn, end_pfn);
+ bootmap_size = init_bootmem_node(0, bootmap_pfn, phys_base>>PAGE_SHIFT, end_pfn);
/* Now register the available physical memory with the
* allocator.
*/
- for (i = 0; sp_banks[i].num_bytes != 0; i++) {
-#ifdef DEBUG_BOOTMEM
- prom_printf("free_bootmem: base[%lx] size[%lx]\n",
- sp_banks[i].base_addr,
- sp_banks[i].num_bytes);
-#endif
+ for (i = 0; sp_banks[i].num_bytes != 0; i++)
free_bootmem(sp_banks[i].base_addr,
sp_banks[i].num_bytes);
- }
- /* Reserve the kernel text/data/bss, the bootmem bootmap and initrd. */
-#ifdef DEBUG_BOOTMEM
-#ifdef CONFIG_BLK_DEV_INITRD
- if (initrd_start)
- prom_printf("reserve_bootmem: base[%lx] size[%lx]\n",
- initrd_start, initrd_end - initrd_start);
-#endif
- prom_printf("reserve_bootmem: base[%lx] size[%lx]\n",
- phys_base, (start_pfn << PAGE_SHIFT) - phys_base);
- prom_printf("reserve_bootmem: base[%lx] size[%lx]\n",
- (bootmap_pfn << PAGE_SHIFT), bootmap_size);
-#endif
#ifdef CONFIG_BLK_DEV_INITRD
if (initrd_start) {
- reserve_bootmem(initrd_start, initrd_end - initrd_start);
+ size = initrd_end - initrd_start;
+
+ /* Resert the initrd image area. */
+ reserve_bootmem(initrd_start, size);
+ *pages_avail -= PAGE_ALIGN(size) >> PAGE_SHIFT;
+
initrd_start += PAGE_OFFSET;
initrd_end += PAGE_OFFSET;
}
#endif
- reserve_bootmem(phys_base, (start_pfn << PAGE_SHIFT) - phys_base);
- reserve_bootmem((bootmap_pfn << PAGE_SHIFT), bootmap_size);
+ /* Reserve the kernel text/data/bss. */
+ size = (start_pfn << PAGE_SHIFT) - phys_base;
+ reserve_bootmem(phys_base, size);
+ *pages_avail -= PAGE_ALIGN(size) >> PAGE_SHIFT;
+
+ /* Reserve the bootmem map. We do not account for it
+ * in pages_avail because we will release that memory
+ * in free_all_bootmem.
+ */
+ size = bootmap_size;
+ reserve_bootmem((bootmap_pfn << PAGE_SHIFT), size);
+ *pages_avail -= PAGE_ALIGN(size) >> PAGE_SHIFT;
-#ifdef DEBUG_BOOTMEM
- prom_printf("init_bootmem: return end_pfn[%lx]\n", end_pfn);
-#endif
return end_pfn;
}
@@ -946,7 +923,7 @@ void __init paging_init(void)
extern unsigned int sparc64_vpte_patchme2[1];
unsigned long alias_base = phys_base + PAGE_OFFSET;
unsigned long second_alias_page = 0;
- unsigned long pt, flags, end_pfn;
+ unsigned long pt, flags, end_pfn, pages_avail;
unsigned long shift = alias_base - ((unsigned long)&empty_zero_page);
set_bit(0, mmu_context_bmap);
@@ -1001,7 +978,8 @@ void __init paging_init(void)
flushi((long)&sparc64_vpte_patchme1[0]);
/* Setup bootmem... */
- last_valid_pfn = end_pfn = bootmem_init();
+ pages_avail = 0;
+ last_valid_pfn = end_pfn = bootmem_init(&pages_avail);
#ifdef CONFIG_SUN_SERIAL
/* This does not logically belong here, but we need to
@@ -1039,10 +1017,20 @@ void __init paging_init(void)
flush_tlb_all();
{
- unsigned long zones_size[MAX_NR_ZONES] = { 0, 0, 0};
+ unsigned long zones_size[MAX_NR_ZONES];
+ unsigned long zholes_size[MAX_NR_ZONES];
+ unsigned long npages;
+ int znum;
- zones_size[ZONE_DMA] = end_pfn;
- free_area_init(zones_size);
+ for (znum = 0; znum < MAX_NR_ZONES; znum++)
+ zones_size[znum] = zholes_size[znum] = 0;
+
+ npages = end_pfn - (phys_base >> PAGE_SHIFT);
+ zones_size[ZONE_DMA] = npages;
+ zholes_size[ZONE_DMA] = npages - pages_avail;
+
+ free_area_init_node(0, NULL, zones_size,
+ phys_base, zholes_size);
}
device_scan();
@@ -1139,9 +1127,6 @@ static void __init taint_real_pages(void)
struct sparc_phys_banks saved_sp_banks[SPARC_PHYS_BANKS];
int i;
-#ifdef DEBUG_BOOTMEM
- prom_printf("taint_real_pages: Rescan sp_banks[].\n");
-#endif
for (i = 0; i < SPARC_PHYS_BANKS; i++) {
saved_sp_banks[i].base_addr =
sp_banks[i].base_addr;
@@ -1176,10 +1161,6 @@ static void __init taint_real_pages(void)
goto do_next_page;
}
}
-#ifdef DEBUG_BOOTMEM
- prom_printf("taint: Page went away, reserve page %lx.\n",
- old_start);
-#endif
reserve_bootmem(old_start, PAGE_SIZE);
do_next_page:
@@ -1188,70 +1169,6 @@ static void __init taint_real_pages(void)
}
}
-void __init free_mem_map_range(struct page *first, struct page *last)
-{
- first = (struct page *) PAGE_ALIGN((unsigned long)first);
- last = (struct page *) ((unsigned long)last & PAGE_MASK);
-#ifdef DEBUG_BOOTMEM
- prom_printf("[%p,%p] ", first, last);
-#endif
- while (first < last) {
- ClearPageReserved(mem_map + MAP_NR(first));
- set_page_count(mem_map + MAP_NR(first), 1);
- free_page((unsigned long)first);
- num_physpages++;
-
- first = (struct page *)((unsigned long)first + PAGE_SIZE);
- }
-}
-
-/* Walk through holes in sp_banks regions, if the mem_map array
- * areas representing those holes consume a page or more, free
- * up such pages. This helps a lot on machines where physical
- * ram is configured such that it begins at some hugh value.
- *
- * The sp_banks array is sorted by base address.
- */
-void __init free_unused_mem_map(void)
-{
- int i;
-
-#ifdef DEBUG_BOOTMEM
- prom_printf("free_unused_mem_map: ");
-#endif
- for (i = 0; sp_banks[i].num_bytes; i++) {
- if (i == 0) {
- struct page *first, *last;
-
- first = mem_map;
- last = &mem_map[sp_banks[i].base_addr >> PAGE_SHIFT];
- free_mem_map_range(first, last);
- } else {
- struct page *first, *last;
- unsigned long prev_end;
-
- prev_end = sp_banks[i-1].base_addr +
- sp_banks[i-1].num_bytes;
- prev_end = PAGE_ALIGN(prev_end);
- first = &mem_map[prev_end >> PAGE_SHIFT];
- last = &mem_map[sp_banks[i].base_addr >> PAGE_SHIFT];
-
- free_mem_map_range(first, last);
-
- if (!sp_banks[i+1].num_bytes) {
- prev_end = sp_banks[i].base_addr +
- sp_banks[i].num_bytes;
- first = &mem_map[prev_end >> PAGE_SHIFT];
- last = &mem_map[last_valid_pfn];
- free_mem_map_range(first, last);
- }
- }
- }
-#ifdef DEBUG_BOOTMEM
- prom_printf("\n");
-#endif
-}
-
void __init mem_init(void)
{
unsigned long codepages, datapages, initpages;
@@ -1279,16 +1196,10 @@ void __init mem_init(void)
taint_real_pages();
- max_mapnr = last_valid_pfn;
+ max_mapnr = last_valid_pfn - (phys_base >> PAGE_SHIFT);
high_memory = __va(last_valid_pfn << PAGE_SHIFT);
-#ifdef DEBUG_BOOTMEM
- prom_printf("mem_init: Calling free_all_bootmem().\n");
-#endif
num_physpages = free_all_bootmem();
-#if 0
- free_unused_mem_map();
-#endif
codepages = (((unsigned long) &etext) - ((unsigned long)&_start));
codepages = PAGE_ALIGN(codepages) >> PAGE_SHIFT;
datapages = (((unsigned long) &edata) - ((unsigned long)&etext));
@@ -1317,19 +1228,6 @@ void __init mem_init(void)
datapages << (PAGE_SHIFT-10),
initpages << (PAGE_SHIFT-10),
PAGE_OFFSET, (last_valid_pfn << PAGE_SHIFT));
-
- /* NOTE NOTE NOTE NOTE
- * Please keep track of things and make sure this
- * always matches the code in mm/page_alloc.c -DaveM
- */
- i = nr_free_pages() >> 7;
- if (i < 48)
- i = 48;
- if (i > 256)
- i = 256;
- freepages.min = i;
- freepages.low = i << 1;
- freepages.high = freepages.low + i;
}
void free_initmem (void)
diff --git a/arch/sparc64/prom/Makefile b/arch/sparc64/prom/Makefile
index 88ca5251b..04471ab85 100644
--- a/arch/sparc64/prom/Makefile
+++ b/arch/sparc64/prom/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.5 1999/12/21 04:02:26 davem Exp $
+# $Id: Makefile,v 1.6 2000/03/31 04:06:25 davem Exp $
# Makefile for the Sun Boot PROM interface library under
# Linux.
#
diff --git a/arch/sparc64/prom/misc.c b/arch/sparc64/prom/misc.c
index 8d6404fea..50b287080 100644
--- a/arch/sparc64/prom/misc.c
+++ b/arch/sparc64/prom/misc.c
@@ -1,4 +1,4 @@
-/* $Id: misc.c,v 1.16 1999/11/19 05:53:04 davem Exp $
+/* $Id: misc.c,v 1.17 2000/04/15 06:02:50 davem Exp $
* misc.c: Miscellaneous prom functions that don't belong
* anywhere else.
*
@@ -64,7 +64,7 @@ prom_cmdline(void)
* on SMP, we need to drop the IRQ locks we hold.
*/
#ifdef __SMP__
- hardirq_exit(smp_processor_id());
+ irq_exit(smp_processor_id(), 0);
smp_capture();
#else
local_irq_count--;
@@ -74,8 +74,8 @@ prom_cmdline(void)
#ifdef __SMP__
smp_release();
- hardirq_enter(smp_processor_id());
- spin_unlock_wait(&global_irq_lock);
+ irq_enter(smp_processor_id(), 0);
+ spin_unlock_wait(&__br_write_locks[BR_GLOBALIRQ_LOCK].lock);
#else
local_irq_count++;
#endif
diff --git a/arch/sparc64/solaris/fs.c b/arch/sparc64/solaris/fs.c
index 2c17d664d..57e50cd8d 100644
--- a/arch/sparc64/solaris/fs.c
+++ b/arch/sparc64/solaris/fs.c
@@ -1,4 +1,4 @@
-/* $Id: fs.c,v 1.17 2000/03/10 04:43:30 davem Exp $
+/* $Id: fs.c,v 1.18 2000/04/08 02:11:54 davem Exp $
* fs.c: fs related syscall emulation for Solaris
*
* Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -506,7 +506,7 @@ asmlinkage int solaris_fstatvfs(unsigned int fd, u32 buf)
unlock_kernel();
fput(file);
}
-out:
+
return error;
}
diff --git a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c
index c9341b0fd..ef4c9aa01 100644
--- a/arch/sparc64/solaris/misc.c
+++ b/arch/sparc64/solaris/misc.c
@@ -1,4 +1,4 @@
-/* $Id: misc.c,v 1.23 2000/03/13 21:57:34 davem Exp $
+/* $Id: misc.c,v 1.26 2000/04/14 09:59:02 davem Exp $
* misc.c: Miscelaneous syscall emulation for Solaris
*
* Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -54,7 +54,8 @@ static u32 do_solaris_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u64 o
unsigned long retval, ret_type;
lock_kernel();
- current->personality |= PER_SVR4;
+ /* Do we need it here? */
+ set_personality(PER_SVR4);
if (flags & MAP_NORESERVE) {
static int cnt = 0;
@@ -719,11 +720,7 @@ asmlinkage int do_sol_unimplemented(struct pt_regs *regs)
asmlinkage void solaris_register(void)
{
- lock_kernel();
- current->personality = PER_SVR4;
- put_exec_domain(current->exec_domain);
- current->exec_domain = lookup_exec_domain(current->personality);
- unlock_kernel();
+ set_personality(PER_SVR4);
}
extern long solaris_to_linux_signals[], linux_to_solaris_signals[];