提交 76a22271 编写于 作者: L Linus Torvalds

Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm

* 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm:
  [ARM] 3672/1: PXA: don't probe output GPIOs for interrupt
  [ARM] 3671/1: ep93xx: add cirrus logic edb9315 support
  [ARM] 3370/2: ep93xx: add crunch support
  [ARM] 3665/1: crunch: add ptrace support
  [ARM] 3664/1: crunch: add signal frame save/restore
  [ARM] 3663/1: fix resource->end off-by-one thinko during physmap conversion
  [ARM] 3662/1: ixp23xx: don't include asm/hardware.h in uncompress.h
  [ARM] 3660/1: Remove legacy defines
  [ARM] 3661/1: S3C2412: Fix compilation if CPU_S3C2410 only
  [ARM] 3658/1: S3C244X: Change usb-gadget name to s3c2440-usbgadget
  [ARM] Remove the __arch_* layer from uaccess.h
...@@ -22,6 +22,9 @@ obj-$(CONFIG_PCI) += bios32.o ...@@ -22,6 +22,9 @@ obj-$(CONFIG_PCI) += bios32.o
obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o
obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o
AFLAGS_crunch-bits.o := -Wa,-mcpu=ep9312
obj-$(CONFIG_IWMMXT) += iwmmxt.o obj-$(CONFIG_IWMMXT) += iwmmxt.o
AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt
......
...@@ -109,11 +109,11 @@ EXPORT_SYMBOL(memchr); ...@@ -109,11 +109,11 @@ EXPORT_SYMBOL(memchr);
EXPORT_SYMBOL(__memzero); EXPORT_SYMBOL(__memzero);
/* user mem (segment) */ /* user mem (segment) */
EXPORT_SYMBOL(__arch_copy_from_user); EXPORT_SYMBOL(__copy_from_user);
EXPORT_SYMBOL(__arch_copy_to_user); EXPORT_SYMBOL(__copy_to_user);
EXPORT_SYMBOL(__arch_clear_user); EXPORT_SYMBOL(__clear_user);
EXPORT_SYMBOL(__arch_strnlen_user); EXPORT_SYMBOL(__strnlen_user);
EXPORT_SYMBOL(__arch_strncpy_from_user); EXPORT_SYMBOL(__strncpy_from_user);
EXPORT_SYMBOL(__get_user_1); EXPORT_SYMBOL(__get_user_1);
EXPORT_SYMBOL(__get_user_2); EXPORT_SYMBOL(__get_user_2);
......
...@@ -59,6 +59,9 @@ int main(void) ...@@ -59,6 +59,9 @@ int main(void)
DEFINE(TI_VFPSTATE, offsetof(struct thread_info, vfpstate)); DEFINE(TI_VFPSTATE, offsetof(struct thread_info, vfpstate));
#ifdef CONFIG_IWMMXT #ifdef CONFIG_IWMMXT
DEFINE(TI_IWMMXT_STATE, offsetof(struct thread_info, fpstate.iwmmxt)); DEFINE(TI_IWMMXT_STATE, offsetof(struct thread_info, fpstate.iwmmxt));
#endif
#ifdef CONFIG_CRUNCH
DEFINE(TI_CRUNCH_STATE, offsetof(struct thread_info, crunchstate));
#endif #endif
BLANK(); BLANK();
DEFINE(S_R0, offsetof(struct pt_regs, ARM_r0)); DEFINE(S_R0, offsetof(struct pt_regs, ARM_r0));
......
/*
* arch/arm/kernel/crunch-bits.S
* Cirrus MaverickCrunch context switching and handling
*
* Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
*
* Shamelessly stolen from the iWMMXt code by Nicolas Pitre, which is
* Copyright (c) 2003-2004, MontaVista Software, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/linkage.h>
#include <asm/ptrace.h>
#include <asm/thread_info.h>
#include <asm/asm-offsets.h>
#include <asm/arch/ep93xx-regs.h>
/*
* We can't use hex constants here due to a bug in gas.
*/
#define CRUNCH_MVDX0 0
#define CRUNCH_MVDX1 8
#define CRUNCH_MVDX2 16
#define CRUNCH_MVDX3 24
#define CRUNCH_MVDX4 32
#define CRUNCH_MVDX5 40
#define CRUNCH_MVDX6 48
#define CRUNCH_MVDX7 56
#define CRUNCH_MVDX8 64
#define CRUNCH_MVDX9 72
#define CRUNCH_MVDX10 80
#define CRUNCH_MVDX11 88
#define CRUNCH_MVDX12 96
#define CRUNCH_MVDX13 104
#define CRUNCH_MVDX14 112
#define CRUNCH_MVDX15 120
#define CRUNCH_MVAX0L 128
#define CRUNCH_MVAX0M 132
#define CRUNCH_MVAX0H 136
#define CRUNCH_MVAX1L 140
#define CRUNCH_MVAX1M 144
#define CRUNCH_MVAX1H 148
#define CRUNCH_MVAX2L 152
#define CRUNCH_MVAX2M 156
#define CRUNCH_MVAX2H 160
#define CRUNCH_MVAX3L 164
#define CRUNCH_MVAX3M 168
#define CRUNCH_MVAX3H 172
#define CRUNCH_DSPSC 176
#define CRUNCH_SIZE 184
.text
/*
* Lazy switching of crunch coprocessor context
*
* r10 = struct thread_info pointer
* r9 = ret_from_exception
* lr = undefined instr exit
*
* called from prefetch exception handler with interrupts disabled
*/
ENTRY(crunch_task_enable)
ldr r8, =(EP93XX_APB_VIRT_BASE + 0x00130000) @ syscon addr
ldr r1, [r8, #0x80]
tst r1, #0x00800000 @ access to crunch enabled?
movne pc, lr @ if so no business here
mov r3, #0xaa @ unlock syscon swlock
str r3, [r8, #0xc0]
orr r1, r1, #0x00800000 @ enable access to crunch
str r1, [r8, #0x80]
ldr r3, =crunch_owner
add r0, r10, #TI_CRUNCH_STATE @ get task crunch save area
ldr r2, [sp, #60] @ current task pc value
ldr r1, [r3] @ get current crunch owner
str r0, [r3] @ this task now owns crunch
sub r2, r2, #4 @ adjust pc back
str r2, [sp, #60]
ldr r2, [r8, #0x80]
mov r2, r2 @ flush out enable (@@@)
teq r1, #0 @ test for last ownership
mov lr, r9 @ normal exit from exception
beq crunch_load @ no owner, skip save
crunch_save:
cfstr64 mvdx0, [r1, #CRUNCH_MVDX0] @ save 64b registers
cfstr64 mvdx1, [r1, #CRUNCH_MVDX1]
cfstr64 mvdx2, [r1, #CRUNCH_MVDX2]
cfstr64 mvdx3, [r1, #CRUNCH_MVDX3]
cfstr64 mvdx4, [r1, #CRUNCH_MVDX4]
cfstr64 mvdx5, [r1, #CRUNCH_MVDX5]
cfstr64 mvdx6, [r1, #CRUNCH_MVDX6]
cfstr64 mvdx7, [r1, #CRUNCH_MVDX7]
cfstr64 mvdx8, [r1, #CRUNCH_MVDX8]
cfstr64 mvdx9, [r1, #CRUNCH_MVDX9]
cfstr64 mvdx10, [r1, #CRUNCH_MVDX10]
cfstr64 mvdx11, [r1, #CRUNCH_MVDX11]
cfstr64 mvdx12, [r1, #CRUNCH_MVDX12]
cfstr64 mvdx13, [r1, #CRUNCH_MVDX13]
cfstr64 mvdx14, [r1, #CRUNCH_MVDX14]
cfstr64 mvdx15, [r1, #CRUNCH_MVDX15]
#ifdef __ARMEB__
#error fix me for ARMEB
#endif
cfmv32al mvfx0, mvax0 @ save 72b accumulators
cfstr32 mvfx0, [r1, #CRUNCH_MVAX0L]
cfmv32am mvfx0, mvax0
cfstr32 mvfx0, [r1, #CRUNCH_MVAX0M]
cfmv32ah mvfx0, mvax0
cfstr32 mvfx0, [r1, #CRUNCH_MVAX0H]
cfmv32al mvfx0, mvax1
cfstr32 mvfx0, [r1, #CRUNCH_MVAX1L]
cfmv32am mvfx0, mvax1
cfstr32 mvfx0, [r1, #CRUNCH_MVAX1M]
cfmv32ah mvfx0, mvax1
cfstr32 mvfx0, [r1, #CRUNCH_MVAX1H]
cfmv32al mvfx0, mvax2
cfstr32 mvfx0, [r1, #CRUNCH_MVAX2L]
cfmv32am mvfx0, mvax2
cfstr32 mvfx0, [r1, #CRUNCH_MVAX2M]
cfmv32ah mvfx0, mvax2
cfstr32 mvfx0, [r1, #CRUNCH_MVAX2H]
cfmv32al mvfx0, mvax3
cfstr32 mvfx0, [r1, #CRUNCH_MVAX3L]
cfmv32am mvfx0, mvax3
cfstr32 mvfx0, [r1, #CRUNCH_MVAX3M]
cfmv32ah mvfx0, mvax3
cfstr32 mvfx0, [r1, #CRUNCH_MVAX3H]
cfmv32sc mvdx0, dspsc @ save status word
cfstr64 mvdx0, [r1, #CRUNCH_DSPSC]
teq r0, #0 @ anything to load?
cfldr64eq mvdx0, [r1, #CRUNCH_MVDX0] @ mvdx0 was clobbered
moveq pc, lr
crunch_load:
cfldr64 mvdx0, [r0, #CRUNCH_DSPSC] @ load status word
cfmvsc32 dspsc, mvdx0
cfldr32 mvfx0, [r0, #CRUNCH_MVAX0L] @ load 72b accumulators
cfmval32 mvax0, mvfx0
cfldr32 mvfx0, [r0, #CRUNCH_MVAX0M]
cfmvam32 mvax0, mvfx0
cfldr32 mvfx0, [r0, #CRUNCH_MVAX0H]
cfmvah32 mvax0, mvfx0
cfldr32 mvfx0, [r0, #CRUNCH_MVAX1L]
cfmval32 mvax1, mvfx0
cfldr32 mvfx0, [r0, #CRUNCH_MVAX1M]
cfmvam32 mvax1, mvfx0
cfldr32 mvfx0, [r0, #CRUNCH_MVAX1H]
cfmvah32 mvax1, mvfx0
cfldr32 mvfx0, [r0, #CRUNCH_MVAX2L]
cfmval32 mvax2, mvfx0
cfldr32 mvfx0, [r0, #CRUNCH_MVAX2M]
cfmvam32 mvax2, mvfx0
cfldr32 mvfx0, [r0, #CRUNCH_MVAX2H]
cfmvah32 mvax2, mvfx0
cfldr32 mvfx0, [r0, #CRUNCH_MVAX3L]
cfmval32 mvax3, mvfx0
cfldr32 mvfx0, [r0, #CRUNCH_MVAX3M]
cfmvam32 mvax3, mvfx0
cfldr32 mvfx0, [r0, #CRUNCH_MVAX3H]
cfmvah32 mvax3, mvfx0
cfldr64 mvdx0, [r0, #CRUNCH_MVDX0] @ load 64b registers
cfldr64 mvdx1, [r0, #CRUNCH_MVDX1]
cfldr64 mvdx2, [r0, #CRUNCH_MVDX2]
cfldr64 mvdx3, [r0, #CRUNCH_MVDX3]
cfldr64 mvdx4, [r0, #CRUNCH_MVDX4]
cfldr64 mvdx5, [r0, #CRUNCH_MVDX5]
cfldr64 mvdx6, [r0, #CRUNCH_MVDX6]
cfldr64 mvdx7, [r0, #CRUNCH_MVDX7]
cfldr64 mvdx8, [r0, #CRUNCH_MVDX8]
cfldr64 mvdx9, [r0, #CRUNCH_MVDX9]
cfldr64 mvdx10, [r0, #CRUNCH_MVDX10]
cfldr64 mvdx11, [r0, #CRUNCH_MVDX11]
cfldr64 mvdx12, [r0, #CRUNCH_MVDX12]
cfldr64 mvdx13, [r0, #CRUNCH_MVDX13]
cfldr64 mvdx14, [r0, #CRUNCH_MVDX14]
cfldr64 mvdx15, [r0, #CRUNCH_MVDX15]
mov pc, lr
/*
* Back up crunch regs to save area and disable access to them
* (mainly for gdb or sleep mode usage)
*
* r0 = struct thread_info pointer of target task or NULL for any
*/
ENTRY(crunch_task_disable)
stmfd sp!, {r4, r5, lr}
mrs ip, cpsr
orr r2, ip, #PSR_I_BIT @ disable interrupts
msr cpsr_c, r2
ldr r4, =(EP93XX_APB_VIRT_BASE + 0x00130000) @ syscon addr
ldr r3, =crunch_owner
add r2, r0, #TI_CRUNCH_STATE @ get task crunch save area
ldr r1, [r3] @ get current crunch owner
teq r1, #0 @ any current owner?
beq 1f @ no: quit
teq r0, #0 @ any owner?
teqne r1, r2 @ or specified one?
bne 1f @ no: quit
ldr r5, [r4, #0x80] @ enable access to crunch
mov r2, #0xaa
str r2, [r4, #0xc0]
orr r5, r5, #0x00800000
str r5, [r4, #0x80]
mov r0, #0 @ nothing to load
str r0, [r3] @ no more current owner
ldr r2, [r4, #0x80] @ flush out enable (@@@)
mov r2, r2
bl crunch_save
mov r2, #0xaa @ disable access to crunch
str r2, [r4, #0xc0]
bic r5, r5, #0x00800000
str r5, [r4, #0x80]
ldr r5, [r4, #0x80] @ flush out enable (@@@)
mov r5, r5
1: msr cpsr_c, ip @ restore interrupt mode
ldmfd sp!, {r4, r5, pc}
/*
* Copy crunch state to given memory address
*
* r0 = struct thread_info pointer of target task
* r1 = memory address where to store crunch state
*
* this is called mainly in the creation of signal stack frames
*/
ENTRY(crunch_task_copy)
mrs ip, cpsr
orr r2, ip, #PSR_I_BIT @ disable interrupts
msr cpsr_c, r2
ldr r3, =crunch_owner
add r2, r0, #TI_CRUNCH_STATE @ get task crunch save area
ldr r3, [r3] @ get current crunch owner
teq r2, r3 @ does this task own it...
beq 1f
@ current crunch values are in the task save area
msr cpsr_c, ip @ restore interrupt mode
mov r0, r1
mov r1, r2
mov r2, #CRUNCH_SIZE
b memcpy
1: @ this task owns crunch regs -- grab a copy from there
mov r0, #0 @ nothing to load
mov r3, lr @ preserve return address
bl crunch_save
msr cpsr_c, ip @ restore interrupt mode
mov pc, r3
/*
* Restore crunch state from given memory address
*
* r0 = struct thread_info pointer of target task
* r1 = memory address where to get crunch state from
*
* this is used to restore crunch state when unwinding a signal stack frame
*/
ENTRY(crunch_task_restore)
mrs ip, cpsr
orr r2, ip, #PSR_I_BIT @ disable interrupts
msr cpsr_c, r2
ldr r3, =crunch_owner
add r2, r0, #TI_CRUNCH_STATE @ get task crunch save area
ldr r3, [r3] @ get current crunch owner
teq r2, r3 @ does this task own it...
beq 1f
@ this task doesn't own crunch regs -- use its save area
msr cpsr_c, ip @ restore interrupt mode
mov r0, r2
mov r2, #CRUNCH_SIZE
b memcpy
1: @ this task owns crunch regs -- load them directly
mov r0, r1
mov r1, #0 @ nothing to save
mov r3, lr @ preserve return address
bl crunch_load
msr cpsr_c, ip @ restore interrupt mode
mov pc, r3
/*
* arch/arm/kernel/crunch.c
* Cirrus MaverickCrunch context switching and handling
*
* Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <asm/arch/ep93xx-regs.h>
#include <asm/thread_notify.h>
#include <asm/io.h>
struct crunch_state *crunch_owner;
void crunch_task_release(struct thread_info *thread)
{
local_irq_disable();
if (crunch_owner == &thread->crunchstate)
crunch_owner = NULL;
local_irq_enable();
}
static int crunch_enabled(u32 devcfg)
{
return !!(devcfg & EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE);
}
static int crunch_do(struct notifier_block *self, unsigned long cmd, void *t)
{
struct thread_info *thread = (struct thread_info *)t;
struct crunch_state *crunch_state;
u32 devcfg;
crunch_state = &thread->crunchstate;
switch (cmd) {
case THREAD_NOTIFY_FLUSH:
memset(crunch_state, 0, sizeof(*crunch_state));
/*
* FALLTHROUGH: Ensure we don't try to overwrite our newly
* initialised state information on the first fault.
*/
case THREAD_NOTIFY_RELEASE:
crunch_task_release(thread);
break;
case THREAD_NOTIFY_SWITCH:
devcfg = __raw_readl(EP93XX_SYSCON_DEVICE_CONFIG);
if (crunch_enabled(devcfg) || crunch_owner == crunch_state) {
devcfg ^= EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE;
__raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
__raw_writel(devcfg, EP93XX_SYSCON_DEVICE_CONFIG);
}
break;
}
return NOTIFY_DONE;
}
static struct notifier_block crunch_notifier_block = {
.notifier_call = crunch_do,
};
static int __init crunch_init(void)
{
thread_register_notifier(&crunch_notifier_block);
return 0;
}
late_initcall(crunch_init);
...@@ -492,9 +492,15 @@ call_fpe: ...@@ -492,9 +492,15 @@ call_fpe:
b do_fpe @ CP#1 (FPE) b do_fpe @ CP#1 (FPE)
b do_fpe @ CP#2 (FPE) b do_fpe @ CP#2 (FPE)
mov pc, lr @ CP#3 mov pc, lr @ CP#3
#ifdef CONFIG_CRUNCH
b crunch_task_enable @ CP#4 (MaverickCrunch)
b crunch_task_enable @ CP#5 (MaverickCrunch)
b crunch_task_enable @ CP#6 (MaverickCrunch)
#else
mov pc, lr @ CP#4 mov pc, lr @ CP#4
mov pc, lr @ CP#5 mov pc, lr @ CP#5
mov pc, lr @ CP#6 mov pc, lr @ CP#6
#endif
mov pc, lr @ CP#7 mov pc, lr @ CP#7
mov pc, lr @ CP#8 mov pc, lr @ CP#8
mov pc, lr @ CP#9 mov pc, lr @ CP#9
......
...@@ -634,6 +634,32 @@ static int ptrace_setwmmxregs(struct task_struct *tsk, void __user *ufp) ...@@ -634,6 +634,32 @@ static int ptrace_setwmmxregs(struct task_struct *tsk, void __user *ufp)
#endif #endif
#ifdef CONFIG_CRUNCH
/*
* Get the child Crunch state.
*/
static int ptrace_getcrunchregs(struct task_struct *tsk, void __user *ufp)
{
struct thread_info *thread = task_thread_info(tsk);
crunch_task_disable(thread); /* force it to ram */
return copy_to_user(ufp, &thread->crunchstate, CRUNCH_SIZE)
? -EFAULT : 0;
}
/*
* Set the child Crunch state.
*/
static int ptrace_setcrunchregs(struct task_struct *tsk, void __user *ufp)
{
struct thread_info *thread = task_thread_info(tsk);
crunch_task_release(thread); /* force a reload */
return copy_from_user(&thread->crunchstate, ufp, CRUNCH_SIZE)
? -EFAULT : 0;
}
#endif
long arch_ptrace(struct task_struct *child, long request, long addr, long data) long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{ {
unsigned long tmp; unsigned long tmp;
...@@ -765,6 +791,16 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -765,6 +791,16 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
child->ptrace_message = data; child->ptrace_message = data;
break; break;
#ifdef CONFIG_CRUNCH
case PTRACE_GETCRUNCHREGS:
ret = ptrace_getcrunchregs(child, (void __user *)data);
break;
case PTRACE_SETCRUNCHREGS:
ret = ptrace_setcrunchregs(child, (void __user *)data);
break;
#endif
default: default:
ret = ptrace_request(child, request, addr, data); ret = ptrace_request(child, request, addr, data);
break; break;
......
...@@ -132,6 +132,37 @@ sys_sigaction(int sig, const struct old_sigaction __user *act, ...@@ -132,6 +132,37 @@ sys_sigaction(int sig, const struct old_sigaction __user *act,
return ret; return ret;
} }
#ifdef CONFIG_CRUNCH
static int preserve_crunch_context(struct crunch_sigframe *frame)
{
char kbuf[sizeof(*frame) + 8];
struct crunch_sigframe *kframe;
/* the crunch context must be 64 bit aligned */
kframe = (struct crunch_sigframe *)((unsigned long)(kbuf + 8) & ~7);
kframe->magic = CRUNCH_MAGIC;
kframe->size = CRUNCH_STORAGE_SIZE;
crunch_task_copy(current_thread_info(), &kframe->storage);
return __copy_to_user(frame, kframe, sizeof(*frame));
}
static int restore_crunch_context(struct crunch_sigframe *frame)
{
char kbuf[sizeof(*frame) + 8];
struct crunch_sigframe *kframe;
/* the crunch context must be 64 bit aligned */
kframe = (struct crunch_sigframe *)((unsigned long)(kbuf + 8) & ~7);
if (__copy_from_user(kframe, frame, sizeof(*frame)))
return -1;
if (kframe->magic != CRUNCH_MAGIC ||
kframe->size != CRUNCH_STORAGE_SIZE)
return -1;
crunch_task_restore(current_thread_info(), &kframe->storage);
return 0;
}
#endif
#ifdef CONFIG_IWMMXT #ifdef CONFIG_IWMMXT
static int preserve_iwmmxt_context(struct iwmmxt_sigframe *frame) static int preserve_iwmmxt_context(struct iwmmxt_sigframe *frame)
...@@ -214,6 +245,10 @@ static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf) ...@@ -214,6 +245,10 @@ static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf)
err |= !valid_user_regs(regs); err |= !valid_user_regs(regs);
aux = (struct aux_sigframe __user *) sf->uc.uc_regspace; aux = (struct aux_sigframe __user *) sf->uc.uc_regspace;
#ifdef CONFIG_CRUNCH
if (err == 0)
err |= restore_crunch_context(&aux->crunch);
#endif
#ifdef CONFIG_IWMMXT #ifdef CONFIG_IWMMXT
if (err == 0 && test_thread_flag(TIF_USING_IWMMXT)) if (err == 0 && test_thread_flag(TIF_USING_IWMMXT))
err |= restore_iwmmxt_context(&aux->iwmmxt); err |= restore_iwmmxt_context(&aux->iwmmxt);
...@@ -333,6 +368,10 @@ setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set) ...@@ -333,6 +368,10 @@ setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set)
err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set)); err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set));
aux = (struct aux_sigframe __user *) sf->uc.uc_regspace; aux = (struct aux_sigframe __user *) sf->uc.uc_regspace;
#ifdef CONFIG_CRUNCH
if (err == 0)
err |= preserve_crunch_context(&aux->crunch);
#endif
#ifdef CONFIG_IWMMXT #ifdef CONFIG_IWMMXT
if (err == 0 && test_thread_flag(TIF_USING_IWMMXT)) if (err == 0 && test_thread_flag(TIF_USING_IWMMXT))
err |= preserve_iwmmxt_context(&aux->iwmmxt); err |= preserve_iwmmxt_context(&aux->iwmmxt);
......
...@@ -12,13 +12,13 @@ ...@@ -12,13 +12,13 @@
.text .text
/* Prototype: int __arch_clear_user(void *addr, size_t sz) /* Prototype: int __clear_user(void *addr, size_t sz)
* Purpose : clear some user memory * Purpose : clear some user memory
* Params : addr - user memory address to clear * Params : addr - user memory address to clear
* : sz - number of bytes to clear * : sz - number of bytes to clear
* Returns : number of bytes NOT cleared * Returns : number of bytes NOT cleared
*/ */
ENTRY(__arch_clear_user) ENTRY(__clear_user)
stmfd sp!, {r1, lr} stmfd sp!, {r1, lr}
mov r2, #0 mov r2, #0
cmp r1, #4 cmp r1, #4
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
/* /*
* Prototype: * Prototype:
* *
* size_t __arch_copy_from_user(void *to, const void *from, size_t n) * size_t __copy_from_user(void *to, const void *from, size_t n)
* *
* Purpose: * Purpose:
* *
...@@ -83,7 +83,7 @@ ...@@ -83,7 +83,7 @@
.text .text
ENTRY(__arch_copy_from_user) ENTRY(__copy_from_user)
#include "copy_template.S" #include "copy_template.S"
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
/* /*
* Prototype: * Prototype:
* *
* size_t __arch_copy_to_user(void *to, const void *from, size_t n) * size_t __copy_to_user(void *to, const void *from, size_t n)
* *
* Purpose: * Purpose:
* *
...@@ -86,7 +86,7 @@ ...@@ -86,7 +86,7 @@
.text .text
ENTRY(__arch_copy_to_user) ENTRY(__copy_to_user)
#include "copy_template.S" #include "copy_template.S"
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
* returns the number of characters copied (strlen of copied string), * returns the number of characters copied (strlen of copied string),
* -EFAULT on exception, or "len" if we fill the whole buffer * -EFAULT on exception, or "len" if we fill the whole buffer
*/ */
ENTRY(__arch_strncpy_from_user) ENTRY(__strncpy_from_user)
mov ip, r1 mov ip, r1
1: subs r2, r2, #1 1: subs r2, r2, #1
USER( ldrplbt r3, [r1], #1) USER( ldrplbt r3, [r1], #1)
......
...@@ -14,13 +14,13 @@ ...@@ -14,13 +14,13 @@
.text .text
.align 5 .align 5
/* Prototype: unsigned long __arch_strnlen_user(const char *str, long n) /* Prototype: unsigned long __strnlen_user(const char *str, long n)
* Purpose : get length of a string in user memory * Purpose : get length of a string in user memory
* Params : str - address of string in user memory * Params : str - address of string in user memory
* Returns : length of string *including terminator* * Returns : length of string *including terminator*
* or zero on exception, or n + 1 if too long * or zero on exception, or n + 1 if too long
*/ */
ENTRY(__arch_strnlen_user) ENTRY(__strnlen_user)
mov r2, r0 mov r2, r0
1: 1:
USER( ldrbt r3, [r0], #1) USER( ldrbt r3, [r0], #1)
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#define PAGE_SHIFT 12 #define PAGE_SHIFT 12
/* Prototype: int __arch_copy_to_user(void *to, const char *from, size_t n) /* Prototype: int __copy_to_user(void *to, const char *from, size_t n)
* Purpose : copy a block to user memory from kernel memory * Purpose : copy a block to user memory from kernel memory
* Params : to - user memory * Params : to - user memory
* : from - kernel memory * : from - kernel memory
...@@ -39,7 +39,7 @@ USER( strgtbt r3, [r0], #1) @ May fault ...@@ -39,7 +39,7 @@ USER( strgtbt r3, [r0], #1) @ May fault
sub r2, r2, ip sub r2, r2, ip
b .Lc2u_dest_aligned b .Lc2u_dest_aligned
ENTRY(__arch_copy_to_user) ENTRY(__copy_to_user)
stmfd sp!, {r2, r4 - r7, lr} stmfd sp!, {r2, r4 - r7, lr}
cmp r2, #4 cmp r2, #4
blt .Lc2u_not_enough blt .Lc2u_not_enough
...@@ -283,7 +283,7 @@ USER( strgtbt r3, [r0], #1) @ May fault ...@@ -283,7 +283,7 @@ USER( strgtbt r3, [r0], #1) @ May fault
9001: ldmfd sp!, {r0, r4 - r7, pc} 9001: ldmfd sp!, {r0, r4 - r7, pc}
.previous .previous
/* Prototype: unsigned long __arch_copy_from_user(void *to,const void *from,unsigned long n); /* Prototype: unsigned long __copy_from_user(void *to,const void *from,unsigned long n);
* Purpose : copy a block from user memory to kernel memory * Purpose : copy a block from user memory to kernel memory
* Params : to - kernel memory * Params : to - kernel memory
* : from - user memory * : from - user memory
...@@ -302,7 +302,7 @@ USER( ldrgtbt r3, [r1], #1) @ May fault ...@@ -302,7 +302,7 @@ USER( ldrgtbt r3, [r1], #1) @ May fault
sub r2, r2, ip sub r2, r2, ip
b .Lcfu_dest_aligned b .Lcfu_dest_aligned
ENTRY(__arch_copy_from_user) ENTRY(__copy_from_user)
stmfd sp!, {r0, r2, r4 - r7, lr} stmfd sp!, {r0, r2, r4 - r7, lr}
cmp r2, #4 cmp r2, #4
blt .Lcfu_not_enough blt .Lcfu_not_enough
......
...@@ -2,8 +2,19 @@ if ARCH_EP93XX ...@@ -2,8 +2,19 @@ if ARCH_EP93XX
menu "Cirrus EP93xx Implementation Options" menu "Cirrus EP93xx Implementation Options"
config CRUNCH
bool "Support for MaverickCrunch"
help
Enable kernel support for MaverickCrunch.
comment "EP93xx Platforms" comment "EP93xx Platforms"
config MACH_EDB9315
bool "Support Cirrus Logic EDB9315"
help
Say 'Y' here if you want your kernel to support the Cirrus
Logic EDB9315 Evaluation Board.
config MACH_GESBC9312 config MACH_GESBC9312
bool "Support Glomation GESBC-9312-sx" bool "Support Glomation GESBC-9312-sx"
help help
......
...@@ -6,5 +6,6 @@ obj-m := ...@@ -6,5 +6,6 @@ obj-m :=
obj-n := obj-n :=
obj- := obj- :=
obj-$(CONFIG_MACH_EDB9315) += edb9315.o
obj-$(CONFIG_MACH_GESBC9312) += gesbc9312.o obj-$(CONFIG_MACH_GESBC9312) += gesbc9312.o
obj-$(CONFIG_MACH_TS72XX) += ts72xx.o obj-$(CONFIG_MACH_TS72XX) += ts72xx.o
/*
* arch/arm/mach-ep93xx/edb9315.c
* Cirrus Logic EDB9315 support.
*
* Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/mtd/physmap.h>
#include <linux/platform_device.h>
#include <asm/io.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
static struct physmap_flash_data edb9315_flash_data = {
.width = 4,
};
static struct resource edb9315_flash_resource = {
.start = 0x60000000,
.end = 0x61ffffff,
.flags = IORESOURCE_MEM,
};
static struct platform_device edb9315_flash = {
.name = "physmap-flash",
.id = 0,
.dev = {
.platform_data = &edb9315_flash_data,
},
.num_resources = 1,
.resource = &edb9315_flash_resource,
};
static void __init edb9315_init_machine(void)
{
ep93xx_init_devices();
platform_device_register(&edb9315_flash);
}
MACHINE_START(EDB9315, "Cirrus Logic EDB9315 Evaluation Board")
/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
.phys_io = EP93XX_APB_PHYS_BASE,
.io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
.timer = &ep93xx_timer,
.init_machine = edb9315_init_machine,
MACHINE_END
...@@ -30,7 +30,7 @@ static struct physmap_flash_data gesbc9312_flash_data = { ...@@ -30,7 +30,7 @@ static struct physmap_flash_data gesbc9312_flash_data = {
static struct resource gesbc9312_flash_resource = { static struct resource gesbc9312_flash_resource = {
.start = 0x60000000, .start = 0x60000000,
.end = 0x60800000, .end = 0x607fffff,
.flags = IORESOURCE_MEM, .flags = IORESOURCE_MEM,
}; };
......
...@@ -118,7 +118,7 @@ static struct physmap_flash_data ts72xx_flash_data = { ...@@ -118,7 +118,7 @@ static struct physmap_flash_data ts72xx_flash_data = {
static struct resource ts72xx_flash_resource = { static struct resource ts72xx_flash_resource = {
.start = TS72XX_NOR_PHYS_BASE, .start = TS72XX_NOR_PHYS_BASE,
.end = TS72XX_NOR_PHYS_BASE + 0x01000000, .end = TS72XX_NOR_PHYS_BASE + 0x00ffffff,
.flags = IORESOURCE_MEM, .flags = IORESOURCE_MEM,
}; };
......
...@@ -59,7 +59,7 @@ static struct physmap_flash_data espresso_flash_data = { ...@@ -59,7 +59,7 @@ static struct physmap_flash_data espresso_flash_data = {
static struct resource espresso_flash_resource = { static struct resource espresso_flash_resource = {
.start = 0x90000000, .start = 0x90000000,
.end = 0x92000000, .end = 0x91ffffff,
.flags = IORESOURCE_MEM, .flags = IORESOURCE_MEM,
}; };
......
...@@ -304,7 +304,7 @@ static struct physmap_flash_data ixdp2351_flash_data = { ...@@ -304,7 +304,7 @@ static struct physmap_flash_data ixdp2351_flash_data = {
static struct resource ixdp2351_flash_resource = { static struct resource ixdp2351_flash_resource = {
.start = 0x90000000, .start = 0x90000000,
.end = 0x94000000, .end = 0x93ffffff,
.flags = IORESOURCE_MEM, .flags = IORESOURCE_MEM,
}; };
......
...@@ -143,7 +143,7 @@ static struct physmap_flash_data roadrunner_flash_data = { ...@@ -143,7 +143,7 @@ static struct physmap_flash_data roadrunner_flash_data = {
static struct resource roadrunner_flash_resource = { static struct resource roadrunner_flash_resource = {
.start = 0x90000000, .start = 0x90000000,
.end = 0x94000000, .end = 0x93ffffff,
.flags = IORESOURCE_MEM, .flags = IORESOURCE_MEM,
}; };
......
...@@ -88,8 +88,8 @@ static int pxa_gpio_irq_type(unsigned int irq, unsigned int type) ...@@ -88,8 +88,8 @@ static int pxa_gpio_irq_type(unsigned int irq, unsigned int type)
if (type == IRQT_PROBE) { if (type == IRQT_PROBE) {
/* Don't mess with enabled GPIOs using preconfigured edges or /* Don't mess with enabled GPIOs using preconfigured edges or
GPIOs set to alternate function during probe */ GPIOs set to alternate function or to output during probe */
if ((GPIO_IRQ_rising_edge[idx] | GPIO_IRQ_falling_edge[idx]) & if ((GPIO_IRQ_rising_edge[idx] | GPIO_IRQ_falling_edge[idx] | GPDR(gpio)) &
GPIO_bit(gpio)) GPIO_bit(gpio))
return 0; return 0;
if (GAFR(gpio) & (0x3 << (((gpio) & 0xf)*2))) if (GAFR(gpio) & (0x3 << (((gpio) & 0xf)*2)))
......
...@@ -69,6 +69,7 @@ void __init s3c244x_map_io(struct map_desc *mach_desc, int size) ...@@ -69,6 +69,7 @@ void __init s3c244x_map_io(struct map_desc *mach_desc, int size)
s3c_device_i2c.name = "s3c2440-i2c"; s3c_device_i2c.name = "s3c2440-i2c";
s3c_device_nand.name = "s3c2440-nand"; s3c_device_nand.name = "s3c2440-nand";
s3c_device_usbgadget.name = "s3c2440-usbgadget";
} }
void __init s3c244x_init_clocks(int xtal) void __init s3c244x_init_clocks(int xtal)
......
...@@ -33,9 +33,7 @@ ...@@ -33,9 +33,7 @@
* bus_to_virt: Used to convert an address for DMA operations * bus_to_virt: Used to convert an address for DMA operations
* to an address that the kernel can use. * to an address that the kernel can use.
*/ */
#define __virt_to_bus__is_a_macro
#define __virt_to_bus(x) __virt_to_phys(x) #define __virt_to_bus(x) __virt_to_phys(x)
#define __bus_to_virt__is_a_macro
#define __bus_to_virt(x) __phys_to_virt(x) #define __bus_to_virt(x) __phys_to_virt(x)
#endif #endif
...@@ -23,9 +23,7 @@ ...@@ -23,9 +23,7 @@
* There is something to do here later !, Mar 2000, Jungjun Kim * There is something to do here later !, Mar 2000, Jungjun Kim
*/ */
#define __virt_to_bus__is_a_macro
#define __virt_to_bus(x) __virt_to_phys(x) #define __virt_to_bus(x) __virt_to_phys(x)
#define __bus_to_virt__is_a_macro
#define __bus_to_virt(x) __phys_to_virt(x) #define __bus_to_virt(x) __phys_to_virt(x)
#endif #endif
...@@ -30,9 +30,7 @@ ...@@ -30,9 +30,7 @@
* bus_to_virt: Used to convert an address for DMA operations * bus_to_virt: Used to convert an address for DMA operations
* to an address that the kernel can use. * to an address that the kernel can use.
*/ */
#define __virt_to_bus__is_a_macro
#define __virt_to_bus(x) (x - PAGE_OFFSET + PHYS_OFFSET) #define __virt_to_bus(x) (x - PAGE_OFFSET + PHYS_OFFSET)
#define __bus_to_virt__is_a_macro
#define __bus_to_virt(x) (x - PHYS_OFFSET + PAGE_OFFSET) #define __bus_to_virt(x) (x - PHYS_OFFSET + PAGE_OFFSET)
#endif #endif
...@@ -295,15 +295,4 @@ ...@@ -295,15 +295,4 @@
#define IXP23XX_PCI_CPP_ADDR_BITS IXP23XX_PCI_CSR(0x0160) #define IXP23XX_PCI_CPP_ADDR_BITS IXP23XX_PCI_CSR(0x0160)
#ifndef __ASSEMBLY__
/*
* Is system memory on the XSI or CPP bus?
*/
static inline unsigned ixp23xx_cpp_boot(void)
{
return (*IXP23XX_EXP_CFG0 & IXP23XX_EXP_CFG0_XSI_NOT_PRES);
}
#endif
#endif #endif
...@@ -43,5 +43,15 @@ extern struct sys_timer ixp23xx_timer; ...@@ -43,5 +43,15 @@ extern struct sys_timer ixp23xx_timer;
#define IXP23XX_UART_XTAL 14745600 #define IXP23XX_UART_XTAL 14745600
#ifndef __ASSEMBLY__
/*
* Is system memory on the XSI or CPP bus?
*/
static inline unsigned ixp23xx_cpp_boot(void)
{
return (*IXP23XX_EXP_CFG0 & IXP23XX_EXP_CFG0_XSI_NOT_PRES);
}
#endif
#endif #endif
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
#ifndef __ASM_ARCH_UNCOMPRESS_H #ifndef __ASM_ARCH_UNCOMPRESS_H
#define __ASM_ARCH_UNCOMPRESS_H #define __ASM_ARCH_UNCOMPRESS_H
#include <asm/hardware.h> #include <asm/arch/ixp23xx.h>
#include <linux/serial_reg.h> #include <linux/serial_reg.h>
#define UART_BASE ((volatile u32 *)IXP23XX_UART1_PHYS) #define UART_BASE ((volatile u32 *)IXP23XX_UART1_PHYS)
......
...@@ -7,25 +7,23 @@ ...@@ -7,25 +7,23 @@
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
* *
* S3C2440 Signal Drive Strength Control * S3C2440/S3C2412 Signal Drive Strength Control
*
* Changelog:
* 11-Aug-2004 BJD Created file
* 25-Aug-2004 BJD Added the _SELECT_* defs for using with functions
*/ */
#ifndef __ASM_ARCH_REGS_DSC_H #ifndef __ASM_ARCH_REGS_DSC_H
#define __ASM_ARCH_REGS_DSC_H "2440-dsc" #define __ASM_ARCH_REGS_DSC_H "2440-dsc"
#ifdef CONFIG_CPU_S3C2440 #if defined(CONFIG_CPU_S3C2412)
#define S3C2412_DSC0 S3C2410_GPIOREG(0xdc)
#define S3C2412_DSC1 S3C2410_GPIOREG(0xe0)
#endif
#if defined(CONFIG_CPU_S3C2440)
#define S3C2440_DSC0 S3C2410_GPIOREG(0xc4) #define S3C2440_DSC0 S3C2410_GPIOREG(0xc4)
#define S3C2440_DSC1 S3C2410_GPIOREG(0xc8) #define S3C2440_DSC1 S3C2410_GPIOREG(0xc8)
#define S3C2412_DSC0 S3C2410_GPIOREG(0xdc)
#define S3C2412_DSC1 S3C2410_GPIOREG(0xe0)
#define S3C2440_SELECT_DSC0 (0) #define S3C2440_SELECT_DSC0 (0)
#define S3C2440_SELECT_DSC1 (1<<31) #define S3C2440_SELECT_DSC1 (1<<31)
......
...@@ -72,6 +72,14 @@ union fp_state { ...@@ -72,6 +72,14 @@ union fp_state {
#define FP_SIZE (sizeof(union fp_state) / sizeof(int)) #define FP_SIZE (sizeof(union fp_state) / sizeof(int))
struct crunch_state {
unsigned int mvdx[16][2];
unsigned int mvax[4][3];
unsigned int dspsc[2];
};
#define CRUNCH_SIZE sizeof(struct crunch_state)
#endif #endif
#endif #endif
...@@ -25,6 +25,11 @@ ...@@ -25,6 +25,11 @@
#define PTRACE_SET_SYSCALL 23 #define PTRACE_SET_SYSCALL 23
/* PTRACE_SYSCALL is 24 */
#define PTRACE_GETCRUNCHREGS 25
#define PTRACE_SETCRUNCHREGS 26
/* /*
* PSR bits * PSR bits
*/ */
......
...@@ -59,6 +59,7 @@ struct thread_info { ...@@ -59,6 +59,7 @@ struct thread_info {
struct cpu_context_save cpu_context; /* cpu context */ struct cpu_context_save cpu_context; /* cpu context */
__u8 used_cp[16]; /* thread used copro */ __u8 used_cp[16]; /* thread used copro */
unsigned long tp_value; unsigned long tp_value;
struct crunch_state crunchstate;
union fp_state fpstate __attribute__((aligned(8))); union fp_state fpstate __attribute__((aligned(8)));
union vfp_state vfpstate; union vfp_state vfpstate;
struct restart_block restart_block; struct restart_block restart_block;
...@@ -101,6 +102,11 @@ extern void free_thread_info(struct thread_info *); ...@@ -101,6 +102,11 @@ extern void free_thread_info(struct thread_info *);
#define thread_saved_fp(tsk) \ #define thread_saved_fp(tsk) \
((unsigned long)(task_thread_info(tsk)->cpu_context.fp)) ((unsigned long)(task_thread_info(tsk)->cpu_context.fp))
extern void crunch_task_disable(struct thread_info *);
extern void crunch_task_copy(struct thread_info *, void *);
extern void crunch_task_restore(struct thread_info *, void *);
extern void crunch_task_release(struct thread_info *);
extern void iwmmxt_task_disable(struct thread_info *); extern void iwmmxt_task_disable(struct thread_info *);
extern void iwmmxt_task_copy(struct thread_info *, void *); extern void iwmmxt_task_copy(struct thread_info *, void *);
extern void iwmmxt_task_restore(struct thread_info *, void *); extern void iwmmxt_task_restore(struct thread_info *, void *);
......
...@@ -353,66 +353,47 @@ do { \ ...@@ -353,66 +353,47 @@ do { \
: "r" (x), "i" (-EFAULT) \ : "r" (x), "i" (-EFAULT) \
: "cc") : "cc")
extern unsigned long __arch_copy_from_user(void *to, const void __user *from, unsigned long n);
extern unsigned long __arch_copy_to_user(void __user *to, const void *from, unsigned long n); extern unsigned long __copy_from_user(void *to, const void __user *from, unsigned long n);
extern unsigned long __arch_clear_user(void __user *addr, unsigned long n); extern unsigned long __copy_to_user(void __user *to, const void *from, unsigned long n);
extern unsigned long __arch_strncpy_from_user(char *to, const char __user *from, unsigned long count); extern unsigned long __clear_user(void __user *addr, unsigned long n);
extern unsigned long __arch_strnlen_user(const char __user *s, long n); extern unsigned long __strncpy_from_user(char *to, const char __user *from, unsigned long count);
extern unsigned long __strnlen_user(const char __user *s, long n);
static inline unsigned long copy_from_user(void *to, const void __user *from, unsigned long n) static inline unsigned long copy_from_user(void *to, const void __user *from, unsigned long n)
{ {
if (access_ok(VERIFY_READ, from, n)) if (access_ok(VERIFY_READ, from, n))
n = __arch_copy_from_user(to, from, n); n = __copy_from_user(to, from, n);
else /* security hole - plug it */ else /* security hole - plug it */
memzero(to, n); memzero(to, n);
return n; return n;
} }
static inline unsigned long __copy_from_user(void *to, const void __user *from, unsigned long n)
{
return __arch_copy_from_user(to, from, n);
}
static inline unsigned long copy_to_user(void __user *to, const void *from, unsigned long n) static inline unsigned long copy_to_user(void __user *to, const void *from, unsigned long n)
{ {
if (access_ok(VERIFY_WRITE, to, n)) if (access_ok(VERIFY_WRITE, to, n))
n = __arch_copy_to_user(to, from, n); n = __copy_to_user(to, from, n);
return n; return n;
} }
static inline unsigned long __copy_to_user(void __user *to, const void *from, unsigned long n)
{
return __arch_copy_to_user(to, from, n);
}
#define __copy_to_user_inatomic __copy_to_user #define __copy_to_user_inatomic __copy_to_user
#define __copy_from_user_inatomic __copy_from_user #define __copy_from_user_inatomic __copy_from_user
static inline unsigned long clear_user (void __user *to, unsigned long n) static inline unsigned long clear_user(void __user *to, unsigned long n)
{ {
if (access_ok(VERIFY_WRITE, to, n)) if (access_ok(VERIFY_WRITE, to, n))
n = __arch_clear_user(to, n); n = __clear_user(to, n);
return n; return n;
} }
static inline unsigned long __clear_user (void __user *to, unsigned long n) static inline long strncpy_from_user(char *dst, const char __user *src, long count)
{
return __arch_clear_user(to, n);
}
static inline long strncpy_from_user (char *dst, const char __user *src, long count)
{ {
long res = -EFAULT; long res = -EFAULT;
if (access_ok(VERIFY_READ, src, 1)) if (access_ok(VERIFY_READ, src, 1))
res = __arch_strncpy_from_user(dst, src, count); res = __strncpy_from_user(dst, src, count);
return res; return res;
} }
static inline long __strncpy_from_user (char *dst, const char __user *src, long count)
{
return __arch_strncpy_from_user(dst, src, count);
}
#define strlen_user(s) strnlen_user(s, ~0UL >> 1) #define strlen_user(s) strnlen_user(s, ~0UL >> 1)
static inline long strnlen_user(const char __user *s, long n) static inline long strnlen_user(const char __user *s, long n)
...@@ -420,7 +401,7 @@ static inline long strnlen_user(const char __user *s, long n) ...@@ -420,7 +401,7 @@ static inline long strnlen_user(const char __user *s, long n)
unsigned long res = 0; unsigned long res = 0;
if (__addr_ok(s)) if (__addr_ok(s))
res = __arch_strnlen_user(s, n); res = __strnlen_user(s, n);
return res; return res;
} }
......
...@@ -35,6 +35,17 @@ struct ucontext { ...@@ -35,6 +35,17 @@ struct ucontext {
* bytes, to prevent unpredictable padding in the signal frame. * bytes, to prevent unpredictable padding in the signal frame.
*/ */
#ifdef CONFIG_CRUNCH
#define CRUNCH_MAGIC 0x5065cf03
#define CRUNCH_STORAGE_SIZE (CRUNCH_SIZE + 8)
struct crunch_sigframe {
unsigned long magic;
unsigned long size;
struct crunch_state storage;
} __attribute__((__aligned__(8)));
#endif
#ifdef CONFIG_IWMMXT #ifdef CONFIG_IWMMXT
/* iwmmxt_area is 0x98 bytes long, preceeded by 8 bytes of signature */ /* iwmmxt_area is 0x98 bytes long, preceeded by 8 bytes of signature */
#define IWMMXT_MAGIC 0x12ef842a #define IWMMXT_MAGIC 0x12ef842a
...@@ -74,6 +85,9 @@ struct vfp_sigframe ...@@ -74,6 +85,9 @@ struct vfp_sigframe
* one of these. * one of these.
*/ */
struct aux_sigframe { struct aux_sigframe {
#ifdef CONFIG_CRUNCH
struct crunch_sigframe crunch;
#endif
#ifdef CONFIG_IWMMXT #ifdef CONFIG_IWMMXT
struct iwmmxt_sigframe iwmmxt; struct iwmmxt_sigframe iwmmxt;
#endif #endif
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册