1129198Scognet/* $NetBSD: copystr.S,v 1.8 2002/10/13 14:54:48 bjh21 Exp $ */ 2129198Scognet 3139735Simp/*- 4129198Scognet * Copyright (c) 1995 Mark Brinicombe. 5129198Scognet * All rights reserved. 6129198Scognet * 7129198Scognet * Redistribution and use in source and binary forms, with or without 8129198Scognet * modification, are permitted provided that the following conditions 9129198Scognet * are met: 10129198Scognet * 1. Redistributions of source code must retain the above copyright 11129198Scognet * notice, this list of conditions and the following disclaimer. 12129198Scognet * 2. Redistributions in binary form must reproduce the above copyright 13129198Scognet * notice, this list of conditions and the following disclaimer in the 14129198Scognet * documentation and/or other materials provided with the distribution. 15129198Scognet * 3. All advertising materials mentioning features or use of this software 16129198Scognet * must display the following acknowledgement: 17129198Scognet * This product includes software developed by Mark Brinicombe. 18129198Scognet * 4. The name of the company nor the name of the author may be used to 19129198Scognet * endorse or promote products derived from this software without specific 20129198Scognet * prior written permission. 21129198Scognet * 22129198Scognet * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 23129198Scognet * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 24129198Scognet * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25129198Scognet * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 26129198Scognet * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 27129198Scognet * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28129198Scognet * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29129198Scognet * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30129198Scognet * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31129198Scognet * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32129198Scognet * SUCH DAMAGE. 33129198Scognet * 34129198Scognet * copystr.S 35129198Scognet * 36129198Scognet * optimised and fault protected copystr functions 37129198Scognet * 38129198Scognet * Created : 16/05/95 39129198Scognet */ 40129198Scognet 41129198Scognet#include "assym.s" 42129198Scognet#include <machine/asm.h> 43129198Scognet#include <machine/armreg.h> 44129198Scognet__FBSDID("$FreeBSD$"); 45129198Scognet 46129198Scognet#include <sys/errno.h> 47129198Scognet 48129198Scognet .text 49276596Sian .align 2 50239268Sgonzo 51284264Sandrew#if __ARM_ARCH >= 6 52239268Sgonzo#define GET_PCB(tmp) \ 53239268Sgonzo mrc p15, 0, tmp, c13, c0, 4; \ 54261415Scognet add tmp, tmp, #(TD_PCB) 55129198Scognet#else 56129198Scognet.Lpcb: 57129198Scognet .word _C_LABEL(__pcpu) + PC_CURPCB 58239268Sgonzo 59239268Sgonzo#define GET_PCB(tmp) \ 60239268Sgonzo ldr tmp, .Lpcb 61129198Scognet#endif 62129198Scognet 63129198Scognet/* 64129198Scognet * r0 - from 65129198Scognet * r1 - to 66129198Scognet * r2 - maxlens 67129198Scognet * r3 - lencopied 68129198Scognet * 69129198Scognet * Copy string from r0 to r1 70129198Scognet */ 71129198ScognetENTRY(copystr) 72129198Scognet stmfd sp!, {r4-r5} /* stack is 8 byte aligned */ 73129198Scognet teq r2, #0x00000000 74129198Scognet mov r5, #0x00000000 75129198Scognet moveq r0, #ENAMETOOLONG 76129198Scognet beq 2f 77129198Scognet 78129198Scognet1: ldrb r4, [r0], #0x0001 79129198Scognet add r5, r5, #0x00000001 80129198Scognet teq r4, #0x00000000 81129198Scognet strb r4, [r1], #0x0001 82129198Scognet teqne r5, r2 83129198Scognet bne 1b 84129198Scognet 85129198Scognet teq r4, #0x00000000 86129198Scognet moveq r0, #0x00000000 87129198Scognet movne r0, #ENAMETOOLONG 88129198Scognet 89129198Scognet2: teq r3, #0x00000000 90129198Scognet strne r5, [r3] 91129198Scognet 92129198Scognet ldmfd sp!, {r4-r5} /* stack is 8 byte aligned */ 93137463Scognet RET 94248361SandrewEND(copystr) 95129198Scognet 96129198Scognet#define SAVE_REGS stmfd sp!, {r4-r6} 97129198Scognet#define RESTORE_REGS ldmfd sp!, {r4-r6} 98129198Scognet 99129198Scognet/* 100129198Scognet * r0 - user space address 101129198Scognet * r1 - kernel space address 102129198Scognet * r2 - maxlens 103129198Scognet * r3 - lencopied 104129198Scognet * 105129198Scognet * Copy string from user space to kernel space 106129198Scognet */ 107129198ScognetENTRY(copyinstr) 108129198Scognet SAVE_REGS 109129198Scognet 110129198Scognet teq r2, #0x00000000 111129198Scognet mov r6, #0x00000000 112129198Scognet moveq r0, #ENAMETOOLONG 113129198Scognet beq 2f 114129198Scognet 115289372Skib ldr r12, =VM_MAXUSER_ADDRESS 116289372Skib 117239268Sgonzo GET_PCB(r4) 118129198Scognet ldr r4, [r4] 119129198Scognet 120129198Scognet#ifdef DIAGNOSTIC 121129198Scognet teq r4, #0x00000000 122129198Scognet beq .Lcopystrpcbfault 123129198Scognet#endif 124129198Scognet 125129198Scognet adr r5, .Lcopystrfault 126129198Scognet str r5, [r4, #PCB_ONFAULT] 127129198Scognet 128289372Skib1: 129289372Skib cmp r0, r12 130289372Skib bcs .Lcopystrfault 131289372Skib ldrbt r5, [r0], #0x0001 132129198Scognet add r6, r6, #0x00000001 133129198Scognet teq r5, #0x00000000 134129198Scognet strb r5, [r1], #0x0001 135129198Scognet teqne r6, r2 136129198Scognet bne 1b 137129198Scognet 138129198Scognet mov r0, #0x00000000 139129198Scognet str r0, [r4, #PCB_ONFAULT] 140129198Scognet 141129198Scognet teq r5, #0x00000000 142129198Scognet moveq r0, #0x00000000 143129198Scognet movne r0, #ENAMETOOLONG 144129198Scognet 145129198Scognet2: teq r3, #0x00000000 146129198Scognet strne r6, [r3] 147129198Scognet 148129198Scognet RESTORE_REGS 149137463Scognet RET 150248361SandrewEND(copyinstr) 151129198Scognet 152129198Scognet/* 153129198Scognet * r0 - kernel space address 154129198Scognet * r1 - user space address 155129198Scognet * r2 - maxlens 156129198Scognet * r3 - lencopied 157129198Scognet * 158129198Scognet * Copy string from kernel space to user space 159129198Scognet */ 160129198ScognetENTRY(copyoutstr) 161129198Scognet SAVE_REGS 162129198Scognet 163129198Scognet teq r2, #0x00000000 164129198Scognet mov r6, #0x00000000 165129198Scognet moveq r0, #ENAMETOOLONG 166129198Scognet beq 2f 167129198Scognet 168289372Skib ldr r12, =VM_MAXUSER_ADDRESS 169289372Skib 170239268Sgonzo GET_PCB(r4) 171129198Scognet ldr r4, [r4] 172129198Scognet 173129198Scognet#ifdef DIAGNOSTIC 174129198Scognet teq r4, #0x00000000 175129198Scognet beq .Lcopystrpcbfault 176129198Scognet#endif 177129198Scognet 178129198Scognet adr r5, .Lcopystrfault 179129198Scognet str r5, [r4, #PCB_ONFAULT] 180129198Scognet 181289372Skib1: 182289372Skib cmp r0, r12 183289372Skib bcs .Lcopystrfault 184289372Skib ldrb r5, [r0], #0x0001 185129198Scognet add r6, r6, #0x00000001 186129198Scognet teq r5, #0x00000000 187129198Scognet strbt r5, [r1], #0x0001 188129198Scognet teqne r6, r2 189129198Scognet bne 1b 190129198Scognet 191129198Scognet mov r0, #0x00000000 192129198Scognet str r0, [r4, #PCB_ONFAULT] 193129198Scognet 194129198Scognet teq r5, #0x00000000 195129198Scognet moveq r0, #0x00000000 196129198Scognet movne r0, #ENAMETOOLONG 197129198Scognet 198129198Scognet2: teq r3, #0x00000000 199129198Scognet strne r6, [r3] 200129198Scognet 201129198Scognet RESTORE_REGS 202137463Scognet RET 203248361SandrewEND(copyoutstr) 204129198Scognet 205129198Scognet/* A fault occurred during the copy */ 206129198Scognet.Lcopystrfault: 207129198Scognet mov r1, #0x00000000 208129198Scognet str r1, [r4, #PCB_ONFAULT] 209289372Skib mov r0, #EFAULT 210129198Scognet RESTORE_REGS 211137463Scognet RET 212129198Scognet 213129198Scognet#ifdef DIAGNOSTIC 214129198Scognet.Lcopystrpcbfault: 215129198Scognet mov r2, r1 216129198Scognet mov r1, r0 217129198Scognet adr r0, Lcopystrpcbfaulttext 218129198Scognet bic sp, sp, #7 /* align stack to 8 bytes */ 219129198Scognet b _C_LABEL(panic) 220129198Scognet 221129198ScognetLcopystrpcbfaulttext: 222129198Scognet .asciz "No valid PCB during copyinoutstr() addr1=%08x addr2=%08x\n" 223276596Sian .align 2 224129198Scognet#endif 225