diff options
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r-- | arch/arm/kernel/armksyms.c | 7 | ||||
-rw-r--r-- | arch/arm/kernel/bios32.c | 65 | ||||
-rw-r--r-- | arch/arm/kernel/bios32.h | 1 | ||||
-rw-r--r-- | arch/arm/kernel/calls.S | 71 | ||||
-rw-r--r-- | arch/arm/kernel/debug-armv.S | 15 | ||||
-rw-r--r-- | arch/arm/kernel/dec21285.c | 4 | ||||
-rw-r--r-- | arch/arm/kernel/entry-armo.S | 1 | ||||
-rw-r--r-- | arch/arm/kernel/entry-armv.S | 10 | ||||
-rw-r--r-- | arch/arm/kernel/entry-common.S | 129 | ||||
-rw-r--r-- | arch/arm/kernel/head-armv.S | 70 | ||||
-rw-r--r-- | arch/arm/kernel/process.c | 7 | ||||
-rw-r--r-- | arch/arm/kernel/setup.c | 91 | ||||
-rw-r--r-- | arch/arm/kernel/signal.c | 3 | ||||
-rw-r--r-- | arch/arm/kernel/sys_arm.c | 84 | ||||
-rw-r--r-- | arch/arm/kernel/time.c | 2 | ||||
-rw-r--r-- | arch/arm/kernel/traps.c | 58 |
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, ¤t->thread.fpstate.soft, sizeof (fp)); + memcpy(fp, ¤t->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); |