summaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r--arch/arm/kernel/armksyms.c7
-rw-r--r--arch/arm/kernel/bios32.c65
-rw-r--r--arch/arm/kernel/bios32.h1
-rw-r--r--arch/arm/kernel/calls.S71
-rw-r--r--arch/arm/kernel/debug-armv.S15
-rw-r--r--arch/arm/kernel/dec21285.c4
-rw-r--r--arch/arm/kernel/entry-armo.S1
-rw-r--r--arch/arm/kernel/entry-armv.S10
-rw-r--r--arch/arm/kernel/entry-common.S129
-rw-r--r--arch/arm/kernel/head-armv.S70
-rw-r--r--arch/arm/kernel/process.c7
-rw-r--r--arch/arm/kernel/setup.c91
-rw-r--r--arch/arm/kernel/signal.c3
-rw-r--r--arch/arm/kernel/sys_arm.c84
-rw-r--r--arch/arm/kernel/time.c2
-rw-r--r--arch/arm/kernel/traps.c58
16 files changed, 383 insertions, 235 deletions
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index cdd7a9821..0caf4bf26 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -16,6 +16,7 @@
#include <asm/dma.h>
#include <asm/pgalloc.h>
#include <asm/proc-fns.h>
+#include <asm/processor.h>
#include <asm/semaphore.h>
#include <asm/system.h>
#include <asm/uaccess.h>
@@ -29,8 +30,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 pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
-
/*
* syscalls
*/
@@ -125,7 +124,6 @@ EXPORT_SYMBOL(cpu_cache_purge_area);
EXPORT_SYMBOL(__machine_arch_type);
/* networking */
-EXPORT_SYMBOL(csum_partial_copy);
EXPORT_SYMBOL(csum_partial_copy_nocheck);
EXPORT_SYMBOL(__csum_ipv6_magic);
@@ -172,8 +170,7 @@ EXPORT_SYMBOL_NOVERS(strpbrk);
EXPORT_SYMBOL_NOVERS(strtok);
EXPORT_SYMBOL_NOVERS(strrchr);
EXPORT_SYMBOL_NOVERS(strstr);
-EXPORT_SYMBOL_NOVERS(__memset);
-EXPORT_SYMBOL_NOVERS(memset); /* needed for some versions of gcc */
+EXPORT_SYMBOL_NOVERS(memset);
EXPORT_SYMBOL_NOVERS(memcpy);
EXPORT_SYMBOL_NOVERS(memmove);
EXPORT_SYMBOL_NOVERS(memcmp);
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index b9b7d57b4..d055ae1fb 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -5,6 +5,7 @@
*
* Bits taken from various places.
*/
+#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/errno.h>
@@ -33,8 +34,8 @@ void pcibios_report_device_errors(void)
continue;
pci_write_config_word(dev, PCI_STATUS, status & 0xf900);
- printk(KERN_DEBUG "PCI: status %04X on %s\n",
- status, dev->name);
+ printk(KERN_DEBUG "PCI: %02X:%02X: status %04X on %s\n",
+ dev->bus->number, dev->devfn, status, dev->name);
}
}
@@ -162,9 +163,10 @@ void __init pcibios_update_irq(struct pci_dev *dev, int irq)
*/
void __init pcibios_fixup_bus(struct pci_bus *bus)
{
- struct pci_dev *dev;
+ struct list_head *walk = &bus->devices;
- for (dev = bus->devices; dev; dev = dev->sibling) {
+ for (walk = walk->next; walk != &bus->devices; walk = walk->next) {
+ struct pci_dev *dev = pci_dev_b(walk);
u16 cmd;
/*
@@ -220,6 +222,7 @@ static u8 __init no_swizzle(struct pci_dev *dev, u8 *pin)
return 0;
}
+#ifdef CONFIG_FOOTBRIDGE
/* ebsa285 host-specific stuff */
static int irqmap_ebsa285[] __initdata = { IRQ_IN1, IRQ_IN0, IRQ_PCI, IRQ_IN3 };
@@ -255,7 +258,7 @@ static int irqmap_cats[] __initdata = { IRQ_PCI, IRQ_IN0, IRQ_IN1, IRQ_IN3 };
static int __init cats_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
if (dev->irq >= 128)
- return 16 + (dev->irq & 0x1f);
+ return dev->irq & 0x1f;
if (dev->irq >= 1 && dev->irq <= 4)
return irqmap_cats[dev->irq - 1];
@@ -313,17 +316,53 @@ static struct hw_pci netwinder_pci __initdata = {
no_swizzle,
netwinder_map_irq
};
+#endif
+
+#ifdef CONFIG_ARCH_NEXUSPCI
+/*
+ * Owing to a PCB cockup, issue A backplanes are wired thus:
+ *
+ * Slot 1 2 3 4 5 Bridge
+ * IRQ D C B A A
+ * A D C B B
+ * B A D C C
+ * C B A D D
+ *
+ * ID A31 A30 A29 A28 A27 A26
+ */
+
+static int irqmap_ftv[] __initdata = { IRQ_PCI_A, IRQ_PCI_B, IRQ_PCI_C, IRQ_PCI_D };
+
+static int __init ftv_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ return irqmap_ftv[(slot + pin) & 3];
+}
+
+/* ftv host-specific stuff */
+static struct hw_pci ftv_pci __initdata = {
+ plx90x0_init,
+ 0x9000,
+ 0x00100000,
+ no_swizzle,
+ ftv_map_irq
+};
+#endif
void __init pcibios_init(void)
{
struct hw_pci *hw_pci = NULL;
+#ifdef CONFIG_FOOTBRIDGE
if (machine_is_ebsa285())
hw_pci = &ebsa285_pci;
else if (machine_is_cats())
hw_pci = &cats_pci;
else if (machine_is_netwinder())
hw_pci = &netwinder_pci;
+#endif
+#ifdef CONFIG_ARCH_NEXUSPCI
+ hw_pci = &ftv_pci;
+#endif
if (hw_pci == NULL)
return;
@@ -346,12 +385,14 @@ void __init pcibios_init(void)
pci_fixup_irqs(hw_pci->swizzle, hw_pci->map_irq);
pci_set_bus_ranges();
+#ifdef CONFIG_FOOTBRIDGE
/*
* 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();
+#endif
}
char * __init pcibios_setup(char *str)
@@ -363,7 +404,17 @@ char * __init pcibios_setup(char *str)
return str;
}
-void __init
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+/*
+ * Assign new address to PCI resource. We hope our resource information
+ * is complete.
+ *
+ * Expects start=0, end=size-1, flags=resource type.
+ */
+int pci_assign_resource(struct pci_dev *dev, int i)
+{
+ return 0;
+}
+
+void pcibios_align_resource(void *data, struct resource *res, unsigned long size)
{
}
diff --git a/arch/arm/kernel/bios32.h b/arch/arm/kernel/bios32.h
index fb3117452..9a4380732 100644
--- a/arch/arm/kernel/bios32.h
+++ b/arch/arm/kernel/bios32.h
@@ -7,3 +7,4 @@ struct hw_pci {
};
void __init dc21285_init(void);
+void __init plx90x0_init(void);
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index 51f3dcde2..d8d416c4e 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -25,19 +25,19 @@
.long SYMBOL_NAME(sys_time)
.long SYMBOL_NAME(sys_mknod)
/* 15 */ .long SYMBOL_NAME(sys_chmod)
- .long SYMBOL_NAME(sys_lchown)
+ .long SYMBOL_NAME(sys_lchown16)
.long SYMBOL_NAME(sys_ni_syscall) /* was sys_break */
- .long SYMBOL_NAME(sys_stat)
+ .long SYMBOL_NAME(sys_ni_syscall) /* was sys_stat */
.long SYMBOL_NAME(sys_lseek)
/* 20 */ .long SYMBOL_NAME(sys_getpid)
- .long SYMBOL_NAME(sys_mount_wrapper)
+ .long SYMBOL_NAME(sys_mount)
.long SYMBOL_NAME(sys_oldumount)
- .long SYMBOL_NAME(sys_setuid)
- .long SYMBOL_NAME(sys_getuid)
+ .long SYMBOL_NAME(sys_setuid16)
+ .long SYMBOL_NAME(sys_getuid16)
/* 25 */ .long SYMBOL_NAME(sys_stime)
.long SYMBOL_NAME(sys_ptrace)
.long SYMBOL_NAME(sys_alarm)
- .long SYMBOL_NAME(sys_fstat)
+ .long SYMBOL_NAME(sys_ni_syscall) /* was sys_fstat */
.long SYMBOL_NAME(sys_pause)
/* 30 */ .long SYMBOL_NAME(sys_utime)
.long SYMBOL_NAME(sys_ni_syscall) /* was sys_stty */
@@ -55,11 +55,11 @@
.long SYMBOL_NAME(sys_times)
.long SYMBOL_NAME(sys_ni_syscall) /* was sys_prof */
/* 45 */ .long SYMBOL_NAME(sys_brk)
- .long SYMBOL_NAME(sys_setgid)
- .long SYMBOL_NAME(sys_getgid)
+ .long SYMBOL_NAME(sys_setgid16)
+ .long SYMBOL_NAME(sys_getgid16)
.long SYMBOL_NAME(sys_signal)
- .long SYMBOL_NAME(sys_geteuid)
-/* 50 */ .long SYMBOL_NAME(sys_getegid)
+ .long SYMBOL_NAME(sys_geteuid16)
+/* 50 */ .long SYMBOL_NAME(sys_getegid16)
.long SYMBOL_NAME(sys_acct)
.long SYMBOL_NAME(sys_umount)
.long SYMBOL_NAME(sys_ni_syscall) /* was sys_lock */
@@ -79,8 +79,8 @@
.long SYMBOL_NAME(sys_sigaction)
.long SYMBOL_NAME(sys_sgetmask)
.long SYMBOL_NAME(sys_ssetmask)
-/* 70 */ .long SYMBOL_NAME(sys_setreuid)
- .long SYMBOL_NAME(sys_setregid)
+/* 70 */ .long SYMBOL_NAME(sys_setreuid16)
+ .long SYMBOL_NAME(sys_setregid16)
.long SYMBOL_NAME(sys_sigsuspend_wrapper)
.long SYMBOL_NAME(sys_sigpending)
.long SYMBOL_NAME(sys_sethostname)
@@ -89,11 +89,11 @@
.long SYMBOL_NAME(sys_getrusage)
.long SYMBOL_NAME(sys_gettimeofday)
.long SYMBOL_NAME(sys_settimeofday)
-/* 80 */ .long SYMBOL_NAME(sys_getgroups)
- .long SYMBOL_NAME(sys_setgroups)
+/* 80 */ .long SYMBOL_NAME(sys_getgroups16)
+ .long SYMBOL_NAME(sys_setgroups16)
.long SYMBOL_NAME(old_select)
.long SYMBOL_NAME(sys_symlink)
- .long SYMBOL_NAME(sys_lstat)
+ .long SYMBOL_NAME(sys_ni_syscall) /* was sys_lstat */
/* 85 */ .long SYMBOL_NAME(sys_readlink)
.long SYMBOL_NAME(sys_uselib)
.long SYMBOL_NAME(sys_swapon)
@@ -104,7 +104,7 @@
.long SYMBOL_NAME(sys_truncate)
.long SYMBOL_NAME(sys_ftruncate)
.long SYMBOL_NAME(sys_fchmod)
-/* 95 */ .long SYMBOL_NAME(sys_fchown)
+/* 95 */ .long SYMBOL_NAME(sys_fchown16)
.long SYMBOL_NAME(sys_getpriority)
.long SYMBOL_NAME(sys_setpriority)
.long SYMBOL_NAME(sys_ni_syscall) /* was sys_profil */
@@ -132,7 +132,7 @@
/* 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) */
+ .long SYMBOL_NAME(sys_ni_syscall)
.long SYMBOL_NAME(sys_adjtimex)
/* 125 */ .long SYMBOL_NAME(sys_mprotect)
.long SYMBOL_NAME(sys_sigprocmask)
@@ -147,9 +147,9 @@
/* 135 */ .long SYMBOL_NAME(sys_sysfs)
.long SYMBOL_NAME(sys_personality)
.long SYMBOL_NAME(sys_ni_syscall) /* .long _sys_afs_syscall */
- .long SYMBOL_NAME(sys_setfsuid)
- .long SYMBOL_NAME(sys_setfsgid)
-/* 140 */ .long SYMBOL_NAME(sys_llseek_wrapper)
+ .long SYMBOL_NAME(sys_setfsuid16)
+ .long SYMBOL_NAME(sys_setfsgid16)
+/* 140 */ .long SYMBOL_NAME(sys_llseek)
.long SYMBOL_NAME(sys_getdents)
.long SYMBOL_NAME(sys_select)
.long SYMBOL_NAME(sys_flock)
@@ -173,14 +173,14 @@
.long SYMBOL_NAME(sys_sched_rr_get_interval)
.long SYMBOL_NAME(sys_nanosleep)
.long SYMBOL_NAME(sys_mremap)
- .long SYMBOL_NAME(sys_setresuid)
-/* 165 */ .long SYMBOL_NAME(sys_getresuid)
+ .long SYMBOL_NAME(sys_setresuid16)
+/* 165 */ .long SYMBOL_NAME(sys_getresuid16)
.long SYMBOL_NAME(sys_ni_syscall)
.long SYMBOL_NAME(sys_query_module)
.long SYMBOL_NAME(sys_poll)
.long SYMBOL_NAME(sys_nfsservctl)
-/* 170 */ .long SYMBOL_NAME(sys_setresgid)
- .long SYMBOL_NAME(sys_getresgid)
+/* 170 */ .long SYMBOL_NAME(sys_setresgid16)
+ .long SYMBOL_NAME(sys_getresgid16)
.long SYMBOL_NAME(sys_prctl)
.long SYMBOL_NAME(sys_rt_sigreturn_wrapper)
.long SYMBOL_NAME(sys_rt_sigaction)
@@ -191,7 +191,7 @@
.long SYMBOL_NAME(sys_rt_sigsuspend_wrapper)
/* 180 */ .long SYMBOL_NAME(sys_pread)
.long SYMBOL_NAME(sys_pwrite)
- .long SYMBOL_NAME(sys_chown)
+ .long SYMBOL_NAME(sys_chown16)
.long SYMBOL_NAME(sys_getcwd)
.long SYMBOL_NAME(sys_capget)
/* 185 */ .long SYMBOL_NAME(sys_capset)
@@ -207,8 +207,27 @@
/* 195 */ .long SYMBOL_NAME(sys_stat64)
.long SYMBOL_NAME(sys_lstat64)
.long SYMBOL_NAME(sys_fstat64)
+ .long SYMBOL_NAME(sys_lchown)
+ .long SYMBOL_NAME(sys_getuid)
+/* 200 */ .long SYMBOL_NAME(sys_getgid)
+ .long SYMBOL_NAME(sys_geteuid)
+ .long SYMBOL_NAME(sys_getegid)
+ .long SYMBOL_NAME(sys_setreuid)
+ .long SYMBOL_NAME(sys_setregid)
+/* 205 */ .long SYMBOL_NAME(sys_getgroups)
+ .long SYMBOL_NAME(sys_setgroups)
+ .long SYMBOL_NAME(sys_fchown)
+ .long SYMBOL_NAME(sys_setresuid)
+ .long SYMBOL_NAME(sys_getresuid)
+/* 210 */ .long SYMBOL_NAME(sys_setresgid)
+ .long SYMBOL_NAME(sys_getresgid)
+ .long SYMBOL_NAME(sys_chown)
+ .long SYMBOL_NAME(sys_setuid)
+ .long SYMBOL_NAME(sys_setgid)
+/* 215 */ .long SYMBOL_NAME(sys_setfsuid)
+ .long SYMBOL_NAME(sys_setfsgid)
- .rept NR_syscalls-197
+ .rept NR_syscalls-216
.long SYMBOL_NAME(sys_ni_syscall)
.endr
#endif
diff --git a/arch/arm/kernel/debug-armv.S b/arch/arm/kernel/debug-armv.S
index fef1489b7..5802dac70 100644
--- a/arch/arm/kernel/debug-armv.S
+++ b/arch/arm/kernel/debug-armv.S
@@ -134,19 +134,26 @@
#elif defined(CONFIG_ARCH_SA1100)
.macro addruart,rx
mov \rx, #0xf8000000
- add \rx, \rx, #0x00050000
+ add \rx, \rx, #0x00050000 @ Ser3
+ @add \rx, \rx, #0x00010000 @ Ser1
.endm
.macro senduart,rd,rx
- str \rd, [\rx, #0x14] @ UARTDR
+ str \rd, [\rx, #0x14] @ UTDR
.endm
- .macro busyuart,rd,rx
+ .macro waituart,rd,rx
1001: ldr \rd, [\rx, #0x20] @ UTSR1
- tst \rd, #1 << 2
+ tst \rd, #1 << 2 @ UTSR1_TNF
beq 1001b
.endm
+ .macro busyuart,rd,rx
+1001: ldr \rd, [\rx, #0x20] @ UTSR1
+ tst \rd, #1 << 0 @ UTSR1_TBY
+ bne 1001b
+ .endm
+
#else
#error Unknown architecture
#endif
diff --git a/arch/arm/kernel/dec21285.c b/arch/arm/kernel/dec21285.c
index dc7cc054e..6158e995a 100644
--- a/arch/arm/kernel/dec21285.c
+++ b/arch/arm/kernel/dec21285.c
@@ -220,7 +220,9 @@ void __init dc21285_init(void)
#ifdef CONFIG_HOST_FOOTBRIDGE
csrio.flags = IORESOURCE_IO;
+ csrio.name = "DC21285";
csrmem.flags = IORESOURCE_MEM;
+ csrmem.name = "DC21285";
allocate_resource(&ioport_resource, &csrio, 128,
0xff00, 0xffff, 128, NULL, NULL);
@@ -244,7 +246,7 @@ void __init dc21285_init(void)
(1 << 31) | (1 << 29) | (1 << 28) | (1 << 24);
#endif
- printk(KERN_DEBUG"PCI: DC21285 footbridge, revision %02lX\n",
+ printk(KERN_DEBUG "PCI: DC21285 footbridge, revision %02lX\n",
*CSR_CLASSREV & 0xff);
pci_scan_bus(0, &dc21285_ops, NULL);
diff --git a/arch/arm/kernel/entry-armo.S b/arch/arm/kernel/entry-armo.S
index 5d9ce0ac6..f2dc9e36c 100644
--- a/arch/arm/kernel/entry-armo.S
+++ b/arch/arm/kernel/entry-armo.S
@@ -535,7 +535,6 @@ Ldata_unknown: @ Part of jumptable
mov r0, r1
mov r1, r4
mov r2, r3
- mov r3, lr
b baddataabort
Ldata_ldrstr_post:
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 6d4107ede..f4f03ee93 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -429,7 +429,10 @@ __und_invalid: sub sp, sp, #S_FRAME_SIZE
and r2, r6, #31 @ int mode
b SYMBOL_NAME(bad_mode)
-
+#ifdef CONFIG_NWFPE
+ /* The FPE is always present */
+ .equ fpe_not_present, 0
+#else
wfs_mask_data: .word 0x0e200110 @ WFS/RFS
.word 0x0fef0fff
.word 0x0d0d0100 @ LDF [sp]/STF [sp]
@@ -466,6 +469,7 @@ fpe_not_present:
add r5, r5, r4, lsl #2
str r5, [sp, r6, lsr #14] @ Save reg
mov pc, r9
+#endif
/*
* SVC mode handlers
@@ -685,11 +689,11 @@ 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
+ ldr r2, [r1, #TSS_DOMAIN]
ldmfd sp!, {ip}
+ mcr p15, 0, r2, c3, c0 @ Set domain register
msr spsr, ip @ Save tasks CPSR into SPSR for this return
ldmfd sp!, {r4 - sl, fp, pc}^ @ Load all regs saved previously
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index bdf6de6b3..2be1a6012 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -3,6 +3,9 @@
* All exits to user mode from the kernel go through this code.
*/
+#define S_OFF 8
+#define SYSCALL_REGS r4, r5
+
/*
* 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
@@ -16,9 +19,9 @@
.align 5
fast_syscall_return:
- str r0, [sp, #S_R0 + 4] @ returned r0
+ str r0, [sp, #S_R0 + S_OFF] @ returned r0
slow_syscall_return:
- add sp, sp, #4
+ add sp, sp, #S_OFF
ret_from_sys_call:
#ifdef HARVARD_CACHE
ldr r0, bh_data
@@ -74,65 +77,71 @@ ret_from_exception:
/*=============================================================================
* SWI handler
*-----------------------------------------------------------------------------
- *
- * We now handle sys-call tracing, and the errno in the task structure.
- * Still have a problem with >4 arguments for functions. Theres only
- * a couple of functions in the code that have 5 arguments, so Im not
- * too worried.
*/
+/*
+ * Create some aliases for some registers. These should allow
+ * us to have in theory up to 7 arguments to a function.
+ */
+scno .req r9 @ syscall number
+tbl .req r8 @ syscall table pointer
+tip .req r7 @ temporary IP
+
.align 5
vector_swi: save_user_regs
mask_pc lr, lr
mov fp, #0
- ldr r6, [lr, #-4] @ get SWI instruction
- arm700_bug_check r6, r7
+ ldr scno, [lr, #-4] @ get SWI instruction
+ arm700_bug_check scno, ip
#ifdef CONFIG_ALIGNMENT_TRAP
- ldr r7, .LCswi
- ldr r7, [r7]
- mcr p15, 0, r7, c1, c0
+ ldr ip, .LCswi
+ ldr ip, [ip]
+ mcr p15, 0, ip, c1, c0
#endif
- enable_irqs r7
+ enable_irqs ip
- str r4, [sp, #-4]! @ new style: (r0 = arg1, r4 = arg5)
+ stmdb sp!, {SYSCALL_REGS} @ new style: (r0 = arg1, r4 = arg5, r5 = arg6)
+ @ Note that we dont have to handle
+ @ sys_syscalls arg7 here
adrsvc al, lr, fast_syscall_return
- bic r6, r6, #0xff000000 @ mask off SWI op-code
- eor r6, r6, #OS_NUMBER<<20 @ check OS number
- cmp r6, #NR_syscalls @ check upper syscall limit
+ bic scno, scno, #0xff000000 @ mask off SWI op-code
+ eor scno, scno, #OS_NUMBER<<20 @ check OS number
+ cmp scno, #NR_syscalls @ check upper syscall limit
bcs 2f
- get_current_task r7
- ldr ip, [r7, #TSK_FLAGS] @ check for syscall tracing
- adr r5, SYMBOL_NAME(sys_call_table)
+ get_current_task ip
+ ldr ip, [ip, #TSK_FLAGS] @ check for syscall tracing
+ adr tbl, SYMBOL_NAME(sys_call_table)
tst ip, #PF_TRACESYS
- ldreq pc, [r5, r6, lsl #2] @ call sys routine
+ ldreq pc, [tbl, scno, lsl #2] @ call sys routine
- ldr r7, [sp, #S_IP + 4] @ save old IP
- mov r0, #0
- str r0, [sp, #S_IP + 4] @ trace entry [IP = 0]
+ ldr tip, [sp, #S_IP + S_OFF] @ save old IP
+ mov ip, #0
+ str ip, [sp, #S_IP + S_OFF] @ trace entry [IP = 0]
bl SYMBOL_NAME(syscall_trace)
- str r7, [sp, #S_IP + 4]
+ str tip, [sp, #S_IP + S_OFF]
- ldmib sp, {r0 - r3} @ have to reload r0 - r3
+ add ip, sp, #S_OFF
+ ldmia ip, {r0 - r3} @ have to reload r0 - r3
mov lr, pc
- ldr pc, [r5, r6, lsl #2] @ call sys routine
- str r0, [sp, #S_R0 + 4] @ returned r0
+ ldr pc, [tbl, scno, lsl #2] @ call sys routine
+ str r0, [sp, #S_R0 + S_OFF] @ returned r0
- mov r0, #1
- str r0, [sp, #S_IP + 4] @ trace exit [IP = 1]
+ mov ip, #1
+ str ip, [sp, #S_IP + S_OFF] @ trace exit [IP = 1]
bl SYMBOL_NAME(syscall_trace)
- str r7, [sp, #S_IP + 4]
+ str tip, [sp, #S_IP + S_OFF]
b slow_syscall_return
-2: add r1, sp, #4
- tst r6, #0x00f00000 @ is it a Unix SWI?
+2: add r1, sp, #S_OFF
+ tst scno, #0x00f00000 @ is it a Unix SWI?
bne 3f
- subs r0, r6, #(KSWI_SYS_BASE - KSWI_BASE)
+ subs r0, scno, #(KSWI_SYS_BASE - KSWI_BASE)
bcs SYMBOL_NAME(arm_syscall)
b SYMBOL_NAME(sys_ni_syscall) @ not private func
-3: eor r0, r6, #OS_NUMBER <<20 @ Put OS number back
+3: eor r0, scno, #OS_NUMBER <<20 @ Put OS number back
adrsvc al, lr, slow_syscall_return
b SYMBOL_NAME(deferred)
@@ -150,67 +159,49 @@ ENTRY(sys_call_table)
@ r0 = syscall number
@ r5 = syscall table
SYMBOL_NAME(sys_syscall):
- eor r6, r0, #OS_NUMBER << 20
- cmp r6, #NR_syscalls @ check range
- 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]
+ eor scno, r0, #OS_NUMBER << 20
+ cmp scno, #NR_syscalls @ check range
+ add ip, sp, #S_OFF
+ ldmleib ip, {r0 - r3, SYSCALL_REGS} @ get our args
+ stmleia sp, {SYSCALL_REGS} @ Put our arg on the stack
+ ldrle pc, [tbl, scno, lsl #2]
mov r0, #-ENOSYS
- mov pc, lr
+ RETINSTR(mov,pc,lr)
sys_fork_wrapper:
- add r0, sp, #4
+ add r0, sp, #S_OFF
b SYMBOL_NAME(sys_fork)
sys_vfork_wrapper:
- add r0, sp, #4
+ add r0, sp, #S_OFF
b SYMBOL_NAME(sys_vfork)
sys_execve_wrapper:
- add r3, sp, #4
+ add r3, sp, #S_OFF
b SYMBOL_NAME(sys_execve)
-sys_mount_wrapper:
- mov r6, lr
- add r5, sp, #4
- str r5, [sp]
- str r4, [sp, #-4]!
- bl SYMBOL_NAME(sys_compat_mount)
- add sp, sp, #4
- RETINSTR(mov,pc,r6)
-
sys_clone_wapper:
- add r2, sp, #4
+ add r2, sp, #S_OFF
b SYMBOL_NAME(sys_clone)
-sys_llseek_wrapper:
- mov r6, lr
- add r5, sp, #4
- str r5, [sp]
- str r4, [sp, #-4]!
- bl SYMBOL_NAME(sys_compat_llseek)
- add sp, sp, #4
- RETINSTR(mov,pc,r6)
-
sys_sigsuspend_wrapper:
- add r3, sp, #4
+ add r3, sp, #S_OFF
b SYMBOL_NAME(sys_sigsuspend)
sys_rt_sigsuspend_wrapper:
- add r2, sp, #4
+ add r2, sp, #S_OFF
b SYMBOL_NAME(sys_rt_sigsuspend)
sys_sigreturn_wrapper:
- add r0, sp, #4
+ add r0, sp, #S_OFF
b SYMBOL_NAME(sys_sigreturn)
sys_rt_sigreturn_wrapper:
- add r0, sp, #4
+ add r0, sp, #S_OFF
b SYMBOL_NAME(sys_rt_sigreturn)
sys_sigaltstack_wrapper:
- ldr r2, [sp, #4 + S_SP]
+ ldr r2, [sp, #S_OFF + S_SP]
b do_sigaltstack
.data
diff --git a/arch/arm/kernel/head-armv.S b/arch/arm/kernel/head-armv.S
index 2996d89af..35e71a4a9 100644
--- a/arch/arm/kernel/head-armv.S
+++ b/arch/arm/kernel/head-armv.S
@@ -69,7 +69,7 @@ ENTRY(_stext)
* r1 contains the unique architecture number. See
* linux/arch/arm/kernel/setup.c machine_desc[] array for the complete
* list. If you require a new number, please follow the instructions
- * given in Documentation/ARM-README.
+ * given in Documentation/arm/README.
*/
__entry: teq r0, #0
movne r0, #'i'
@@ -83,7 +83,7 @@ __entry: teq r0, #0
moveq r0, #'a'
beq __error
bl __create_page_tables
- adr lr, __aligned_call
+ adr lr, __ret
add pc, r10, #12 @ flush caches (returns ctrl reg)
__switch_data: .long __mmap_switched
@@ -94,16 +94,11 @@ __switch_data: .long __mmap_switched
.long SYMBOL_NAME(cr_alignment)
.long SYMBOL_NAME(init_task_union)+8192
- /*
- * This needs to be aligned to a cache line.
- */
- .align 5
-__aligned_call:
- ldr lr, __switch_data
-#ifdef CONFIG_ALIGNMENT_TRAP
- orr r0, r0, #2 @ ...........A.
-#endif
+__ret: ldr lr, __switch_data
mcr p15, 0, r0, c1, c0
+ mov r0, r0
+ mov r0, r0
+ mov r0, r0
mov pc, lr
/*
@@ -126,6 +121,9 @@ __mmap_switched:
str r9, [r6] @ Save processor ID
str r1, [r7] @ Save machine type
+#ifdef CONFIG_ALIGNMENT_TRAP
+ orr r0, r0, #2 @ ...........A.
+#endif
bic r2, r0, #2 @ Clear 'A' bit
stmia r8, {r0, r2} @ Save control register values
b SYMBOL_NAME(start_kernel)
@@ -137,16 +135,16 @@ __mmap_switched:
* amount which are required to get the kernel running, which
* generally means mapping in the kernel code.
*
- * We only map in 2MB of RAM, which should be sufficient in
+ * We only map in 4MB of RAM, which should be sufficient in
* all cases.
*
- * r4 = physical address of page tables
* r5 = physical address of start of RAM
* r6 = physical IO address
* r7 = byte offset into page tables for IO
* r8 = page table flags
*/
__create_page_tables:
+ add r4, r5, #SWAPPER_PGDIR_OFFSET
mov r0, r4
mov r3, #0
add r2, r0, #0x4000 @ Clear page table
@@ -157,13 +155,22 @@ __create_page_tables:
teq r0, r2
bne 1b
/*
- * map in two sections (2MB) for kernel.
+ * Create identity mapping for first MB of kernel.
+ * map in four sections (4MB) for kernel.
* these are marked cacheable and bufferable.
+ *
+ * The identity mapping will be removed by paging_init()
*/
- add r0, r4, #(TEXTADDR - 0x8000) >> 18
mov r3, #0x0c
orr r3, r3, r8
add r3, r3, r5
+ add r0, r4, r5, lsr #18
+ str r3, [r0]
+ add r0, r4, #(TEXTADDR - 0x8000) >> 18
+ str r3, [r0], #4
+ add r3, r3, #1 << 20
+ str r3, [r0], #4
+ add r3, r3, #1 << 20
str r3, [r0], #4
add r3, r3, #1 << 20
str r3, [r0], #4
@@ -174,8 +181,11 @@ __create_page_tables:
* via a serial before paging_init.
*/
add r0, r4, r7
+ rsb r3, r7, #0x4000 @ PTRS_PER_PGD*sizeof(long)
+ cmp r3, #0x0800
+ addge r2, r0, #0x0800
+ addlt r2, r0, r3
orr r3, r6, r8
- add r2, r0, #0x0800
1: str r3, [r0], #4
add r3, r3, #1 << 20
teq r0, r2
@@ -273,7 +283,7 @@ __lookup_processor_type:
* Lookup machine architecture
* r1 = machine architecture number
* Returns:
- * r4 = physical address of page tables
+ * r4 = unused word
* r5 = physical start address of RAM
* r6 = physical address of IO
* r7 = byte offset into page tables for IO
@@ -284,7 +294,6 @@ __lookup_architecture_type:
adr r4, __arch_types_start
add r4, r4, r1, lsl #4
ldmia r4, {r4, r5, r6, r7}
- add r4, r5, #SWAPPER_PGDIR_OFFSET
mov r7, r7, lsr #18
mov pc, lr
1: mov r7, #0
@@ -330,20 +339,20 @@ __arch_types_start:
@ 0x04 - DEC EBSA285
.long 0
.long 0
- .long 0x24000000 @ I/O base address (0x42000000 -> 0xfe000000)
- .long 0xe0000000
+ .long DC21285_ARMCSR_BASE
+ .long 0xfe000000
@ 0x05 - Rebel.com NetWinder
.long 0
.long 0
- .long 0x24000000 @ I/O base address (0x42000000 -> 0xfe000000)
- .long 0xe0000000
+ .long DC21285_ARMCSR_BASE
+ .long 0xfe000000
@ 0x06 - CATS
.long 0
.long 0
- .long 0x24000000 @ I/O base address (0x42000000 -> 0xfe000000)
- .long 0xe0000000
+ .long DC21285_ARMCSR_BASE
+ .long 0xfe000000
@ 0x07 - tbox
.long 0
@@ -398,9 +407,16 @@ __arch_types_start:
.long 0
.long 0
.long 0
-__arch_types_end:
- @ unknown - SA1100
+
+ @ 0x10 - SA1100
.long 0
.long 0xc0000000
.long 0x80000000
- .long 0xe0000000
+ .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/process.c b/arch/arm/kernel/process.c
index 9afacbde3..46afd5938 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -50,13 +50,13 @@ void enable_hlt(void)
static int __init nohlt_setup(char *__unused)
{
hlt_counter = 1;
- return 0;
+ return 1;
}
static int __init hlt_setup(char *__unused)
{
hlt_counter = 0;
- return 0;
+ return 1;
}
__setup("nohlt", nohlt_setup);
@@ -114,6 +114,7 @@ void machine_halt(void)
void machine_power_off(void)
{
+ arch_power_off();
}
void show_regs(struct pt_regs * regs)
@@ -284,7 +285,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
int dump_fpu (struct pt_regs *regs, struct user_fp *fp)
{
if (current->used_math)
- memcpy(fp, &current->thread.fpstate.soft, sizeof (fp));
+ memcpy(fp, &current->thread.fpstate.soft, sizeof (*fp));
return current->used_math;
}
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index a060bf4d9..a2f7292f6 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -54,13 +54,13 @@ struct meminfo meminfo;
struct machine_desc {
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 */
unsigned int broken_hlt :1; /* hlt is broken */
unsigned int soft_reboot :1; /* soft reboot */
- unsigned int video_start; /* start of video RAM */
- unsigned int video_end; /* end of video RAM */
void (*fixup)(struct machine_desc *,
struct param_struct *, char **);
};
@@ -201,7 +201,7 @@ parse_cmdline(char **cmdline_p, char *from)
meminfo.nr_banks = 0;
}
- start = 0;
+ start = PHYS_OFFSET;
size = memparse(from + 4, &from);
if (*from == '@')
start = memparse(from + 1, &from);
@@ -250,17 +250,18 @@ static void __init setup_initrd(unsigned int start, unsigned int size)
}
#define O_PFN_DOWN(x) ((x) >> PAGE_SHIFT)
-#define P_PFN_DOWN(x) O_PFN_DOWN((x) - PHYS_OFFSET)
#define V_PFN_DOWN(x) O_PFN_DOWN(__pa(x))
#define O_PFN_UP(x) (PAGE_ALIGN(x) >> PAGE_SHIFT)
-#define P_PFN_UP(x) O_PFN_UP((x) - PHYS_OFFSET)
#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)
@@ -277,10 +278,10 @@ static unsigned int __init find_bootmap_pfn(unsigned int bootmap_pages)
*/
#ifdef CONFIG_BLK_DEV_INITRD
if (initrd_start) {
- if (__pa(initrd_end) > (meminfo.end + PHYS_OFFSET)) {
+ if (__pa(initrd_end) > meminfo.end) {
printk ("initrd extends beyond end of memory "
"(0x%08lx > 0x%08lx) - disabling initrd\n",
- __pa(initrd_end), meminfo.end + PHYS_OFFSET);
+ __pa(initrd_end), meminfo.end);
initrd_start = 0;
initrd_end = 0;
}
@@ -373,7 +374,7 @@ static void __init setup_bootmem(void)
#endif
#ifdef CONFIG_BLK_DEV_INITRD
if (initrd_start)
- reserve_bootmem(O_PFN_DOWN(initrd_start),
+ reserve_bootmem(V_PFN_DOWN(initrd_start),
PFN_RANGE(initrd_start, initrd_end));
#endif
}
@@ -528,16 +529,66 @@ fixup_coebsa285(struct machine_desc *desc, struct param_struct *params,
char **cmdline)
{
#if 0
- if (machine_is_co285()) {
- extern unsigned long boot_memory_end;
- extern char boot_command_line[];
+ extern unsigned long boot_memory_end;
+ extern char boot_command_line[];
- meminfo.nr_banks = 1;
- meminfo.bank[0].start = PHYS_OFFSET;
- meminfo.bank[0].size = boot_memory_end;
+ meminfo.nr_banks = 1;
+ meminfo.bank[0].start = PHYS_OFFSET;
+ meminfo.bank[0].size = boot_memory_end;
+
+ *cmdline = boot_command_line;
+#endif
+}
- *cmdline = boot_command_line;
+static void __init
+fixup_sa1100(struct machine_desc *desc, struct param_struct *params,
+ char **cmdline)
+{
+#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;
+ }
+ meminfo.bank[i].start = mem_desc[i].phys_start;
+ meminfo.bank[i].size = mem_desc[i].length;
}
+ meminfo.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), 0x00400000 );
+#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_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
}
@@ -565,7 +616,7 @@ static struct machine_desc machine_desc[] __initdata = {
NO_VIDEO,
0, 0, 0, 0, 0,
NULL
- }, { "Nexus-FTV/PCI", /* Philip Blundell */
+ }, { "FTV/PCI", /* Philip Blundell */
NO_PARAMS,
NO_VIDEO,
0, 0, 0, 0, 0,
@@ -627,9 +678,15 @@ static struct machine_desc machine_desc[] __initdata = {
NULL
}, { "Shark", /* Alexander Schulz */
NO_PARAMS,
- NO_VIDEO,
+ /* do you really mean 0x200000? */
+ 0x06000000, 0x06000000+0x00200000,
0, 0, 0, 0, 0,
NULL
+ }, { "SA1100-based", /* Nicolas Pitre */
+ NO_PARAMS,
+ NO_VIDEO,
+ 0, 0, 0, 0, 0,
+ fixup_sa1100
}
};
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 852bbfac1..f9fbd2536 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -18,6 +18,7 @@
#include <linux/stddef.h>
#include <linux/binfmts.h>
#include <linux/tty.h>
+#include <linux/highuid.h>
#include <asm/ucontext.h>
#include <asm/uaccess.h>
@@ -277,6 +278,7 @@ setup_sigcontext(struct sigcontext *sc, /*struct _fpstate *fpstate,*/
err |= __put_user (current->thread.trap_no, &sc->trap_no);
err |= __put_user (current->thread.error_code, &sc->error_code);
+ err |= __put_user (current->thread.address, &sc->fault_address);
err |= __put_user (mask, &sc->oldmask);
return err;
@@ -500,6 +502,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
info.si_code = SI_USER;
info.si_pid = current->p_pptr->pid;
info.si_uid = current->p_pptr->uid;
+ info.si_uid16 = high2lowuid(current->p_pptr->uid);
}
/* If the (new) signal is now blocked, requeue it. */
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c
index 408149bc5..5e989663b 100644
--- a/arch/arm/kernel/sys_arm.c
+++ b/arch/arm/kernel/sys_arm.c
@@ -79,12 +79,26 @@ out:
return error;
}
+#define PGOFF_SHIFT (PAGE_SHIFT - 12)
+#define PGOFF_MASK (~((1 << PGOFF_SHIFT) - 1))
+
/*
- * Perform the select(nd, in, out, ex, tv) and mmap() system
- * calls. ARM Linux didn't use to be able to handle more than
- * 4 system call parameters, so these system calls used a memory
- * block for parameter passing..
+ * Note: off_4k is always units of 4K. If we can't do the requested
+ * offset, we return EINVAL.
*/
+asmlinkage long
+sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
+ unsigned long flags, unsigned long fd, unsigned long off_4k)
+{
+ unsigned long pgoff;
+
+ if (off_4k & ~PGOFF_MASK)
+ return -EINVAL;
+
+ pgoff = off_4k >> PGOFF_SHIFT;
+
+ return do_mmap2(addr, len, prot, flags, fd, pgoff);
+}
struct mmap_arg_struct {
unsigned long addr;
@@ -112,6 +126,10 @@ out:
return error;
}
+/*
+ * Perform the select(nd, in, out, ex, tv) and mmap() system
+ * calls.
+ */
extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
struct sel_arg_struct {
@@ -251,48 +269,11 @@ out:
return error;
}
-/*
- * Detect the old function calling standard
- */
-static inline unsigned long old_calling_standard (struct pt_regs *regs)
-{
- unsigned long instr, *pcv = (unsigned long *)(instruction_pointer(regs) - 8);
- return (!get_user (instr, pcv) && instr == 0xe1a0300d);
-}
-
/* Compatability functions - we used to pass 5 parameters as r0, r1, r2, *r3, *(r3+4)
* We now use r0 - r4, and return an error if the old style calling standard is used.
* Eventually these functions will disappear.
*/
-asmlinkage int
-sys_compat_llseek (unsigned int fd, unsigned long offset_high, unsigned long offset_low,
- loff_t *result, unsigned int origin, struct pt_regs *regs)
-{
- extern int sys_llseek (unsigned int, unsigned long, unsigned long, loff_t *, unsigned int);
-
- if (old_calling_standard (regs)) {
- printk (KERN_NOTICE "%s (%d): unsupported llseek call standard\n",
- current->comm, current->pid);
- return -EINVAL;
- }
- return sys_llseek (fd, offset_high, offset_low, result, origin);
-}
-
-asmlinkage int
-sys_compat_mount (char *devname, char *dirname, char *type, unsigned long flags, void *data,
- struct pt_regs *regs)
-{
- extern int sys_mount (char *, char *, char *, unsigned long, void *);
-
- if (old_calling_standard (regs)) {
- printk (KERN_NOTICE "%s (%d): unsupported mount call standard\n",
- current->comm, current->pid);
- return -EINVAL;
- }
- return sys_mount (devname, dirname, type, flags, data);
-}
-
-asmlinkage int sys_uname (struct old_utsname * name)
+asmlinkage int sys_uname(struct old_utsname * name)
{
static int warned = 0;
int err;
@@ -331,15 +312,15 @@ asmlinkage int sys_olduname(struct oldold_utsname * name)
down(&uts_sem);
error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
- error -= __put_user(0,name->sysname+__OLD_UTS_LEN);
- error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
- error -= __put_user(0,name->nodename+__OLD_UTS_LEN);
- error -= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
- error -= __put_user(0,name->release+__OLD_UTS_LEN);
- error -= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
- error -= __put_user(0,name->version+__OLD_UTS_LEN);
- error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
- error -= __put_user(0,name->machine+__OLD_UTS_LEN);
+ error |= __put_user(0,name->sysname+__OLD_UTS_LEN);
+ error |= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
+ error |= __put_user(0,name->nodename+__OLD_UTS_LEN);
+ error |= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
+ error |= __put_user(0,name->release+__OLD_UTS_LEN);
+ error |= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
+ error |= __put_user(0,name->version+__OLD_UTS_LEN);
+ error |= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
+ error |= __put_user(0,name->machine+__OLD_UTS_LEN);
up(&uts_sem);
@@ -354,4 +335,3 @@ asmlinkage int sys_pause(void)
schedule();
return -ERESTARTNOHAND;
}
-
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index c48c62108..67c2597e6 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -112,7 +112,7 @@ void do_gettimeofday(struct timeval *tv)
/*
* xtime is atomically updated in timer_bh. lost_ticks is
- * nonzero if the tiemr bottom half hasnt executed yet.
+ * nonzero if the timer bottom half hasnt executed yet.
*/
if (lost_ticks)
tv->tv_usec += USECS_PER_JIFFY;
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 26ecfa194..ac15651d3 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -187,10 +187,11 @@ void die(const char *str, struct pt_regs *regs, int err)
dump_instr(instruction_pointer(regs), 0);
}
- spin_unlock_irq(&die_lock);
+ spin_unlock_irq(&die_lock);
+ do_exit(SIGSEGV);
}
-static void die_if_kernel(const char *str, struct pt_regs *regs, int err)
+void die_if_kernel(const char *str, struct pt_regs *regs, int err)
{
if (user_mode(regs))
return;
@@ -241,11 +242,10 @@ asmlinkage void do_unexp_fiq (struct pt_regs *regs)
}
/*
- * bad_mode handles the impossible case in the vectors.
- * If you see one of these, then it's extremely serious,
- * and could mean you have buggy hardware. It never
- * returns, and never tries to sync. We hope that we
- * can dump out some state information...
+ * bad_mode handles the impossible case in the vectors. If you see one of
+ * these, then it's extremely serious, and could mean you have buggy hardware.
+ * It never returns, and never tries to sync. We hope that we can at least
+ * dump out some state information...
*/
asmlinkage void bad_mode(struct pt_regs *regs, int reason, int proc_mode)
{
@@ -255,7 +255,8 @@ asmlinkage void bad_mode(struct pt_regs *regs, int reason, int proc_mode)
handler[reason], processor_modes[proc_mode]);
/*
- * Dump out the vectors and stub routines
+ * Dump out the vectors and stub routines. Maybe a better solution
+ * would be to dump them out only if we detect that they are corrupted.
*/
printk(KERN_CRIT "Vectors:\n");
dump_mem(0, 0x40);
@@ -279,6 +280,9 @@ asmlinkage void math_state_restore (void)
current->used_math = 1;
}
+/*
+ * Handle some more esoteric system calls
+ */
asmlinkage int arm_syscall (int no, struct pt_regs *regs)
{
switch (no) {
@@ -295,7 +299,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 */
+ /* r0 = start, r1 = end, r2 = flags */
cpu_flush_cache_area(regs->ARM_r0, regs->ARM_r1, 1);
#endif
break;
@@ -308,7 +312,7 @@ asmlinkage int arm_syscall (int no, struct pt_regs *regs)
if (no <= 0x7ff)
return -ENOSYS;
#ifdef CONFIG_DEBUG_USER
- /* experiance shows that these seem to indicate that
+ /* experience shows that these seem to indicate that
* something catastrophic has happened
*/
printk("[%d] %s: arm syscall %d\n", current->pid, current->comm, no);
@@ -357,16 +361,19 @@ asmlinkage void arm_invalidptr(const char *function, int size)
function, __builtin_return_address(0), size);
}
-#ifdef CONFIG_CPU_26
-asmlinkage void baddataabort(int code, unsigned long instr, struct pt_regs *regs)
+/*
+ * A data abort trap was taken, but the instruction was not an instruction
+ * which should cause the trap to be taken. Try to abort it. Note that
+ * the while(1) is there because we cannot currently handle returning from
+ * this function.
+ */
+asmlinkage void
+baddataabort(int code, unsigned long instr, struct pt_regs *regs)
{
unsigned long phys, addr = instruction_pointer(regs);
#ifdef CONFIG_DEBUG_ERRORS
- printk("pid=%d\n", current->pid);
-
- show_regs(regs);
- dump_instr(instruction_pointer(regs), 1);
+ dump_instr(addr, 1);
{
pgd_t *pgd;
@@ -385,10 +392,10 @@ asmlinkage void baddataabort(int code, unsigned long instr, struct pt_regs *regs
printk ("\n");
}
#endif
- panic("unknown data abort code %d [pc=%08lx *pc=%08lx lr=%08lx sp=%08lx]",
- code, regs->ARM_pc, instr, regs->ARM_lr, regs->ARM_sp);
+ force_sig(SIGILL, current);
+ die_if_kernel("unknown data abort code", regs, instr);
+ while (1);
}
-#endif
void __bug(const char *file, int line, void *data)
{
@@ -425,6 +432,19 @@ asmlinkage void __div0(void)
__backtrace();
}
+void abort(void)
+{
+ void *lr = __builtin_return_address(0);
+
+ printk(KERN_CRIT "abort() called from %p! (Please "
+ "report to rmk@arm.linux.org.uk)\n", lr);
+
+ *(int *)0 = 0;
+
+ /* if that doesn't kill us, halt */
+ panic("Oops failed to kill thread");
+}
+
void __init trap_init(void)
{
extern void __trap_init(void);