1/* $NetBSD: copystr.S,v 1.10 2009/01/18 01:19:32 bjh21 Exp $ */ 2 3/* 4 * Copyright (c) 1995 Mark Brinicombe. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Mark Brinicombe. 18 * 4. The name of the company nor the name of the author may be used to 19 * endorse or promote products derived from this software without specific 20 * prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 26 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 27 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * copystr.S 35 * 36 * optimised and fault protected copystr functions 37 * 38 * Created : 16/05/95 39 */ 40 41#include "opt_multiprocessor.h" 42#include "opt_cpuoptions.h" 43 44#include "assym.h" 45#include <machine/asm.h> 46#include <machine/cpu.h> 47 48RCSID("$NetBSD: copystr.S,v 1.10 2009/01/18 01:19:32 bjh21 Exp $") 49 50#include <sys/errno.h> 51 52 .text 53 .align 0 54/* 55 * r0 - from 56 * r1 - to 57 * r2 - maxlens 58 * r3 - lencopied 59 * 60 * Copy string from r0 to r1 61 */ 62ENTRY(copystr) 63 stmfd sp!, {r4-r5} /* stack is 8 byte aligned */ 64 teq r2, #0x00000000 65 mov r5, #0x00000000 66 moveq r0, #ENAMETOOLONG 67 beq 2f 68 691: ldrb r4, [r0], #0x0001 70 add r5, r5, #0x00000001 71 teq r4, #0x00000000 72 strb r4, [r1], #0x0001 73 teqne r5, r2 74 bne 1b 75 76 teq r4, #0x00000000 77 moveq r0, #0x00000000 78 movne r0, #ENAMETOOLONG 79 802: teq r3, #0x00000000 81 strne r5, [r3] 82 83 ldmfd sp!, {r4-r5} /* stack is 8 byte aligned */ 84 RET 85 86#ifdef __PROG32 87#define SAVE_REGS stmfd sp!, {r4-r6} 88#define RESTORE_REGS ldmfd sp!, {r4-r6} 89#else 90/* Need to save R14_svc because it'll get trampled if we take a page fault. */ 91#define SAVE_REGS stmfd sp!, {r4-r6, r14} 92#define RESTORE_REGS ldmfd sp!, {r4-r6, r14} 93#endif 94 95/* 96 * r0 - user space address 97 * r1 - kernel space address 98 * r2 - maxlens 99 * r3 - lencopied 100 * 101 * Copy string from user space to kernel space 102 */ 103ENTRY(copyinstr) 104 SAVE_REGS 105 106 teq r2, #0x00000000 107 mov r6, #0x00000000 108 moveq r0, #ENAMETOOLONG 109 beq 2f 110 111 GET_CURPCB(r4) 112 113#ifdef DIAGNOSTIC 114 teq r4, #0x00000000 115 beq .Lcopystrpcbfault 116#endif 117 118 adr r5, .Lcopystrfault 119 str r5, [r4, #PCB_ONFAULT] 120 1211: ldrbt r5, [r0], #0x0001 122 add r6, r6, #0x00000001 123 teq r5, #0x00000000 124 strb r5, [r1], #0x0001 125 teqne r6, r2 126 bne 1b 127 128 mov r0, #0x00000000 129 str r0, [r4, #PCB_ONFAULT] 130 131 teq r5, #0x00000000 132 moveq r0, #0x00000000 133 movne r0, #ENAMETOOLONG 134 1352: teq r3, #0x00000000 136 strne r6, [r3] 137 138 RESTORE_REGS 139 RET 140 141/* 142 * r0 - kernel space address 143 * r1 - user space address 144 * r2 - maxlens 145 * r3 - lencopied 146 * 147 * Copy string from kernel space to user space 148 */ 149ENTRY(copyoutstr) 150 SAVE_REGS 151 152 teq r2, #0x00000000 153 mov r6, #0x00000000 154 moveq r0, #ENAMETOOLONG 155 beq 2f 156 157 GET_CURPCB(r4) 158 159#ifdef DIAGNOSTIC 160 teq r4, #0x00000000 161 beq .Lcopystrpcbfault 162#endif 163 164 adr r5, .Lcopystrfault 165 str r5, [r4, #PCB_ONFAULT] 166 1671: ldrb r5, [r0], #0x0001 168 add r6, r6, #0x00000001 169 teq r5, #0x00000000 170 strbt r5, [r1], #0x0001 171 teqne r6, r2 172 bne 1b 173 174 mov r0, #0x00000000 175 str r0, [r4, #PCB_ONFAULT] 176 177 teq r5, #0x00000000 178 moveq r0, #0x00000000 179 movne r0, #ENAMETOOLONG 180 1812: teq r3, #0x00000000 182 strne r6, [r3] 183 184 RESTORE_REGS 185 RET 186 187/* A fault occurred during the copy */ 188.Lcopystrfault: 189 mov r1, #0x00000000 190 str r1, [r4, #PCB_ONFAULT] 191 RESTORE_REGS 192 RET 193 194#ifdef DIAGNOSTIC 195.Lcopystrpcbfault: 196 mov r2, r1 197 mov r1, r0 198 adr r0, Lcopystrpcbfaulttext 199 bic sp, sp, #7 /* align stack to 8 bytes */ 200 b _C_LABEL(panic) 201 202Lcopystrpcbfaulttext: 203 .asciz "No valid PCB during copyinoutstr() addr1=%08x addr2=%08x\n" 204 .align 0 205#endif 206