1 /*
2  * Copyright (c) 2013-2014 Wind River Systems, Inc.
3  * Copyright 2024 Arm Limited and/or its affiliates <open-source-office@arm.com>
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 /**
9  * @file
10  * @brief ARM Cortex-A and Cortex-R System Control Block interface
11  */
12 
13 #include <zephyr/kernel.h>
14 #include <zephyr/arch/cpu.h>
15 #include <zephyr/sys/util.h>
16 #include <zephyr/linker/linker-defs.h>
17 
18 #if defined(CONFIG_AARCH32_ARMV8_R)
19 
20 #define VECTOR_ADDRESS ((uintptr_t)_vector_start)
21 
relocate_vector_table(void)22 static inline void relocate_vector_table(void)
23 {
24 	write_sctlr(read_sctlr() & ~HIVECS);
25 	write_vbar(VECTOR_ADDRESS & VBAR_MASK);
26 	barrier_isync_fence_full();
27 }
28 
29 #else
30 
31 #if defined(__GNUC__)
32 /*
33  * GCC can detect if memcpy is passed a NULL argument, however one of
34  * the cases of relocate_vector_table() it is valid to pass NULL, so we
35  * suppress the warning for this case.  We need to do this before
36  * string.h is included to get the declaration of memcpy.
37  */
38 #pragma GCC diagnostic push
39 #pragma GCC diagnostic ignored "-Wnonnull"
40 #endif /* __GNUC__ */
41 
42 #include <string.h>
43 
44 #define VECTOR_ADDRESS 0
45 
relocate_vector_table(void)46 void __weak relocate_vector_table(void)
47 {
48 #if defined(CONFIG_XIP) && (CONFIG_FLASH_BASE_ADDRESS != 0) ||                                     \
49 	!defined(CONFIG_XIP) && (CONFIG_SRAM_BASE_ADDRESS != 0)
50 	write_sctlr(read_sctlr() & ~HIVECS);
51 	size_t vector_size = (size_t)_vector_end - (size_t)_vector_start;
52 	(void)memcpy(VECTOR_ADDRESS, _vector_start, vector_size);
53 #endif
54 }
55 
56 #if defined(__GNUC__)
57 #pragma GCC diagnostic pop
58 #endif
59 
60 #endif /* !CONFIG_AARCH32_ARMV8_R */
61 
z_arm_relocate_vector_table(void)62 void z_arm_relocate_vector_table(void)
63 {
64 	relocate_vector_table();
65 }
66 
67 /**
68  *
69  * @brief Reset the system
70  *
71  * This routine resets the processor.
72  *
73  */
74 
sys_arch_reboot(int type)75 void __weak sys_arch_reboot(int type)
76 {
77 	ARG_UNUSED(type);
78 }
79