Home | History | Annotate | Line # | Download | only in arm
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License, Version 1.0 only
      6  * (the "License").  You may not use this file except in compliance
      7  * with the License.
      8  *
      9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     10  * or http://www.opensolaris.org/os/licensing.
     11  * See the License for the specific language governing permissions
     12  * and limitations under the License.
     13  *
     14  * When distributing Covered Code, include this CDDL HEADER in each
     15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     16  * If applicable, add the following below this CDDL HEADER, with the
     17  * fields enclosed by brackets "[]" replaced with your own identifying
     18  * information: Portions Copyright [yyyy] [name of copyright owner]
     19  *
     20  * CDDL HEADER END
     21  *
     22  * $FreeBSD: head/sys/cddl/dev/dtrace/arm/dtrace_asm.S 308427 2016-11-07 20:02:18Z gonzo $
     23  */
     24 /*
     25  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
     26  * Use is subject to license terms.
     27  */
     28 
     29 #define _ASM
     30 #define _LOCORE
     31 
     32 #include <sys/cpuvar_defs.h>
     33 #include <sys/dtrace.h>
     34 
     35 #include <machine/asm.h>
     36 #include <arm/armreg.h>
     37 
     38 #define	PSR_I	I32_bit
     39 #define	PSR_F	F32_bit
     40 
     41 #ifdef	__ARM_BIG_ENDIAN
     42 #define	__BIG_ENDIAN 1
     43 #endif
     44 
     45 #define EENTRY(x)	ENTRY_NP(x)
     46 #define EEND(x)		/* nothing */
     47 
     48 /*
     49 void dtrace_membar_producer(void)
     50 */
     51 ENTRY(dtrace_membar_producer)
     52 	RET
     53 END(dtrace_membar_producer)
     54 
     55 /*
     56 void dtrace_membar_consumer(void)
     57 */
     58 ENTRY(dtrace_membar_consumer)
     59 	RET
     60 END(dtrace_membar_consumer)
     61 
     62 /*
     63 dtrace_icookie_t dtrace_interrupt_disable(void)
     64 */
     65 ENTRY(dtrace_interrupt_disable)
     66 	mrs	r0, cpsr
     67 	mov	r1, r0
     68 	orr	r1, r1, #(PSR_I | PSR_F)
     69 	msr	cpsr_c, r1
     70 	RET
     71 END(dtrace_interrupt_disable)
     72 
     73 /*
     74 void dtrace_interrupt_enable(dtrace_icookie_t cookie)
     75 */
     76 ENTRY(dtrace_interrupt_enable)
     77 	and	r0, r0, #(PSR_I | PSR_F)
     78 	mrs	r1, cpsr
     79 	bic	r1, r1, #(PSR_I | PSR_F)
     80 	orr	r1, r1, r0
     81 	msr	cpsr_c, r1
     82 	RET
     83 END(dtrace_interrupt_enable)
     84 
     85 /*
     86 uint8_t
     87 dtrace_fuword8_nocheck(void *addr)
     88 */
     89 ENTRY(dtrace_fuword8_nocheck)
     90 	ldrb	r3, [r0]
     91 	mov 	r0, r3
     92 	RET
     93 END(dtrace_fuword8_nocheck)
     94 
     95 /*
     96 uint16_t
     97 dtrace_fuword16_nocheck(void *addr)
     98 */
     99 ENTRY(dtrace_fuword16_nocheck)
    100 	ldrh	r3, [r0]
    101 	mov 	r0, r3
    102 	RET
    103 END(dtrace_fuword16_nocheck)
    104 
    105 /*
    106 uint32_t
    107 dtrace_fuword32_nocheck(void *addr)
    108 */
    109 ENTRY(dtrace_fuword32_nocheck)
    110 	ldr	r3, [r0]
    111 	mov 	r0, r3
    112 	RET
    113 END(dtrace_fuword32_nocheck)
    114 
    115 /*
    116 uint64_t
    117 dtrace_fuword64_nocheck(void *addr)
    118 */
    119 ENTRY(dtrace_fuword64_nocheck)
    120 	ldm	r0, {r2, r3}
    121 
    122 	mov	r0, r2
    123 	mov	r1, r3
    124 #if defined(__BIG_ENDIAN__)
    125 /* big endian */
    126 	mov	r0, r3
    127 	mov	r1, r2
    128 #else
    129 /* little endian */
    130 	mov	r0, r2
    131 	mov	r1, r3
    132 
    133 #endif
    134 	RET
    135 END(dtrace_fuword64_nocheck)
    136 
    137 /*
    138 void
    139 dtrace_copy(uintptr_t uaddr, uintptr_t kaddr, size_t size)
    140 */
    141 ENTRY(dtrace_copy)
    142 	stmfd   sp!, {r4-r5}			/* stack is 8 byte aligned */
    143 	teq	r2, #0x00000000
    144 	mov	r5, #0x00000000
    145 	beq	2f
    146 
    147 1:	ldrb	r4, [r0], #0x0001
    148 	add	r5, r5, #0x00000001
    149 	strb	r4, [r1], #0x0001
    150 	teqne	r5, r2
    151 	bne	1b
    152 
    153 2:	ldmfd	sp!, {r4-r5}			/* stack is 8 byte aligned */
    154 	RET
    155 END(dtrace_copy)
    156 
    157 /*
    158 void
    159 dtrace_copystr(uintptr_t uaddr, uintptr_t kaddr, size_t size,
    160     volatile uint16_t *flags)
    161 XXX: Check for flags?
    162 */
    163 ENTRY(dtrace_copystr)
    164 	stmfd	sp!, {r4-r5}			/* stack is 8 byte aligned */
    165 	teq	r2, #0x00000000
    166 	mov	r5, #0x00000000
    167 	beq	2f
    168 
    169 1:	ldrb	r4, [r0], #0x0001
    170 	add	r5, r5, #0x00000001
    171 	teq	r4, #0x00000000
    172 	strb	r4, [r1], #0x0001
    173 	teqne	r5, r2
    174 	bne	1b
    175 
    176 2:	ldmfd	sp!, {r4-r5}			/* stack is 8 byte aligned */
    177 	RET
    178 END(dtrace_copystr)
    179 
    180 /*
    181 uintptr_t
    182 dtrace_caller(int aframes)
    183 */
    184 ENTRY(dtrace_caller)
    185 	mov	r0, #-1
    186 	RET
    187 END(dtrace_caller)
    188 
    189 /*
    190 uint32_t
    191 dtrace_cas32(uint32_t *target, uint32_t cmp, uint32_t new)
    192 
    193 void *
    194 dtrace_casptr(volatile void *target, volatile void *cmp, volatile void *new)
    195 */
    196 EENTRY(dtrace_casptr)
    197 ENTRY(dtrace_cas32)
    198 #if __ARM_ARCH >= 6
    199 
    200 1:	ldrex	r3, [r0]	/* Load target */
    201 	cmp	r3, r1		/* Check if *target == cmp */
    202 	bne	2f		/* No, return */
    203 	strex	ip, r2, [r0]	/* Store new to target */
    204 	cmp	ip, #0		/* Did the store succeed? */
    205 	bne	1b		/* No, try again */
    206 2:	mov	r0, r3		/* Return the value loaded from target */
    207 	RET
    208 
    209 #else
    210 
    211 	/*
    212 	 * We don't support MP on CPUs older than v6, so just disable interrupts
    213 	 * and use non-atomic instructions.
    214 	 */
    215 
    216 	stmfd	sp!, {r4, r5}
    217 
    218 	mrs	r3, cpsr
    219 	mov	r4, r3
    220 	orr	r4, r4, #(PSR_I | PSR_F)
    221 	msr	cpsr_c, r4
    222 
    223 	ldr	r5, [r0]
    224 	cmp	r5, r1
    225 	movne	r0, r5
    226 	bne	2f
    227 
    228 	str	r2, [r0]
    229 	mov	r0, r5
    230 
    231 2:
    232 	msr	cpsr_c, r3
    233 	ldmfd	sp!, {r4, r5}
    234 	RET
    235 #endif
    236 END(dtrace_cas32)
    237 EEND(dtrace_casptr)
    238