1/* $NetBSD: copystr.S,v 1.11 2013/08/18 06:28:18 matt 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 46#include <machine/asm.h> 47 48#include <arm/locore.h> 49 50RCSID("$NetBSD: copystr.S,v 1.11 2013/08/18 06:28:18 matt Exp $") 51 52#include <sys/errno.h> 53 54 .text 55 .align 0 56/* 57 * r0 - from 58 * r1 - to 59 * r2 - maxlens 60 * r3 - lencopied 61 * 62 * Copy string from r0 to r1 63 */ 64ENTRY(copystr) 65 push {r4-r5} /* stack is 8 byte aligned */ 66 teq r2, #0x00000000 67 mov r5, #0x00000000 68 moveq r0, #ENAMETOOLONG 69 beq 2f 70 711: ldrb r4, [r0], #0x0001 72 add r5, r5, #0x00000001 73 teq r4, #0x00000000 74 strb r4, [r1], #0x0001 75 teqne r5, r2 76 bne 1b 77 78 teq r4, #0x00000000 79 moveq r0, #0x00000000 80 movne r0, #ENAMETOOLONG 81 822: teq r3, #0x00000000 83 strne r5, [r3] 84 85 pop {r4-r5} /* stack is 8 byte aligned */ 86 RET 87END(copystr) 88 89#ifdef __PROG32 90#define SAVE_REGS push {r3-r6} 91#define RESTORE_REGS pop {r3-r6} 92#else 93/* Need to save R14_svc because it'll get trampled if we take a page fault. */ 94#define SAVE_REGS stmfd sp!, {r4-r6, r14} 95#define RESTORE_REGS ldmfd sp!, {r4-r6, r14} 96#endif 97 98/* 99 * r0 - user space address 100 * r1 - kernel space address 101 * r2 - maxlens 102 * r3 - lencopied 103 * 104 * Copy string from user space to kernel space 105 */ 106ENTRY(copyinstr) 107 SAVE_REGS 108 109 teq r2, #0x00000000 110 mov r6, #0x00000000 111 moveq r0, #ENAMETOOLONG 112 beq 2f 113 114 GET_CURPCB(r4) 115 116#ifdef DIAGNOSTIC 117 teq r4, #0x00000000 118 beq .Lcopystrpcbfault 119#endif 120 121 adr r5, .Lcopystrfault 122 str r5, [r4, #PCB_ONFAULT] 123 1241: ldrbt r5, [r0], #0x0001 125 add r6, r6, #0x00000001 126 teq r5, #0x00000000 127 strb r5, [r1], #0x0001 128 teqne r6, r2 129 bne 1b 130 131 mov r0, #0x00000000 132 str r0, [r4, #PCB_ONFAULT] 133 134 teq r5, #0x00000000 135 moveq r0, #0x00000000 136 movne r0, #ENAMETOOLONG 137 1382: teq r3, #0x00000000 139 strne r6, [r3] 140 141 RESTORE_REGS 142 RET 143END(copyinstr) 144 145/* 146 * r0 - kernel space address 147 * r1 - user space address 148 * r2 - maxlens 149 * r3 - lencopied 150 * 151 * Copy string from kernel space to user space 152 */ 153ENTRY(copyoutstr) 154 SAVE_REGS 155 156 teq r2, #0x00000000 157 mov r6, #0x00000000 158 moveq r0, #ENAMETOOLONG 159 beq 2f 160 161 GET_CURPCB(r4) 162 163#ifdef DIAGNOSTIC 164 teq r4, #0x00000000 165 beq .Lcopystrpcbfault 166#endif 167 168 adr r5, .Lcopystrfault 169 str r5, [r4, #PCB_ONFAULT] 170 1711: ldrb r5, [r0], #0x0001 172 add r6, r6, #0x00000001 173 teq r5, #0x00000000 174 strbt r5, [r1], #0x0001 175 teqne r6, r2 176 bne 1b 177 178 mov r0, #0x00000000 179 str r0, [r4, #PCB_ONFAULT] 180 181 teq r5, #0x00000000 182 moveq r0, #0x00000000 183 movne r0, #ENAMETOOLONG 184 1852: teq r3, #0x00000000 186 strne r6, [r3] 187 188 RESTORE_REGS 189 RET 190 191/* A fault occurred during the copy */ 192.Lcopystrfault: 193 mov r1, #0x00000000 194 str r1, [r4, #PCB_ONFAULT] 195 RESTORE_REGS 196 RET 197 198#ifdef DIAGNOSTIC 199.Lcopystrpcbfault: 200 mov r2, r1 201 mov r1, r0 202 adr r0, .Lcopystrpcbfaulttext 203 bic sp, sp, #7 /* align stack to 8 bytes */ 204 b _C_LABEL(panic) 205 206.Lcopystrpcbfaulttext: 207 .asciz "No valid PCB during copyinoutstr() addr1=%08x addr2=%08x\n" 208 .align 0 209#endif 210END(copyoutstr) 211