diff options
Diffstat (limited to 'arch/mips/lib')
-rw-r--r-- | arch/mips/lib/Makefile | 4 | ||||
-rw-r--r-- | arch/mips/lib/csum_partial_copy.c | 8 | ||||
-rw-r--r-- | arch/mips/lib/memcpy.S | 15 | ||||
-rw-r--r-- | arch/mips/lib/uncached.c | 76 |
4 files changed, 97 insertions, 6 deletions
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile index 037303412909..cf12caf80774 100644 --- a/arch/mips/lib/Makefile +++ b/arch/mips/lib/Makefile | |||
@@ -2,8 +2,8 @@ | |||
2 | # Makefile for MIPS-specific library files.. | 2 | # Makefile for MIPS-specific library files.. |
3 | # | 3 | # |
4 | 4 | ||
5 | lib-y += csum_partial_copy.o memcpy.o promlib.o \ | 5 | lib-y += csum_partial_copy.o memcpy.o promlib.o strlen_user.o strncpy_user.o \ |
6 | strlen_user.o strncpy_user.o strnlen_user.o | 6 | strnlen_user.o uncached.o |
7 | 7 | ||
8 | obj-y += iomap.o | 8 | obj-y += iomap.o |
9 | 9 | ||
diff --git a/arch/mips/lib/csum_partial_copy.c b/arch/mips/lib/csum_partial_copy.c index ffed0a6a1c16..6e9f366f961d 100644 --- a/arch/mips/lib/csum_partial_copy.c +++ b/arch/mips/lib/csum_partial_copy.c | |||
@@ -16,8 +16,8 @@ | |||
16 | /* | 16 | /* |
17 | * copy while checksumming, otherwise like csum_partial | 17 | * copy while checksumming, otherwise like csum_partial |
18 | */ | 18 | */ |
19 | unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char *dst, | 19 | unsigned int csum_partial_copy_nocheck(const unsigned char *src, |
20 | int len, unsigned int sum) | 20 | unsigned char *dst, int len, unsigned int sum) |
21 | { | 21 | { |
22 | /* | 22 | /* |
23 | * It's 2:30 am and I don't feel like doing it real ... | 23 | * It's 2:30 am and I don't feel like doing it real ... |
@@ -33,8 +33,8 @@ unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char * | |||
33 | * Copy from userspace and compute checksum. If we catch an exception | 33 | * Copy from userspace and compute checksum. If we catch an exception |
34 | * then zero the rest of the buffer. | 34 | * then zero the rest of the buffer. |
35 | */ | 35 | */ |
36 | unsigned int csum_partial_copy_from_user (const unsigned char *src, unsigned char *dst, | 36 | unsigned int csum_partial_copy_from_user (const unsigned char __user *src, |
37 | int len, unsigned int sum, int *err_ptr) | 37 | unsigned char *dst, int len, unsigned int sum, int *err_ptr) |
38 | { | 38 | { |
39 | int missing; | 39 | int missing; |
40 | 40 | ||
diff --git a/arch/mips/lib/memcpy.S b/arch/mips/lib/memcpy.S index a78865f76547..7f9aafa4d80e 100644 --- a/arch/mips/lib/memcpy.S +++ b/arch/mips/lib/memcpy.S | |||
@@ -13,6 +13,21 @@ | |||
13 | * Mnemonic names for arguments to memcpy/__copy_user | 13 | * Mnemonic names for arguments to memcpy/__copy_user |
14 | */ | 14 | */ |
15 | #include <linux/config.h> | 15 | #include <linux/config.h> |
16 | |||
17 | /* | ||
18 | * Hack to resolve longstanding prefetch issue | ||
19 | * | ||
20 | * Prefetching may be fatal on some systems if we're prefetching beyond the | ||
21 | * end of memory on some systems. It's also a seriously bad idea on non | ||
22 | * dma-coherent systems. | ||
23 | */ | ||
24 | #if !defined(CONFIG_DMA_COHERENT) || !defined(CONFIG_DMA_IP27) | ||
25 | #undef CONFIG_CPU_HAS_PREFETCH | ||
26 | #endif | ||
27 | #ifdef CONFIG_MIPS_MALTA | ||
28 | #undef CONFIG_CPU_HAS_PREFETCH | ||
29 | #endif | ||
30 | |||
16 | #include <asm/asm.h> | 31 | #include <asm/asm.h> |
17 | #include <asm/asm-offsets.h> | 32 | #include <asm/asm-offsets.h> |
18 | #include <asm/regdef.h> | 33 | #include <asm/regdef.h> |
diff --git a/arch/mips/lib/uncached.c b/arch/mips/lib/uncached.c new file mode 100644 index 000000000000..98ce89f8068b --- /dev/null +++ b/arch/mips/lib/uncached.c | |||
@@ -0,0 +1,76 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2005 Thiemo Seufer | ||
7 | * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved. | ||
8 | * Author: Maciej W. Rozycki <macro@mips.com> | ||
9 | */ | ||
10 | |||
11 | #include <linux/init.h> | ||
12 | |||
13 | #include <asm/addrspace.h> | ||
14 | #include <asm/bug.h> | ||
15 | |||
16 | #ifndef CKSEG2 | ||
17 | #define CKSEG2 CKSSEG | ||
18 | #endif | ||
19 | #ifndef TO_PHYS_MASK | ||
20 | #define TO_PHYS_MASK -1 | ||
21 | #endif | ||
22 | |||
23 | /* | ||
24 | * FUNC is executed in one of the uncached segments, depending on its | ||
25 | * original address as follows: | ||
26 | * | ||
27 | * 1. If the original address is in CKSEG0 or CKSEG1, then the uncached | ||
28 | * segment used is CKSEG1. | ||
29 | * 2. If the original address is in XKPHYS, then the uncached segment | ||
30 | * used is XKPHYS(2). | ||
31 | * 3. Otherwise it's a bug. | ||
32 | * | ||
33 | * The same remapping is done with the stack pointer. Stack handling | ||
34 | * works because we don't handle stack arguments or more complex return | ||
35 | * values, so we can avoid sharing the same stack area between a cached | ||
36 | * and the uncached mode. | ||
37 | */ | ||
38 | unsigned long __init run_uncached(void *func) | ||
39 | { | ||
40 | register long sp __asm__("$sp"); | ||
41 | register long ret __asm__("$2"); | ||
42 | long lfunc = (long)func, ufunc; | ||
43 | long usp; | ||
44 | |||
45 | if (sp >= (long)CKSEG0 && sp < (long)CKSEG2) | ||
46 | usp = CKSEG1ADDR(sp); | ||
47 | else if ((long long)sp >= (long long)PHYS_TO_XKPHYS(0LL, 0) && | ||
48 | (long long)sp < (long long)PHYS_TO_XKPHYS(8LL, 0)) | ||
49 | usp = PHYS_TO_XKPHYS((long long)K_CALG_UNCACHED, | ||
50 | XKPHYS_TO_PHYS((long long)sp)); | ||
51 | else { | ||
52 | BUG(); | ||
53 | usp = sp; | ||
54 | } | ||
55 | if (lfunc >= (long)CKSEG0 && lfunc < (long)CKSEG2) | ||
56 | ufunc = CKSEG1ADDR(lfunc); | ||
57 | else if ((long long)lfunc >= (long long)PHYS_TO_XKPHYS(0LL, 0) && | ||
58 | (long long)lfunc < (long long)PHYS_TO_XKPHYS(8LL, 0)) | ||
59 | ufunc = PHYS_TO_XKPHYS((long long)K_CALG_UNCACHED, | ||
60 | XKPHYS_TO_PHYS((long long)lfunc)); | ||
61 | else { | ||
62 | BUG(); | ||
63 | ufunc = lfunc; | ||
64 | } | ||
65 | |||
66 | __asm__ __volatile__ ( | ||
67 | " move $16, $sp\n" | ||
68 | " move $sp, %1\n" | ||
69 | " jalr %2\n" | ||
70 | " move $sp, $16" | ||
71 | : "=r" (ret) | ||
72 | : "r" (usp), "r" (ufunc) | ||
73 | : "$16", "$31"); | ||
74 | |||
75 | return ret; | ||
76 | } | ||