bsps/arm: Add BSP for ZynqMP RPU

This commit is contained in:
Philip Kirkpatrick
2023-06-29 18:36:44 +02:00
committed by Joel Sherrill
parent 001a0a4db6
commit 793c0f4671
28 changed files with 1379 additions and 2 deletions

View File

@@ -0,0 +1,129 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (C) 2013, 2017 embedded brains GmbH
*
* Copyright (C) 2019 DornerWorks
*
* Written by Jeff Kubascik <jeff.kubascik@dornerworks.com>
* and Josh Whitehead <josh.whitehead@dornerworks.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/console.h>
#include <rtems/bspIo.h>
#include <rtems/sysinit.h>
#include <rtems/termiostypes.h>
#include <bsp/irq.h>
#include <dev/serial/zynq-uart.h>
#include <bspopts.h>
static zynq_uart_context zynqmp_uart_instances[2] = {
{
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "Zynq UART 0" ),
.regs = (volatile struct zynq_uart *) 0xff000000,
.irq = ZYNQMP_IRQ_UART_0
}, {
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "Zynq UART 1" ),
.regs = (volatile struct zynq_uart *) 0xff010000,
.irq = ZYNQMP_IRQ_UART_1
}
};
rtems_status_code console_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
size_t i;
for (i = 0; i < RTEMS_ARRAY_SIZE(zynqmp_uart_instances); ++i) {
char uart[] = "/dev/ttySX";
uart[sizeof(uart) - 2] = (char) ('0' + i);
rtems_termios_device_install(
&uart[0],
&zynq_uart_handler,
NULL,
&zynqmp_uart_instances[i].base
);
if (i == BSP_CONSOLE_MINOR) {
link(&uart[0], CONSOLE_DEVICE_NAME);
}
}
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;
}
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);
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
);

View File

@@ -0,0 +1,96 @@
/**
* @file
* @ingroup RTEMSBSPsARMZynqMP
* @brief Global BSP definitions.
*/
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (C) 2013, 2014 embedded brains GmbH
*
* Copyright (C) 2019 DornerWorks
*
* Written by Jeff Kubascik <jeff.kubascik@dornerworks.com>
* and Josh Whitehead <josh.whitehead@dornerworks.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef LIBBSP_ARM_XILINX_ZYNQMP_BSP_H
#define LIBBSP_ARM_XILINX_ZYNQMP_BSP_H
/**
* @defgroup RTEMSBSPsARMZynqMP Xilinx Zynq UltraScale+ MPSoC
*
* @ingroup RTEMSBSPsARM
*
* @brief Xilinx Zynq UltraScale+ MPSoC Board Support Package.
*
* @{
*/
#include <bspopts.h>
#define BSP_FEATURE_IRQ_EXTENSION
#ifndef ASM
#include <rtems.h>
#include <bsp/default-initial-extension.h>
#include <bsp/start.h>
#include <peripheral_maps/xilinx_zynqmp.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define BSP_ARM_GIC_CPUIF_BASE 0x00F9001000
#define BSP_ARM_GIC_DIST_BASE 0xF9000000
#define BSP_ARM_A9MPCORE_SCU_BASE 0
#define BSP_ARM_A9MPCORE_GT_BASE 0
#define BSP_SELECTED_TTC_ADDR ZYNQMP_TTC0
/**
* @brief Zynq UltraScale+ MPSoC specific set up of the MMU.
*
* Provide in the application to override the defaults in the BSP.
*/
BSP_START_TEXT_SECTION void zynqmp_setup_mpu_and_cache(void);
void zynqmp_debug_console_flush(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* ASM */
/** @} */
#endif /* LIBBSP_ARM_XILINX_ZYNQMP_BSP_H */

View File

@@ -0,0 +1,65 @@
/**
* @file
* @ingroup zynqmp_interrupt
* @brief Interrupt definitions.
*/
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (C) 2013 embedded brains GmbH
*
* Copyright (C) 2019 DornerWorks
*
* Written by Jeff Kubascik <jeff.kubascik@dornerworks.com>
* and Josh Whitehead <josh.whitehead@dornerworks.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef LIBBSP_ARM_XILINX_ZYNQMP_IRQ_H
#define LIBBSP_ARM_XILINX_ZYNQMP_IRQ_H
#ifndef ASM
#include <rtems/irq.h>
#include <rtems/irq-extension.h>
#include <dev/irq/arm-gic-irq.h>
#include <peripheral_maps/xilinx_zynqmp.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define BSP_SELECTED_TTC_IRQ ZYNQMP_IRQ_TTC_0_0
#define BSP_INTERRUPT_VECTOR_COUNT 188
/** @} */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* ASM */
#endif /* LIBBSP_ARM_XILINX_ZYNQMP_IRQ_H */

View File

@@ -0,0 +1,54 @@
/**
* @file
* @ingroup zynqmp_tm27
* @brief Interrupt mechanisms for tm27 test.
*/
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (C) 2013 embedded brains GmbH
*
* Copyright (C) 2019 DornerWorks
*
* Written by Jeff Kubascik <jeff.kubascik@dornerworks.com>
* and Josh Whitehead <josh.whitehead@dornerworks.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _RTEMS_TMTEST27
#error "This is an RTEMS internal file you must not include directly."
#endif
#ifndef __tm27_h
#define __tm27_h
/**
* @defgroup zynqmp_tm27 TM27 Test Support
* @ingroup RTEMSBSPsARMZynqMP
* @brief Interrupt Mechanisms for tm27 test
*/
#include <dev/irq/arm-gic-tm27.h>
#endif /* __tm27_h */

View File

@@ -0,0 +1,43 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (C) 2013 embedded brains GmbH
*
* Copyright (C) 2019 DornerWorks
*
* Written by Jeff Kubascik <jeff.kubascik@dornerworks.com>
* and Josh Whitehead <josh.whitehead@dornerworks.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/bootcard.h>
void bsp_reset(void)
{
zynqmp_debug_console_flush();
while (true) {
/* Wait */
}
}

View File

@@ -0,0 +1,48 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (C) 2013, 2015 embedded brains GmbH
*
* Copyright (C) 2019 DornerWorks
*
* Written by Jeff Kubascik <jeff.kubascik@dornerworks.com>
* and Josh Whitehead <josh.whitehead@dornerworks.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/bootcard.h>
#include <bsp/irq-generic.h>
#include <bsp/linker-symbols.h>
#include <libcpu/arm-cp15.h>
void bsp_start(void)
{
bsp_interrupt_initialize();
rtems_cache_coherent_add_area(
bsp_section_nocacheheap_begin,
(uintptr_t) bsp_section_nocacheheap_size
);
}

View File

@@ -0,0 +1,66 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (C) 2013, 2014 embedded brains GmbH
*
* Copyright (C) 2019 DornerWorks
*
* Written by Jeff Kubascik <jeff.kubascik@dornerworks.com>
* and Josh Whitehead <josh.whitehead@dornerworks.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/start.h>
BSP_START_TEXT_SECTION void bsp_start_hook_0(void)
{
/*
* On reset, V will be set. This points the exceptions to the FSBL's vectors. The FSBL
* should clear this bit before booting RTEMS but in some debugging
* configurations the bit may not be. The other bits should already be clear
* on reset. Since the correct settings in these bits are critical,
* make sure SCTLR[M, I, A, C, V] are cleared. Afterwards, exceptions are
* handled by RTEMS.
* Note 1: The APU also does these steps in start.S in _start in the #if block:
* `#if (__ARM_ARCH >= 7 && __ARM_ARCH_PROFILE == 'A') || __ARM_ARCH >= 8`
* Note 2: Not all Arm R cores need this (like the TMS570). So, this probably should
* be in this hook and not in start.S
*
* Ref: https://developer.arm.com/documentation/ddi0460/c/System-Control/Register-descriptions/c1--System-Control-Register?lang=en
*/
__asm__ volatile(
"mrc p15, 0, r0, c1, c0, 0 \n"
"bic r1, r0, #0x3000 \n" /* Clear V[13] and I[12] */
"bic r1, r1, #0x7 \n" /* Clear C[2] A[1] and M[0] */
"mcr p15, 0, r1, c1, c0, 0 \n"
: :);
}
BSP_START_TEXT_SECTION void bsp_start_hook_1(void)
{
bsp_start_copy_sections();
zynqmp_setup_mpu_and_cache();
bsp_start_clear_bss();
}

View File

@@ -0,0 +1,143 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (C) 2023 Reflex Aerospace GmbH
*
* Written by Philip Kirkpatrick <p.kirkpatrick@reflexaerospace.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/start.h>
#include <xil_mpu.h>
#include <xil_cache.h>
#include <xreg_cortexr5.h>
static BSP_START_TEXT_SECTION void zynqmp_configure_mpu_sections(void);
/*
* Make weak and let the user override.
*/
BSP_START_TEXT_SECTION void zynqmp_setup_mpu_and_cache(void) __attribute__ ((weak));
BSP_START_TEXT_SECTION void zynqmp_setup_mpu_and_cache(void)
{
zynqmp_configure_mpu_sections();
Xil_EnableMPU();
Xil_DCacheEnable();
Xil_ICacheEnable();
}
/*
* Setup MPU sections.
*
* The MPU on the ZynqMP RPU only supports 16 regions.
* Regions must align on boundaries equal to the size of the region
* Regions may overlap or be nested with the later definition taking precedence
*
* Note: LWIP for Zynq requires an available region in xemacpsif_dma.c:init_dma()
* this is used for the BD memory.
*
* The following code attempts to implement the section map from Init_MPU() in
* https://github.com/Xilinx/embeddedsw/blob/master/lib/bsp/standalone/src/arm/cortexr5/platform/ZynqMP/mpu.c
* and from ARMV7_CP15_START_DEFAULT_SECTIONS in bsps/arm/include/bsp/arm-cp15-start.h
* Due to the limitation on number of regions, some compromises have been made.
* - Merges device memories instead of configuring each one independently
* - For DRAM, assumes a baseline of `Normal write-back Cacheable` `Full Access`
* then uses precedence to set no-cache and RO sections
*
* Reference:
* https://docs.xilinx.com/r/en-US/ug1085-zynq-ultrascale-trm/System-Address-Map-Interconnects
* https://developer.arm.com/documentation/ddi0460/c/Memory-Protection-Unit
*
*| | Memory Range | Attributes of MPURegion |
*|-----------------|-------------------------|-----------------------------|
*| DDR | 0x00000000 - 0x7FFFFFFF | Normal write-back Cacheable |
*| -rodata | | + PRIV_RO_USER_RO |
*| -nocache | | Normal non-cacheable |
*| -nocachenoload | | Normal non-cacheable |
*| PL | 0x80000000 - 0xBFFFFFFF | Strongly Ordered |
*| Devices | 0xC0000000 - 0xFFFFFFFF | Device Memory |
*| -QSPI | 0xC0000000 - 0xDFFFFFFF | |
*| -PCIe | 0xE0000000 - 0xEFFFFFFF | |
*| -Reserved | 0xF0000000 - 0xF7FFFFFF | |
*| -STM_CORESIGHT | 0xF8000000 - 0xF8FFFFFF | |
*| -RPU_R5_GIC | 0xF9000000 - 0xF90FFFFF | |
*| -Reserved | 0xF9100000 - 0xFCFFFFFF | |
*| -FPS | 0xFD000000 - 0xFDFFFFFF | |
*| -LPS | 0xFE000000 - 0xFFFFFFFF | (1) |
*| OCM | 0xFFFC0000 - 0xFFFFFFFF | Normal write-back Cacheable |
*
* Note 1: Actual range for LPS goes to 0xFFBFFFFF, to use less sections go to
* 0xFFFFFFFF and use precedence to configure OCM
*/
static BSP_START_TEXT_SECTION void zynqmp_configure_mpu_sections(void)
{
u32 addr;
u64 size;
u32 attrib;
// Configure baseline DDR memory 0x00000000 - 0x7FFFFFFF
addr = 0x00000000U;
size = 0x80000000U;
attrib = NORM_NSHARED_WB_WA | PRIV_RW_USER_RW;
Xil_SetMPURegion(addr, size, attrib);
// Configure PL interfaces 0x80000000 - 0xBFFFFFFF
addr = 0x80000000U;
size = 0x40000000U;
attrib = STRONG_ORDERD_SHARED | PRIV_RW_USER_RW;
Xil_SetMPURegion(addr, size, attrib);
// Configure devices 0xC0000000 - 0xFFFFFFFF
addr = 0xC0000000U;
size = 0x40000000U;
attrib = DEVICE_NONSHARED | PRIV_RW_USER_RW;
Xil_SetMPURegion(addr, size, attrib);
// Configure OCM 0xFFFC0000 - 0xFFFFFFFF
addr = 0xFFFC0000U;
size = 0x00040000U;
attrib = NORM_NSHARED_WB_WA | PRIV_RW_USER_RW;
Xil_SetMPURegion(addr, size, attrib);
// Add RO region for RO section
addr = (u32) bsp_section_rodata_begin;
size = bsp_section_rodata_end - bsp_section_rodata_begin;
attrib = NORM_NSHARED_WB_WA | PRIV_RO_USER_RO;
Xil_SetMPURegion(addr, size, attrib);
// Add no cache region for no cache section
addr = (u32) bsp_section_nocache_begin;
size = bsp_section_nocache_end - bsp_section_nocache_begin;
attrib = NORM_SHARED_NCACHE | PRIV_RW_USER_RW;
Xil_SetMPURegion(addr, size, attrib);
// Add no cache region for no cache no load section
addr = (u32) bsp_section_nocachenoload_begin;
size = bsp_section_nocachenoload_end - bsp_section_nocachenoload_begin;
attrib = NORM_SHARED_NCACHE | PRIV_RW_USER_RW;
Xil_SetMPURegion(addr, size, attrib);
}

View File

@@ -41,6 +41,9 @@ extern "C" {
#include "xil_types.h"
#include "xil_assert.h"
#include "xil_io.h"
#ifdef __rtems__
#include <xil_system.h>
#endif
/************************** Constant Definitions *****************************/
/*

View File

@@ -0,0 +1,118 @@
/**
* @file
* @ingroup RTEMSBSPsShared
* @brief Xilinx Zynq Ultrascale+ MPSoC Peripheral memory map.
*/
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (C) 2023 Reflex Aerospace GmbH
*
* Written by Philip Kirkpatrick <p.kirkpatrick@reflexaerospace.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef LIBBSP_SHARED_PERIPHERAL_MAPS_ZYNQMP
#define LIBBSP_SHARED_PERIPHERAL_MAPS_ZYNQMP
/* Data derived from https://docs.xilinx.com/r/en-US/ug1085-zynq-ultrascale-trm/PS-I/O-Peripherals-Registers */
/* LPD IO Peripherals */
#define ZYNQMP_UART0 (0xFF000000)
#define ZYNQMP_UART1 (0xFF010000)
#define ZYNQMP_I2C0 (0xFF020000)
#define ZYNQMP_I2C1 (0xFF030000)
#define ZYNQMP_SPI0 (0xFF040000)
#define ZYNQMP_SPI1 (0xFF050000)
#define ZYNQMP_CAN0 (0xFF060000)
#define ZYNQMP_CAN1 (0xFF070000)
#define ZYNQMP_GPIO (0xFF0A0000)
#define ZYNQMP_GEM0 (0xFF0B0000)
#define ZYNQMP_GEM1 (0xFF0C0000)
#define ZYNQMP_GEM2 (0xFF0D0000)
#define ZYNQMP_GEM3 (0xFF0E0000)
#define ZYNQMP_QSPI (0xFF0F0000)
#define ZYNQMP_NAND (0xFF100000)
#define ZYNQMP_SD0 (0xFF160000)
#define ZYNQMP_SD1 (0xFF170000)
#define ZYNQMP_IPI_MSG (0xFF990000)
#define ZYNQMP_USB0 (0xFF9D0000)
#define ZYNQMP_USB1 (0xFF9E0000)
#define ZYNQMP_AMS (0xFFA50000)
#define ZYNQMP_PSSYSMON (0xFFA50800)
#define ZYNQMP_PLSYSMON (0xFFA50C00)
#define ZYNQMP_CSU_SWDT (0xFFCB0000)
/* FPD IO Peripherals */
#define ZYNQMP_SATA (0xFD0C0000)
#define ZYNQMP_PCIE (0xFD0E0000)
#define ZYNQMP_PCIE_IN (0xFD0E0800)
#define ZYNQMP_PCIE_EG (0xFD0E0C00)
#define ZYNQMP_PCIE_DMA (0xFD0F0000)
#define ZYNQMP_SIOU (0xFD3D0000)
#define ZYNQMP_GTR (0xFD400000)
#define ZYNQMP_PCIE_ATTR (0xFD480000)
#define ZYNQMP_DP (0xFD4A0000)
#define ZYNQMP_GPU (0xFD4B0000)
#define ZYNQMP_DP_DMA (0xFD4C0000)
/* LPD System Registers */
#define ZYNQMP_IPI (0xFF300000)
#define ZYNQMP_TTC0 (0xFF110000)
#define ZYNQMP_TTC1 (0xFF120000)
#define ZYNQMP_TTC2 (0xFF130000)
#define ZYNQMP_TTC3 (0xFF140000)
#define ZYNQMP_LPD_SWDT (0xFF150000)
#define ZYNQMP_XPPU (0xFF980000)
#define ZYNQMP_XPPU_SINK (0xFF9C0000)
#define ZYNQMP_PL_LPD (0xFF9B0000)
#define ZYNQMP_OCM (0xFFA00000)
#define ZYNQMP_LPD_FPD (0xFFA10000)
#define ZYNQMP_RTC (0xFFA60000)
#define ZYNQMP_OCM_XMPU (0xFFA70000)
#define ZYNQMP_LPD_DMA (0xFFA80000)
#define ZYNQMP_CSU_DMA (0xFFC80000)
#define ZYNQMP_CSU (0xFFCA0000)
#define ZYNQMP_BBRAM (0xFFCD0000)
/* System Interrupt Table */
/* SPIs */
#define ZYNQMP_IRQ_UART_0 53
#define ZYNQMP_IRQ_UART_1 54
#define ZYNQMP_IRQ_TTC_0_0 68
#define ZYNQMP_IRQ_TTC_0_1 69
#define ZYNQMP_IRQ_TTC_0_2 70
#define ZYNQMP_IRQ_TTC_1_0 71
#define ZYNQMP_IRQ_TTC_1_1 72
#define ZYNQMP_IRQ_TTC_1_2 73
#define ZYNQMP_IRQ_TTC_2_0 74
#define ZYNQMP_IRQ_TTC_2_1 75
#define ZYNQMP_IRQ_TTC_2_2 76
#define ZYNQMP_IRQ_TTC_3_0 77
#define ZYNQMP_IRQ_TTC_3_1 78
#define ZYNQMP_IRQ_TTC_3_2 79
#endif /* LIBBSP_SHARED_PERIPHERAL_MAPS_ZYNQMP */

View File

@@ -0,0 +1,229 @@
/**
* @file
*
* @ingroup RTEMSBSPsARMZynqMP
*
* @brief Triple Timer Counter clock functions definitions.
*/
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (C) 2023 Reflex Aerospace GmbH
*
* Written by Philip Kirkpatrick <p.kirkpatrick@reflexaerospace.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 <stdlib.h>
#include <rtems.h>
#include <bsp.h>
#include <bsp/irq.h>
#include <peripheral_maps/xilinx_zynqmp.h>
#include <dev/clock/xttcps_hw.h>
#include <rtems/timecounter.h>
typedef struct {
struct timecounter ttc_tc;
uint32_t irq_match_interval;
uint32_t tick_miss;
} ttc_clock_context;
static ttc_clock_context ttc_clock_instance = {0, };
#define TTC_REFERENCE_CLOCK 100000000
uint32_t _CPU_Counter_frequency( void )
{
return ttc_clock_instance.ttc_tc.tc_frequency;
}
static uint32_t zynqmp_ttc_get_timecount(struct timecounter *tc)
{
uint32_t time;
time = XTtcPs_ReadReg(BSP_SELECTED_TTC_ADDR, XTTCPS_COUNT_VALUE_OFFSET);
return time;
}
CPU_Counter_ticks _CPU_Counter_read(void)
{
return zynqmp_ttc_get_timecount(&ttc_clock_instance.ttc_tc);
}
/**
* @brief Initialize the HW peripheral for clock driver
*
* Clock driver is implemented by RTI module
*
* @retval Void
*/
static void zynqmp_ttc_clock_driver_support_initialize_hardware(void)
{
uint32_t microsec_per_tick;
uint16_t clock_ratio;
uint8_t index;
uint32_t frequency;
uint32_t prescaler;
uint32_t tmp_reg_val;
microsec_per_tick = rtems_configuration_get_microseconds_per_tick();
/* Check the TTC is OFF before reconfiguring */
XTtcPs_WriteReg(BSP_SELECTED_TTC_ADDR, XTTCPS_CNT_CNTRL_OFFSET,
/* Don't enable waveform output */
XTTCPS_CNT_CNTRL_DIS_MASK | XTTCPS_CNT_CNTRL_EN_WAVE_MASK);
/* Prescaler value is 2^(N + 1)
* Divide down the clock as much as possible while still retaining a
* frequency that is an integer multiple of 1MHz. This maximizes time to
* overflow while minimizing rounding errors in 1us periods
*/
clock_ratio = TTC_REFERENCE_CLOCK / 1000000;
/* Search for the highest set bit. This is effectively min(log2(ratio)) */
for(index = sizeof(clock_ratio) * 8 - 1; index > 0; index--) {
if((clock_ratio >> (index)) & 0x01) {
break;
}
}
if(index == 0 && (clock_ratio & 0x01) == 0) {
/* No prescaler */
frequency = TTC_REFERENCE_CLOCK;
XTtcPs_WriteReg(BSP_SELECTED_TTC_ADDR, XTTCPS_CLK_CNTRL_OFFSET, 0);
} else {
prescaler = index - 1;
frequency = TTC_REFERENCE_CLOCK / (1 << (prescaler + 1));
XTtcPs_WriteReg(BSP_SELECTED_TTC_ADDR, XTTCPS_CLK_CNTRL_OFFSET,
prescaler << XTTCPS_CLK_CNTRL_PS_VAL_SHIFT |
XTTCPS_CLK_CNTRL_PS_EN_MASK);
}
/* Max out the counter interval */
tmp_reg_val = XTTCPS_INTERVAL_VAL_MASK;
XTtcPs_WriteReg(BSP_SELECTED_TTC_ADDR, XTTCPS_INTERVAL_VAL_OFFSET,
tmp_reg_val);
/* Setup match register to generate tick IRQ */
ttc_clock_instance.irq_match_interval =
(uint32_t) ((frequency * microsec_per_tick) / 1000000);
XTtcPs_WriteReg(BSP_SELECTED_TTC_ADDR, XTTCPS_MATCH_0_OFFSET,
ttc_clock_instance.irq_match_interval);
/* Clear interupts (clear on read) */
XTtcPs_ReadReg(BSP_SELECTED_TTC_ADDR, XTTCPS_ISR_OFFSET);
/* Enable interupt for match register */
XTtcPs_WriteReg(BSP_SELECTED_TTC_ADDR, XTTCPS_IER_OFFSET,
XTTCPS_IXR_MATCH_0_MASK);
/* Configure, reset, and enable counter */
XTtcPs_WriteReg(BSP_SELECTED_TTC_ADDR, XTTCPS_CNT_CNTRL_OFFSET,
XTTCPS_CNT_CNTRL_EN_WAVE_MASK | /* Don't enable waveform output */
XTTCPS_CNT_CNTRL_RST_MASK | /* Reset count and start counter */
XTTCPS_CNT_CNTRL_MATCH_MASK /* Enable match mode */
/* Increment mode */
/* Overflow mode */
/* Not disabled */
);
/* set timecounter */
ttc_clock_instance.ttc_tc.tc_get_timecount = zynqmp_ttc_get_timecount;
ttc_clock_instance.ttc_tc.tc_counter_mask = XTTCPS_COUNT_VALUE_MASK;
ttc_clock_instance.ttc_tc.tc_frequency = frequency;
ttc_clock_instance.ttc_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
rtems_timecounter_install(&ttc_clock_instance.ttc_tc);
}
/**
* @brief Clears interrupt source
*
* @retval Void
*/
static void zynqmp_ttc_clock_driver_support_at_tick( void )
{
uint32_t irq_flags;
uint32_t cval;
uint32_t now;
uint32_t delta;
/* Get and clear interupts (clear on read) */
irq_flags = XTtcPs_ReadReg(BSP_SELECTED_TTC_ADDR, XTTCPS_ISR_OFFSET);
if(irq_flags & XTTCPS_IXR_MATCH_0_MASK) {
/* Update match */
cval = XTtcPs_ReadReg(BSP_SELECTED_TTC_ADDR, XTTCPS_MATCH_0_OFFSET);
/* Check that the match for the next tick is in the future
* If no, then set the match for one irq interval from now
* This will have the effect that your timebase will slip but
* won't hang waiting for the counter to wrap around.
* If this happens during normal operation, there is a problem
* causing this interrupt to not be serviced quickly enough
* If this happens during debugging, that is normal and expected
* because the TTC does NOT pause when the CPU is halted on a breakpoint
*/
now = XTtcPs_ReadReg(BSP_SELECTED_TTC_ADDR, XTTCPS_COUNT_VALUE_OFFSET);
delta = now - cval;
if(delta > ttc_clock_instance.irq_match_interval) {
cval = now;
ttc_clock_instance.tick_miss++;
}
cval += ttc_clock_instance.irq_match_interval;
XTtcPs_WriteReg(BSP_SELECTED_TTC_ADDR, XTTCPS_MATCH_0_OFFSET, cval);
}
/* Else, something is set up wrong, only match should be enabled */
}
/**
* @brief registers RTI interrupt handler
*
* @param[in] Clock_isr new ISR handler
* @param[in] Old_ticker old ISR handler (unused and type broken)
*
* @retval Void
*/
static void zynqmp_ttc_clock_driver_support_install_isr(
rtems_isr_entry Clock_isr
)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
sc = rtems_interrupt_handler_install(
BSP_SELECTED_TTC_IRQ,
"Clock",
RTEMS_INTERRUPT_UNIQUE,
(rtems_interrupt_handler) Clock_isr,
NULL
);
if ( sc != RTEMS_SUCCESSFUL ) {
rtems_fatal_error_occurred(0xdeadbeef);
}
}
#define Clock_driver_support_at_tick \
zynqmp_ttc_clock_driver_support_at_tick
#define Clock_driver_support_initialize_hardware \
zynqmp_ttc_clock_driver_support_initialize_hardware
#define Clock_driver_support_install_isr(Clock_isr) \
zynqmp_ttc_clock_driver_support_install_isr( Clock_isr )
#include "../../../shared/dev/clock/clockimpl.h"