Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * linux/arch/arm/lib/csumpartialcopyuser.S | |
3 | * | |
4 | * Copyright (C) 1995-1998 Russell King | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License version 2 as | |
8 | * published by the Free Software Foundation. | |
9 | * | |
10 | * 27/03/03 Ian Molton Clean up CONFIG_CPU | |
11 | * | |
12 | */ | |
13 | #include <linux/linkage.h> | |
14 | #include <asm/assembler.h> | |
15 | #include <asm/errno.h> | |
e6ae744d | 16 | #include <asm/asm-offsets.h> |
1da177e4 LT |
17 | |
18 | .text | |
19 | ||
20 | .macro save_regs | |
21 | stmfd sp!, {r1 - r2, r4 - r8, fp, ip, lr, pc} | |
22 | .endm | |
23 | ||
24 | .macro load_regs,flags | |
25 | ldm\flags fp, {r1, r2, r4-r8, fp, sp, pc} | |
26 | .endm | |
27 | ||
28 | .macro load1b, reg1 | |
29 | 9999: ldrbt \reg1, [r0], $1 | |
30 | .section __ex_table, "a" | |
31 | .align 3 | |
32 | .long 9999b, 6001f | |
33 | .previous | |
34 | .endm | |
35 | ||
36 | .macro load2b, reg1, reg2 | |
37 | 9999: ldrbt \reg1, [r0], $1 | |
38 | 9998: ldrbt \reg2, [r0], $1 | |
39 | .section __ex_table, "a" | |
40 | .long 9999b, 6001f | |
41 | .long 9998b, 6001f | |
42 | .previous | |
43 | .endm | |
44 | ||
45 | .macro load1l, reg1 | |
46 | 9999: ldrt \reg1, [r0], $4 | |
47 | .section __ex_table, "a" | |
48 | .align 3 | |
49 | .long 9999b, 6001f | |
50 | .previous | |
51 | .endm | |
52 | ||
53 | .macro load2l, reg1, reg2 | |
54 | 9999: ldrt \reg1, [r0], $4 | |
55 | 9998: ldrt \reg2, [r0], $4 | |
56 | .section __ex_table, "a" | |
57 | .long 9999b, 6001f | |
58 | .long 9998b, 6001f | |
59 | .previous | |
60 | .endm | |
61 | ||
62 | .macro load4l, reg1, reg2, reg3, reg4 | |
63 | 9999: ldrt \reg1, [r0], $4 | |
64 | 9998: ldrt \reg2, [r0], $4 | |
65 | 9997: ldrt \reg3, [r0], $4 | |
66 | 9996: ldrt \reg4, [r0], $4 | |
67 | .section __ex_table, "a" | |
68 | .long 9999b, 6001f | |
69 | .long 9998b, 6001f | |
70 | .long 9997b, 6001f | |
71 | .long 9996b, 6001f | |
72 | .previous | |
73 | .endm | |
74 | ||
75 | /* | |
76 | * unsigned int | |
77 | * csum_partial_copy_from_user(const char *src, char *dst, int len, int sum, int *err_ptr) | |
78 | * r0 = src, r1 = dst, r2 = len, r3 = sum, [sp] = *err_ptr | |
79 | * Returns : r0 = checksum, [[sp, #0], #0] = 0 or -EFAULT | |
80 | */ | |
81 | ||
82 | #define FN_ENTRY ENTRY(csum_partial_copy_from_user) | |
83 | ||
84 | #include "csumpartialcopygeneric.S" | |
85 | ||
86 | /* | |
87 | * FIXME: minor buglet here | |
88 | * We don't return the checksum for the data present in the buffer. To do | |
89 | * so properly, we would have to add in whatever registers were loaded before | |
90 | * the fault, which, with the current asm above is not predictable. | |
91 | */ | |
92 | .section .fixup,"ax" | |
93 | .align 4 | |
94 | 6001: mov r4, #-EFAULT | |
95 | ldr r5, [fp, #4] @ *err_ptr | |
96 | str r4, [r5] | |
97 | ldmia sp, {r1, r2} @ retrieve dst, len | |
98 | add r2, r2, r1 | |
99 | mov r0, #0 @ zero the buffer | |
100 | 6002: teq r2, r1 | |
101 | strneb r0, [r1], #1 | |
102 | bne 6002b | |
103 | load_regs ea | |
104 | .previous |