summaryrefslogtreecommitdiffstats
path: root/bsps/aarch64
diff options
context:
space:
mode:
Diffstat (limited to 'bsps/aarch64')
-rw-r--r--bsps/aarch64/include/bsp/aarch64-mmu.h165
-rw-r--r--bsps/aarch64/include/bsp/linker-symbols.h4
-rw-r--r--bsps/aarch64/include/bsp/start.h2
-rw-r--r--bsps/aarch64/include/dev/irq/arm-gic-arch.h29
-rw-r--r--bsps/aarch64/raspberrypi/console/console.c69
-rw-r--r--bsps/aarch64/raspberrypi/include/bsp.h76
-rw-r--r--bsps/aarch64/raspberrypi/include/bsp/irq.h85
-rw-r--r--bsps/aarch64/raspberrypi/include/bsp/raspberrypi.h480
-rw-r--r--bsps/aarch64/raspberrypi/include/tm27.h46
-rw-r--r--bsps/aarch64/raspberrypi/start/bspstart.c49
-rw-r--r--bsps/aarch64/raspberrypi/start/bspstarthooks.c53
-rw-r--r--bsps/aarch64/raspberrypi/start/bspstartmmu.c84
-rw-r--r--bsps/aarch64/shared/cache/cache.c64
-rw-r--r--bsps/aarch64/shared/mmu/vmsav8-64-nommu.c49
-rw-r--r--bsps/aarch64/shared/mmu/vmsav8-64.c81
-rw-r--r--bsps/aarch64/shared/start/aarch64-smp.c85
-rw-r--r--bsps/aarch64/shared/start/linkcmds.base11
-rw-r--r--bsps/aarch64/shared/start/start.S143
-rw-r--r--bsps/aarch64/xilinx-versal/dev/serial/versal-uart-polled.c37
-rw-r--r--bsps/aarch64/xilinx-versal/dev/serial/versal-uart.c323
-rw-r--r--bsps/aarch64/xilinx-versal/include/bsp.h13
-rw-r--r--bsps/aarch64/xilinx-versal/include/bsp/i2c.h64
-rw-r--r--bsps/aarch64/xilinx-versal/include/bsp/irq.h2
-rw-r--r--bsps/aarch64/xilinx-versal/include/dev/serial/versal-uart-regs.h1
-rw-r--r--bsps/aarch64/xilinx-versal/include/dev/serial/versal-uart.h4
-rw-r--r--bsps/aarch64/xilinx-versal/start/bspstart.c12
-rw-r--r--bsps/aarch64/xilinx-versal/start/bspstarthooks.c3
-rw-r--r--bsps/aarch64/xilinx-versal/start/bspstartmmu.c60
-rw-r--r--bsps/aarch64/xilinx-zynqmp/console/console.c210
-rw-r--r--bsps/aarch64/xilinx-zynqmp/fdt/bsp_fdt.c51
-rw-r--r--bsps/aarch64/xilinx-zynqmp/fdt/cfc400x.dts114
-rw-r--r--bsps/aarch64/xilinx-zynqmp/fdt/cfc400x_dtb.c130
-rw-r--r--bsps/aarch64/xilinx-zynqmp/fdt/zynqmp.dts98
-rw-r--r--bsps/aarch64/xilinx-zynqmp/fdt/zynqmp_dtb.c105
-rw-r--r--bsps/aarch64/xilinx-zynqmp/include/bsp.h30
-rw-r--r--bsps/aarch64/xilinx-zynqmp/include/bsp/i2c.h2
-rw-r--r--bsps/aarch64/xilinx-zynqmp/include/bsp/irq.h7
-rw-r--r--bsps/aarch64/xilinx-zynqmp/include/bsp/jffs2_xnandpsu.h56
-rw-r--r--bsps/aarch64/xilinx-zynqmp/include/bsp/jffs2_xqspipsu.h62
-rw-r--r--bsps/aarch64/xilinx-zynqmp/jffs2_xnandpsu.c375
-rw-r--r--bsps/aarch64/xilinx-zynqmp/jffs2_xqspipsu.c186
-rw-r--r--bsps/aarch64/xilinx-zynqmp/start/bspstarthooks.c42
-rw-r--r--bsps/aarch64/xilinx-zynqmp/start/bspstartmmu.c33
43 files changed, 3299 insertions, 296 deletions
diff --git a/bsps/aarch64/include/bsp/aarch64-mmu.h b/bsps/aarch64/include/bsp/aarch64-mmu.h
index e82012576f..8c69705230 100644
--- a/bsps/aarch64/include/bsp/aarch64-mmu.h
+++ b/bsps/aarch64/include/bsp/aarch64-mmu.h
@@ -37,54 +37,20 @@
#ifndef LIBBSP_AARCH64_SHARED_AARCH64_MMU_H
#define LIBBSP_AARCH64_SHARED_AARCH64_MMU_H
-#include <bsp/start.h>
+#include <bsp/fatal.h>
#include <bsp/linker-symbols.h>
-#include <rtems/score/aarch64-system-registers.h>
-#include <bspopts.h>
+#include <bsp/start.h>
#include <bsp/utility.h>
+#include <bspopts.h>
+#include <libcpu/mmu-vmsav8-64.h>
+#include <rtems/score/aarch64-system-registers.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
-/* VMSAv8 Long-descriptor fields */
-#define MMU_DESC_AF BSP_BIT64( 10 )
-#define MMU_DESC_SH_INNER ( BSP_BIT64( 9 ) | BSP_BIT64( 8 ) )
-#define MMU_DESC_WRITE_DISABLE BSP_BIT64( 7 )
-/* PAGE and TABLE flags are the same bit, but only apply on certain levels */
-#define MMU_DESC_TYPE_TABLE BSP_BIT64( 1 )
-#define MMU_DESC_TYPE_PAGE BSP_BIT64( 1 )
-#define MMU_DESC_VALID BSP_BIT64( 0 )
-#define MMU_DESC_MAIR_ATTR( val ) BSP_FLD64( val, 2, 3 )
-#define MMU_DESC_MAIR_ATTR_GET( reg ) BSP_FLD64GET( reg, 2, 3 )
-#define MMU_DESC_MAIR_ATTR_SET( reg, val ) BSP_FLD64SET( reg, val, 2, 3 )
-#define MMU_DESC_PAGE_TABLE_MASK 0xFFFFFFFFF000LL
-
-/* Page table configuration */
-#define MMU_PAGE_BITS 12
-#define MMU_PAGE_SIZE ( 1 << MMU_PAGE_BITS )
-#define MMU_BITS_PER_LEVEL 9
-#define MMU_TOP_LEVEL_PAGE_BITS ( 2 * MMU_BITS_PER_LEVEL + MMU_PAGE_BITS )
-
-#define AARCH64_MMU_FLAGS_BASE \
- ( MMU_DESC_VALID | MMU_DESC_SH_INNER | MMU_DESC_AF )
-
-#define AARCH64_MMU_DATA_RO_CACHED \
- ( AARCH64_MMU_FLAGS_BASE | MMU_DESC_MAIR_ATTR( 3 ) | MMU_DESC_WRITE_DISABLE )
-#define AARCH64_MMU_CODE_CACHED AARCH64_MMU_DATA_RO_CACHED
-#define AARCH64_MMU_CODE_RW_CACHED AARCH64_MMU_DATA_RW_CACHED
-
-#define AARCH64_MMU_DATA_RO \
- ( AARCH64_MMU_FLAGS_BASE | MMU_DESC_MAIR_ATTR( 1 ) | MMU_DESC_WRITE_DISABLE )
-#define AARCH64_MMU_CODE AARCH64_MMU_DATA_RO
-#define AARCH64_MMU_CODE_RW AARCH64_MMU_DATA_RW
-
-/* RW implied by not ORing in RO */
-#define AARCH64_MMU_DATA_RW_CACHED \
- ( AARCH64_MMU_FLAGS_BASE | MMU_DESC_MAIR_ATTR( 3 ) )
-#define AARCH64_MMU_DATA_RW \
- ( AARCH64_MMU_FLAGS_BASE | MMU_DESC_MAIR_ATTR( 1 ) )
-#define AARCH64_MMU_DEVICE ( AARCH64_MMU_FLAGS_BASE | MMU_DESC_MAIR_ATTR( 0 ) )
+/* AArch64 uses levels 0, 1, 2, and 3 */
+#define MMU_MAX_SUBTABLE_PAGE_BITS ( 3 * MMU_BITS_PER_LEVEL + MMU_PAGE_BITS )
typedef struct {
uintptr_t begin;
@@ -130,6 +96,10 @@ typedef struct {
.end = (uintptr_t) bsp_section_rtemsstack_end, \
.flags = AARCH64_MMU_DATA_RW_CACHED \
}, { \
+ .begin = (uintptr_t) bsp_section_noinit_begin, \
+ .end = (uintptr_t) bsp_section_noinit_end, \
+ .flags = AARCH64_MMU_DATA_RW_CACHED \
+ }, { \
.begin = (uintptr_t) bsp_section_work_begin, \
.end = (uintptr_t) bsp_section_work_end, \
.flags = AARCH64_MMU_DATA_RW_CACHED \
@@ -183,8 +153,8 @@ BSP_START_TEXT_SECTION static inline rtems_status_code
aarch64_mmu_page_table_alloc( uint64_t **page_table )
{
/* First page table is already in use as TTB0 */
- static uintptr_t *current_page_table =
- (uintptr_t *) bsp_translation_table_base;
+ static uintptr_t current_page_table =
+ (uintptr_t) bsp_translation_table_base;
current_page_table += MMU_PAGE_SIZE;
*page_table = (uint64_t *) current_page_table;
@@ -250,15 +220,15 @@ aarch64_mmu_get_sub_table(
BSP_START_TEXT_SECTION static inline rtems_status_code aarch64_mmu_map_block(
uint64_t *page_table,
- uintptr_t root_address,
- uintptr_t addr,
+ uint64_t root_address,
+ uint64_t addr,
uint64_t size,
- uint32_t level,
+ int8_t level,
uint64_t flags
)
{
uint32_t shift = ( 2 - level ) * MMU_BITS_PER_LEVEL + MMU_PAGE_BITS;
- uintptr_t granularity = 1 << shift;
+ uint64_t granularity = 1LLU << shift;
uint64_t page_flag = 0;
if ( level == 2 ) {
@@ -267,23 +237,35 @@ BSP_START_TEXT_SECTION static inline rtems_status_code aarch64_mmu_map_block(
while ( size > 0 ) {
uintptr_t index = aarch64_mmu_get_index( root_address, addr, shift );
- uintptr_t block_bottom = RTEMS_ALIGN_DOWN( addr, granularity );
+ uint64_t block_bottom = RTEMS_ALIGN_DOWN( addr, granularity );
uint64_t chunk_size = granularity;
/* check for perfect block match */
if ( block_bottom == addr ) {
if ( size >= chunk_size ) {
- /* when page_flag is set the last level must be a page descriptor */
- if ( page_flag || ( page_table[index] & MMU_DESC_TYPE_TABLE ) != MMU_DESC_TYPE_TABLE ) {
+ /* level -1 can't contain block descriptors, fall through to subtable */
+ if ( level != -1 ) {
+ /* when page_flag is set the last level must be a page descriptor */
+ if ( page_flag || ( page_table[index] & MMU_DESC_TYPE_TABLE ) != MMU_DESC_TYPE_TABLE ) {
+ /* no sub-table, apply block properties */
+ page_table[index] = addr | flags | page_flag;
+ size -= chunk_size;
+ addr += chunk_size;
+ continue;
+ }
+ }
+ } else {
+ /* block starts on a boundary, but is short */
+ chunk_size = size;
+
+ /* it isn't possible to go beyond page table level 2 */
+ if ( page_flag ) {
/* no sub-table, apply block properties */
page_table[index] = addr | flags | page_flag;
size -= chunk_size;
addr += chunk_size;
continue;
}
- } else {
- /* block starts on a boundary, but is short */
- chunk_size = size;
}
} else {
uintptr_t block_top = RTEMS_ALIGN_UP( addr, granularity );
@@ -295,7 +277,7 @@ BSP_START_TEXT_SECTION static inline rtems_status_code aarch64_mmu_map_block(
}
/* Deal with any subtable modification */
- uintptr_t new_root_address = root_address + index * granularity;
+ uint64_t new_root_address = root_address + index * granularity;
uint64_t *sub_table = NULL;
rtems_status_code sc;
@@ -336,6 +318,33 @@ BSP_START_DATA_SECTION extern const aarch64_mmu_config_entry
BSP_START_DATA_SECTION extern const size_t
aarch64_mmu_config_table_size;
+/* Get the maximum number of bits supported by this hardware */
+BSP_START_TEXT_SECTION static inline uint64_t
+aarch64_mmu_get_cpu_pa_bits( void )
+{
+ uint64_t id_reg = _AArch64_Read_id_aa64mmfr0_el1();
+
+ switch ( AARCH64_ID_AA64MMFR0_EL1_PARANGE_GET( id_reg ) ) {
+ case 0:
+ return 32;
+ case 1:
+ return 36;
+ case 2:
+ return 40;
+ case 3:
+ return 42;
+ case 4:
+ return 44;
+ case 5:
+ return 48;
+ case 6:
+ return 52;
+ default:
+ return 48;
+ }
+ return 48;
+}
+
BSP_START_TEXT_SECTION static inline void
aarch64_mmu_set_translation_table_entries(
uint64_t *ttb,
@@ -345,14 +354,19 @@ aarch64_mmu_set_translation_table_entries(
/* Force alignemnt to 4k page size */
uintptr_t begin = RTEMS_ALIGN_DOWN( config->begin, MMU_PAGE_SIZE );
uintptr_t end = RTEMS_ALIGN_UP( config->end, MMU_PAGE_SIZE );
+ uint64_t max_mappable = 1LLU << aarch64_mmu_get_cpu_pa_bits();
rtems_status_code sc;
+ if ( begin >= max_mappable || end > max_mappable ) {
+ bsp_fatal( BSP_FATAL_MMU_ADDRESS_INVALID );
+ }
+
sc = aarch64_mmu_map_block(
ttb,
0x0,
begin,
end - begin,
- 0,
+ -1,
config->flags
);
@@ -372,7 +386,7 @@ BSP_START_TEXT_SECTION static inline void aarch64_mmu_setup_translation_table(
aarch64_mmu_page_table_set_blocks(
ttb,
(uintptr_t) NULL,
- MMU_TOP_LEVEL_PAGE_BITS,
+ MMU_MAX_SUBTABLE_PAGE_BITS,
0
);
@@ -385,17 +399,15 @@ BSP_START_TEXT_SECTION static inline void aarch64_mmu_setup_translation_table(
}
BSP_START_TEXT_SECTION static inline void
-aarch64_mmu_setup_translation_table_and_enable(
- const aarch64_mmu_config_entry *config_table,
- size_t config_count
-)
+aarch64_mmu_enable( void )
{
uint64_t sctlr;
- aarch64_mmu_setup_translation_table(
- config_table,
- config_count
- );
+ /* CPUECTLR_EL1.SMPEN is already set on ZynqMP and is not writable */
+
+ /* Flush and invalidate cache */
+ rtems_cache_flush_entire_data();
+ rtems_cache_invalidate_entire_data();
/* Enable MMU and cache */
sctlr = _AArch64_Read_sctlr_el1();
@@ -403,13 +415,32 @@ aarch64_mmu_setup_translation_table_and_enable(
_AArch64_Write_sctlr_el1( sctlr );
}
+BSP_START_TEXT_SECTION static inline void
+aarch64_mmu_disable( void )
+{
+ uint64_t sctlr;
+
+ /*
+ * Flush data cache before disabling the MMU. While the MMU is disabled, all
+ * accesses are treated as uncached device memory.
+ */
+ rtems_cache_flush_entire_data();
+
+ /* Disable MMU */
+ sctlr = _AArch64_Read_sctlr_el1();
+ sctlr &= ~(AARCH64_SCTLR_EL1_M);
+ _AArch64_Write_sctlr_el1( sctlr );
+}
+
BSP_START_TEXT_SECTION static inline void aarch64_mmu_setup( void )
{
/* Set TCR */
- /* 128GB/36 bits mappable (64-0x1c) */
+ /* 256TB/48 bits mappable (64-0x10) */
_AArch64_Write_tcr_el1(
- AARCH64_TCR_EL1_T0SZ( 0x1c ) | AARCH64_TCR_EL1_IRGN0( 0x1 ) |
- AARCH64_TCR_EL1_ORGN0( 0x1 ) | AARCH64_TCR_EL1_SH0( 0x3 ) | AARCH64_TCR_EL1_TG0( 0x0 )
+ AARCH64_TCR_EL1_T0SZ( 0x10 ) | AARCH64_TCR_EL1_IRGN0( 0x1 ) |
+ AARCH64_TCR_EL1_ORGN0( 0x1 ) | AARCH64_TCR_EL1_SH0( 0x3 ) |
+ AARCH64_TCR_EL1_TG0( 0x0 ) | AARCH64_TCR_EL1_IPS( 0x5ULL ) |
+ AARCH64_TCR_EL1_EPD1
);
/* Set MAIR */
diff --git a/bsps/aarch64/include/bsp/linker-symbols.h b/bsps/aarch64/include/bsp/linker-symbols.h
index 38c655ba97..222c217abb 100644
--- a/bsps/aarch64/include/bsp/linker-symbols.h
+++ b/bsps/aarch64/include/bsp/linker-symbols.h
@@ -108,6 +108,10 @@ LINKER_SYMBOL(bsp_section_rtemsstack_begin)
LINKER_SYMBOL(bsp_section_rtemsstack_end)
LINKER_SYMBOL(bsp_section_rtemsstack_size)
+LINKER_SYMBOL(bsp_section_noinit_begin)
+LINKER_SYMBOL(bsp_section_noinit_end)
+LINKER_SYMBOL(bsp_section_noinit_size)
+
LINKER_SYMBOL(bsp_section_work_begin)
LINKER_SYMBOL(bsp_section_work_end)
LINKER_SYMBOL(bsp_section_work_size)
diff --git a/bsps/aarch64/include/bsp/start.h b/bsps/aarch64/include/bsp/start.h
index 586eec4f48..f0af5be841 100644
--- a/bsps/aarch64/include/bsp/start.h
+++ b/bsps/aarch64/include/bsp/start.h
@@ -172,7 +172,7 @@ AArch64_start_set_vector_base(void)
/*
* Do not use bsp_vector_table_begin == 0, since this will get optimized away.
*/
- if (bsp_vector_table_end != bsp_vector_table_size) {
+ if (&bsp_vector_table_end[0] != &bsp_vector_table_size[0]) {
__asm__ volatile (
"msr VBAR_EL1, %[vtable]\n"
: : [vtable] "r" (bsp_start_vector_table_begin)
diff --git a/bsps/aarch64/include/dev/irq/arm-gic-arch.h b/bsps/aarch64/include/dev/irq/arm-gic-arch.h
index 0911320851..5ca2c7314e 100644
--- a/bsps/aarch64/include/dev/irq/arm-gic-arch.h
+++ b/bsps/aarch64/include/dev/irq/arm-gic-arch.h
@@ -3,9 +3,10 @@
/**
* @file
*
- * @ingroup RTEMSBSPsAArch64Shared
+ * @ingroup DevIRQGIC
*
- * @brief AArch64-specific ARM GICv3 handlers.
+ * @brief This header file provides interfaces of the ARM Generic Interrupt
+ * Controller (GIC) support specific to the AArch64 architecture.
*/
/*
@@ -46,12 +47,24 @@
extern "C" {
#endif
-static inline void arm_interrupt_handler_dispatch(rtems_vector_number vector)
+/**
+ * @addtogroup DevIRQGIC
+ *
+ * @{
+ */
+
+static inline uint32_t arm_interrupt_enable_interrupts(void)
{
- uint32_t interrupt_level = _CPU_ISR_Get_level();
- AArch64_interrupt_enable(1);
- bsp_interrupt_handler_dispatch(vector);
- _CPU_ISR_Set_level(interrupt_level);
+ uint32_t status = _CPU_ISR_Get_level();
+ /* Enable interrupts for nesting */
+ _CPU_ISR_Set_level(0);
+ return status;
+}
+
+static inline void arm_interrupt_restore_interrupts(uint32_t status)
+{
+ /* Restore interrupts to previous level */
+ _CPU_ISR_Set_level(status);
}
static inline void arm_interrupt_facility_set_exception_handler(void)
@@ -66,6 +79,8 @@ static inline void arm_interrupt_facility_set_exception_handler(void)
);
}
+/** @} */
+
#ifdef __cplusplus
}
#endif
diff --git a/bsps/aarch64/raspberrypi/console/console.c b/bsps/aarch64/raspberrypi/console/console.c
new file mode 100644
index 0000000000..73bb0036ff
--- /dev/null
+++ b/bsps/aarch64/raspberrypi/console/console.c
@@ -0,0 +1,69 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSBSPsAArch64Raspberrypi4
+ *
+ * @brief Console Configuration
+ */
+
+/*
+ * Copyright (C) 2022 Mohd Noor Aman
+ *
+ *
+ * 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.
+ */
+
+#include <rtems/bspIo.h>
+
+#include <bsp.h>
+#include <dev/serial/arm-pl011.h>
+#include <bsp/console-termios.h>
+
+#include <bspopts.h>
+
+arm_pl011_context raspberrypi_4_context = {
+ .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("PL011"),
+ .regs = (volatile pl011 *) BSP_RPI4_PL011_BASE,
+ .initial_baud = 115200
+};
+
+const console_device console_device_table[] = {
+ {
+ .device_file = "/dev/ttyS0",
+ .probe = console_device_probe_default,
+ .handler = &arm_pl011_fns,
+ .context = &raspberrypi_4_context.base
+ }
+};
+
+const size_t console_device_count = RTEMS_ARRAY_SIZE(console_device_table);
+
+static void output_char( char c )
+{
+ arm_pl011_write_polled(&raspberrypi_4_context.base, c);
+}
+
+BSP_output_char_function_type BSP_output_char = output_char;
+
+BSP_polling_getchar_function_type BSP_poll_char = NULL;
diff --git a/bsps/aarch64/raspberrypi/include/bsp.h b/bsps/aarch64/raspberrypi/include/bsp.h
new file mode 100644
index 0000000000..4fa81edd40
--- /dev/null
+++ b/bsps/aarch64/raspberrypi/include/bsp.h
@@ -0,0 +1,76 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSBSPsAArch64Raspberrypi4
+ *
+ * @brief Core BSP definitions
+ */
+
+/*
+ * Copyright (C) 2022 Mohd Noor Aman
+ *
+ *
+ * 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 LIBBSP_AARCH64_RASPBERRYPI_4_BSP_H
+#define LIBBSP_AARCH64_RASPBERRYPI_4_BSP_H
+
+/**
+ * @addtogroup RTEMSBSPsAArch64
+ *
+ * @{
+ */
+
+#include <bspopts.h>
+
+#ifndef ASM
+
+#include <bsp/default-initial-extension.h>
+#include <bsp/start.h>
+
+#include <rtems.h>
+
+/*Raspberry pi MMU initialization */
+BSP_START_TEXT_SECTION void raspberrypi_4_setup_mmu_and_cache(void);
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define BSP_ARM_GIC_CPUIF_BASE 0xFF842000
+#define BSP_ARM_GIC_DIST_BASE 0xFF841000
+
+#define BSP_RPI4_PL011_BASE 0xFE201000
+#define BSP_RPI4_PL011_LENGTH 0x200
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* ASM */
+
+/** @} */
+
+#endif /* LIBBSP_AARCH64_RASPBERRYPI_4_BSP_H */
diff --git a/bsps/aarch64/raspberrypi/include/bsp/irq.h b/bsps/aarch64/raspberrypi/include/bsp/irq.h
new file mode 100644
index 0000000000..d493e83707
--- /dev/null
+++ b/bsps/aarch64/raspberrypi/include/bsp/irq.h
@@ -0,0 +1,85 @@
+/**
+ * @file
+ *
+ * @ingroup raspberrypi_interrupt
+ *
+ * @brief Interrupt definitions.
+ */
+
+/**
+ * Copyright (c) 2013 Alan Cudmore
+ * Copyright (c) 2022 Mohd Noor Aman
+ * Copyright (c) 2024 Ning Yang
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ *
+ * http://www.rtems.org/license/LICENSE
+ *
+ */
+
+#ifndef LIBBSP_ARM_RASPBERRYPI_IRQ_H
+#define LIBBSP_ARM_RASPBERRYPI_IRQ_H
+
+#ifndef ASM
+
+#include <rtems.h>
+#include <dev/irq/arm-gic-irq.h>
+
+/**
+ * @defgroup raspberrypi_interrupt Interrrupt Support
+ *
+ * @ingroup RTEMSBSPsARMRaspberryPi
+ *
+ * @brief Interrupt support.
+ */
+
+#define BCM2835_INTC_TOTAL_IRQ 216
+
+#define BCM2835_IRQ_SET1_MIN 0
+#define BCM2835_IRQ_SET2_MIN 32
+
+#define BCM2711_IRQ_VC_PERIPHERAL_BASE 96
+
+/* Interrupt Vectors: System Timer */
+#define BCM2835_IRQ_ID_GPU_TIMER_M0 (BCM2711_IRQ_VC_PERIPHERAL_BASE + 0)
+#define BCM2835_IRQ_ID_GPU_TIMER_M1 (BCM2711_IRQ_VC_PERIPHERAL_BASE + 1)
+#define BCM2835_IRQ_ID_GPU_TIMER_M2 (BCM2711_IRQ_VC_PERIPHERAL_BASE + 2)
+#define BCM2835_IRQ_ID_GPU_TIMER_M3 (BCM2711_IRQ_VC_PERIPHERAL_BASE + 3)
+
+#define BCM2835_IRQ_ID_USB 9
+#define BCM2835_IRQ_ID_AUX 29
+#define BCM2835_IRQ_ID_SPI_SLAVE 43
+#define BCM2835_IRQ_ID_PWA0 45
+#define BCM2835_IRQ_ID_PWA1 46
+#define BCM2835_IRQ_ID_SMI 48
+#define BCM2835_IRQ_ID_GPIO_0 49
+#define BCM2835_IRQ_ID_GPIO_1 50
+#define BCM2835_IRQ_ID_GPIO_2 51
+#define BCM2835_IRQ_ID_GPIO_3 52
+#define BCM2835_IRQ_ID_I2C 53
+#define BCM2835_IRQ_ID_SPI 54
+#define BCM2835_IRQ_ID_PCM 55
+#define BCM2835_IRQ_ID_UART 57
+#define BCM2835_IRQ_ID_SD 62
+
+#define BCM2835_IRQ_ID_BASIC_BASE_ID 64
+#define BCM2835_IRQ_ID_TIMER_0 64
+#define BCM2835_IRQ_ID_MAILBOX_0 65
+#define BCM2835_IRQ_ID_DOORBELL_0 66
+#define BCM2835_IRQ_ID_DOORBELL_1 67
+#define BCM2835_IRQ_ID_GPU0_HALTED 68
+#define BCM2835_IRQ_ID_GPU1_HALTED 69
+#define BCM2835_IRQ_ID_ILL_ACCESS_1 70
+#define BCM2835_IRQ_ID_ILL_ACCESS_0 71
+#define BSP_TIMER_VIRT_PPI 27
+#define BSP_TIMER_PHYS_NS_PPI 30
+#define BSP_VPL011_SPI 32
+
+#define BSP_INTERRUPT_VECTOR_COUNT BCM2835_INTC_TOTAL_IRQ
+#define BSP_INTERRUPT_VECTOR_INVALID (UINT32_MAX)
+
+#define BSP_IRQ_COUNT (BCM2835_INTC_TOTAL_IRQ)
+
+#endif /* ASM */
+#endif /* LIBBSP_ARM_RASPBERRYPI_IRQ_H */
diff --git a/bsps/aarch64/raspberrypi/include/bsp/raspberrypi.h b/bsps/aarch64/raspberrypi/include/bsp/raspberrypi.h
new file mode 100644
index 0000000000..f185d1df57
--- /dev/null
+++ b/bsps/aarch64/raspberrypi/include/bsp/raspberrypi.h
@@ -0,0 +1,480 @@
+/**
+ * @file
+ *
+ * @ingroup raspberrypi_4_regs
+ *
+ * @brief Register definitions.
+ */
+
+/*
+ * Copyright (c) 2022 Mohd Noor Aman
+ * Copyright (c) 2024 Ning Yang
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ *
+ * http://www.rtems.org/license/LICENSE
+ *
+ */
+
+
+#ifndef LIBBSP_AARCH64_RASPBERRYPI_RASPBERRYPI_4_H
+#define LIBBSP_AARCH64_RASPBERRYPI_RASPBERRYPI_4_H
+
+
+#include <bspopts.h>
+#include <stdint.h>
+#include <bsp/utility.h>
+
+
+/**
+ * @defgroup raspberrypi_reg Register Definitions
+ *
+ * @ingroup RTEMSBSPsARMRaspberryPi
+ *
+ * @brief Register Definitions
+ *
+ * @{
+ */
+
+/**
+ * @name Register Macros
+ *
+ * @{
+ */
+
+#define BCM2711_REG(x) (*(volatile uint64_t *)(x))
+#define BCM2711_BIT(n) (1 << (n))
+#define BCM2835_REG(addr) (*(volatile uint32_t*)(addr))
+
+/** @} */
+
+/**
+ * @name Peripheral Base Register Address
+ *
+ * @{
+ */
+
+#define RPI_PERIPHERAL_BASE 0xFE000000
+#define BASE_OFFSET 0xFE000000
+#define RPI_PERIPHERAL_SIZE 0x01800000
+
+/**
+ * @name Bus to Physical address translation
+ * Macro.
+ * @{
+ */
+#define BUS_TO_PHY(x) ((x) - BASE_OFFSET)
+
+/** @} */
+
+/**
+ * @name Internal ARM Timer Registers
+ *
+ * @{
+ */
+
+#define BCM2711_CLOCK_FREQ 250000000
+
+#define BCM2711_TIMER_BASE (RPI_PERIPHERAL_BASE + 0xB400)
+
+#define BCM2711_TIMER_LOD (BCM2711_TIMER_BASE + 0x00)
+#define BCM2711_TIMER_VAL (BCM2711_TIMER_BASE + 0x04)
+#define BCM2711_TIMER_CTL (BCM2711_TIMER_BASE + 0x08)
+#define BCM2711_TIMER_CLI (BCM2711_TIMER_BASE + 0x0C)
+#define BCM2711_TIMER_RIS (BCM2711_TIMER_BASE + 0x10)
+#define BCM2711_TIMER_MIS (BCM2711_TIMER_BASE + 0x14)
+#define BCM2711_TIMER_RLD (BCM2711_TIMER_BASE + 0x18)
+#define BCM2711_TIMER_DIV (BCM2711_TIMER_BASE + 0x1C)
+#define BCM2711_TIMER_CNT (BCM2711_TIMER_BASE + 0x20)
+
+#define BCM2711_TIMER_PRESCALE 0xF9
+
+/** @} */
+
+/**
+ * @name Power Management and Watchdog Registers
+ *
+ * @{
+ */
+
+#define BCM2711_PM_PASSWD_MAGIC 0x5a000000
+
+#define BCM2711_PM_BASE (RPI_PERIPHERAL_BASE + 0x100000)
+
+#define BCM2711_PM_GNRIC (BCM2711_PM_BASE + 0x00)
+#define BCM2711_PM_GNRIC_POWUP 0x00000001
+#define BCM2711_PM_GNRIC_POWOK 0x00000002
+#define BCM2711_PM_GNRIC_ISPOW 0x00000004
+#define BCM2711_PM_GNRIC_MEMREP 0x00000008
+#define BCM2711_PM_GNRIC_MRDONE 0x00000010
+#define BCM2711_PM_GNRIC_ISFUNC 0x00000020
+#define BCM2711_PM_GNRIC_RSTN 0x00000fc0
+#define BCM2711_PM_GNRIC_ENAB 0x00001000
+#define BCM2711_PM_GNRIC_CFG 0x007f0000
+
+#define BCM2711_PM_AUDIO (BCM2711_PM_BASE + 0x04)
+#define BCM2711_PM_AUDIO_APSM 0x000fffff
+#define BCM2711_PM_AUDIO_CTRLEN 0x00100000
+#define BCM2711_PM_AUDIO_RSTN 0x00200000
+
+#define BCM2711_PM_STATUS (BCM2711_PM_BASE + 0x18)
+
+#define BCM2711_PM_RSTC (BCM2711_PM_BASE + 0x1c)
+#define BCM2711_PM_RSTC_DRCFG 0x00000003
+#define BCM2711_PM_RSTC_WRCFG 0x00000030
+#define BCM2711_PM_RSTC_WRCFG_FULL 0x00000020
+#define BCM2711_PM_RSTC_SRCFG 0x00000300
+#define BCM2711_PM_RSTC_QRCFG 0x00003000
+#define BCM2711_PM_RSTC_FRCFG 0x00030000
+#define BCM2711_PM_RSTC_HRCFG 0x00300000
+
+#define BCM2711_PM_RSTS (BCM2711_PM_BASE + 0x20)
+#define BCM2711_PM_RSTS_HADDRQ 0x00000001
+#define BCM2711_PM_RSTS_HADDRF 0x00000002
+#define BCM2711_PM_RSTS_HADDRH 0x00000004
+#define BCM2711_PM_RSTS_HADWRQ 0x00000010
+#define BCM2711_PM_RSTS_HADWRF 0x0000002
+#define BCM2711_PM_RSTS_HADWRH 0x00000040
+#define BCM2711_PM_RSTS_HADSRQ 0x00000100
+#define BCM2711_PM_RSTS_HADSRF 0x00000200
+#define BCM2711_PM_RSTS_HADSRH 0x00000400
+#define BCM2711_PM_RSTS_HADPOR 0x00001000
+
+#define BCM2711_PM_WDOG (BCM2711_PM_BASE + 0x24)
+
+/** @} */
+
+
+/** @} */
+
+/**
+ * @name AUX Registers
+ *
+ * @{
+ */
+
+#define BCM2711_AUX_BASE (RPI_PERIPHERAL_BASE + 0x215000)
+
+#define AUX_ENABLES (BCM2711_AUX_BASE + 0x04)
+#define AUX_MU_IO_REG (BCM2711_AUX_BASE + 0x40)
+#define AUX_MU_IER_REG (BCM2711_AUX_BASE + 0x44)
+#define AUX_MU_IIR_REG (BCM2711_AUX_BASE + 0x48)
+#define AUX_MU_LCR_REG (BCM2711_AUX_BASE + 0x4C)
+#define AUX_MU_MCR_REG (BCM2711_AUX_BASE + 0x50)
+#define AUX_MU_LSR_REG (BCM2711_AUX_BASE + 0x54)
+#define AUX_MU_MSR_REG (BCM2711_AUX_BASE + 0x58)
+#define AUX_MU_SCRATCH (BCM2711_AUX_BASE + 0x5C)
+#define AUX_MU_CNTL_REG (BCM2711_AUX_BASE + 0x60)
+#define AUX_MU_STAT_REG (BCM2711_AUX_BASE + 0x64)
+#define AUX_MU_BAUD_REG (BCM2711_AUX_BASE + 0x68)
+
+/** @} */
+
+
+
+/** @} */
+
+/**
+ * @name GPU Timer Registers
+ *
+ * @{
+ */
+
+/**
+ * NOTE: The GPU uses Compare registers 0 and 2 for
+ * it's own RTOS. 1 and 3 are available for use in
+ * RTEMS.
+ */
+#define BCM2711_GPU_TIMER_BASE (RPI_PERIPHERAL_BASE + 0x3000)
+
+#define BCM2711_GPU_TIMER_CS (BCM2711_GPU_TIMER_BASE + 0x00)
+#define BCM2711_GPU_TIMER_CS_M0 0x00000001
+#define BCM2711_GPU_TIMER_CS_M1 0x00000002
+#define BCM2711_GPU_TIMER_CS_M2 0x00000004
+#define BCM2711_GPU_TIMER_CS_M3 0x00000008
+#define BCM2711_GPU_TIMER_CLO (BCM2711_GPU_TIMER_BASE + 0x04)
+#define BCM2711_GPU_TIMER_CHI (BCM2711_GPU_TIMER_BASE + 0x08)
+#define BCM2711_GPU_TIMER_C0 (BCM2711_GPU_TIMER_BASE + 0x0C)
+#define BCM2711_GPU_TIMER_C1 (BCM2711_GPU_TIMER_BASE + 0x10)
+#define BCM2711_GPU_TIMER_C2 (BCM2711_GPU_TIMER_BASE + 0x14)
+#define BCM2711_GPU_TIMER_C3 (BCM2711_GPU_TIMER_BASE + 0x18)
+
+/**
+ * NOTE: compatible with the BCM2835 system timer
+ */
+#define BCM2835_GPU_TIMER_CS_M3 BCM2711_GPU_TIMER_CS_M3
+#define BCM2835_GPU_TIMER_C3 BCM2711_GPU_TIMER_C3
+#define BCM2835_GPU_TIMER_CLO BCM2711_GPU_TIMER_CLO
+#define BCM2835_GPU_TIMER_CS BCM2711_GPU_TIMER_CS
+/** @} */
+
+/**
+ * @name EMMC Registers
+ *
+ * @{
+ */
+
+/**
+ * NOTE: Since the SD controller follows the SDHCI standard,
+ * the rtems-libbsd tree already provides the remaining registers.
+ */
+
+#define BCM2711_EMMC_BASE (RPI_PERIPHERAL_BASE + 0x300000)
+
+/** @} */
+
+/**
+* @name Mailbox Registers
+*
+* @{
+*/
+
+#define BCM2711_MBOX_BASE (RPI_PERIPHERAL_BASE+0xB880)
+
+#define BCM2711_MBOX_READ (BCM2711_MBOX_BASE+0x00)
+#define BCM2711_MBOX_PEEK (BCM2711_MBOX_BASE+0x10)
+#define BCM2711_MBOX_SENDER (BCM2711_MBOX_BASE+0x14)
+#define BCM2711_MBOX_STATUS (BCM2711_MBOX_BASE+0x18)
+#define BCM2711_MBOX_WRITE (BCM2711_MBOX_BASE+0x20)
+#define BCM2711_MBOX_CONFIG (BCM2711_MBOX_BASE+0x1C)
+
+#define BCM2711_MBOX_RESPONSE 0x80000000
+#define BCM2711_MBOX_FULL 0x80000000
+#define BCM2711_MBOX_EMPTY 0x40000000
+
+/** @} */
+
+/**
+* @name Mailbox Channels
+*
+* @{
+*/
+
+/* Power Manager channel */
+#define BCM2711_MBOX_CHANNEL_PM 0
+/* Framebuffer channel */
+#define BCM2711_MBOX_CHANNEL_FB 1
+ /* Virtual UART channel */
+#define BCM2711_MBOX_CHANNEL_VUART 2
+ /* VCHIQ channel */
+#define BCM2711_MBOX_CHANNEL_VCHIQ 3
+ /* LEDs channel */
+#define BCM2711_MBOX_CHANNEL_LED 4
+ /* Button channel */
+#define BCM2711_MBOX_CHANNEL_BUTTON 5
+ /* Touch screen channel */
+#define BCM2711_MBOX_CHANNEL_TOUCHS 6
+
+#define BCM2711_MBOX_CHANNEL_COUNT 7
+/* Property tags (ARM <-> VC) channel */
+#define BCM2711_MBOX_CHANNEL_PROP_AVC 8
+ /* Property tags (VC <-> ARM) channel */
+#define BCM2711_MBOX_CHANNEL_PROP_VCA 9
+
+/** @} */
+
+
+
+/**
+ * @name Raspberry Pi 2 Interrupt Register Defines
+ *
+ * @{
+ */
+
+/* Timers interrupt control registers */
+#define BCM2711_CORE0_TIMER_IRQ_CTRL_BASE 0xFF800040
+#define BCM2711_CORE1_TIMER_IRQ_CTRL_BASE 0xFF800044
+#define BCM2711_CORE2_TIMER_IRQ_CTRL_BASE 0xFF800048
+#define BCM2711_CORE3_TIMER_IRQ_CTRL_BASE 0xFF80004C
+
+#define BCM2711_CORE_TIMER_IRQ_CTRL(cpuidx) \
+ (BCM2711_CORE0_TIMER_IRQ_CTRL_BASE + 0x4 * (cpuidx))
+
+
+/**
+ * @name Raspberry Pi 4 ARM_LOCAL registers
+ *
+ * @{
+ */
+
+#define BCM2711_LOCAL_REGS_BASE 0x4C0000000
+#define BCM2711_LOCAL_REGS_SIZE 0x100
+
+#define BCM2711_LOCAL_ARM_CONTROL (BCM2711_LOCAL_REGS_BASE + 0x00)
+#define BCM2711_LOCAL_CORE_IRQ_CONTROL (BCM2711_LOCAL_REGS_BASE + 0x0c)
+#define BCM2711_LOCAL_PMU_CONTROL_SET (BCM2711_LOCAL_REGS_BASE + 0x10)
+#define BCM2711_LOCAL_PMU_CONTROL_CLR (BCM2711_LOCAL_REGS_BASE + 0x14)
+#define BCM2711_LOCAL_PERI_IRQ_ROUTE0 (BCM2711_LOCAL_REGS_BASE + 0x24)
+#define BCM2711_LOCAL_AXI_QUIET_TIME (BCM2711_LOCAL_REGS_BASE + 0x30)
+#define BCM2711_LOCAL_LOCAL_TIMER_CONTROL (BCM2711_LOCAL_REGS_BASE + 0x34)
+#define BCM2711_LOCAL_LOCAL_TIMER_IRQ (BCM2711_LOCAL_REGS_BASE + 0x38)
+
+#define BCM2711_LOCAL_TIMER_CNTRL0 (BCM2711_LOCAL_REGS_BASE + 0x40)
+#define BCM2711_LOCAL_TIMER_CNTRL1 (BCM2711_LOCAL_REGS_BASE + 0x44)
+#define BCM2711_LOCAL_TIMER_CNTRL2 (BCM2711_LOCAL_REGS_BASE + 0x48)
+#define BCM2711_LOCAL_TIMER_CNTRL3 (BCM2711_LOCAL_REGS_BASE + 0x4c)
+
+#define BCM2711_LOCAL_MAILBOX_CNTRL0 (BCM2711_LOCAL_REGS_BASE + 0x50)
+#define BCM2711_LOCAL_MAILBOX_CNTRL1 (BCM2711_LOCAL_REGS_BASE + 0x54)
+#define BCM2711_LOCAL_MAILBOX_CNTRL2 (BCM2711_LOCAL_REGS_BASE + 0x58)
+#define BCM2711_LOCAL_MAILBOX_CNTRL3 (BCM2711_LOCAL_REGS_BASE + 0x5c)
+
+#define BCM2711_LOCAL_IRQ_SOURCE0 (BCM2711_LOCAL_REGS_BASE + 0x60)
+#define BCM2711_LOCAL_IRQ_SOURCE1 (BCM2711_LOCAL_REGS_BASE + 0x64)
+#define BCM2711_LOCAL_IRQ_SOURCE2 (BCM2711_LOCAL_REGS_BASE + 0x68)
+#define BCM2711_LOCAL_IRQ_SOURCE3 (BCM2711_LOCAL_REGS_BASE + 0x6c)
+
+#define BCM2711_LOCAL_FIQ_SOURCE0 (BCM2711_LOCAL_REGS_BASE + 0x70)
+#define BCM2711_LOCAL_FIQ_SOURCE1 (BCM2711_LOCAL_REGS_BASE + 0x74)
+#define BCM2711_LOCAL_FIQ_SOURCE2 (BCM2711_LOCAL_REGS_BASE + 0x78)
+#define BCM2711_LOCAL_FIQ_SOURCE3 (BCM2711_LOCAL_REGS_BASE + 0x7c)
+
+/**
+ * @name Raspberry Pi 4 Mailbox registers
+ *
+ * @{
+ */
+
+
+
+#define BCM2711_MAILBOX_00_WRITE_SET_BASE 0x4C000080
+#define BCM2711_MAILBOX_01_WRITE_SET_BASE 0x4C000084
+#define BCM2711_MAILBOX_02_WRITE_SET_BASE 0x4C000088
+#define BCM2711_MAILBOX_03_WRITE_SET_BASE 0x4C00008C
+#define BCM2711_MAILBOX_04_WRITE_SET_BASE 0x4C000090
+#define BCM2711_MAILBOX_05_WRITE_SET_BASE 0x4C000094
+#define BCM2711_MAILBOX_06_WRITE_SET_BASE 0x4C000098
+#define BCM2711_MAILBOX_07_WRITE_SET_BASE 0x4C00009C
+#define BCM2711_MAILBOX_08_WRITE_SET_BASE 0x4C0000A0
+#define BCM2711_MAILBOX_09_WRITE_SET_BASE 0x4C0000A4
+#define BCM2711_MAILBOX_10_WRITE_SET_BASE 0x4C0000A8
+#define BCM2711_MAILBOX_11_WRITE_SET_BASE 0x4C0000AC
+#define BCM2711_MAILBOX_12_WRITE_SET_BASE 0x4C0000B0
+#define BCM2711_MAILBOX_13_WRITE_SET_BASE 0x4C0000B4
+#define BCM2711_MAILBOX_14_WRITE_SET_BASE 0x4C0000B8
+#define BCM2711_MAILBOX_15_WRITE_SET_BASE 0x4C0000BC
+
+#define BCM2711_MAILBOX_00_READ_CLEAR_BASE 0x4C0000C0
+#define BCM2711_MAILBOX_01_READ_CLEAR_BASE 0x4C0000C4
+#define BCM2711_MAILBOX_02_READ_CLEAR_BASE 0x4C0000C8
+#define BCM2711_MAILBOX_03_READ_CLEAR_BASE 0x4C0000CC
+#define BCM2711_MAILBOX_04_READ_CLEAR_BASE 0x4C0000D0
+#define BCM2711_MAILBOX_05_READ_CLEAR_BASE 0x4C0000D4
+#define BCM2711_MAILBOX_06_READ_CLEAR_BASE 0x4C0000D8
+#define BCM2711_MAILBOX_07_READ_CLEAR_BASE 0x4C0000DC
+#define BCM2711_MAILBOX_08_READ_CLEAR_BASE 0x4C0000E0
+#define BCM2711_MAILBOX_09_READ_CLEAR_BASE 0x4C0000E4
+#define BCM2711_MAILBOX_10_READ_CLEAR_BASE 0x4C0000E8
+#define BCM2711_MAILBOX_11_READ_CLEAR_BASE 0x4C0000EC
+#define BCM2711_MAILBOX_12_READ_CLEAR_BASE 0x4C0000F0
+#define BCM2711_MAILBOX_13_READ_CLEAR_BASE 0x4C0000F4
+#define BCM2711_MAILBOX_14_READ_CLEAR_BASE 0x4C0000F8
+#define BCM2711_MAILBOX_15_READ_CLEAR_BASE 0x4C0000FC
+
+
+/**
+ * @name Raspberry Pi 4 ARM_C FIQ and IRQ registers
+ *
+ * @{
+ */
+
+#define BCM2711_ARMC_REGS_BASE (RPI_PERIPHERAL_BASE + 0xB200)
+#define BCM2711_ARMC_REGS_SIZE 0x200
+
+#define BCM2711_ARMC_IRQ0_PENDING0 (BCM2711_ARMC_REGS_BASE + 0x00)
+#define BCM2711_ARMC_IRQ0_PENDING1 (BCM2711_ARMC_REGS_BASE + 0x04)
+#define BCM2711_ARMC_IRQ0_PENDING2 (BCM2711_ARMC_REGS_BASE + 0x08)
+#define BCM2711_ARMC_IRQ0_SET_EN_0 (BCM2711_ARMC_REGS_BASE + 0x10)
+#define BCM2711_ARMC_IRQ0_SET_EN_1 (BCM2711_ARMC_REGS_BASE + 0x14)
+#define BCM2711_ARMC_IRQ0_SET_EN_2 (BCM2711_ARMC_REGS_BASE + 0x18)
+#define BCM2711_ARMC_IRQ0_CLR_EN_0 (BCM2711_ARMC_REGS_BASE + 0x20)
+#define BCM2711_ARMC_IRQ0_CLR_EN_1 (BCM2711_ARMC_REGS_BASE + 0x24)
+#define BCM2711_ARMC_IRQ0_CLR_EN_2 (BCM2711_ARMC_REGS_BASE + 0x28)
+
+#define BCM2711_ARMC_IRQ_STATUS0 (BCM2711_ARMC_REGS_BASE + 0x30)
+#define BCM2711_ARMC_IRQ_STATUS1 (BCM2711_ARMC_REGS_BASE + 0x34)
+#define BCM2711_ARMC_IRQ_STATUS2 (BCM2711_ARMC_REGS_BASE + 0x38)
+
+#define BCM2711_ARMC_IRQ1_PENDING0 (BCM2711_ARMC_REGS_BASE + 0x40)
+#define BCM2711_ARMC_IRQ1_PENDING1 (BCM2711_ARMC_REGS_BASE + 0x44)
+#define BCM2711_ARMC_IRQ1_PENDING2 (BCM2711_ARMC_REGS_BASE + 0x48)
+#define BCM2711_ARMC_IRQ1_SET_EN_0 (BCM2711_ARMC_REGS_BASE + 0x50)
+#define BCM2711_ARMC_IRQ1_SET_EN_1 (BCM2711_ARMC_REGS_BASE + 0x54)
+#define BCM2711_ARMC_IRQ1_SET_EN_2 (BCM2711_ARMC_REGS_BASE + 0x58)
+#define BCM2711_ARMC_IRQ1_CLR_EN_0 (BCM2711_ARMC_REGS_BASE + 0x60)
+#define BCM2711_ARMC_IRQ1_CLR_EN_1 (BCM2711_ARMC_REGS_BASE + 0x64)
+#define BCM2711_ARMC_IRQ1_CLR_EN_2 (BCM2711_ARMC_REGS_BASE + 0x68)
+
+#define BCM2711_ARMC_IRQ2_PENDING0 (BCM2711_ARMC_REGS_BASE + 0x80)
+#define BCM2711_ARMC_IRQ2_PENDING1 (BCM2711_ARMC_REGS_BASE + 0x84)
+#define BCM2711_ARMC_IRQ2_PENDING2 (BCM2711_ARMC_REGS_BASE + 0x88)
+#define BCM2711_ARMC_IRQ2_SET_EN_0 (BCM2711_ARMC_REGS_BASE + 0x90)
+#define BCM2711_ARMC_IRQ2_SET_EN_1 (BCM2711_ARMC_REGS_BASE + 0x94)
+#define BCM2711_ARMC_IRQ2_SET_EN_2 (BCM2711_ARMC_REGS_BASE + 0x98)
+#define BCM2711_ARMC_IRQ2_CLR_EN_0 (BCM2711_ARMC_REGS_BASE + 0xA0)
+#define BCM2711_ARMC_IRQ2_CLR_EN_1 (BCM2711_ARMC_REGS_BASE + 0xA4)
+#define BCM2711_ARMC_IRQ2_CLR_EN_2 (BCM2711_ARMC_REGS_BASE + 0xA8)
+
+#define BCM2711_ARMC_IRQ3_PENDING0 (BCM2711_ARMC_REGS_BASE + 0xC0)
+#define BCM2711_ARMC_IRQ3_PENDING1 (BCM2711_ARMC_REGS_BASE + 0xC4)
+#define BCM2711_ARMC_IRQ3_PENDING2 (BCM2711_ARMC_REGS_BASE + 0xC8)
+#define BCM2711_ARMC_IRQ3_SET_EN_0 (BCM2711_ARMC_REGS_BASE + 0xD0)
+#define BCM2711_ARMC_IRQ3_SET_EN_1 (BCM2711_ARMC_REGS_BASE + 0xD4)
+#define BCM2711_ARMC_IRQ3_SET_EN_2 (BCM2711_ARMC_REGS_BASE + 0xD8)
+#define BCM2711_ARMC_IRQ3_CLR_EN_0 (BCM2711_ARMC_REGS_BASE + 0xE0)
+#define BCM2711_ARMC_IRQ3_CLR_EN_1 (BCM2711_ARMC_REGS_BASE + 0xE4)
+#define BCM2711_ARMC_IRQ3_CLR_EN_2 (BCM2711_ARMC_REGS_BASE + 0xE8)
+
+
+
+#define BCM2711_ARMC_FIQ0_PENDING0 (BCM2711_ARMC_REGS_BASE + 0x100)
+#define BCM2711_ARMC_FIQ0_PENDING1 (BCM2711_ARMC_REGS_BASE + 0x104)
+#define BCM2711_ARMC_FIQ0_PENDING2 (BCM2711_ARMC_REGS_BASE + 0x108)
+#define BCM2711_ARMC_FIQ0_SET_EN_0 (BCM2711_ARMC_REGS_BASE + 0x110)
+#define BCM2711_ARMC_FIQ0_SET_EN_1 (BCM2711_ARMC_REGS_BASE + 0x114)
+#define BCM2711_ARMC_FIQ0_SET_EN_2 (BCM2711_ARMC_REGS_BASE + 0x118)
+#define BCM2711_ARMC_FIQ0_CLR_EN_0 (BCM2711_ARMC_REGS_BASE + 0x120)
+#define BCM2711_ARMC_FIQ0_CLR_EN_1 (BCM2711_ARMC_REGS_BASE + 0x124)
+#define BCM2711_ARMC_FIQ0_CLR_EN_2 (BCM2711_ARMC_REGS_BASE + 0x128)
+
+#define BCM2711_ARMC_FIQ1_PENDING0 (BCM2711_ARMC_REGS_BASE + 0x140)
+#define BCM2711_ARMC_FIQ1_PENDING1 (BCM2711_ARMC_REGS_BASE + 0x144)
+#define BCM2711_ARMC_FIQ1_PENDING2 (BCM2711_ARMC_REGS_BASE + 0x148)
+#define BCM2711_ARMC_FIQ1_SET_EN_0 (BCM2711_ARMC_REGS_BASE + 0x150)
+#define BCM2711_ARMC_FIQ1_SET_EN_1 (BCM2711_ARMC_REGS_BASE + 0x154)
+#define BCM2711_ARMC_FIQ1_SET_EN_2 (BCM2711_ARMC_REGS_BASE + 0x158)
+#define BCM2711_ARMC_FIQ1_CLR_EN_0 (BCM2711_ARMC_REGS_BASE + 0x160)
+#define BCM2711_ARMC_FIQ1_CLR_EN_1 (BCM2711_ARMC_REGS_BASE + 0x164)
+#define BCM2711_ARMC_FIQ1_CLR_EN_2 (BCM2711_ARMC_REGS_BASE + 0x168)
+
+#define BCM2711_ARMC_FIQ2_PENDING0 (BCM2711_ARMC_REGS_BASE + 0x180)
+#define BCM2711_ARMC_FIQ2_PENDING1 (BCM2711_ARMC_REGS_BASE + 0x184)
+#define BCM2711_ARMC_FIQ2_PENDING2 (BCM2711_ARMC_REGS_BASE + 0x188)
+#define BCM2711_ARMC_FIQ2_SET_EN_0 (BCM2711_ARMC_REGS_BASE + 0x190)
+#define BCM2711_ARMC_FIQ2_SET_EN_1 (BCM2711_ARMC_REGS_BASE + 0x194)
+#define BCM2711_ARMC_FIQ2_SET_EN_2 (BCM2711_ARMC_REGS_BASE + 0x198)
+#define BCM2711_ARMC_FIQ2_CLR_EN_0 (BCM2711_ARMC_REGS_BASE + 0x1A0)
+#define BCM2711_ARMC_FIQ2_CLR_EN_1 (BCM2711_ARMC_REGS_BASE + 0x1A4)
+#define BCM2711_ARMC_FIQ2_CLR_EN_2 (BCM2711_ARMC_REGS_BASE + 0x1A8)
+
+#define BCM2711_ARMC_FIQ3_PENDING0 (BCM2711_ARMC_REGS_BASE + 0x1C0)
+#define BCM2711_ARMC_FIQ3_PENDING1 (BCM2711_ARMC_REGS_BASE + 0x1C4)
+#define BCM2711_ARMC_FIQ3_PENDING2 (BCM2711_ARMC_REGS_BASE + 0x1C8)
+#define BCM2711_ARMC_FIQ3_SET_EN_0 (BCM2711_ARMC_REGS_BASE + 0x1D0)
+#define BCM2711_ARMC_FIQ3_SET_EN_1 (BCM2711_ARMC_REGS_BASE + 0x1D4)
+#define BCM2711_ARMC_FIQ3_SET_EN_2 (BCM2711_ARMC_REGS_BASE + 0x1D8)
+#define BCM2711_ARMC_FIQ3_CLR_EN_0 (BCM2711_ARMC_REGS_BASE + 0x1E0)
+#define BCM2711_ARMC_FIQ3_CLR_EN_1 (BCM2711_ARMC_REGS_BASE + 0x1E4)
+#define BCM2711_ARMC_FIQ3_CLR_EN_2 (BCM2711_ARMC_REGS_BASE + 0x1E8)
+
+#define BCM2711_ARMC_SWIRQ_SET (BCM2711_ARMC_REGS_BASE + 0x1F0)
+#define BCM2711_ARMC_SWIRQ_CLEAR (BCM2711_ARMC_REGS_BASE + 0x1F4)
+
+
+
+
+
+/** @} */
+
+#endif /* LIBBSP_ARM_RASPBERRYPI_RASPBERRYPI_H */
diff --git a/bsps/aarch64/raspberrypi/include/tm27.h b/bsps/aarch64/raspberrypi/include/tm27.h
new file mode 100644
index 0000000000..653f88ed01
--- /dev/null
+++ b/bsps/aarch64/raspberrypi/include/tm27.h
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSBSPsAArch64Raspberrypi4
+ *
+ * @brief BSP tm27 header
+ */
+
+/*
+ * Copyright (C) 2022 Mohd Noor Aman
+ *
+ *
+ * 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_TMTEST27
+#error "This is an RTEMS internal file you must not include directly."
+#endif
+
+#ifndef __tm27_h
+#define __tm27_h
+
+#include <dev/irq/arm-gic-tm27.h>
+
+#endif /* __tm27_h */ \ No newline at end of file
diff --git a/bsps/aarch64/raspberrypi/start/bspstart.c b/bsps/aarch64/raspberrypi/start/bspstart.c
new file mode 100644
index 0000000000..368c5d0d08
--- /dev/null
+++ b/bsps/aarch64/raspberrypi/start/bspstart.c
@@ -0,0 +1,49 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSBSPsAArch64Raspberrypi4
+ *
+ * @brief BSP Startup
+ */
+
+/*
+ * Copyright (C) 2022 Mohd Noor Aman
+ *
+ *
+ * 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.
+ */
+
+#include <bsp.h>
+#include <bsp/bootcard.h>
+#include <bsp/irq-generic.h>
+#include <bsp/linker-symbols.h>
+
+void bsp_start( void )
+{
+ bsp_interrupt_initialize();
+ rtems_cache_coherent_add_area(
+ bsp_section_nocacheheap_begin,
+ (uintptr_t) bsp_section_nocacheheap_size
+ );
+}
diff --git a/bsps/aarch64/raspberrypi/start/bspstarthooks.c b/bsps/aarch64/raspberrypi/start/bspstarthooks.c
new file mode 100644
index 0000000000..fe0fe77c09
--- /dev/null
+++ b/bsps/aarch64/raspberrypi/start/bspstarthooks.c
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSBSPsAArch64Raspberrypi4
+ *
+ * @brief BSP Startup Hooks
+ */
+
+/*
+ * Copyright (C) 2022 Mohd Noor Aman
+ *
+ *
+ * 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.
+ */
+
+#include <bsp.h>
+#include <bsp/irq-generic.h>
+#include <bsp/start.h>
+#include <rtems/score/cpu.h>
+
+BSP_START_TEXT_SECTION void bsp_start_hook_0(void)
+{
+ /* Do nothing */
+}
+
+BSP_START_TEXT_SECTION void bsp_start_hook_1(void)
+{
+ AArch64_start_set_vector_base();
+ bsp_start_copy_sections();
+ raspberrypi_4_setup_mmu_and_cache();
+ bsp_start_clear_bss();
+} \ No newline at end of file
diff --git a/bsps/aarch64/raspberrypi/start/bspstartmmu.c b/bsps/aarch64/raspberrypi/start/bspstartmmu.c
new file mode 100644
index 0000000000..18a9a112b0
--- /dev/null
+++ b/bsps/aarch64/raspberrypi/start/bspstartmmu.c
@@ -0,0 +1,84 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSBSPsAArch64Raspberrypi4
+ *
+ * @brief This source file contains the default MMU tables and setup.
+ */
+
+/*
+ * Copyright (C) 2022 Mohd Noor Aman
+ *
+ *
+ * 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.
+ */
+
+#include <bsp.h>
+#include <bsp/start.h>
+#include <bsp/aarch64-mmu.h>
+#include <bsp/raspberrypi.h>
+#include <libcpu/mmu-vmsav8-64.h>
+
+
+BSP_START_DATA_SECTION static const aarch64_mmu_config_entry
+raspberrypi_4_mmu_config_table[] = {
+ AARCH64_MMU_DEFAULT_SECTIONS,
+
+ { /* RPI peripheral address */
+ .begin = (unsigned)RPI_PERIPHERAL_BASE,
+ .end = (unsigned)RPI_PERIPHERAL_BASE + (unsigned)RPI_PERIPHERAL_SIZE,
+ .flags = AARCH64_MMU_DEVICE
+ },
+
+ { /* RPI ARM local registers */
+ .begin = (unsigned)BCM2711_LOCAL_REGS_BASE,
+ .end = (unsigned)BCM2711_LOCAL_REGS_BASE + (unsigned)BCM2711_LOCAL_REGS_SIZE,
+ .flags = AARCH64_MMU_DEVICE
+ },
+
+ { /* RPI GIC Interface address */
+ .begin = 0xFF800000U,
+ .end = 0xFFA00000U,
+ .flags = AARCH64_MMU_DEVICE
+ }
+
+};
+/*
+ * Make weak and let the user override.
+ */
+BSP_START_TEXT_SECTION void
+raspberrypi_4_setup_mmu_and_cache( void ) __attribute__ ((weak));
+
+BSP_START_TEXT_SECTION void
+raspberrypi_4_setup_mmu_and_cache( void )
+{
+ aarch64_mmu_setup();
+
+ aarch64_mmu_setup_translation_table(
+ &raspberrypi_4_mmu_config_table[ 0 ],
+ RTEMS_ARRAY_SIZE( raspberrypi_4_mmu_config_table )
+ );
+
+ aarch64_mmu_enable();
+} \ No newline at end of file
diff --git a/bsps/aarch64/shared/cache/cache.c b/bsps/aarch64/shared/cache/cache.c
index 9e7446a077..be459d5083 100644
--- a/bsps/aarch64/shared/cache/cache.c
+++ b/bsps/aarch64/shared/cache/cache.c
@@ -36,7 +36,6 @@
#include <rtems.h>
#include <bsp.h>
-#include <bsp/utility.h>
#include <rtems/score/aarch64-system-registers.h>
#define CPU_DATA_CACHE_ALIGNMENT 64
@@ -47,8 +46,6 @@
#define CPU_CACHE_SUPPORT_PROVIDES_CACHE_SIZE_FUNCTIONS
-#define CPU_CACHE_SUPPORT_PROVIDES_DISABLE_DATA
-
#define AARCH64_CACHE_L1_CPU_DATA_ALIGNMENT ( (size_t) 64 )
#define AARCH64_CACHE_PREPARE_MVA(mva) (const void *) \
RTEMS_ALIGN_DOWN ( (size_t) mva, AARCH64_CACHE_L1_CPU_DATA_ALIGNMENT )
@@ -66,15 +63,6 @@ void AArch64_data_cache_clean_and_invalidate_line(const void *d_addr)
);
}
-static inline void _CPU_cache_flush_1_data_line(const void *d_addr)
-{
- /* Flush the Data cache */
- AArch64_data_cache_clean_and_invalidate_line( d_addr );
-
- /* Wait for L1 flush to complete */
- _AARCH64_Data_synchronization_barrier();
-}
-
static inline void
_CPU_cache_flush_data_range(
const void *d_addr,
@@ -108,15 +96,6 @@ static inline void AArch64_data_cache_invalidate_line(const void *d_addr)
);
}
-static inline void _CPU_cache_invalidate_1_data_line(const void *d_addr)
-{
- /* Invalidate the data cache line */
- AArch64_data_cache_invalidate_line( d_addr );
-
- /* Wait for L1 invalidate to complete */
- _AARCH64_Data_synchronization_barrier();
-}
-
static inline void
_CPU_cache_invalidate_data_range(
const void *d_addr,
@@ -155,15 +134,6 @@ static inline void AArch64_instruction_cache_invalidate_line(const void *i_addr)
__builtin___clear_cache((void *)i_addr, ((char *)i_addr) + sizeof(void*) - 1);
}
-static inline void _CPU_cache_invalidate_1_instruction_line(const void *d_addr)
-{
- /* Invalidate the Instruction cache line */
- AArch64_instruction_cache_invalidate_line( d_addr );
-
- /* Wait for L1 invalidate to complete */
- _AARCH64_Data_synchronization_barrier();
-}
-
static inline void
_CPU_cache_invalidate_instruction_range( const void *i_addr, size_t n_bytes)
{
@@ -183,9 +153,15 @@ static inline void _CPU_cache_unfreeze_instruction(void)
/* TODO */
}
-static inline uint64_t AArch64_get_ccsidr_for_level(uint64_t val)
+static inline uint64_t AArch64_get_ccsidr_for_level(
+ uint64_t level, bool instruction
+)
{
- _AArch64_Write_csselr_el1(val);
+ uint64_t csselr = AARCH64_CSSELR_EL1_LEVEL(level - 1);
+
+ csselr |= instruction ? AARCH64_CSSELR_EL1_IND : 0;
+
+ _AArch64_Write_csselr_el1(csselr);
return _AArch64_Read_ccsidr_el1();
}
@@ -216,7 +192,7 @@ static inline void AArch64_data_cache_clean_level(uint64_t level)
uint64_t way;
uint64_t way_shift;
- ccsidr = AArch64_get_ccsidr_for_level(AARCH64_CSSELR_EL1_LEVEL(level));
+ ccsidr = AArch64_get_ccsidr_for_level(level, false);
line_power = AArch64_ccsidr_get_line_power(ccsidr);
associativity = AArch64_ccsidr_get_associativity(ccsidr);
@@ -229,7 +205,7 @@ static inline void AArch64_data_cache_clean_level(uint64_t level)
for (set = 0; set < num_sets; ++set) {
uint64_t set_and_way = (way << way_shift)
| (set << line_power)
- | (level << 1);
+ | ((level - 1) << 1);
__asm__ volatile (
"dc csw, %[set_and_way]"
@@ -276,7 +252,7 @@ static inline void AArch64_data_cache_clean_all_levels(void)
uint64_t loc = AArch64_clidr_get_level_of_coherency(clidr);
uint64_t level = 0;
- for (level = 0; level < loc; ++level) {
+ for (level = 1; level <= loc; ++level) {
uint64_t ctype = AArch64_clidr_get_cache_type(clidr, level);
/* Check if this level has a data cache or unified cache */
@@ -301,7 +277,7 @@ static inline void AArch64_cache_invalidate_level(uint64_t level)
uint64_t way;
uint64_t way_shift;
- ccsidr = AArch64_get_ccsidr_for_level(AARCH64_CSSELR_EL1_LEVEL(level));
+ ccsidr = AArch64_get_ccsidr_for_level(level, false);
line_power = AArch64_ccsidr_get_line_power(ccsidr);
associativity = AArch64_ccsidr_get_associativity(ccsidr);
@@ -314,7 +290,7 @@ static inline void AArch64_cache_invalidate_level(uint64_t level)
for (set = 0; set < num_sets; ++set) {
uint64_t set_and_way = (way << way_shift)
| (set << line_power)
- | (level << 1);
+ | ((level - 1) << 1);
__asm__ volatile (
"dc isw, %[set_and_way]"
@@ -332,7 +308,7 @@ static inline void AArch64_data_cache_invalidate_all_levels(void)
uint64_t loc = AArch64_clidr_get_level_of_coherency(clidr);
uint64_t level = 0;
- for (level = 0; level < loc; ++level) {
+ for (level = 1; level <= loc; ++level) {
uint64_t ctype = AArch64_clidr_get_cache_type(clidr, level);
/* Check if this level has a data cache or unified cache */
@@ -373,6 +349,7 @@ static inline void _CPU_cache_disable_data(void)
rtems_interrupt_local_enable(level);
}
+#ifdef RTEMS_SMP
static inline
void AArch64_instruction_cache_inner_shareable_invalidate_all(void)
{
@@ -383,6 +360,7 @@ void AArch64_instruction_cache_inner_shareable_invalidate_all(void)
: "memory"
);
}
+#endif /* RTEMS_SMP */
static inline void AArch64_instruction_cache_invalidate(void)
{
@@ -446,17 +424,11 @@ static inline size_t AArch64_get_cache_size(
clidr = _AArch64_Read_clidr_el1();
loc = AArch64_clidr_get_level_of_coherency(clidr);
- if (level >= loc) {
+ if (level > loc) {
return 0;
}
- if (level == 0) {
- level = loc - 1;
- }
-
- ccsidr = AArch64_get_ccsidr_for_level(
- AARCH64_CSSELR_EL1_LEVEL(level) | (instruction ? AARCH64_CSSELR_EL1_IND : 0)
- );
+ ccsidr = AArch64_get_ccsidr_for_level(level, instruction);
return (1U << (AArch64_ccsidr_get_line_power(ccsidr)+4))
* AArch64_ccsidr_get_associativity(ccsidr)
diff --git a/bsps/aarch64/shared/mmu/vmsav8-64-nommu.c b/bsps/aarch64/shared/mmu/vmsav8-64-nommu.c
new file mode 100644
index 0000000000..2c793fa239
--- /dev/null
+++ b/bsps/aarch64/shared/mmu/vmsav8-64-nommu.c
@@ -0,0 +1,49 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSBSPsAArch64Shared
+ *
+ * @brief AArch64 MMU dummy implementation.
+ */
+
+/*
+ * Copyright (C) 2021 On-Line Applications Research Corporation (OAR)
+ * Written by Kinsey Moore <kinsey.moore@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.
+ */
+
+#include <libcpu/mmu-vmsav8-64.h>
+
+/*
+ * This must have a non-header implementation because it is used by libdebugger.
+ */
+rtems_status_code aarch64_mmu_map(
+ uintptr_t addr,
+ uint64_t size,
+ uint64_t flags
+)
+{
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/bsps/aarch64/shared/mmu/vmsav8-64.c b/bsps/aarch64/shared/mmu/vmsav8-64.c
new file mode 100644
index 0000000000..c426dec900
--- /dev/null
+++ b/bsps/aarch64/shared/mmu/vmsav8-64.c
@@ -0,0 +1,81 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSBSPsAArch64Shared
+ *
+ * @brief AArch64 MMU implementation.
+ */
+
+/*
+ * Copyright (C) 2021 On-Line Applications Research Corporation (OAR)
+ * Written by Kinsey Moore <kinsey.moore@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.
+ */
+
+#include <bsp/aarch64-mmu.h>
+#include <rtems/score/cpu.h>
+
+/*
+ * This must have a non-header implementation because it is used by libdebugger.
+ */
+rtems_status_code aarch64_mmu_map(
+ uintptr_t addr,
+ uint64_t size,
+ uint64_t flags
+)
+{
+ rtems_status_code sc;
+ ISR_Level level;
+ uint64_t max_mappable = 1LLU << aarch64_mmu_get_cpu_pa_bits();
+
+ if ( addr >= max_mappable || (addr + size) > max_mappable ) {
+ return RTEMS_INVALID_ADDRESS;
+ }
+
+ /*
+ * Disable interrupts so they don't run while the MMU tables are being
+ * modified.
+ */
+ _ISR_Local_disable( level );
+
+ sc = aarch64_mmu_map_block(
+ (uint64_t *) bsp_translation_table_base,
+ 0x0,
+ addr,
+ size,
+ -1,
+ flags
+ );
+ _AARCH64_Data_synchronization_barrier();
+ __asm__ volatile(
+ "tlbi vmalle1\n"
+ );
+ _AARCH64_Data_synchronization_barrier();
+ _AARCH64_Instruction_synchronization_barrier();
+
+ _ISR_Local_enable( level );
+
+ return sc;
+}
diff --git a/bsps/aarch64/shared/start/aarch64-smp.c b/bsps/aarch64/shared/start/aarch64-smp.c
new file mode 100644
index 0000000000..5ec7babce7
--- /dev/null
+++ b/bsps/aarch64/shared/start/aarch64-smp.c
@@ -0,0 +1,85 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSBSPsAArch64Shared
+ *
+ * @brief SMP startup and interop code.
+ */
+
+/*
+ * Copyright (C) 2021 On-Line Applications Research Corporation (OAR)
+ * Written by Kinsey Moore <kinsey.moore@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.
+ */
+
+#include <rtems/score/smpimpl.h>
+
+#include <bsp/irq.h>
+
+static void bsp_inter_processor_interrupt( void *arg )
+{
+ _SMP_Inter_processor_interrupt_handler( _Per_CPU_Get() );
+}
+
+uint32_t _CPU_SMP_Initialize( void )
+{
+ return arm_gic_irq_processor_count();
+}
+
+void _CPU_SMP_Finalize_initialization( uint32_t cpu_count )
+{
+ if ( cpu_count > 0 ) {
+ rtems_status_code sc;
+
+ sc = rtems_interrupt_handler_install(
+ ARM_GIC_IRQ_SGI_0,
+ "IPI",
+ RTEMS_INTERRUPT_UNIQUE,
+ bsp_inter_processor_interrupt,
+ NULL
+ );
+ _Assert( sc == RTEMS_SUCCESSFUL );
+ (void) sc;
+
+#if defined( BSP_DATA_CACHE_ENABLED ) || \
+ defined( BSP_INSTRUCTION_CACHE_ENABLED )
+ /* Enable unified L2 cache */
+ rtems_cache_enable_data();
+#endif
+ }
+}
+
+void _CPU_SMP_Prepare_start_multitasking( void )
+{
+ /* Do nothing */
+}
+
+void _CPU_SMP_Send_interrupt( uint32_t target_processor_index )
+{
+ arm_gic_irq_generate_software_irq(
+ ARM_GIC_IRQ_SGI_0,
+ 1U << target_processor_index
+ );
+}
diff --git a/bsps/aarch64/shared/start/linkcmds.base b/bsps/aarch64/shared/start/linkcmds.base
index a560b1016e..d442dbea28 100644
--- a/bsps/aarch64/shared/start/linkcmds.base
+++ b/bsps/aarch64/shared/start/linkcmds.base
@@ -56,7 +56,7 @@ bsp_stack_hyp_size = DEFINED (bsp_stack_hyp_size) ? bsp_stack_hyp_size : 0;
bsp_stack_hyp_size = ALIGN (bsp_stack_hyp_size, bsp_stack_align);
MEMORY {
- UNEXPECTED_SECTIONS : ORIGIN = 0xffffffff, LENGTH = 0
+ UNEXPECTED_SECTIONS : ORIGIN = 0xffffffffffffffff, LENGTH = 0
}
SECTIONS {
@@ -151,7 +151,7 @@ SECTIONS {
} > REGION_RODATA AT > REGION_RODATA_LOAD
.data.rel.ro : ALIGN_WITH_INPUT {
*(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*)
- *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*)
+ *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*)
} > REGION_RODATA AT > REGION_RODATA_LOAD
.jcr : ALIGN_WITH_INPUT {
KEEP (*(.jcr))
@@ -321,6 +321,13 @@ SECTIONS {
} > REGION_WORK AT > REGION_WORK
bsp_section_rtemsstack_size = bsp_section_rtemsstack_end - bsp_section_rtemsstack_begin;
+ .noinit (NOLOAD) : ALIGN_WITH_INPUT {
+ bsp_section_noinit_begin = .;
+ *(SORT_BY_NAME (SORT_BY_ALIGNMENT (.noinit*)))
+ bsp_section_noinit_end = .;
+ } > REGION_WORK AT > REGION_WORK
+ bsp_section_noinit_size = bsp_section_noinit_end - bsp_section_noinit_begin;
+
.work : ALIGN_WITH_INPUT {
/*
* The work section will occupy the remaining REGION_WORK region and
diff --git a/bsps/aarch64/shared/start/start.S b/bsps/aarch64/shared/start/start.S
index f4c39dacdf..0237583463 100644
--- a/bsps/aarch64/shared/start/start.S
+++ b/bsps/aarch64/shared/start/start.S
@@ -55,6 +55,11 @@ _start:
mov x5, x1 /* machine type number or ~0 for DT boot */
mov x6, x2 /* physical address of ATAGs or DTB */
#else /* BSP_START_NEEDS_REGISTER_INITIALIZATION */
+ /*
+ * This block is dead code. No aarch64 targets require this. It might be
+ * needed for hardware simulations or in future processor variants with
+ * lock-step cores.
+ */
mov x0, XZR
mov x1, XZR
mov x2, XZR
@@ -87,8 +92,42 @@ _start:
mov x29, XZR
mov x30, XZR
#ifdef AARCH64_MULTILIB_VFP
-#endif
-#endif
+ mov CPTR_EL3, XZR
+ mov CPTR_EL2, XZR
+ mov d0, XZR
+ mov d1, XZR
+ mov d2, XZR
+ mov d3, XZR
+ mov d4, XZR
+ mov d5, XZR
+ mov d6, XZR
+ mov d7, XZR
+ mov d8, XZR
+ mov d9, XZR
+ mov d10, XZR
+ mov d11, XZR
+ mov d12, XZR
+ mov d13, XZR
+ mov d14, XZR
+ mov d15, XZR
+ mov d16, XZR
+ mov d17, XZR
+ mov d18, XZR
+ mov d19, XZR
+ mov d20, XZR
+ mov d21, XZR
+ mov d22, XZR
+ mov d23, XZR
+ mov d24, XZR
+ mov d25, XZR
+ mov d26, XZR
+ mov d27, XZR
+ mov d28, XZR
+ mov d29, XZR
+ mov d30, XZR
+ mov d31, XZR
+#endif /* AARCH64_MULTILIB_VFP */
+#endif /* BSP_START_NEEDS_REGISTER_INITIALIZATION */
/* Initialize SCTLR_EL1 */
mov x0, XZR
@@ -105,6 +144,33 @@ _start:
b.eq _el2_start
_el3_start:
+ /*
+ * Before leaving the Secure World, we need to initialize the GIC. We
+ * do that here in an early stack context in EL3. This will NOT work
+ * on secondary core boot! We assume only the primary boot core will
+ * start in EL3 if any. Usually on real hardware, we should be running
+ * on top of trusted firmware and will not boot in EL3. Qemu fakes it
+ * for us and will start the primary core in EL3 and secondary cores
+ * will be brought up in EL1NS as expected.
+ */
+ #ifdef AARCH64_MULTILIB_ARCH_V8_ILP32
+ ldr w1, =_ISR_Stack_size
+ ldr w2, =_ISR_Stack_area_begin
+ #else
+ ldr x1, =_ISR_Stack_size
+ ldr x2, =_ISR_Stack_area_begin
+ #endif
+ add x3, x1, x2
+ /* using SP0 for the early init stack context at EL3 */
+ msr spsel, #0
+ mov sp, x3
+
+ /*
+ * Invoke the start hook 0.
+ * We don't set up exception handling, so this hook better behave.
+ */
+ bl bsp_start_hook_0
+
/* Drop from EL3 to EL2 */
/* Initialize HCR_EL2 and SCTLR_EL2 */
@@ -114,27 +180,16 @@ _el3_start:
mrs x0, SCR_EL3
/* Set EL2 to AArch64 */
orr x0, x0, #(1<<10)
-#ifdef AARCH64_IS_NONSECURE
/* Set EL1 to NS */
orr x0, x0, #1
-#endif
msr SCR_EL3, x0
/* set EL2h mode for eret */
-#ifdef AARCH64_IS_NONSECURE
mov x0, #0b01001
-#else
- mov x0, #0b00101
-#endif
-
msr SPSR_EL3, x0
/* Set EL2 entry point */
-#ifdef AARCH64_IS_NONSECURE
adr x0, _el2_start
-#else
- adr x0, _el1_start
-#endif
msr ELR_EL3, x0
eret
@@ -166,21 +221,21 @@ _el1_start:
#ifdef RTEMS_SMP
/* Read MPIDR and get current processor index */
mrs x7, mpidr_el1
- and x7, #0xff
+ and x7, x7, #0xff
#endif
#ifdef RTEMS_SMP
/*
* Get current per-CPU control and store it in PL1 only Thread ID
- * Register (TPIDRPRW).
+ * Register (TPIDR_EL1).
*/
#ifdef AARCH64_MULTILIB_ARCH_V8_ILP32
ldr w1, =_Per_CPU_Information
#else
ldr x1, =_Per_CPU_Information
#endif
- add x1, x1, x7, asl #PER_CPU_CONTROL_SIZE_LOG2
- mcr p15, 0, x1, c13, c0, 4
+ add x1, x1, x7, lsl #PER_CPU_CONTROL_SIZE_LOG2
+ msr TPIDR_EL1, x1
#endif
@@ -201,8 +256,8 @@ _el1_start:
#endif
add x3, x1, x2
- /* Save original DAIF value */
- mrs x4, DAIF
+ /* Disable interrupts and debug */
+ msr DAIFSet, #0xa
#ifdef BSP_START_NEEDS_REGISTER_INITIALIZATION
mov x8, XZR
@@ -252,54 +307,14 @@ _el1_start:
/* FPU does not need to be enabled on AArch64 */
-#ifdef BSP_START_NEEDS_REGISTER_INITIALIZATION
- mov x0, #0
- mov CPTR_EL3, XZR
- mov CPTR_EL2, XZR
- mov d0, XZR
- mov d1, XZR
- mov d2, XZR
- mov d3, XZR
- mov d4, XZR
- mov d5, XZR
- mov d6, XZR
- mov d7, XZR
- mov d8, XZR
- mov d9, XZR
- mov d10, XZR
- mov d11, XZR
- mov d12, XZR
- mov d13, XZR
- mov d14, XZR
- mov d15, XZR
- mov d16, XZR
- mov d17, XZR
- mov d18, XZR
- mov d19, XZR
- mov d20, XZR
- mov d21, XZR
- mov d22, XZR
- mov d23, XZR
- mov d24, XZR
- mov d25, XZR
- mov d26, XZR
- mov d27, XZR
- mov d28, XZR
- mov d29, XZR
- mov d30, XZR
- mov d31, XZR
-#endif /* BSP_START_NEEDS_REGISTER_INITIALIZATION */
+ /* Ensure FPU traps are disabled by default */
+ mrs x0, FPCR
+ bic x0, x0, #((1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12))
+ bic x0, x0, #(1 << 15)
+ msr FPCR, x0
#endif /* AARCH64_MULTILIB_VFP */
- /*
- * Invoke the start hook 0.
- *
- */
-
- mov x1, x5 /* machine type number or ~0 for DT boot */
- bl bsp_start_hook_0
-
/* Branch to start hook 1 */
bl bsp_start_hook_1
diff --git a/bsps/aarch64/xilinx-versal/dev/serial/versal-uart-polled.c b/bsps/aarch64/xilinx-versal/dev/serial/versal-uart-polled.c
index 83493db909..9453dc248b 100644
--- a/bsps/aarch64/xilinx-versal/dev/serial/versal-uart-polled.c
+++ b/bsps/aarch64/xilinx-versal/dev/serial/versal-uart-polled.c
@@ -152,23 +152,6 @@ int versal_uart_initialize(rtems_termios_device_context *base)
return 0;
}
-static bool versal_uart_first_open(
- struct rtems_termios_tty *tty,
- rtems_termios_device_context *base,
- struct termios *term,
- rtems_libio_open_close_args_t *args
-)
-{
- int rc = versal_uart_initialize(base);
- if ( rc < 0 ) {
- return false;
- }
-
- rtems_termios_set_initial_baud(tty, VERSAL_UART_DEFAULT_BAUD);
-
- return true;
-}
-
int versal_uart_read_polled(rtems_termios_device_context *base)
{
volatile versal_uart *regs = versal_uart_get_regs(base);
@@ -209,23 +192,3 @@ void versal_uart_reset_tx_flush(rtems_termios_device_context *base)
/* Wait for empty */
}
}
-
-static void versal_uart_write_support(
- rtems_termios_device_context *base,
- const char *s,
- size_t n
-)
-{
- size_t i;
-
- for (i = 0; i < n; i++) {
- versal_uart_write_polled(base, s[i]);
- }
-}
-
-const rtems_termios_device_handler versal_uart_handler = {
- .first_open = versal_uart_first_open,
- .write = versal_uart_write_support,
- .poll_read = versal_uart_read_polled,
- .mode = TERMIOS_POLLED
-};
diff --git a/bsps/aarch64/xilinx-versal/dev/serial/versal-uart.c b/bsps/aarch64/xilinx-versal/dev/serial/versal-uart.c
new file mode 100644
index 0000000000..bf469f66b2
--- /dev/null
+++ b/bsps/aarch64/xilinx-versal/dev/serial/versal-uart.c
@@ -0,0 +1,323 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (C) 2022 Chris Johns <chris@contemporary.software>
+ *
+ * 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.
+ */
+
+#include <dev/serial/versal-uart.h>
+#include <dev/serial/versal-uart-regs.h>
+#include <bsp/irq.h>
+
+#include <bspopts.h>
+
+static uint32_t versal_uart_intr_all(void)
+{
+ return VERSAL_UARTI_OEI |
+ VERSAL_UARTI_BEI |
+ VERSAL_UARTI_PEI |
+ VERSAL_UARTI_FEI |
+ VERSAL_UARTI_RTI |
+ VERSAL_UARTI_TXI |
+ VERSAL_UARTI_RXI |
+ VERSAL_UARTI_DSRMI |
+ VERSAL_UARTI_DCDMI |
+ VERSAL_UARTI_CTSMI |
+ VERSAL_UARTI_RIMI;
+}
+
+#ifdef VERSAL_CONSOLE_USE_INTERRUPTS
+static void versal_uart_intr_clear(volatile versal_uart *regs, uint32_t ints)
+{
+ regs->uarticr = ints;
+}
+
+static void versal_uart_intr_clearall(volatile versal_uart *regs)
+{
+ versal_uart_intr_clear(regs, versal_uart_intr_all());
+}
+
+static void versal_uart_intr_enable(volatile versal_uart *regs, uint32_t ints)
+{
+ regs->uartimsc |= ints;
+}
+#endif
+
+static void versal_uart_intr_disable(volatile versal_uart *regs, uint32_t ints)
+{
+ regs->uartimsc &= ~ints;
+}
+
+static void versal_uart_intr_disableall(volatile versal_uart *regs)
+{
+ versal_uart_intr_disable(regs, versal_uart_intr_all());
+}
+
+#ifdef VERSAL_CONSOLE_USE_INTERRUPTS
+static bool versal_uart_flags_clear(volatile versal_uart *regs, uint32_t flags)
+{
+ return (regs->uartfr & flags) == 0;
+}
+
+static void versal_uart_interrupt(void *arg)
+{
+ rtems_termios_tty *tty = arg;
+ versal_uart_context *ctx = rtems_termios_get_device_context(tty);
+ volatile versal_uart *regs = ctx->regs;
+ uint32_t uartmis = regs->uartmis;
+
+ versal_uart_intr_clear(regs, uartmis);
+
+ if ((uartmis & (VERSAL_UARTI_RTI | VERSAL_UARTI_RXI)) != 0) {
+ char buf[32];
+ int c = 0;
+ while (c < sizeof(buf) &&
+ versal_uart_flags_clear(regs, VERSAL_UARTFR_RXFE)) {
+ buf[c++] = (char) VERSAL_UARTDR_DATA_GET(regs->uartdr);
+ }
+ rtems_termios_enqueue_raw_characters(tty, buf, c);
+ }
+
+ if (ctx->transmitting) {
+ int sent = ctx->tx_queued;
+ ctx->transmitting = false;
+ ctx->tx_queued = 0;
+ versal_uart_intr_disable(regs, VERSAL_UARTI_TXI);
+ rtems_termios_dequeue_characters(tty, sent);
+ }
+}
+#endif
+
+static bool versal_uart_first_open(
+ rtems_termios_tty *tty,
+ rtems_termios_device_context *base,
+ struct termios *term,
+ rtems_libio_open_close_args_t *args
+)
+{
+#ifdef VERSAL_CONSOLE_USE_INTERRUPTS
+ versal_uart_context *ctx = (versal_uart_context *) base;
+ volatile versal_uart *regs = ctx->regs;
+ rtems_status_code sc;
+
+ ctx->transmitting = false;
+ ctx->tx_queued = 0;
+ ctx->first_send = true;
+#endif
+
+ rtems_termios_set_initial_baud(tty, VERSAL_UART_DEFAULT_BAUD);
+ versal_uart_initialize(base);
+
+#ifdef VERSAL_CONSOLE_USE_INTERRUPTS
+ regs->uartifls = VERSAL_UARTIFLS_RXIFLSEL(2) | VERSAL_UARTIFLS_TXIFLSEL(2);
+ regs->uartlcr_h |= VERSAL_UARTLCR_H_FEN;
+ versal_uart_intr_disableall(regs);
+ sc = rtems_interrupt_handler_install(
+ ctx->irq,
+ "UART",
+ RTEMS_INTERRUPT_SHARED,
+ versal_uart_interrupt,
+ tty
+ );
+ if (sc != RTEMS_SUCCESSFUL) {
+ return false;
+ }
+ versal_uart_intr_clearall(regs);
+ versal_uart_intr_enable(regs, VERSAL_UARTI_RTI | VERSAL_UARTI_RXI);
+#endif
+
+ return true;
+}
+
+#ifdef VERSAL_CONSOLE_USE_INTERRUPTS
+static void versal_uart_last_close(
+ rtems_termios_tty *tty,
+ rtems_termios_device_context *base,
+ rtems_libio_open_close_args_t *args
+)
+{
+ versal_uart_context *ctx = (versal_uart_context *) base;
+ rtems_interrupt_handler_remove(ctx->irq, versal_uart_interrupt, tty);
+}
+#endif
+
+static void versal_uart_write_support(
+ rtems_termios_device_context *base,
+ const char *buf,
+ size_t len
+)
+{
+#ifdef VERSAL_CONSOLE_USE_INTERRUPTS
+ versal_uart_context *ctx = (versal_uart_context *) base;
+ volatile versal_uart *regs = ctx->regs;
+
+ if (len > 0) {
+ size_t len_remaining = len;
+ const char *p = &buf[0];
+ versal_uart_intr_enable(regs, VERSAL_UARTI_TXI);
+ /*
+ * The PL011 IP in the Versal needs preloading the TX FIFO with
+ * exactly 17 characters for the first TX interrupt to be
+ * generated.
+ */
+ if (ctx->first_send) {
+ ctx->first_send = false;
+ for (int i = 0; i < 17; ++i) {
+ regs->uartdr = VERSAL_UARTDR_DATA('\r');
+ }
+ }
+ while (versal_uart_flags_clear(regs, VERSAL_UARTFR_TXFF) &&
+ len_remaining > 0) {
+ regs->uartdr = VERSAL_UARTDR_DATA(*p++);
+ --len_remaining;
+ }
+ ctx->tx_queued = len - len_remaining;
+ ctx->transmitting = true;
+ }
+#else
+ ssize_t i;
+ for (i = 0; i < len; ++i) {
+ versal_uart_write_polled(base, buf[i]);
+ }
+#endif
+}
+
+static bool versal_uart_set_attributes(
+ rtems_termios_device_context *context,
+ const struct termios *term
+)
+{
+ versal_uart_context *ctx = (versal_uart_context *) context;
+ volatile versal_uart *regs = ctx->regs;
+ int32_t baud;
+ uint32_t ibauddiv = 0;
+ uint32_t fbauddiv = 0;
+ uint32_t mode = 0;
+ int rc;
+
+ /*
+ * Determine the baud rate
+ */
+ baud = rtems_termios_baud_to_number(term->c_ospeed);
+
+ if (baud > 0) {
+ uint32_t maxerr = 3;
+
+ rc = versal_cal_baud_rate(
+ VERSAL_UART_DEFAULT_BAUD,
+ maxerr,
+ &ibauddiv,
+ &fbauddiv
+ );
+ if (rc != 0) {
+ return rc;
+ }
+ }
+
+ /*
+ * Configure the mode register
+ */
+ mode = regs->uartlcr_h & VERSAL_UARTLCR_H_FEN;
+
+ /*
+ * Parity
+ */
+ if ((term->c_cflag & PARENB) != 0) {
+ mode |= VERSAL_UARTLCR_H_PEN;
+ if ((term->c_cflag & PARODD) == 0) {
+ mode |= VERSAL_UARTLCR_H_EPS;
+ }
+ }
+
+ /*
+ * Character Size
+ */
+ switch (term->c_cflag & CSIZE)
+ {
+ case CS5:
+ mode = VERSAL_UARTLCR_H_WLEN_SET(mode, VERSAL_UARTLCR_H_WLEN_5);
+ break;
+ case CS6:
+ mode = VERSAL_UARTLCR_H_WLEN_SET(mode, VERSAL_UARTLCR_H_WLEN_6);
+ break;
+ case CS7:
+ mode = VERSAL_UARTLCR_H_WLEN_SET(mode, VERSAL_UARTLCR_H_WLEN_7);
+ break;
+ case CS8:
+ default:
+ mode = VERSAL_UARTLCR_H_WLEN_SET(mode, VERSAL_UARTLCR_H_WLEN_8);
+ break;
+ }
+
+ /*
+ * Stop Bits
+ */
+ if (term->c_cflag & CSTOPB) {
+ /* 2 stop bits */
+ mode |= VERSAL_UARTLCR_H_STP2;
+ }
+
+ versal_uart_intr_disableall(regs);
+
+ /*
+ * Wait for any data in the TXFIFO to be sent then wait while the
+ * transmiter is active.
+ */
+ while ((regs->uartfr & VERSAL_UARTFR_TXFE) == 0 ||
+ (regs->uartfr & VERSAL_UARTFR_BUSY) != 0) {
+ /* Wait */
+ }
+
+ regs->uartcr = VERSAL_UARTCR_UARTEN;
+ /* Ignore baud rate of B0. There are no modem control lines to de-assert */
+ if (baud > 0) {
+ regs->uartibrd = VERSAL_UARTIBRD_BAUD_DIVINT(ibauddiv);
+ regs->uartfbrd = VERSAL_UARTFBRD_BAUD_DIVFRAC(fbauddiv);
+ }
+ regs->uartlcr_h = mode;
+
+ /* Control: receive, transmit, uart enable, no CTS, no RTS, no loopback */
+ regs->uartcr = VERSAL_UARTCR_RXE
+ | VERSAL_UARTCR_TXE
+ | VERSAL_UARTCR_UARTEN;
+
+#ifdef VERSAL_CONSOLE_USE_INTERRUPTS
+ versal_uart_intr_clearall(regs);
+ versal_uart_intr_enable(regs, VERSAL_UARTI_RTI | VERSAL_UARTI_RXI);
+#endif
+
+ return true;
+}
+
+const rtems_termios_device_handler versal_uart_handler = {
+ .first_open = versal_uart_first_open,
+ .set_attributes = versal_uart_set_attributes,
+ .write = versal_uart_write_support,
+#ifdef VERSAL_CONSOLE_USE_INTERRUPTS
+ .last_close = versal_uart_last_close,
+ .mode = TERMIOS_IRQ_DRIVEN
+#else
+ .poll_read = versal_uart_read_polled,
+ .mode = TERMIOS_POLLED
+#endif
+};
diff --git a/bsps/aarch64/xilinx-versal/include/bsp.h b/bsps/aarch64/xilinx-versal/include/bsp.h
index 2017e10ade..5b01637786 100644
--- a/bsps/aarch64/xilinx-versal/include/bsp.h
+++ b/bsps/aarch64/xilinx-versal/include/bsp.h
@@ -47,6 +47,7 @@
#ifndef ASM
#include <bsp/default-initial-extension.h>
+#include <bsp/linker-symbols.h>
#include <bsp/start.h>
#include <rtems.h>
@@ -61,6 +62,14 @@ extern "C" {
#define BSP_RESET_SMC
+/*
+ * DDRMC mapping
+ */
+LINKER_SYMBOL(bsp_r0_ram_base)
+LINKER_SYMBOL(bsp_r0_ram_end)
+LINKER_SYMBOL(bsp_r1_ram_base)
+LINKER_SYMBOL(bsp_r1_ram_end)
+
/**
* @brief Versal specific set up of the MMU.
*
@@ -70,6 +79,10 @@ BSP_START_TEXT_SECTION void versal_setup_mmu_and_cache(void);
void versal_debug_console_flush(void);
+uint32_t versal_clock_i2c0(void);
+
+uint32_t versal_clock_i2c1(void);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/bsps/aarch64/xilinx-versal/include/bsp/i2c.h b/bsps/aarch64/xilinx-versal/include/bsp/i2c.h
new file mode 100644
index 0000000000..116f8dd0cb
--- /dev/null
+++ b/bsps/aarch64/xilinx-versal/include/bsp/i2c.h
@@ -0,0 +1,64 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (C) 2022 Chris Johns <chris@contemporary.software>
+ * Copyright (C) 2014 embedded brains GmbH & Co. KG
+ *
+ * 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 LIBBSP_ARM_XILINX_VERSAL_I2C_H
+#define LIBBSP_ARM_XILINX_VERSAL_I2C_H
+
+#include <dev/i2c/cadence-i2c.h>
+#include <bsp/irq.h>
+#include <bsp.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+static inline int versal_register_i2c_0(void)
+{
+ return i2c_bus_register_cadence(
+ "/dev/i2c-0",
+ 0x00FF020000,
+ versal_clock_i2c0(),
+ VERSAL_IRQ_I2C_0
+ );
+}
+
+static inline int versal_register_i2c_1(void)
+{
+ return i2c_bus_register_cadence(
+ "/dev/i2c-1",
+ 0x00FF030000,
+ versal_clock_i2c1(),
+ VERSAL_IRQ_I2C_1
+ );
+}
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* LIBBSP_ARM_XILINX_VERSAL_I2C_H */
diff --git a/bsps/aarch64/xilinx-versal/include/bsp/irq.h b/bsps/aarch64/xilinx-versal/include/bsp/irq.h
index c5f199a9ae..b34bdfd345 100644
--- a/bsps/aarch64/xilinx-versal/include/bsp/irq.h
+++ b/bsps/aarch64/xilinx-versal/include/bsp/irq.h
@@ -53,6 +53,8 @@ extern "C" {
#define BSP_TIMER_VIRT_PPI 27
#define BSP_TIMER_PHYS_S_PPI 29
#define BSP_TIMER_PHYS_NS_PPI 30
+#define VERSAL_IRQ_I2C_0 46
+#define VERSAL_IRQ_I2C_1 47
#define VERSAL_IRQ_UART_0 50
#define VERSAL_IRQ_UART_1 51
#define VERSAL_IRQ_ETHERNET_0 88
diff --git a/bsps/aarch64/xilinx-versal/include/dev/serial/versal-uart-regs.h b/bsps/aarch64/xilinx-versal/include/dev/serial/versal-uart-regs.h
index 59db8f950a..30f918bc60 100644
--- a/bsps/aarch64/xilinx-versal/include/dev/serial/versal-uart-regs.h
+++ b/bsps/aarch64/xilinx-versal/include/dev/serial/versal-uart-regs.h
@@ -110,7 +110,6 @@ typedef struct versal_uart {
#define VERSAL_UARTCR_RXE BSP_BIT32(9)
#define VERSAL_UARTCR_TXE BSP_BIT32(8)
#define VERSAL_UARTCR_LBE BSP_BIT32(7)
-//#define VERSAL_UARTCR_SIREN BSP_BIT32()?
#define VERSAL_UARTCR_UARTEN BSP_BIT32(0)
uint32_t uartifls;
#define VERSAL_UARTIFLS_RXIFLSEL(val) BSP_FLD32(val, 3, 5)
diff --git a/bsps/aarch64/xilinx-versal/include/dev/serial/versal-uart.h b/bsps/aarch64/xilinx-versal/include/dev/serial/versal-uart.h
index 95b5172218..cc6b60b77c 100644
--- a/bsps/aarch64/xilinx-versal/include/dev/serial/versal-uart.h
+++ b/bsps/aarch64/xilinx-versal/include/dev/serial/versal-uart.h
@@ -54,7 +54,9 @@ extern "C" {
typedef struct {
rtems_termios_device_context base;
volatile struct versal_uart *regs;
- bool transmitting; /* Currently unused */
+ volatile size_t tx_queued;
+ volatile bool transmitting;
+ bool first_send;
rtems_vector_number irq;
} versal_uart_context;
diff --git a/bsps/aarch64/xilinx-versal/start/bspstart.c b/bsps/aarch64/xilinx-versal/start/bspstart.c
index 2f0048ddf3..89b06a0ff4 100644
--- a/bsps/aarch64/xilinx-versal/start/bspstart.c
+++ b/bsps/aarch64/xilinx-versal/start/bspstart.c
@@ -38,6 +38,18 @@
#include <bsp/irq-generic.h>
#include <bsp/linker-symbols.h>
+#include <rtems/score/basedefs.h>
+
+RTEMS_WEAK uint32_t versal_clock_i2c0(void)
+{
+ return VERSAL_CLOCK_I2C0;
+}
+
+RTEMS_WEAK uint32_t versal_clock_i2c1(void)
+{
+ return VERSAL_CLOCK_I2C1;
+}
+
void bsp_start( void )
{
bsp_interrupt_initialize();
diff --git a/bsps/aarch64/xilinx-versal/start/bspstarthooks.c b/bsps/aarch64/xilinx-versal/start/bspstarthooks.c
index be98675a24..71d161125b 100644
--- a/bsps/aarch64/xilinx-versal/start/bspstarthooks.c
+++ b/bsps/aarch64/xilinx-versal/start/bspstarthooks.c
@@ -35,11 +35,12 @@
*/
#include <bsp.h>
+#include <bsp/irq-generic.h>
#include <bsp/start.h>
BSP_START_TEXT_SECTION void bsp_start_hook_0(void)
{
- /* Do nothing */
+ bsp_interrupt_facility_initialize();
}
BSP_START_TEXT_SECTION void bsp_start_hook_1(void)
diff --git a/bsps/aarch64/xilinx-versal/start/bspstartmmu.c b/bsps/aarch64/xilinx-versal/start/bspstartmmu.c
index 6ab33cc4f1..ee87890293 100644
--- a/bsps/aarch64/xilinx-versal/start/bspstartmmu.c
+++ b/bsps/aarch64/xilinx-versal/start/bspstartmmu.c
@@ -36,11 +36,19 @@
#include <bsp.h>
#include <bsp/start.h>
#include <bsp/aarch64-mmu.h>
+#include <libcpu/mmu-vmsav8-64.h>
+
+#include <rtems/malloc.h>
+#include <rtems/sysinit.h>
BSP_START_DATA_SECTION static const aarch64_mmu_config_entry
versal_mmu_config_table[] = {
AARCH64_MMU_DEFAULT_SECTIONS,
- { /* APU GIC */
+ { /* Devices */
+ .begin = 0xf1000000U,
+ .end = 0xf2000000U,
+ .flags = AARCH64_MMU_DEVICE
+ }, { /* APU GIC */
.begin = 0xf9000000U,
.end = 0xf90c0000U,
.flags = AARCH64_MMU_DEVICE
@@ -56,6 +64,29 @@ versal_mmu_config_table[] = {
.begin = 0xff000000U,
.end = 0xffc00000U,
.flags = AARCH64_MMU_DEVICE
+ }, { /* DDRMC0_region1_mem, if not used size is 0 and ignored */
+ .begin = (uintptr_t) bsp_r1_ram_base,
+ .end = (uintptr_t) bsp_r1_ram_end,
+ .flags = AARCH64_MMU_DATA_RW_CACHED
+ }
+};
+
+/*
+ * Create an MMU table to get the R1 base and end. This avoids
+ * relocation errors as the R1 addresses are in the upper A64 address
+ * space.
+ *
+ * The versal_mmu_config_table table cannot be used because the regions
+ * in that table have no identifiers to indicate which region is the
+ * the DDRMC0_region1_mem region.
+ */
+static const struct mem_region {
+ uintptr_t begin;
+ uintptr_t end;
+} bsp_r1_region[] = {
+ { /* DDRMC0_region1_mem, if not used size is 0 and ignored */
+ .begin = (uintptr_t) bsp_r1_ram_base,
+ .end = (uintptr_t) bsp_r1_ram_end,
}
};
@@ -70,8 +101,33 @@ versal_setup_mmu_and_cache( void )
{
aarch64_mmu_setup();
- aarch64_mmu_setup_translation_table_and_enable(
+ aarch64_mmu_setup_translation_table(
&versal_mmu_config_table[ 0 ],
RTEMS_ARRAY_SIZE( versal_mmu_config_table )
);
+
+ aarch64_mmu_enable();
+}
+
+void bsp_r1_heap_extend(void);
+void bsp_r1_heap_extend(void)
+{
+ const struct mem_region* r1 = &bsp_r1_region[0];
+ if (r1->begin != r1->end) {
+ rtems_status_code sc =
+ rtems_heap_extend((void*) r1->begin, r1->end - r1->begin);
+ if (sc != RTEMS_SUCCESSFUL) {
+ bsp_fatal(BSP_FATAL_HEAP_EXTEND_ERROR);
+ }
+ }
}
+
+/*
+ * Initialise after the IDLE thread exists so the protected heap
+ * extend call has a valid context.
+ */
+RTEMS_SYSINIT_ITEM(
+ bsp_r1_heap_extend,
+ RTEMS_SYSINIT_IDLE_THREADS,
+ RTEMS_SYSINIT_ORDER_LAST
+);
diff --git a/bsps/aarch64/xilinx-zynqmp/console/console.c b/bsps/aarch64/xilinx-zynqmp/console/console.c
index d1948f1a0c..4023d5c6f3 100644
--- a/bsps/aarch64/xilinx-zynqmp/console/console.c
+++ b/bsps/aarch64/xilinx-zynqmp/console/console.c
@@ -9,7 +9,7 @@
*/
/*
- * Copyright (C) 2020 On-Line Applications Research Corporation (OAR)
+ * Copyright (C) 2022 On-Line Applications Research Corporation (OAR)
* Written by Kinsey Moore <kinsey.moore@oarcorp.com>
*
* Redistribution and use in source and binary forms, with or without
@@ -35,22 +35,163 @@
*/
#include <rtems/console.h>
-#include <rtems/bspIo.h>
+#include <rtems/endian.h>
#include <rtems/sysinit.h>
+#include <rtems/termiostypes.h>
+#include <bsp/aarch64-mmu.h>
+#include <bsp/fdt.h>
#include <bsp/irq.h>
+
#include <dev/serial/zynq-uart.h>
+#include <dev/serial/zynq-uart-regs.h>
#include <bspopts.h>
+#include <libfdt.h>
+
+#include <libchip/ns16550.h>
+
+uint32_t mgmt_uart_reg_shift = 0;
+static uint8_t get_register(uintptr_t addr, uint8_t i)
+{
+ volatile uint8_t *reg = (uint8_t *) addr;
+
+ i <<= mgmt_uart_reg_shift;
+ return reg [i];
+}
+
+static void set_register(uintptr_t addr, uint8_t i, uint8_t val)
+{
+ volatile uint8_t *reg = (uint8_t *) addr;
+
+ i <<= mgmt_uart_reg_shift;
+ reg [i] = val;
+}
+
+static ns16550_context zynqmp_mgmt_uart_context = {
+ .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("Management UART 0"),
+ .get_reg = get_register,
+ .set_reg = set_register,
+ .port = 0,
+ .irq = 0,
+ .clock = 0,
+ .initial_baud = 0,
+};
+
+__attribute__ ((weak)) void zynqmp_configure_management_console(rtems_termios_device_context *base)
+{
+ /* This SLIP-encoded watchdog command sets timeouts to 0xFFFFFFFF seconds. */
+ const char mgmt_watchdog_cmd[] =
+ "\xc0\xda\x00\x00\xff\xff\xff\xff\xff\x00\xff\xff\xff\xffM#\xc0";
+
+ /* Send the system watchdog configuration command */
+ for (int i = 0; i < sizeof(mgmt_watchdog_cmd); i++) {
+ ns16550_polled_putchar(base, mgmt_watchdog_cmd[i]);
+ }
+}
+
+static void zynqmp_management_console_init(void)
+{
+ /* Find the management console in the device tree */
+ const void *fdt = bsp_fdt_get();
+ const uint32_t *prop;
+ uint32_t outprop[4];
+ int proplen;
+ int node;
+
+ const char *alias = fdt_get_alias(fdt, "mgmtport");
+ if (alias == NULL) {
+ return;
+ }
+ node = fdt_path_offset(fdt, alias);
+
+ prop = fdt_getprop(fdt, node, "clock-frequency", &proplen);
+ if ( prop == NULL || proplen != 4 ) {
+ zynqmp_mgmt_uart_context.port = 0;
+ return;
+ }
+ outprop[0] = rtems_uint32_from_big_endian((const uint8_t *) &prop[0]);
+ zynqmp_mgmt_uart_context.clock = outprop[0];
+
+ prop = fdt_getprop(fdt, node, "current-speed", &proplen);
+ if ( prop == NULL || proplen != 4 ) {
+ zynqmp_mgmt_uart_context.port = 0;
+ return;
+ }
+ outprop[0] = rtems_uint32_from_big_endian((const uint8_t *) &prop[0]);
+ zynqmp_mgmt_uart_context.initial_baud = outprop[0];
+
+ prop = fdt_getprop(fdt, node, "interrupts", &proplen);
+ if ( prop == NULL || proplen != 12 ) {
+ zynqmp_mgmt_uart_context.port = 0;
+ return;
+ }
+ outprop[0] = rtems_uint32_from_big_endian((const uint8_t *) &prop[0]);
+ outprop[1] = rtems_uint32_from_big_endian((const uint8_t *) &prop[1]);
+ outprop[2] = rtems_uint32_from_big_endian((const uint8_t *) &prop[2]);
+ /* proplen is in bytes, interrupt mapping expects a length in 32-bit cells */
+ zynqmp_mgmt_uart_context.irq = bsp_fdt_map_intr(outprop, proplen / 4);
+ if ( zynqmp_mgmt_uart_context.irq == 0 ) {
+ zynqmp_mgmt_uart_context.port = 0;
+ return;
+ }
+
+ prop = fdt_getprop(fdt, node, "reg", &proplen);
+ if ( prop == NULL || proplen != 16 ) {
+ zynqmp_mgmt_uart_context.port = 0;
+ return;
+ }
+ outprop[0] = rtems_uint32_from_big_endian((const uint8_t *) &prop[0]);
+ outprop[1] = rtems_uint32_from_big_endian((const uint8_t *) &prop[1]);
+ outprop[2] = rtems_uint32_from_big_endian((const uint8_t *) &prop[2]);
+ outprop[3] = rtems_uint32_from_big_endian((const uint8_t *) &prop[3]);
+ zynqmp_mgmt_uart_context.port = ( ( (uint64_t) outprop[0] ) << 32 ) | outprop[1];
+ uintptr_t uart_base = zynqmp_mgmt_uart_context.port;
+ size_t uart_size = ( ( (uint64_t) outprop[2] ) << 32 ) | outprop[3];
+
+ rtems_status_code sc = aarch64_mmu_map( uart_base,
+ uart_size,
+ AARCH64_MMU_DEVICE);
+ if ( sc != RTEMS_SUCCESSFUL ) {
+ zynqmp_mgmt_uart_context.port = 0;
+ return;
+ }
+
+ prop = fdt_getprop(fdt, node, "reg-offset", &proplen);
+ if ( prop == NULL || proplen != 4 ) {
+ zynqmp_mgmt_uart_context.port = 0;
+ return;
+ }
+ outprop[0] = rtems_uint32_from_big_endian((const uint8_t *) &prop[0]);
+ zynqmp_mgmt_uart_context.port += outprop[0];
+
+ prop = fdt_getprop(fdt, node, "reg-shift", &proplen);
+ if ( prop == NULL || proplen != 4 ) {
+ zynqmp_mgmt_uart_context.port = 0;
+ return;
+ }
+ outprop[0] = rtems_uint32_from_big_endian((const uint8_t *) &prop[0]);
+ mgmt_uart_reg_shift = outprop[0];
+
+ ns16550_probe(&zynqmp_mgmt_uart_context.base);
+
+ zynqmp_configure_management_console(&zynqmp_mgmt_uart_context.base);
+}
+
+RTEMS_SYSINIT_ITEM(
+ zynqmp_management_console_init,
+ RTEMS_SYSINIT_BSP_START,
+ RTEMS_SYSINIT_ORDER_FIRST
+);
static zynq_uart_context zynqmp_uart_instances[2] = {
{
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "Zynq UART 0" ),
- .regs = (volatile struct zynq_uart *) 0xff010000,
+ .regs = (volatile zynq_uart *) ZYNQ_UART_0_BASE_ADDR,
.irq = ZYNQMP_IRQ_UART_0
}, {
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "Zynq UART 1" ),
- .regs = (volatile struct zynq_uart *) 0xff000000,
+ .regs = (volatile zynq_uart *) ZYNQ_UART_1_BASE_ADDR,
.irq = ZYNQMP_IRQ_UART_1
}
};
@@ -66,6 +207,7 @@ rtems_status_code console_initialize(
rtems_termios_initialize();
for (i = 0; i < RTEMS_ARRAY_SIZE(zynqmp_uart_instances); ++i) {
+ zynq_uart_context *ctx = &zynqmp_uart_instances[i];
char uart[] = "/dev/ttySX";
uart[sizeof(uart) - 2] = (char) ('0' + i);
@@ -73,63 +215,27 @@ rtems_status_code console_initialize(
&uart[0],
&zynq_uart_handler,
NULL,
- &zynqmp_uart_instances[i].base
+ &ctx->base
);
- if (i == BSP_CONSOLE_MINOR) {
+ if (ctx->regs == (zynq_uart *) ZYNQ_UART_KERNEL_IO_BASE_ADDR) {
link(&uart[0], CONSOLE_DEVICE_NAME);
}
}
+ if ( zynqmp_mgmt_uart_context.port != 0 ) {
+ rtems_termios_device_install(
+ "/dev/ttyMGMT0",
+ &ns16550_handler_interrupt,
+ NULL,
+ &zynqmp_mgmt_uart_context.base
+ );
+ }
+
return RTEMS_SUCCESSFUL;
}
void zynqmp_debug_console_flush(void)
{
- zynq_uart_reset_tx_flush(&zynqmp_uart_instances[BSP_CONSOLE_MINOR]);
-}
-
-static void zynqmp_debug_console_out(char c)
-{
- rtems_termios_device_context *base =
- &zynqmp_uart_instances[BSP_CONSOLE_MINOR].base;
-
- zynq_uart_write_polled(base, c);
-}
-
-static void zynqmp_debug_console_init(void)
-{
- rtems_termios_device_context *base =
- &zynqmp_uart_instances[BSP_CONSOLE_MINOR].base;
-
- zynq_uart_initialize(base);
- BSP_output_char = zynqmp_debug_console_out;
+ zynq_uart_reset_tx_flush((zynq_uart *) ZYNQ_UART_KERNEL_IO_BASE_ADDR);
}
-
-static void zynqmp_debug_console_early_init(char c)
-{
- rtems_termios_device_context *base =
- &zynqmp_uart_instances[BSP_CONSOLE_MINOR].base;
-
- zynq_uart_initialize(base);
- BSP_output_char = zynqmp_debug_console_out;
- zynqmp_debug_console_out(c);
-}
-
-static int zynqmp_debug_console_in(void)
-{
- rtems_termios_device_context *base =
- &zynqmp_uart_instances[BSP_CONSOLE_MINOR].base;
-
- return zynq_uart_read_polled(base);
-}
-
-BSP_output_char_function_type BSP_output_char = zynqmp_debug_console_early_init;
-
-BSP_polling_getchar_function_type BSP_poll_char = zynqmp_debug_console_in;
-
-RTEMS_SYSINIT_ITEM(
- zynqmp_debug_console_init,
- RTEMS_SYSINIT_BSP_START,
- RTEMS_SYSINIT_ORDER_LAST_BUT_5
-);
diff --git a/bsps/aarch64/xilinx-zynqmp/fdt/bsp_fdt.c b/bsps/aarch64/xilinx-zynqmp/fdt/bsp_fdt.c
new file mode 100644
index 0000000000..0748639256
--- /dev/null
+++ b/bsps/aarch64/xilinx-zynqmp/fdt/bsp_fdt.c
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSBSPsAArch64XilinxZynqMP
+ *
+ * @brief This source file contains the implementatin of bsp_fdt_get().
+ */
+
+/*
+ * Copyright (C) 2022 On-Line Applications Research Corporation (OAR)
+ * Written by Kinsey Moore <kinsey.moore@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.
+ */
+
+#include <bsp.h>
+#include <bsp/fdt.h>
+
+const void *bsp_fdt_get(void)
+{
+ return zynqmp_dtb;
+}
+
+uint32_t bsp_fdt_map_intr(const uint32_t *intr, size_t icells)
+{
+ if (icells != 3) {
+ return 0;
+ }
+ return (intr[0] == 0 ? 32 : 16) + intr[1];
+}
diff --git a/bsps/aarch64/xilinx-zynqmp/fdt/cfc400x.dts b/bsps/aarch64/xilinx-zynqmp/fdt/cfc400x.dts
new file mode 100644
index 0000000000..05647e0848
--- /dev/null
+++ b/bsps/aarch64/xilinx-zynqmp/fdt/cfc400x.dts
@@ -0,0 +1,114 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSBSPsAArch64XilinxZynqMP
+ *
+ * @brief This file provides the CFC-400X device tree
+ */
+
+/*
+ * Copyright (C) 2022 On-Line Applications Research Corporation (OAR)
+ * Written by Kinsey Moore <kinsey.moore@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.
+ */
+
+/dts-v1/;
+
+/ {
+ #address-cells = <0x02>;
+ #size-cells = <0x02>;
+
+ amba {
+ compatible = "simple-bus";
+ #address-cells = <0x02>;
+ #size-cells = <0x02>;
+ ranges;
+
+ interrupt-controller@f9010000 {
+ compatible = "arm,gic-400";
+ #address-cells = <0x02>;
+ #interrupt-cells = <0x03>;
+ reg = <0x00 0xf9010000 0x00 0x10000>;
+ interrupt-controller;
+ phandle = <0x01>;
+ };
+
+ ethernet@ff0b0000 {
+ compatible = "cdns,gem";
+ status = "okay";
+ interrupt-parent = <0x01>;
+ interrupts = <0x00 0x39 0x04>;
+ reg = <0x00 0xff0b0000 0x00 0x1000>;
+ phy-mode = "sgmii";
+ ref-clock-num = <0>;
+ };
+
+ ethernet@ff0c0000 {
+ compatible = "cdns,gem";
+ status = "okay";
+ interrupt-parent = <0x01>;
+ interrupts = <0x00 0x3b 0x04>;
+ reg = <0x00 0xff0c0000 0x00 0x1000>;
+ phy-mode = "sgmii";
+ ref-clock-num = <1>;
+ };
+
+ ethernet@ff0d0000 {
+ compatible = "cdns,gem";
+ status = "okay";
+ interrupt-parent = <0x01>;
+ interrupts = <0x00 0x3d 0x04>;
+ reg = <0x00 0xff0d0000 0x00 0x1000>;
+ phy-mode = "sgmii";
+ ref-clock-num = <2>;
+ };
+
+ ethernet@ff0e0000 {
+ compatible = "cdns,gem";
+ status = "okay";
+ interrupt-parent = <0x01>;
+ interrupts = <0x00 0x3f 0x04>;
+ reg = <0x00 0xff0e0000 0x00 0x1000>;
+ phy-mode = "sgmii";
+ ref-clock-num = <3>;
+ };
+
+ serial@800a0000 {
+ clock-frequency = <0x189c000>;
+ compatible = "ns16550a";
+ current-speed = <0x1c200>;
+ device_type = "serial";
+ interrupt-parent = <0x01>;
+ interrupts = <0x00 0x6e 0x04>;
+ reg = <0x00 0x800a0000 0x00 0x10000>;
+ reg-offset = <0x1000>;
+ reg-shift = <0x02>;
+ };
+ };
+
+ aliases {
+ mgmtport = "/amba/serial@800a0000";
+ };
+};
diff --git a/bsps/aarch64/xilinx-zynqmp/fdt/cfc400x_dtb.c b/bsps/aarch64/xilinx-zynqmp/fdt/cfc400x_dtb.c
new file mode 100644
index 0000000000..7a45b4f7dd
--- /dev/null
+++ b/bsps/aarch64/xilinx-zynqmp/fdt/cfc400x_dtb.c
@@ -0,0 +1,130 @@
+unsigned char zynqmp_dtb[] = {
+ 0xd0, 0x0d, 0xfe, 0xed, 0x00, 0x00, 0x05, 0xf1, 0x00, 0x00, 0x00, 0x38,
+ 0x00, 0x00, 0x05, 0x10, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1,
+ 0x00, 0x00, 0x04, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x01, 0x61, 0x6d, 0x62, 0x61, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x1b,
+ 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x2d, 0x62, 0x75, 0x73, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x01,
+ 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, 0x70, 0x74, 0x2d, 0x63, 0x6f,
+ 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x40, 0x66, 0x39, 0x30,
+ 0x31, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x1b, 0x61, 0x72, 0x6d, 0x2c,
+ 0x67, 0x69, 0x63, 0x2d, 0x34, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x2d,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x65, 0x74, 0x68, 0x65,
+ 0x72, 0x6e, 0x65, 0x74, 0x40, 0x66, 0x66, 0x30, 0x62, 0x30, 0x30, 0x30,
+ 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x09,
+ 0x00, 0x00, 0x00, 0x1b, 0x63, 0x64, 0x6e, 0x73, 0x2c, 0x67, 0x65, 0x6d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05,
+ 0x00, 0x00, 0x00, 0x5f, 0x6f, 0x6b, 0x61, 0x79, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x66,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0c,
+ 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0b, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x82, 0x73, 0x67, 0x6d, 0x69,
+ 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x01, 0x65, 0x74, 0x68, 0x65, 0x72, 0x6e, 0x65, 0x74,
+ 0x40, 0x66, 0x66, 0x30, 0x63, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x1b,
+ 0x63, 0x64, 0x6e, 0x73, 0x2c, 0x67, 0x65, 0x6d, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x5f,
+ 0x6f, 0x6b, 0x61, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x77,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x3e,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06,
+ 0x00, 0x00, 0x00, 0x82, 0x73, 0x67, 0x6d, 0x69, 0x69, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x8b,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
+ 0x65, 0x74, 0x68, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x40, 0x66, 0x66, 0x30,
+ 0x64, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x1b, 0x63, 0x64, 0x6e, 0x73,
+ 0x2c, 0x67, 0x65, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x5f, 0x6f, 0x6b, 0x61, 0x79,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x82,
+ 0x73, 0x67, 0x6d, 0x69, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x65, 0x74, 0x68, 0x65,
+ 0x72, 0x6e, 0x65, 0x74, 0x40, 0x66, 0x66, 0x30, 0x65, 0x30, 0x30, 0x30,
+ 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x09,
+ 0x00, 0x00, 0x00, 0x1b, 0x63, 0x64, 0x6e, 0x73, 0x2c, 0x67, 0x65, 0x6d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05,
+ 0x00, 0x00, 0x00, 0x5f, 0x6f, 0x6b, 0x61, 0x79, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x66,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0c,
+ 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0e, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x82, 0x73, 0x67, 0x6d, 0x69,
+ 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x01, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x40, 0x38,
+ 0x30, 0x30, 0x61, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x99, 0x01, 0x89, 0xc0, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x1b,
+ 0x6e, 0x73, 0x31, 0x36, 0x35, 0x35, 0x30, 0x61, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xa9,
+ 0x00, 0x01, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07,
+ 0x00, 0x00, 0x00, 0xb7, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x66,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0c,
+ 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0a, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x10, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xce,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x01, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0xd8,
+ 0x2f, 0x61, 0x6d, 0x62, 0x61, 0x2f, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c,
+ 0x40, 0x38, 0x30, 0x30, 0x61, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09,
+ 0x23, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x2d, 0x63, 0x65, 0x6c,
+ 0x6c, 0x73, 0x00, 0x23, 0x73, 0x69, 0x7a, 0x65, 0x2d, 0x63, 0x65, 0x6c,
+ 0x6c, 0x73, 0x00, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x6c,
+ 0x65, 0x00, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x00, 0x23, 0x69, 0x6e,
+ 0x74, 0x65, 0x72, 0x72, 0x75, 0x70, 0x74, 0x2d, 0x63, 0x65, 0x6c, 0x6c,
+ 0x73, 0x00, 0x72, 0x65, 0x67, 0x00, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72,
+ 0x75, 0x70, 0x74, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c,
+ 0x65, 0x72, 0x00, 0x70, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x00, 0x73,
+ 0x74, 0x61, 0x74, 0x75, 0x73, 0x00, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72,
+ 0x75, 0x70, 0x74, 0x2d, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x00, 0x69,
+ 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, 0x70, 0x74, 0x73, 0x00, 0x70, 0x68,
+ 0x79, 0x2d, 0x6d, 0x6f, 0x64, 0x65, 0x00, 0x72, 0x65, 0x66, 0x2d, 0x63,
+ 0x6c, 0x6f, 0x63, 0x6b, 0x2d, 0x6e, 0x75, 0x6d, 0x00, 0x63, 0x6c, 0x6f,
+ 0x63, 0x6b, 0x2d, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79,
+ 0x00, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x2d, 0x73, 0x70, 0x65,
+ 0x65, 0x64, 0x00, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x74, 0x79,
+ 0x70, 0x65, 0x00, 0x72, 0x65, 0x67, 0x2d, 0x6f, 0x66, 0x66, 0x73, 0x65,
+ 0x74, 0x00, 0x72, 0x65, 0x67, 0x2d, 0x73, 0x68, 0x69, 0x66, 0x74, 0x00,
+ 0x6d, 0x67, 0x6d, 0x74, 0x70, 0x6f, 0x72, 0x74, 0x00
+};
+unsigned int zynqmp_dtb_len = 1521;
diff --git a/bsps/aarch64/xilinx-zynqmp/fdt/zynqmp.dts b/bsps/aarch64/xilinx-zynqmp/fdt/zynqmp.dts
new file mode 100644
index 0000000000..ec13563072
--- /dev/null
+++ b/bsps/aarch64/xilinx-zynqmp/fdt/zynqmp.dts
@@ -0,0 +1,98 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSBSPsAArch64XilinxZynqMP
+ *
+ * @brief This file provides the base ZynqMP device tree
+ */
+
+/*
+ * Copyright (C) 2022 On-Line Applications Research Corporation (OAR)
+ * Written by Kinsey Moore <kinsey.moore@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.
+ */
+
+/dts-v1/;
+
+/ {
+ #address-cells = <0x02>;
+ #size-cells = <0x02>;
+
+ amba {
+ compatible = "simple-bus";
+ #address-cells = <0x02>;
+ #size-cells = <0x02>;
+ ranges;
+
+ interrupt-controller@f9010000 {
+ compatible = "arm,gic-400";
+ #address-cells = <0x02>;
+ #interrupt-cells = <0x03>;
+ reg = <0x00 0xf9010000 0x00 0x10000>;
+ interrupt-controller;
+ phandle = <0x01>;
+ };
+
+ ethernet@ff0b0000 {
+ compatible = "cdns,gem";
+ status = "okay";
+ interrupt-parent = <0x01>;
+ interrupts = <0x00 0x39 0x04>;
+ reg = <0x00 0xff0b0000 0x00 0x1000>;
+ phy-mode = "rgmii-id";
+ ref-clock-num = <0>;
+ };
+
+ ethernet@ff0c0000 {
+ compatible = "cdns,gem";
+ status = "okay";
+ interrupt-parent = <0x01>;
+ interrupts = <0x00 0x3b 0x04>;
+ reg = <0x00 0xff0c0000 0x00 0x1000>;
+ phy-mode = "rgmii-id";
+ ref-clock-num = <1>;
+ };
+
+ ethernet@ff0d0000 {
+ compatible = "cdns,gem";
+ status = "okay";
+ interrupt-parent = <0x01>;
+ interrupts = <0x00 0x3d 0x04>;
+ reg = <0x00 0xff0d0000 0x00 0x1000>;
+ phy-mode = "rgmii-id";
+ ref-clock-num = <2>;
+ };
+
+ ethernet@ff0e0000 {
+ compatible = "cdns,gem";
+ status = "okay";
+ interrupt-parent = <0x01>;
+ interrupts = <0x00 0x3f 0x04>;
+ reg = <0x00 0xff0e0000 0x00 0x1000>;
+ phy-mode = "rgmii-id";
+ ref-clock-num = <3>;
+ };
+ };
+};
diff --git a/bsps/aarch64/xilinx-zynqmp/fdt/zynqmp_dtb.c b/bsps/aarch64/xilinx-zynqmp/fdt/zynqmp_dtb.c
new file mode 100644
index 0000000000..677dca3ea4
--- /dev/null
+++ b/bsps/aarch64/xilinx-zynqmp/fdt/zynqmp_dtb.c
@@ -0,0 +1,105 @@
+unsigned char zynqmp_dtb[] = {
+ 0xd0, 0x0d, 0xfe, 0xed, 0x00, 0x00, 0x04, 0xbd, 0x00, 0x00, 0x00, 0x38,
+ 0x00, 0x00, 0x04, 0x24, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x11,
+ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99,
+ 0x00, 0x00, 0x03, 0xec, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x01, 0x61, 0x6d, 0x62, 0x61, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x1b,
+ 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x2d, 0x62, 0x75, 0x73, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x01,
+ 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, 0x70, 0x74, 0x2d, 0x63, 0x6f,
+ 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x40, 0x66, 0x39, 0x30,
+ 0x31, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x1b, 0x61, 0x72, 0x6d, 0x2c,
+ 0x67, 0x69, 0x63, 0x2d, 0x34, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x2d,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x65, 0x74, 0x68, 0x65,
+ 0x72, 0x6e, 0x65, 0x74, 0x40, 0x66, 0x66, 0x30, 0x62, 0x30, 0x30, 0x30,
+ 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x09,
+ 0x00, 0x00, 0x00, 0x1b, 0x63, 0x64, 0x6e, 0x73, 0x2c, 0x67, 0x65, 0x6d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05,
+ 0x00, 0x00, 0x00, 0x5f, 0x6f, 0x6b, 0x61, 0x79, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x66,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0c,
+ 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0b, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x82, 0x72, 0x67, 0x6d, 0x69,
+ 0x69, 0x2d, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x65, 0x74, 0x68, 0x65,
+ 0x72, 0x6e, 0x65, 0x74, 0x40, 0x66, 0x66, 0x30, 0x63, 0x30, 0x30, 0x30,
+ 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x09,
+ 0x00, 0x00, 0x00, 0x1b, 0x63, 0x64, 0x6e, 0x73, 0x2c, 0x67, 0x65, 0x6d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05,
+ 0x00, 0x00, 0x00, 0x5f, 0x6f, 0x6b, 0x61, 0x79, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x66,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0c,
+ 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x82, 0x72, 0x67, 0x6d, 0x69,
+ 0x69, 0x2d, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x65, 0x74, 0x68, 0x65,
+ 0x72, 0x6e, 0x65, 0x74, 0x40, 0x66, 0x66, 0x30, 0x64, 0x30, 0x30, 0x30,
+ 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x09,
+ 0x00, 0x00, 0x00, 0x1b, 0x63, 0x64, 0x6e, 0x73, 0x2c, 0x67, 0x65, 0x6d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05,
+ 0x00, 0x00, 0x00, 0x5f, 0x6f, 0x6b, 0x61, 0x79, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x66,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0c,
+ 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x82, 0x72, 0x67, 0x6d, 0x69,
+ 0x69, 0x2d, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x65, 0x74, 0x68, 0x65,
+ 0x72, 0x6e, 0x65, 0x74, 0x40, 0x66, 0x66, 0x30, 0x65, 0x30, 0x30, 0x30,
+ 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x09,
+ 0x00, 0x00, 0x00, 0x1b, 0x63, 0x64, 0x6e, 0x73, 0x2c, 0x67, 0x65, 0x6d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05,
+ 0x00, 0x00, 0x00, 0x5f, 0x6f, 0x6b, 0x61, 0x79, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x66,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0c,
+ 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0e, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x82, 0x72, 0x67, 0x6d, 0x69,
+ 0x69, 0x2d, 0x69, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x09, 0x23, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73,
+ 0x2d, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x00, 0x23, 0x73, 0x69, 0x7a, 0x65,
+ 0x2d, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x00, 0x63, 0x6f, 0x6d, 0x70, 0x61,
+ 0x74, 0x69, 0x62, 0x6c, 0x65, 0x00, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73,
+ 0x00, 0x23, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, 0x70, 0x74, 0x2d,
+ 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x00, 0x72, 0x65, 0x67, 0x00, 0x69, 0x6e,
+ 0x74, 0x65, 0x72, 0x72, 0x75, 0x70, 0x74, 0x2d, 0x63, 0x6f, 0x6e, 0x74,
+ 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x00, 0x70, 0x68, 0x61, 0x6e, 0x64,
+ 0x6c, 0x65, 0x00, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x00, 0x69, 0x6e,
+ 0x74, 0x65, 0x72, 0x72, 0x75, 0x70, 0x74, 0x2d, 0x70, 0x61, 0x72, 0x65,
+ 0x6e, 0x74, 0x00, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, 0x70, 0x74,
+ 0x73, 0x00, 0x70, 0x68, 0x79, 0x2d, 0x6d, 0x6f, 0x64, 0x65, 0x00, 0x72,
+ 0x65, 0x66, 0x2d, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x2d, 0x6e, 0x75, 0x6d,
+ 0x00
+};
+unsigned int zynqmp_dtb_len = 1213;
diff --git a/bsps/aarch64/xilinx-zynqmp/include/bsp.h b/bsps/aarch64/xilinx-zynqmp/include/bsp.h
index 6d49b9ad2a..38a9fad768 100644
--- a/bsps/aarch64/xilinx-zynqmp/include/bsp.h
+++ b/bsps/aarch64/xilinx-zynqmp/include/bsp.h
@@ -45,12 +45,17 @@
#include <bspopts.h>
+#define BSP_FEATURE_IRQ_EXTENSION
+
#ifndef ASM
#include <bsp/default-initial-extension.h>
#include <bsp/start.h>
#include <rtems.h>
+#include <rtems/termiostypes.h>
+
+#include <dev/serial/zynq-uart-zynqmp.h>
#ifdef __cplusplus
extern "C" {
@@ -60,6 +65,13 @@ extern "C" {
#define BSP_ARM_GIC_DIST_BASE 0xf9010000
#define BSP_RESET_SMC
+#define BSP_CPU_ON_USES_SMC
+
+#define BSP_FDT_IS_SUPPORTED
+extern unsigned int zynqmp_dtb_len;
+extern unsigned char zynqmp_dtb[];
+
+#define NANDPSU_BASEADDR 0xFF100000
/**
* @brief Zynq UltraScale+ MPSoC specific set up of the MMU.
@@ -68,12 +80,30 @@ extern "C" {
*/
BSP_START_TEXT_SECTION void zynqmp_setup_mmu_and_cache(void);
+/**
+ * @brief Zynq UltraScale+ MPSoC specific set up of the MMU for non-primary
+ * cores.
+ *
+ * Provide in the application to override the defaults in the BSP.
+ */
+BSP_START_TEXT_SECTION void zynqmp_setup_secondary_cpu_mmu_and_cache( void );
+
void zynqmp_debug_console_flush(void);
uint32_t zynqmp_clock_i2c0(void);
uint32_t zynqmp_clock_i2c1(void);
+/**
+ * @brief Zynq UltraScale+ MPSoC specific set up of a management console.
+ *
+ * Some systems may have a management interface which needs special
+ * initialization. Provide in the application to override the defaults in the
+ * BSP. This will only be called if the interface is found in the device tree.
+ */
+__attribute__ ((weak))
+void zynqmp_configure_management_console(rtems_termios_device_context *base);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/bsps/aarch64/xilinx-zynqmp/include/bsp/i2c.h b/bsps/aarch64/xilinx-zynqmp/include/bsp/i2c.h
index a83d9ed467..f79006b94c 100644
--- a/bsps/aarch64/xilinx-zynqmp/include/bsp/i2c.h
+++ b/bsps/aarch64/xilinx-zynqmp/include/bsp/i2c.h
@@ -2,7 +2,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (C) 2021 On-Line Applications Research (OAR)
- * Copyright (C) 2014 embedded brains GmbH
+ * Copyright (C) 2014 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/bsps/aarch64/xilinx-zynqmp/include/bsp/irq.h b/bsps/aarch64/xilinx-zynqmp/include/bsp/irq.h
index 9af41643bd..024fd0d89a 100644
--- a/bsps/aarch64/xilinx-zynqmp/include/bsp/irq.h
+++ b/bsps/aarch64/xilinx-zynqmp/include/bsp/irq.h
@@ -48,15 +48,16 @@
extern "C" {
#endif /* __cplusplus */
-#define BSP_INTERRUPT_VECTOR_COUNT 1024
+#define BSP_INTERRUPT_VECTOR_COUNT 192
/* Interrupts vectors */
#define BSP_TIMER_VIRT_PPI 27
#define BSP_TIMER_PHYS_NS_PPI 30
+#define ZYNQMP_IRQ_QSPI 47
#define ZYNQMP_IRQ_I2C_0 49
#define ZYNQMP_IRQ_I2C_1 50
-#define ZYNQMP_IRQ_UART_0 54
-#define ZYNQMP_IRQ_UART_1 53
+#define ZYNQMP_IRQ_UART_0 53
+#define ZYNQMP_IRQ_UART_1 54
#define ZYNQMP_IRQ_ETHERNET_0 89
#define ZYNQMP_IRQ_ETHERNET_1 91
#define ZYNQMP_IRQ_ETHERNET_2 93
diff --git a/bsps/aarch64/xilinx-zynqmp/include/bsp/jffs2_xnandpsu.h b/bsps/aarch64/xilinx-zynqmp/include/bsp/jffs2_xnandpsu.h
new file mode 100644
index 0000000000..6b55e50b2b
--- /dev/null
+++ b/bsps/aarch64/xilinx-zynqmp/include/bsp/jffs2_xnandpsu.h
@@ -0,0 +1,56 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (C) 2023 On-Line Applications Research Corporation (OAR)
+ *
+ * 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 LIBBSP_XILINX_ZYNQMP_JFFS2_XNANDPSU_H
+#define LIBBSP_XILINX_ZYNQMP_JFFS2_XNANDPSU_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+#include <dev/nand/xnandpsu.h>
+#include <rtems/jffs2.h>
+
+/**
+ * @brief Mount JFFS2 filesystem on NAND device.
+ *
+ * @param[in] mount_dir The directory to mount the filesystem at.
+ * @param[in] NandPsuInstancePtr A pointer to an initialized NAND instance.
+ *
+ * @retval 0 Successful operation. Negative number otherwise.
+ */
+int xilinx_zynqmp_nand_jffs2_initialize(
+ const char *mount_dir,
+ XNandPsu *NandPsuInstancePtr
+);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* LIBBSP_XILINX_ZYNQMP_JFFS2_XNANDPSU_H */
diff --git a/bsps/aarch64/xilinx-zynqmp/include/bsp/jffs2_xqspipsu.h b/bsps/aarch64/xilinx-zynqmp/include/bsp/jffs2_xqspipsu.h
new file mode 100644
index 0000000000..5f05308a1f
--- /dev/null
+++ b/bsps/aarch64/xilinx-zynqmp/include/bsp/jffs2_xqspipsu.h
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSBSPsAArch64XilinxZynqMP
+ *
+ * @brief XilinxZynqMP QSPI JFFS2 flash driver definitions
+ */
+
+/*
+ * Copyright (C) 2022 On-Line Applications Research Corporation (OAR)
+ *
+ * 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 LIBBSP_XILINX_ZYNQMP_JFFS2_XQSPIPSU_H
+#define LIBBSP_XILINX_ZYNQMP_JFFS2_XQSPIPSU_H
+
+#include <dev/spi/xqspipsu.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @brief Mount jffs2 filesystem.
+ *
+ * @param[in] mount_dir The directory to mount the filesystem at.
+ * @param[in] qspipsu_ptr A pointer to an initialized QSPI instance.
+ *
+ * @retval 0 Successful operation. Negative number otherwise.
+ */
+int xilinx_zynqmp_nor_jffs2_initialize(
+ const char *mount_dir,
+ XQspiPsu *qspipsu_ptr
+);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* LIBBSP_XILINX_ZYNQMP_JFFS2_XQSPIPSU_H */
diff --git a/bsps/aarch64/xilinx-zynqmp/jffs2_xnandpsu.c b/bsps/aarch64/xilinx-zynqmp/jffs2_xnandpsu.c
new file mode 100644
index 0000000000..3fa70cc0c3
--- /dev/null
+++ b/bsps/aarch64/xilinx-zynqmp/jffs2_xnandpsu.c
@@ -0,0 +1,375 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (C) 2023 On-Line Applications Research Corporation (OAR)
+ *
+ * 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.
+ */
+
+/*
+ * This file contains an implementation of a basic JFFS2 filesystem adapter for
+ * the NandPsu peripheral that uses the entirety of the available NAND chip(s)
+ * for a JFFS2 filesystem or up to the maximum size possible. If an
+ * implementation would prefer to only use a portion of the NAND flash chip,
+ * this template would need rework to account for a reduced size and possibly a
+ * start offset while also taking into account the driver's handling of bad
+ * blocks and how that might affect the offset.
+ */
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include <bsp/jffs2_xnandpsu.h>
+#include <rtems/libio.h>
+#include <rtems/libcsupport.h>
+#include <rtems/malloc.h>
+#include <rtems/thread.h>
+#include <dev/nand/xnandpsu_bbm.h>
+
+typedef struct {
+ rtems_jffs2_flash_control super;
+ XNandPsu *nandpsu;
+ rtems_mutex access_lock;
+} flash_control;
+
+static flash_control *get_flash_control(rtems_jffs2_flash_control *super)
+{
+ return (flash_control *) super;
+}
+
+static int flash_read(
+ rtems_jffs2_flash_control *super,
+ uint32_t offset,
+ unsigned char *buffer,
+ size_t size_of_buffer
+)
+{
+ XNandPsu *nandpsu = get_flash_control(super)->nandpsu;
+ rtems_status_code sc;
+
+ rtems_mutex_lock(&(get_flash_control(super)->access_lock));
+ sc = XNandPsu_Read(nandpsu, offset, size_of_buffer, buffer);
+ rtems_mutex_unlock(&(get_flash_control(super)->access_lock));
+ if (sc) {
+ return -EIO;
+ }
+ return 0;
+}
+
+static int flash_write(
+ rtems_jffs2_flash_control *super,
+ uint32_t offset,
+ const unsigned char *buffer,
+ size_t size_of_buffer
+)
+{
+ XNandPsu *nandpsu = get_flash_control(super)->nandpsu;
+ rtems_status_code sc;
+
+ rtems_mutex_lock(&(get_flash_control(super)->access_lock));
+ sc = XNandPsu_Write(nandpsu, offset, size_of_buffer, (void *)buffer);
+ rtems_mutex_unlock(&(get_flash_control(super)->access_lock));
+ if (sc) {
+ return -EIO;
+ }
+ return 0;
+}
+
+static int flash_erase(
+ rtems_jffs2_flash_control *super,
+ uint32_t offset
+)
+{
+ XNandPsu *nandpsu = get_flash_control(super)->nandpsu;
+ rtems_status_code sc;
+ uint64_t BlockSize = nandpsu->Geometry.BlockSize;
+
+ if (offset > nandpsu->Geometry.DeviceSize) {
+ return -EIO;
+ }
+
+ /* Perform erase operation. */
+ rtems_mutex_lock(&(get_flash_control(super)->access_lock));
+ sc = XNandPsu_Erase(nandpsu, RTEMS_ALIGN_DOWN(offset, BlockSize), BlockSize);
+ rtems_mutex_unlock(&(get_flash_control(super)->access_lock));
+ if (sc ) {
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int flash_block_is_bad(
+ rtems_jffs2_flash_control *super,
+ uint32_t offset,
+ bool *bad
+)
+{
+ XNandPsu *nandpsu = get_flash_control(super)->nandpsu;
+ uint32_t BlockIndex;
+ uint8_t BlockData;
+ uint8_t BlockShift;
+ uint8_t BlockType;
+ uint32_t BlockOffset;
+
+ assert(bad);
+
+ if (offset > nandpsu->Geometry.DeviceSize) {
+ return -EIO;
+ }
+
+ *bad = true;
+
+ BlockIndex = offset / nandpsu->Geometry.BlockSize;
+
+ rtems_mutex_lock(&(get_flash_control(super)->access_lock));
+
+ /* XNandPsu_IsBlockBad() is insufficient for this use case */
+ BlockOffset = BlockIndex >> XNANDPSU_BBT_BLOCK_SHIFT;
+ BlockShift = XNandPsu_BbtBlockShift(BlockIndex);
+ BlockData = nandpsu->Bbt[BlockOffset];
+ BlockType = (BlockData >> BlockShift) & XNANDPSU_BLOCK_TYPE_MASK;
+
+ if (BlockType == XNANDPSU_BLOCK_GOOD) {
+ *bad = false;
+ }
+
+ int TargetBlockIndex = BlockIndex % nandpsu->Geometry.NumTargetBlocks;
+ /* The last 4 blocks of every device target are reserved for the BBT */
+ if (nandpsu->Geometry.NumTargetBlocks - TargetBlockIndex <= 4) {
+ *bad = true;
+ }
+
+ rtems_mutex_unlock(&(get_flash_control(super)->access_lock));
+ return 0;
+}
+
+static int flash_block_mark_bad(
+ rtems_jffs2_flash_control *super,
+ uint32_t offset
+)
+{
+ rtems_status_code sc;
+ XNandPsu *nandpsu = get_flash_control(super)->nandpsu;
+ uint32_t BlockIndex;
+
+ if (offset > nandpsu->Geometry.DeviceSize) {
+ return -EIO;
+ }
+
+ BlockIndex = offset / nandpsu->Geometry.BlockSize;
+
+ rtems_mutex_lock(&(get_flash_control(super)->access_lock));
+ sc = XNandPsu_MarkBlockBad(nandpsu, BlockIndex);
+ rtems_mutex_unlock(&(get_flash_control(super)->access_lock));
+ if ( sc != XST_SUCCESS ) {
+ return -EIO;
+ }
+ return RTEMS_SUCCESSFUL;
+}
+
+static int flash_read_oob_locked(
+ rtems_jffs2_flash_control *super,
+ uint32_t offset,
+ uint8_t *oobbuf,
+ uint32_t ooblen
+)
+{
+ uint8_t *spare_bytes;
+ XNandPsu *nandpsu = get_flash_control(super)->nandpsu;
+ uint32_t SpareBytesPerPage = nandpsu->Geometry.SpareBytesPerPage;
+
+ if (offset > nandpsu->Geometry.DeviceSize) {
+ return -EIO;
+ }
+
+ /* Can't request more spare bytes than exist */
+ if (ooblen > SpareBytesPerPage * nandpsu->Geometry.PagesPerBlock) {
+ return -EIO;
+ }
+
+ /* Get page index */
+ uint32_t PageIndex = offset / nandpsu->Geometry.BytesPerPage;
+
+ spare_bytes = rtems_malloc(SpareBytesPerPage);
+ if (spare_bytes == NULL) {
+ return -ENOMEM;
+ }
+
+ while (ooblen) {
+ int rv = XNandPsu_ReadSpareBytes(nandpsu, PageIndex, spare_bytes);
+ /* no guarantee oobbuf can hold all of spare bytes, so read and then copy */
+ uint32_t readlen = SpareBytesPerPage;
+ if (ooblen < readlen) {
+ readlen = ooblen;
+ }
+
+ if (rv) {
+ free(spare_bytes);
+ return -EIO;
+ }
+
+ memcpy(oobbuf, spare_bytes, readlen);
+
+ PageIndex++;
+ ooblen -= readlen;
+ oobbuf += readlen;
+ }
+ free(spare_bytes);
+ return RTEMS_SUCCESSFUL;
+}
+
+static int flash_read_oob(
+ rtems_jffs2_flash_control *super,
+ uint32_t offset,
+ uint8_t *oobbuf,
+ uint32_t ooblen
+)
+{
+ rtems_mutex_lock(&(get_flash_control(super)->access_lock));
+ int ret = flash_read_oob_locked(super, offset, oobbuf, ooblen);
+ rtems_mutex_unlock(&(get_flash_control(super)->access_lock));
+ return ret;
+}
+
+static int flash_write_oob(
+ rtems_jffs2_flash_control *super,
+ uint32_t offset,
+ uint8_t *oobbuf,
+ uint32_t ooblen
+)
+{
+ rtems_status_code sc;
+ uint8_t *spare_bytes;
+ uint8_t *buffer = oobbuf;
+ XNandPsu *nandpsu = get_flash_control(super)->nandpsu;
+ uint32_t SpareBytesPerPage = nandpsu->Geometry.SpareBytesPerPage;
+
+ if (offset > nandpsu->Geometry.DeviceSize) {
+ return -EIO;
+ }
+
+ /* Writing a page spare area to large will result in ignored data. */
+ if (ooblen > SpareBytesPerPage) {
+ return -EIO;
+ }
+
+ spare_bytes = rtems_malloc(SpareBytesPerPage);
+ if (spare_bytes == NULL) {
+ return -ENOMEM;
+ }
+
+ /* Writing a page spare area to small will result in invalid accesses */
+ rtems_mutex_lock(&(get_flash_control(super)->access_lock));
+ if (ooblen < SpareBytesPerPage) {
+ int rv = flash_read_oob_locked(super, offset, spare_bytes, SpareBytesPerPage);
+ if (rv) {
+ free(spare_bytes);
+ rtems_mutex_unlock(&(get_flash_control(super)->access_lock));
+ return rv;
+ }
+ buffer = spare_bytes;
+ memcpy(buffer, oobbuf, ooblen);
+ }
+
+ /* Get page index */
+ uint32_t PageIndex = offset / nandpsu->Geometry.BytesPerPage;
+
+ sc = XNandPsu_WriteSpareBytes(nandpsu, PageIndex, buffer);
+ rtems_mutex_unlock(&(get_flash_control(super)->access_lock));
+ free(spare_bytes);
+
+ if ( sc != XST_SUCCESS ) {
+ return -EIO;
+ }
+ return RTEMS_SUCCESSFUL;
+}
+
+static uint32_t flash_get_oob_size(
+ rtems_jffs2_flash_control *super
+)
+{
+ flash_control *self = get_flash_control(super);
+
+ return self->nandpsu->Geometry.SpareBytesPerPage;
+}
+
+static flash_control flash_instance = {
+ .super = {
+ .read = flash_read,
+ .write = flash_write,
+ .erase = flash_erase,
+ .block_is_bad = flash_block_is_bad,
+ .block_mark_bad = flash_block_mark_bad,
+ .oob_read = flash_read_oob,
+ .oob_write = flash_write_oob,
+ .get_oob_size = flash_get_oob_size,
+ }
+};
+
+static rtems_jffs2_compressor_control compressor_instance = {
+ .compress = rtems_jffs2_compressor_rtime_compress,
+ .decompress = rtems_jffs2_compressor_rtime_decompress
+};
+
+static rtems_jffs2_mount_data mount_data;
+
+int xilinx_zynqmp_nand_jffs2_initialize(
+ const char *mount_dir,
+ XNandPsu *NandInstPtr
+)
+{
+ flash_instance.super.block_size = NandInstPtr->Geometry.BlockSize;
+
+ uint64_t max_size = 0x100000000LU - flash_instance.super.block_size;
+
+ /* JFFS2 maximum FS size is one block less than 4GB */
+ if (NandInstPtr->Geometry.DeviceSize > max_size) {
+ flash_instance.super.flash_size = max_size;
+ } else {
+ flash_instance.super.flash_size = NandInstPtr->Geometry.DeviceSize;
+ }
+
+ flash_instance.super.write_size = NandInstPtr->Geometry.BytesPerPage;
+ flash_instance.nandpsu = NandInstPtr;
+ rtems_mutex_init(&flash_instance.access_lock, "XNandPsu JFFS2 adapter lock");
+ mount_data.flash_control = &flash_instance.super;
+ mount_data.compressor_control = &compressor_instance;
+
+ int rv = 0;
+ rv = mount(
+ NULL,
+ mount_dir,
+ RTEMS_FILESYSTEM_TYPE_JFFS2,
+ RTEMS_FILESYSTEM_READ_WRITE,
+ &mount_data
+ );
+ if ( rv != 0 ) {
+ return rv;
+ }
+
+ return 0;
+}
diff --git a/bsps/aarch64/xilinx-zynqmp/jffs2_xqspipsu.c b/bsps/aarch64/xilinx-zynqmp/jffs2_xqspipsu.c
new file mode 100644
index 0000000000..70d954550d
--- /dev/null
+++ b/bsps/aarch64/xilinx-zynqmp/jffs2_xqspipsu.c
@@ -0,0 +1,186 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 On-Line Applications Research Corporation (OAR)
+ *
+ * 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.
+ */
+
+#include <string.h>
+
+#include <bsp/irq.h>
+#include <bsp/jffs2_xqspipsu.h>
+#include <rtems/jffs2.h>
+#include <rtems/libio.h>
+#include <xqspipsu-flash-helper.h>
+
+typedef struct {
+ rtems_jffs2_flash_control super;
+ XQspiPsu *qspipsu;
+} flash_control;
+
+#define FLASH_DEVICE_ID 0xbb20 /* Type: 0xbb, Capacity: 0x20 */
+
+static flash_control *get_flash_control( rtems_jffs2_flash_control *super )
+{
+ return (flash_control *) super;
+}
+
+static int do_read(
+ rtems_jffs2_flash_control *super,
+ uint32_t offset,
+ unsigned char *buffer,
+ size_t size_of_buffer
+)
+{
+ int Status;
+
+ flash_control *self = get_flash_control( super );
+ XQspiPsu *QspiPsuPtr = self->qspipsu;
+ u8* ReadBuffer = NULL;
+
+ Status = QspiPsu_NOR_Read(
+ QspiPsuPtr,
+ offset,
+ size_of_buffer,
+ &ReadBuffer
+ );
+ if ( Status != XST_SUCCESS ) {
+ return Status;
+ }
+
+ /*
+ * We have to copy since we can't be sure that buffer is properly aligned.
+ */
+ memcpy( buffer, ReadBuffer, size_of_buffer );
+
+ return 0;
+}
+
+static int do_write(
+ rtems_jffs2_flash_control *super,
+ uint32_t offset,
+ const unsigned char *buffer,
+ size_t size_of_buffer
+)
+{
+ int Status;
+
+ flash_control *self = get_flash_control( super );
+ XQspiPsu *QspiPsuPtr = self->qspipsu;
+
+ Status = QspiPsu_NOR_Write(
+ QspiPsuPtr,
+ offset,
+ size_of_buffer,
+ (unsigned char *) buffer
+ );
+ if ( Status != XST_SUCCESS ) {
+ return Status;
+ }
+
+ return 0;
+}
+
+static int do_erase(
+ rtems_jffs2_flash_control *super,
+ uint32_t offset
+)
+{
+ int Status;
+
+ flash_control *self = get_flash_control( super );
+ XQspiPsu *QspiPsuPtr = self->qspipsu;
+
+ Status = QspiPsu_NOR_Erase(
+ QspiPsuPtr,
+ offset,
+ super->block_size
+ );
+ if ( Status != XST_SUCCESS ) {
+ return Status;
+ }
+
+ return 0;
+}
+
+static void do_destroy( rtems_jffs2_flash_control *super )
+{
+ flash_control *self = get_flash_control( super );
+
+ rtems_interrupt_handler_remove(
+ ZYNQMP_IRQ_QSPI,
+ (rtems_interrupt_handler) XQspiPsu_InterruptHandler,
+ self->qspipsu
+ );
+}
+
+static flash_control flash_instance = {
+ .super = {
+ .read = do_read,
+ .write = do_write,
+ .erase = do_erase,
+ .destroy = do_destroy,
+ .device_identifier = FLASH_DEVICE_ID
+ }
+};
+
+static rtems_jffs2_mount_data mount_data = {
+ .flash_control = &flash_instance.super,
+ .compressor_control = NULL
+};
+
+int xilinx_zynqmp_nor_jffs2_initialize(
+ const char *mount_dir,
+ XQspiPsu *qspipsu_ptr
+)
+{
+ int rv = 0;
+
+ flash_instance.qspipsu = qspipsu_ptr;
+
+ rv = QspiPsu_NOR_Initialize(
+ flash_instance.qspipsu,
+ ZYNQMP_IRQ_QSPI
+ );
+ if ( rv != 0 ) {
+ return rv;
+ }
+
+ uint32_t sect_size = QspiPsu_NOR_Get_Sector_Size(qspipsu_ptr);
+ uint32_t flash_size = QspiPsu_NOR_Get_Device_Size(qspipsu_ptr);
+ flash_instance.super.flash_size = flash_size;
+ flash_instance.super.block_size = sect_size;
+
+ rv = mount(
+ NULL,
+ mount_dir,
+ RTEMS_FILESYSTEM_TYPE_JFFS2,
+ RTEMS_FILESYSTEM_READ_WRITE,
+ &mount_data
+ );
+ if ( rv != 0 ) {
+ return rv;
+ }
+
+ return 0;
+}
diff --git a/bsps/aarch64/xilinx-zynqmp/start/bspstarthooks.c b/bsps/aarch64/xilinx-zynqmp/start/bspstarthooks.c
index 7bd787592c..14f2bcc280 100644
--- a/bsps/aarch64/xilinx-zynqmp/start/bspstarthooks.c
+++ b/bsps/aarch64/xilinx-zynqmp/start/bspstarthooks.c
@@ -38,13 +38,49 @@
#include <bsp.h>
#include <bsp/start.h>
-BSP_START_TEXT_SECTION void bsp_start_hook_0(void)
+#ifdef RTEMS_SMP
+#include <rtems/score/aarch64-system-registers.h>
+#include <rtems/score/smpimpl.h>
+
+#include <bsp/irq-generic.h>
+#endif
+
+BSP_START_TEXT_SECTION void bsp_start_hook_0( void )
{
- /* Do nothing */
+ /* do nothing */
}
-BSP_START_TEXT_SECTION void bsp_start_hook_1(void)
+BSP_START_TEXT_SECTION void bsp_start_hook_1( void )
{
+#ifdef RTEMS_SMP
+ uint32_t cpu_index_self;
+
+ cpu_index_self = _SMP_Get_current_processor();
+
+ if ( cpu_index_self != 0 ) {
+ if (
+ cpu_index_self >= rtems_configuration_get_maximum_processors()
+ || !_SMP_Should_start_processor( cpu_index_self )
+ ) {
+ while ( true ) {
+ _AARCH64_Wait_for_event();
+ }
+ }
+
+ /* Change the VBAR from the start to the normal vector table */
+ AArch64_start_set_vector_base();
+
+ zynqmp_setup_secondary_cpu_mmu_and_cache();
+ arm_gic_irq_initialize_secondary_cpu();
+
+ bsp_interrupt_vector_enable( ARM_GIC_IRQ_SGI_0 );
+ _SMP_Start_multitasking_on_secondary_processor(
+ _Per_CPU_Get_by_index( cpu_index_self )
+ );
+ /* Unreached */
+ }
+#endif /* RTEMS_SMP */
+
AArch64_start_set_vector_base();
bsp_start_copy_sections();
zynqmp_setup_mmu_and_cache();
diff --git a/bsps/aarch64/xilinx-zynqmp/start/bspstartmmu.c b/bsps/aarch64/xilinx-zynqmp/start/bspstartmmu.c
index 8d302e97b5..e727f9b1de 100644
--- a/bsps/aarch64/xilinx-zynqmp/start/bspstartmmu.c
+++ b/bsps/aarch64/xilinx-zynqmp/start/bspstartmmu.c
@@ -37,17 +37,11 @@
#include <bsp.h>
#include <bsp/start.h>
#include <bsp/aarch64-mmu.h>
+#include <libcpu/mmu-vmsav8-64.h>
BSP_START_DATA_SECTION static const aarch64_mmu_config_entry
zynqmp_mmu_config_table[] = {
AARCH64_MMU_DEFAULT_SECTIONS,
-#if defined( RTEMS_SMP )
- {
- .begin = 0xffff0000U,
- .end = 0xffffffffU,
- .flags = AARCH64_MMU_DEVICE
- },
-#endif
{
.begin = 0xf9000000U,
.end = 0xf9100000U,
@@ -56,6 +50,10 @@ zynqmp_mmu_config_table[] = {
.begin = 0xfd000000U,
.end = 0xffc00000U,
.flags = AARCH64_MMU_DEVICE
+ }, {
+ .begin = 0x80000000U,
+ .end = 0x80100000U,
+ .flags = 0
}
};
@@ -70,8 +68,27 @@ zynqmp_setup_mmu_and_cache( void )
{
aarch64_mmu_setup();
- aarch64_mmu_setup_translation_table_and_enable(
+ aarch64_mmu_setup_translation_table(
&zynqmp_mmu_config_table[ 0 ],
RTEMS_ARRAY_SIZE( zynqmp_mmu_config_table )
);
+
+ aarch64_mmu_enable();
+}
+
+/*
+ * Make weak and let the user override.
+ */
+BSP_START_TEXT_SECTION void zynqmp_setup_secondary_cpu_mmu_and_cache( void )
+__attribute__ ( ( weak ) );
+
+BSP_START_TEXT_SECTION void zynqmp_setup_secondary_cpu_mmu_and_cache( void )
+{
+ /* Perform basic MMU setup */
+ aarch64_mmu_setup();
+
+ /* Use the existing root page table already configured by CPU0 */
+ _AArch64_Write_ttbr0_el1( (uintptr_t) bsp_translation_table_base );
+
+ aarch64_mmu_enable();
}