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 42129198Scognet#include "assym.s" 43129198Scognet#include <machine/asm.h> 44129198Scognet#include <machine/armreg.h> 45129198Scognet#include <machine/asmacros.h> 46129198Scognet__FBSDID("$FreeBSD$"); 47129198Scognet 48129198Scognet#include <sys/errno.h> 49129198Scognet 50129198Scognet .text 51129198Scognet .align 0 52129198Scognet#ifdef MULTIPROCESSOR 53129198Scognet.Lcpu_info: 54129198Scognet .word _C_LABEL(cpu_info) 55129198Scognet#else 56129198Scognet.Lpcb: 57129198Scognet .word _C_LABEL(__pcpu) + PC_CURPCB 58129198Scognet#endif 59129198Scognet 60129198Scognet/* 61129198Scognet * r0 - from 62129198Scognet * r1 - to 63129198Scognet * r2 - maxlens 64129198Scognet * r3 - lencopied 65129198Scognet * 66129198Scognet * Copy string from r0 to r1 67129198Scognet */ 68129198ScognetENTRY(copystr) 69129198Scognet stmfd sp!, {r4-r5} /* stack is 8 byte aligned */ 70129198Scognet teq r2, #0x00000000 71129198Scognet mov r5, #0x00000000 72129198Scognet moveq r0, #ENAMETOOLONG 73129198Scognet beq 2f 74129198Scognet 75129198Scognet1: ldrb r4, [r0], #0x0001 76129198Scognet add r5, r5, #0x00000001 77129198Scognet teq r4, #0x00000000 78129198Scognet strb r4, [r1], #0x0001 79129198Scognet teqne r5, r2 80129198Scognet bne 1b 81129198Scognet 82129198Scognet teq r4, #0x00000000 83129198Scognet moveq r0, #0x00000000 84129198Scognet movne r0, #ENAMETOOLONG 85129198Scognet 86129198Scognet2: teq r3, #0x00000000 87129198Scognet strne r5, [r3] 88129198Scognet 89129198Scognet ldmfd sp!, {r4-r5} /* stack is 8 byte aligned */ 90137463Scognet RET 91129198Scognet 92129198Scognet#define SAVE_REGS stmfd sp!, {r4-r6} 93129198Scognet#define RESTORE_REGS ldmfd sp!, {r4-r6} 94129198Scognet 95129198Scognet/* 96129198Scognet * r0 - user space address 97129198Scognet * r1 - kernel space address 98129198Scognet * r2 - maxlens 99129198Scognet * r3 - lencopied 100129198Scognet * 101129198Scognet * Copy string from user space to kernel space 102129198Scognet */ 103129198ScognetENTRY(copyinstr) 104129198Scognet SAVE_REGS 105129198Scognet 106129198Scognet teq r2, #0x00000000 107129198Scognet mov r6, #0x00000000 108129198Scognet moveq r0, #ENAMETOOLONG 109129198Scognet beq 2f 110129198Scognet 111129198Scognet#ifdef MULTIPROCESSOR 112129198Scognet /* XXX Probably not appropriate for non-Hydra SMPs */ 113129198Scognet stmfd sp!, {r0-r3, r14} 114129198Scognet bl _C_LABEL(cpu_number) 115129198Scognet ldr r4, .Lcpu_info 116129198Scognet ldr r4, [r4, r0, lsl #2] 117129198Scognet ldr r4, [r4, #CI_CURPCB] 118129198Scognet ldmfd sp!, {r0-r3, r14} 119129198Scognet#else 120129198Scognet ldr r4, .Lpcb 121129198Scognet ldr r4, [r4] 122129198Scognet#endif 123129198Scognet 124129198Scognet#ifdef DIAGNOSTIC 125129198Scognet teq r4, #0x00000000 126129198Scognet beq .Lcopystrpcbfault 127129198Scognet#endif 128129198Scognet 129129198Scognet adr r5, .Lcopystrfault 130129198Scognet str r5, [r4, #PCB_ONFAULT] 131129198Scognet 132129198Scognet1: ldrbt r5, [r0], #0x0001 133129198Scognet add r6, r6, #0x00000001 134129198Scognet teq r5, #0x00000000 135129198Scognet strb r5, [r1], #0x0001 136129198Scognet teqne r6, r2 137129198Scognet bne 1b 138129198Scognet 139129198Scognet mov r0, #0x00000000 140129198Scognet str r0, [r4, #PCB_ONFAULT] 141129198Scognet 142129198Scognet teq r5, #0x00000000 143129198Scognet moveq r0, #0x00000000 144129198Scognet movne r0, #ENAMETOOLONG 145129198Scognet 146129198Scognet2: teq r3, #0x00000000 147129198Scognet strne r6, [r3] 148129198Scognet 149129198Scognet RESTORE_REGS 150137463Scognet RET 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 168129198Scognet#ifdef MULTIPROCESSOR 169129198Scognet /* XXX Probably not appropriate for non-Hydra SMPs */ 170129198Scognet stmfd sp!, {r0-r3, r14} 171129198Scognet bl _C_LABEL(cpu_number) 172129198Scognet ldr r4, .Lcpu_info 173129198Scognet ldr r4, [r4, r0, lsl #2] 174129198Scognet ldr r4, [r4, #CI_CURPCB] 175129198Scognet ldmfd sp!, {r0-r3, r14} 176129198Scognet#else 177129198Scognet ldr r4, .Lpcb 178129198Scognet ldr r4, [r4] 179129198Scognet#endif 180129198Scognet 181129198Scognet#ifdef DIAGNOSTIC 182129198Scognet teq r4, #0x00000000 183129198Scognet beq .Lcopystrpcbfault 184129198Scognet#endif 185129198Scognet 186129198Scognet adr r5, .Lcopystrfault 187129198Scognet str r5, [r4, #PCB_ONFAULT] 188129198Scognet 189129198Scognet1: ldrb r5, [r0], #0x0001 190129198Scognet add r6, r6, #0x00000001 191129198Scognet teq r5, #0x00000000 192129198Scognet strbt r5, [r1], #0x0001 193129198Scognet teqne r6, r2 194129198Scognet bne 1b 195129198Scognet 196129198Scognet mov r0, #0x00000000 197129198Scognet str r0, [r4, #PCB_ONFAULT] 198129198Scognet 199129198Scognet teq r5, #0x00000000 200129198Scognet moveq r0, #0x00000000 201129198Scognet movne r0, #ENAMETOOLONG 202129198Scognet 203129198Scognet2: teq r3, #0x00000000 204129198Scognet strne r6, [r3] 205129198Scognet 206129198Scognet RESTORE_REGS 207137463Scognet RET 208129198Scognet 209129198Scognet/* A fault occurred during the copy */ 210129198Scognet.Lcopystrfault: 211129198Scognet mov r1, #0x00000000 212129198Scognet str r1, [r4, #PCB_ONFAULT] 213129198Scognet RESTORE_REGS 214137463Scognet RET 215129198Scognet 216129198Scognet#ifdef DIAGNOSTIC 217129198Scognet.Lcopystrpcbfault: 218129198Scognet mov r2, r1 219129198Scognet mov r1, r0 220129198Scognet adr r0, Lcopystrpcbfaulttext 221129198Scognet bic sp, sp, #7 /* align stack to 8 bytes */ 222129198Scognet b _C_LABEL(panic) 223129198Scognet 224129198ScognetLcopystrpcbfaulttext: 225129198Scognet .asciz "No valid PCB during copyinoutstr() addr1=%08x addr2=%08x\n" 226129198Scognet .align 0 227129198Scognet#endif 228