VirtualBox

source: vbox/trunk/include/iprt/asm-arm.h@ 93176

Last change on this file since 93176 was 93115, checked in by vboxsync, 3 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.0 KB
Line 
1/** @file
2 * IPRT - ARM Specific Assembly Functions.
3 */
4
5/*
6 * Copyright (C) 2015-2022 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26#ifndef IPRT_INCLUDED_asm_arm_h
27#define IPRT_INCLUDED_asm_arm_h
28#ifndef RT_WITHOUT_PRAGMA_ONCE
29# pragma once
30#endif
31
32#include <iprt/types.h>
33#if !defined(RT_ARCH_ARM64) && !defined(RT_ARCH_ARM32)
34# error "Not on ARM64 or ARM32"
35#endif
36
37/** @defgroup grp_rt_asm_arm ARM Specific ASM Routines
38 * @ingroup grp_rt_asm
39 * @{
40 */
41
42
43#if 0 /* figure out arm64 */
44
45/**
46 * Get the CPSR (Current Program Status) register.
47 * @returns CPSR.
48 */
49#if RT_INLINE_ASM_EXTERNAL
50DECLASM(RTCCUINTREG) ASMGetFlags(void);
51#else
52DECLINLINE(RTCCUINTREG) ASMGetFlags(void)
53{
54 RTCCUINTREG uFlags;
55# if RT_INLINE_ASM_GNU_STYLE
56# ifdef RT_ARCH_ARM64
57 __asm__ __volatile__("mrs %0, nzcv\n\t" : "=r" (uFlags));
58# else
59 __asm__ __volatile__("mrs %0, cpsr\n\t" : "=r" (uFlags));
60# endif
61# else
62# error "Unsupported compiler"
63# endif
64 return uFlags;
65}
66#endif
67
68
69/**
70 * Set the CPSR register.
71 * @param uFlags The new CPSR value.
72 */
73#if RT_INLINE_ASM_EXTERNAL
74DECLASM(void) ASMSetFlags(RTCCUINTREG uFlags);
75#else
76DECLINLINE(void) ASMSetFlags(RTCCUINTREG uFlags)
77{
78# if RT_INLINE_ASM_GNU_STYLE
79 __asm__ __volatile__("msr cpsr_c, %0\n\t"
80 : : "r" (uFlags));
81# else
82# error "Unsupported compiler"
83# endif
84}
85#endif
86
87#endif
88
89
90/**
91 * Gets the content of the CNTVCT_EL0 (or CNTPCT) register.
92 *
93 * @returns CNTVCT_EL0 value.
94 * @note We call this TSC to better fit in with existing x86/amd64 based code.
95 */
96#if RT_INLINE_ASM_EXTERNAL
97DECLASM(uint64_t) ASMReadTSC(void);
98#else
99DECLINLINE(uint64_t) ASMReadTSC(void)
100{
101# if RT_INLINE_ASM_GNU_STYLE
102 uint64_t u64;
103# ifdef RT_ARCH_ARM64
104 __asm__ __volatile__("isb\n\t"
105 "mrs %0, CNTVCT_EL0\n\t"
106 : "=r" (u64));
107# else
108 uint32_t u32Spill;
109 uint32_t u32Comp;
110 __asm__ __volatile__("isb\n"
111 "Lagain:\n\t"
112 "mrrc p15, 0, %[uSpill], %H[uRet], c14\n\t" /* CNTPCT high into uRet.hi */
113 "mrrc p15, 0, %[uRet], %[uSpill], c14\n\t" /* CNTPCT low into uRet.lo */
114 "mrrc p15, 0, %[uSpill], %[uHiComp], c14\n\t" /* CNTPCT high into uHiComp */
115 "cmp %H[uRet], %[uHiComp]\n\t"
116 "b.eq Lagain\n\t" /* Redo if high value changed. */
117 : [uRet] "=r" (u64)
118 , "=r" (uHiComp)
119 , "=r" (uSpill));
120# endif
121 return u64;
122
123# else
124# error "Unsupported compiler"
125# endif
126}
127#endif
128
129#if 0 /* port to arm64, armv7 and check */
130
131/**
132 * Enables interrupts (IRQ and FIQ).
133 */
134#if RT_INLINE_ASM_EXTERNAL
135DECLASM(void) ASMIntEnable(void);
136#else
137DECLINLINE(void) ASMIntEnable(void)
138{
139 RTCCUINTREG uFlags;
140# if RT_INLINE_ASM_GNU_STYLE
141 __asm__ __volatile__("mrs %0, cpsr\n\t"
142 "bic %0, %0, #0xc0\n\t"
143 "msr cpsr_c, %0\n\t"
144 : "=r" (uFlags));
145# else
146# error "Unsupported compiler"
147# endif
148}
149#endif
150
151
152/**
153 * Disables interrupts (IRQ and FIQ).
154 */
155#if RT_INLINE_ASM_EXTERNAL
156DECLASM(void) ASMIntDisable(void);
157#else
158DECLINLINE(void) ASMIntDisable(void)
159{
160 RTCCUINTREG uFlags;
161# if RT_INLINE_ASM_GNU_STYLE
162 __asm__ __volatile__("mrs %0, cpsr\n\t"
163 "orr %0, %0, #0xc0\n\t"
164 "msr cpsr_c, %0\n\t"
165 : "=r" (uFlags));
166# else
167# error "Unsupported compiler"
168# endif
169}
170#endif
171
172
173/**
174 * Disables interrupts and returns previous uFLAGS.
175 */
176#if RT_INLINE_ASM_EXTERNAL
177DECLASM(RTCCUINTREG) ASMIntDisableFlags(void);
178#else
179DECLINLINE(RTCCUINTREG) ASMIntDisableFlags(void)
180{
181 RTCCUINTREG uFlags;
182# if RT_INLINE_ASM_GNU_STYLE
183 RTCCUINTREG uNewFlags;
184 __asm__ __volatile__("mrs %0, cpsr\n\t"
185 "orr %1, %0, #0xc0\n\t"
186 "msr cpsr_c, %1\n\t"
187 : "=r" (uFlags)
188 , "=r" (uNewFlags));
189# else
190# error "Unsupported compiler"
191# endif
192 return uFlags;
193}
194#endif
195
196
197/**
198 * Are interrupts enabled?
199 *
200 * @returns true / false.
201 */
202DECLINLINE(bool) ASMIntAreEnabled(void)
203{
204/** @todo r=bird: reversed, but does both need to be enabled? */
205 return ASMGetFlags() & 0xc0 /* IRQ and FIQ bits */ ? true : false;
206}
207
208#endif
209
210/**
211 * Halts the CPU until interrupted.
212 */
213#if RT_INLINE_ASM_EXTERNAL
214DECLASM(void) ASMHalt(void);
215#else
216DECLINLINE(void) ASMHalt(void)
217{
218# if RT_INLINE_ASM_GNU_STYLE
219 __asm__ __volatile__ ("wfi\n\t"); /* wait for interrupt */
220# else
221# error "Unsupported compiler"
222# endif
223}
224#endif
225
226#if 0
227/**
228 * Gets the CPU ID of the current CPU.
229 *
230 * @returns the CPU ID.
231 * @note the name of this method is a bit misleading but serves the purpose
232 * and prevents #ifdef orgies in other places.
233 */
234#if RT_INLINE_ASM_EXTERNAL
235DECLASM(uint8_t) ASMGetApicId(void);
236#else
237DECLINLINE(uint8_t) ASMGetApicId(void)
238{
239# if RT_INLINE_ASM_GNU_STYLE
240 RTCCUINTREG uCpuId;
241 __asm__ ("mrc p15, 0, %0, c0, c0, 5\n\t" /* CPU ID Register, privileged */
242 : "=r" (uCpuId));
243 return uCpuId;
244# else
245# error "Unsupported compiler"
246# endif
247}
248#endif
249#endif
250
251#if 0
252
253/**
254 * Invalidate page.
255 *
256 * @param pv Address of the page to invalidate.
257 */
258#if RT_INLINE_ASM_EXTERNAL
259DECLASM(void) ASMInvalidatePage(void *pv);
260#else
261DECLINLINE(void) ASMInvalidatePage(void *pv)
262{
263# if RT_INLINE_ASM_GNU_STYLE
264
265# else
266# error "Unsupported compiler"
267# endif
268}
269#endif
270
271
272/**
273 * Write back the internal caches and invalidate them.
274 */
275#if RT_INLINE_ASM_EXTERNAL
276DECLASM(void) ASMWriteBackAndInvalidateCaches(void);
277#else
278DECLINLINE(void) ASMWriteBackAndInvalidateCaches(void)
279{
280# if RT_INLINE_ASM_GNU_STYLE
281
282# else
283# error "Unsupported compiler"
284# endif
285}
286#endif
287
288
289/**
290 * Invalidate internal and (perhaps) external caches without first
291 * flushing dirty cache lines. Use with extreme care.
292 */
293#if RT_INLINE_ASM_EXTERNAL
294DECLASM(void) ASMInvalidateInternalCaches(void);
295#else
296DECLINLINE(void) ASMInvalidateInternalCaches(void)
297{
298# if RT_INLINE_ASM_GNU_STYLE
299
300# else
301# error "Unsupported compiler"
302# endif
303}
304#endif
305
306#endif
307
308
309/** @} */
310#endif /* !IPRT_INCLUDED_asm_arm_h */
311
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette