summaryrefslogtreecommitdiffstats
path: root/bsps/aarch64/xilinx-versal
diff options
context:
space:
mode:
Diffstat (limited to '')
-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.c56
10 files changed, 474 insertions, 41 deletions
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 8b622aec7d..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,
}
};
@@ -77,3 +108,26 @@ versal_setup_mmu_and_cache( void )
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
+);