summaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r--arch/arm/kernel/Makefile15
-rw-r--r--arch/arm/kernel/armksyms.c34
-rw-r--r--arch/arm/kernel/bios32.c351
-rw-r--r--arch/arm/kernel/calls.S10
-rw-r--r--arch/arm/kernel/dec21285.c17
-rw-r--r--arch/arm/kernel/dma-a5k.c2
-rw-r--r--arch/arm/kernel/dma-arc.c10
-rw-r--r--arch/arm/kernel/dma-dummy.c5
-rw-r--r--arch/arm/kernel/dma-footbridge.c2
-rw-r--r--arch/arm/kernel/dma-isa.c8
-rw-r--r--arch/arm/kernel/dma-rpc.c2
-rw-r--r--arch/arm/kernel/dma.c4
-rw-r--r--arch/arm/kernel/ecard.c57
-rw-r--r--arch/arm/kernel/entry-armo.S9
-rw-r--r--arch/arm/kernel/entry-armv.S36
-rw-r--r--arch/arm/kernel/entry-common.S29
-rw-r--r--arch/arm/kernel/fiq.c9
-rw-r--r--arch/arm/kernel/head-armv.S30
-rw-r--r--arch/arm/kernel/hw-footbridge.c91
-rw-r--r--arch/arm/kernel/init_task.c1
-rw-r--r--arch/arm/kernel/ioport.c27
-rw-r--r--arch/arm/kernel/irq.c2
-rw-r--r--arch/arm/kernel/isa.c47
-rw-r--r--arch/arm/kernel/leds-footbridge.c12
-rw-r--r--arch/arm/kernel/process.c31
-rw-r--r--arch/arm/kernel/ptrace.c317
-rw-r--r--arch/arm/kernel/semaphore.c202
-rw-r--r--arch/arm/kernel/setup.c151
-rw-r--r--arch/arm/kernel/signal.c10
-rw-r--r--arch/arm/kernel/time.c21
-rw-r--r--arch/arm/kernel/traps.c26
31 files changed, 1097 insertions, 471 deletions
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 5bcc22af1..557aa6fc5 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -9,8 +9,8 @@ HEAD_OBJ = head-$(PROCESSOR).o
ENTRY_OBJ = entry-$(PROCESSOR).o
O_TARGET := kernel.o
-O_OBJS := $(ENTRY_OBJ) irq.o process.o ptrace.o setup.o \
- signal.o sys_arm.o time.o traps.o
+O_OBJS := $(ENTRY_OBJ) ioport.o irq.o process.o ptrace.o \
+ semaphore.o setup.o signal.o sys_arm.o time.o traps.o
ifeq ($(CONFIG_ISA_DMA),y)
ISA_DMA_OBJS += dma-isa.o
@@ -20,7 +20,7 @@ O_OBJS_arc = dma-arc.o iic.o fiq.o oldlatches.o
O_OBJS_a5k = dma-a5k.o iic.o fiq.o
O_OBJS_rpc = dma-rpc.o iic.o fiq.o
O_OBJS_ebsa110 = dma-dummy.o
-O_OBJS_footbridge = dma-footbridge.o $(ISA_DMA_OBJS)
+O_OBJS_footbridge = dma-footbridge.o $(ISA_DMA_OBJS) isa.o
O_OBJS_nexuspci = dma-dummy.o
OX_OBJS_arc = dma.o
@@ -30,7 +30,7 @@ OX_OBJS_ebsa110 =
OX_OBJS_footbridge= dma.o hw-footbridge.o
OX_OBJS_nexuspci =
-all: lib kernel.o $(HEAD_OBJ) init_task.o
+all: kernel.o $(HEAD_OBJ) init_task.o
O_OBJS += $(O_OBJS_$(MACHINE))
@@ -48,7 +48,7 @@ ifeq ($(MACHINE),nexuspci)
endif
else
ifdef CONFIG_PCI
- O_OBJS += dec21285.o
+ O_OBJS += bios32.o dec21285.o
endif
endif
@@ -80,11 +80,6 @@ include $(TOPDIR)/Rules.make
$(ENTRY_OBJ): ../lib/constants.h
-.PHONY: lib
-
-lib:
- $(MAKE) -C ../lib constants.h
-
# Spell out some dependencies that `make dep' doesn't spot
entry-armv.o: calls.S
entry-armo.o: calls.S
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index c93421ba7..0905d55b5 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -12,6 +12,7 @@
#include <asm/io.h>
#include <asm/dma.h>
#include <asm/pgtable.h>
+#include <asm/proc-fns.h>
#include <asm/semaphore.h>
#include <asm/system.h>
#include <asm/uaccess.h>
@@ -25,9 +26,6 @@ extern void outswb(unsigned int port, const void *to, int len);
extern unsigned int local_bh_count[NR_CPUS];
extern unsigned int local_irq_count[NR_CPUS];
-extern void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags);
-extern void iounmap(void *addr);
-
extern pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
/*
@@ -36,7 +34,6 @@ extern pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
extern int sys_write(int, const char *, int);
extern int sys_read(int, char *, int);
extern int sys_lseek(int, off_t, int);
-extern int sys_open(const char *, int, int);
extern int sys_exit(int);
extern int sys_wait4(int, int *, int, struct rusage *);
@@ -93,7 +90,7 @@ EXPORT_SYMBOL(local_bh_count);
EXPORT_SYMBOL(local_irq_count);
#ifdef CONFIG_CPU_32
EXPORT_SYMBOL(__ioremap);
-EXPORT_SYMBOL(iounmap);
+EXPORT_SYMBOL(__iounmap);
#endif
EXPORT_SYMBOL(kernel_thread);
@@ -101,11 +98,28 @@ EXPORT_SYMBOL(enable_irq);
EXPORT_SYMBOL(disable_irq);
/* processor dependencies */
+#ifdef MULTI_CPU
EXPORT_SYMBOL(processor);
+#else
+EXPORT_SYMBOL(cpu_flush_cache_all);
+EXPORT_SYMBOL(cpu_flush_cache_area);
+EXPORT_SYMBOL(cpu_flush_cache_entry);
+EXPORT_SYMBOL(cpu_clean_cache_area);
+EXPORT_SYMBOL(cpu_flush_ram_page);
+EXPORT_SYMBOL(cpu_flush_tlb_all);
+EXPORT_SYMBOL(cpu_flush_tlb_area);
+EXPORT_SYMBOL(cpu_switch_mm);
+EXPORT_SYMBOL(cpu_set_pmd);
+EXPORT_SYMBOL(cpu_set_pte);
+EXPORT_SYMBOL(cpu_flush_icache_area);
+EXPORT_SYMBOL(cpu_cache_wback_area);
+EXPORT_SYMBOL(cpu_cache_purge_area);
+#endif
EXPORT_SYMBOL(__machine_arch_type);
/* networking */
EXPORT_SYMBOL(csum_partial_copy);
+EXPORT_SYMBOL(csum_partial_copy_nocheck);
EXPORT_SYMBOL(__csum_ipv6_magic);
/* io */
@@ -116,10 +130,6 @@ EXPORT_SYMBOL(insb);
EXPORT_SYMBOL(insw);
EXPORT_SYMBOL(insl);
-EXPORT_SYMBOL(_memcpy_fromio);
-EXPORT_SYMBOL(_memcpy_toio);
-EXPORT_SYMBOL(_memset_io);
-
/* address translation */
#ifndef __virt_to_phys__is_a_macro
EXPORT_SYMBOL(__virt_to_phys);
@@ -154,6 +164,7 @@ EXPORT_SYMBOL_NOVERS(strspn);
EXPORT_SYMBOL_NOVERS(strpbrk);
EXPORT_SYMBOL_NOVERS(strtok);
EXPORT_SYMBOL_NOVERS(strrchr);
+EXPORT_SYMBOL_NOVERS(strstr);
EXPORT_SYMBOL_NOVERS(memset);
EXPORT_SYMBOL_NOVERS(memcpy);
EXPORT_SYMBOL_NOVERS(memmove);
@@ -202,9 +213,8 @@ EXPORT_SYMBOL(find_first_zero_bit);
EXPORT_SYMBOL(find_next_zero_bit);
/* elf */
-EXPORT_SYMBOL(armidlist);
-EXPORT_SYMBOL(armidindex);
EXPORT_SYMBOL(elf_platform);
+EXPORT_SYMBOL(elf_hwcap);
/* syscalls */
EXPORT_SYMBOL(sys_write);
@@ -217,5 +227,5 @@ EXPORT_SYMBOL(sys_wait4);
/* semaphores */
EXPORT_SYMBOL_NOVERS(__down_failed);
EXPORT_SYMBOL_NOVERS(__down_interruptible_failed);
+EXPORT_SYMBOL_NOVERS(__down_trylock_failed);
EXPORT_SYMBOL_NOVERS(__up_wakeup);
-
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
new file mode 100644
index 000000000..35bb0a36a
--- /dev/null
+++ b/arch/arm/kernel/bios32.c
@@ -0,0 +1,351 @@
+/*
+ * arch/arm/kernel/bios32.c
+ *
+ * PCI bios-type initialisation for PCI machines
+ *
+ * Bits taken from various places.
+ */
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/irq.h>
+#include <asm/system.h>
+
+int have_isa_bridge;
+
+int (*pci_irq_fixup)(struct pci_dev *dev);
+
+extern struct pci_ops *dc21285_init(int pass);
+extern void pcibios_fixup_ebsa285(struct pci_dev *dev);
+extern void hw_init(void);
+
+void
+pcibios_report_device_errors(void)
+{
+ struct pci_dev *dev;
+
+ for (dev = pci_devices; dev; dev = dev->next) {
+ u16 status;
+
+ pci_read_config_word(dev, PCI_STATUS, &status);
+
+ if (status & 0xf900) {
+ pci_write_config_word(dev, PCI_STATUS, status & 0xf900);
+ printk(KERN_DEBUG "PCI: %02x:%02x status = %X\n",
+ dev->bus->number, dev->devfn, status);
+ }
+ }
+}
+
+/*
+ * We don't use this to fix the device, but more our initialisation.
+ * It's not the correct use for this, but it works. The actions we
+ * take are:
+ * - enable only IO
+ * - set memory region to start at zero
+ * - (0x48) enable all memory requests from ISA to be channeled to PCI
+ * - (0x42) disable ping-pong (as per errata)
+ * - (0x40) enable PCI packet retry
+ * - (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)
+{
+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, PCI_BASE_ADDRESS_SPACE_MEMORY);
+ pci_write_config_word(dev, PCI_COMMAND, PCI_COMMAND_IO);
+
+ dev->resource[0].end -= dev->resource[0].start;
+ dev->resource[0].start = 0;
+
+ pci_write_config_byte(dev, 0x48, 0xff);
+ pci_write_config_byte(dev, 0x42, 0x00);
+ pci_write_config_byte(dev, 0x40, 0x22);
+ pci_write_config_byte(dev, 0x83, 0x02);
+ pci_write_config_byte(dev, 0x80, 0xe0);
+ pci_write_config_byte(dev, 0x81, 0x01);
+}
+
+struct pci_fixup pcibios_fixups[] = {
+ { PCI_FIXUP_HEADER, PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_83C553, pci_fixup_83c553 },
+ { 0 }
+};
+
+/*
+ * Assign an address to an I/O range.
+ */
+static void __init pcibios_fixup_io_addr(struct pci_dev *dev, struct resource *r, int idx)
+{
+ unsigned int reg = PCI_BASE_ADDRESS_0 + (idx << 2);
+ unsigned int size = r->end - r->start + 1;
+ u32 try;
+
+ /*
+ * We need to avoid collisions with `mirrored' VGA ports and other strange
+ * ISA hardware, so we always want the addresses kilobyte aligned.
+ */
+ if (!size || size > 256) {
+ printk(KERN_ERR "PCI: Cannot assign I/O space to %s, "
+ "%d bytes are too much.\n", dev->name, size);
+ return;
+ }
+
+ if (allocate_resource(&ioport_resource, r, size, 0x9000, ~0, 1024)) {
+ printk(KERN_ERR "PCI: Unable to find free %d bytes of I/O "
+ "space for %s.\n", size, dev->name);
+ return;
+ }
+
+ printk("PCI: Assigning I/O space %04lx-%04lx to %s\n",
+ r->start, r->end, dev->name);
+
+ pci_write_config_dword(dev, reg, r->start | PCI_BASE_ADDRESS_SPACE_IO);
+ pci_read_config_dword(dev, reg, &try);
+
+ if ((try & PCI_BASE_ADDRESS_IO_MASK) != r->start) {
+ r->start = 0;
+ pci_write_config_dword(dev, reg, 0);
+ printk(KERN_ERR "PCI: I/O address setup failed, got %04x\n", try);
+ }
+}
+
+/*
+ * Assign an address to an memory range.
+ */
+static void __init pcibios_fixup_mem_addr(struct pci_dev *dev, struct resource *r, int idx)
+{
+ unsigned int reg = PCI_BASE_ADDRESS_0 + (idx << 2);
+ unsigned int size = r->end - r->start + 1;
+ u32 try;
+
+ if (!size) {
+ printk(KERN_ERR "PCI: Cannot assign memory space to %s, "
+ "%d bytes are too much.\n", dev->name, size);
+ return;
+ }
+
+ if (allocate_resource(&iomem_resource, r, size,
+ 0x00100000, 0x0fffffff, 1024)) {
+ printk(KERN_ERR "PCI: Unable to find free %d bytes of memory "
+ "space for %s.\n", size, dev->name);
+ return;
+ }
+
+ printk("PCI: Assigning memory space %08lx-%08lx to %s\n",
+ r->start, r->end, dev->name);
+
+ pci_write_config_dword(dev, reg, r->start);
+ pci_read_config_dword(dev, reg, &try);
+
+ if (try != r->start) {
+ r->start = 0;
+ pci_write_config_dword(dev, reg, 0);
+ printk(KERN_ERR "PCI: memory address setup failed, "
+ "got %08x\n", try);
+ }
+}
+
+#define _PCI_REGION_IO 1
+#define _PCI_REGION_MEM 2
+
+/*
+ * Fix up one PCI devices regions, enables and interrupt lines
+ */
+static void __init pcibios_fixup_device(struct pci_dev *dev, u16 *cmd)
+{
+ int i, has_regions = 0;
+
+ /*
+ * Fix up the regions. Any regions which aren't allocated
+ * are given a free region.
+ */
+ for (i = 0; i < 6; i++) {
+ struct resource *r = dev->resource + i;
+
+ if (r->flags & IORESOURCE_IO) {
+ has_regions |= _PCI_REGION_IO;
+
+ if (!r->start || r->end == 0xffffffff)
+ pcibios_fixup_io_addr(dev, r, i);
+ } else if (r->end) {
+ has_regions |= _PCI_REGION_MEM;
+
+ if (!r->start)
+ pcibios_fixup_mem_addr(dev, r, i);
+ }
+ }
+
+ switch (dev->class >> 8) {
+ case PCI_CLASS_BRIDGE_ISA:
+ case PCI_CLASS_BRIDGE_EISA:
+ /*
+ * If this device is an ISA bridge, set the have_isa_bridge
+ * flag. We will then go looking for things like keyboard,
+ * etc
+ */
+ have_isa_bridge = !0;
+ /* FALL THROUGH */
+
+ default:
+ /*
+ * Don't enable VGA-compatible cards since they have
+ * fixed I/O and memory space.
+ *
+ * Don't enabled disabled IDE interfaces either because
+ * some BIOSes may reallocate the same address when they
+ * find that no devices are attached.
+ */
+ if (has_regions & _PCI_REGION_IO &&
+ !((*cmd) & PCI_COMMAND_IO)) {
+ printk("PCI: Enabling I/O for %s\n", dev->name);
+ *cmd |= PCI_COMMAND_IO;
+ }
+
+ if (has_regions & _PCI_REGION_MEM &&
+ !((*cmd) & PCI_COMMAND_MEMORY)) {
+ printk("PCI: Enabling memory for %s\n", dev->name);
+ *cmd |= PCI_COMMAND_MEMORY;
+ }
+ }
+}
+
+/*
+ * Fix base addresses, I/O and memory enables and IRQ's
+ */
+static void __init pcibios_fixup_devices(void)
+{
+ struct pci_dev *dev;
+
+ for (dev = pci_devices; dev; dev = dev->next) {
+ u16 cmd;
+
+ /*
+ * architecture specific hacks.
+ * I don't really want this here,
+ * but I don't see any other place
+ * for it to live.
+ */
+ if (machine_is_netwinder() &&
+ dev->vendor == PCI_VENDOR_ID_DEC &&
+ dev->device == PCI_DEVICE_ID_DEC_21142)
+ /* Put the chip to sleep in case the driver isn't loaded */
+ pci_write_config_dword(dev, 0x40, 0x80000000);
+
+ /*
+ * Set latency timer to 32, and a cache line size to 32 bytes.
+ * Also, set system error enable, parity error enable, and
+ * fast back to back transaction enable. Disable ROM.
+ */
+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 32);
+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 8);
+ pci_write_config_dword(dev, PCI_ROM_ADDRESS, 0);
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
+
+ cmd |= PCI_COMMAND_FAST_BACK | PCI_COMMAND_SERR |
+ PCI_COMMAND_PARITY;
+
+ pcibios_fixup_device(dev, &cmd);
+
+ pci_write_config_word(dev, PCI_COMMAND, cmd);
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
+
+ /*
+ * now fixup the IRQs, if required
+ */
+ if (pci_irq_fixup)
+ dev->irq = pci_irq_fixup(dev);
+
+ /*
+ * If any remaining IRQs are weird, fix it now.
+ */
+ if (dev->irq >= NR_IRQS)
+ dev->irq = 0;
+
+ /*
+ * catch any drivers still reading this from the
+ * device itself. This can be removed once
+ * all drivers are fixed. (are there any?)
+ */
+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+ }
+}
+
+/*
+ * Allocate resources for all PCI devices that have been enabled.
+ * We need to do that before we try to fix up anything.
+ */
+static void __init pcibios_claim_resources(void)
+{
+ struct pci_dev *dev;
+ int idx;
+
+ for (dev = pci_devices; dev; dev = dev->next)
+ for (idx = 0; idx < PCI_NUM_RESOURCES; idx++) {
+ struct resource *a, *r = &dev->resource[idx];
+
+ /*
+ * Ignore regions that start at 0 or
+ * end at 0xffffffff
+ */
+ if (!r->start || r->end == 0xffffffff)
+ continue;
+
+ if (r->flags & IORESOURCE_IO)
+ a = &ioport_resource;
+ else
+ a = &iomem_resource;
+
+ if (request_resource(a, r) < 0)
+ printk(KERN_ERR "PCI: Address space collision "
+ "on region %d of %s\n",
+ idx, dev->name);
+ /* We probably should disable the region,
+ * shouldn't we?
+ */
+ }
+}
+
+/*
+ * Called after each bus is probed, but before its children
+ * are examined.
+ *
+ * No fixup of bus required
+ */
+void __init pcibios_fixup_bus(struct pci_bus *bus)
+{
+}
+
+void __init pcibios_init(void)
+{
+ struct pci_ops *ops;
+
+ /*
+ * Pre-initialisation. Set up the host bridge.
+ */
+ ops = dc21285_init(0);
+
+ printk("PCI: Probing PCI hardware\n");
+
+ pci_scan_bus(0, ops, NULL);
+ pcibios_claim_resources();
+ pcibios_fixup_devices();
+
+ /*
+ * Now clear down any PCI error IRQs and
+ * register the error handler
+ */
+ dc21285_init(1);
+
+ /*
+ * Initialise any other hardware after we've
+ * got the PCI bus initialised. We may need
+ * the PCI bus to talk to this other hardware.
+ */
+ hw_init();
+}
+
+char * __init pcibios_setup(char *str)
+{
+ return str;
+}
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index 154e3aeab..c95eeb1b0 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -119,9 +119,9 @@
.long SYMBOL_NAME(sys_newlstat)
.long SYMBOL_NAME(sys_newfstat)
.long SYMBOL_NAME(sys_uname)
-/* 110 */ .long SYMBOL_NAME(sys_ni_syscall)
+/* 110 */ .long SYMBOL_NAME(sys_iopl)
.long SYMBOL_NAME(sys_vhangup)
- .long SYMBOL_NAME(sys_idle)
+ .long SYMBOL_NAME(sys_ni_syscall)
.long SYMBOL_NAME(sys_syscall) /* call a syscall */
.long SYMBOL_NAME(sys_wait4)
/* 115 */ .long SYMBOL_NAME(sys_swapoff)
@@ -129,7 +129,7 @@
.long SYMBOL_NAME(sys_ipc)
.long SYMBOL_NAME(sys_fsync)
.long SYMBOL_NAME(sys_sigreturn_wrapper)
- .long SYMBOL_NAME(sys_clone_wapper)
+/* 120 */ .long SYMBOL_NAME(sys_clone_wapper)
.long SYMBOL_NAME(sys_setdomainname)
.long SYMBOL_NAME(sys_newuname)
.long SYMBOL_NAME(sys_ni_syscall) /* .long SYMBOL_NAME(sys_modify_ldt) */
@@ -157,8 +157,8 @@
/* 145 */ .long SYMBOL_NAME(sys_readv)
.long SYMBOL_NAME(sys_writev)
.long SYMBOL_NAME(sys_getsid)
- .long SYMBOL_NAME(sys_ni_syscall)
- .long SYMBOL_NAME(sys_ni_syscall)
+ .long SYMBOL_NAME(sys_fdatasync)
+ .long SYMBOL_NAME(sys_sysctl)
/* 150 */ .long SYMBOL_NAME(sys_mlock)
.long SYMBOL_NAME(sys_munlock)
.long SYMBOL_NAME(sys_mlockall)
diff --git a/arch/arm/kernel/dec21285.c b/arch/arm/kernel/dec21285.c
index 80cef0b23..6a4988b15 100644
--- a/arch/arm/kernel/dec21285.c
+++ b/arch/arm/kernel/dec21285.c
@@ -1,7 +1,7 @@
/*
- * arch/arm/kernel/dec21285.c: PCI functions for DEC 21285
+ * arch/arm/kernel/dec21285.c: PCI functions for DC21285
*
- * Copyright (C) 1998 Russell King, Phil Blundell
+ * Copyright (C) 1998-1999 Russell King, Phil Blundell
*/
#include <linux/config.h>
#include <linux/sched.h>
@@ -11,6 +11,7 @@
#include <linux/interrupt.h>
#include <linux/mm.h>
#include <linux/init.h>
+#include <linux/ioport.h>
#include <asm/irq.h>
#include <asm/system.h>
@@ -129,7 +130,7 @@ pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn,
return PCIBIOS_SUCCESSFUL;
}
-__initfunc(void pci_set_cmd(struct pci_dev *dev, unsigned short clear, unsigned short set))
+void __init pci_set_cmd(struct pci_dev *dev, unsigned short clear, unsigned short set)
{
unsigned short cmd;
@@ -138,7 +139,7 @@ __initfunc(void pci_set_cmd(struct pci_dev *dev, unsigned short clear, unsigned
pci_write_config_word(dev, PCI_COMMAND, cmd);
}
-__initfunc(void pci_set_base_addr(struct pci_dev *dev, int idx, unsigned int addr))
+void __init pci_set_base_addr(struct pci_dev *dev, int idx, unsigned int addr)
{
int reg = PCI_BASE_ADDRESS_0 + (idx << 2);
@@ -148,7 +149,7 @@ __initfunc(void pci_set_base_addr(struct pci_dev *dev, int idx, unsigned int add
dev->base_address[idx] = addr;
}
-__initfunc(void pcibios_fixup(void))
+void __init pcibios_fixup(void)
{
struct pci_dev *dev;
@@ -167,7 +168,7 @@ __initfunc(void pcibios_fixup(void))
hw_init();
}
-__initfunc(void pcibios_init(void))
+void __init pcibios_init(void)
{
unsigned int mem_size = (unsigned int)high_memory - PAGE_OFFSET;
unsigned long cntl;
@@ -242,11 +243,11 @@ __initfunc(void pcibios_init(void))
printk(KERN_DEBUG"PCI: DEC21285 revision %02lX\n", *CSR_CLASSREV & 0xff);
}
-__initfunc(void pcibios_fixup_bus(struct pci_bus *bus))
+void __init pcibios_fixup_bus(struct pci_bus *bus)
{
}
-__initfunc(char *pcibios_setup(char *str))
+char * __init pcibios_setup(char *str)
{
return str;
}
diff --git a/arch/arm/kernel/dma-a5k.c b/arch/arm/kernel/dma-a5k.c
index df02ea54e..84740b6d2 100644
--- a/arch/arm/kernel/dma-a5k.c
+++ b/arch/arm/kernel/dma-a5k.c
@@ -91,7 +91,7 @@ int arch_set_dma_speed(dmach_t channel, dma_t *dma, int cycle_ns)
return 0;
}
-__initfunc(void arch_dma_init(dma_t *dma))
+void __init arch_dma_init(dma_t *dma)
{
dma[DMA_VIRTUAL_FLOPPY].dma_irq = 64;
}
diff --git a/arch/arm/kernel/dma-arc.c b/arch/arm/kernel/dma-arc.c
index 9be27bdae..53ef12b1c 100644
--- a/arch/arm/kernel/dma-arc.c
+++ b/arch/arm/kernel/dma-arc.c
@@ -15,8 +15,11 @@
#include "dma.h"
+#define DEBUG
+
int arch_request_dma(dmach_t channel, dma_t *dma, const char * dev_id)
{
+ printk("arch_request_dma channel=%d F0=%d F1=%d\n",channel,DMA_VIRTUAL_FLOPPY0,DMA_VIRTUAL_FLOPPY1);
if (channel == DMA_VIRTUAL_FLOPPY0 ||
channel == DMA_VIRTUAL_FLOPPY1)
return 0;
@@ -30,8 +33,9 @@ void arch_free_dma(dmach_t channel, dma_t *dma)
void arch_enable_dma(dmach_t channel, dma_t *dma)
{
+ printk("arch_enable_dma channel=%d F0=%d F1=%d\n",channel,DMA_VIRTUAL_FLOPPY0,DMA_VIRTUAL_FLOPPY1);
switch (channel) {
-#ifdef CONFIG_BLK_DEV_FD
+#ifdef CONFIG_BLK_DEV_FD1772
case DMA_VIRTUAL_FLOPPY0: { /* Data DMA */
switch (dma->dma_mode) {
case DMA_MODE_READ: /* read */
@@ -100,7 +104,7 @@ void arch_enable_dma(dmach_t channel, dma_t *dma)
int arch_get_dma_residue(dmach_t channel, dma_t *dma)
{
switch (channel) {
-#ifdef CONFIG_BLK_DEV_FD
+#ifdef CONFIG_BLK_DEV_FD1772
case DMA_VIRTUAL_FLOPPY0: { /* Data DMA */
extern unsigned int fdc1772_bytestogo;
@@ -139,7 +143,7 @@ int arch_set_dma_speed(dmach_t channel, dma_t *dma, int cycle_ns)
return 0;
}
-__initfunc(void arch_dma_init(dma_t *dma))
+void __init arch_dma_init(dma_t *dma)
{
dma[DMA_VIRTUAL_FLOPPY0].dma_irq = 64;
dma[DMA_VIRTUAL_FLOPPY1].dma_irq = 65;
diff --git a/arch/arm/kernel/dma-dummy.c b/arch/arm/kernel/dma-dummy.c
index db46ef1c3..7efc85363 100644
--- a/arch/arm/kernel/dma-dummy.c
+++ b/arch/arm/kernel/dma-dummy.c
@@ -8,8 +8,7 @@
*/
#include <linux/errno.h>
#include <linux/init.h>
-
-#include <asm/spinlock.h>
+#include <linux/spinlock.h>
spinlock_t dma_spin_lock = SPIN_LOCK_UNLOCKED;
@@ -27,6 +26,6 @@ int get_dma_list(char *buf)
return 0;
}
-__initfunc(void init_dma(void))
+void __init init_dma(void)
{
}
diff --git a/arch/arm/kernel/dma-footbridge.c b/arch/arm/kernel/dma-footbridge.c
index a355283dc..016b11c15 100644
--- a/arch/arm/kernel/dma-footbridge.c
+++ b/arch/arm/kernel/dma-footbridge.c
@@ -104,7 +104,7 @@ int arch_set_dma_speed(dmach_t channel, dma_t *dma, int cycle_ns)
return 0;
}
-__initfunc(void arch_dma_init(dma_t *dma))
+void __init arch_dma_init(dma_t *dma)
{
#ifdef CONFIG_ISA_DMA
has_isa_dma = isa_init_dma();
diff --git a/arch/arm/kernel/dma-isa.c b/arch/arm/kernel/dma-isa.c
index 19be50433..f5f98bbac 100644
--- a/arch/arm/kernel/dma-isa.c
+++ b/arch/arm/kernel/dma-isa.c
@@ -11,6 +11,7 @@
* Copyright (C) 1998 Phil Blundell
*/
#include <linux/sched.h>
+#include <linux/ioport.h>
#include <linux/init.h>
#include <asm/dma.h>
@@ -125,7 +126,7 @@ void isa_disable_dma(int channel, dma_t *dma)
outb(channel | 4, isa_dma_port[channel][ISA_DMA_MASK]);
}
-__initfunc(int isa_init_dma(void))
+int __init isa_init_dma(void)
{
int dmac_found;
@@ -138,7 +139,7 @@ __initfunc(int isa_init_dma(void))
dmac_found = inb(0x00) == 0x55 && inb(0x00) == 0xaa;
if (dmac_found) {
- int channel;
+ int channel, i;
for (channel = 0; channel < 8; channel++)
isa_disable_dma(channel, NULL);
@@ -173,6 +174,9 @@ __initfunc(int isa_init_dma(void))
outb(0x33, 0x4d6);
request_dma(DMA_ISA_CASCADE, "cascade");
+
+ for (i = 0; i < sizeof(dma_resources) / sizeof(dma_resources[0]); i++)
+ request_resource(&ioport_resource, dma_resources + i);
}
return dmac_found;
diff --git a/arch/arm/kernel/dma-rpc.c b/arch/arm/kernel/dma-rpc.c
index d3fcd9116..e27232255 100644
--- a/arch/arm/kernel/dma-rpc.c
+++ b/arch/arm/kernel/dma-rpc.c
@@ -359,7 +359,7 @@ int arch_set_dma_speed(dmach_t channel, dma_t *dma, int cycle)
outb(tcr, IOMD_DMATCR);
}
-__initfunc(void arch_dma_init(dma_t *dma))
+void __init arch_dma_init(dma_t *dma)
{
outb(0, IOMD_IO0CR);
outb(0, IOMD_IO1CR);
diff --git a/arch/arm/kernel/dma.c b/arch/arm/kernel/dma.c
index 219e1f0f2..7d1a11cd5 100644
--- a/arch/arm/kernel/dma.c
+++ b/arch/arm/kernel/dma.c
@@ -19,13 +19,13 @@
#include <linux/malloc.h>
#include <linux/mman.h>
#include <linux/init.h>
+#include <linux/spinlock.h>
#include <asm/page.h>
#include <asm/irq.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/dma.h>
-#include <asm/spinlock.h>
/* A note on resource allocation:
@@ -221,7 +221,7 @@ EXPORT_SYMBOL(get_dma_residue);
EXPORT_SYMBOL(set_dma_sg);
EXPORT_SYMBOL(set_dma_speed);
-__initfunc(void init_dma(void))
+void __init init_dma(void)
{
arch_dma_init(dma_chan);
}
diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c
index dd4bf670c..c4b0efef8 100644
--- a/arch/arm/kernel/ecard.c
+++ b/arch/arm/kernel/ecard.c
@@ -44,6 +44,7 @@
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/pgtable.h>
+#include <asm/mmu_context.h>
#ifdef CONFIG_ARCH_ARC
#include <asm/arch/oldlatches.h>
@@ -231,8 +232,42 @@ static wait_queue_head_t ecard_wait;
static wait_queue_head_t ecard_done;
static struct ecard_request *ecard_req;
+/* to be removed when exec_mmap becomes extern */
+static int exec_mmap(void)
+{
+ struct mm_struct * mm, * old_mm;
+
+ old_mm = current->mm;
+ if (old_mm && atomic_read(&old_mm->mm_users) == 1) {
+ flush_cache_mm(old_mm);
+ mm_release();
+ exit_mmap(old_mm);
+ flush_tlb_mm(old_mm);
+ return 0;
+ }
+
+ mm = mm_alloc();
+ if (mm) {
+ struct mm_struct *active_mm = current->active_mm;
+
+ current->mm = mm;
+ current->active_mm = mm;
+ activate_mm(active_mm, mm);
+ mm_release();
+ if (old_mm) {
+ if (active_mm != old_mm) BUG();
+ mmput(old_mm);
+ return 0;
+ }
+ mmdrop(active_mm);
+ return 0;
+ }
+ return -ENOMEM;
+}
+
/*
- * Set up the expansion card daemon's environment.
+ * Set up the expansion card
+ * daemon's environment.
*/
static void
ecard_init_task(void)
@@ -251,6 +286,8 @@ ecard_init_task(void)
pgd_t *src_pgd, *dst_pgd;
unsigned int dst_addr = IO_START;
+ exec_mmap();
+
src_pgd = pgd_offset(current->mm, IO_BASE);
dst_pgd = pgd_offset(current->mm, dst_addr);
@@ -333,7 +370,7 @@ ecard_call(struct ecard_request *req)
* call the loader. We can't schedule, or
* sleep for this call.
*/
- if ((current == task[0] || in_interrupt()) &&
+ if ((current == &init_task || in_interrupt()) &&
req->req == req_reset && req->ec == NULL) {
ecard_init_task();
ecard_task_reset(req);
@@ -721,8 +758,8 @@ again:
printk(KERN_WARNING "Wild interrupt from backplane (masks)\n");
}
-__initfunc(static void
-ecard_probeirqhw(void))
+static void __init
+ecard_probeirqhw(void)
{
ecard_t *ec;
int found;
@@ -798,8 +835,6 @@ unsigned int ecard_address(ecard_t *ec, card_type_t type, card_speed_t speed)
return address;
}
-static const char *unknown = "*unknown*";
-
static int ecard_prints(char *buffer, ecard_t *ec)
{
char *start = buffer;
@@ -818,7 +853,7 @@ static int ecard_prints(char *buffer, ecard_t *ec)
ec->card_desc = kmalloc(strlen(incd.d.string)+1, GFP_KERNEL);
if (ec->card_desc)
- strcpy(ec->card_desc, incd.d.string);
+ strcpy((char *)ec->card_desc, incd.d.string);
}
buffer += sprintf(buffer, "%s\n", ec->card_desc ? ec->card_desc : "*unknown*");
@@ -872,8 +907,8 @@ static void ecard_proc_init(void)
* If bit 1 of the first byte of the card is set, then the
* card does not exist.
*/
-__initfunc(static int
-ecard_probe(int slot, card_type_t type))
+static int __init
+ecard_probe(int slot, card_type_t type)
{
ecard_t **ecp;
ecard_t *ec;
@@ -1009,7 +1044,7 @@ ecard_t *ecard_find(int cid, const card_ids *cids)
return finding_pos;
}
-__initfunc(static void ecard_free_all(void))
+static void __init ecard_free_all(void)
{
ecard_t *ec, *ecn;
@@ -1029,7 +1064,7 @@ __initfunc(static void ecard_free_all(void))
* Locate all hardware - interrupt management and
* actual cards.
*/
-__initfunc(void ecard_init(void))
+void __init ecard_init(void)
{
int slot;
diff --git a/arch/arm/kernel/entry-armo.S b/arch/arm/kernel/entry-armo.S
index 758163f07..5d9ce0ac6 100644
--- a/arch/arm/kernel/entry-armo.S
+++ b/arch/arm/kernel/entry-armo.S
@@ -650,6 +650,15 @@ Ldata_ldcstc_pre:
b SYMBOL_NAME(do_DataAbort)
/*
+ * Register switch for older 26-bit only ARMs
+ */
+ENTRY(__switch_to)
+ stmfd sp!, {r4 - sl, fp, lr} @ Store most regs on stack
+ str sp, [r0, #TSS_SAVE] @ Save sp_SVC
+ ldr sp, [r1, #TSS_SAVE] @ Get saved sp_SVC
+ ldmfd sp!, {r4 - sl, fp, pc}^ @ Load all regs saved previously
+
+/*
*=============================================================================
* Low-level interface code
*-----------------------------------------------------------------------------
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 9456abe33..3e015d866 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -16,6 +16,7 @@
#include <asm/errno.h>
#include <asm/hardware.h>
#include <asm/arch/irqs.h>
+#include <asm/proc-fns.h>
#include "../lib/constants.h"
@@ -244,6 +245,10 @@ irq_prio_ebsa110:
movne \irqnr, #IRQ_PCI
bne 1001f
+ tst \irqstat, #IRQ_MASK_DOORBELLHOST
+ movne \irqnr, #IRQ_DOORBELLHOST
+ bne 1001f
+
tst \irqstat, #IRQ_MASK_I2OINPOST
movne \irqnr, #IRQ_I2OINPOST
bne 1001f
@@ -449,9 +454,13 @@ __dabt_svc: sub sp, sp, #S_FRAME_SIZE
biceq r0, r0, #I_BIT @ previously
msreq cpsr, r0
mov r0, r2
+#ifdef MULTI_CPU
ldr r2, .LCprocfns
mov lr, pc
- ldr pc, [r2, #8] @ call processor specific code
+ ldr pc, [r2] @ call processor specific code
+#else
+ bl cpu_data_abort
+#endif
mov r3, sp
bl SYMBOL_NAME(do_DataAbort)
ldr r0, [sp, #S_PSR]
@@ -503,7 +512,9 @@ __und_svc: sub sp, sp, #S_FRAME_SIZE
.LCirq: .word __temp_irq
.LCund: .word __temp_und
.LCabt: .word __temp_abt
+#ifdef MULTI_CPU
.LCprocfns: .word SYMBOL_NAME(processor)
+#endif
.LCfp: .word SYMBOL_NAME(fp_enter)
#ifdef CONFIG_ALIGNMENT_TRAP
.LCswi: .word SYMBOL_NAME(cr_alignment)
@@ -536,9 +547,13 @@ __dabt_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go
mrs r2, cpsr @ Enable interrupts if they were
bic r2, r2, #I_BIT @ previously
msr cpsr, r2
+#ifdef MULTI_CPU
ldr r2, .LCprocfns
mov lr, pc
- ldr pc, [r2, #8] @ call processor specific code
+ ldr pc, [r2] @ call processor specific code
+#else
+ bl cpu_data_abort
+#endif
mov r3, sp
adrsvc al, lr, ret_from_sys_call
b SYMBOL_NAME(do_DataAbort)
@@ -651,6 +666,23 @@ __pabt_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go
movs pc, lr
#endif
+/*
+ * Register switch for ARMv3 and ARMv4 processors
+ * r0 = previous, r1 = next, return previous.
+ * previous and next are guaranteed not to be the same.
+ */
+ENTRY(__switch_to)
+ stmfd sp!, {r4 - sl, fp, lr} @ Store most regs on stack
+ mrs ip, cpsr
+ stmfd sp!, {ip} @ Save cpsr_SVC
+ ldr r2, [r1, #TSS_DOMAIN]
+ str sp, [r0, #TSS_SAVE] @ Save sp_SVC
+ ldr sp, [r1, #TSS_SAVE] @ Get saved sp_SVC
+ mcr p15, 0, r2, c3, c0 @ Set domain register
+ ldmfd sp!, {ip}
+ msr spsr, ip @ Save tasks CPSR into SPSR for this return
+ ldmfd sp!, {r4 - sl, fp, pc}^ @ Load all regs saved previously
+
.section ".text.init",#alloc,#execinstr
/*
* Vector stubs. NOTE that we only align 'vector_IRQ' to a cache line boundary,
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 7dbc7ff95..bdf6de6b3 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -2,6 +2,16 @@
/*============================================================================
* All exits to user mode from the kernel go through this code.
*/
+
+/*
+ * Define to favour ARM8, ARM9 and StrongARM cpus. This says that it is
+ * cheaper to use two LDR instructions than a two-register LDM, if the
+ * latter would entail calculating an address specially.
+ */
+#if defined(CONFIG_CPU_SA110)
+#define HARVARD_CACHE
+#endif
+
.globl ret_from_sys_call
.align 5
@@ -10,18 +20,23 @@ fast_syscall_return:
slow_syscall_return:
add sp, sp, #4
ret_from_sys_call:
+#ifdef HARVARD_CACHE
+ ldr r0, bh_data
+ ldr r4, bh_data+4
+#else
adr r0, bh_data
ldmia r0, {r0, r4}
+#endif
ldr r0, [r0]
ldr r1, [r4]
tst r0, r1
blne SYMBOL_NAME(do_bottom_half)
ret_with_reschedule:
- get_current_task r1 @ check for scheduling
- ldr r0, [r1, #TSK_NEED_RESCHED]
+ get_current_task r5
+ ldr r0, [r5, #TSK_NEED_RESCHED]
+ ldr r1, [r5, #TSK_SIGPENDING]
teq r0, #0
bne ret_reschedule
- ldr r1, [r1, #TSK_SIGPENDING]
teq r1, #0 @ check for signals
bne ret_signal
@@ -37,8 +52,13 @@ ret_reschedule: adrsvc al, lr, ret_with_reschedule
.globl ret_from_exception
ret_from_exception:
+#ifdef HARVARD_CACHE
+ ldr r0, bh_data
+ ldr r1, bh_data + 4
+#else
adr r0, bh_data
ldmia r0, {r0, r1}
+#endif
ldr r0, [r0]
ldr r1, [r1]
mov r4, #0
@@ -132,7 +152,8 @@ ENTRY(sys_call_table)
SYMBOL_NAME(sys_syscall):
eor r6, r0, #OS_NUMBER << 20
cmp r6, #NR_syscalls @ check range
- ldmleib sp, {r0 - r4} @ get our args
+ add ip, sp, #4
+ ldmleib ip, {r0 - r4} @ get our args
strle r4, [sp] @ Put our arg on the stack
ldrle pc, [r5, r6, lsl #2]
mov r0, #-ENOSYS
diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c
index e3e87469f..7a16832c7 100644
--- a/arch/arm/kernel/fiq.c
+++ b/arch/arm/kernel/fiq.c
@@ -53,15 +53,12 @@ static unsigned long no_fiq_insn;
#ifdef CONFIG_CPU_32
static inline void unprotect_page_0(void)
{
- __asm__ __volatile__("mcr p15, 0, %0, c3, c0" :
- : "r" (DOMAIN_USER_MANAGER |
- DOMAIN_KERNEL_CLIENT |
- DOMAIN_IO_CLIENT));
+ modify_domain(DOMAIN_USER, DOMAIN_MANAGER);
}
static inline void protect_page_0(void)
{
- set_fs(get_fs());
+ modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
}
#else
@@ -216,7 +213,7 @@ void release_fiq(struct fiq_handler *f)
while (current_fiq->fiq_op(current_fiq->dev_id, 0));
}
-__initfunc(void init_FIQ(void))
+void __init init_FIQ(void)
{
no_fiq_insn = *(unsigned long *)FIQ_VECTOR;
set_fs(get_fs());
diff --git a/arch/arm/kernel/head-armv.S b/arch/arm/kernel/head-armv.S
index 2e13f0818..e9a05aed6 100644
--- a/arch/arm/kernel/head-armv.S
+++ b/arch/arm/kernel/head-armv.S
@@ -72,6 +72,8 @@ ENTRY(_stext)
* r1 = 6 -> CATS
* r1 = 7 -> tbox
* r1 = 8 -> SA110/21285 as co-processor
+ * r1 = 9 -> CL-PS7110 system
+ * r1 = 12 -> SA1100 based system
*/
__entry: teq r0, #0 @ check for illegal entry...
@@ -162,9 +164,16 @@ __entry: teq r0, #0 @ check for illegal entry...
addne r0, r4, #0x3600 @ d8000000
strne r3, [r0]
#endif
-@
-@ The following should work on both v3 and v4 implementations
-@
+ b aligned_call
+/*
+ * The following should work on both v3 and v4 implementations
+ * Note: it seems that if the mov pc,lr is on the next cache
+ * line, it doesn't get fetched before the MMU starts
+ * translating, which prevents the kernel from booting.
+ * Ensure that this never happens.
+ */
+ .align 5
+aligned_call:
mov lr, pc
mov pc, r10 @ Call processor flush (returns ctrl reg)
adr r5, __entry
@@ -178,7 +187,7 @@ __entry: teq r0, #0 @ check for illegal entry...
#ifdef CONFIG_ARCH_RPC
/* Turn the screen red on a error - RiscPC only.
*/
-1: mov r0, #0x02000000
+ mov r0, #0x02000000
mov r3, #0x11
orr r3, r3, r3, lsl #8
orr r3, r3, r3, lsl #16
@@ -187,6 +196,7 @@ __entry: teq r0, #0 @ check for illegal entry...
str r3, [r0], #4
str r3, [r0], #4
#endif
+1: mov r0, r0
b 1b
.Lbranch: .long .Lalready_done_mmap @ Real address of routine
@@ -245,6 +255,12 @@ __entry: teq r0, #0 @ check for illegal entry...
.long DC21285_ARMCSR_BASE @ Physical I/O base address
.long 0x7cf00000 >> 18 @ Virtual I/O base address
+ @ SA1100
+ .long SYMBOL_NAME(swapper_pg_dir) - 0xc0000000 + 0xc0000000
+ .long 0xc0000000
+ .long 0x80000000 @ IO mapping will change when kernel gets on its feet
+ .long 0x3800
+
.LCProcTypes: @ ARM6 / 610
.long 0x41560600
.long 0xffffff00
@@ -266,9 +282,9 @@ __entry: teq r0, #0 @ check for illegal entry...
b .Larmv3_flush_late @ arm v3 flush & ctrl late setup
mov pc, lr
- @ StrongARM
- .long 0x4401a100
- .long 0xfffffff0
+ @ StrongARM-110 and StrongARM-1100
+ .long 0x4401a100 @ 4401a100 and 4401a110
+ .long 0xffffffe0
.long 0x00000c02
b .Larmv4_flush_early
b .Lsa_fastclock
diff --git a/arch/arm/kernel/hw-footbridge.c b/arch/arm/kernel/hw-footbridge.c
index 857f120e1..54a64b811 100644
--- a/arch/arm/kernel/hw-footbridge.c
+++ b/arch/arm/kernel/hw-footbridge.c
@@ -44,7 +44,7 @@ extern void (*kd_mksound)(unsigned int hz, unsigned int ticks);
static int irqmap_ebsa[] __initdata = { IRQ_IN1, IRQ_IN0, IRQ_PCI, IRQ_IN3 };
-__initfunc(static int ebsa_irqval(struct pci_dev *dev))
+static int __init ebsa_irqval(struct pci_dev *dev)
{
unsigned char pin;
@@ -59,7 +59,7 @@ __initfunc(static int ebsa_irqval(struct pci_dev *dev))
#ifdef CONFIG_CATS
static int irqmap_cats[] __initdata = { IRQ_PCI, IRQ_IN0, IRQ_IN1, IRQ_IN3 };
-__initfunc(static int cats_irqval(struct pci_dev *dev))
+static int __init cats_irqval(struct pci_dev *dev)
{
if (dev->irq >= 128)
return 16 + (dev->irq & 0x1f);
@@ -80,7 +80,7 @@ __initfunc(static int cats_irqval(struct pci_dev *dev))
}
#endif
-__initfunc(void pcibios_fixup_ebsa285(struct pci_dev *dev))
+void __init pcibios_fixup_ebsa285(struct pci_dev *dev)
{
/* Latency timer of 32 */
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 32);
@@ -284,7 +284,7 @@ static struct irqaction irq_pci_error = {
irq_pci_err, SA_INTERRUPT, 0, "PCI error", NULL, NULL
};
-__initfunc(void pcibios_init_ebsa285(void))
+void __init pcibios_init_ebsa285(void)
{
setup_arm_irq(IRQ_PCI_ERR, &irq_pci_error);
}
@@ -592,7 +592,7 @@ static inline void wb977_init_gpio(void)
/*
* Initialise the Winbond W83977F chip.
*/
-__initfunc(static void wb977_init(void))
+static void __init wb977_init(void)
{
request_region(0x370, 2, "W83977AF configuration");
@@ -642,7 +642,7 @@ void __netwinder_text cpld_modify(int mask, int set)
gpio_modify_op(GPIO_IOLOAD, 0);
}
-__initfunc(static void cpld_init(void))
+static void __init cpld_init(void)
{
unsigned long flags;
@@ -662,7 +662,7 @@ static unsigned char rwa_unlock[] __initdata =
#define dprintk printk
#endif
-#define WRITE_RWA(r,v) do { outb((r), 0x279); outb((v), 0xa79); } while (0)
+#define WRITE_RWA(r,v) do { outb((r), 0x279); udelay(10); outb((v), 0xa79); } while (0)
static inline void rwa010_unlock(void)
{
@@ -671,8 +671,10 @@ static inline void rwa010_unlock(void)
WRITE_RWA(2, 2);
mdelay(10);
- for (i = 0; i < sizeof(rwa_unlock); i++)
+ for (i = 0; i < sizeof(rwa_unlock); i++) {
outb(rwa_unlock[i], 0x279);
+ udelay(10);
+ }
}
static inline void rwa010_read_ident(void)
@@ -685,22 +687,22 @@ static inline void rwa010_read_ident(void)
outb(1, 0x279);
- mdelay(10);
+ mdelay(1);
dprintk("Identifier: ");
for (i = 0; i < 9; i++) {
si[i] = 0;
for (j = 0; j < 8; j++) {
int bit;
- mdelay(1);
+ udelay(250);
inb(0x203);
- mdelay(1);
+ udelay(250);
bit = inb(0x203);
dprintk("%02X ", bit);
+ bit = (bit == 0xaa) ? 1 : 0;
si[i] |= bit << j;
}
- mdelay(10);
- dprintk("%02X ", si[i]);
+ dprintk("(%02X) ", si[i]);
}
dprintk("\n");
}
@@ -842,7 +844,7 @@ static void rwa010_soundblaster_reset(void)
outb(1, 0x38b);
}
-__initfunc(static void rwa010_init(void))
+static void __init rwa010_init(void)
{
rwa010_unlock();
rwa010_read_ident();
@@ -866,8 +868,63 @@ EXPORT_SYMBOL(cpld_modify);
#define DEFAULT_LEDS GPIO_GREEN_LED
#endif
-__initfunc(void hw_init(void))
+/*
+ * CATS stuff
+ */
+#ifdef CONFIG_CATS
+
+#define CONFIG_PORT 0x370
+#define INDEX_PORT (CONFIG_PORT)
+#define DATA_PORT (CONFIG_PORT + 1)
+
+static void __init cats_hw_init(void)
{
+ /* Set Aladdin to CONFIGURE mode */
+ outb(0x51, CONFIG_PORT);
+ outb(0x23, CONFIG_PORT);
+
+ /* Select logical device 3 */
+ outb(0x07, INDEX_PORT);
+ outb(0x03, DATA_PORT);
+
+ /* Set parallel port to DMA channel 3, ECP+EPP1.9,
+ enable EPP timeout */
+ outb(0x74, INDEX_PORT);
+ outb(0x03, DATA_PORT);
+
+ outb(0xf0, INDEX_PORT);
+ outb(0x0f, DATA_PORT);
+
+ outb(0xf1, INDEX_PORT);
+ outb(0x07, DATA_PORT);
+
+ /* Select logical device 4 */
+ outb(0x07, INDEX_PORT);
+ outb(0x04, DATA_PORT);
+
+ /* UART1 high speed mode */
+ outb(0xf0, INDEX_PORT);
+ outb(0x02, DATA_PORT);
+
+ /* Select logical device 5 */
+ outb(0x07, INDEX_PORT);
+ outb(0x05, DATA_PORT);
+
+ /* UART2 high speed mode */
+ outb(0xf0, INDEX_PORT);
+ outb(0x02, DATA_PORT);
+
+ /* Set Aladdin to RUN mode */
+ outb(0xbb, CONFIG_PORT);
+}
+
+#endif
+
+void __init hw_init(void)
+{
+ extern void register_isa_ports(unsigned int, unsigned int,
+ unsigned int);
+ register_isa_ports(DC21285_PCI_MEM, DC21285_PCI_IO, 0);
#ifdef CONFIG_ARCH_NETWINDER
/*
* this ought to have a better home...
@@ -888,6 +945,10 @@ __initfunc(void hw_init(void))
spin_unlock_irqrestore(&gpio_lock, flags);
}
#endif
+#ifdef CONFIG_CATS
+ if (machine_is_cats())
+ cats_hw_init();
+#endif
leds_event(led_start);
}
diff --git a/arch/arm/kernel/init_task.c b/arch/arm/kernel/init_task.c
index 5d09ea540..e3853f3d5 100644
--- a/arch/arm/kernel/init_task.c
+++ b/arch/arm/kernel/init_task.c
@@ -6,7 +6,6 @@
static struct vm_area_struct init_mmap = INIT_MMAP;
static struct fs_struct init_fs = INIT_FS;
-static struct file * init_fd_array[NR_OPEN] = { NULL, };
static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS;
struct mm_struct init_mm = INIT_MM(init_mm);
diff --git a/arch/arm/kernel/ioport.c b/arch/arm/kernel/ioport.c
new file mode 100644
index 000000000..bae897747
--- /dev/null
+++ b/arch/arm/kernel/ioport.c
@@ -0,0 +1,27 @@
+/*
+ * linux/arch/arm/kernel/ioport.c
+ *
+ * IO permission support for ARM.
+ */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/ioport.h>
+
+#include <asm/pgtable.h>
+#include <asm/uaccess.h>
+
+asmlinkage int sys_iopl(unsigned long turn_on)
+{
+ if (turn_on && !capable(CAP_SYS_RAWIO))
+ return -EPERM;
+
+ /*
+ * We only support an on_off approach
+ */
+ modify_domain(DOMAIN_IO, turn_on ? DOMAIN_MANAGER : DOMAIN_CLIENT);
+
+ return 0;
+}
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index ee6e07c6c..41e2050e6 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -479,7 +479,7 @@ out:
return irq_found;
}
-__initfunc(void init_IRQ(void))
+void __init init_IRQ(void)
{
extern void init_dma(void);
int irq;
diff --git a/arch/arm/kernel/isa.c b/arch/arm/kernel/isa.c
new file mode 100644
index 000000000..a5424f8b6
--- /dev/null
+++ b/arch/arm/kernel/isa.c
@@ -0,0 +1,47 @@
+/*
+ * arch/arm/kernel/isa.c
+ *
+ * ISA shared memory and I/O port support
+ *
+ * Copyright (C) 1999 Phil Blundell
+ */
+
+/*
+ * Nothing about this is actually ARM specific. One day we could move
+ * it into kernel/resource.c or some place like that.
+ */
+
+#include <linux/stddef.h>
+#include <linux/types.h>
+#include <linux/linkage.h>
+#include <linux/fs.h>
+#include <linux/sysctl.h>
+#include <linux/init.h>
+
+static unsigned int isa_membase, isa_portbase, isa_portshift;
+
+static ctl_table ctl_isa_vars[4] = {
+ {BUS_ISA_MEM_BASE, "membase", &isa_membase,
+ sizeof(isa_membase), 0444, NULL, &proc_dointvec},
+ {BUS_ISA_PORT_BASE, "portbase", &isa_portbase,
+ sizeof(isa_portbase), 0444, NULL, &proc_dointvec},
+ {BUS_ISA_PORT_SHIFT, "portshift", &isa_portshift,
+ sizeof(isa_portshift), 0444, NULL, &proc_dointvec},
+ {0}
+};
+
+static struct ctl_table_header *isa_sysctl_header;
+
+static ctl_table ctl_isa[2] = {{BUS_ISA, "isa", NULL, 0, 0555, ctl_isa_vars},
+ {0}};
+static ctl_table ctl_bus[2] = {{CTL_BUS, "bus", NULL, 0, 0555, ctl_isa},
+ {0}};
+
+void __init
+register_isa_ports(unsigned int membase, unsigned int portbase, unsigned int portshift)
+{
+ isa_membase = membase;
+ isa_portbase = portbase;
+ isa_portshift = portshift;
+ isa_sysctl_header = register_sysctl_table(ctl_bus, 0);
+}
diff --git a/arch/arm/kernel/leds-footbridge.c b/arch/arm/kernel/leds-footbridge.c
index cb6c7f4b4..6b4cb001b 100644
--- a/arch/arm/kernel/leds-footbridge.c
+++ b/arch/arm/kernel/leds-footbridge.c
@@ -21,10 +21,10 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/spinlock.h>
#include <asm/hardware.h>
#include <asm/leds.h>
-#include <asm/spinlock.h>
#include <asm/system.h>
#define LED_STATE_ENABLED 1
@@ -33,8 +33,9 @@ static char led_state;
static char hw_led_state;
static spinlock_t leds_lock = SPIN_LOCK_UNLOCKED;
+extern spinlock_t gpio_lock;
-#ifdef CONFIG_ARCH_EBSA285
+#ifdef CONFIG_FOOTBRIDGE
static void __ebsa285_text ebsa285_leds_event(led_event_t evt)
{
@@ -222,12 +223,13 @@ static void dummy_leds_event(led_event_t evt)
{
}
-__initfunc(void
-init_leds_event(led_event_t evt))
+void __init
+init_leds_event(led_event_t evt)
{
switch (machine_arch_type) {
-#ifdef CONFIG_ARCH_EBSA285
+#ifdef CONFIG_FOOTBRIDGE
case MACH_TYPE_EBSA285:
+ case MACH_TYPE_CO285:
leds_event = ebsa285_leds_event;
break;
#endif
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index ff0c548b4..776dc9b88 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -9,7 +9,6 @@
* This file handles the architecture-dependent parts of process handling..
*/
-#define __KERNEL_SYSCALLS__
#include <stdarg.h>
#include <linux/errno.h>
@@ -54,16 +53,15 @@ void enable_hlt(void)
/*
* The idle loop on an ARM...
*/
-asmlinkage int sys_idle(void)
+void cpu_idle(void)
{
- if (current->pid != 0)
- return -EPERM;
-
/* endless idle loop with no priority at all */
+ init_idle();
+ current->priority = 0;
+ current->counter = -100;
while (1) {
if (!current->need_resched && !hlt_counter)
proc_idle();
- current->policy = SCHED_YIELD;
schedule();
#ifndef CONFIG_NO_PGT_CACHE
check_pgt_cache();
@@ -73,7 +71,7 @@ asmlinkage int sys_idle(void)
static char reboot_mode = 'h';
-__initfunc(void reboot_setup(char *str, int *ints))
+void __init reboot_setup(char *str, int *ints)
{
reboot_mode = str[0];
}
@@ -207,10 +205,7 @@ void exit_thread(void)
void flush_thread(void)
{
- int i;
-
- for (i = 0; i < NR_DEBUGS; i++)
- current->tss.debug[i] = 0;
+ memset(&current->thread.debug, 0, sizeof(current->thread.debug));
current->used_math = 0;
current->flags &= ~PF_USEDFPU;
}
@@ -232,7 +227,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
save = ((struct context_save_struct *)(childregs)) - 1;
init_thread_css(save);
- p->tss.save = save;
+ p->thread.save = save;
return 0;
}
@@ -245,7 +240,7 @@ int dump_fpu (struct pt_regs *regs, struct user_fp *fp)
int fpvalid = 0;
if (current->used_math)
- memcpy (fp, &current->tss.fpstate.soft, sizeof (fp));
+ memcpy (fp, &current->thread.fpstate.soft, sizeof (fp));
return fpvalid;
}
@@ -255,8 +250,6 @@ int dump_fpu (struct pt_regs *regs, struct user_fp *fp)
*/
void dump_thread(struct pt_regs * regs, struct user * dump)
{
- int i;
-
dump->magic = CMAGIC;
dump->start_code = current->mm->start_code;
dump->start_stack = regs->ARM_sp & ~(PAGE_SIZE - 1);
@@ -265,8 +258,11 @@ void dump_thread(struct pt_regs * regs, struct user * dump)
dump->u_dsize = (current->mm->brk - current->mm->start_data + PAGE_SIZE - 1) >> PAGE_SHIFT;
dump->u_ssize = 0;
- for (i = 0; i < NR_DEBUGS; i++)
- dump->u_debugreg[i] = current->tss.debug[i];
+ dump->u_debugreg[0] = current->thread.debug.bp[0].address;
+ dump->u_debugreg[1] = current->thread.debug.bp[1].address;
+ dump->u_debugreg[2] = current->thread.debug.bp[0].insn;
+ dump->u_debugreg[3] = current->thread.debug.bp[1].insn;
+ dump->u_debugreg[4] = current->thread.debug.nsaved;
if (dump->start_stack < 0x04000000)
dump->u_ssize = (0x04000000 - dump->start_stack) >> PAGE_SHIFT;
@@ -285,7 +281,6 @@ void dump_thread(struct pt_regs * regs, struct user * dump)
*/
pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
{
- extern int sys_exit(int) __attribute__((noreturn));
pid_t __ret;
__asm__ __volatile__(
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index fbc3a2187..6104b4dbe 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -28,7 +28,7 @@
/*
* this routine will get a word off of the processes privileged stack.
- * the offset is how far from the base addr as stored in the TSS.
+ * the offset is how far from the base addr as stored in the THREAD.
* this routine assumes that all the privileged stacks are in our
* data space.
*/
@@ -43,7 +43,7 @@ static inline long get_stack_long(struct task_struct *task, int offset)
/*
* this routine will put a word on the processes privileged stack.
- * the offset is how far from the base addr as stored in the TSS.
+ * the offset is how far from the base addr as stored in the THREAD.
* this routine assumes that all the privileged stacks are in our
* data space.
*/
@@ -59,209 +59,24 @@ static inline long put_stack_long(struct task_struct *task, int offset,
return 0;
}
-/*
- * This routine gets a long from any process space by following the page
- * tables. NOTE! You should check that the long isn't on a page boundary,
- * and that it is in the task area before calling this: this routine does
- * no checking.
- */
-static unsigned long get_long(struct task_struct * tsk,
- struct vm_area_struct * vma, unsigned long addr)
+static int
+read_long(struct task_struct *child, unsigned long addr, unsigned long *res)
{
- pgd_t *pgdir;
- pmd_t *pgmiddle;
- pte_t *pgtable;
- unsigned long page;
-
-repeat:
- pgdir = pgd_offset(vma->vm_mm, addr);
- if (pgd_none(*pgdir)) {
- handle_mm_fault(tsk, vma, addr, 0);
- goto repeat;
- }
- if (pgd_bad(*pgdir)) {
- printk("ptrace: bad page directory %08lx\n", pgd_val(*pgdir));
- pgd_clear(pgdir);
- return 0;
- }
- pgmiddle = pmd_offset(pgdir, addr);
- if (pmd_none(*pgmiddle)) {
- handle_mm_fault(tsk, vma, addr, 0);
- goto repeat;
- }
- if (pmd_bad(*pgmiddle)) {
- printk("ptrace: bad page middle %08lx\n", pmd_val(*pgmiddle));
- pmd_clear(pgmiddle);
- return 0;
- }
- pgtable = pte_offset(pgmiddle, addr);
- if (!pte_present(*pgtable)) {
- handle_mm_fault(tsk, vma, addr, 0);
- goto repeat;
- }
- page = pte_page(*pgtable);
-
- if(MAP_NR(page) >= max_mapnr)
- return 0;
- page += addr & ~PAGE_MASK;
- return *(unsigned long *)page;
-}
+ int copied;
-/*
- * This routine puts a long into any process space by following the page
- * tables. NOTE! You should check that the long isn't on a page boundary,
- * and that it is in the task area before calling this: this routine does
- * no checking.
- *
- * Now keeps R/W state of the page so that a text page stays readonly
- * even if a debugger scribbles breakpoints into it. -M.U-
- */
-static void put_long(struct task_struct * tsk, struct vm_area_struct * vma, unsigned long addr,
- unsigned long data)
-{
- pgd_t *pgdir;
- pmd_t *pgmiddle;
- pte_t *pgtable;
- unsigned long page;
-
-repeat:
- pgdir = pgd_offset(vma->vm_mm, addr);
- if (!pgd_present(*pgdir)) {
- handle_mm_fault(tsk, vma, addr, 1);
- goto repeat;
- }
- if (pgd_bad(*pgdir)) {
- printk("ptrace: bad page directory %08lx\n", pgd_val(*pgdir));
- pgd_clear(pgdir);
- return;
- }
- pgmiddle = pmd_offset(pgdir, addr);
- if (pmd_none(*pgmiddle)) {
- handle_mm_fault(tsk, vma, addr, 1);
- goto repeat;
- }
- if (pmd_bad(*pgmiddle)) {
- printk("ptrace: bad page middle %08lx\n", pmd_val(*pgmiddle));
- pmd_clear(pgmiddle);
- return;
- }
- pgtable = pte_offset(pgmiddle, addr);
- if (!pte_present(*pgtable)) {
- handle_mm_fault(tsk, vma, addr, 1);
- goto repeat;
- }
- page = pte_page(*pgtable);
- if (!pte_write(*pgtable)) {
- handle_mm_fault(tsk, vma, addr, 1);
- goto repeat;
- }
-
- if (MAP_NR(page) < max_mapnr) {
- page += addr & ~PAGE_MASK;
-
- flush_cache_range(vma->vm_mm, addr, addr + sizeof(unsigned long));
-
- *(unsigned long *)page = data;
-
- clean_cache_area(page, sizeof(unsigned long));
+ copied = access_process_vm(child, addr, res, sizeof(*res), 0);
- set_pte(pgtable, pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
- flush_tlb_page(vma, addr & PAGE_MASK);
- }
+ return copied != sizeof(*res) ? -EIO : 0;
}
-/*
- * This routine checks the page boundaries, and that the offset is
- * within the task area. It then calls get_long() to read a long.
- */
-static int read_long(struct task_struct * tsk, unsigned long addr,
- unsigned long * result)
+static int
+write_long(struct task_struct *child, unsigned long addr, unsigned long val)
{
- struct vm_area_struct * vma = find_extend_vma(tsk, addr);
-
- if (!vma)
- return -EIO;
- if ((addr & ~PAGE_MASK) > PAGE_SIZE-sizeof(long)) {
- unsigned long low,high;
- struct vm_area_struct * vma_high = vma;
-
- if (addr + sizeof(long) >= vma->vm_end) {
- vma_high = vma->vm_next;
- if (!vma_high || vma_high->vm_start != vma->vm_end)
- return -EIO;
- }
- low = get_long(tsk, vma, addr & ~(sizeof(long)-1));
- high = get_long(tsk, vma_high, (addr+sizeof(long)) & ~(sizeof(long)-1));
- switch (addr & (sizeof(long)-1)) {
- case 1:
- low >>= 8;
- low |= high << 24;
- break;
- case 2:
- low >>= 16;
- low |= high << 16;
- break;
- case 3:
- low >>= 24;
- low |= high << 8;
- break;
- }
- *result = low;
- } else
- *result = get_long(tsk, vma, addr);
- return 0;
-}
+ int copied;
-/*
- * This routine checks the page boundaries, and that the offset is
- * within the task area. It then calls put_long() to write a long.
- */
-static int write_long(struct task_struct * tsk, unsigned long addr,
- unsigned long data)
-{
- struct vm_area_struct * vma = find_extend_vma(tsk, addr);
-
- if (!vma)
- return -EIO;
- if ((addr & ~PAGE_MASK) > PAGE_SIZE-sizeof(long)) {
- unsigned long low,high;
- struct vm_area_struct * vma_high = vma;
-
- if (addr + sizeof(long) >= vma->vm_end) {
- vma_high = vma->vm_next;
- if (!vma_high || vma_high->vm_start != vma->vm_end)
- return -EIO;
- }
- low = get_long(tsk, vma, addr & ~(sizeof(long)-1));
- high = get_long(tsk, vma_high, (addr+sizeof(long)) & ~(sizeof(long)-1));
- switch (addr & (sizeof(long)-1)) {
- case 0: /* shouldn't happen, but safety first */
- low = data;
- break;
- case 1:
- low &= 0x000000ff;
- low |= data << 8;
- high &= ~0xff;
- high |= data >> 24;
- break;
- case 2:
- low &= 0x0000ffff;
- low |= data << 16;
- high &= ~0xffff;
- high |= data >> 16;
- break;
- case 3:
- low &= 0x00ffffff;
- low |= data << 24;
- high &= ~0xffffff;
- high |= data >> 8;
- break;
- }
- put_long(tsk, vma, addr & ~(sizeof(long)-1),low);
- put_long(tsk, vma_high, (addr+sizeof(long)) & ~(sizeof(long)-1),high);
- } else
- put_long(tsk, vma, addr, data);
- return 0;
+ copied = access_process_vm(child, addr, &val, sizeof(val), 1);
+
+ return copied != sizeof(val) ? -EIO : 0;
}
/*
@@ -315,7 +130,7 @@ printk ("sh%dx%d", type, shift);
val = (((signed long)val) >> shift);
break;
case 3:
- __asm__ __volatile__("mov %0, %0, ror %1" : "=r" (val) : "0" (val), "r" (shift));
+ val = (val >> shift) | (val << (32 - shift));
break;
}
printk ("=%08lX ", val);
@@ -343,26 +158,19 @@ printk ("op2=r%02ldsh%dx%d", insn & 15, shift, type);
val = (((signed long)val) >> shift);
break;
case 3:
- __asm__ __volatile__("mov %0, %0, ror %1" : "=r" (val) : "0" (val), "r" (shift));
+ val = (val >> shift) | (val << (32 - shift));
break;
}
printk ("=%08lX ", val);
return val;
}
-int ptrace_set_bpt (struct task_struct *child)
+static unsigned long
+get_branch_address(struct task_struct *child, unsigned long pc, unsigned long insn)
{
- unsigned long insn, pc, alt;
- int i, nsaved = 0, res;
-
- pc = pc_pointer (get_stack_long (child, 15/*REG_PC*/));
+ unsigned long alt = 0;
- res = read_long (child, pc, &insn);
- if (res < 0)
- return res;
-
- child->tss.debug[nsaved++] = alt = pc + 4;
-printk ("ptrace_set_bpt: insn=%08lX pc=%08lX ", insn, pc);
+printk(KERN_DEBUG "ptrace_set_bpt: insn=%08lX pc=%08lX ", insn, pc);
switch (insn & 0x0e100000) {
case 0x00000000:
case 0x00100000:
@@ -423,7 +231,7 @@ printk ("ldr ");
alt -= ptrace_getldrop2 (child, insn);
}
if (read_long (child, alt, &alt) < 0)
- alt = pc + 4; /* not valid */
+ alt = 0; /* not valid */
else
alt = pc_pointer (alt);
}
@@ -440,7 +248,7 @@ printk ("ldrimm ");
alt -= insn & 0xfff;
}
if (read_long (child, alt, &alt) < 0)
- alt = pc + 4; /* not valid */
+ alt = 0; /* not valid */
else
alt = pc_pointer (alt);
}
@@ -473,7 +281,7 @@ printk ("ldm ");
base = ptrace_getrn (child, insn);
if (read_long (child, base + nr_regs, &alt) < 0)
- alt = pc + 4; /* not valid */
+ alt = 0; /* not valid */
else
alt = pc_pointer (alt);
break;
@@ -499,22 +307,55 @@ printk ("b/bl ");
break;
}
printk ("=%08lX\n", alt);
- if (alt != pc + 4)
- child->tss.debug[nsaved++] = alt;
- for (i = 0; i < nsaved; i++) {
- res = read_long (child, child->tss.debug[i], &insn);
- if (res >= 0) {
- child->tss.debug[i + 2] = insn;
- res = write_long (child, child->tss.debug[i], BREAKINST);
+ return alt;
+}
+
+static int
+add_breakpoint(struct task_struct *child, struct debug_info *dbg, unsigned long addr)
+{
+ int nr = dbg->nsaved;
+ int res = -EINVAL;
+
+ if (nr < 2) {
+ res = read_long(child, addr, &dbg->bp[nr].insn);
+ if (res == 0)
+ res = write_long(child, addr, BREAKINST);
+
+ if (res == 0) {
+ dbg->bp[nr].address = addr;
+ dbg->nsaved += 1;
}
- if (res < 0) {
- child->tss.debug[4] = 0;
- return res;
+ } else
+ printk(KERN_DEBUG "add_breakpoint: too many breakpoints\n");
+
+ return res;
+}
+
+int ptrace_set_bpt (struct task_struct *child)
+{
+ struct debug_info *dbg = &child->thread.debug;
+ unsigned long insn, pc, alt;
+ int res;
+
+ pc = pc_pointer (get_stack_long (child, 15/*REG_PC*/));
+
+ res = read_long(child, pc, &insn);
+ if (res >= 0) {
+ res = 0;
+
+ dbg->nsaved = 0;
+
+ res = add_breakpoint(child, dbg, pc + 4);
+
+ if (res == 0) {
+ alt = get_branch_address(child, pc, insn);
+ if (alt)
+ res = add_breakpoint(child, dbg, alt);
}
}
- child->tss.debug[4] = nsaved;
- return 0;
+
+ return res;
}
/* Ensure no single-step breakpoint is pending. Returns non-zero
@@ -522,16 +363,24 @@ printk ("=%08lX\n", alt);
*/
int ptrace_cancel_bpt (struct task_struct *child)
{
- int i, nsaved = child->tss.debug[4];
+ struct debug_info *dbg = &child->thread.debug;
+ unsigned long tmp;
+ int i, nsaved = dbg->nsaved;
- child->tss.debug[4] = 0;
+ dbg->nsaved = 0;
if (nsaved > 2) {
printk ("ptrace_cancel_bpt: bogus nsaved: %d!\n", nsaved);
nsaved = 2;
}
- for (i = 0; i < nsaved; i++)
- write_long (child, child->tss.debug[i], child->tss.debug[i + 2]);
+
+ for (i = 0; i < nsaved; i++) {
+ read_long(child, dbg->bp[i].address, &tmp);
+ if (tmp != BREAKINST)
+ printk(KERN_ERR "ptrace_cancel_bpt: weirdness\n");
+ write_long(child, dbg->bp[i].address, dbg->bp[i].insn);
+ }
+
return nsaved != 0;
}
@@ -598,8 +447,8 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
unsigned long tmp;
ret = read_long(child, addr, &tmp);
- if (ret >= 0)
- ret = put_user(tmp, (unsigned long *)data);
+ if (ret)
+ put_user(tmp, (unsigned long *) data);
goto out;
}
@@ -619,7 +468,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA:
- ret = write_long(child,addr,data);
+ ret = write_long(child, addr, data);
goto out;
case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
@@ -665,7 +514,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
ret = -EIO;
if ((unsigned long) data > _NSIG)
goto out;
- child->tss.debug[4] = -1;
+ child->thread.debug.nsaved = -1;
child->flags &= ~PF_TRACESYS;
wake_up_process(child);
child->exit_code = data;
diff --git a/arch/arm/kernel/semaphore.c b/arch/arm/kernel/semaphore.c
new file mode 100644
index 000000000..1bb21be3f
--- /dev/null
+++ b/arch/arm/kernel/semaphore.c
@@ -0,0 +1,202 @@
+/*
+ * ARM semaphore implementation, taken from
+ *
+ * i386 semaphore implementation.
+ *
+ * (C) Copyright 1999 Linus Torvalds
+ *
+ * Modified for ARM by Russell King
+ */
+#include <linux/sched.h>
+
+#include <asm/semaphore.h>
+
+/*
+ * Semaphores are implemented using a two-way counter:
+ * The "count" variable is decremented for each process
+ * that tries to aquire the semaphore, while the "sleeping"
+ * variable is a count of such aquires.
+ *
+ * Notably, the inline "up()" and "down()" functions can
+ * efficiently test if they need to do any extra work (up
+ * needs to do something only if count was negative before
+ * the increment operation.
+ *
+ * "sleeping" and the contention routine ordering is
+ * protected by the semaphore spinlock.
+ *
+ * Note that these functions are only called when there is
+ * contention on the lock, and as such all this is the
+ * "non-critical" part of the whole semaphore business. The
+ * critical part is the inline stuff in <asm/semaphore.h>
+ * where we want to avoid any extra jumps and calls.
+ */
+
+/*
+ * Logic:
+ * - only on a boundary condition do we need to care. When we go
+ * from a negative count to a non-negative, we wake people up.
+ * - when we go from a non-negative count to a negative do we
+ * (a) synchronize with the "sleeper" count and (b) make sure
+ * that we're on the wakeup list before we synchronize so that
+ * we cannot lose wakeup events.
+ */
+
+void __up(struct semaphore *sem)
+{
+ wake_up(&sem->wait);
+}
+
+static spinlock_t semaphore_lock = SPIN_LOCK_UNLOCKED;
+
+void __down(struct semaphore * sem)
+{
+ struct task_struct *tsk = current;
+ DECLARE_WAITQUEUE(wait, tsk);
+ tsk->state = TASK_UNINTERRUPTIBLE;
+ add_wait_queue(&sem->wait, &wait);
+
+ spin_lock_irq(&semaphore_lock);
+ sem->sleepers++;
+ for (;;) {
+ int sleepers = sem->sleepers;
+
+ /*
+ * Add "everybody else" into it. They aren't
+ * playing, because we own the spinlock.
+ */
+ if (!atomic_add_negative(sleepers - 1, &sem->count)) {
+ sem->sleepers = 0;
+ wake_up(&sem->wait);
+ break;
+ }
+ sem->sleepers = 1; /* us - see -1 above */
+ spin_unlock_irq(&semaphore_lock);
+
+ schedule();
+ tsk->state = TASK_UNINTERRUPTIBLE;
+ spin_lock_irq(&semaphore_lock);
+ }
+ spin_unlock_irq(&semaphore_lock);
+ remove_wait_queue(&sem->wait, &wait);
+ tsk->state = TASK_RUNNING;
+}
+
+int __down_interruptible(struct semaphore * sem)
+{
+ int retval;
+ struct task_struct *tsk = current;
+ DECLARE_WAITQUEUE(wait, tsk);
+ tsk->state = TASK_INTERRUPTIBLE;
+ add_wait_queue(&sem->wait, &wait);
+
+ spin_lock_irq(&semaphore_lock);
+ sem->sleepers ++;
+ for (;;) {
+ int sleepers = sem->sleepers;
+
+ /*
+ * With signals pending, this turns into
+ * the trylock failure case - we won't be
+ * sleeping, and we* can't get the lock as
+ * it has contention. Just correct the count
+ * and exit.
+ */
+ retval = -EINTR;
+ if (signal_pending(current)) {
+ sem->sleepers = 0;
+ if (atomic_add_negative(sleepers, &sem->count))
+ break;
+ wake_up(&sem->wait);
+ break;
+ }
+
+ /*
+ * Add "everybody else" into it. They aren't
+ * playing, because we own the spinlock. The
+ * "-1" is because we're still hoping to get
+ * the lock.
+ */
+ if (!atomic_add_negative(sleepers - 1, &sem->count)) {
+ wake_up(&sem->wait);
+ retval = 0;
+ sem->sleepers = 0;
+ break;
+ }
+ sem->sleepers = 1; /* us - see -1 above */
+ spin_unlock_irq(&semaphore_lock);
+
+ schedule();
+ tsk->state = TASK_INTERRUPTIBLE;
+ spin_lock_irq(&semaphore_lock);
+ }
+ spin_unlock_irq(&semaphore_lock);
+ tsk->state = TASK_RUNNING;
+ remove_wait_queue(&sem->wait, &wait);
+ return retval;
+}
+
+/*
+ * Trylock failed - make sure we correct for
+ * having decremented the count.
+ *
+ * We could have done the trylock with a
+ * single "cmpxchg" without failure cases,
+ * but then it wouldn't work on a 386.
+ */
+int __down_trylock(struct semaphore * sem)
+{
+ int sleepers;
+
+ spin_lock_irq(&semaphore_lock);
+ sleepers = sem->sleepers + 1;
+ sem->sleepers = 0;
+
+ /*
+ * Add "everybody else" and us into it. They aren't
+ * playing, because we own the spinlock.
+ */
+ if (!atomic_add_negative(sleepers, &sem->count))
+ wake_up(&sem->wait);
+
+ spin_unlock_irq(&semaphore_lock);
+ return 1;
+}
+
+/*
+ * The semaphore operations have a special calling sequence that
+ * allow us to do a simpler in-line version of them. These routines
+ * need to convert that sequence back into the C sequence when
+ * there is contention on the semaphore.
+ *
+ * r0 contains the semaphore pointer on entry. Save the C-clobbered
+ * registers (r0 to r3, ip and lr) except r0 in the cases where it
+ * is used as a return value..
+ */
+asm(".align 5
+ .globl __down_failed
+__down_failed:
+ stmfd sp!, {r0 - r3, ip, lr}
+ bl __down
+ ldmfd sp!, {r0 - r3, ip, pc}");
+
+asm(".align 5
+ .globl __down_interruptible_failed
+__down_interruptible_failed:
+ stmfd sp!, {r1 - r3, ip, lr}
+ bl __down_interruptible
+ ldmfd sp!, {r1 - r3, ip, pc}");
+
+asm(".align 5
+ .globl __down_trylock_failed
+__down_trylock_failed:
+ stmfd sp!, {r1 - r3, ip, lr}
+ bl __down_trylock
+ ldmfd sp!, {r1 - r3, ip, pc}");
+
+asm(".align 5
+ .globl __up_wakeup
+__up_wakeup:
+ stmfd sp!, {r0 - r3, ip, lr}
+ bl __up
+ ldmfd sp!, {r0 - r3, ip, pc}");
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 0b0a70087..8258bd767 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -1,7 +1,7 @@
/*
* linux/arch/arm/kernel/setup.c
*
- * Copyright (C) 1995-1998 Russell King
+ * Copyright (C) 1995-1999 Russell King
*/
/*
@@ -38,24 +38,6 @@
#include <asm/setup.h>
#include <asm/system.h>
-/* Work out which CPUs to support */
-#ifdef CONFIG_ARCH_ACORN
-#define SUPPORT_CPU_ARM6
-#define SUPPORT_CPU_ARM7
-#define SUPPORT_CPU_SA110
-#else
-#define SUPPORT_CPU_SA110
-#endif
-#ifdef CONFIG_CPU_ARM6
-#define SUPPORT_CPU_ARM6
-#endif
-#ifdef CONFIG_CPU_ARM7
-#define SUPPORT_CPU_ARM7
-#endif
-#ifdef CONFIG_CPU_SA110
-#define SUPPORT_CPU_SA110
-#endif
-
#define MEM_SIZE (16*1024*1024)
#define COMMAND_LINE_SIZE 256
@@ -63,6 +45,10 @@
#define CONFIG_CMDLINE ""
#endif
+#ifndef PARAMS_BASE
+#define PARAMS_BASE NULL
+#endif
+
extern void reboot_setup(char *str, int *ints);
extern void fpe_init(void);
extern void disable_hlt(void);
@@ -76,71 +62,32 @@ struct screen_info screen_info = {
orig_video_isVGA: 1,
orig_video_points: 8
};
-struct processor processor;
+
+extern int root_mountflags;
+extern int _etext, _edata, _end;
+
unsigned char aux_device_present;
-extern const struct processor arm2_processor_functions;
-extern const struct processor arm250_processor_functions;
-extern const struct processor arm3_processor_functions;
-extern const struct processor arm6_processor_functions;
-extern const struct processor arm7_processor_functions;
-extern const struct processor sa110_processor_functions;
-
-char elf_platform[ELF_PLATFORM_SIZE];
-
-const struct armversions armidlist[] = {
- /*-- Match -- --- Mask -- -- Manu -- Processor uname -m --- ELF STUFF ---
- --- processor asm funcs --- */
-#if defined(CONFIG_CPU_26)
- /* ARM2 fake ident */
- { 0x41560200, 0xfffffff0, "ARM/VLSI", "arm2" , "armv1" , "v1", 0,
- &arm2_processor_functions },
- /* ARM250 fake ident */
- { 0x41560250, 0xfffffff0, "ARM/VLSI", "arm250" , "armv2" , "v2", HWCAP_SWP,
- &arm250_processor_functions },
- /* ARM3 processors */
- { 0x41560300, 0xfffffff0, "ARM/VLSI", "arm3" , "armv2" , "v2", HWCAP_SWP,
- &arm3_processor_functions },
-#elif defined(CONFIG_CPU_32)
-#ifdef SUPPORT_CPU_ARM6
- /* ARM6 */
- { 0x41560600, 0xfffffff0, "ARM/VLSI", "arm6" , "armv3" , "v3", HWCAP_SWP,
- &arm6_processor_functions },
- /* ARM610 */
- { 0x41560610, 0xfffffff0, "ARM/VLSI", "arm610" , "armv3" , "v3", HWCAP_SWP,
- &arm6_processor_functions },
-#endif
-#ifdef SUPPORT_CPU_ARM7
- /* ARM7's have a strange numbering */
- { 0x41007000, 0xffffff00, "ARM/VLSI", "arm7" , "armv3" , "v3", HWCAP_SWP,
- &arm7_processor_functions },
- /* ARM710 IDs are non-standard */
- { 0x41007100, 0xfff8ff00, "ARM/VLSI", "arm710" , "armv3" , "v3", HWCAP_SWP,
- &arm7_processor_functions },
-#endif
-#ifdef SUPPORT_CPU_SA110
-#ifdef CONFIG_ARCH_RPC
- /* Acorn RiscPC's can't handle ARMv4 half-word instructions */
- { 0x4401a100, 0xfffffff0, "Intel", "sa110" , "armv4" , "v4", HWCAP_SWP,
- &sa110_processor_functions },
-#else
- { 0x4401a100, 0xfffffff0, "Intel", "sa110" , "armv4" , "v4", HWCAP_SWP|HWCAP_HALF,
- &sa110_processor_functions },
-#endif
-#endif
-#endif
- { 0x00000000, 0x00000000, "***", "unknown", "unknown", "**", 0, NULL }
-};
+ char elf_platform[ELF_PLATFORM_SIZE];
+unsigned int elf_hwcap;
/*
* From head-armv.S
*/
unsigned int processor_id;
unsigned int __machine_arch_type;
-int armidindex;
+#ifdef MULTI_CPU
+struct processor processor;
+#endif
+#ifdef CONFIG_ARCH_ACORN
+int memc_ctrl_reg;
+int number_mfm_drives;
+unsigned int vram_size;
+#endif
-extern int root_mountflags;
-extern int _etext, _edata, _end;
+static struct proc_info_item proc_info;
+static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };
+#define ENDIANNESS ((char)endian_test.l)
/*-------------------------------------------------------------------------
* Early initialisation routines for various configurable items in the
@@ -152,8 +99,8 @@ extern int _etext, _edata, _end;
* initial ram disk
*/
#ifdef CONFIG_BLK_DEV_INITRD
-__initfunc(static void
-check_initrd(unsigned long mem_start, unsigned long mem_end))
+static void __init
+check_initrd(unsigned long mem_start, unsigned long mem_end)
{
if (initrd_end > mem_end) {
printk ("initrd extends beyond end of memory "
@@ -167,8 +114,8 @@ check_initrd(unsigned long mem_start, unsigned long mem_end))
#define check_initrd(ms,me)
#endif
-__initfunc(void
-setup_processor(void))
+void __init
+setup_processor(void)
{
armidindex = 0;
@@ -187,8 +134,8 @@ static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
static char command_line[COMMAND_LINE_SIZE] = { 0, };
char saved_command_line[COMMAND_LINE_SIZE];
-__initfunc(static void
-setup_mem(char *cmd_line, unsigned long *mem_start, unsigned long *mem_sz))
+static void __init
+setup_mem(char *cmd_line, unsigned long *mem_start, unsigned long *mem_sz)
{
char c = ' ', *to = command_line;
int len = 0;
@@ -233,8 +180,8 @@ setup_mem(char *cmd_line, unsigned long *mem_start, unsigned long *mem_sz))
*to = '\0';
}
-__initfunc(static void
-setup_ram(int doload, int prompt, int image_start))
+static void __init
+setup_ram(int doload, int prompt, int image_start)
{
#ifdef CONFIG_BLK_DEV_RAM
extern int rd_doload;
@@ -250,8 +197,8 @@ setup_ram(int doload, int prompt, int image_start))
/*
* initial ram disk
*/
-__initfunc(static void
-setup_initrd(unsigned int start, unsigned int size))
+static void __init
+setup_initrd(unsigned int start, unsigned int size)
{
#ifdef CONFIG_BLK_DEV_INITRD
if (start) {
@@ -277,8 +224,8 @@ unsigned int vram_size;
static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };
#define ENDIANNESS ((char)endian_test.l)
-__initfunc(void
-setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigned long * memory_end_p))
+void __init
+setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigned long * memory_end_p)
{
struct param_struct *params = (struct param_struct *)PARAMS_BASE;
static unsigned char smptrap;
@@ -297,10 +244,10 @@ setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigned long * mem
setup_processor();
- init_task.mm->start_code = TASK_SIZE;
- init_task.mm->end_code = TASK_SIZE + (unsigned long) &_etext;
- init_task.mm->end_data = TASK_SIZE + (unsigned long) &_edata;
- init_task.mm->brk = TASK_SIZE + (unsigned long) &_end;
+ init_mm.start_code = TASK_SIZE;
+ init_mm.end_code = TASK_SIZE + (unsigned long) &_etext;
+ init_mm.end_data = TASK_SIZE + (unsigned long) &_edata;
+ init_mm.brk = TASK_SIZE + (unsigned long) &_end;
/*
* Add your machine dependencies here
@@ -309,7 +256,13 @@ setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigned long * mem
case MACH_TYPE_EBSA110:
/* EBSA110 locks if we execute 'wait for interrupt' */
disable_hlt();
- params = NULL;
+ if (params && params->u1.s.page_size != 4096)
+ params = NULL;
+ break;
+
+ case MACH_TYPE_RISCPC:
+ /* RiscPC can't handle half-word loads and stores */
+ elf_hwcap &= ~HWCAP_HALF;
break;
case MACH_TYPE_EBSA285:
@@ -415,7 +368,7 @@ setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigned long * mem
from = params->commandline;
} else {
- ROOT_DEV = 0x00ff;
+ ROOT_DEV = to_kdev_t(0x00ff);
setup_ram(1, 1, 0);
setup_initrd(0, 0);
@@ -441,9 +394,6 @@ setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigned long * mem
check_initrd(*memory_start_p, memory_end);
- sprintf(system_utsname.machine, "%s%c", armidlist[armidindex].arch_vsn, ENDIANNESS);
- sprintf(elf_platform, "%s%c", armidlist[armidindex].elf_vsn, ENDIANNESS);
-
#ifdef CONFIG_VT
#if defined(CONFIG_VGA_CONSOLE)
conswitchp = &vga_con;
@@ -462,7 +412,7 @@ static const char *machine_desc[] = {
"unknown",
"Nexus-FTV/PCI",
"EBSA285",
- "Corel-NetWinder",
+ "Rebel-NetWinder",
"Chalice-CATS",
"unknown-TBOX",
"co-EBSA285",
@@ -476,12 +426,13 @@ int get_cpuinfo(char * buffer)
int len;
len = sprintf(buffer,
- "Processor\t: %s %s rev %d\n"
+ "Processor\t: %s %s rev %d (%s)\n"
"BogoMips\t: %lu.%02lu\n"
"Hardware\t: %s\n",
- armidlist[armidindex].manu,
- armidlist[armidindex].name,
+ proc_info.manufacturer,
+ proc_info.cpu_name,
(int)processor_id & 15,
+ elf_platform,
(loops_per_sec+2500) / 500000,
((loops_per_sec+2500) / 5000) % 100,
machine_desc[machine_arch_type]);
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 5ec48f752..7b2f430c1 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -273,8 +273,8 @@ setup_sigcontext(struct sigcontext *sc, /*struct _fpstate *fpstate,*/
err |= __put_user (regs->ARM_cpsr, &sc->arm_cpsr);
#endif
- err |= __put_user (current->tss.trap_no, &sc->trap_no);
- err |= __put_user (current->tss.error_code, &sc->error_code);
+ err |= __put_user (current->thread.trap_no, &sc->trap_no);
+ err |= __put_user (current->thread.error_code, &sc->error_code);
err |= __put_user (mask, &sc->oldmask);
return err;
@@ -543,12 +543,8 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV:
- lock_kernel();
- if (current->binfmt
- && current->binfmt->core_dump
- && current->binfmt->core_dump(signr, regs))
+ if (do_coredump(signr, regs))
exit_code |= 0x80;
- unlock_kernel();
/* FALLTHRU */
default:
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index 4e49885b8..c48c62108 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -76,6 +76,25 @@ unsigned long mktime(unsigned int year, unsigned int mon,
)*60 + sec; /* finally seconds */
}
+/*
+ * Handle profile stuff...
+ */
+static void do_profile(unsigned long pc)
+{
+ if (prof_buffer && current->pid) {
+ extern int _stext;
+
+ pc -= (unsigned long)&_stext;
+
+ pc >>= prof_shift;
+
+ if (pc >= prof_len)
+ pc = prof_len - 1;
+
+ prof_buffer[pc] += 1;
+ }
+}
+
#include <asm/arch/time.h>
static unsigned long do_gettimeoffset(void)
@@ -130,7 +149,7 @@ void do_settimeofday(struct timeval *tv)
sti();
}
-__initfunc(void time_init(void))
+void __init time_init(void)
{
xtime.tv_usec = 0;
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 9267fec09..9f9e6934f 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -16,11 +16,11 @@
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/mm.h>
+#include <linux/spinlock.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/io.h>
-#include <asm/spinlock.h>
#include <asm/atomic.h>
#include <asm/pgtable.h>
@@ -198,8 +198,8 @@ void bad_user_access_alignment(const void *ptr)
{
printk(KERN_ERR "bad user access alignment: ptr = %p, pc = %p\n", ptr,
__builtin_return_address(0));
- current->tss.error_code = 0;
- current->tss.trap_no = 11;
+ current->thread.error_code = 0;
+ current->thread.trap_no = 11;
force_sig(SIGBUS, current);
/* die_if_kernel("Oops - bad user access alignment", regs, mode);*/
}
@@ -210,8 +210,8 @@ asmlinkage void do_undefinstr(int address, struct pt_regs *regs, int mode)
printk(KERN_INFO "%s (%d): undefined instruction: pc=%08lx\n",
current->comm, current->pid, instruction_pointer(regs));
#endif
- current->tss.error_code = 0;
- current->tss.trap_no = 6;
+ current->thread.error_code = 0;
+ current->thread.trap_no = 6;
force_sig(SIGILL, current);
die_if_kernel("Oops - undefined instruction", regs, mode);
}
@@ -222,8 +222,8 @@ asmlinkage void do_excpt(int address, struct pt_regs *regs, int mode)
printk(KERN_INFO "%s (%d): address exception: pc=%08lx\n",
current->comm, current->pid, instruction_pointer(regs));
#endif
- current->tss.error_code = 0;
- current->tss.trap_no = 11;
+ current->thread.error_code = 0;
+ current->thread.trap_no = 11;
force_sig(SIGBUS, current);
die_if_kernel("Oops - address exception", regs, mode);
}
@@ -292,9 +292,7 @@ asmlinkage int arm_syscall (int no, struct pt_regs *regs)
case 2: /* sys_cacheflush */
#ifdef CONFIG_CPU_32
/* r0 = start, r1 = length, r2 = flags */
- processor.u.armv3v4._flush_cache_area(regs->ARM_r0,
- regs->ARM_r1,
- 1);
+ cpu_flush_cache_area(regs->ARM_r0, regs->ARM_r1, 1);
#endif
break;
@@ -367,7 +365,7 @@ asmlinkage void baddataabort(int code, unsigned long instr, struct pt_regs *regs
{
pgd_t *pgd;
- printk ("current->tss.memmap = %08lX\n", current->tss.memmap);
+ printk ("current->thread.memmap = %08lX\n", current->thread.memmap);
pgd = pgd_offset(current->mm, addr);
printk ("*pgd = %08lx", pgd_val (*pgd));
if (!pgd_none (*pgd)) {
@@ -387,3 +385,9 @@ asmlinkage void baddataabort(int code, unsigned long instr, struct pt_regs *regs
code, regs->ARM_pc, instr, regs->ARM_lr, regs->ARM_sp);
}
#endif
+
+asmlinkage void __div0(void)
+{
+ printk("Awooga, division by zero in kernel.\n");
+ __backtrace();
+}