diff options
Diffstat (limited to 'arch/avr32/lib')
| -rw-r--r-- | arch/avr32/lib/Makefile | 10 | ||||
| -rw-r--r-- | arch/avr32/lib/__avr32_asr64.S | 31 | ||||
| -rw-r--r-- | arch/avr32/lib/__avr32_lsl64.S | 31 | ||||
| -rw-r--r-- | arch/avr32/lib/__avr32_lsr64.S | 31 | ||||
| -rw-r--r-- | arch/avr32/lib/clear_user.S | 76 | ||||
| -rw-r--r-- | arch/avr32/lib/copy_user.S | 119 | ||||
| -rw-r--r-- | arch/avr32/lib/csum_partial.S | 47 | ||||
| -rw-r--r-- | arch/avr32/lib/csum_partial_copy_generic.S | 99 | ||||
| -rw-r--r-- | arch/avr32/lib/delay.c | 55 | ||||
| -rw-r--r-- | arch/avr32/lib/findbit.S | 154 | ||||
| -rw-r--r-- | arch/avr32/lib/io-readsl.S | 24 | ||||
| -rw-r--r-- | arch/avr32/lib/io-readsw.S | 43 | ||||
| -rw-r--r-- | arch/avr32/lib/io-writesl.S | 20 | ||||
| -rw-r--r-- | arch/avr32/lib/io-writesw.S | 38 | ||||
| -rw-r--r-- | arch/avr32/lib/libgcc.h | 33 | ||||
| -rw-r--r-- | arch/avr32/lib/longlong.h | 98 | ||||
| -rw-r--r-- | arch/avr32/lib/memcpy.S | 62 | ||||
| -rw-r--r-- | arch/avr32/lib/memset.S | 72 | ||||
| -rw-r--r-- | arch/avr32/lib/strncpy_from_user.S | 60 | ||||
| -rw-r--r-- | arch/avr32/lib/strnlen_user.S | 67 |
20 files changed, 1170 insertions, 0 deletions
diff --git a/arch/avr32/lib/Makefile b/arch/avr32/lib/Makefile new file mode 100644 index 000000000000..09ac43e40522 --- /dev/null +++ b/arch/avr32/lib/Makefile | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | # | ||
| 2 | # Makefile for AVR32-specific library files | ||
| 3 | # | ||
| 4 | |||
| 5 | lib-y := copy_user.o clear_user.o | ||
| 6 | lib-y += strncpy_from_user.o strnlen_user.o | ||
| 7 | lib-y += delay.o memset.o memcpy.o findbit.o | ||
| 8 | lib-y += csum_partial.o csum_partial_copy_generic.o | ||
| 9 | lib-y += io-readsw.o io-readsl.o io-writesw.o io-writesl.o | ||
| 10 | lib-y += __avr32_lsl64.o __avr32_lsr64.o __avr32_asr64.o | ||
diff --git a/arch/avr32/lib/__avr32_asr64.S b/arch/avr32/lib/__avr32_asr64.S new file mode 100644 index 000000000000..368b6bca4c76 --- /dev/null +++ b/arch/avr32/lib/__avr32_asr64.S | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2005-2006 Atmel Corporation | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | * DWtype __avr32_asr64(DWtype u, word_type b) | ||
| 11 | */ | ||
| 12 | .text | ||
| 13 | .global __avr32_asr64 | ||
| 14 | .type __avr32_asr64,@function | ||
| 15 | __avr32_asr64: | ||
| 16 | cp.w r12, 0 | ||
| 17 | reteq r12 | ||
| 18 | |||
| 19 | rsub r9, r12, 32 | ||
| 20 | brle 1f | ||
| 21 | |||
| 22 | lsl r8, r11, r9 | ||
| 23 | lsr r10, r10, r12 | ||
| 24 | asr r11, r11, r12 | ||
| 25 | or r10, r8 | ||
| 26 | retal r12 | ||
| 27 | |||
| 28 | 1: neg r9 | ||
| 29 | asr r10, r11, r9 | ||
| 30 | asr r11, 31 | ||
| 31 | retal r12 | ||
diff --git a/arch/avr32/lib/__avr32_lsl64.S b/arch/avr32/lib/__avr32_lsl64.S new file mode 100644 index 000000000000..f1dbc2b36257 --- /dev/null +++ b/arch/avr32/lib/__avr32_lsl64.S | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2005-2006 Atmel Corporation | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | * DWtype __avr32_lsl64(DWtype u, word_type b) | ||
| 11 | */ | ||
| 12 | .text | ||
| 13 | .global __avr32_lsl64 | ||
| 14 | .type __avr32_lsl64,@function | ||
| 15 | __avr32_lsl64: | ||
| 16 | cp.w r12, 0 | ||
| 17 | reteq r12 | ||
| 18 | |||
| 19 | rsub r9, r12, 32 | ||
| 20 | brle 1f | ||
| 21 | |||
| 22 | lsr r8, r10, r9 | ||
| 23 | lsl r10, r10, r12 | ||
| 24 | lsl r11, r11, r12 | ||
| 25 | or r11, r8 | ||
| 26 | retal r12 | ||
| 27 | |||
| 28 | 1: neg r9 | ||
| 29 | lsl r11, r10, r9 | ||
| 30 | mov r10, 0 | ||
| 31 | retal r12 | ||
diff --git a/arch/avr32/lib/__avr32_lsr64.S b/arch/avr32/lib/__avr32_lsr64.S new file mode 100644 index 000000000000..e65bb7f0d24c --- /dev/null +++ b/arch/avr32/lib/__avr32_lsr64.S | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2005-2006 Atmel Corporation | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | * DWtype __avr32_lsr64(DWtype u, word_type b) | ||
| 11 | */ | ||
| 12 | .text | ||
| 13 | .global __avr32_lsr64 | ||
| 14 | .type __avr32_lsr64,@function | ||
| 15 | __avr32_lsr64: | ||
| 16 | cp.w r12, 0 | ||
| 17 | reteq r12 | ||
| 18 | |||
| 19 | rsub r9, r12, 32 | ||
| 20 | brle 1f | ||
| 21 | |||
| 22 | lsl r8, r11, r9 | ||
| 23 | lsr r11, r11, r12 | ||
| 24 | lsr r10, r10, r12 | ||
| 25 | or r10, r8 | ||
| 26 | retal r12 | ||
| 27 | |||
| 28 | 1: neg r9 | ||
| 29 | lsr r10, r11, r9 | ||
| 30 | mov r11, 0 | ||
| 31 | retal r12 | ||
diff --git a/arch/avr32/lib/clear_user.S b/arch/avr32/lib/clear_user.S new file mode 100644 index 000000000000..d8991b6f8eb7 --- /dev/null +++ b/arch/avr32/lib/clear_user.S | |||
| @@ -0,0 +1,76 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2004-2006 Atmel Corporation | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | */ | ||
| 8 | #include <asm/page.h> | ||
| 9 | #include <asm/thread_info.h> | ||
| 10 | #include <asm/asm.h> | ||
| 11 | |||
| 12 | .text | ||
| 13 | .align 1 | ||
| 14 | .global clear_user | ||
| 15 | .type clear_user, "function" | ||
| 16 | clear_user: | ||
| 17 | branch_if_kernel r8, __clear_user | ||
| 18 | ret_if_privileged r8, r12, r11, r11 | ||
| 19 | |||
| 20 | .global __clear_user | ||
| 21 | .type __clear_user, "function" | ||
| 22 | __clear_user: | ||
| 23 | mov r9, r12 | ||
| 24 | mov r8, 0 | ||
| 25 | andl r9, 3, COH | ||
| 26 | brne 5f | ||
| 27 | |||
| 28 | 1: sub r11, 4 | ||
| 29 | brlt 2f | ||
| 30 | |||
| 31 | 10: st.w r12++, r8 | ||
| 32 | sub r11, 4 | ||
| 33 | brge 10b | ||
| 34 | |||
| 35 | 2: sub r11, -4 | ||
| 36 | reteq 0 | ||
| 37 | |||
| 38 | /* Unaligned count or address */ | ||
| 39 | bld r11, 1 | ||
| 40 | brcc 12f | ||
| 41 | 11: st.h r12++, r8 | ||
| 42 | sub r11, 2 | ||
| 43 | reteq 0 | ||
| 44 | 12: st.b r12++, r8 | ||
| 45 | retal 0 | ||
| 46 | |||
| 47 | /* Unaligned address */ | ||
| 48 | 5: cp.w r11, 4 | ||
| 49 | brlt 2b | ||
| 50 | |||
| 51 | lsl r9, 2 | ||
| 52 | add pc, pc, r9 | ||
| 53 | 13: st.b r12++, r8 | ||
| 54 | sub r11, 1 | ||
| 55 | 14: st.b r12++, r8 | ||
| 56 | sub r11, 1 | ||
| 57 | 15: st.b r12++, r8 | ||
| 58 | sub r11, 1 | ||
| 59 | rjmp 1b | ||
| 60 | |||
| 61 | .size clear_user, . - clear_user | ||
| 62 | .size __clear_user, . - __clear_user | ||
| 63 | |||
| 64 | .section .fixup, "ax" | ||
| 65 | .align 1 | ||
| 66 | 18: sub r11, -4 | ||
| 67 | 19: retal r11 | ||
| 68 | |||
| 69 | .section __ex_table, "a" | ||
| 70 | .align 2 | ||
| 71 | .long 10b, 18b | ||
| 72 | .long 11b, 19b | ||
| 73 | .long 12b, 19b | ||
| 74 | .long 13b, 19b | ||
| 75 | .long 14b, 19b | ||
| 76 | .long 15b, 19b | ||
diff --git a/arch/avr32/lib/copy_user.S b/arch/avr32/lib/copy_user.S new file mode 100644 index 000000000000..ea59c04b07de --- /dev/null +++ b/arch/avr32/lib/copy_user.S | |||
| @@ -0,0 +1,119 @@ | |||
| 1 | /* | ||
| 2 | * Copy to/from userspace with optional address space checking. | ||
| 3 | * | ||
| 4 | * Copyright 2004-2006 Atmel Corporation | ||
| 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 | #include <asm/page.h> | ||
| 11 | #include <asm/thread_info.h> | ||
| 12 | #include <asm/asm.h> | ||
| 13 | |||
| 14 | /* | ||
| 15 | * __kernel_size_t | ||
| 16 | * __copy_user(void *to, const void *from, __kernel_size_t n) | ||
| 17 | * | ||
| 18 | * Returns the number of bytes not copied. Might be off by | ||
| 19 | * max 3 bytes if we get a fault in the main loop. | ||
| 20 | * | ||
| 21 | * The address-space checking functions simply fall through to | ||
| 22 | * the non-checking version. | ||
| 23 | */ | ||
| 24 | .text | ||
| 25 | .align 1 | ||
| 26 | .global copy_from_user | ||
| 27 | .type copy_from_user, @function | ||
| 28 | copy_from_user: | ||
| 29 | branch_if_kernel r8, __copy_user | ||
| 30 | ret_if_privileged r8, r11, r10, r10 | ||
| 31 | rjmp __copy_user | ||
| 32 | .size copy_from_user, . - copy_from_user | ||
| 33 | |||
| 34 | .global copy_to_user | ||
| 35 | .type copy_to_user, @function | ||
| 36 | copy_to_user: | ||
| 37 | branch_if_kernel r8, __copy_user | ||
| 38 | ret_if_privileged r8, r12, r10, r10 | ||
| 39 | .size copy_to_user, . - copy_to_user | ||
| 40 | |||
| 41 | .global __copy_user | ||
| 42 | .type __copy_user, @function | ||
| 43 | __copy_user: | ||
| 44 | mov r9, r11 | ||
| 45 | andl r9, 3, COH | ||
| 46 | brne 6f | ||
| 47 | |||
| 48 | /* At this point, from is word-aligned */ | ||
| 49 | 1: sub r10, 4 | ||
| 50 | brlt 3f | ||
| 51 | |||
| 52 | 2: | ||
| 53 | 10: ld.w r8, r11++ | ||
| 54 | 11: st.w r12++, r8 | ||
| 55 | sub r10, 4 | ||
| 56 | brge 2b | ||
| 57 | |||
| 58 | 3: sub r10, -4 | ||
| 59 | reteq 0 | ||
| 60 | |||
| 61 | /* | ||
| 62 | * Handle unaligned count. Need to be careful with r10 here so | ||
| 63 | * that we return the correct value even if we get a fault | ||
| 64 | */ | ||
| 65 | 4: | ||
| 66 | 20: ld.ub r8, r11++ | ||
| 67 | 21: st.b r12++, r8 | ||
| 68 | sub r10, 1 | ||
| 69 | reteq 0 | ||
| 70 | 22: ld.ub r8, r11++ | ||
| 71 | 23: st.b r12++, r8 | ||
| 72 | sub r10, 1 | ||
| 73 | reteq 0 | ||
| 74 | 24: ld.ub r8, r11++ | ||
| 75 | 25: st.b r12++, r8 | ||
| 76 | retal 0 | ||
| 77 | |||
| 78 | /* Handle unaligned from-pointer */ | ||
| 79 | 6: cp.w r10, 4 | ||
| 80 | brlt 4b | ||
| 81 | rsub r9, r9, 4 | ||
| 82 | |||
| 83 | 30: ld.ub r8, r11++ | ||
| 84 | 31: st.b r12++, r8 | ||
| 85 | sub r10, 1 | ||
| 86 | sub r9, 1 | ||
| 87 | breq 1b | ||
| 88 | 32: ld.ub r8, r11++ | ||
| 89 | 33: st.b r12++, r8 | ||
| 90 | sub r10, 1 | ||
| 91 | sub r9, 1 | ||
| 92 | breq 1b | ||
| 93 | 34: ld.ub r8, r11++ | ||
| 94 | 35: st.b r12++, r8 | ||
| 95 | sub r10, 1 | ||
| 96 | rjmp 1b | ||
| 97 | .size __copy_user, . - __copy_user | ||
| 98 | |||
| 99 | .section .fixup,"ax" | ||
| 100 | .align 1 | ||
| 101 | 19: sub r10, -4 | ||
| 102 | 29: retal r10 | ||
| 103 | |||
| 104 | .section __ex_table,"a" | ||
| 105 | .align 2 | ||
| 106 | .long 10b, 19b | ||
| 107 | .long 11b, 19b | ||
| 108 | .long 20b, 29b | ||
| 109 | .long 21b, 29b | ||
| 110 | .long 22b, 29b | ||
| 111 | .long 23b, 29b | ||
| 112 | .long 24b, 29b | ||
| 113 | .long 25b, 29b | ||
| 114 | .long 30b, 29b | ||
| 115 | .long 31b, 29b | ||
| 116 | .long 32b, 29b | ||
| 117 | .long 33b, 29b | ||
| 118 | .long 34b, 29b | ||
| 119 | .long 35b, 29b | ||
diff --git a/arch/avr32/lib/csum_partial.S b/arch/avr32/lib/csum_partial.S new file mode 100644 index 000000000000..6a262b528eb7 --- /dev/null +++ b/arch/avr32/lib/csum_partial.S | |||
| @@ -0,0 +1,47 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2004-2006 Atmel Corporation | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | * unsigned int csum_partial(const unsigned char *buff, | ||
| 11 | * int len, unsigned int sum) | ||
| 12 | */ | ||
| 13 | .text | ||
| 14 | .global csum_partial | ||
| 15 | .type csum_partial,"function" | ||
| 16 | .align 1 | ||
| 17 | csum_partial: | ||
| 18 | /* checksum complete words, aligned or not */ | ||
| 19 | 3: sub r11, 4 | ||
| 20 | brlt 5f | ||
| 21 | 4: ld.w r9, r12++ | ||
| 22 | add r10, r9 | ||
| 23 | acr r10 | ||
| 24 | sub r11, 4 | ||
| 25 | brge 4b | ||
| 26 | |||
| 27 | /* return if we had a whole number of words */ | ||
| 28 | 5: sub r11, -4 | ||
| 29 | reteq r10 | ||
| 30 | |||
| 31 | /* checksum any remaining bytes at the end */ | ||
| 32 | mov r9, 0 | ||
| 33 | mov r8, 0 | ||
| 34 | cp r11, 2 | ||
| 35 | brlt 6f | ||
| 36 | ld.uh r9, r12++ | ||
| 37 | sub r11, 2 | ||
| 38 | breq 7f | ||
| 39 | lsl r9, 16 | ||
| 40 | 6: ld.ub r8, r12++ | ||
| 41 | lsl r8, 8 | ||
| 42 | 7: or r9, r8 | ||
| 43 | add r10, r9 | ||
| 44 | acr r10 | ||
| 45 | |||
| 46 | retal r10 | ||
| 47 | .size csum_partial, . - csum_partial | ||
diff --git a/arch/avr32/lib/csum_partial_copy_generic.S b/arch/avr32/lib/csum_partial_copy_generic.S new file mode 100644 index 000000000000..a3a0f9b8929c --- /dev/null +++ b/arch/avr32/lib/csum_partial_copy_generic.S | |||
| @@ -0,0 +1,99 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2004-2006 Atmel Corporation | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | */ | ||
| 8 | #include <asm/errno.h> | ||
| 9 | #include <asm/asm.h> | ||
| 10 | |||
| 11 | /* | ||
| 12 | * unsigned int csum_partial_copy_generic(const char *src, char *dst, int len | ||
| 13 | * int sum, int *src_err_ptr, | ||
| 14 | * int *dst_err_ptr) | ||
| 15 | * | ||
| 16 | * Copy src to dst while checksumming, otherwise like csum_partial. | ||
| 17 | */ | ||
| 18 | |||
| 19 | .macro ld_src size, reg, ptr | ||
| 20 | 9999: ld.\size \reg, \ptr | ||
| 21 | .section __ex_table, "a" | ||
| 22 | .long 9999b, fixup_ld_src | ||
| 23 | .previous | ||
| 24 | .endm | ||
| 25 | |||
| 26 | .macro st_dst size, ptr, reg | ||
| 27 | 9999: st.\size \ptr, \reg | ||
| 28 | .section __ex_table, "a" | ||
| 29 | .long 9999b, fixup_st_dst | ||
| 30 | .previous | ||
| 31 | .endm | ||
| 32 | |||
| 33 | .text | ||
| 34 | .global csum_partial_copy_generic | ||
| 35 | .type csum_partial_copy_generic,"function" | ||
| 36 | .align 1 | ||
| 37 | csum_partial_copy_generic: | ||
| 38 | pushm r4-r7,lr | ||
| 39 | |||
| 40 | /* The inner loop */ | ||
| 41 | 1: sub r10, 4 | ||
| 42 | brlt 5f | ||
| 43 | 2: ld_src w, r5, r12++ | ||
| 44 | st_dst w, r11++, r5 | ||
| 45 | add r9, r5 | ||
| 46 | acr r9 | ||
| 47 | sub r10, 4 | ||
| 48 | brge 2b | ||
| 49 | |||
| 50 | /* return if we had a whole number of words */ | ||
| 51 | 5: sub r10, -4 | ||
| 52 | brne 7f | ||
| 53 | |||
| 54 | 6: mov r12, r9 | ||
| 55 | popm r4-r7,pc | ||
| 56 | |||
| 57 | /* handle additional bytes at the tail */ | ||
| 58 | 7: mov r5, 0 | ||
| 59 | mov r4, 32 | ||
| 60 | 8: ld_src ub, r6, r12++ | ||
| 61 | st_dst b, r11++, r6 | ||
| 62 | lsl r5, 8 | ||
| 63 | sub r4, 8 | ||
| 64 | bfins r5, r6, 0, 8 | ||
| 65 | sub r10, 1 | ||
| 66 | brne 8b | ||
| 67 | |||
| 68 | lsl r5, r5, r4 | ||
| 69 | add r9, r5 | ||
| 70 | acr r9 | ||
| 71 | rjmp 6b | ||
| 72 | |||
| 73 | /* Exception handler */ | ||
| 74 | .section .fixup,"ax" | ||
| 75 | .align 1 | ||
| 76 | fixup_ld_src: | ||
| 77 | mov r9, -EFAULT | ||
| 78 | cp.w r8, 0 | ||
| 79 | breq 1f | ||
| 80 | st.w r8[0], r9 | ||
| 81 | |||
| 82 | 1: /* | ||
| 83 | * TODO: zero the complete destination - computing the rest | ||
| 84 | * is too much work | ||
| 85 | */ | ||
| 86 | |||
| 87 | mov r9, 0 | ||
| 88 | rjmp 6b | ||
| 89 | |||
| 90 | fixup_st_dst: | ||
| 91 | mov r9, -EFAULT | ||
| 92 | lddsp r8, sp[20] | ||
| 93 | cp.w r8, 0 | ||
| 94 | breq 1f | ||
| 95 | st.w r8[0], r9 | ||
| 96 | 1: mov r9, 0 | ||
| 97 | rjmp 6b | ||
| 98 | |||
| 99 | .previous | ||
diff --git a/arch/avr32/lib/delay.c b/arch/avr32/lib/delay.c new file mode 100644 index 000000000000..462c8307b680 --- /dev/null +++ b/arch/avr32/lib/delay.c | |||
| @@ -0,0 +1,55 @@ | |||
| 1 | /* | ||
| 2 | * Precise Delay Loops for avr32 | ||
| 3 | * | ||
| 4 | * Copyright (C) 1993 Linus Torvalds | ||
| 5 | * Copyright (C) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz> | ||
| 6 | * Copyright (C) 2005-2006 Atmel Corporation | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/delay.h> | ||
| 14 | #include <linux/module.h> | ||
| 15 | #include <linux/types.h> | ||
| 16 | |||
| 17 | #include <asm/delay.h> | ||
| 18 | #include <asm/processor.h> | ||
| 19 | #include <asm/sysreg.h> | ||
| 20 | |||
| 21 | int read_current_timer(unsigned long *timer_value) | ||
| 22 | { | ||
| 23 | *timer_value = sysreg_read(COUNT); | ||
| 24 | return 0; | ||
| 25 | } | ||
| 26 | |||
| 27 | void __delay(unsigned long loops) | ||
| 28 | { | ||
| 29 | unsigned bclock, now; | ||
| 30 | |||
| 31 | bclock = sysreg_read(COUNT); | ||
| 32 | do { | ||
| 33 | now = sysreg_read(COUNT); | ||
| 34 | } while ((now - bclock) < loops); | ||
| 35 | } | ||
| 36 | |||
| 37 | inline void __const_udelay(unsigned long xloops) | ||
| 38 | { | ||
| 39 | unsigned long long loops; | ||
| 40 | |||
| 41 | asm("mulu.d %0, %1, %2" | ||
| 42 | : "=r"(loops) | ||
| 43 | : "r"(current_cpu_data.loops_per_jiffy * HZ), "r"(xloops)); | ||
| 44 | __delay(loops >> 32); | ||
| 45 | } | ||
| 46 | |||
| 47 | void __udelay(unsigned long usecs) | ||
| 48 | { | ||
| 49 | __const_udelay(usecs * 0x000010c7); /* 2**32 / 1000000 (rounded up) */ | ||
| 50 | } | ||
| 51 | |||
| 52 | void __ndelay(unsigned long nsecs) | ||
| 53 | { | ||
| 54 | __const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */ | ||
| 55 | } | ||
diff --git a/arch/avr32/lib/findbit.S b/arch/avr32/lib/findbit.S new file mode 100644 index 000000000000..2b4856f4bf7c --- /dev/null +++ b/arch/avr32/lib/findbit.S | |||
| @@ -0,0 +1,154 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2006 Atmel Corporation | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | */ | ||
| 8 | #include <linux/linkage.h> | ||
| 9 | |||
| 10 | .text | ||
| 11 | /* | ||
| 12 | * unsigned long find_first_zero_bit(const unsigned long *addr, | ||
| 13 | * unsigned long size) | ||
| 14 | */ | ||
| 15 | ENTRY(find_first_zero_bit) | ||
| 16 | cp.w r11, 0 | ||
| 17 | reteq r11 | ||
| 18 | mov r9, r11 | ||
| 19 | 1: ld.w r8, r12[0] | ||
| 20 | com r8 | ||
| 21 | brne .L_found | ||
| 22 | sub r12, -4 | ||
| 23 | sub r9, 32 | ||
| 24 | brgt 1b | ||
| 25 | retal r11 | ||
| 26 | |||
| 27 | /* | ||
| 28 | * unsigned long find_next_zero_bit(const unsigned long *addr, | ||
| 29 | * unsigned long size, | ||
| 30 | * unsigned long offset) | ||
| 31 | */ | ||
| 32 | ENTRY(find_next_zero_bit) | ||
| 33 | lsr r8, r10, 5 | ||
| 34 | sub r9, r11, r10 | ||
| 35 | retle r11 | ||
| 36 | |||
| 37 | lsl r8, 2 | ||
| 38 | add r12, r8 | ||
| 39 | andl r10, 31, COH | ||
| 40 | breq 1f | ||
| 41 | |||
| 42 | /* offset is not word-aligned. Handle the first (32 - r10) bits */ | ||
| 43 | ld.w r8, r12[0] | ||
| 44 | com r8 | ||
| 45 | sub r12, -4 | ||
| 46 | lsr r8, r8, r10 | ||
| 47 | brne .L_found | ||
| 48 | |||
| 49 | /* r9 = r9 - (32 - r10) = r9 + r10 - 32 */ | ||
| 50 | add r9, r10 | ||
| 51 | sub r9, 32 | ||
| 52 | retle r11 | ||
| 53 | |||
| 54 | /* Main loop. offset must be word-aligned */ | ||
| 55 | 1: ld.w r8, r12[0] | ||
| 56 | com r8 | ||
| 57 | brne .L_found | ||
| 58 | sub r12, -4 | ||
| 59 | sub r9, 32 | ||
| 60 | brgt 1b | ||
| 61 | retal r11 | ||
| 62 | |||
| 63 | /* Common return path for when a bit is actually found. */ | ||
| 64 | .L_found: | ||
| 65 | brev r8 | ||
| 66 | clz r10, r8 | ||
| 67 | rsub r9, r11 | ||
| 68 | add r10, r9 | ||
| 69 | |||
| 70 | /* XXX: If we don't have to return exactly "size" when the bit | ||
| 71 | is not found, we may drop this "min" thing */ | ||
| 72 | min r12, r11, r10 | ||
| 73 | retal r12 | ||
| 74 | |||
| 75 | /* | ||
| 76 | * unsigned long find_first_bit(const unsigned long *addr, | ||
| 77 | * unsigned long size) | ||
| 78 | */ | ||
| 79 | ENTRY(find_first_bit) | ||
| 80 | cp.w r11, 0 | ||
| 81 | reteq r11 | ||
| 82 | mov r9, r11 | ||
| 83 | 1: ld.w r8, r12[0] | ||
| 84 | cp.w r8, 0 | ||
| 85 | brne .L_found | ||
| 86 | sub r12, -4 | ||
| 87 | sub r9, 32 | ||
| 88 | brgt 1b | ||
| 89 | retal r11 | ||
| 90 | |||
| 91 | /* | ||
| 92 | * unsigned long find_next_bit(const unsigned long *addr, | ||
| 93 | * unsigned long size, | ||
| 94 | * unsigned long offset) | ||
| 95 | */ | ||
| 96 | ENTRY(find_next_bit) | ||
| 97 | lsr r8, r10, 5 | ||
| 98 | sub r9, r11, r10 | ||
| 99 | retle r11 | ||
| 100 | |||
| 101 | lsl r8, 2 | ||
| 102 | add r12, r8 | ||
| 103 | andl r10, 31, COH | ||
| 104 | breq 1f | ||
| 105 | |||
| 106 | /* offset is not word-aligned. Handle the first (32 - r10) bits */ | ||
| 107 | ld.w r8, r12[0] | ||
| 108 | sub r12, -4 | ||
| 109 | lsr r8, r8, r10 | ||
| 110 | brne .L_found | ||
| 111 | |||
| 112 | /* r9 = r9 - (32 - r10) = r9 + r10 - 32 */ | ||
| 113 | add r9, r10 | ||
| 114 | sub r9, 32 | ||
| 115 | retle r11 | ||
| 116 | |||
| 117 | /* Main loop. offset must be word-aligned */ | ||
| 118 | 1: ld.w r8, r12[0] | ||
| 119 | cp.w r8, 0 | ||
| 120 | brne .L_found | ||
| 121 | sub r12, -4 | ||
| 122 | sub r9, 32 | ||
| 123 | brgt 1b | ||
| 124 | retal r11 | ||
| 125 | |||
| 126 | ENTRY(generic_find_next_zero_le_bit) | ||
| 127 | lsr r8, r10, 5 | ||
| 128 | sub r9, r11, r10 | ||
| 129 | retle r11 | ||
| 130 | |||
| 131 | lsl r8, 2 | ||
| 132 | add r12, r8 | ||
| 133 | andl r10, 31, COH | ||
| 134 | breq 1f | ||
| 135 | |||
| 136 | /* offset is not word-aligned. Handle the first (32 - r10) bits */ | ||
| 137 | ldswp.w r8, r12[0] | ||
| 138 | sub r12, -4 | ||
| 139 | lsr r8, r8, r10 | ||
| 140 | brne .L_found | ||
| 141 | |||
| 142 | /* r9 = r9 - (32 - r10) = r9 + r10 - 32 */ | ||
| 143 | add r9, r10 | ||
| 144 | sub r9, 32 | ||
| 145 | retle r11 | ||
| 146 | |||
| 147 | /* Main loop. offset must be word-aligned */ | ||
| 148 | 1: ldswp.w r8, r12[0] | ||
| 149 | cp.w r8, 0 | ||
| 150 | brne .L_found | ||
| 151 | sub r12, -4 | ||
| 152 | sub r9, 32 | ||
| 153 | brgt 1b | ||
| 154 | retal r11 | ||
diff --git a/arch/avr32/lib/io-readsl.S b/arch/avr32/lib/io-readsl.S new file mode 100644 index 000000000000..b103511ed6c4 --- /dev/null +++ b/arch/avr32/lib/io-readsl.S | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2004-2006 Atmel Corporation | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | */ | ||
| 8 | |||
| 9 | .global __raw_readsl | ||
| 10 | .type __raw_readsl,@function | ||
| 11 | __raw_readsl: | ||
| 12 | cp.w r10, 0 | ||
| 13 | reteq r12 | ||
| 14 | |||
| 15 | /* | ||
| 16 | * If r11 isn't properly aligned, we might get an exception on | ||
| 17 | * some implementations. But there's not much we can do about it. | ||
| 18 | */ | ||
| 19 | 1: ld.w r8, r12[0] | ||
| 20 | sub r10, 1 | ||
| 21 | st.w r11++, r8 | ||
| 22 | brne 1b | ||
| 23 | |||
| 24 | retal r12 | ||
diff --git a/arch/avr32/lib/io-readsw.S b/arch/avr32/lib/io-readsw.S new file mode 100644 index 000000000000..456be9909027 --- /dev/null +++ b/arch/avr32/lib/io-readsw.S | |||
| @@ -0,0 +1,43 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2004-2006 Atmel Corporation | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | */ | ||
| 8 | |||
| 9 | .Lnot_word_aligned: | ||
| 10 | /* | ||
| 11 | * Bad alignment will cause a hardware exception, which is as | ||
| 12 | * good as anything. No need for us to check for proper alignment. | ||
| 13 | */ | ||
| 14 | ld.uh r8, r12[0] | ||
| 15 | sub r10, 1 | ||
| 16 | st.h r11++, r8 | ||
| 17 | |||
| 18 | /* fall through */ | ||
| 19 | |||
| 20 | .global __raw_readsw | ||
| 21 | .type __raw_readsw,@function | ||
| 22 | __raw_readsw: | ||
| 23 | cp.w r10, 0 | ||
| 24 | reteq r12 | ||
| 25 | mov r9, 3 | ||
| 26 | tst r11, r9 | ||
| 27 | brne .Lnot_word_aligned | ||
| 28 | |||
| 29 | sub r10, 2 | ||
| 30 | brlt 2f | ||
| 31 | |||
| 32 | 1: ldins.h r8:t, r12[0] | ||
| 33 | ldins.h r8:b, r12[0] | ||
| 34 | st.w r11++, r8 | ||
| 35 | sub r10, 2 | ||
| 36 | brge 1b | ||
| 37 | |||
| 38 | 2: sub r10, -2 | ||
| 39 | reteq r12 | ||
| 40 | |||
| 41 | ld.uh r8, r12[0] | ||
| 42 | st.h r11++, r8 | ||
| 43 | retal r12 | ||
diff --git a/arch/avr32/lib/io-writesl.S b/arch/avr32/lib/io-writesl.S new file mode 100644 index 000000000000..22138b3a16e5 --- /dev/null +++ b/arch/avr32/lib/io-writesl.S | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2004-2006 Atmel Corporation | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | */ | ||
| 8 | |||
| 9 | .global __raw_writesl | ||
| 10 | .type __raw_writesl,@function | ||
| 11 | __raw_writesl: | ||
| 12 | cp.w r10, 0 | ||
| 13 | reteq r12 | ||
| 14 | |||
| 15 | 1: ld.w r8, r11++ | ||
| 16 | sub r10, 1 | ||
| 17 | st.w r12[0], r8 | ||
| 18 | brne 1b | ||
| 19 | |||
| 20 | retal r12 | ||
diff --git a/arch/avr32/lib/io-writesw.S b/arch/avr32/lib/io-writesw.S new file mode 100644 index 000000000000..8c4a53f1c52a --- /dev/null +++ b/arch/avr32/lib/io-writesw.S | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2004-2006 Atmel Corporation | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | */ | ||
| 8 | |||
| 9 | .Lnot_word_aligned: | ||
| 10 | ld.uh r8, r11++ | ||
| 11 | sub r10, 1 | ||
| 12 | st.h r12[0], r8 | ||
| 13 | |||
| 14 | .global __raw_writesw | ||
| 15 | .type __raw_writesw,@function | ||
| 16 | __raw_writesw: | ||
| 17 | cp.w r10, 0 | ||
| 18 | mov r9, 3 | ||
| 19 | reteq r12 | ||
| 20 | tst r11, r9 | ||
| 21 | brne .Lnot_word_aligned | ||
| 22 | |||
| 23 | sub r10, 2 | ||
| 24 | brlt 2f | ||
| 25 | |||
| 26 | 1: ld.w r8, r11++ | ||
| 27 | bfextu r9, r8, 16, 16 | ||
| 28 | st.h r12[0], r9 | ||
| 29 | st.h r12[0], r8 | ||
| 30 | sub r10, 2 | ||
| 31 | brge 1b | ||
| 32 | |||
| 33 | 2: sub r10, -2 | ||
| 34 | reteq r12 | ||
| 35 | |||
| 36 | ld.uh r8, r11++ | ||
| 37 | st.h r12[0], r8 | ||
| 38 | retal r12 | ||
diff --git a/arch/avr32/lib/libgcc.h b/arch/avr32/lib/libgcc.h new file mode 100644 index 000000000000..5a091b5e3618 --- /dev/null +++ b/arch/avr32/lib/libgcc.h | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | /* Definitions for various functions 'borrowed' from gcc-3.4.3 */ | ||
| 2 | |||
| 3 | #define BITS_PER_UNIT 8 | ||
| 4 | |||
| 5 | typedef int QItype __attribute__ ((mode (QI))); | ||
| 6 | typedef unsigned int UQItype __attribute__ ((mode (QI))); | ||
| 7 | typedef int HItype __attribute__ ((mode (HI))); | ||
| 8 | typedef unsigned int UHItype __attribute__ ((mode (HI))); | ||
| 9 | typedef int SItype __attribute__ ((mode (SI))); | ||
| 10 | typedef unsigned int USItype __attribute__ ((mode (SI))); | ||
| 11 | typedef int DItype __attribute__ ((mode (DI))); | ||
| 12 | typedef unsigned int UDItype __attribute__ ((mode (DI))); | ||
| 13 | typedef float SFtype __attribute__ ((mode (SF))); | ||
| 14 | typedef float DFtype __attribute__ ((mode (DF))); | ||
| 15 | typedef int word_type __attribute__ ((mode (__word__))); | ||
| 16 | |||
| 17 | #define W_TYPE_SIZE (4 * BITS_PER_UNIT) | ||
| 18 | #define Wtype SItype | ||
| 19 | #define UWtype USItype | ||
| 20 | #define HWtype SItype | ||
| 21 | #define UHWtype USItype | ||
| 22 | #define DWtype DItype | ||
| 23 | #define UDWtype UDItype | ||
| 24 | #define __NW(a,b) __ ## a ## si ## b | ||
| 25 | #define __NDW(a,b) __ ## a ## di ## b | ||
| 26 | |||
| 27 | struct DWstruct {Wtype high, low;}; | ||
| 28 | |||
| 29 | typedef union | ||
| 30 | { | ||
| 31 | struct DWstruct s; | ||
| 32 | DWtype ll; | ||
| 33 | } DWunion; | ||
diff --git a/arch/avr32/lib/longlong.h b/arch/avr32/lib/longlong.h new file mode 100644 index 000000000000..cd5e369ac437 --- /dev/null +++ b/arch/avr32/lib/longlong.h | |||
| @@ -0,0 +1,98 @@ | |||
| 1 | /* longlong.h -- definitions for mixed size 32/64 bit arithmetic. | ||
| 2 | Copyright (C) 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000 | ||
| 3 | Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This definition file is free software; you can redistribute it | ||
| 6 | and/or modify it under the terms of the GNU General Public | ||
| 7 | License as published by the Free Software Foundation; either | ||
| 8 | version 2, or (at your option) any later version. | ||
| 9 | |||
| 10 | This definition file is distributed in the hope that it will be | ||
| 11 | useful, but WITHOUT ANY WARRANTY; without even the implied | ||
| 12 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
| 13 | See the GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program; if not, write to the Free Software | ||
| 17 | Foundation, Inc., 59 Temple Place - Suite 330, | ||
| 18 | Boston, MA 02111-1307, USA. */ | ||
| 19 | |||
| 20 | /* Borrowed from gcc-3.4.3 */ | ||
| 21 | |||
| 22 | #define __BITS4 (W_TYPE_SIZE / 4) | ||
| 23 | #define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2)) | ||
| 24 | #define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1)) | ||
| 25 | #define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2)) | ||
| 26 | |||
| 27 | #define count_leading_zeros(count, x) ((count) = __builtin_clz(x)) | ||
| 28 | |||
| 29 | #define __udiv_qrnnd_c(q, r, n1, n0, d) \ | ||
| 30 | do { \ | ||
| 31 | UWtype __d1, __d0, __q1, __q0; \ | ||
| 32 | UWtype __r1, __r0, __m; \ | ||
| 33 | __d1 = __ll_highpart (d); \ | ||
| 34 | __d0 = __ll_lowpart (d); \ | ||
| 35 | \ | ||
| 36 | __r1 = (n1) % __d1; \ | ||
| 37 | __q1 = (n1) / __d1; \ | ||
| 38 | __m = (UWtype) __q1 * __d0; \ | ||
| 39 | __r1 = __r1 * __ll_B | __ll_highpart (n0); \ | ||
| 40 | if (__r1 < __m) \ | ||
| 41 | { \ | ||
| 42 | __q1--, __r1 += (d); \ | ||
| 43 | if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\ | ||
| 44 | if (__r1 < __m) \ | ||
| 45 | __q1--, __r1 += (d); \ | ||
| 46 | } \ | ||
| 47 | __r1 -= __m; \ | ||
| 48 | \ | ||
| 49 | __r0 = __r1 % __d1; \ | ||
| 50 | __q0 = __r1 / __d1; \ | ||
| 51 | __m = (UWtype) __q0 * __d0; \ | ||
| 52 | __r0 = __r0 * __ll_B | __ll_lowpart (n0); \ | ||
| 53 | if (__r0 < __m) \ | ||
| 54 | { \ | ||
| 55 | __q0--, __r0 += (d); \ | ||
| 56 | if (__r0 >= (d)) \ | ||
| 57 | if (__r0 < __m) \ | ||
| 58 | __q0--, __r0 += (d); \ | ||
| 59 | } \ | ||
| 60 | __r0 -= __m; \ | ||
| 61 | \ | ||
| 62 | (q) = (UWtype) __q1 * __ll_B | __q0; \ | ||
| 63 | (r) = __r0; \ | ||
| 64 | } while (0) | ||
| 65 | |||
| 66 | #define udiv_qrnnd __udiv_qrnnd_c | ||
| 67 | |||
| 68 | #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ | ||
| 69 | do { \ | ||
| 70 | UWtype __x; \ | ||
| 71 | __x = (al) - (bl); \ | ||
| 72 | (sh) = (ah) - (bh) - (__x > (al)); \ | ||
| 73 | (sl) = __x; \ | ||
| 74 | } while (0) | ||
| 75 | |||
| 76 | #define umul_ppmm(w1, w0, u, v) \ | ||
| 77 | do { \ | ||
| 78 | UWtype __x0, __x1, __x2, __x3; \ | ||
| 79 | UHWtype __ul, __vl, __uh, __vh; \ | ||
| 80 | \ | ||
| 81 | __ul = __ll_lowpart (u); \ | ||
| 82 | __uh = __ll_highpart (u); \ | ||
| 83 | __vl = __ll_lowpart (v); \ | ||
| 84 | __vh = __ll_highpart (v); \ | ||
| 85 | \ | ||
| 86 | __x0 = (UWtype) __ul * __vl; \ | ||
| 87 | __x1 = (UWtype) __ul * __vh; \ | ||
| 88 | __x2 = (UWtype) __uh * __vl; \ | ||
| 89 | __x3 = (UWtype) __uh * __vh; \ | ||
| 90 | \ | ||
| 91 | __x1 += __ll_highpart (__x0);/* this can't give carry */ \ | ||
| 92 | __x1 += __x2; /* but this indeed can */ \ | ||
| 93 | if (__x1 < __x2) /* did we get it? */ \ | ||
| 94 | __x3 += __ll_B; /* yes, add it in the proper pos. */ \ | ||
| 95 | \ | ||
| 96 | (w1) = __x3 + __ll_highpart (__x1); \ | ||
| 97 | (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \ | ||
| 98 | } while (0) | ||
diff --git a/arch/avr32/lib/memcpy.S b/arch/avr32/lib/memcpy.S new file mode 100644 index 000000000000..0abb26142b64 --- /dev/null +++ b/arch/avr32/lib/memcpy.S | |||
| @@ -0,0 +1,62 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2004-2006 Atmel Corporation | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | * void *memcpy(void *to, const void *from, unsigned long n) | ||
| 11 | * | ||
| 12 | * This implementation does word-aligned loads in the main loop, | ||
| 13 | * possibly sacrificing alignment of stores. | ||
| 14 | * | ||
| 15 | * Hopefully, in most cases, both "to" and "from" will be | ||
| 16 | * word-aligned to begin with. | ||
| 17 | */ | ||
| 18 | .text | ||
| 19 | .global memcpy | ||
| 20 | .type memcpy, @function | ||
| 21 | memcpy: | ||
| 22 | mov r9, r11 | ||
| 23 | andl r9, 3, COH | ||
| 24 | brne 1f | ||
| 25 | |||
| 26 | /* At this point, "from" is word-aligned */ | ||
| 27 | 2: sub r10, 4 | ||
| 28 | mov r9, r12 | ||
| 29 | brlt 4f | ||
| 30 | |||
| 31 | 3: ld.w r8, r11++ | ||
| 32 | sub r10, 4 | ||
| 33 | st.w r12++, r8 | ||
| 34 | brge 3b | ||
| 35 | |||
| 36 | 4: neg r10 | ||
| 37 | reteq r9 | ||
| 38 | |||
| 39 | /* Handle unaligned count */ | ||
| 40 | lsl r10, 2 | ||
| 41 | add pc, pc, r10 | ||
| 42 | ld.ub r8, r11++ | ||
| 43 | st.b r12++, r8 | ||
| 44 | ld.ub r8, r11++ | ||
| 45 | st.b r12++, r8 | ||
| 46 | ld.ub r8, r11++ | ||
| 47 | st.b r12++, r8 | ||
| 48 | retal r9 | ||
| 49 | |||
| 50 | /* Handle unaligned "from" pointer */ | ||
| 51 | 1: sub r10, 4 | ||
| 52 | brlt 4b | ||
| 53 | add r10, r9 | ||
| 54 | lsl r9, 2 | ||
| 55 | add pc, pc, r9 | ||
| 56 | ld.ub r8, r11++ | ||
| 57 | st.b r12++, r8 | ||
| 58 | ld.ub r8, r11++ | ||
| 59 | st.b r12++, r8 | ||
| 60 | ld.ub r8, r11++ | ||
| 61 | st.b r12++, r8 | ||
| 62 | rjmp 2b | ||
diff --git a/arch/avr32/lib/memset.S b/arch/avr32/lib/memset.S new file mode 100644 index 000000000000..40da32c0480c --- /dev/null +++ b/arch/avr32/lib/memset.S | |||
| @@ -0,0 +1,72 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2004-2006 Atmel Corporation | ||
| 3 | * | ||
| 4 | * Based on linux/arch/arm/lib/memset.S | ||
| 5 | * Copyright (C) 1995-2000 Russell King | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License version 2 as | ||
| 9 | * published by the Free Software Foundation. | ||
| 10 | * | ||
| 11 | * ASM optimised string functions | ||
| 12 | */ | ||
| 13 | #include <asm/asm.h> | ||
| 14 | |||
| 15 | /* | ||
| 16 | * r12: void *b | ||
| 17 | * r11: int c | ||
| 18 | * r10: size_t len | ||
| 19 | * | ||
| 20 | * Returns b in r12 | ||
| 21 | */ | ||
| 22 | .text | ||
| 23 | .global memset | ||
| 24 | .type memset, @function | ||
| 25 | .align 5 | ||
| 26 | memset: | ||
| 27 | mov r9, r12 | ||
| 28 | mov r8, r12 | ||
| 29 | or r11, r11, r11 << 8 | ||
| 30 | andl r9, 3, COH | ||
| 31 | brne 1f | ||
| 32 | |||
| 33 | 2: or r11, r11, r11 << 16 | ||
| 34 | sub r10, 4 | ||
| 35 | brlt 5f | ||
| 36 | |||
| 37 | /* Let's do some real work */ | ||
| 38 | 4: st.w r8++, r11 | ||
| 39 | sub r10, 4 | ||
| 40 | brge 4b | ||
| 41 | |||
| 42 | /* | ||
| 43 | * When we get here, we've got less than 4 bytes to set. r10 | ||
| 44 | * might be negative. | ||
| 45 | */ | ||
| 46 | 5: sub r10, -4 | ||
| 47 | reteq r12 | ||
| 48 | |||
| 49 | /* Fastpath ends here, exactly 32 bytes from memset */ | ||
| 50 | |||
| 51 | /* Handle unaligned count or pointer */ | ||
| 52 | bld r10, 1 | ||
| 53 | brcc 6f | ||
| 54 | st.b r8++, r11 | ||
| 55 | st.b r8++, r11 | ||
| 56 | bld r10, 0 | ||
| 57 | retcc r12 | ||
| 58 | 6: st.b r8++, r11 | ||
| 59 | retal r12 | ||
| 60 | |||
| 61 | /* Handle unaligned pointer */ | ||
| 62 | 1: sub r10, 4 | ||
| 63 | brlt 5b | ||
| 64 | add r10, r9 | ||
| 65 | lsl r9, 1 | ||
| 66 | add pc, r9 | ||
| 67 | st.b r8++, r11 | ||
| 68 | st.b r8++, r11 | ||
| 69 | st.b r8++, r11 | ||
| 70 | rjmp 2b | ||
| 71 | |||
| 72 | .size memset, . - memset | ||
diff --git a/arch/avr32/lib/strncpy_from_user.S b/arch/avr32/lib/strncpy_from_user.S new file mode 100644 index 000000000000..72bd50599ec6 --- /dev/null +++ b/arch/avr32/lib/strncpy_from_user.S | |||
| @@ -0,0 +1,60 @@ | |||
| 1 | /* | ||
| 2 | * Copy to/from userspace with optional address space checking. | ||
| 3 | * | ||
| 4 | * Copyright 2004-2006 Atmel Corporation | ||
| 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 | #include <linux/errno.h> | ||
| 11 | |||
| 12 | #include <asm/page.h> | ||
| 13 | #include <asm/thread_info.h> | ||
| 14 | #include <asm/asm.h> | ||
| 15 | |||
| 16 | /* | ||
| 17 | * long strncpy_from_user(char *dst, const char *src, long count) | ||
| 18 | * | ||
| 19 | * On success, returns the length of the string, not including | ||
| 20 | * the terminating NUL. | ||
| 21 | * | ||
| 22 | * If the string is longer than count, returns count | ||
| 23 | * | ||
| 24 | * If userspace access fails, returns -EFAULT | ||
| 25 | */ | ||
| 26 | .text | ||
| 27 | .align 1 | ||
| 28 | .global strncpy_from_user | ||
| 29 | .type strncpy_from_user, "function" | ||
| 30 | strncpy_from_user: | ||
| 31 | mov r9, -EFAULT | ||
| 32 | branch_if_kernel r8, __strncpy_from_user | ||
| 33 | ret_if_privileged r8, r11, r10, r9 | ||
| 34 | |||
| 35 | .global __strncpy_from_user | ||
| 36 | .type __strncpy_from_user, "function" | ||
| 37 | __strncpy_from_user: | ||
| 38 | cp.w r10, 0 | ||
| 39 | reteq 0 | ||
| 40 | |||
| 41 | mov r9, r10 | ||
| 42 | |||
| 43 | 1: ld.ub r8, r11++ | ||
| 44 | st.b r12++, r8 | ||
| 45 | cp.w r8, 0 | ||
| 46 | breq 2f | ||
| 47 | sub r9, 1 | ||
| 48 | brne 1b | ||
| 49 | |||
| 50 | 2: sub r10, r9 | ||
| 51 | retal r10 | ||
| 52 | |||
| 53 | .section .fixup, "ax" | ||
| 54 | .align 1 | ||
| 55 | 3: mov r12, -EFAULT | ||
| 56 | retal r12 | ||
| 57 | |||
| 58 | .section __ex_table, "a" | ||
| 59 | .align 2 | ||
| 60 | .long 1b, 3b | ||
diff --git a/arch/avr32/lib/strnlen_user.S b/arch/avr32/lib/strnlen_user.S new file mode 100644 index 000000000000..65ce11afa66a --- /dev/null +++ b/arch/avr32/lib/strnlen_user.S | |||
| @@ -0,0 +1,67 @@ | |||
| 1 | /* | ||
| 2 | * Copy to/from userspace with optional address space checking. | ||
| 3 | * | ||
| 4 | * Copyright 2004-2006 Atmel Corporation | ||
| 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 | #include <asm/page.h> | ||
| 11 | #include <asm/thread_info.h> | ||
| 12 | #include <asm/processor.h> | ||
| 13 | #include <asm/asm.h> | ||
| 14 | |||
| 15 | .text | ||
| 16 | .align 1 | ||
| 17 | .global strnlen_user | ||
| 18 | .type strnlen_user, "function" | ||
| 19 | strnlen_user: | ||
| 20 | branch_if_kernel r8, __strnlen_user | ||
| 21 | sub r8, r11, 1 | ||
| 22 | add r8, r12 | ||
| 23 | retcs 0 | ||
| 24 | brmi adjust_length /* do a closer inspection */ | ||
| 25 | |||
| 26 | .global __strnlen_user | ||
| 27 | .type __strnlen_user, "function" | ||
| 28 | __strnlen_user: | ||
| 29 | mov r10, r12 | ||
| 30 | |||
| 31 | 10: ld.ub r8, r12++ | ||
| 32 | cp.w r8, 0 | ||
| 33 | breq 2f | ||
| 34 | sub r11, 1 | ||
| 35 | brne 10b | ||
| 36 | |||
| 37 | sub r12, -1 | ||
| 38 | 2: sub r12, r10 | ||
| 39 | retal r12 | ||
| 40 | |||
| 41 | |||
| 42 | .type adjust_length, "function" | ||
| 43 | adjust_length: | ||
| 44 | cp.w r12, 0 /* addr must always be < TASK_SIZE */ | ||
| 45 | retmi 0 | ||
| 46 | |||
| 47 | pushm lr | ||
| 48 | lddpc lr, _task_size | ||
| 49 | sub r11, lr, r12 | ||
| 50 | mov r9, r11 | ||
| 51 | rcall __strnlen_user | ||
| 52 | cp.w r12, r9 | ||
| 53 | brgt 1f | ||
| 54 | popm pc | ||
| 55 | 1: popm pc, r12=0 | ||
| 56 | |||
| 57 | .align 2 | ||
| 58 | _task_size: | ||
| 59 | .long TASK_SIZE | ||
| 60 | |||
| 61 | .section .fixup, "ax" | ||
| 62 | .align 1 | ||
| 63 | 19: retal 0 | ||
| 64 | |||
| 65 | .section __ex_table, "a" | ||
| 66 | .align 2 | ||
| 67 | .long 10b, 19b | ||
