Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.19 173 lines 4.3 kB view raw
1/* 2 * linux/arch/arm26/lib/uaccess-kernel.S 3 * 4 * Copyright (C) 1998 Russell King 5 * 6 * Note! Some code fragments found in here have a special calling 7 * convention - they are not APCS compliant! 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License version 2 as 11 * published by the Free Software Foundation. 12 */ 13#include <linux/linkage.h> 14#include <asm/assembler.h> 15 16 .text 17 18//FIXME - surely this can be done in C not asm, removing the problem of keeping C and asm in sync? (this is a struct uaccess_t) 19 20 .globl uaccess_kernel 21uaccess_kernel: 22 .word uaccess_kernel_put_byte 23 .word uaccess_kernel_get_byte 24 .word uaccess_kernel_put_half 25 .word uaccess_kernel_get_half 26 .word uaccess_kernel_put_word 27 .word uaccess_kernel_get_word 28 .word uaccess_kernel_put_dword 29 .word uaccess_kernel_copy 30 .word uaccess_kernel_copy 31 .word uaccess_kernel_clear 32 .word uaccess_kernel_strncpy 33 .word uaccess_kernel_strnlen 34 35@ In : r0 = x, r1 = addr, r2 = error 36@ Out: r2 = error 37uaccess_kernel_put_byte: 38 stmfd sp!, {lr} 39 strb r0, [r1] 40 ldmfd sp!, {pc}^ 41 42@ In : r0 = x, r1 = addr, r2 = error 43@ Out: r2 = error 44uaccess_kernel_put_half: 45 stmfd sp!, {lr} 46 strb r0, [r1] 47 mov r0, r0, lsr #8 48 strb r0, [r1, #1] 49 ldmfd sp!, {pc}^ 50 51@ In : r0 = x, r1 = addr, r2 = error 52@ Out: r2 = error 53uaccess_kernel_put_word: 54 stmfd sp!, {lr} 55 str r0, [r1] 56 ldmfd sp!, {pc}^ 57 58@ In : r0 = x, r1 = addr, r2 = error 59@ Out: r2 = error 60uaccess_kernel_put_dword: 61 stmfd sp!, {lr} 62 str r0, [r1], #4 63 str r0, [r1], #0 64 ldmfd sp!, {pc}^ 65 66@ In : r0 = addr, r1 = error 67@ Out: r0 = x, r1 = error 68uaccess_kernel_get_byte: 69 stmfd sp!, {lr} 70 ldrb r0, [r0] 71 ldmfd sp!, {pc}^ 72 73@ In : r0 = addr, r1 = error 74@ Out: r0 = x, r1 = error 75uaccess_kernel_get_half: 76 stmfd sp!, {lr} 77 ldr r0, [r0] 78 mov r0, r0, lsl #16 79 mov r0, r0, lsr #16 80 ldmfd sp!, {pc}^ 81 82@ In : r0 = addr, r1 = error 83@ Out: r0 = x, r1 = error 84uaccess_kernel_get_word: 85 stmfd sp!, {lr} 86 ldr r0, [r0] 87 ldmfd sp!, {pc}^ 88 89 90/* Prototype: int uaccess_kernel_copy(void *to, const char *from, size_t n) 91 * Purpose : copy a block to kernel memory from kernel memory 92 * Params : to - kernel memory 93 * : from - kernel memory 94 * : n - number of bytes to copy 95 * Returns : Number of bytes NOT copied. 96 */ 97uaccess_kernel_copy: 98 stmfd sp!, {lr} 99 bl memcpy 100 mov r0, #0 101 ldmfd sp!, {pc}^ 102 103/* Prototype: int uaccess_kernel_clear(void *addr, size_t sz) 104 * Purpose : clear some kernel memory 105 * Params : addr - kernel memory address to clear 106 * : sz - number of bytes to clear 107 * Returns : number of bytes NOT cleared 108 */ 109uaccess_kernel_clear: 110 stmfd sp!, {lr} 111 mov r2, #0 112 cmp r1, #4 113 blt 2f 114 ands ip, r0, #3 115 beq 1f 116 cmp ip, #1 117 strb r2, [r0], #1 118 strleb r2, [r0], #1 119 strltb r2, [r0], #1 120 rsb ip, ip, #4 121 sub r1, r1, ip @ 7 6 5 4 3 2 1 1221: subs r1, r1, #8 @ -1 -2 -3 -4 -5 -6 -7 123 bmi 2f 124 str r2, [r0], #4 125 str r2, [r0], #4 126 b 1b 1272: adds r1, r1, #4 @ 3 2 1 0 -1 -2 -3 128 strpl r2, [r0], #4 129 tst r1, #2 @ 1x 1x 0x 0x 1x 1x 0x 130 strneb r2, [r0], #1 131 strneb r2, [r0], #1 132 tst r1, #1 @ x1 x0 x1 x0 x1 x0 x1 133 strneb r2, [r0], #1 134 mov r0, #0 135 ldmfd sp!, {pc}^ 136 137/* Prototype: size_t uaccess_kernel_strncpy(char *dst, char *src, size_t len) 138 * Purpose : copy a string from kernel memory to kernel memory 139 * Params : dst - kernel memory destination 140 * : src - kernel memory source 141 * : len - maximum length of string 142 * Returns : number of characters copied 143 */ 144uaccess_kernel_strncpy: 145 stmfd sp!, {lr} 146 mov ip, r2 1471: subs r2, r2, #1 148 bmi 2f 149 ldrb r3, [r1], #1 150 strb r3, [r0], #1 151 teq r3, #0 152 bne 1b 1532: subs r0, ip, r2 154 ldmfd sp!, {pc}^ 155 156/* Prototype: int uaccess_kernel_strlen(char *str, long n) 157 * Purpose : get length of a string in kernel memory 158 * Params : str - address of string in kernel memory 159 * Returns : length of string *including terminator*, 160 * or zero on exception, or n + 1 if too long 161 */ 162uaccess_kernel_strnlen: 163 stmfd sp!, {lr} 164 mov r2, r0 1651: ldrb r1, [r0], #1 166 teq r1, #0 167 beq 2f 168 subs r1, r1, #1 169 bne 1b 170 add r0, r0, #1 1712: sub r0, r0, r2 172 ldmfd sp!, {pc}^ 173