1/* $NetBSD: copystr.S,v 1.8 2002/10/13 14:54:48 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 43#include "assym.h" 44#include <machine/asm.h> 45 46RCSID("$NetBSD: copystr.S,v 1.8 2002/10/13 14:54:48 bjh21 Exp $") 47 48#include <sys/errno.h> 49 50 .text 51 .align 0 52#ifdef MULTIPROCESSOR 53.Lcpu_info: 54 .word _C_LABEL(cpu_info) 55#else 56.Lcurpcb: 57 .word _C_LABEL(curpcb) 58#endif 59 60/* 61 * r0 - from 62 * r1 - to 63 * r2 - maxlens 64 * r3 - lencopied 65 * 66 * Copy string from r0 to r1 67 */ 68ENTRY(copystr) 69 stmfd sp!, {r4-r5} /* stack is 8 byte aligned */ 70 teq r2, #0x00000000 71 mov r5, #0x00000000 72 moveq r0, #ENAMETOOLONG 73 beq 2f 74 751: ldrb r4, [r0], #0x0001 76 add r5, r5, #0x00000001 77 teq r4, #0x00000000 78 strb r4, [r1], #0x0001 79 teqne r5, r2 80 bne 1b 81 82 teq r4, #0x00000000 83 moveq r0, #0x00000000 84 movne r0, #ENAMETOOLONG 85 862: teq r3, #0x00000000 87 strne r5, [r3] 88 89 ldmfd sp!, {r4-r5} /* stack is 8 byte aligned */ 90 mov pc, lr 91 92#ifdef __PROG32 93#define SAVE_REGS stmfd sp!, {r4-r6} 94#define RESTORE_REGS ldmfd sp!, {r4-r6} 95#else 96/* Need to save R14_svc because it'll get trampled if we take a page fault. */ 97#define SAVE_REGS stmfd sp!, {r4-r6, r14} 98#define RESTORE_REGS ldmfd sp!, {r4-r6, r14} 99#endif 100 101/* 102 * r0 - user space address 103 * r1 - kernel space address 104 * r2 - maxlens 105 * r3 - lencopied 106 * 107 * Copy string from user space to kernel space 108 */ 109ENTRY(copyinstr) 110 SAVE_REGS 111 112 teq r2, #0x00000000 113 mov r6, #0x00000000 114 moveq r0, #ENAMETOOLONG 115 beq 2f 116 117#ifdef MULTIPROCESSOR 118 /* XXX Probably not appropriate for non-Hydra SMPs */ 119 stmfd sp!, {r0-r3, r14} 120 bl _C_LABEL(cpu_number) 121 ldr r4, .Lcpu_info 122 ldr r4, [r4, r0, lsl #2] 123 ldr r4, [r4, #CI_CURPCB] 124 ldmfd sp!, {r0-r3, r14} 125#else 126 ldr r4, .Lcurpcb 127 ldr r4, [r4] 128#endif 129 130#ifdef DIAGNOSTIC 131 teq r4, #0x00000000 132 beq .Lcopystrpcbfault 133#endif 134 135 adr r5, .Lcopystrfault 136 str r5, [r4, #PCB_ONFAULT] 137 1381: ldrbt r5, [r0], #0x0001 139 add r6, r6, #0x00000001 140 teq r5, #0x00000000 141 strb r5, [r1], #0x0001 142 teqne r6, r2 143 bne 1b 144 145 mov r0, #0x00000000 146 str r0, [r4, #PCB_ONFAULT] 147 148 teq r5, #0x00000000 149 moveq r0, #0x00000000 150 movne r0, #ENAMETOOLONG 151 1522: teq r3, #0x00000000 153 strne r6, [r3] 154 155 RESTORE_REGS 156 mov pc, lr 157 158/* 159 * r0 - kernel space address 160 * r1 - user space address 161 * r2 - maxlens 162 * r3 - lencopied 163 * 164 * Copy string from kernel space to user space 165 */ 166ENTRY(copyoutstr) 167 SAVE_REGS 168 169 teq r2, #0x00000000 170 mov r6, #0x00000000 171 moveq r0, #ENAMETOOLONG 172 beq 2f 173 174#ifdef MULTIPROCESSOR 175 /* XXX Probably not appropriate for non-Hydra SMPs */ 176 stmfd sp!, {r0-r3, r14} 177 bl _C_LABEL(cpu_number) 178 ldr r4, .Lcpu_info 179 ldr r4, [r4, r0, lsl #2] 180 ldr r4, [r4, #CI_CURPCB] 181 ldmfd sp!, {r0-r3, r14} 182#else 183 ldr r4, .Lcurpcb 184 ldr r4, [r4] 185#endif 186 187#ifdef DIAGNOSTIC 188 teq r4, #0x00000000 189 beq .Lcopystrpcbfault 190#endif 191 192 adr r5, .Lcopystrfault 193 str r5, [r4, #PCB_ONFAULT] 194 1951: ldrb r5, [r0], #0x0001 196 add r6, r6, #0x00000001 197 teq r5, #0x00000000 198 strbt r5, [r1], #0x0001 199 teqne r6, r2 200 bne 1b 201 202 mov r0, #0x00000000 203 str r0, [r4, #PCB_ONFAULT] 204 205 teq r5, #0x00000000 206 moveq r0, #0x00000000 207 movne r0, #ENAMETOOLONG 208 2092: teq r3, #0x00000000 210 strne r6, [r3] 211 212 RESTORE_REGS 213 mov pc, lr 214 215/* A fault occurred during the copy */ 216.Lcopystrfault: 217 mov r1, #0x00000000 218 str r1, [r4, #PCB_ONFAULT] 219 RESTORE_REGS 220 mov pc, lr 221 222#ifdef DIAGNOSTIC 223.Lcopystrpcbfault: 224 mov r2, r1 225 mov r1, r0 226 adr r0, Lcopystrpcbfaulttext 227 bic sp, sp, #7 /* align stack to 8 bytes */ 228 b _C_LABEL(panic) 229 230Lcopystrpcbfaulttext: 231 .asciz "No valid PCB during copyinoutstr() addr1=%08x addr2=%08x\n" 232 .align 0 233#endif 234