Home | History | Annotate | Line # | Download | only in aarch64
cpufunc_asm_armv8.S revision 1.7
      1  1.7  ryo /*	$NetBSD: cpufunc_asm_armv8.S,v 1.7 2020/07/19 07:18:07 ryo Exp $	*/
      2  1.1  ryo 
      3  1.1  ryo /*-
      4  1.1  ryo  * Copyright (c) 2014 Robin Randhawa
      5  1.1  ryo  * Copyright (c) 2015 The FreeBSD Foundation
      6  1.1  ryo  * All rights reserved.
      7  1.1  ryo  *
      8  1.1  ryo  * Portions of this software were developed by Andrew Turner
      9  1.1  ryo  * under sponsorship from the FreeBSD Foundation
     10  1.1  ryo  *
     11  1.1  ryo  * Redistribution and use in source and binary forms, with or without
     12  1.1  ryo  * modification, are permitted provided that the following conditions
     13  1.1  ryo  * are met:
     14  1.1  ryo  * 1. Redistributions of source code must retain the above copyright
     15  1.1  ryo  *    notice, this list of conditions and the following disclaimer.
     16  1.1  ryo  * 2. Redistributions in binary form must reproduce the above copyright
     17  1.1  ryo  *    notice, this list of conditions and the following disclaimer in the
     18  1.1  ryo  *    documentation and/or other materials provided with the distribution.
     19  1.1  ryo  *
     20  1.1  ryo  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     21  1.1  ryo  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     22  1.1  ryo  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     23  1.1  ryo  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     24  1.1  ryo  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     25  1.1  ryo  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     26  1.1  ryo  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     27  1.1  ryo  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     28  1.1  ryo  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     29  1.1  ryo  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     30  1.1  ryo  * SUCH DAMAGE.
     31  1.1  ryo  *
     32  1.1  ryo  * $FreeBSD: head/sys/arm64/arm64/cpufunc_asm.S 313347 2017-02-06 17:50:09Z andrew $
     33  1.1  ryo  */
     34  1.1  ryo 
     35  1.3  ryo #include "opt_cputypes.h"
     36  1.1  ryo #include "opt_multiprocessor.h"
     37  1.1  ryo #include <aarch64/asm.h>
     38  1.1  ryo 
     39  1.1  ryo 	.text
     40  1.1  ryo 	.align	2
     41  1.1  ryo 
     42  1.1  ryo /*
     43  1.1  ryo  * Macro to handle the cache. This takes the start address in x0, length
     44  1.5  ryo  * in x1. It will corrupt x2-x5.
     45  1.1  ryo  */
     46  1.7  ryo .macro cache_handle_range dcop = "", icop = ""
     47  1.1  ryo 	mrs	x3, ctr_el0
     48  1.5  ryo 	mov	x4, #4			/* size of word */
     49  1.7  ryo .ifnb \dcop
     50  1.1  ryo 	ubfx	x2, x3, #16, #4		/* x2 = D cache shift */
     51  1.5  ryo 	lsl	x2, x4, x2		/* x2 = D cache line size */
     52  1.5  ryo .endif
     53  1.7  ryo .ifnb \icop
     54  1.1  ryo 	and	x3, x3, #15		/* x3 = I cache shift */
     55  1.5  ryo 	lsl	x3, x4, x3		/* x3 = I cache line size */
     56  1.1  ryo .endif
     57  1.7  ryo .ifnb \dcop
     58  1.5  ryo 	sub	x4, x2, #1		/* Get the address mask */
     59  1.5  ryo 	and	x4, x0, x4		/* Get the low bits of the address */
     60  1.5  ryo 	add	x5, x1, x4		/* Add these to the size */
     61  1.5  ryo 	bic	x4, x0, x4		/* Clear the low bit of the address */
     62  1.1  ryo 1:
     63  1.5  ryo 	dc	\dcop, x4
     64  1.5  ryo 	add	x4, x4, x2		/* Move to the next line */
     65  1.5  ryo 	subs	x5, x5, x2		/* Reduce the size */
     66  1.5  ryo 	b.hi	1b			/* Check if we are done */
     67  1.1  ryo 	dsb	ish
     68  1.1  ryo .endif
     69  1.7  ryo .ifnb \icop
     70  1.5  ryo 	sub	x4, x3, #1		/* Get the address mask */
     71  1.5  ryo 	and	x4, x0, x4		/* Get the low bits of the address */
     72  1.5  ryo 	add	x5, x1, x4		/* Add these to the size */
     73  1.5  ryo 	bic	x4, x0, x4		/* Clear the low bit of the address */
     74  1.5  ryo 1:
     75  1.5  ryo 	ic	\icop, x4
     76  1.5  ryo 	add	x4, x4, x3		/* Move to the next line */
     77  1.5  ryo 	subs	x5, x5, x3		/* Reduce the size */
     78  1.1  ryo 	b.hi	1b			/* Check if we are done */
     79  1.5  ryo 	dsb	ish
     80  1.1  ryo 	isb
     81  1.1  ryo .endif
     82  1.1  ryo .endm
     83  1.1  ryo 
     84  1.1  ryo 
     85  1.1  ryo ENTRY(aarch64_nullop)
     86  1.1  ryo 	ret
     87  1.1  ryo END(aarch64_nullop)
     88  1.1  ryo 
     89  1.1  ryo ENTRY(aarch64_cpuid)
     90  1.1  ryo 	mrs	x0, midr_el1
     91  1.1  ryo 	ret
     92  1.1  ryo END(aarch64_cpuid)
     93  1.1  ryo 
     94  1.1  ryo /*
     95  1.1  ryo  * void aarch64_dcache_wb_range(vaddr_t, vsize_t)
     96  1.1  ryo  */
     97  1.1  ryo ENTRY(aarch64_dcache_wb_range)
     98  1.1  ryo 	cache_handle_range	dcop = cvac
     99  1.5  ryo 	ret
    100  1.1  ryo END(aarch64_dcache_wb_range)
    101  1.1  ryo 
    102  1.1  ryo /*
    103  1.1  ryo  * void aarch64_dcache_wbinv_range(vaddr_t, vsize_t)
    104  1.1  ryo  */
    105  1.1  ryo ENTRY(aarch64_dcache_wbinv_range)
    106  1.1  ryo 	cache_handle_range	dcop = civac
    107  1.5  ryo 	ret
    108  1.1  ryo END(aarch64_dcache_wbinv_range)
    109  1.1  ryo 
    110  1.1  ryo /*
    111  1.1  ryo  * void aarch64_dcache_inv_range(vaddr_t, vsize_t)
    112  1.1  ryo  *
    113  1.1  ryo  * Note, we must not invalidate everything.  If the range is too big we
    114  1.1  ryo  * must use wb-inv of the entire cache.
    115  1.1  ryo  */
    116  1.1  ryo ENTRY(aarch64_dcache_inv_range)
    117  1.1  ryo 	cache_handle_range	dcop = ivac
    118  1.5  ryo 	ret
    119  1.1  ryo END(aarch64_dcache_inv_range)
    120  1.1  ryo 
    121  1.1  ryo /*
    122  1.1  ryo  * void aarch64_idcache_wbinv_range(vaddr_t, vsize_t)
    123  1.1  ryo  */
    124  1.1  ryo ENTRY(aarch64_idcache_wbinv_range)
    125  1.5  ryo 	cache_handle_range	dcop = civac, icop = ivau
    126  1.5  ryo 	ret
    127  1.1  ryo END(aarch64_idcache_wbinv_range)
    128  1.1  ryo 
    129  1.1  ryo /*
    130  1.1  ryo  * void aarch64_icache_sync_range(vaddr_t, vsize_t)
    131  1.1  ryo  */
    132  1.1  ryo ENTRY(aarch64_icache_sync_range)
    133  1.5  ryo 	cache_handle_range	dcop = cvau, icop = ivau
    134  1.5  ryo 	ret
    135  1.1  ryo END(aarch64_icache_sync_range)
    136  1.1  ryo 
    137  1.1  ryo /*
    138  1.6  ryo  * void aarch64_icache_inv_range(vaddr_t, vsize_t)
    139  1.6  ryo  */
    140  1.6  ryo ENTRY(aarch64_icache_inv_range)
    141  1.6  ryo 	cache_handle_range	icop = ivau
    142  1.6  ryo 	ret
    143  1.6  ryo END(aarch64_icache_inv_range)
    144  1.6  ryo 
    145  1.6  ryo /*
    146  1.6  ryo  * void aarch64_icache_barrier_range(vaddr_t, vsize_t)
    147  1.6  ryo  */
    148  1.6  ryo ENTRY(aarch64_icache_barrier_range)
    149  1.6  ryo 	dsb	ishst
    150  1.6  ryo 	isb
    151  1.6  ryo 	ret
    152  1.6  ryo END(aarch64_icache_barrier_range)
    153  1.6  ryo 
    154  1.6  ryo /*
    155  1.1  ryo  * void aarch64_icache_inv_all(void)
    156  1.1  ryo  */
    157  1.1  ryo ENTRY(aarch64_icache_inv_all)
    158  1.1  ryo 	dsb	ish
    159  1.1  ryo #ifdef MULTIPROCESSOR
    160  1.2  ryo 	ic	ialluis
    161  1.2  ryo #else
    162  1.1  ryo 	ic	iallu
    163  1.1  ryo #endif
    164  1.1  ryo 	dsb	ish
    165  1.1  ryo 	isb
    166  1.1  ryo 	ret
    167  1.2  ryo END(aarch64_icache_inv_all)
    168  1.1  ryo 
    169  1.1  ryo 
    170  1.1  ryo 
    171  1.1  ryo ENTRY(aarch64_drain_writebuf)
    172  1.1  ryo 	dsb	sy
    173  1.1  ryo 	ret
    174  1.1  ryo END(aarch64_drain_writebuf)
    175  1.1  ryo 
    176  1.1  ryo 
    177  1.1  ryo /*
    178  1.1  ryo  * TLB ops
    179  1.1  ryo  */
    180  1.1  ryo 
    181  1.1  ryo /* void aarch64_set_ttbr0(uint64_t ttbr0) */
    182  1.1  ryo ENTRY(aarch64_set_ttbr0)
    183  1.1  ryo 	dsb	ish
    184  1.1  ryo 	msr	ttbr0_el1, x0
    185  1.1  ryo 	dsb	ish
    186  1.1  ryo 	isb
    187  1.1  ryo 	ret
    188  1.1  ryo END(aarch64_set_ttbr0)
    189  1.1  ryo 
    190  1.3  ryo #ifdef CPU_THUNDERX
    191  1.3  ryo /*
    192  1.3  ryo  * Cavium erratum 27456
    193  1.3  ryo  * void aarch64_set_ttbr0_thunderx(uint64_t ttbr0)
    194  1.3  ryo  */
    195  1.3  ryo ENTRY(aarch64_set_ttbr0_thunderx)
    196  1.3  ryo 	dsb	ish
    197  1.3  ryo 	msr	ttbr0_el1, x0
    198  1.3  ryo 	isb
    199  1.3  ryo 	ic	iallu
    200  1.3  ryo 	dsb	nsh
    201  1.3  ryo 	isb
    202  1.3  ryo 	ret
    203  1.3  ryo END(aarch64_set_ttbr0_thunderx)
    204  1.3  ryo #endif /* CPU_THUNDERX */
    205  1.3  ryo 
    206  1.1  ryo /* void aarch64_tlbi_all(void) */
    207  1.1  ryo ENTRY(aarch64_tlbi_all)
    208  1.1  ryo 	dsb	ishst
    209  1.1  ryo #ifdef MULTIPROCESSOR
    210  1.1  ryo 	tlbi	vmalle1is
    211  1.1  ryo #else
    212  1.1  ryo 	tlbi	vmalle1
    213  1.1  ryo #endif
    214  1.1  ryo 	dsb	ish
    215  1.1  ryo 	isb
    216  1.1  ryo 	ret
    217  1.1  ryo END(aarch64_tlbi_all)
    218  1.1  ryo 
    219  1.1  ryo /* void aarch64_tlbi_by_asid(int asid) */
    220  1.1  ryo ENTRY(aarch64_tlbi_by_asid)
    221  1.1  ryo 	/* x8 = bit 63[ASID]48, 47[RES0]0 */
    222  1.1  ryo 	lsl	x8, x0, #48
    223  1.1  ryo 	dsb	ishst
    224  1.1  ryo #ifdef MULTIPROCESSOR
    225  1.1  ryo 	tlbi	aside1is, x8
    226  1.1  ryo #else
    227  1.1  ryo 	tlbi	aside1, x8
    228  1.1  ryo #endif
    229  1.1  ryo 	dsb	ish
    230  1.1  ryo 	isb
    231  1.1  ryo 	ret
    232  1.1  ryo END(aarch64_tlbi_by_asid)
    233  1.1  ryo 
    234  1.1  ryo /* aarch64_tlbi_by_va(vaddr_t va) */
    235  1.1  ryo ENTRY(aarch64_tlbi_by_va)
    236  1.1  ryo 	/* x8 = bit 63[RES0]44, 43[VA(55:12)]0 */
    237  1.1  ryo 	ubfx	x8, x0, #12, #44
    238  1.1  ryo 	dsb	ishst
    239  1.1  ryo #ifdef MULTIPROCESSOR
    240  1.1  ryo 	tlbi	vaae1is, x8
    241  1.1  ryo #else
    242  1.1  ryo 	tlbi	vaae1, x8
    243  1.1  ryo #endif
    244  1.1  ryo 	dsb	ish
    245  1.1  ryo 	isb
    246  1.1  ryo 	ret
    247  1.1  ryo END(aarch64_tlbi_by_va)
    248  1.1  ryo 
    249  1.1  ryo /* aarch64_tlbi_by_va_ll(vaddr_t va) */
    250  1.1  ryo ENTRY(aarch64_tlbi_by_va_ll)
    251  1.1  ryo 	/* x8 = bit 63[RES0]44, 43[VA(55:12)]0 */
    252  1.1  ryo 	ubfx	x8, x0, #12, #44
    253  1.1  ryo 	dsb	ishst
    254  1.1  ryo #ifdef MULTIPROCESSOR
    255  1.1  ryo 	tlbi	vaale1is, x8
    256  1.1  ryo #else
    257  1.1  ryo 	tlbi	vaale1, x8
    258  1.1  ryo #endif
    259  1.1  ryo 	dsb	ish
    260  1.1  ryo 	isb
    261  1.1  ryo 	ret
    262  1.1  ryo END(aarch64_tlbi_by_va_ll)
    263  1.1  ryo 
    264  1.1  ryo /* aarch64_tlbi_by_asid_va(int asid, vaddr_t va) */
    265  1.1  ryo ENTRY(aarch64_tlbi_by_asid_va)
    266  1.1  ryo 	/* x8 = bit 63[ASID]48, 47[RES0]44, 43[VA(55:12)]0 */
    267  1.1  ryo 	lsl	x8, x0, #48
    268  1.1  ryo 	bfxil	x8, x1, #12, #44
    269  1.4  ryo 	dsb	ishst
    270  1.1  ryo #ifdef MULTIPROCESSOR
    271  1.1  ryo 	tlbi	vae1is, x8
    272  1.1  ryo #else
    273  1.1  ryo 	tlbi	vae1, x8
    274  1.1  ryo #endif
    275  1.4  ryo 	dsb	ish
    276  1.4  ryo 	isb
    277  1.1  ryo 	ret
    278  1.1  ryo END(aarch64_tlbi_by_asid_va)
    279  1.1  ryo 
    280  1.1  ryo /* aarch64_tlbi_by_asid_va_ll(int asid, vaddr_t va) */
    281  1.1  ryo ENTRY(aarch64_tlbi_by_asid_va_ll)
    282  1.1  ryo 	/* x8 = bit 63[ASID]48, 47[RES0]44, 43[VA(55:12)]0 */
    283  1.1  ryo 	lsl	x8, x0, #48
    284  1.1  ryo 	bfxil	x8, x1, #12, #44
    285  1.4  ryo 	dsb	ishst
    286  1.1  ryo #ifdef MULTIPROCESSOR
    287  1.1  ryo 	tlbi	vale1is, x8
    288  1.1  ryo #else
    289  1.1  ryo 	tlbi	vale1, x8
    290  1.1  ryo #endif
    291  1.4  ryo 	dsb	ish
    292  1.4  ryo 	isb
    293  1.1  ryo 	ret
    294  1.1  ryo END(aarch64_tlbi_by_asid_va_ll)
    295