[PATCH v1 6/8] score: Add AArch64 port
Kinsey Moore
kinsey.moore at oarcorp.com
Fri Sep 25 15:27:30 UTC 2020
This adds a CPU port for AArch64(ARMv8) with support for exceptions and
interrupts.
---
cpukit/include/rtems/score/tls.h | 2 +-
.../cpu/aarch64/aarch64-context-validate.S | 295 ++++++++++
.../aarch64-context-volatile-clobber.S | 90 +++
.../cpu/aarch64/aarch64-exception-default.S | 407 +++++++++++++
.../cpu/aarch64/aarch64-exception-default.c | 39 ++
.../aarch64/aarch64-exception-frame-print.c | 96 +++
.../cpu/aarch64/aarch64-exception-interrupt.S | 306 ++++++++++
.../score/cpu/aarch64/aarch64-thread-idle.c | 48 ++
cpukit/score/cpu/aarch64/cpu.c | 196 +++++++
cpukit/score/cpu/aarch64/cpu_asm.S | 134 +++++
.../cpu/aarch64/include/libcpu/vectors.h | 101 ++++
cpukit/score/cpu/aarch64/include/rtems/asm.h | 90 +++
.../cpu/aarch64/include/rtems/score/aarch64.h | 81 +++
.../cpu/aarch64/include/rtems/score/cpu.h | 548 ++++++++++++++++++
.../aarch64/include/rtems/score/cpuatomic.h | 34 ++
.../cpu/aarch64/include/rtems/score/cpuimpl.h | 81 +++
spec/build/cpukit/cpuaarch64.yml | 32 +
spec/build/cpukit/librtemscpu.yml | 2 +
18 files changed, 2581 insertions(+), 1 deletion(-)
create mode 100644 cpukit/score/cpu/aarch64/aarch64-context-validate.S
create mode 100644 cpukit/score/cpu/aarch64/aarch64-context-volatile-clobber.S
create mode 100644 cpukit/score/cpu/aarch64/aarch64-exception-default.S
create mode 100644 cpukit/score/cpu/aarch64/aarch64-exception-default.c
create mode 100644 cpukit/score/cpu/aarch64/aarch64-exception-frame-print.c
create mode 100644 cpukit/score/cpu/aarch64/aarch64-exception-interrupt.S
create mode 100644 cpukit/score/cpu/aarch64/aarch64-thread-idle.c
create mode 100644 cpukit/score/cpu/aarch64/cpu.c
create mode 100644 cpukit/score/cpu/aarch64/cpu_asm.S
create mode 100644 cpukit/score/cpu/aarch64/include/libcpu/vectors.h
create mode 100644 cpukit/score/cpu/aarch64/include/rtems/asm.h
create mode 100644 cpukit/score/cpu/aarch64/include/rtems/score/aarch64.h
create mode 100644 cpukit/score/cpu/aarch64/include/rtems/score/cpu.h
create mode 100644 cpukit/score/cpu/aarch64/include/rtems/score/cpuatomic.h
create mode 100644 cpukit/score/cpu/aarch64/include/rtems/score/cpuimpl.h
create mode 100644 spec/build/cpukit/cpuaarch64.yml
diff --git a/cpukit/include/rtems/score/tls.h b/cpukit/include/rtems/score/tls.h
index 65a49d87be..8c15eee569 100644
--- a/cpukit/include/rtems/score/tls.h
+++ b/cpukit/include/rtems/score/tls.h
@@ -85,7 +85,7 @@ typedef struct TLS_Thread_control_block {
struct TLS_Thread_control_block *tcb;
#else /* !__i386__ */
TLS_Dynamic_thread_vector *dtv;
-#if CPU_SIZEOF_POINTER == 4
+#if CPU_SIZEOF_POINTER == 4 || CPU_SIZEOF_POINTER == 8
uintptr_t reserved;
#endif
#endif /* __i386__ */
diff --git a/cpukit/score/cpu/aarch64/aarch64-context-validate.S b/cpukit/score/cpu/aarch64/aarch64-context-validate.S
new file mode 100644
index 0000000000..afd339ad85
--- /dev/null
+++ b/cpukit/score/cpu/aarch64/aarch64-context-validate.S
@@ -0,0 +1,295 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (C) 2020 On-Line Applications Research Corporation (OAR)
+ * Written by Kinsey Moore <kinsey.moore at oarcorp.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/asm.h>
+#include <rtems/score/cpu.h>
+
+#define FRAME_OFFSET_X4 0
+#define FRAME_OFFSET_X5 8
+#define FRAME_OFFSET_X6 16
+#define FRAME_OFFSET_X7 24
+#define FRAME_OFFSET_X8 32
+#define FRAME_OFFSET_X9 40
+#define FRAME_OFFSET_X10 48
+#define FRAME_OFFSET_X11 56
+#define FRAME_OFFSET_LR 64
+
+#ifdef AARCH64_MULTILIB_VFP
+ #define FRAME_OFFSET_V8 72
+ #define FRAME_OFFSET_V9 88
+ #define FRAME_OFFSET_V10 104
+ #define FRAME_OFFSET_V11 120
+ #define FRAME_OFFSET_V12 136
+ #define FRAME_OFFSET_V13 152
+ #define FRAME_OFFSET_V14 168
+ #define FRAME_OFFSET_V15 184
+
+ #define FRAME_SIZE (FRAME_OFFSET_V15 + 16)
+#else
+ #define FRAME_SIZE (FRAME_OFFSET_LR + 8)
+#endif
+
+ .section .text
+
+FUNCTION_ENTRY(_CPU_Context_validate)
+
+ /* Save */
+
+ sub sp, sp, #FRAME_SIZE
+
+ str x4, [sp, #FRAME_OFFSET_X4]
+ str x5, [sp, #FRAME_OFFSET_X5]
+ str x6, [sp, #FRAME_OFFSET_X6]
+ str x7, [sp, #FRAME_OFFSET_X7]
+ str x8, [sp, #FRAME_OFFSET_X8]
+ str x9, [sp, #FRAME_OFFSET_X9]
+ str x10, [sp, #FRAME_OFFSET_X10]
+ str x11, [sp, #FRAME_OFFSET_X11]
+ str lr, [sp, #FRAME_OFFSET_LR]
+
+#ifdef AARCH64_MULTILIB_VFP
+ str d8, [sp, #FRAME_OFFSET_V8]
+ str d9, [sp, #FRAME_OFFSET_V9]
+ str d10, [sp, #FRAME_OFFSET_V10]
+ str d11, [sp, #FRAME_OFFSET_V11]
+ str d12, [sp, #FRAME_OFFSET_V12]
+ str d13, [sp, #FRAME_OFFSET_V13]
+ str d14, [sp, #FRAME_OFFSET_V14]
+ str d15, [sp, #FRAME_OFFSET_V15]
+#endif
+
+ /* Fill */
+
+ /* R1 is used for temporary values */
+ mov x1, x0
+
+ /* R2 contains the stack pointer */
+ mov x2, sp
+
+.macro fill_register reg
+ add x1, x1, #1
+ mov \reg, x1
+.endm
+
+
+#ifdef AARCH64_MULTILIB_VFP
+ /* X3 contains the FPSCR */
+ mrs x3, FPSR
+ ldr x4, =0xf000001f
+ bic x3, x3, x4
+ and x4, x4, x0
+ orr x3, x3, x4
+ msr FPSR, x3
+#else
+ fill_register x3
+#endif
+
+ fill_register x4
+ fill_register x5
+ fill_register x6
+ fill_register x7
+ fill_register x8
+ fill_register x9
+ fill_register x10
+ fill_register x11
+ fill_register x12
+ fill_register lr
+
+#ifdef AARCH64_MULTILIB_VFP
+.macro fill_vfp_register regnum
+ add x1, x1, #1
+ fmov d\regnum\(), x1
+ fmov v\regnum\().D[1], x1
+.endm
+
+ fill_vfp_register 0
+ fill_vfp_register 1
+ fill_vfp_register 2
+ fill_vfp_register 3
+ fill_vfp_register 4
+ fill_vfp_register 5
+ fill_vfp_register 6
+ fill_vfp_register 7
+ fill_vfp_register 8
+ fill_vfp_register 9
+ fill_vfp_register 10
+ fill_vfp_register 11
+ fill_vfp_register 12
+ fill_vfp_register 13
+ fill_vfp_register 14
+ fill_vfp_register 15
+ fill_vfp_register 16
+ fill_vfp_register 17
+ fill_vfp_register 18
+ fill_vfp_register 19
+ fill_vfp_register 20
+ fill_vfp_register 21
+ fill_vfp_register 22
+ fill_vfp_register 23
+ fill_vfp_register 24
+ fill_vfp_register 25
+ fill_vfp_register 26
+ fill_vfp_register 27
+ fill_vfp_register 28
+ fill_vfp_register 29
+ fill_vfp_register 30
+ fill_vfp_register 31
+#endif /* AARCH64_MULTILIB_VFP */
+
+ /* Check */
+check:
+
+.macro check_register reg
+ add x1, x1, #1
+ cmp \reg, x1
+ bne restore
+.endm
+
+ /* A compare involving the stack pointer is deprecated */
+ mov x1, sp
+ cmp x2, x1
+ bne restore
+
+ mov x1, x0
+
+#ifndef AARCH64_MULTILIB_VFP
+ check_register x3
+#endif
+
+ check_register x4
+ check_register x5
+ check_register x6
+ check_register x7
+ check_register x8
+ check_register x9
+ check_register x10
+ check_register x11
+ check_register x12
+ check_register lr
+
+#ifdef AARCH64_MULTILIB_VFP
+ b check_vfp
+#endif
+
+ b check
+
+ /* Restore */
+restore:
+
+ ldr x4, [sp, #FRAME_OFFSET_X4]
+ ldr x5, [sp, #FRAME_OFFSET_X5]
+ ldr x6, [sp, #FRAME_OFFSET_X6]
+ ldr x7, [sp, #FRAME_OFFSET_X7]
+ ldr x8, [sp, #FRAME_OFFSET_X8]
+ ldr x9, [sp, #FRAME_OFFSET_X9]
+ ldr x10, [sp, #FRAME_OFFSET_X10]
+ ldr x11, [sp, #FRAME_OFFSET_X11]
+ ldr lr, [sp, #FRAME_OFFSET_LR]
+
+#ifdef AARCH64_MULTILIB_VFP
+ ldr d8, [sp, #FRAME_OFFSET_V8]
+ ldr d9, [sp, #FRAME_OFFSET_V9]
+ ldr d10, [sp, #FRAME_OFFSET_V10]
+ ldr d11, [sp, #FRAME_OFFSET_V11]
+ ldr d12, [sp, #FRAME_OFFSET_V12]
+ ldr d13, [sp, #FRAME_OFFSET_V13]
+ ldr d14, [sp, #FRAME_OFFSET_V14]
+ ldr d15, [sp, #FRAME_OFFSET_V15]
+#endif
+
+ add sp, sp, #FRAME_SIZE
+
+ ret
+
+FUNCTION_END(_CPU_Context_validate)
+
+#ifdef AARCH64_MULTILIB_VFP
+check_vfp:
+
+.macro check_vfp_register regnum
+ add x1, x1, #1
+ fmov x4, d\regnum
+ fmov x5, v\regnum\().D[1]
+ cmp x5, x4
+ bne 1f
+ cmp x1, x4
+ bne 1f
+ b 2f
+1:
+ b restore
+2:
+.endm
+
+ mrs x4, FPSR
+ cmp x4, x3
+ bne restore
+
+ check_vfp_register 0
+ check_vfp_register 1
+ check_vfp_register 2
+ check_vfp_register 3
+ check_vfp_register 4
+ check_vfp_register 5
+ check_vfp_register 6
+ check_vfp_register 7
+ check_vfp_register 8
+ check_vfp_register 9
+ check_vfp_register 10
+ check_vfp_register 11
+ check_vfp_register 12
+ check_vfp_register 13
+ check_vfp_register 14
+ check_vfp_register 15
+ check_vfp_register 16
+ check_vfp_register 17
+ check_vfp_register 18
+ check_vfp_register 19
+ check_vfp_register 20
+ check_vfp_register 21
+ check_vfp_register 22
+ check_vfp_register 23
+ check_vfp_register 24
+ check_vfp_register 25
+ check_vfp_register 26
+ check_vfp_register 27
+ check_vfp_register 28
+ check_vfp_register 29
+ check_vfp_register 30
+ check_vfp_register 31
+
+ /* Restore x4 and x5 */
+ mov x1, x0
+ fill_register x4
+ fill_register x5
+
+ b check
+#endif /* AARCH64_MULTILIB_VFP */
diff --git a/cpukit/score/cpu/aarch64/aarch64-context-volatile-clobber.S b/cpukit/score/cpu/aarch64/aarch64-context-volatile-clobber.S
new file mode 100644
index 0000000000..b36159c90f
--- /dev/null
+++ b/cpukit/score/cpu/aarch64/aarch64-context-volatile-clobber.S
@@ -0,0 +1,90 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (C) 2020 On-Line Applications Research Corporation (OAR)
+ * Written by Kinsey Moore <kinsey.moore at oarcorp.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/asm.h>
+
+ .section .text
+
+FUNCTION_ENTRY(_CPU_Context_volatile_clobber)
+
+.macro clobber_register reg
+ sub x0, x0, #1
+ mov \reg, x0
+.endm
+
+#ifdef AARCH64_MULTILIB_VFP
+ mrs x1, FPCR
+ ldr x2, =0xf000001f
+ bic x1, x1, x2
+ and x2, x2, x0
+ orr x1, x1, x2
+ msr FPCR, x1
+
+.macro clobber_vfp_register reg
+ sub x0, x0, #1
+ fmov \reg, x0
+.endm
+
+ clobber_vfp_register d0
+ clobber_vfp_register d1
+ clobber_vfp_register d2
+ clobber_vfp_register d3
+ clobber_vfp_register d4
+ clobber_vfp_register d5
+ clobber_vfp_register d6
+ clobber_vfp_register d7
+ clobber_vfp_register d16
+ clobber_vfp_register d17
+ clobber_vfp_register d18
+ clobber_vfp_register d19
+ clobber_vfp_register d20
+ clobber_vfp_register d21
+ clobber_vfp_register d22
+ clobber_vfp_register d23
+ clobber_vfp_register d24
+ clobber_vfp_register d25
+ clobber_vfp_register d26
+ clobber_vfp_register d27
+ clobber_vfp_register d28
+ clobber_vfp_register d29
+ clobber_vfp_register d30
+ clobber_vfp_register d31
+#endif /* AARCH64_MULTILIB_VFP */
+
+ clobber_register x1
+ clobber_register x2
+ clobber_register x3
+ clobber_register x12
+
+ ret
+
+FUNCTION_END(_CPU_Context_volatile_clobber)
diff --git a/cpukit/score/cpu/aarch64/aarch64-exception-default.S b/cpukit/score/cpu/aarch64/aarch64-exception-default.S
new file mode 100644
index 0000000000..18e068cb14
--- /dev/null
+++ b/cpukit/score/cpu/aarch64/aarch64-exception-default.S
@@ -0,0 +1,407 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (C) 2020 On-Line Applications Research Corporation (OAR)
+ * Written by Kinsey Moore <kinsey.moore at oarcorp.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/asm.h>
+
+.extern _AArch64_Exception_default
+
+.globl bsp_start_vector_table_begin
+.globl bsp_start_vector_table_end
+.globl bsp_start_vector_table_size
+.globl bsp_vector_table_size
+
+.section ".text"
+
+/*
+ * This is the exception vector table and the pointers to the default
+ * exceptions handlers.
+ */
+
+/* TODO(kmoore) The current implementation here assumes that SP is not misaligned */
+ .macro JUMP_HANDLER
+ mov x0, #0x7f /* mask to use in BIC, lower 7 bits */
+ bic x0, lr, x0 /* lr contains PC, mask off to the base of the current vector */
+ ldr x0, [x0, #0x78] /* load address from the last word in the vector */
+ blr x0 /* branch and link to address in x0, no reason to save current LR since it has already been saved and current contents are junk */
+ ldp x0, lr, [sp], #16 /* pop x0,lr from stack */
+ eret /* return from exception */
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ .endm
+
+ .macro JUMP_TARGET_SP0
+ /* takes up the space of 2 instructions */
+#ifdef AARCH64_MULTILIB_ARCH_V8_ILP32
+ .word .print_exception_dump_sp0
+ .word 0x0
+#else
+ .dword .print_exception_dump_sp0
+#endif
+ .endm
+
+ .macro JUMP_TARGET_SPx
+ /* takes up the space of 2 instructions */
+#ifdef AARCH64_MULTILIB_ARCH_V8_ILP32
+ .word .print_exception_dump_spx
+ .word 0x0
+#else
+ .dword .print_exception_dump_spx
+#endif
+ .endm
+
+bsp_start_vector_table_begin:
+.balign 0x800
+Vector_table_el3:
+curr_el_sp0_sync: // The exception handler for the synchronous exception from the current EL using SP0.
+ stp x0, lr, [sp, #-16]! /* push x0,lr on to the stack */
+ bl curr_el_sp0_sync_get_pc /* get current execution address */
+curr_el_sp0_sync_get_pc: /* current PC now in LR */
+ JUMP_HANDLER
+ JUMP_TARGET_SP0
+.balign 0x80
+curr_el_sp0_irq: // The exception handler for the IRQ exception from the current EL using SP0.
+ stp x0, lr, [sp, #-16]! /* push x0,lr on to the stack */
+ bl curr_el_sp0_irq_get_pc /* get current execution address */
+curr_el_sp0_irq_get_pc: /* current PC now in LR */
+ JUMP_HANDLER
+ JUMP_TARGET_SP0
+.balign 0x80
+curr_el_sp0_fiq: // The exception handler for the FIQ exception from the current EL using SP0.
+ stp x0, lr, [sp, #-16]! /* push x0,lr on to the stack */
+ bl curr_el_sp0_fiq_get_pc /* get current execution address */
+curr_el_sp0_fiq_get_pc: /* current PC now in LR */
+ JUMP_HANDLER
+ JUMP_TARGET_SP0
+.balign 0x80
+curr_el_sp0_serror: // The exception handler for the system error exception from the current EL using SP0.
+ stp x0, lr, [sp, #-16]! /* push x0,lr on to the stack */
+ bl curr_el_sp0_serror_get_pc /* get current execution address */
+curr_el_sp0_serror_get_pc: /* current PC now in LR */
+ JUMP_HANDLER
+ JUMP_TARGET_SP0
+.balign 0x80
+curr_el_spx_sync: // The exception handler for the synchronous exception from the current EL using the // current SP.
+ stp x0, lr, [sp, #-16]! /* push x0,lr on to the stack */
+ bl curr_el_spx_sync_get_pc /* get current execution address */
+curr_el_spx_sync_get_pc: /* current PC now in LR */
+ JUMP_HANDLER
+ JUMP_TARGET_SPx
+.balign 0x80
+curr_el_spx_irq: // The exception handler for IRQ exception from the current EL using the current SP.
+ stp x0, lr, [sp, #-16]! /* push x0,lr on to the stack */
+ bl curr_el_spx_irq_get_pc /* get current execution address */
+curr_el_spx_irq_get_pc: /* current PC now in LR */
+ JUMP_HANDLER
+ JUMP_TARGET_SPx
+.balign 0x80
+curr_el_spx_fiq: // The exception handler for the FIQ exception from the current EL using the current SP.
+ stp x0, lr, [sp, #-16]! /* push x0,lr on to the stack */
+ bl curr_el_spx_fiq_get_pc /* get current execution address */
+curr_el_spx_fiq_get_pc: /* current PC now in LR */
+ JUMP_HANDLER
+ JUMP_TARGET_SPx
+.balign 0x80
+curr_el_spx_serror: // The exception handler for the system error exception from the current EL using the // current SP.
+ stp x0, lr, [sp, #-16]! /* push x0,lr on to the stack */
+ bl curr_el_spx_serror_get_pc /* get current execution address */
+curr_el_spx_serror_get_pc: /* current PC now in LR */
+ JUMP_HANDLER
+ JUMP_TARGET_SPx
+.balign 0x80
+lower_el_aarch64_sync: // The exception handler for the synchronous exception from a lower EL (AArch64).
+ stp x0, lr, [sp, #-16]! /* push x0,lr on to the stack */
+ bl lower_el_aarch64_sync_get_pc /* get current execution address */
+lower_el_aarch64_sync_get_pc: /* current PC now in LR */
+ JUMP_HANDLER
+ JUMP_TARGET_SPx
+.balign 0x80
+lower_el_aarch64_irq: // The exception handler for the IRQ exception from a lower EL (AArch64).
+ stp x0, lr, [sp, #-16]! /* push x0,lr on to the stack */
+ bl lower_el_aarch64_irq_get_pc /* get current execution address */
+lower_el_aarch64_irq_get_pc: /* current PC now in LR */
+ JUMP_HANDLER
+ JUMP_TARGET_SPx
+.balign 0x80
+lower_el_aarch64_fiq: // The exception handler for the FIQ exception from a lower EL (AArch64).
+ stp x0, lr, [sp, #-16]! /* push x0,lr on to the stack */
+ bl lower_el_aarch64_fiq_get_pc /* get current execution address */
+lower_el_aarch64_fiq_get_pc: /* current PC now in LR */
+ JUMP_HANDLER
+ JUMP_TARGET_SPx
+.balign 0x80
+lower_el_aarch64_serror: // The exception handler for the system error exception from a lower EL(AArch64).
+ stp x0, lr, [sp, #-16]! /* push x0,lr on to the stack */
+ bl lower_el_aarch64_serror_get_pc /* get current execution address */
+lower_el_aarch64_serror_get_pc: /* current PC now in LR */
+ JUMP_HANDLER
+ JUMP_TARGET_SPx
+.balign 0x80
+lower_el_aarch32_sync: // The exception handler for the synchronous exception from a lower EL(AArch32).
+ stp x0, lr, [sp, #-16]! /* push x0,lr on to the stack */
+ bl lower_el_aarch32_sync_get_pc /* get current execution address */
+lower_el_aarch32_sync_get_pc: /* current PC now in LR */
+ JUMP_HANDLER
+ JUMP_TARGET_SPx
+.balign 0x80
+lower_el_aarch32_irq: // The exception handler for the IRQ exception from a lower EL (AArch32).
+ stp x0, lr, [sp, #-16]! /* push x0,lr on to the stack */
+ bl lower_el_aarch32_irq_get_pc /* get current execution address */
+lower_el_aarch32_irq_get_pc: /* current PC now in LR */
+ JUMP_HANDLER
+ JUMP_TARGET_SPx
+.balign 0x80
+lower_el_aarch32_fiq: // The exception handler for the FIQ exception from a lower EL (AArch32).
+ stp x0, lr, [sp, #-16]! /* push x0,lr on to the stack */
+ bl lower_el_aarch32_fiq_get_pc /* get current execution address */
+lower_el_aarch32_fiq_get_pc: /* current PC now in LR */
+ JUMP_HANDLER
+ JUMP_TARGET_SPx
+.balign 0x80
+lower_el_aarch32_serror: // The exception handler for the system error exception from a lower EL(AArch32).
+ stp x0, lr, [sp, #-16]! /* push x0,lr on to the stack */
+ bl lower_el_aarch32_serror_get_pc /* get current execution address */
+lower_el_aarch32_serror_get_pc : /* current PC now in LR */
+ JUMP_HANDLER
+ JUMP_TARGET_SPx
+
+bsp_start_vector_table_end:
+
+ .set bsp_start_vector_table_size, bsp_start_vector_table_end - bsp_start_vector_table_begin
+ .set bsp_vector_table_size, bsp_start_vector_table_size
+
+/* This involves switching a few things around. the real x0 and lr are on SPx and need to be retrieved
+ * while the lr upon entry contains the pointer into the AArch64 vector table */
+.print_exception_dump_spx:
+/* switch to exception stack (SP0) */
+ msr spsel, #0
+/* save space for exception context */
+ sub sp, sp, #AARCH64_EXCEPTION_FRAME_SIZE
+/* push exception vector, LR currently points into the actual exception vector table */
+ and lr, lr, #0x780
+ lsr lr, lr, #7
+ str lr, [sp, #AARCH64_EXCEPTION_FRAME_REGISTER_VECTOR_OFFSET]
+/* pop x0,lr from stack, saved by generic handler */
+/* this modifies the stack pointer back to the pre-vector-handler value which is safe because this will never return */
+ msr spsel, #1
+ ldp x0, lr, [sp], #16
+ msr spsel, #0
+/* save LR */
+ str lr, [sp, #AARCH64_EXCEPTION_FRAME_REGISTER_LR_OFFSET]
+/* push the start of the context */
+ bl .push_exception_context_start
+/* save original sp in x0 for .push_exception_context_finish */
+ msr spsel, #1
+ mov x0, sp
+ msr spsel, #0
+/* push the remainder of the context */
+ bl .push_exception_context_finish
+/* save sp into x0 for handler */
+ mov x0, sp
+/* jump into the handler */
+ bl _AArch64_Exception_default
+
+ /* Just in case */
+ b twiddle
+
+.print_exception_dump_sp0:
+/* save space for exception context */
+ sub sp, sp, #AARCH64_EXCEPTION_FRAME_SIZE
+/* push exception vector, LR currently points into the actual exception vector */
+ and lr, lr, #0x780
+ lsr lr, lr, #7
+ str lr, [sp, #AARCH64_EXCEPTION_FRAME_REGISTER_VECTOR_OFFSET]
+/* get x0,lr from stack, saved by generic handler */
+ add sp, sp, #AARCH64_EXCEPTION_FRAME_SIZE
+ ldp x0, lr, [sp]
+ sub sp, sp, #AARCH64_EXCEPTION_FRAME_SIZE
+/* save LR */
+ str lr, [sp, #AARCH64_EXCEPTION_FRAME_REGISTER_LR_OFFSET]
+/* push the start of the context */
+ bl .push_exception_context_start
+/* save original sp in x0 for .push_exception_context_finish */
+ add x0, sp, #(AARCH64_EXCEPTION_FRAME_SIZE + 16)
+/* push the remainder of the context */
+ bl .push_exception_context_finish
+/* save sp (exception frame) into x0 for handler */
+ mov x0, sp
+/* jump into the handler */
+ bl _AArch64_Exception_default
+
+ /* Just in case */
+twiddle:
+ b twiddle
+
+/* assumes SP is at the base of the context and LR has already been pushed */
+.push_exception_context_start:
+/* push x0-x29(fp) */
+ stp x0, x1, [sp, #0x00]
+ stp x2, x3, [sp, #0x10]
+ stp x4, x5, [sp, #0x20]
+ stp x6, x7, [sp, #0x30]
+ stp x8, x9, [sp, #0x40]
+ stp x10, x11, [sp, #0x50]
+ stp x12, x13, [sp, #0x60]
+ stp x14, x15, [sp, #0x70]
+ stp x16, x17, [sp, #0x80]
+ stp x18, x19, [sp, #0x90]
+ stp x20, x21, [sp, #0xa0]
+ stp x22, x23, [sp, #0xb0]
+ stp x24, x25, [sp, #0xc0]
+ stp x26, x27, [sp, #0xd0]
+ stp x28, x29, [sp, #0xe0]
+ ret
+
+/* Expects original SP to be stored in x0 */
+.push_exception_context_finish:
+/* get exception LR for PC */
+ mrs x1, ELR_EL1
+/* push sp and pc */
+ stp x0, x1, [sp, #AARCH64_EXCEPTION_FRAME_REGISTER_SP_OFFSET]
+/* get daif and spsr */
+ mrs x0, DAIF
+ mrs x1, SPSR_EL1
+/* push daif and spsr */
+ stp x0, x1, [sp, #AARCH64_EXCEPTION_FRAME_REGISTER_DAIF_OFFSET]
+/* get ESR and FAR */
+ mrs x0, ESR_EL1
+ mrs x1, FAR_EL1
+/* push FAR and ESR */
+ stp x0, x1, [sp, #AARCH64_EXCEPTION_FRAME_REGISTER_SYNDROME_OFFSET]
+/* get fpcr and fpsr */
+ mrs x0, FPSR
+ mrs x1, FPCR
+/* push fpcr and fpsr */
+ stp x0, x1, [sp, #AARCH64_EXCEPTION_FRAME_REGISTER_FPSR_OFFSET]
+/* push VFP registers */
+ stp q0, q1, [sp, #(AARCH64_EXCEPTION_FRAME_REGISTER_Q0_OFFSET + 0x000)]
+ stp q2, q3, [sp, #(AARCH64_EXCEPTION_FRAME_REGISTER_Q0_OFFSET + 0x020)]
+ stp q4, q5, [sp, #(AARCH64_EXCEPTION_FRAME_REGISTER_Q0_OFFSET + 0x040)]
+ stp q6, q7, [sp, #(AARCH64_EXCEPTION_FRAME_REGISTER_Q0_OFFSET + 0x060)]
+ stp q8, q9, [sp, #(AARCH64_EXCEPTION_FRAME_REGISTER_Q0_OFFSET + 0x080)]
+ stp q10, q11, [sp, #(AARCH64_EXCEPTION_FRAME_REGISTER_Q0_OFFSET + 0x0a0)]
+ stp q12, q13, [sp, #(AARCH64_EXCEPTION_FRAME_REGISTER_Q0_OFFSET + 0x0c0)]
+ stp q14, q15, [sp, #(AARCH64_EXCEPTION_FRAME_REGISTER_Q0_OFFSET + 0x0e0)]
+ stp q16, q17, [sp, #(AARCH64_EXCEPTION_FRAME_REGISTER_Q0_OFFSET + 0x100)]
+ stp q18, q19, [sp, #(AARCH64_EXCEPTION_FRAME_REGISTER_Q0_OFFSET + 0x120)]
+ stp q20, q21, [sp, #(AARCH64_EXCEPTION_FRAME_REGISTER_Q0_OFFSET + 0x140)]
+ stp q22, q23, [sp, #(AARCH64_EXCEPTION_FRAME_REGISTER_Q0_OFFSET + 0x160)]
+ stp q24, q25, [sp, #(AARCH64_EXCEPTION_FRAME_REGISTER_Q0_OFFSET + 0x180)]
+ stp q26, q27, [sp, #(AARCH64_EXCEPTION_FRAME_REGISTER_Q0_OFFSET + 0x1a0)]
+ stp q28, q29, [sp, #(AARCH64_EXCEPTION_FRAME_REGISTER_Q0_OFFSET + 0x1c0)]
+ stp q30, q31, [sp, #(AARCH64_EXCEPTION_FRAME_REGISTER_Q0_OFFSET + 0x1e0)]
+/* done, return to exception handler */
+ ret
+
+/* apply the exception frame to the current register status, SP points to the EF */
+.pop_exception_context_and_ret:
+/* pop daif and spsr */
+ ldp x2, x3, [sp, #AARCH64_EXCEPTION_FRAME_REGISTER_DAIF_OFFSET]
+/* restore daif and spsr */
+ msr DAIF, x2
+ msr SPSR_EL1, x3
+/* pop FAR and ESR */
+ ldp x2, x3, [sp, #AARCH64_EXCEPTION_FRAME_REGISTER_SYNDROME_OFFSET]
+/* restore ESR and FAR */
+ msr ESR_EL1, x2
+ msr FAR_EL1, x3
+/* pop fpcr and fpsr */
+ ldp x2, x3, [sp, #AARCH64_EXCEPTION_FRAME_REGISTER_FPSR_OFFSET]
+/* restore fpcr and fpsr */
+ msr FPSR, x2
+ msr FPCR, x3
+/* restore LR */
+ ldr lr, [sp, #AARCH64_EXCEPTION_FRAME_REGISTER_LR_OFFSET]
+/* pop VFP registers */
+ ldp q0, q1, [sp, #(AARCH64_EXCEPTION_FRAME_REGISTER_Q0_OFFSET + 0x000)]
+ ldp q2, q3, [sp, #(AARCH64_EXCEPTION_FRAME_REGISTER_Q0_OFFSET + 0x020)]
+ ldp q4, q5, [sp, #(AARCH64_EXCEPTION_FRAME_REGISTER_Q0_OFFSET + 0x040)]
+ ldp q6, q7, [sp, #(AARCH64_EXCEPTION_FRAME_REGISTER_Q0_OFFSET + 0x060)]
+ ldp q8, q9, [sp, #(AARCH64_EXCEPTION_FRAME_REGISTER_Q0_OFFSET + 0x080)]
+ ldp q10, q11, [sp, #(AARCH64_EXCEPTION_FRAME_REGISTER_Q0_OFFSET + 0x0a0)]
+ ldp q12, q13, [sp, #(AARCH64_EXCEPTION_FRAME_REGISTER_Q0_OFFSET + 0x0c0)]
+ ldp q14, q15, [sp, #(AARCH64_EXCEPTION_FRAME_REGISTER_Q0_OFFSET + 0x0e0)]
+ ldp q16, q17, [sp, #(AARCH64_EXCEPTION_FRAME_REGISTER_Q0_OFFSET + 0x100)]
+ ldp q18, q19, [sp, #(AARCH64_EXCEPTION_FRAME_REGISTER_Q0_OFFSET + 0x120)]
+ ldp q20, q21, [sp, #(AARCH64_EXCEPTION_FRAME_REGISTER_Q0_OFFSET + 0x140)]
+ ldp q22, q23, [sp, #(AARCH64_EXCEPTION_FRAME_REGISTER_Q0_OFFSET + 0x160)]
+ ldp q24, q25, [sp, #(AARCH64_EXCEPTION_FRAME_REGISTER_Q0_OFFSET + 0x180)]
+ ldp q26, q27, [sp, #(AARCH64_EXCEPTION_FRAME_REGISTER_Q0_OFFSET + 0x1a0)]
+ ldp q28, q29, [sp, #(AARCH64_EXCEPTION_FRAME_REGISTER_Q0_OFFSET + 0x1c0)]
+ ldp q30, q31, [sp, #(AARCH64_EXCEPTION_FRAME_REGISTER_Q0_OFFSET + 0x1e0)]
+/* pop x0-x29(fp) */
+ ldp x2, x3, [sp, #0x10]
+ ldp x4, x5, [sp, #0x20]
+ ldp x6, x7, [sp, #0x30]
+ ldp x8, x9, [sp, #0x40]
+ ldp x10, x11, [sp, #0x50]
+ ldp x12, x13, [sp, #0x60]
+ ldp x14, x15, [sp, #0x70]
+ ldp x16, x17, [sp, #0x80]
+ ldp x18, x19, [sp, #0x90]
+ ldp x20, x21, [sp, #0xa0]
+ ldp x22, x23, [sp, #0xb0]
+ ldp x24, x25, [sp, #0xc0]
+ ldp x26, x27, [sp, #0xd0]
+ ldp x28, x29, [sp, #0xe0]
+/* pop sp (TODO(kmoore): ignored, factor out) and ELR */
+ ldp x0, x1, [sp, #AARCH64_EXCEPTION_FRAME_REGISTER_SP_OFFSET]
+/* restore exception LR */
+ msr ELR_EL1, x1
+ ldp x0, x1, [sp, #0x00]
+ add sp, sp, #AARCH64_EXCEPTION_FRAME_SIZE
+
+ /* We must clear reservations here to ensure consistency with atomic operations */
+ clrex
+
+ ret
+
+
diff --git a/cpukit/score/cpu/aarch64/aarch64-exception-default.c b/cpukit/score/cpu/aarch64/aarch64-exception-default.c
new file mode 100644
index 0000000000..d71d2ac38c
--- /dev/null
+++ b/cpukit/score/cpu/aarch64/aarch64-exception-default.c
@@ -0,0 +1,39 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (C) 2020 On-Line Applications Research Corporation (OAR)
+ * Written by Kinsey Moore <kinsey.moore at oarcorp.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/score/cpu.h>
+#include <rtems/fatal.h>
+
+void _AArch64_Exception_default( CPU_Exception_frame *frame )
+{
+ rtems_fatal( RTEMS_FATAL_SOURCE_EXCEPTION, (rtems_fatal_code) frame );
+}
diff --git a/cpukit/score/cpu/aarch64/aarch64-exception-frame-print.c b/cpukit/score/cpu/aarch64/aarch64-exception-frame-print.c
new file mode 100644
index 0000000000..def8a4455d
--- /dev/null
+++ b/cpukit/score/cpu/aarch64/aarch64-exception-frame-print.c
@@ -0,0 +1,96 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (C) 2020 On-Line Applications Research Corporation (OAR)
+ * Written by Kinsey Moore <kinsey.moore at oarcorp.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <inttypes.h>
+
+#include <rtems/score/cpu.h>
+#include <rtems/bspIo.h>
+
+void _CPU_Exception_frame_print( const CPU_Exception_frame *frame )
+{
+ printk(
+ "\n"
+ "X0 = 0x%016" PRIx64 " X17 = 0x%016" PRIx64 "\n"
+ "X1 = 0x%016" PRIx64 " X18 = 0x%016" PRIx64 "\n"
+ "X2 = 0x%016" PRIx64 " X19 = 0x%016" PRIx64 "\n"
+ "X3 = 0x%016" PRIx64 " X20 = 0x%016" PRIx64 "\n"
+ "X4 = 0x%016" PRIx64 " X21 = 0x%016" PRIx64 "\n"
+ "X5 = 0x%016" PRIx64 " X22 = 0x%016" PRIx64 "\n"
+ "X6 = 0x%016" PRIx64 " X23 = 0x%016" PRIx64 "\n"
+ "X7 = 0x%016" PRIx64 " X24 = 0x%016" PRIx64 "\n"
+ "X8 = 0x%016" PRIx64 " X25 = 0x%016" PRIx64 "\n"
+ "X9 = 0x%016" PRIx64 " X26 = 0x%016" PRIx64 "\n"
+ "X10 = 0x%016" PRIx64 " X27 = 0x%016" PRIx64 "\n"
+ "X11 = 0x%016" PRIx64 " X28 = 0x%016" PRIx64 "\n"
+ "X12 = 0x%016" PRIx64 " FP = 0x%016" PRIx64 "\n"
+ "X13 = 0x%016" PRIx64 " LR = 0x%016" PRIxPTR "\n"
+ "X14 = 0x%016" PRIx64 " SP = 0x%016" PRIx64 "\n"
+ "X15 = 0x%016" PRIx64 " PC = 0x%016" PRIxPTR "\n"
+ "X16 = 0x%016" PRIx64 " DAIF = 0x%016" PRIx64 "\n"
+ "VEC = 0x%016" PRIxPTR " CPSR = 0x%016" PRIx64 "\n"
+ "ESR = 0x%016" PRIx64 " FAR = 0x%016" PRIx64 "\n",
+ frame->register_x0, frame->register_x17,
+ frame->register_x1, frame->register_x18,
+ frame->register_x2, frame->register_x19,
+ frame->register_x3, frame->register_x20,
+ frame->register_x4, frame->register_x21,
+ frame->register_x5, frame->register_x22,
+ frame->register_x6, frame->register_x23,
+ frame->register_x7, frame->register_x24,
+ frame->register_x8, frame->register_x25,
+ frame->register_x9, frame->register_x26,
+ frame->register_x10, frame->register_x27,
+ frame->register_x11, frame->register_x28,
+ frame->register_x12, frame->register_fp,
+ frame->register_x13, (intptr_t)frame->register_lr,
+ frame->register_x14, frame->register_sp,
+ frame->register_x15, (intptr_t)frame->register_pc,
+ frame->register_x16, frame->register_daif,
+ (intptr_t) frame->vector, frame->register_cpsr,
+ frame->register_syndrome, frame->register_fault_address
+ );
+
+ const uint128_t *qx = &frame->register_q0;
+ int i;
+
+ printk(
+ "FPCR = 0x%016" PRIx64 " FPSR = 0x%016" PRIx64 "\n",
+ frame->register_fpcr, frame->register_fpsr
+ );
+
+ for ( i = 0; i < 32; ++i ) {
+ uint64_t low = (uint64_t) qx[i];
+ uint64_t high = (uint64_t) (qx[i] >> 32);
+
+ printk( "Q%02i = 0x%016" PRIx64 "%016" PRIx64 "\n", i, high, low );
+ }
+}
diff --git a/cpukit/score/cpu/aarch64/aarch64-exception-interrupt.S b/cpukit/score/cpu/aarch64/aarch64-exception-interrupt.S
new file mode 100644
index 0000000000..6d10e6b0be
--- /dev/null
+++ b/cpukit/score/cpu/aarch64/aarch64-exception-interrupt.S
@@ -0,0 +1,306 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (C) 2020 On-Line Applications Research Corporation (OAR)
+ * Written by Kinsey Moore <kinsey.moore at oarcorp.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/asm.h>
+
+.globl _AArch64_Exception_interrupt_no_nest
+.globl _AArch64_Exception_interrupt_nest
+
+#ifdef AARCH64_MULTILIB_ARCH_V8_ILP32
+ #define SELF_CPU_CONTROL_GET_REG w19
+#else
+ #define SELF_CPU_CONTROL_GET_REG x19
+#endif
+#define SELF_CPU_CONTROL x19
+#define NON_VOLATILE_SCRATCH x20
+
+/* it's understood that CPU state is saved prior to this and restored after this */
+/* NOTE: This function does not follow the AArch64 procedure call specification
+ * because all relevant state is known to be saved in the interrupt context,
+ * hence the blind usage of x19, x20, and x21 */
+.AArch64_Interrupt_Handler:
+ /* Get per-CPU control of current processor */
+ GET_SELF_CPU_CONTROL SELF_CPU_CONTROL_GET_REG
+
+ /* Increment interrupt nest and thread dispatch disable level */
+ ldr w2, [SELF_CPU_CONTROL, #PER_CPU_ISR_NEST_LEVEL]
+ ldr w3, [SELF_CPU_CONTROL, #PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL]
+ add w2, w2, #1
+ add w3, w3, #1
+ str w2, [SELF_CPU_CONTROL, #PER_CPU_ISR_NEST_LEVEL]
+ str w3, [SELF_CPU_CONTROL, #PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL]
+
+ /* Save LR */
+ mov x21, LR
+
+ /* Call BSP dependent interrupt dispatcher */
+ bl bsp_interrupt_dispatch
+
+ /* Restore LR */
+ mov LR, x21
+
+ /* Load some per-CPU variables */
+ ldr w0, [SELF_CPU_CONTROL, #PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL]
+ ldrb w1, [SELF_CPU_CONTROL, #PER_CPU_DISPATCH_NEEDED]
+ ldr w2, [SELF_CPU_CONTROL, #PER_CPU_ISR_DISPATCH_DISABLE]
+ ldr w3, [SELF_CPU_CONTROL, #PER_CPU_ISR_NEST_LEVEL]
+
+ /* Decrement levels and determine thread dispatch state */
+ eor w1, w1, w0
+ sub w0, w0, #1
+ orr w1, w1, w0
+ orr w1, w1, w2
+ sub w3, w3, #1
+
+ /* Store thread dispatch disable and ISR nest levels */
+ str w0, [SELF_CPU_CONTROL, #PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL]
+ str w3, [SELF_CPU_CONTROL, #PER_CPU_ISR_NEST_LEVEL]
+
+ /* Return should_skip_thread_dispatch in x0 */
+ mov x0, x1
+ /* Return from handler */
+ ret
+
+/* NOTE: This function does not follow the AArch64 procedure call specification
+ * because all relevant state is known to be saved in the interrupt context,
+ * hence the blind usage of x19, x20, and x21 */
+.AArch64_Perform_Thread_Dispatch:
+ /* Get per-CPU control of current processor */
+ GET_SELF_CPU_CONTROL SELF_CPU_CONTROL_GET_REG
+
+ /* Thread dispatch */
+ mrs NON_VOLATILE_SCRATCH, DAIF
+
+.Ldo_thread_dispatch:
+
+ /* Set ISR dispatch disable and thread dispatch disable level to one */
+ mov w0, #1
+ str w0, [SELF_CPU_CONTROL, #PER_CPU_ISR_DISPATCH_DISABLE]
+ str w0, [SELF_CPU_CONTROL, #PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL]
+
+ /* Save LR */
+ mov x21, LR
+
+ /* Call _Thread_Do_dispatch(), this function will enable interrupts */
+ mov x0, SELF_CPU_CONTROL
+ mov x1, NON_VOLATILE_SCRATCH
+ mov x2, #0x80
+ bic x1, x1, x2
+ bl _Thread_Do_dispatch
+
+ /* Restore LR */
+ mov LR, x21
+
+ /* Disable interrupts */
+ msr DAIF, NON_VOLATILE_SCRATCH
+
+#ifdef RTEMS_SMP
+ GET_SELF_CPU_CONTROL SELF_CPU_CONTROL_GET_REG
+#endif
+
+ /* Check if we have to do the thread dispatch again */
+ ldrb w0, [SELF_CPU_CONTROL, #PER_CPU_DISPATCH_NEEDED]
+ cmp w0, #0
+ bne .Ldo_thread_dispatch
+
+ /* We are done with thread dispatching */
+ mov w0, #0
+ str w0, [SELF_CPU_CONTROL, #PER_CPU_ISR_DISPATCH_DISABLE]
+
+ /* Return from thread dispatch */
+ ret
+
+/* Must save corruptible registers and non-corruptible registers expected to be used,
+ * x0 and lr expected to be already saved on the stack */
+.macro push_interrupt_context
+/* push x1-x21 on to the stack, need 19-21 because they're modified without obeying PCS */
+ stp lr, x1, [sp, #-16]!
+ stp x2, x3, [sp, #-16]!
+ stp x4, x5, [sp, #-16]!
+ stp x6, x7, [sp, #-16]!
+ stp x8, x9, [sp, #-16]!
+ stp x10, x11, [sp, #-16]!
+ stp x12, x13, [sp, #-16]!
+ stp x14, x15, [sp, #-16]!
+ stp x16, x17, [sp, #-16]!
+ stp x18, x19, [sp, #-16]!
+ stp x20, x21, [sp, #-16]!
+/* push q0-q31 on to the stack, need everything because parts of every register are volatile/corruptible */
+ stp q0, q1, [sp, #-32]!
+ stp q2, q3, [sp, #-32]!
+ stp q4, q5, [sp, #-32]!
+ stp q6, q7, [sp, #-32]!
+ stp q8, q9, [sp, #-32]!
+ stp q10, q11, [sp, #-32]!
+ stp q12, q13, [sp, #-32]!
+ stp q14, q15, [sp, #-32]!
+ stp q16, q17, [sp, #-32]!
+ stp q18, q19, [sp, #-32]!
+ stp q20, q21, [sp, #-32]!
+ stp q22, q23, [sp, #-32]!
+ stp q24, q25, [sp, #-32]!
+ stp q26, q27, [sp, #-32]!
+ stp q28, q29, [sp, #-32]!
+ stp q30, q31, [sp, #-32]!
+/* get exception LR for PC and spsr */
+ mrs x0, ELR_EL1
+ mrs x1, SPSR_EL1
+/* push pc and spsr */
+ stp x0, x1, [sp, #-16]!
+/* get fpcr and fpsr */
+ mrs x0, FPSR
+ mrs x1, FPCR
+/* push fpcr and fpsr */
+ stp x0, x1, [sp, #-16]!
+.endm
+
+/* Must match inverse order of .push_interrupt_context */
+.macro pop_interrupt_context
+/* pop fpcr and fpsr */
+ ldp x0, x1, [sp], #16
+/* restore fpcr and fpsr */
+ msr FPCR, x1
+ msr FPSR, x0
+/* pop pc and spsr */
+ ldp x0, x1, [sp], #16
+/* restore exception LR for PC and spsr */
+ msr SPSR_EL1, x1
+ msr ELR_EL1, x0
+/* pop q0-q31 */
+ ldp q30, q31, [sp], #32
+ ldp q28, q29, [sp], #32
+ ldp q26, q27, [sp], #32
+ ldp q24, q25, [sp], #32
+ ldp q22, q23, [sp], #32
+ ldp q20, q21, [sp], #32
+ ldp q18, q19, [sp], #32
+ ldp q16, q17, [sp], #32
+ ldp q14, q15, [sp], #32
+ ldp q12, q13, [sp], #32
+ ldp q10, q11, [sp], #32
+ ldp q8, q9, [sp], #32
+ ldp q6, q7, [sp], #32
+ ldp q4, q5, [sp], #32
+ ldp q2, q3, [sp], #32
+ ldp q0, q1, [sp], #32
+/* pop x1-x21 */
+ ldp x20, x21, [sp], #16
+ ldp x18, x19, [sp], #16
+ ldp x16, x17, [sp], #16
+ ldp x14, x15, [sp], #16
+ ldp x12, x13, [sp], #16
+ ldp x10, x11, [sp], #16
+ ldp x8, x9, [sp], #16
+ ldp x6, x7, [sp], #16
+ ldp x4, x5, [sp], #16
+ ldp x2, x3, [sp], #16
+ ldp lr, x1, [sp], #16
+ /* Must clear reservations here to ensure consistency with atomic operations */
+ clrex
+.endm
+
+_AArch64_Exception_interrupt_nest:
+
+/* basic execution template:
+save volatile regs on interrupt stack
+execute irq handler
+restore volatile regs from interrupt stack
+eret
+*/
+
+/* push interrupt context */
+ push_interrupt_context
+
+/* jump into the handler, ignore return value */
+ bl .AArch64_Interrupt_Handler
+
+/* sp should be where it was pre-handler (pointing at the exception frame)
+ * or something has leaked stack space */
+/* pop interrupt context */
+ pop_interrupt_context
+/* return to vector for final cleanup */
+ ret
+
+_AArch64_Exception_interrupt_no_nest:
+/* RTEMS ARM impl does this:
+save volatile registers on thread stack(some x, all q, ELR, etc.)
+switch to interrupt stack
+execute interrupt handler
+switch to thread stack
+call thread dispatch
+restore volatile registers from thread stack
+eret
+
+AArch64 implementation does:
+exception handler dispatch saves x0, lr on stack
+exception handler dispatch calls actual handler
+exception handler dispatch pops x0, lr from stack
+eret
+
+actual handler:
+save volatile registers on thread stack(some x, all q, ELR, etc.)
+switch to interrupt stack
+execute interrupt handler
+switch to thread stack
+call thread dispatch
+restore volatile registers from thread stack
+ret to dispatch
+*/
+
+
+/* push interrupt context */
+ push_interrupt_context
+
+ /* Switch to interrupt stack, interrupt dispatch may enable interrupts causing nesting */
+ msr spsel, #0
+
+/* jump into the handler */
+ bl .AArch64_Interrupt_Handler
+
+ /* Switch back to thread stack, interrupt dispatch should disable interrupts before returning */
+ msr spsel, #1
+
+ /*
+ * Check thread dispatch necessary, ISR dispatch disable and thread
+ * dispatch disable level.
+ */
+ cmp x0, #0
+ bne .Lno_need_thread_dispatch
+ bl .AArch64_Perform_Thread_Dispatch
+
+.Lno_need_thread_dispatch:
+/* sp should be where it was pre-handler (pointing at the exception frame)
+ * or something has leaked stack space */
+/* pop interrupt context */
+ pop_interrupt_context
+/* return to vector for final cleanup */
+ ret
diff --git a/cpukit/score/cpu/aarch64/aarch64-thread-idle.c b/cpukit/score/cpu/aarch64/aarch64-thread-idle.c
new file mode 100644
index 0000000000..6fab7651f5
--- /dev/null
+++ b/cpukit/score/cpu/aarch64/aarch64-thread-idle.c
@@ -0,0 +1,48 @@
+/**
+ * @file
+ *
+ * @brief CPU Thread Idle Body
+ */
+
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (C) 2020 On-Line Applications Research Corporation (OAR)
+ * Written by Kinsey Moore <kinsey.moore at oarcorp.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/score/cpu.h>
+
+
+void *_CPU_Thread_Idle_body( uintptr_t ignored )
+{
+ while ( true ) {
+ __asm__ volatile ("wfi");
+ }
+}
+
diff --git a/cpukit/score/cpu/aarch64/cpu.c b/cpukit/score/cpu/aarch64/cpu.c
new file mode 100644
index 0000000000..4b7180d96c
--- /dev/null
+++ b/cpukit/score/cpu/aarch64/cpu.c
@@ -0,0 +1,196 @@
+/**
+ * @file
+ *
+ * @ingroup RTEMSScoreCPUAArch64
+ *
+ * @brief AArch64 architecture support implementation.
+ */
+
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (C) 2020 On-Line Applications Research Corporation (OAR)
+ * Written by Kinsey Moore <kinsey.moore at oarcorp.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/score/assert.h>
+#include <rtems/score/cpu.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/tls.h>
+
+#ifdef AARCH64_MULTILIB_VFP
+ RTEMS_STATIC_ASSERT(
+ offsetof( Context_Control, register_d8 ) == AARCH64_CONTEXT_CONTROL_D8_OFFSET,
+ AARCH64_CONTEXT_CONTROL_D8_OFFSET
+ );
+#endif
+
+ RTEMS_STATIC_ASSERT(
+ offsetof( Context_Control, thread_id )
+ == AARCH64_CONTEXT_CONTROL_THREAD_ID_OFFSET,
+ AARCH64_CONTEXT_CONTROL_THREAD_ID_OFFSET
+ );
+
+ RTEMS_STATIC_ASSERT(
+ offsetof( Context_Control, isr_dispatch_disable )
+ == AARCH64_CONTEXT_CONTROL_ISR_DISPATCH_DISABLE,
+ AARCH64_CONTEXT_CONTROL_ISR_DISPATCH_DISABLE
+ );
+
+#ifdef RTEMS_SMP
+ RTEMS_STATIC_ASSERT(
+ offsetof( Context_Control, is_executing )
+ == AARCH64_CONTEXT_CONTROL_IS_EXECUTING_OFFSET,
+ AARCH64_CONTEXT_CONTROL_IS_EXECUTING_OFFSET
+ );
+#endif
+
+RTEMS_STATIC_ASSERT(
+ sizeof( CPU_Exception_frame ) == AARCH64_EXCEPTION_FRAME_SIZE,
+ AARCH64_EXCEPTION_FRAME_SIZE
+);
+
+RTEMS_STATIC_ASSERT(
+ sizeof( CPU_Exception_frame ) % CPU_STACK_ALIGNMENT == 0,
+ CPU_Exception_frame_alignment
+);
+
+RTEMS_STATIC_ASSERT(
+ offsetof( CPU_Exception_frame, register_sp )
+ == AARCH64_EXCEPTION_FRAME_REGISTER_SP_OFFSET,
+ AARCH64_EXCEPTION_FRAME_REGISTER_SP_OFFSET
+);
+
+RTEMS_STATIC_ASSERT(
+ offsetof( CPU_Exception_frame, register_lr )
+ == AARCH64_EXCEPTION_FRAME_REGISTER_LR_OFFSET,
+ AARCH64_EXCEPTION_FRAME_REGISTER_LR_OFFSET
+);
+
+RTEMS_STATIC_ASSERT(
+ offsetof( CPU_Exception_frame, register_daif )
+ == AARCH64_EXCEPTION_FRAME_REGISTER_DAIF_OFFSET,
+ AARCH64_EXCEPTION_FRAME_REGISTER_DAIF_OFFSET
+);
+
+RTEMS_STATIC_ASSERT(
+ offsetof( CPU_Exception_frame, register_syndrome )
+ == AARCH64_EXCEPTION_FRAME_REGISTER_SYNDROME_OFFSET,
+ AARCH64_EXCEPTION_FRAME_REGISTER_SYNDROME_OFFSET
+);
+
+RTEMS_STATIC_ASSERT(
+ offsetof( CPU_Exception_frame, vector )
+ == AARCH64_EXCEPTION_FRAME_REGISTER_VECTOR_OFFSET,
+ AARCH64_EXCEPTION_FRAME_REGISTER_VECTOR_OFFSET
+);
+
+RTEMS_STATIC_ASSERT(
+ offsetof( CPU_Exception_frame, register_fpsr )
+ == AARCH64_EXCEPTION_FRAME_REGISTER_FPSR_OFFSET,
+ AARCH64_EXCEPTION_FRAME_REGISTER_FPSR_OFFSET
+);
+
+RTEMS_STATIC_ASSERT(
+ offsetof( CPU_Exception_frame, register_q0 )
+ == AARCH64_EXCEPTION_FRAME_REGISTER_Q0_OFFSET,
+ AARCH64_EXCEPTION_FRAME_REGISTER_Q0_OFFSET
+);
+
+
+void _CPU_Context_Initialize(
+ Context_Control *the_context,
+ void *stack_area_begin,
+ size_t stack_area_size,
+ uint64_t new_level,
+ void (*entry_point)( void ),
+ bool is_fp,
+ void *tls_area
+)
+{
+ (void) new_level;
+
+ the_context->register_sp = (uintptr_t) stack_area_begin + stack_area_size;
+ the_context->register_lr = (uintptr_t) entry_point;
+ the_context->isr_dispatch_disable = 0;
+
+ the_context->thread_id = (uintptr_t) tls_area;
+
+ if ( tls_area != NULL ) {
+ _TLS_TCB_at_area_begin_initialize( tls_area );
+ }
+}
+
+void _CPU_ISR_Set_level( uint64_t level )
+{
+ /* Set the mask bit if interrupts are disabled */
+ level = level ? AARCH64_PSTATE_I : 0;
+ __asm__ volatile (
+ "msr DAIF, %[level]\n"
+ : : [level] "r" (level)
+ );
+}
+
+uint64_t _CPU_ISR_Get_level( void )
+{
+ uint64_t level;
+
+ __asm__ volatile (
+ "mrs %[level], DAIF\n"
+ : [level] "=&r" (level)
+ );
+
+ return level & AARCH64_PSTATE_I;
+}
+
+void _CPU_ISR_install_vector(
+ uint32_t vector,
+ CPU_ISR_handler new_handler,
+ CPU_ISR_handler *old_handler
+)
+{
+ /* Redirection table starts at the end of the vector table */
+ CPU_ISR_handler *table = (CPU_ISR_handler *) (MAX_EXCEPTIONS * 4);
+
+ CPU_ISR_handler current_handler = table [vector];
+
+ /* The current handler is now the old one */
+ if (old_handler != NULL) {
+ *old_handler = current_handler;
+ }
+
+ /* Write only if necessary to avoid writes to a maybe read-only memory */
+ if (current_handler != new_handler) {
+ table [vector] = new_handler;
+ }
+}
+
+void _CPU_Initialize( void )
+{
+ /* Do nothing */
+}
diff --git a/cpukit/score/cpu/aarch64/cpu_asm.S b/cpukit/score/cpu/aarch64/cpu_asm.S
new file mode 100644
index 0000000000..9f04be7cce
--- /dev/null
+++ b/cpukit/score/cpu/aarch64/cpu_asm.S
@@ -0,0 +1,134 @@
+/**
+ * @file
+ *
+ * @ingroup RTEMSScoreCPUAArch64
+ *
+ * @brief AArch64 architecture support implementation.
+ */
+
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (C) 2020 On-Line Applications Research Corporation (OAR)
+ * Written by Kinsey Moore <kinsey.moore at oarcorp.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/asm.h>
+
+ .text
+
+/*
+ * void _CPU_Context_switch( run_context, heir_context )
+ * void _CPU_Context_restore( run_context, heir_context )
+ *
+ * This routine performs a normal non-FP context.
+ *
+ * X0 = run_context X1 = heir_context
+ *
+ * This function copies the current registers to where x0 points, then
+ * restores the ones from where x1 points.
+ *
+ */
+
+#ifdef AARCH64_MULTILIB_ARCH_V8_ILP32
+#define reg_2 w2
+#else
+#define reg_2 x2
+#endif
+
+DEFINE_FUNCTION_AARCH64(_CPU_Context_switch)
+/* Start saving context */
+ GET_SELF_CPU_CONTROL reg_2
+ ldr x3, [x2, #PER_CPU_ISR_DISPATCH_DISABLE]
+
+ stp x19, x20, [x0]
+ stp x21, x22, [x0, #0x10]
+ stp x23, x24, [x0, #0x20]
+ stp x25, x26, [x0, #0x30]
+ stp x27, x28, [x0, #0x40]
+ stp fp, lr, [x0, #0x50]
+ mov x4, sp
+ str x4, [x0, #0x60]
+
+#ifdef AARCH64_MULTILIB_VFP
+ add x5, x0, #AARCH64_CONTEXT_CONTROL_D8_OFFSET
+ stp d8, d9, [x5]
+ stp d10, d11, [x5, #16]
+ stp d12, d13, [x5, #32]
+ stp d14, d15, [x5, #48]
+#endif
+
+ str x3, [x0, #AARCH64_CONTEXT_CONTROL_ISR_DISPATCH_DISABLE]
+
+#ifdef RTEMS_SMP
+#error SMP not yet supported
+#endif
+
+/* Start restoring context */
+.L_restore:
+#if !defined(RTEMS_SMP) && defined(AARCH64_MULTILIB_HAS_LOAD_STORE_EXCLUSIVE)
+ clrex
+#endif
+
+ ldr x3, [x1, #AARCH64_CONTEXT_CONTROL_THREAD_ID_OFFSET]
+
+ ldr x4, [x1, #AARCH64_CONTEXT_CONTROL_ISR_DISPATCH_DISABLE]
+
+#ifdef AARCH64_MULTILIB_VFP
+ add x5, x1, #AARCH64_CONTEXT_CONTROL_D8_OFFSET
+ ldp d8, d9, [x5]
+ ldp d10, d11, [x5, #16]
+ ldp d12, d13, [x5, #32]
+ ldp d14, d15, [x5, #48]
+#endif
+
+ msr TPIDR_EL0, x3
+
+ str x4, [x2, #PER_CPU_ISR_DISPATCH_DISABLE]
+
+ ldp x19, x20, [x1]
+ ldp x21, x22, [x1, #0x10]
+ ldp x23, x24, [x1, #0x20]
+ ldp x25, x26, [x1, #0x30]
+ ldp x27, x28, [x1, #0x40]
+ ldp fp, lr, [x1, #0x50]
+ ldr x4, [x1, #0x60]
+ mov sp, x4
+ ret
+
+/*
+ * void _CPU_Context_restore( new_context )
+ *
+ * This function restores the registers from where x0 points.
+ * It must match _CPU_Context_switch()
+ *
+ */
+DEFINE_FUNCTION_AARCH64(_CPU_Context_restore)
+ mov x1, x0
+ GET_SELF_CPU_CONTROL reg_2
+ b .L_restore
diff --git a/cpukit/score/cpu/aarch64/include/libcpu/vectors.h b/cpukit/score/cpu/aarch64/include/libcpu/vectors.h
new file mode 100644
index 0000000000..af12efb350
--- /dev/null
+++ b/cpukit/score/cpu/aarch64/include/libcpu/vectors.h
@@ -0,0 +1,101 @@
+/**
+ * @file
+ *
+ * @ingroup RTEMSScoreCPUAArch64
+ *
+ * @brief ARM AArch64 Exception API.
+ */
+
+
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (C) 2020 On-Line Applications Research Corporation (OAR)
+ * Written by Kinsey Moore <kinsey.moore at oarcorp.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPU_AARCH64_VECTORS_H
+#define LIBCPU_AARCH64_VECTORS_H
+
+#ifndef ASM
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* VBAR, Vector Base Address Register, Security Extensions */
+
+static inline void
+*AArch64_get_vector_base_address(void)
+{
+ void *base;
+
+ __asm__ volatile (
+ "mrs %[base], VBAR_EL1\n"
+ : [base] "=&r" (base)
+ );
+
+ return base;
+}
+
+static inline void
+AArch64_set_vector_base_address(void *base)
+{
+ __asm__ volatile (
+ "msr VBAR_EL1, %[base]\n"
+ : : [base] "r" (base)
+ );
+}
+
+static inline void
+*AArch64_get_hyp_vector_base_address(void)
+{
+ void *base;
+
+ __asm__ volatile (
+ "mrs %[base], VBAR_EL2\n"
+ : [base] "=&r" (base)
+ );
+
+ return base;
+}
+
+static inline void
+AArch64_set_hyp_vector_base_address(void *base)
+{
+ __asm__ volatile (
+ "msr VBAR_EL2, %[base]\n"
+ : : [base] "r" (base)
+ );
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* ASM */
+
+#endif /* LIBCPU_AARCH64_VECTORS_H */
diff --git a/cpukit/score/cpu/aarch64/include/rtems/asm.h b/cpukit/score/cpu/aarch64/include/rtems/asm.h
new file mode 100644
index 0000000000..21111d2559
--- /dev/null
+++ b/cpukit/score/cpu/aarch64/include/rtems/asm.h
@@ -0,0 +1,90 @@
+/**
+ * @file
+ *
+ * @brief AArch64 Assembler Support API
+ *
+ * This include file attempts to address the problems
+ * caused by incompatible flavors of assemblers and
+ * toolsets. It primarily addresses variations in the
+ * use of leading underscores on symbols and the requirement
+ * that register names be preceded by a %.
+ *
+ *
+ * NOTE: The spacing in the use of these macros
+ * is critical to them working as advertised.
+ */
+
+
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (C) 2020 On-Line Applications Research Corporation (OAR)
+ * Written by Kinsey Moore <kinsey.moore at oarcorp.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTEMS_ASM_H
+#define _RTEMS_ASM_H
+
+/*
+ * Indicate we are in an assembly file and get the basic CPU definitions.
+ */
+
+#ifndef ASM
+#define ASM
+#endif
+#include <rtems/score/percpu.h>
+
+/**
+ * @defgroup RTEMSScoreCPUAArch64ASM AArch64 Assembler Support
+ *
+ * @ingroup RTEMSScoreCPUAArch64
+ *
+ * @brief AArch64 Assembler Support
+ */
+/**@{**/
+
+/*
+ * Following must be tailor for a particular flavor of the C compiler.
+ * They may need to put underscores in front of the symbols.
+ */
+
+#define FUNCTION_ENTRY(name) \
+ .align 8; \
+ .globl name; \
+ .type name, %function; \
+ name:
+
+#define FUNCTION_END(name) \
+ .size name, . - name
+
+#define DEFINE_FUNCTION_AARCH64(name) \
+ .align 8 ; .globl name ; name: ; .globl name ## _aarch64 ; name ## _aarch64:
+
+.macro GET_SELF_CPU_CONTROL REG
+ ldr \REG, =_Per_CPU_Information
+.endm
+
+/** @} */
+
+#endif /* _RTEMS_ASM_H */
diff --git a/cpukit/score/cpu/aarch64/include/rtems/score/aarch64.h b/cpukit/score/cpu/aarch64/include/rtems/score/aarch64.h
new file mode 100644
index 0000000000..6fb091f7cf
--- /dev/null
+++ b/cpukit/score/cpu/aarch64/include/rtems/score/aarch64.h
@@ -0,0 +1,81 @@
+/**
+ * @file
+ *
+ * @brief ARM AArch64 Assembler Support API
+ */
+
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (C) 2020 On-Line Applications Research Corporation (OAR)
+ * Written by Kinsey Moore <kinsey.moore at oarcorp.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTEMS_SCORE_AARCH64_H
+#define _RTEMS_SCORE_AARCH64_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup RTEMSScoreCPUAArch64
+ */
+/**@{**/
+
+#if defined(__LP64__)
+ #define CPU_MODEL_NAME "AArch64-LP64"
+ #define AARCH64_MULTILIB_ARCH_V8
+#elif defined(__ILP32__)
+ #define CPU_MODEL_NAME "AArch64-ILP32"
+ #define AARCH64_MULTILIB_ARCH_V8_ILP32
+#endif
+
+#define AARCH64_MULTILIB_HAS_WFI
+#define AARCH64_MULTILIB_HAS_LOAD_STORE_EXCLUSIVE
+#define AARCH64_MULTILIB_HAS_BARRIER_INSTRUCTIONS
+#define AARCH64_MULTILIB_HAS_CPACR
+
+#define AARCH64_MULTILIB_CACHE_LINE_MAX_64
+
+#if defined(__ARM_NEON)
+ #define AARCH64_MULTILIB_VFP
+#else
+ #error "FPU support not implemented"
+#endif
+
+
+/*
+ * Define the name of the CPU family.
+ */
+
+#define CPU_NAME "AArch64"
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTEMS_SCORE_AARCH64_H */
diff --git a/cpukit/score/cpu/aarch64/include/rtems/score/cpu.h b/cpukit/score/cpu/aarch64/include/rtems/score/cpu.h
new file mode 100644
index 0000000000..316a405a8b
--- /dev/null
+++ b/cpukit/score/cpu/aarch64/include/rtems/score/cpu.h
@@ -0,0 +1,548 @@
+/**
+ * @file
+ *
+ * @brief AArch64 Architecture Support API
+ */
+
+
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (C) 2020 On-Line Applications Research Corporation (OAR)
+ * Written by Kinsey Moore <kinsey.moore at oarcorp.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTEMS_SCORE_CPU_H
+#define _RTEMS_SCORE_CPU_H
+
+#include <rtems/score/basedefs.h>
+#if defined(RTEMS_PARAVIRT)
+#include <rtems/score/paravirt.h>
+#endif
+#include <rtems/score/aarch64.h>
+#include <libcpu/vectors.h>
+
+/**
+ * @addtogroup RTEMSScoreCPUAArch64
+ *
+ * @{
+ */
+
+/**
+ * @name Program State Registers
+ */
+/**@{**/
+
+#define AARCH64_PSTATE_N (1LL << 31)
+#define AARCH64_PSTATE_Z (1LL << 30)
+#define AARCH64_PSTATE_C (1LL << 29)
+#define AARCH64_PSTATE_V (1LL << 28)
+#define AARCH64_PSTATE_D (1LL << 9)
+#define AARCH64_PSTATE_A (1LL << 8)
+#define AARCH64_PSTATE_I (1LL << 7)
+#define AARCH64_PSTATE_F (1LL << 6)
+
+/** @} */
+
+/*
+ * AArch64 uses the PIC interrupt model.
+ */
+#define CPU_SIMPLE_VECTORED_INTERRUPTS FALSE
+
+#define CPU_ISR_PASSES_FRAME_POINTER FALSE
+
+#define CPU_HARDWARE_FP FALSE
+
+#define CPU_SOFTWARE_FP FALSE
+
+#define CPU_ALL_TASKS_ARE_FP FALSE
+
+#define CPU_IDLE_TASK_IS_FP FALSE
+
+#define CPU_USE_DEFERRED_FP_SWITCH FALSE
+
+#define CPU_ENABLE_ROBUST_THREAD_DISPATCH TRUE
+
+#define CPU_STACK_GROWS_UP FALSE
+
+#if defined(AARCH64_MULTILIB_CACHE_LINE_MAX_64)
+ #define CPU_CACHE_LINE_BYTES 64
+#else
+ #define CPU_CACHE_LINE_BYTES 32
+#endif
+
+#define CPU_STRUCTURE_ALIGNMENT RTEMS_ALIGNED( CPU_CACHE_LINE_BYTES )
+
+#define CPU_MODES_INTERRUPT_MASK 0x1
+
+#define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 0
+
+#define CPU_PROVIDES_ISR_IS_IN_PROGRESS FALSE
+
+#define CPU_STACK_MINIMUM_SIZE (1024 * 10)
+
+/* This could be either 4 or 8, depending on the ABI in use.
+ * Could also use __LP64__ or __ILP32__ */
+/* AAPCS64, section 5.1, Fundamental Data Types */
+#define CPU_SIZEOF_POINTER __SIZEOF_POINTER__
+
+/* AAPCS64, section 5.1, Fundamental Data Types */
+#define CPU_ALIGNMENT 16
+
+#define CPU_HEAP_ALIGNMENT CPU_ALIGNMENT
+
+/* AAPCS64, section 6.2.2, Stack constraints at a public interface */
+#define CPU_STACK_ALIGNMENT 16
+
+#define CPU_INTERRUPT_STACK_ALIGNMENT CPU_CACHE_LINE_BYTES
+
+#define CPU_USE_GENERIC_BITFIELD_CODE TRUE
+
+#define CPU_USE_LIBC_INIT_FINI_ARRAY TRUE
+
+#define CPU_MAXIMUM_PROCESSORS 32
+
+#define AARCH64_CONTEXT_CONTROL_THREAD_ID_OFFSET 112
+
+#ifdef AARCH64_MULTILIB_VFP
+ #define AARCH64_CONTEXT_CONTROL_D8_OFFSET 120
+#endif
+
+#define AARCH64_CONTEXT_CONTROL_ISR_DISPATCH_DISABLE 104
+
+#ifdef RTEMS_SMP
+ #if defined(AARCH64_MULTILIB_VFP)
+ #define AARCH64_CONTEXT_CONTROL_IS_EXECUTING_OFFSET 112
+ #else
+ #define AARCH64_CONTEXT_CONTROL_IS_EXECUTING_OFFSET 48
+ #endif
+#endif
+
+#define AARCH64_EXCEPTION_FRAME_SIZE 848
+
+#define AARCH64_EXCEPTION_FRAME_REGISTER_SP_OFFSET 248
+#define AARCH64_EXCEPTION_FRAME_REGISTER_LR_OFFSET 240
+#define AARCH64_EXCEPTION_FRAME_REGISTER_DAIF_OFFSET 264
+#define AARCH64_EXCEPTION_FRAME_REGISTER_SYNDROME_OFFSET 280
+#define AARCH64_EXCEPTION_FRAME_REGISTER_VECTOR_OFFSET 296
+#define AARCH64_EXCEPTION_FRAME_REGISTER_FPSR_OFFSET 312
+#define AARCH64_EXCEPTION_FRAME_REGISTER_Q0_OFFSET 336
+
+#ifndef ASM
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef unsigned __int128 uint128_t;
+
+typedef struct {
+ uint64_t register_x19;
+ uint64_t register_x20;
+ uint64_t register_x21;
+ uint64_t register_x22;
+ uint64_t register_x23;
+ uint64_t register_x24;
+ uint64_t register_x25;
+ uint64_t register_x26;
+ uint64_t register_x27;
+ uint64_t register_x28;
+ uint64_t register_fp;
+ uint64_t register_lr;
+ uint64_t register_sp;
+ uint64_t isr_dispatch_disable;
+ uint64_t thread_id;
+#ifdef AARCH64_MULTILIB_VFP
+ uint64_t register_d8;
+ uint64_t register_d9;
+ uint64_t register_d10;
+ uint64_t register_d11;
+ uint64_t register_d12;
+ uint64_t register_d13;
+ uint64_t register_d14;
+ uint64_t register_d15;
+#endif
+#ifdef RTEMS_SMP
+ volatile bool is_executing;
+#endif
+} Context_Control;
+
+static inline void _AARCH64_Data_memory_barrier( void )
+{
+ __asm__ volatile ( "dmb LD" : : : "memory" );
+}
+
+static inline void _AARCH64_Data_synchronization_barrier( void )
+{
+ __asm__ volatile ( "dsb LD" : : : "memory" );
+}
+
+static inline void _AARCH64_Instruction_synchronization_barrier( void )
+{
+ __asm__ volatile ( "isb" : : : "memory" );
+}
+
+void _CPU_ISR_Set_level( uint64_t level );
+
+uint64_t _CPU_ISR_Get_level( void );
+
+#if defined(AARCH64_DISABLE_INLINE_ISR_DISABLE_ENABLE)
+uint64_t AArch64_interrupt_disable( void );
+void AArch64_interrupt_enable( uint64_t level );
+void AArch64_interrupt_flash( uint64_t level );
+#else
+static inline uint64_t AArch64_interrupt_disable( void )
+{
+ uint64_t level = _CPU_ISR_Get_level();
+ __asm__ volatile (
+ "msr DAIFSet, #0x2\n"
+ );
+ return level;
+}
+
+static inline void AArch64_interrupt_enable( uint64_t level )
+{
+ __asm__ volatile (
+ "msr DAIF, %[level]\n"
+ : : [level] "r" (level)
+ );
+}
+
+static inline void AArch64_interrupt_flash( uint64_t level )
+{
+ AArch64_interrupt_enable(level);
+ AArch64_interrupt_disable();
+}
+#endif /* !AARCH64_DISABLE_INLINE_ISR_DISABLE_ENABLE */
+
+#define _CPU_ISR_Disable( _isr_cookie ) \
+ do { \
+ _isr_cookie = AArch64_interrupt_disable(); \
+ } while (0)
+
+#define _CPU_ISR_Enable( _isr_cookie ) \
+ AArch64_interrupt_enable( _isr_cookie )
+
+#define _CPU_ISR_Flash( _isr_cookie ) \
+ AArch64_interrupt_flash( _isr_cookie )
+
+RTEMS_INLINE_ROUTINE bool _CPU_ISR_Is_enabled( uint64_t level )
+{
+ return ( level & AARCH64_PSTATE_I ) == 0;
+}
+
+void _CPU_Context_Initialize(
+ Context_Control *the_context,
+ void *stack_area_begin,
+ size_t stack_area_size,
+ uint64_t new_level,
+ void (*entry_point)( void ),
+ bool is_fp,
+ void *tls_area
+);
+
+#define _CPU_Context_Get_SP( _context ) \
+ (_context)->register_sp
+
+#ifdef RTEMS_SMP
+ static inline bool _CPU_Context_Get_is_executing(
+ const Context_Control *context
+ )
+ {
+ return context->is_executing;
+ }
+
+ static inline void _CPU_Context_Set_is_executing(
+ Context_Control *context,
+ bool is_executing
+ )
+ {
+ context->is_executing = is_executing;
+ }
+#endif
+
+#define _CPU_Context_Restart_self( _the_context ) \
+ _CPU_Context_restore( (_the_context) );
+
+#define _CPU_Context_Initialize_fp( _destination ) \
+ do { \
+ *(*(_destination)) = _CPU_Null_fp_context; \
+ } while (0)
+
+#define _CPU_Fatal_halt( _source, _err ) \
+ do { \
+ uint64_t _level; \
+ uint32_t _error = _err; \
+ _CPU_ISR_Disable( _level ); \
+ (void) _level; \
+ __asm__ volatile ("mov x0, %0\n" \
+ : "=r" (_error) \
+ : "0" (_error) \
+ : "x0" ); \
+ while (1); \
+ } while (0);
+
+/**
+ * @brief CPU initialization.
+ */
+void _CPU_Initialize( void );
+
+typedef void ( *CPU_ISR_handler )( void );
+
+void _CPU_ISR_install_vector(
+ uint32_t vector,
+ CPU_ISR_handler new_handler,
+ CPU_ISR_handler *old_handler
+);
+
+/**
+ * @brief CPU switch context.
+ */
+void _CPU_Context_switch( Context_Control *run, Context_Control *heir );
+
+void _CPU_Context_restore( Context_Control *new_context )
+ RTEMS_NO_RETURN;
+
+#ifdef RTEMS_SMP
+ uint32_t _CPU_SMP_Initialize( void );
+
+ bool _CPU_SMP_Start_processor( uint32_t cpu_index );
+
+ void _CPU_SMP_Finalize_initialization( uint32_t cpu_count );
+
+ void _CPU_SMP_Prepare_start_multitasking( void );
+
+ static inline uint32_t _CPU_SMP_Get_current_processor( void )
+ {
+ uint32_t mpidr;
+
+ __asm__ volatile (
+ "mrs %[mpidr], mpidr_el1\n"
+ : [mpidr] "=&r" (mpidr)
+ );
+
+ return mpidr & 0xffU;
+ }
+
+ void _CPU_SMP_Send_interrupt( uint32_t target_processor_index );
+
+ static inline void _AARCH64_Send_event( void )
+ {
+ __asm__ volatile ( "sev" : : : "memory" );
+ }
+
+ static inline void _AARCH64_Wait_for_event( void )
+ {
+ __asm__ volatile ( "wfe" : : : "memory" );
+ }
+
+ static inline void _CPU_SMP_Processor_event_broadcast( void )
+ {
+ _AARCH64_Data_synchronization_barrier();
+ _AARCH64_Send_event();
+ }
+
+ static inline void _CPU_SMP_Processor_event_receive( void )
+ {
+ _AARCH64_Wait_for_event();
+ _AARCH64_Data_memory_barrier();
+ }
+#endif
+
+
+static inline uint32_t CPU_swap_u32( uint32_t value )
+{
+ uint32_t tmp = value; /* make compiler warnings go away */
+ __asm__ volatile ("EOR %1, %0, %0, ROR #16\n"
+ "BIC %1, %1, #0xff0000\n"
+ "MOV %0, %0, ROR #8\n"
+ "EOR %0, %0, %1, LSR #8\n"
+ : "=r" (value), "=r" (tmp)
+ : "0" (value), "1" (tmp));
+ return value;
+}
+
+static inline uint16_t CPU_swap_u16( uint16_t value )
+{
+ return (uint16_t) (((value & 0xffU) << 8) | ((value >> 8) & 0xffU));
+}
+
+typedef uint32_t CPU_Counter_ticks;
+
+uint32_t _CPU_Counter_frequency( void );
+
+CPU_Counter_ticks _CPU_Counter_read( void );
+
+static inline CPU_Counter_ticks _CPU_Counter_difference(
+ CPU_Counter_ticks second,
+ CPU_Counter_ticks first
+)
+{
+ return second - first;
+}
+
+void *_CPU_Thread_Idle_body( uintptr_t ignored );
+
+typedef enum {
+ AARCH64_EXCEPTION_SP0_SYNCHRONOUS = 0,
+ AARCH64_EXCEPTION_SP0_IRQ = 1,
+ AARCH64_EXCEPTION_SP0_FIQ = 2,
+ AARCH64_EXCEPTION_SP0_SERROR = 3,
+ AARCH64_EXCEPTION_SPx_SYNCHRONOUS = 4,
+ AARCH64_EXCEPTION_SPx_IRQ = 5,
+ AARCH64_EXCEPTION_SPx_FIQ = 6,
+ AARCH64_EXCEPTION_SPx_SERROR = 7,
+ AARCH64_EXCEPTION_LEL64_SYNCHRONOUS = 8,
+ AARCH64_EXCEPTION_LEL64_IRQ = 9,
+ AARCH64_EXCEPTION_LEL64_FIQ = 10,
+ AARCH64_EXCEPTION_LEL64_SERROR = 11,
+ AARCH64_EXCEPTION_LEL32_SYNCHRONOUS = 12,
+ AARCH64_EXCEPTION_LEL32_IRQ = 13,
+ AARCH64_EXCEPTION_LEL32_FIQ = 14,
+ AARCH64_EXCEPTION_LEL32_SERROR = 15,
+ MAX_EXCEPTIONS = 16,
+ AARCH64_EXCEPTION_MAKE_ENUM_64_BIT = 0xffffffffffffffff
+} AArch64_symbolic_exception_name;
+
+#define VECTOR_POINTER_OFFSET 0x78
+#define VECTOR_ENTRY_SIZE 0x80
+void _AArch64_Exception_interrupt_no_nest( void );
+void _AArch64_Exception_interrupt_nest( void );
+static inline void* AArch64_set_exception_handler(
+ AArch64_symbolic_exception_name exception,
+ void (*handler)(void)
+)
+{
+ // get current table address
+ char *vbar = (char*)AArch64_get_vector_base_address();
+ // calculate address of vector to be replaced
+ char *cvector_address = vbar + VECTOR_ENTRY_SIZE * exception + VECTOR_POINTER_OFFSET;
+ // get current vector pointer
+ void (**vector_address)(void) = (void(**)(void))cvector_address;
+ void (*current_vector_pointer)(void);
+ current_vector_pointer = *vector_address;
+ // replace vector pointer
+ *vector_address = handler;
+ // return now-previous vector pointer
+ return (void*)current_vector_pointer;
+}
+
+typedef struct {
+ uint64_t register_x0;
+ uint64_t register_x1;
+ uint64_t register_x2;
+ uint64_t register_x3;
+ uint64_t register_x4;
+ uint64_t register_x5;
+ uint64_t register_x6;
+ uint64_t register_x7;
+ uint64_t register_x8;
+ uint64_t register_x9;
+ uint64_t register_x10;
+ uint64_t register_x11;
+ uint64_t register_x12;
+ uint64_t register_x13;
+ uint64_t register_x14;
+ uint64_t register_x15;
+ uint64_t register_x16;
+ uint64_t register_x17;
+ uint64_t register_x18;
+ uint64_t register_x19;
+ uint64_t register_x20;
+ uint64_t register_x21;
+ uint64_t register_x22;
+ uint64_t register_x23;
+ uint64_t register_x24;
+ uint64_t register_x25;
+ uint64_t register_x26;
+ uint64_t register_x27;
+ uint64_t register_x28;
+ uint64_t register_fp;
+ void *register_lr;
+#ifdef AARCH64_MULTILIB_ARCH_V8_ILP32
+ uint32_t _register_lr_top;
+#endif
+ uint64_t register_sp;
+ void *register_pc;
+#ifdef AARCH64_MULTILIB_ARCH_V8_ILP32
+ uint32_t _register_pc_top;
+#endif
+ uint64_t register_daif;
+ uint64_t register_cpsr;
+ uint64_t register_syndrome;
+ uint64_t register_fault_address;
+ AArch64_symbolic_exception_name vector;
+ uint64_t reserved_for_stack_alignment;
+ uint64_t register_fpsr;
+ uint64_t register_fpcr;
+ uint128_t register_q0;
+ uint128_t register_q1;
+ uint128_t register_q2;
+ uint128_t register_q3;
+ uint128_t register_q4;
+ uint128_t register_q5;
+ uint128_t register_q6;
+ uint128_t register_q7;
+ uint128_t register_q8;
+ uint128_t register_q9;
+ uint128_t register_q10;
+ uint128_t register_q11;
+ uint128_t register_q12;
+ uint128_t register_q13;
+ uint128_t register_q14;
+ uint128_t register_q15;
+ uint128_t register_q16;
+ uint128_t register_q17;
+ uint128_t register_q18;
+ uint128_t register_q19;
+ uint128_t register_q20;
+ uint128_t register_q21;
+ uint128_t register_q22;
+ uint128_t register_q23;
+ uint128_t register_q24;
+ uint128_t register_q25;
+ uint128_t register_q26;
+ uint128_t register_q27;
+ uint128_t register_q28;
+ uint128_t register_q29;
+ uint128_t register_q30;
+ uint128_t register_q31;
+} CPU_Exception_frame;
+
+void _CPU_Exception_frame_print( const CPU_Exception_frame *frame );
+
+void _AArch64_Exception_default( CPU_Exception_frame *frame );
+
+/** Type that can store a 32-bit integer or a pointer. */
+typedef uintptr_t CPU_Uint32ptr;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ASM */
+
+/** @} */
+
+#endif /* _RTEMS_SCORE_CPU_H */
diff --git a/cpukit/score/cpu/aarch64/include/rtems/score/cpuatomic.h b/cpukit/score/cpu/aarch64/include/rtems/score/cpuatomic.h
new file mode 100644
index 0000000000..ca9fc0c707
--- /dev/null
+++ b/cpukit/score/cpu/aarch64/include/rtems/score/cpuatomic.h
@@ -0,0 +1,34 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (C) 2020 On-Line Applications Research Corporation (OAR)
+ * Written by Kinsey Moore <kinsey.moore at oarcorp.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTEMS_SCORE_ATOMIC_CPU_H
+#define _RTEMS_SCORE_ATOMIC_CPU_H
+
+#include <rtems/score/cpustdatomic.h>
+
+#endif /* _RTEMS_SCORE_ATOMIC_CPU_H */
diff --git a/cpukit/score/cpu/aarch64/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/aarch64/include/rtems/score/cpuimpl.h
new file mode 100644
index 0000000000..de741440df
--- /dev/null
+++ b/cpukit/score/cpu/aarch64/include/rtems/score/cpuimpl.h
@@ -0,0 +1,81 @@
+/**
+ * @file
+ *
+ * @brief CPU Port Implementation API
+ */
+
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (C) 2020 On-Line Applications Research Corporation (OAR)
+ * Written by Kinsey Moore <kinsey.moore at oarcorp.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTEMS_SCORE_CPUIMPL_H
+#define _RTEMS_SCORE_CPUIMPL_H
+
+#include <rtems/score/cpu.h>
+
+/**
+ * @defgroup RTEMSScoreCPUAArch64 AArch64
+ *
+ * @ingroup RTEMSScoreCPU
+ *
+ * @brief ARM AArch64 Architecture Support
+ *
+ * @{
+ */
+
+#define CPU_PER_CPU_CONTROL_SIZE 0
+#define CPU_INTERRUPT_FRAME_SIZE 240
+
+#ifndef ASM
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void _CPU_Context_volatile_clobber( uintptr_t pattern );
+
+void _CPU_Context_validate( uintptr_t pattern );
+
+RTEMS_INLINE_ROUTINE void _CPU_Instruction_illegal( void )
+{
+ __asm__ volatile ( ".inst 0x0" );
+}
+
+RTEMS_INLINE_ROUTINE void _CPU_Instruction_no_operation( void )
+{
+ __asm__ volatile ( "nop" );
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ASM */
+
+/** @} */
+
+#endif /* _RTEMS_SCORE_CPUIMPL_H */
diff --git a/spec/build/cpukit/cpuaarch64.yml b/spec/build/cpukit/cpuaarch64.yml
new file mode 100644
index 0000000000..ae10055f8b
--- /dev/null
+++ b/spec/build/cpukit/cpuaarch64.yml
@@ -0,0 +1,32 @@
+build-type: objects
+cflags: []
+cppflags: []
+cxxflags: []
+enabled-by:
+- aarch64
+includes: []
+install:
+- destination: ${BSP_INCLUDEDIR}/libcpu
+ source:
+ - cpukit/score/cpu/arm/include/libcpu/vectors.h
+- destination: ${BSP_INCLUDEDIR}/rtems
+ source:
+ - cpukit/score/cpu/aarch64/include/rtems/asm.h
+- destination: ${BSP_INCLUDEDIR}/rtems/score
+ source:
+ - cpukit/score/cpu/aarch64/include/rtems/score/cpu.h
+ - cpukit/score/cpu/aarch64/include/rtems/score/cpuatomic.h
+ - cpukit/score/cpu/aarch64/include/rtems/score/cpuimpl.h
+ - cpukit/score/cpu/aarch64/include/rtems/score/aarch64.h
+links: []
+source:
+- cpukit/score/cpu/aarch64/cpu.c
+- cpukit/score/cpu/aarch64/cpu_asm.S
+- cpukit/score/cpu/aarch64/aarch64-context-validate.S
+- cpukit/score/cpu/aarch64/aarch64-context-volatile-clobber.S
+- cpukit/score/cpu/aarch64/aarch64-thread-idle.c
+- cpukit/score/cpu/aarch64/aarch64-exception-default.c
+- cpukit/score/cpu/aarch64/aarch64-exception-default.S
+- cpukit/score/cpu/aarch64/aarch64-exception-interrupt.S
+- cpukit/score/cpu/aarch64/aarch64-exception-frame-print.c
+type: build
diff --git a/spec/build/cpukit/librtemscpu.yml b/spec/build/cpukit/librtemscpu.yml
index e3606dbdc8..f835cecb45 100644
--- a/spec/build/cpukit/librtemscpu.yml
+++ b/spec/build/cpukit/librtemscpu.yml
@@ -456,6 +456,8 @@ install:
- cpukit/include/uuid/uuid.h
install-path: ${BSP_LIBDIR}
links:
+- role: build-dependency
+ uid: cpuaarch64
- role: build-dependency
uid: cpuarm
- role: build-dependency
--
2.20.1
More information about the devel
mailing list