summaryrefslogtreecommitdiffstats
path: root/include/asm-mips
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1998-05-04 09:12:48 +0000
committerRalf Baechle <ralf@linux-mips.org>1998-05-04 09:12:48 +0000
commit2e0f55e79c49509b7ff70ff1a10e1e9e90a3dfd4 (patch)
tree9ff1a23dd500f1c70eb99fcd688d47d38abb0253 /include/asm-mips
parentbbc6b4b59f51131f040a752cbe20a1805db08b0b (diff)
o New memset. Fastest in town for size > 6 bytes.
o New clear_user. o Memcpy now efficiently copies the (src^dest)&3 != 0. o Memmove new correctly deals with overlaps o Rewrite csum_partial in assembler. o Rewrte csum_partial_from_user in assembler. o __copy_user is now integrated with memcpy. o get_user now returns a zero value on error. o copy_from_user now clears the destination buffer on error. o strncpy_user now has a more efficient caller routine. o strlen_user now has a more efficient caller routines and is faster. o The unaligned handler is now much cleaner. It's now also save from interrupt. Some more esotheric bugs fixed as well. o Don't export bcopy anymore, it's now a inline function. o Delete ancient junk from the first days of Linux/MIPS. o Delete dead code in indy_sc.c. o Including the IDE driver doesn't crash an Indy anymore. o Eleminate active_ds. We now use current_ds directly in the thread structure which is faster and threadsafe. Saves almost 2kb on the kernel. o Serial console should work again.
Diffstat (limited to 'include/asm-mips')
-rw-r--r--include/asm-mips/branch.h13
-rw-r--r--include/asm-mips/ide.h76
-rw-r--r--include/asm-mips/offset.h17
-rw-r--r--include/asm-mips/processor.h11
-rw-r--r--include/asm-mips/stackframe.h17
-rw-r--r--include/asm-mips/string.h7
-rw-r--r--include/asm-mips/system.h129
-rw-r--r--include/asm-mips/uaccess.h247
8 files changed, 309 insertions, 208 deletions
diff --git a/include/asm-mips/branch.h b/include/asm-mips/branch.h
index 08dda213e..d8882cfb1 100644
--- a/include/asm-mips/branch.h
+++ b/include/asm-mips/branch.h
@@ -5,7 +5,9 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 1996, 1997 by Ralf Baechle
+ * Copyright (C) 1996, 1997, 1998 by Ralf Baechle
+ *
+ * $Id: branch.h,v 1.2 1998/04/28 19:37:46 ralf Exp $
*/
#include <asm/ptrace.h>
@@ -15,12 +17,13 @@ extern inline int delay_slot(struct pt_regs *regs)
}
extern int __compute_return_epc(struct pt_regs *regs);
+
extern inline int compute_return_epc(struct pt_regs *regs)
{
- if (delay_slot(regs)) {
- return __compute_return_epc(regs);
+ if (!delay_slot(regs)) {
+ regs->cp0_epc += 4;
+ return 0;
}
- regs->cp0_epc += 4;
- return 0;
+ return __compute_return_epc(regs);
}
diff --git a/include/asm-mips/ide.h b/include/asm-mips/ide.h
index bda27206d..b54a7657c 100644
--- a/include/asm-mips/ide.h
+++ b/include/asm-mips/ide.h
@@ -21,40 +21,36 @@ typedef unsigned short ide_ioreg_t;
#define ide_sti() sti()
+struct ide_ops {
+ int (*ide_default_irq)(ide_ioreg_t base);
+ ide_ioreg_t (*ide_default_io_base)(int index);
+ void (*ide_init_hwif_ports)(ide_ioreg_t *p, ide_ioreg_t base, int *irq);
+ int (*ide_request_irq)(unsigned int irq, void (*handler)(int, void *,
+ struct pt_regs *), unsigned long flags,
+ const char *device, void *dev_id);
+ void (*ide_free_irq)(unsigned int irq, void *dev_id);
+ int (*ide_check_region) (ide_ioreg_t from, unsigned int extent);
+ void (*ide_request_region)(ide_ioreg_t from, unsigned int extent,
+ const char *name);
+ void (*ide_release_region)(ide_ioreg_t from, unsigned int extent);
+};
+
+extern struct ide_ops *ide_ops;
+
static __inline__ int ide_default_irq(ide_ioreg_t base)
{
- switch (base) {
- case 0x1f0: return 14;
- case 0x170: return 15;
- case 0x1e8: return 11;
- case 0x168: return 10;
- default:
- return 0;
- }
+ return ide_ops->ide_default_irq(base);
}
static __inline__ ide_ioreg_t ide_default_io_base(int index)
{
- switch (index) {
- case 0: return 0x1f0;
- case 1: return 0x170;
- case 2: return 0x1e8;
- case 3: return 0x168;
- default:
- return 0;
- }
+ return ide_ops->ide_default_io_base(index);
}
-static __inline__ void ide_init_hwif_ports (ide_ioreg_t *p, ide_ioreg_t base, int *irq)
+static __inline__ void ide_init_hwif_ports(ide_ioreg_t *p, ide_ioreg_t base,
+ int *irq)
{
- ide_ioreg_t port = base;
- int i = 8;
-
- while (i--)
- *p++ = port++;
- *p++ = base + 0x206;
- if (irq != NULL)
- *irq = 0;
+ ide_ops->ide_init_hwif_ports(p, base, irq);
}
typedef union {
@@ -68,38 +64,41 @@ typedef union {
} b;
} select_t;
-static __inline__ int ide_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+static __inline__ int ide_request_irq(unsigned int irq, void (*handler)(int,void *, struct pt_regs *),
unsigned long flags, const char *device, void *dev_id)
{
- return request_irq(irq, handler, flags, device, dev_id);
-}
+ return ide_ops->ide_request_irq(irq, handler, flags, device, dev_id);
+}
static __inline__ void ide_free_irq(unsigned int irq, void *dev_id)
{
- free_irq(irq, dev_id);
+ ide_ops->ide_free_irq(irq, dev_id);
}
static __inline__ int ide_check_region (ide_ioreg_t from, unsigned int extent)
{
- return check_region(from, extent);
+ return ide_ops->ide_check_region(from, extent);
}
-static __inline__ void ide_request_region (ide_ioreg_t from, unsigned int extent, const char *name)
+static __inline__ void ide_request_region(ide_ioreg_t from,
+ unsigned int extent, const char *name)
{
- request_region(from, extent, name);
+ ide_ops->ide_request_region(from, extent, name);
}
-static __inline__ void ide_release_region (ide_ioreg_t from, unsigned int extent)
+static __inline__ void ide_release_region(ide_ioreg_t from,
+ unsigned int extent)
{
- release_region(from, extent);
+ ide_ops->ide_release_region(from, extent);
}
/*
* The following are not needed for the non-m68k ports
*/
-static __inline__ int ide_ack_intr (ide_ioreg_t status_port, ide_ioreg_t irq_port)
+static __inline__ int ide_ack_intr (ide_ioreg_t status_port,
+ ide_ioreg_t irq_port)
{
- return(1);
+ return 1;
}
static __inline__ void ide_fix_driveid(struct hd_driveid *id)
@@ -110,7 +109,10 @@ static __inline__ void ide_release_lock (int *ide_lock)
{
}
-static __inline__ void ide_get_lock (int *ide_lock, void (*handler)(int, void *, struct pt_regs *), void *data)
+static __inline__ void ide_get_lock (int *ide_lock,
+ void (*handler)(int, void *,
+ struct pt_regs *),
+ void *data)
{
}
diff --git a/include/asm-mips/offset.h b/include/asm-mips/offset.h
index e211de3cc..32deafe7b 100644
--- a/include/asm-mips/offset.h
+++ b/include/asm-mips/offset.h
@@ -50,7 +50,7 @@
#define TASK_PRIORITY 56
#define TASK_FLAGS 4
#define TASK_SIGPENDING 8
-#define TASK_MM 920
+#define TASK_MM 928
/* MIPS specific thread_struct offsets. */
#define THREAD_REG16 568
@@ -67,13 +67,14 @@
#define THREAD_STATUS 612
#define THREAD_FPU 616
#define THREAD_BVADDR 880
-#define THREAD_ECODE 884
-#define THREAD_TRAPNO 888
-#define THREAD_PGDIR 892
-#define THREAD_MFLAGS 896
-#define THREAD_CURDS 900
-#define THREAD_TRAMP 904
-#define THREAD_OLDCTX 908
+#define THREAD_BUADDR 884
+#define THREAD_ECODE 888
+#define THREAD_TRAPNO 892
+#define THREAD_PGDIR 896
+#define THREAD_MFLAGS 900
+#define THREAD_CURDS 904
+#define THREAD_TRAMP 908
+#define THREAD_OLDCTX 912
/* Linux mm_struct offsets. */
#define MM_COUNT 12
diff --git a/include/asm-mips/processor.h b/include/asm-mips/processor.h
index 765208d3e..98d5e6a86 100644
--- a/include/asm-mips/processor.h
+++ b/include/asm-mips/processor.h
@@ -5,7 +5,7 @@
* written by Ralf Baechle
* Modified further for R[236]000 compatibility by Paul M. Antoine
*
- * $Id: processor.h,v 1.8 1998/03/27 04:47:59 ralf Exp $
+ * $Id: processor.h,v 1.13 1998/04/25 05:35:15 ralf Exp $
*/
#ifndef __ASM_MIPS_PROCESSOR_H
#define __ASM_MIPS_PROCESSOR_H
@@ -90,7 +90,7 @@ typedef struct {
*/
struct thread_struct {
/* Saved main processor registers. */
- unsigned long reg16 __attribute__ ((aligned (8)));
+ unsigned long reg16;
unsigned long reg17, reg18, reg19, reg20, reg21, reg22, reg23;
unsigned long reg29, reg30, reg31;
@@ -98,10 +98,11 @@ struct thread_struct {
unsigned long cp0_status;
/* Saved fpu/fpu emulator stuff. */
- union mips_fpu_union fpu __attribute__ ((aligned (8)));
+ union mips_fpu_union fpu;
/* Other stuff associated with the thread. */
- unsigned long cp0_badvaddr;
+ unsigned long cp0_badvaddr; /* Last user fault */
+ unsigned long cp0_baduaddr; /* Last kernel fault accessing USEG */
unsigned long error_code;
unsigned long trap_no;
unsigned long pg_dir; /* used in tlb refill */
@@ -135,7 +136,7 @@ struct thread_struct {
/* \
* Other stuff associated with the process \
*/ \
- 0, 0, 0, (unsigned long) swapper_pg_dir, \
+ 0, 0, 0, 0, (unsigned long) swapper_pg_dir, \
/* \
* For now the default is to fix address errors \
*/ \
diff --git a/include/asm-mips/stackframe.h b/include/asm-mips/stackframe.h
index e925dcd50..726e82f23 100644
--- a/include/asm-mips/stackframe.h
+++ b/include/asm-mips/stackframe.h
@@ -3,7 +3,7 @@
*
* Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Paul M. Antoine.
*
- * $Id: stackframe.h,v 1.6 1998/03/26 07:39:21 ralf Exp $
+ * $Id: stackframe.h,v 1.7 1998/04/28 19:39:15 ralf Exp $
*/
#ifndef __ASM_MIPS_STACKFRAME_H
#define __ASM_MIPS_STACKFRAME_H
@@ -174,10 +174,6 @@
/*
* Move to kernel mode and enable interrupts.
* Set cp0 enable bit as sign that we're running on the kernel stack
- *
- * Note that the mtc0 will be effective on R4000 pipeline stage 7. This
- * means that another three instructions will be executed with interrupts
- * disabled. Arch/mips/mips3/r4xx0.S makes use of this fact.
*/
#define STI \
mfc0 t0,CP0_STATUS; \
@@ -186,4 +182,15 @@
xori t0,0x1e; \
mtc0 t0,CP0_STATUS
+/*
+ * Just move to kernel mode and leave interrupts as they are.
+ * Set cp0 enable bit as sign that we're running on the kernel stack
+ */
+#define KMODE \
+ mfc0 t0,CP0_STATUS; \
+ li t1,ST0_CU0|0x1e; \
+ or t0,t1; \
+ xori t0,0x1e; \
+ mtc0 t0,CP0_STATUS
+
#endif /* __ASM_MIPS_STACKFRAME_H */
diff --git a/include/asm-mips/string.h b/include/asm-mips/string.h
index 39e6b445c..7f4bded24 100644
--- a/include/asm-mips/string.h
+++ b/include/asm-mips/string.h
@@ -7,7 +7,7 @@
*
* Copyright (c) 1994, 1995, 1996, 1997 by Ralf Baechle
*
- * $Id: string.h,v 1.4 1998/03/21 19:31:09 ralf Exp $
+ * $Id: string.h,v 1.7 1998/03/25 00:24:10 ralf Exp $
*/
#ifndef __ASM_MIPS_STRING_H
#define __ASM_MIPS_STRING_H
@@ -128,7 +128,10 @@ extern void *memcpy(void *__to, __const__ void *__from, size_t __n);
extern void *memmove(void *__dest, __const__ void *__src, size_t __n);
#define __HAVE_ARCH_BCOPY
-extern char * bcopy(const char * src, char * dest, int count);
+extern __inline__ char * bcopy(const char * src, char * dest, int count)
+{
+ memmove(dest, src, count);
+}
#define __HAVE_ARCH_MEMSCAN
extern __inline__ void *memscan(void *__addr, int __c, size_t __size)
diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h
index abeaa3343..ab8faf278 100644
--- a/include/asm-mips/system.h
+++ b/include/asm-mips/system.h
@@ -7,6 +7,8 @@
*
* Copyright (C) 1994, 1995 by Ralf Baechle
* Modified further for R[236]000 by Paul M. Antoine, 1996
+ *
+ * $Id: system.h,v 1.6 1998/05/03 11:13:54 ralf Exp $
*/
#ifndef __ASM_MIPS_SYSTEM_H
#define __ASM_MIPS_SYSTEM_H
@@ -17,18 +19,18 @@
extern __inline__ void
__sti(void)
{
- __asm__ __volatile__(
- ".set\tnoreorder\n\t"
- ".set\tnoat\n\t"
- "mfc0\t$1,$12\n\t"
- "ori\t$1,0x1f\n\t"
- "xori\t$1,0x1e\n\t"
- "mtc0\t$1,$12\n\t"
- ".set\tat\n\t"
- ".set\treorder"
- : /* no outputs */
- : /* no inputs */
- : "$1", "memory");
+ __asm__ __volatile__(
+ ".set\tnoreorder\n\t"
+ ".set\tnoat\n\t"
+ "mfc0\t$1,$12\n\t"
+ "ori\t$1,0x1f\n\t"
+ "xori\t$1,0x1e\n\t"
+ "mtc0\t$1,$12\n\t"
+ ".set\tat\n\t"
+ ".set\treorder"
+ : /* no outputs */
+ : /* no inputs */
+ : "$1", "memory");
}
/*
@@ -41,21 +43,21 @@ __sti(void)
extern __inline__ void
__cli(void)
{
- __asm__ __volatile__(
- ".set\tnoreorder\n\t"
- ".set\tnoat\n\t"
- "mfc0\t$1,$12\n\t"
- "ori\t$1,1\n\t"
- "xori\t$1,1\n\t"
- "mtc0\t$1,$12\n\t"
- "nop\n\t"
- "nop\n\t"
- "nop\n\t"
- ".set\tat\n\t"
- ".set\treorder"
- : /* no outputs */
- : /* no inputs */
- : "$1", "memory");
+ __asm__ __volatile__(
+ ".set\tnoreorder\n\t"
+ ".set\tnoat\n\t"
+ "mfc0\t$1,$12\n\t"
+ "ori\t$1,1\n\t"
+ "xori\t$1,1\n\t"
+ "mtc0\t$1,$12\n\t"
+ "nop\n\t"
+ "nop\n\t"
+ "nop\n\t"
+ ".set\tat\n\t"
+ ".set\treorder"
+ : /* no outputs */
+ : /* no inputs */
+ : "$1", "memory");
}
#define __save_flags(x) \
@@ -87,16 +89,16 @@ __asm__ __volatile__( \
extern void __inline__
__restore_flags(int flags)
{
- __asm__ __volatile__(
- ".set\tnoreorder\n\t"
- "mtc0\t%0,$12\n\t"
- "nop\n\t"
- "nop\n\t"
- "nop\n\t"
- ".set\treorder"
- : /* no output */
- : "r" (flags)
- : "memory");
+ __asm__ __volatile__(
+ ".set\tnoreorder\n\t"
+ "mtc0\t%0,$12\n\t"
+ "nop\n\t"
+ "nop\n\t"
+ "nop\n\t"
+ ".set\treorder"
+ : /* no output */
+ : "r" (flags)
+ : "memory");
}
/*
@@ -113,7 +115,7 @@ __asm__ __volatile__( \
"# prevent instructions being moved around\n\t" \
".set\tnoreorder\n\t" \
".set\treorder" \
- : /* no output */ \
+ : /* no output */ \
: /* no input */ \
: "memory")
@@ -125,47 +127,12 @@ __asm__ __volatile__( \
extern asmlinkage void (*resume)(void *tsk);
#endif /* !defined (__LANGUAGE_ASSEMBLY__) */
-/*
- * FIXME: resume() assumes current == prev
- */
#define switch_to(prev,next) \
do { \
- prev->tss.current_ds = active_ds; \
- active_ds = next->tss.current_ds; \
- resume(next); \
+ resume(next); \
} while(0)
/*
- * The 8 and 16 bit variants have to disable interrupts temporarily.
- * Both are currently unused.
- */
-extern __inline__ unsigned long xchg_u8(volatile char * m, unsigned long val)
-{
- unsigned long flags, retval;
-
- save_flags(flags);
- cli();
- retval = *m;
- *m = val;
- restore_flags(flags);
-
- return retval;
-}
-
-extern __inline__ unsigned long xchg_u16(volatile short * m, unsigned long val)
-{
- unsigned long flags, retval;
-
- save_flags(flags);
- cli();
- retval = *m;
- *m = val;
- restore_flags(flags);
-
- return retval;
-}
-
-/*
* For 32 and 64 bit operands we can take advantage of ll and sc.
* FIXME: This doesn't work for R3000 machines.
*/
@@ -186,8 +153,9 @@ extern __inline__ unsigned long xchg_u32(volatile int * m, unsigned long val)
".set\tat\n\t"
".set\treorder"
: "=r" (val), "=r" (m), "=r" (dummy)
- : "1" (m), "2" (val));
-#else /* FIXME: Brain-dead approach, but then again, I AM hacking - PMA */
+ : "1" (m), "2" (val)
+ : "memory");
+#else
unsigned long flags, retval;
save_flags(flags);
@@ -218,7 +186,8 @@ extern __inline__ unsigned long xchg_u64(volatile long * m, unsigned long val)
".set\tat\n\t"
".set\treorder"
: "=r" (val), "=r" (m), "=r" (dummy)
- : "1" (m), "2" (val));
+ : "1" (m), "2" (val)
+ : "memory");
return val;
}
@@ -239,14 +208,12 @@ extern void __xchg_called_with_bad_pointer(void);
static __inline__ unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
{
switch (size) {
- case 1:
- return xchg_u8(ptr, x);
- case 2:
- return xchg_u16(ptr, x);
case 4:
return xchg_u32(ptr, x);
+#if defined(__mips64)
case 8:
return xchg_u64(ptr, x);
+#endif
}
__xchg_called_with_bad_pointer();
return x;
diff --git a/include/asm-mips/uaccess.h b/include/asm-mips/uaccess.h
index 42a7df686..8b139fe23 100644
--- a/include/asm-mips/uaccess.h
+++ b/include/asm-mips/uaccess.h
@@ -5,16 +5,15 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 1996, 1997 by Ralf Baechle
+ * Copyright (C) 1996, 1997, 1998 by Ralf Baechle
*
- * $Id: uaccess.h,v 1.7 1998/03/21 08:04:33 ralf Exp $
+ * $Id: uaccess.h,v 1.15 1998/05/03 11:13:54 ralf Exp $
*/
#ifndef __ASM_MIPS_UACCESS_H
#define __ASM_MIPS_UACCESS_H
#include <linux/errno.h>
#include <linux/sched.h>
-#include <asm/asm.h>
#define STR(x) __STR(x)
#define __STR(x) #x
@@ -32,11 +31,9 @@
#define VERIFY_READ 0
#define VERIFY_WRITE 1
-extern mm_segment_t active_ds;
-
-#define get_fs() (active_ds)
+#define get_fs() (current->tss.current_ds)
#define get_ds() (KERNEL_DS)
-#define set_fs(x) (active_ds=(x))
+#define set_fs(x) (current->tss.current_ds=(x))
#define segment_eq(a,b) ((a).seg == (b).seg)
@@ -107,24 +104,6 @@ if (__get_user(x,ptr)) return ret; })
struct __large_struct { unsigned long buf[100]; };
#define __m(x) (*(struct __large_struct *)(x))
-#define copy_to_user(to,from,n) __copy_tofrom_user((to),(from),(n),__cu_to)
-#define copy_from_user(to,from,n) __copy_tofrom_user((to),(from),(n),__cu_from)
-
-extern size_t __copy_user(void *__to, const void *__from, size_t __n);
-
-#define __copy_tofrom_user(to,from,n,v) ({ \
- void * __cu_to; \
- const void * __cu_from; \
- long __cu_len; \
- \
- __cu_to = (to); \
- __cu_from = (from); \
- __cu_len = (n); \
- if (__access_ok(((unsigned long)(v)),__cu_len,__access_mask)) \
- __cu_len = __copy_user(__cu_to, __cu_from, __cu_len); \
- __cu_len; \
-})
-
/*
* Yuck. We need two variants, one for 64bit operation and one
* for 32 bit mode and old iron.
@@ -174,10 +153,11 @@ __asm__ __volatile__( \
"2:\n\t" \
".section\t.fixup,\"ax\"\n" \
"3:\tli\t%0,%3\n\t" \
+ "move\t%1,$0\n\t" \
"j\t2b\n\t" \
".previous\n\t" \
".section\t__ex_table,\"a\"\n\t" \
- STR(PTR)"\t1b,3b\n\t" \
+ ".word\t1b,3b\n\t" \
".previous" \
:"=r" (__gu_err), "=r" (__gu_val) \
:"o" (__m(__gu_addr)), "i" (-EFAULT)); })
@@ -193,11 +173,13 @@ __asm__ __volatile__( \
"move\t%0,$0\n" \
"3:\t.section\t.fixup,\"ax\"\n" \
"4:\tli\t%0,%4\n\t" \
+ "move\t%1,$0\n\t" \
+ "move\t%D1,$0\n\t" \
"j\t3b\n\t" \
".previous\n\t" \
".section\t__ex_table,\"a\"\n\t" \
- STR(PTR)"\t1b,4b\n\t" \
- STR(PTR)"\t2b,4b\n\t" \
+ ".word\t1b,4b\n\t" \
+ ".word\t2b,4b\n\t" \
".previous" \
:"=r" (__gu_err), "=&r" (__gu_val) \
:"o" (__m(__gu_addr)), "o" (__m(__gu_addr + 4)), \
@@ -257,7 +239,7 @@ __asm__ __volatile__( \
"j\t2b\n\t" \
".previous\n\t" \
".section\t__ex_table,\"a\"\n\t" \
- STR(PTR)"\t1b,3b\n\t" \
+ ".word\t1b,3b\n\t" \
".previous" \
:"=r" (__pu_err) \
:"r" (__pu_val), "o" (__m(__pu_addr)), "i" (-EFAULT)); })
@@ -274,8 +256,8 @@ __asm__ __volatile__( \
"j\t3b\n\t" \
".previous\n\t" \
".section\t__ex_table,\"a\"\n\t" \
- STR(PTR)"\t1b,4b\n\t" \
- STR(PTR)"\t2b,4b\n\t" \
+ ".word\t1b,4b\n\t" \
+ ".word\t2b,4b\n\t" \
".previous" \
:"=r" (__pu_err) \
:"r" (__pu_val), "o" (__m(__pu_addr)), "o" (__m(__pu_addr + 4)), \
@@ -293,60 +275,195 @@ if (copy_from_user(to,from,n)) \
return retval; \
})
-#define __copy_to_user(to,from,n) \
- __copy_user((to),(from),(n))
+extern size_t __copy_user(void *__to, const void *__from, size_t __n);
-#define __copy_from_user(to,from,n) \
- __copy_user((to),(from),(n))
+#define __copy_to_user(to,from,n) ({ \
+ void *__cu_to; \
+ const void *__cu_from; \
+ long __cu_len; \
+ \
+ __cu_to = (to); \
+ __cu_from = (from); \
+ __cu_len = (n); \
+ __asm__ __volatile__( \
+ "move\t$4, %1\n\t" \
+ "move\t$5, %2\n\t" \
+ "move\t$6, %3\n\t" \
+ "jal\t__copy_user\n\t" \
+ "move\t%0, $6" \
+ : "=r" (__cu_len) \
+ : "r" (__cu_to), "r" (__cu_from), "r" (__cu_len) \
+ : "$4", "$5", "$6", "$8", "$9", "$10", "$11", "$12", "$15", \
+ "$24", "$31","memory"); \
+ __cu_len; \
+})
-#define __clear_user(addr,size) \
-({ \
- void *__cu_end; \
+#define __copy_from_user(to,from,n) ({ \
+ void *__cu_to; \
+ const void *__cu_from; \
+ long __cu_len; \
+ \
+ __cu_to = (to); \
+ __cu_from = (from); \
+ __cu_len = (n); \
__asm__ __volatile__( \
- ".set\tnoreorder\n\t" \
- "1:\taddiu\t%0,1\n" \
- "bne\t%0,%1,1b\n\t" \
- "sb\t$0,-1(%0)\n\t" \
- "2:\t.set\treorder\n\t" \
- ".section\t.fixup,\"ax\"\n" \
- "3:\tsubu\t%0,1\n\t" \
- "j\t2b\n\t" \
- ".previous\n\t" \
- ".section\t__ex_table,\"a\"\n\t" \
- STR(PTR)"\t1b,3b\n\t" \
- ".previous" \
- :"=r" (addr), "=r" (__cu_end) \
- :"0" (addr), "1" (addr + size), "i" (-EFAULT) \
- :"memory"); \
- size = __cu_end - (addr); \
+ "move\t$4, %1\n\t" \
+ "move\t$5, %2\n\t" \
+ "move\t$6, %3\n\t" \
+ ".set\tnoat\n\t" \
+ "addu\t$1, %2, %3\n\t" \
+ ".set\tat\n\t" \
+ "jal\t__copy_user\n\t" \
+ "move\t%0, $6" \
+ : "=r" (__cu_len) \
+ : "r" (__cu_to), "r" (__cu_from), "r" (__cu_len) \
+ : "$4", "$5", "$6", "$8", "$9", "$10", "$11", "$12", "$15", \
+ "$24", "$31","memory"); \
+ __cu_len; \
+})
+
+#define copy_to_user(to,from,n) ({ \
+ void *__cu_to; \
+ const void *__cu_from; \
+ long __cu_len; \
+ \
+ __cu_to = (to); \
+ __cu_from = (from); \
+ __cu_len = (n); \
+ if (access_ok(VERIFY_WRITE, __cu_to, __cu_len)) \
+ __asm__ __volatile__( \
+ "move\t$4, %1\n\t" \
+ "move\t$5, %2\n\t" \
+ "move\t$6, %3\n\t" \
+ "jal\t__copy_user\n\t" \
+ "move\t%0, $6" \
+ : "=r" (__cu_len) \
+ : "r" (__cu_to), "r" (__cu_from), "r" (__cu_len) \
+ : "$4", "$5", "$6", "$8", "$9", "$10", "$11", "$12", \
+ "$15", "$24", "$31","memory"); \
+ __cu_len; \
+})
+
+#define copy_from_user(to,from,n) ({ \
+ void *__cu_to; \
+ const void *__cu_from; \
+ long __cu_len; \
+ \
+ __cu_to = (to); \
+ __cu_from = (from); \
+ __cu_len = (n); \
+ if (access_ok(VERIFY_READ, __cu_from, __cu_len)) \
+ __asm__ __volatile__( \
+ "move\t$4, %1\n\t" \
+ "move\t$5, %2\n\t" \
+ "move\t$6, %3\n\t" \
+ ".set\tnoat\n\t" \
+ "addu\t$1, %2, %3\n\t" \
+ ".set\tat\n\t" \
+ "jal\t__copy_user\n\t" \
+ "move\t%0, $6" \
+ : "=r" (__cu_len) \
+ : "r" (__cu_to), "r" (__cu_from), "r" (__cu_len) \
+ : "$4", "$5", "$6", "$8", "$9", "$10", "$11", "$12", \
+ "$15", "$24", "$31","memory"); \
+ __cu_len; \
})
+extern inline __kernel_size_t
+__clear_user(void *addr, __kernel_size_t size)
+{
+ __kernel_size_t res;
+
+ __asm__ __volatile__(
+ "move\t$4, %1\n\t"
+ "move\t$5, $0\n\t"
+ "move\t$6, %2\n\t"
+ "jal\t__bzero\n\t"
+ "move\t%0, $6"
+ : "=r" (res)
+ : "r" (addr), "r" (size)
+ : "$4", "$5", "$6", "$8", "$9", "$31");
+
+ return res;
+}
+
#define clear_user(addr,n) ({ \
void * __cl_addr = (addr); \
unsigned long __cl_size = (n); \
if (__cl_size && __access_ok(VERIFY_WRITE, ((unsigned long)(__cl_addr)), __cl_size)) \
-__clear_user(__cl_addr, __cl_size); \
+__cl_size = __clear_user(__cl_addr, __cl_size); \
__cl_size; })
/*
* Returns: -EFAULT if exception before terminator, N if the entire
* buffer filled, else strlen.
*/
-extern long __strncpy_from_user(char *__to, const char *__from, long __to_len);
+extern inline long
+__strncpy_from_user(char *__to, const char *__from, long __len)
+{
+ long res;
+
+ __asm__ __volatile__(
+ "move\t$4, %1\n\t"
+ "move\t$5, %2\n\t"
+ "move\t$6, %3\n\t"
+ "jal\t__strncpy_from_user_nocheck_asm\n\t"
+ "move\t%0, $2"
+ : "=r" (res)
+ : "r" (__to), "r" (__from), "r" (__len)
+ : "$2", "$3", "$4", "$5", "$6", "$8", "$31", "memory");
+
+ return res;
+}
+
+extern inline long
+strncpy_from_user(char *__to, const char *__from, long __len)
+{
+ long res;
+
+ __asm__ __volatile__(
+ "move\t$4, %1\n\t"
+ "move\t$5, %2\n\t"
+ "move\t$6, %3\n\t"
+ "jal\t__strncpy_from_user_asm\n\t"
+ "move\t%0, $2"
+ : "=r" (res)
+ : "r" (__to), "r" (__from), "r" (__len)
+ : "$2", "$3", "$4", "$5", "$6", "$8", "$31", "memory");
+
+ return res;
+}
-#define strncpy_from_user(dest,src,count) ({ \
- const void * __sc_src = (src); \
- long __sc_res = -EFAULT; \
- if (access_ok(VERIFY_READ, __sc_src, 0)) { \
- __sc_res = __strncpy_from_user(dest, __sc_src, count); \
-} __sc_res; })
/* Returns: 0 if bad, string length+1 (memory size) of string if ok */
-extern long __strlen_user(const char *);
+extern inline long __strlen_user(const char *s)
+{
+ long res;
-extern inline long strlen_user(const char *str)
+ __asm__ __volatile__(
+ "move\t$4, %1\n\t"
+ "jal\t__strlen_user_nocheck_asm\n\t"
+ "move\t%0, $2"
+ : "=r" (res)
+ : "r" (s)
+ : "$2", "$4", "$8", "$31");
+
+ return res;
+}
+
+extern inline long strlen_user(const char *s)
{
- return access_ok(VERIFY_READ,str,0) ? __strlen_user(str) : 0;
+ long res;
+
+ __asm__ __volatile__(
+ "move\t$4, %1\n\t"
+ "jal\t__strlen_user_asm\n\t"
+ "move\t%0, $2"
+ : "=r" (res)
+ : "r" (s)
+ : "$2", "$4", "$8", "$31");
+
+ return res;
}
struct exception_table_entry