Move patches to its own directory

This commit is contained in:
2024-09-06 08:22:14 +02:00
parent e2c770208e
commit 3dad4fb3d1
24 changed files with 19 additions and 19 deletions

View File

@@ -0,0 +1,438 @@
diff --git a/include/sbi_utils/serial/alveo_uart.h b/include/sbi_utils/serial/alveo_uart.h
new file mode 100644
index 0000000..0b6408c
--- /dev/null
+++ b/include/sbi_utils/serial/alveo_uart.h
@@ -0,0 +1,13 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#ifndef __SERIAL_ALVEO_UART_H__
+#define __SERIAL_ALVEO_UART_H__
+
+#include <sbi/sbi_types.h>
+
+int alveo_uart_init(unsigned long base, u32 in_freq, u32 baudrate, u32 reg_shift,
+ u32 reg_width, u32 reg_offset);
+
+#endif
diff --git a/lib/utils/serial/Kconfig b/lib/utils/serial/Kconfig
index e3589ca..b754c7c 100644
--- a/lib/utils/serial/Kconfig
+++ b/lib/utils/serial/Kconfig
@@ -84,6 +84,10 @@ config SERIAL_UART8250
bool "8250 UART support"
default n
+config SERIAL_ALVEO_UART
+ bool "ALveo UART support"
+ default n
+
config SERIAL_XILINX_UARTLITE
bool "Xilinx UART Lite support"
default n
diff --git a/lib/utils/serial/alveo_uart.c b/lib/utils/serial/alveo_uart.c
new file mode 100644
index 0000000..a351741
--- /dev/null
+++ b/lib/utils/serial/alveo_uart.c
@@ -0,0 +1,123 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <sbi/riscv_io.h>
+#include <sbi/sbi_console.h>
+#include <sbi_utils/serial/alveo_uart.h>
+
+/* clang-format off */
+
+#define UART_RBR_OFFSET 0 /* In: Recieve Buffer Register */
+#define UART_THR_OFFSET 0 /* Out: Transmitter Holding Register */
+#define UART_DLL_OFFSET 0 /* Out: Divisor Latch Low */
+#define UART_IER_OFFSET 1 /* I/O: Interrupt Enable Register */
+#define UART_DLM_OFFSET 1 /* Out: Divisor Latch High */
+#define UART_FCR_OFFSET 2 /* Out: FIFO Control Register */
+#define UART_IIR_OFFSET 2 /* I/O: Interrupt Identification Register */
+#define UART_LCR_OFFSET 3 /* Out: Line Control Register */
+#define UART_MCR_OFFSET 4 /* Out: Modem Control Register */
+#define UART_LSR_OFFSET 5 /* In: Line Status Register */
+#define UART_MSR_OFFSET 6 /* In: Modem Status Register */
+#define UART_SCR_OFFSET 7 /* I/O: Scratch Register */
+#define UART_MDR1_OFFSET 8 /* I/O: Mode Register */
+
+#define UART_LSR_FIFOE 0x80 /* Fifo error */
+#define UART_LSR_TEMT 0x40 /* Transmitter empty */
+#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
+#define UART_LSR_BI 0x10 /* Break interrupt indicator */
+#define UART_LSR_FE 0x08 /* Frame error indicator */
+#define UART_LSR_PE 0x04 /* Parity error indicator */
+#define UART_LSR_OE 0x02 /* Overrun error indicator */
+#define UART_LSR_DR 0x01 /* Receiver data ready */
+#define UART_LSR_BRK_ERROR_BITS 0x1E /* BI, FE, PE, OE bits */
+
+/* clang-format on */
+
+static volatile char *alveo_uart_base;
+static u32 alveo_uart_in_freq;
+static u32 alveo_uart_baudrate;
+static u32 alveo_uart_reg_width;
+static u32 alveo_uart_reg_shift;
+
+static u32 get_reg(u32 num)
+{
+ u32 offset = num << alveo_uart_reg_shift;
+
+ if (alveo_uart_reg_width == 1)
+ return readb(alveo_uart_base + offset);
+ else if (alveo_uart_reg_width == 2)
+ return readw(alveo_uart_base + offset);
+ else
+ return readl(alveo_uart_base + offset);
+}
+
+static void set_reg(u32 num, u32 val)
+{
+ u32 offset = num << alveo_uart_reg_shift;
+
+ if (alveo_uart_reg_width == 1)
+ writeb(val, alveo_uart_base + offset);
+ else if (alveo_uart_reg_width == 2)
+ writew(val, alveo_uart_base + offset);
+ else
+ writel(val, alveo_uart_base + offset);
+}
+
+static void alveo_uart_putc(char ch)
+{
+ while (!(get_reg(UART_LSR_OFFSET) & UART_LSR_TEMT))
+ ;
+
+ set_reg(UART_THR_OFFSET, ch);
+}
+
+static int alveo_uart_getc(void)
+{
+ if (get_reg(UART_LSR_OFFSET) & UART_LSR_DR)
+ return get_reg(UART_RBR_OFFSET);
+ return -1;
+}
+
+static struct sbi_console_device alveo_uart_console = {
+ .name = "alveo_uart",
+ .console_putc = alveo_uart_putc,
+ .console_getc = alveo_uart_getc
+};
+
+int alveo_uart_init(unsigned long base, u32 in_freq, u32 baudrate, u32 reg_shift,
+ u32 reg_width, u32 reg_offset)
+{
+ u16 bdiv = 0;
+
+ alveo_uart_base = (volatile char *)base + reg_offset;
+ alveo_uart_reg_shift = reg_shift;
+ alveo_uart_reg_width = reg_width;
+ alveo_uart_in_freq = in_freq;
+ alveo_uart_baudrate = baudrate;
+
+ if (alveo_uart_baudrate) {
+ bdiv = alveo_uart_in_freq / (16 * alveo_uart_baudrate);
+ }
+
+ /* Disable all interrupts */
+ set_reg(UART_IER_OFFSET, 0x00);
+ /* Enable DLAB */
+ set_reg(UART_LCR_OFFSET, 0x80);
+
+ if (bdiv) {
+ /* Set divisor low byte */
+ set_reg(UART_DLL_OFFSET, bdiv & 0xff);
+ /* Set divisor high byte */
+ set_reg(UART_DLM_OFFSET, (bdiv >> 8) & 0xff);
+ }
+
+ /* 8 bits, no parity, one stop bit */
+ set_reg(UART_LCR_OFFSET, 0x03); // previous was 0x0B
+ /* Disable all interrupts*/
+ set_reg(UART_IER_OFFSET, 0x00);
+
+ sbi_console_set_device(&alveo_uart_console);
+
+ return 0;
+}
diff --git a/lib/utils/serial/objects.mk b/lib/utils/serial/objects.mk
index 1e6bd2e..0268bdf 100644
--- a/lib/utils/serial/objects.mk
+++ b/lib/utils/serial/objects.mk
@@ -44,5 +44,6 @@ libsbiutils-objs-$(CONFIG_SERIAL_SHAKTI) += serial/shakti-uart.o
libsbiutils-objs-$(CONFIG_SERIAL_SIFIVE) += serial/sifive-uart.o
libsbiutils-objs-$(CONFIG_SERIAL_LITEX) += serial/litex-uart.o
libsbiutils-objs-$(CONFIG_SERIAL_UART8250) += serial/uart8250.o
+libsbiutils-objs-$(CONFIG_SERIAL_ALVEO_UART) += serial/alveo_uart.o
libsbiutils-objs-$(CONFIG_SERIAL_XILINX_UARTLITE) += serial/xlnx-uartlite.o
libsbiutils-objs-$(CONFIG_SERIAL_SEMIHOSTING) += serial/semihosting.o
diff --git a/platform/fpga/sargantana_alveo/Kconfig b/platform/fpga/sargantana_alveo/Kconfig
new file mode 100644
index 0000000..bf3e7e6
--- /dev/null
+++ b/platform/fpga/sargantana_alveo/Kconfig
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: BSD-2-Clause
+
+config PLATFORM_SARGANTANA_ALVEO_FPGA
+ bool
+ select FDT
+ select IPI_MSWI
+ select IRQCHIP_PLIC
+ select SERIAL_ALVEO_UART
+ select TIMER_MTIMER
+ default y
diff --git a/platform/fpga/sargantana_alveo/configs/defconfig b/platform/fpga/sargantana_alveo/configs/defconfig
new file mode 100644
index 0000000..e69de29
diff --git a/platform/fpga/sargantana_alveo/objects.mk b/platform/fpga/sargantana_alveo/objects.mk
new file mode 100644
index 0000000..d444abe
--- /dev/null
+++ b/platform/fpga/sargantana_alveo/objects.mk
@@ -0,0 +1,87 @@
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2019 Western Digital Corporation or its affiliates.
+#
+
+# Compiler pre-processor flags
+platform-cppflags-y =
+
+# C Compiler and assembler flags.
+platform-cflags-y =
+platform-asflags-y =
+
+# Linker flags: additional libraries and object files that the platform
+# code needs can be added here
+platform-ldflags-y =
+
+#
+# Command for platform specific "make run"
+# Useful for development and debugging on plaftform simulator (such as QEMU)
+#
+# platform-runcmd = your_platform_run.sh
+
+#
+# Platform RISC-V XLEN, ABI, ISA and Code Model configuration.
+# These are optional parameters but platforms can optionaly provide it.
+# Some of these are guessed based on GCC compiler capabilities
+#
+PLATFORM_RISCV_XLEN = 64
+PLATFORM_RISCV_ABI = lp64d
+PLATFORM_RISCV_ISA = rv64imafd
+PLATFORM_RISCV_CODE_MODEL = medany
+
+# Space separated list of object file names to be compiled for the platform
+platform-objs-y += platform.o
+
+#
+# If the platform support requires a builtin device tree file, the name of
+# the device tree compiled file should be specified here. The device tree
+# source file be in the form <dt file name>.dts
+#
+# platform-objs-y += <dt file name>.o
+
+# Firmware load address configuration. This is mandatory.
+FW_TEXT_START=0x80000000
+
+# Optional parameter for path to external FDT
+# FW_FDT_PATH="path to platform flattened device tree file"
+
+#
+# Dynamic firmware configuration.
+# Optional parameters are commented out. Uncomment and define these parameters
+# as needed.
+#
+FW_DYNAMIC=n
+
+#
+# Jump firmware configuration.
+# Optional parameters are commented out. Uncomment and define these parameters
+# as needed.
+#
+FW_JUMP=n
+# This needs to be 4MB aligned for 32-bit support
+# This needs to be 2MB aligned for 64-bit support
+# ifeq ($(PLATFORM_RISCV_XLEN), 32)
+# FW_JUMP_ADDR=0x80400000
+# else
+# FW_JUMP_ADDR=0x80200000
+# endif
+# FW_JUMP_FDT_ADDR=0x82200000
+
+#
+# Firmware with payload configuration.
+# Optional parameters are commented out. Uncomment and define these parameters
+# as needed.
+#
+FW_PAYLOAD=y
+# This needs to be 4MB aligned for 32-bit support
+# This needs to be 2MB aligned for 64-bit support
+ifeq ($(PLATFORM_RISCV_XLEN), 32)
+FW_PAYLOAD_OFFSET=0x400000
+else
+FW_PAYLOAD_OFFSET=0x200000
+endif
+FW_PAYLOAD_ALIGN=0x1000
+# FW_PAYLOAD_PATH="path to next boot stage binary image file"
+# FW_PAYLOAD_FDT_ADDR=0x82200000
diff --git a/platform/fpga/sargantana_alveo/platform.c b/platform/fpga/sargantana_alveo/platform.c
new file mode 100644
index 0000000..a359b34
--- /dev/null
+++ b/platform/fpga/sargantana_alveo/platform.c
@@ -0,0 +1,146 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ */
+
+#include <sbi/riscv_asm.h>
+#include <sbi/riscv_encoding.h>
+#include <sbi/sbi_const.h>
+#include <sbi/sbi_platform.h>
+
+/*
+ * Include these files as needed.
+ * See objects.mk SARGANTANA_ALVEO_xxx configuration parameters.
+ */
+
+#include <sbi_utils/serial/alveo_uart.h>
+#include <sbi/sbi_timer.h>
+
+#define SARGANTANA_ALVEO_HART_COUNT 1
+
+#define SARGANTANA_ALVEO_UART_BASE_ADDR 0x40000000
+#define SARGANTANA_ALVEO_UART_OFFSET 0x1000
+//#define SARGANTANA_ALVEO_UART_ADDR SARGANTANA_ALVEO_UART_BASE_ADDR + SARGANTANA_ALVEO_UART_XLNX_OFFSET
+#define SARGANTANA_ALVEO_UART_INPUT_FREQ 50000000
+#define SARGANTANA_ALVEO_UART_BAUDRATE 115200
+
+#define SARGANTANA_ALVEO_TIMER_BASE 0x40170000
+#define ADDR_TIME_L 0x0u // 32 lower bits of the time register
+#define ADDR_TIME_H 0x1u // 32 higher bits of the time register
+#define ADDR_TIMECMP_L 0x2u // 32 lower bits of the time comparator
+#define ADDR_TIMECMP_H 0x3u // 32 higher bits of the time comparator
+
+volatile uint32_t *timer_base_ptr = (uint32_t *)(SARGANTANA_ALVEO_TIMER_BASE);
+
+/*
+ * Platform early initialization.
+ */
+static int sargantana_alveo_early_init(bool cold_boot)
+{
+ return 0;
+}
+
+/*
+ * Platform final initialization.
+ */
+static int sargantana_alveo_final_init(bool cold_boot)
+{
+ return 0;
+}
+
+/*
+ * Initialize the platform console.
+ */
+static int sargantana_alveo_console_init(void)
+{
+ return alveo_uart_init(SARGANTANA_ALVEO_UART_BASE_ADDR,
+ SARGANTANA_ALVEO_UART_INPUT_FREQ,
+ SARGANTANA_ALVEO_UART_BAUDRATE,
+ 2, 4,
+ SARGANTANA_ALVEO_UART_OFFSET);
+}
+
+/*
+ * Initialize the platform interrupt controller for current HART.
+ */
+static int sargantana_alveo_irqchip_init(bool cold_boot)
+{
+ u32 hartid = current_hartid();
+ return hartid;
+}
+
+/*
+ * Initialize IPI for current HART.
+ */
+static int sargantana_alveo_ipi_init(bool cold_boot)
+{
+ return 0;
+}
+
+/*
+ * Get platform timer value.
+ */
+static u64 sargantana_alveo_timer_value(void)
+{
+ return ((u64)*(timer_base_ptr + ADDR_TIME_H) << 32) + *(timer_base_ptr + ADDR_TIME_L);
+}
+
+/*
+ * Start platform timer event for current HART.
+ */
+static void sargantana_alveo_timer_event_start(u64 next_event)
+{
+ *(timer_base_ptr + ADDR_TIMECMP_H) = next_event >> 32;
+ *(timer_base_ptr + ADDR_TIMECMP_L) = next_event;
+}
+
+/*
+ * Stop platform timer event for current HART.
+ */
+static void sargantana_alveo_timer_event_stop(void)
+{
+
+ *(timer_base_ptr + ADDR_TIMECMP_H) = 0;
+ *(timer_base_ptr + ADDR_TIMECMP_L) = 0;
+}
+
+static struct sbi_timer_device mtimer = {
+ .name = "generic_timer", // TODO Where the timer comes from? I would prefer a better name :p
+ .timer_freq = SARGANTANA_ALVEO_UART_INPUT_FREQ,
+ .timer_value = sargantana_alveo_timer_value,
+ .timer_event_start = sargantana_alveo_timer_event_start,
+ .timer_event_stop = sargantana_alveo_timer_event_stop
+};
+
+/*
+ * Initialize platform timer for current HART.
+ */
+static int sargantana_alveo_timer_init(bool cold_boot)
+{
+ *(timer_base_ptr + ADDR_TIMECMP_H) = 0;
+ *(timer_base_ptr + ADDR_TIMECMP_L) = 0;
+ sbi_timer_set_device(&mtimer);
+ return 0;
+}
+
+/*
+ * Platform descriptor.
+ */
+const struct sbi_platform_operations sargantana_alveo_ops = {
+ .early_init = sargantana_alveo_early_init,
+ .final_init = sargantana_alveo_final_init,
+ .console_init = sargantana_alveo_console_init,
+ .irqchip_init = sargantana_alveo_irqchip_init,
+ .ipi_init = sargantana_alveo_ipi_init,
+ .timer_init = sargantana_alveo_timer_init
+};
+const struct sbi_platform platform = {
+ .opensbi_version = OPENSBI_VERSION,
+ .platform_version = SBI_PLATFORM_VERSION(0x0, 0x01),
+ .name = "Sargantana (for Xilinx Alveo FPGA)",
+ .features = SBI_PLATFORM_DEFAULT_FEATURES,
+ .hart_count = SARGANTANA_ALVEO_HART_COUNT,
+ .hart_stack_size = SBI_PLATFORM_DEFAULT_HART_STACK_SIZE,
+ .platform_ops_addr = (unsigned long)&sargantana_alveo_ops
+};

View File

@@ -0,0 +1,68 @@
Only in busybox-1.36.1-mod: tags
diff -up -r busybox-1.36.1/util-linux/switch_root.c busybox-1.36.1-mod/util-linux/switch_root.c
--- busybox-1.36.1/util-linux/switch_root.c 2021-09-30 00:04:47.000000000 +0200
+++ busybox-1.36.1-mod/util-linux/switch_root.c 2024-07-01 16:08:28.336541504 +0200
@@ -181,6 +181,8 @@ int switch_root_main(int argc UNUSED_PAR
unsigned dry_run = 0;
dev_t rootdev;
+ printf("HELLO THIS IS SWITCH ROOT STARTING\n");
+
// Parse args. '+': stop at first non-option
if (ENABLE_SWITCH_ROOT && (!ENABLE_RUN_INIT || applet_name[0] == 's')) {
//usage:#define switch_root_trivial_usage
@@ -241,12 +243,15 @@ int switch_root_main(int argc UNUSED_PAR
if (stat("/init", &st) != 0 || !S_ISREG(st.st_mode)) {
bb_error_msg_and_die("'%s' is not a regular file", "/init");
}
+ printf("SWITCH ROOT LINE %d OK\n", __LINE__);
statfs("/", &stfs); // this never fails
+ printf("SWITCH ROOT LINE %d OK\n", __LINE__);
if ((unsigned)stfs.f_type != RAMFS_MAGIC
&& (unsigned)stfs.f_type != TMPFS_MAGIC
) {
bb_simple_error_msg_and_die("root filesystem is not ramfs/tmpfs");
}
+ printf("SWITCH ROOT LINE %d OK\n", __LINE__);
if (!dry_run) {
// Zap everything out of rootdev
@@ -258,19 +263,26 @@ int switch_root_main(int argc UNUSED_PAR
bb_simple_perror_msg_and_die("error moving root");
}
}
+ printf("SWITCH ROOT LINE %d OK\n", __LINE__);
+ printf("XCHROOT\n");
xchroot(".");
+ printf("SWITCH ROOT LINE %d OK\n", __LINE__);
// The chdir is needed to recalculate "." and ".." links
/*xchdir("/"); - done in xchroot */
// If a new console specified, redirect stdin/stdout/stderr to it
if (console) {
+ printf("REDIRECTING CONSOLE\n");
+ printf("SWITCH ROOT LINE %d OK\n", __LINE__);
int fd = open_or_warn(console, O_RDWR);
if (fd >= 0) {
xmove_fd(fd, 0);
xdup2(0, 1);
xdup2(0, 2);
}
+ printf("SWITCH ROOT LINE %d OK\n", __LINE__);
}
+ printf("SWITCH ROOT LINE %d OK\n", __LINE__);
if (dry_run) {
// Does NEW_INIT look like it can be executed?
@@ -280,8 +292,11 @@ int switch_root_main(int argc UNUSED_PAR
if (access(argv[0], X_OK) == 0)
return 0;
} else {
+ printf("SWITCH ROOT LINE %d OK\n", __LINE__);
+ printf("LAUNCHING EXECV\n");
// Exec NEW_INIT
execv(argv[0], argv);
+ printf("RETURNED FROM EXECV???\n");
}
bb_perror_msg_and_die("can't execute '%s'", argv[0]);
}

View File

@@ -0,0 +1,21 @@
diff --git a/drivers/xxvnet_carv.c b/drivers/xxvnet_carv.c
index d3f60f9..9fd4c21 100644
--- a/drivers/xxvnet_carv.c
+++ b/drivers/xxvnet_carv.c
@@ -36,6 +36,7 @@
#include <linux/iopoll.h>
#include <linux/random.h>
#include <linux/clk.h>
+#include <linux/platform_device.h>
#include "xxvnet_carv.h"
@@ -1511,7 +1512,7 @@ axienet_dma_probe(struct platform_device *pdev, struct net_device *ndev)
spin_lock_init(&q->tx_lock);
spin_lock_init(&q->rx_lock);
- netif_napi_add(ndev, &lp->napi, axienet_rx_poll, AXIENET_NAPI_WEIGHT);
+ netif_napi_add(ndev, &lp->napi, axienet_rx_poll);
return 0;
}

View File

@@ -0,0 +1,7 @@
diff --git a/drivers/Kbuild b/drivers/Kbuild
index 28d6c0f..7f02860 100644
--- a/drivers/Kbuild
+++ b/drivers/Kbuild
@@ -1,2 +1 @@
obj-m := xxvnet_carv.o
-obj-m := xilinx_dma.o

View File

@@ -0,0 +1,23 @@
diff --git a/drivers/xxvnet_carv.c b/drivers/xxvnet_carv.c
index eb664bb..d3f60f9 100644
--- a/drivers/xxvnet_carv.c
+++ b/drivers/xxvnet_carv.c
@@ -1435,12 +1435,12 @@ static void axienet_poll_controller(struct net_device *ndev)
{
struct axienet_local *lp = netdev_priv(ndev);
- disable_irq(lp->tx_irq);
- disable_irq(lp->rx_irq);
- axienet_rx_irq(lp->tx_irq, ndev);
- axienet_tx_irq(lp->rx_irq, ndev);
- enable_irq(lp->tx_irq);
- enable_irq(lp->rx_irq);
+ disable_irq(lp->dq->tx_irq);
+ disable_irq(lp->dq->rx_irq);
+ axienet_rx_irq(lp->dq->tx_irq, ndev);
+ axienet_tx_irq(lp->dq->rx_irq, ndev);
+ enable_irq(lp->dq->tx_irq);
+ enable_irq(lp->dq->rx_irq);
}
#endif

View File

@@ -0,0 +1,37 @@
diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c
index c366701..c5b5249 100644
--- a/lib/sbi/sbi_hart.c
+++ b/lib/sbi/sbi_hart.c
@@ -199,7 +199,7 @@ static int delegate_traps(struct sbi_scratch *scratch)
return 0;
/* Send M-mode interrupts and most exceptions to S-mode */
- interrupts = MIP_SSIP | MIP_STIP | MIP_SEIP;
+ interrupts = MIP_SSIP | MIP_STIP;
interrupts |= sbi_pmu_irq_bit();
exceptions = (1U << CAUSE_MISALIGNED_FETCH) | (1U << CAUSE_BREAKPOINT) |
diff --git a/lib/sbi/sbi_irqchip.c b/lib/sbi/sbi_irqchip.c
index 0ae604a..dd4592a 100644
--- a/lib/sbi/sbi_irqchip.c
+++ b/lib/sbi/sbi_irqchip.c
@@ -37,8 +37,7 @@ int sbi_irqchip_init(struct sbi_scratch *scratch, bool cold_boot)
if (rc)
return rc;
- if (ext_irqfn != default_irqfn)
- csr_set(CSR_MIE, MIP_MEIP);
+ csr_set(CSR_MIE, MIP_MEIP);
return 0;
}
@@ -47,8 +46,7 @@ void sbi_irqchip_exit(struct sbi_scratch *scratch)
{
const struct sbi_platform *plat = sbi_platform_ptr(scratch);
- if (ext_irqfn != default_irqfn)
- csr_clear(CSR_MIE, MIP_MEIP);
+ csr_clear(CSR_MIE, MIP_MEIP);
sbi_platform_irqchip_exit(plat);
}

View File

@@ -0,0 +1,19 @@
diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c
index c366701..1ef6145 100644
--- a/lib/sbi/sbi_hart.c
+++ b/lib/sbi/sbi_hart.c
@@ -241,6 +241,14 @@ void sbi_hart_delegation_dump(struct sbi_scratch *scratch,
prefix, suffix, csr_read(CSR_MIDELEG));
sbi_printf("%sMEDELEG%s: 0x%" PRILX "\n",
prefix, suffix, csr_read(CSR_MEDELEG));
+ sbi_printf("%sMTVEC%s : 0x%" PRILX "\n",
+ prefix, suffix, csr_read(CSR_MTVEC));
+ sbi_printf("%sMIE%s : 0x%" PRILX "\n",
+ prefix, suffix, csr_read(CSR_MIE));
+ sbi_printf("%sMIP%s : 0x%" PRILX "\n",
+ prefix, suffix, csr_read(CSR_MIP));
+ sbi_printf("%sMSTATUS%s: 0x%" PRILX "\n",
+ prefix, suffix, csr_read(CSR_MSTATUS));
}
unsigned int sbi_hart_mhpm_mask(struct sbi_scratch *scratch)

View File

@@ -0,0 +1,24 @@
diff --git a/lib/sbi/sbi_irqchip.c b/lib/sbi/sbi_irqchip.c
index 0ae604a..dd4592a 100644
--- a/lib/sbi/sbi_irqchip.c
+++ b/lib/sbi/sbi_irqchip.c
@@ -37,8 +37,7 @@ int sbi_irqchip_init(struct sbi_scratch *scratch, bool cold_boot)
if (rc)
return rc;
- if (ext_irqfn != default_irqfn)
- csr_set(CSR_MIE, MIP_MEIP);
+ csr_set(CSR_MIE, MIP_MEIP);
return 0;
}
@@ -47,8 +46,7 @@ void sbi_irqchip_exit(struct sbi_scratch *scratch)
{
const struct sbi_platform *plat = sbi_platform_ptr(scratch);
- if (ext_irqfn != default_irqfn)
- csr_clear(CSR_MIE, MIP_MEIP);
+ csr_clear(CSR_MIE, MIP_MEIP);
sbi_platform_irqchip_exit(plat);
}

View File

@@ -0,0 +1,26 @@
diff --git a/lib/sbi/sbi_irqchip.c b/lib/sbi/sbi_irqchip.c
index 0ae604a..94832c8 100644
--- a/lib/sbi/sbi_irqchip.c
+++ b/lib/sbi/sbi_irqchip.c
@@ -37,8 +37,8 @@ int sbi_irqchip_init(struct sbi_scratch *scratch, bool cold_boot)
if (rc)
return rc;
- if (ext_irqfn != default_irqfn)
- csr_set(CSR_MIE, MIP_MEIP);
+ csr_set(CSR_MIE, MIP_MEIP | MIP_SEIP);
+ csr_set(CSR_MSTATUS, MSTATUS_MIE | MSTATUS_SIE);
return 0;
}
@@ -47,8 +47,8 @@ void sbi_irqchip_exit(struct sbi_scratch *scratch)
{
const struct sbi_platform *plat = sbi_platform_ptr(scratch);
- if (ext_irqfn != default_irqfn)
- csr_clear(CSR_MIE, MIP_MEIP);
+ csr_clear(CSR_MIE, MIP_MEIP | MIP_SEIP);
+ csr_clear(CSR_MSTATUS, MSTATUS_MIE | MSTATUS_SIE);
sbi_platform_irqchip_exit(plat);
}

View File

@@ -0,0 +1,13 @@
--- a/platform/fpga/openpiton/platform.c 2024-03-12 16:27:13.886525365 +0100
+++ b/platform/fpga/openpiton/platform.c 2024-05-27 11:42:47.748244398 +0200
@@ -24,8 +24,8 @@
#define OPENPITON_DEFAULT_UART_REG_WIDTH 1
#define OPENPITON_DEFAULT_UART_REG_OFFSET 0
#define OPENPITON_DEFAULT_PLIC_ADDR 0xfff1100000
-#define OPENPITON_DEFAULT_PLIC_NUM_SOURCES 2
-#define OPENPITON_DEFAULT_HART_COUNT 3
+#define OPENPITON_DEFAULT_PLIC_NUM_SOURCES 3
+#define OPENPITON_DEFAULT_HART_COUNT 20
#define OPENPITON_DEFAULT_CLINT_ADDR 0xfff1020000
#define OPENPITON_DEFAULT_ACLINT_MTIMER_FREQ 1000000
#define OPENPITON_DEFAULT_ACLINT_MSWI_ADDR \

View File

@@ -0,0 +1,200 @@
diff --git a/lib/sbi/sbi_irqchip.c b/lib/sbi/sbi_irqchip.c
index 0ae604a..e34e90c 100644
--- a/lib/sbi/sbi_irqchip.c
+++ b/lib/sbi/sbi_irqchip.c
@@ -9,6 +9,9 @@
#include <sbi/sbi_irqchip.h>
#include <sbi/sbi_platform.h>
+#include <sbi/sbi_console.h>
+
+static void do_plic_test(void);
static int default_irqfn(void)
{
@@ -37,8 +40,10 @@ int sbi_irqchip_init(struct sbi_scratch *scratch, bool cold_boot)
if (rc)
return rc;
- if (ext_irqfn != default_irqfn)
- csr_set(CSR_MIE, MIP_MEIP);
+ //csr_set(CSR_MIE, MIP_SEIP);
+ //csr_set(CSR_MSTATUS, MSTATUS_SIE);
+
+ do_plic_test();
return 0;
}
@@ -47,8 +52,170 @@ void sbi_irqchip_exit(struct sbi_scratch *scratch)
{
const struct sbi_platform *plat = sbi_platform_ptr(scratch);
- if (ext_irqfn != default_irqfn)
- csr_clear(CSR_MIE, MIP_MEIP);
+ //csr_clear(CSR_MIE, MIP_SEIP);
+ //csr_clear(CSR_MSTATUS, MSTATUS_SIE);
sbi_platform_irqchip_exit(plat);
}
+
+
+/* ----------------- PLIC tests ---------------- */
+
+
+#define MIE_MEIE (1UL << 11) // Machine External Interrupt Enable
+#define SIE_SEIE (1UL << 9)
+#define MIDELEG_SEIE (1UL << 9) // Delegate Machine External Interrupt to Supervisor
+#define PLIC_TIMER_PORT 4
+// Base address of PLIC
+#define PLIC_BASE 0x40800000UL
+#define PLIC_PRIORITY_OFFSET 0x0UL
+#define PLIC_PENDING_OFFSET 0x1000UL
+#define PLIC_ENABLE_OFFSET 0x2080UL
+#define PLIC_THRESHOLD_OFFSET 0x201000UL
+#define PLIC_CLAIM_OFFSET 0x201004UL
+
+// Aux timer
+#define AUX_TIMER_BASE 0x40010000UL
+#define MTIMECMP_OFFSET 0x4000UL
+#define MTIME_OFFSET 0xBFF8UL
+
+#define MSTATUS_MPP_MASK (3 << 11)
+#define MSTATUS_MPP_SUPERVISOR (1 << 11)
+
+static volatile unsigned long *mtime = (unsigned long *)(AUX_TIMER_BASE + MTIME_OFFSET);
+static volatile unsigned long *mtimecmp = (unsigned long *)(AUX_TIMER_BASE + MTIMECMP_OFFSET);
+
+
+static void dumpregs(int machine)
+{
+ char *prefix = "\t";
+ char *suffix = "\t";
+ sbi_printf("Registers:\n");
+ if (machine) {
+ sbi_printf("%sMIE%s: 0x%" PRILX "\n",
+ prefix, suffix, csr_read(CSR_MIE));
+ sbi_printf("%sMIP%s: 0x%" PRILX "\n",
+ prefix, suffix, csr_read(CSR_MIP));
+ sbi_printf("%sMSTATUS%s: 0x%" PRILX "\n",
+ prefix, suffix, csr_read(CSR_MSTATUS));
+ sbi_printf("%sMIDELEG%s: 0x%" PRILX "\n",
+ prefix, suffix, csr_read(CSR_MIDELEG));
+ }
+ sbi_printf("%sSIE%s: 0x%" PRILX "\n",
+ prefix, suffix, csr_read(CSR_SIE));
+ sbi_printf("%sSIP%s: 0x%" PRILX "\n",
+ prefix, suffix, csr_read(CSR_SIP));
+ sbi_printf("%sSSTATUS%s: 0x%" PRILX "\n",
+ prefix, suffix, csr_read(CSR_SSTATUS));
+ sbi_printf("%sSTVEC%s: 0x%" PRILX "\n",
+ prefix, suffix, csr_read(CSR_STVEC));
+}
+
+static void __attribute__((optimize("O0"))) switch_to_supervisor_mode(int (*target_address)(void))
+{
+ unsigned long mstatus;
+
+ // Read the current mstatus
+ asm volatile("csrr %0, mstatus" : "=r"(mstatus));
+
+ // Set the MPP field to supervisor mode
+ mstatus = (mstatus & ~MSTATUS_MPP_MASK) | MSTATUS_MPP_SUPERVISOR;
+
+ // Write back the modified mstatus
+ asm volatile("csrw mstatus, %0" : : "r"(mstatus));
+
+ // Set the mepc to the target address
+ asm volatile("csrw mepc, %0" : : "r"(target_address));
+
+ // Use mret to return to the specified address in supervisor mode
+ asm volatile("mret");
+}
+
+static int supervisor_mode_code(void)
+{
+ sbi_printf("Hello from supervisor\n");
+ dumpregs(0);
+
+ /* Enable timer interrupt */
+ *mtimecmp = *mtime + 10000;
+
+ sbi_printf("Timer alarm programmed\n");
+ sbi_printf("Waiting for interrupt...\n");
+ int i = 0;
+ char *s = "-\\|/";
+ while (1) {
+ for (volatile unsigned long j = 0; j < 100000; j++);
+ sbi_printf("\r%c", s[i++]);
+ if (i >= 4)
+ i = 0;
+ }
+ return 0;
+}
+
+static void __attribute__((aligned(4))) __attribute__((interrupt ("supervisor"))) supervisor_trap_entry(void)
+{
+ sbi_printf("\nSupervisor Trap Entry Reached!\n");
+ sbi_printf("\nTEST-RESULT-OK\n");
+ while (1) {
+ }
+}
+
+static void do_plic_test(void)
+{
+ sbi_printf("--- TESTING PLIC ---\n");
+
+ /* Disable auxiliar timer interrupt */
+ *mtimecmp = 0xffffffffUL;
+ sbi_printf("Timer interrupt disabled\n");
+
+
+ /* Enable supervisor interrupt delegation */
+
+ csr_set(CSR_SIE, SIE_SEIE); // Enable supervisor external interrupts
+ csr_set(CSR_SSTATUS, SSTATUS_SIE); // Enable global interrupts in supervisor mode
+ csr_set(CSR_MIDELEG, MIDELEG_SEIE); // Delegate machine interrupts to supervisor mode
+ csr_write(CSR_STVEC, &supervisor_trap_entry);
+
+ sbi_printf("Enabled supervisor delegation:\n");
+
+ dumpregs(1);
+
+ /* Configure PLIC aux timer input */
+ volatile unsigned *plic_priority = (unsigned *)(PLIC_BASE + PLIC_PRIORITY_OFFSET + PLIC_TIMER_PORT * 4);
+ volatile unsigned *plic_enable = (unsigned *)(PLIC_BASE + PLIC_ENABLE_OFFSET);
+ volatile unsigned *plic_threshold = (unsigned *)(PLIC_BASE + PLIC_THRESHOLD_OFFSET);
+ volatile unsigned *plic_claim = (unsigned *)(PLIC_BASE + PLIC_CLAIM_OFFSET);
+ volatile unsigned *plic_pending = (unsigned *)(PLIC_BASE + PLIC_PENDING_OFFSET);
+
+ sbi_printf("Enabling timer in PLIC\n");
+ *plic_priority = PLIC_TIMER_PORT;
+ *plic_threshold = PLIC_TIMER_PORT - 1;
+ *plic_enable |= (1 << PLIC_TIMER_PORT);
+
+ /* Clear interrupt */
+ sbi_printf("Pending: %d\n", *plic_pending);
+ unsigned claim = *plic_claim;
+ sbi_printf("Claim: %d\n", claim);
+ *plic_claim = claim;
+ sbi_printf("Pending: %d\n", *plic_pending);
+
+ sbi_printf("Clearing MIP\n");
+ csr_write(CSR_MIP, 0);
+
+ /* Enable external timer interrupts */
+ //sbi_printf("Enabling MEIE in MIE register\n");
+ //csr_set(CSR_MIE, MIE_MEIE); /* Needed? */
+ //sbi_printf("Enabling MIE in MSTATUS register\n");
+ //csr_set(CSR_MSTATUS, MSTATUS_MIE); /* Needed? */
+
+ sbi_printf("Switching to supervisor\n");
+
+ dumpregs(1);
+
+ switch_to_supervisor_mode(&supervisor_mode_code);
+
+ /* Never reached */
+ while (1);
+}
+
+

View File

@@ -0,0 +1,229 @@
diff --git a/lib/sbi/sbi_timer.c b/lib/sbi/sbi_timer.c
index 7b618de..65e42b0 100644
--- a/lib/sbi/sbi_timer.c
+++ b/lib/sbi/sbi_timer.c
@@ -183,13 +183,17 @@ int sbi_timer_init(struct sbi_scratch *scratch, bool cold_boot)
u64 *time_delta;
const struct sbi_platform *plat = sbi_platform_ptr(scratch);
+ sbi_printf("sbi_timer_init: begins\n");
+
if (cold_boot) {
time_delta_off = sbi_scratch_alloc_offset(sizeof(*time_delta));
if (!time_delta_off)
return SBI_ENOMEM;
- if (sbi_hart_has_extension(scratch, SBI_HART_EXT_ZICNTR))
+ if (sbi_hart_has_extension(scratch, SBI_HART_EXT_ZICNTR)) {
+ sbi_printf("sbi_timer_init: got Zicntr extension\n");
get_time_val = get_ticks;
+ }
} else {
if (!time_delta_off)
return SBI_ENOMEM;
@@ -198,7 +202,10 @@ int sbi_timer_init(struct sbi_scratch *scratch, bool cold_boot)
time_delta = sbi_scratch_offset_ptr(scratch, time_delta_off);
*time_delta = 0;
- return sbi_platform_timer_init(plat, cold_boot);
+ int rc = sbi_platform_timer_init(plat, cold_boot);
+ if (rc)
+ sbi_printf("sbi_platform_timer: sbi_platform_timer_init failed (%d)\n", rc);
+ return rc;
}
void sbi_timer_exit(struct sbi_scratch *scratch)
diff --git a/lib/sbi/sbi_trap.c b/lib/sbi/sbi_trap.c
index b4f3a17..cde2073 100644
--- a/lib/sbi/sbi_trap.c
+++ b/lib/sbi/sbi_trap.c
@@ -283,6 +283,7 @@ static int sbi_trap_aia_irq(void)
*/
struct sbi_trap_context *sbi_trap_handler(struct sbi_trap_context *tcntx)
{
+ sbi_printf("<");
int rc = SBI_ENOTSUPP;
const char *msg = "trap handler failed";
struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
@@ -295,6 +296,7 @@ struct sbi_trap_context *sbi_trap_handler(struct sbi_trap_context *tcntx)
sbi_trap_set_context(scratch, tcntx);
if (mcause & MCAUSE_IRQ_MASK) {
+ sbi_printf("i(%lu)", mcause & ~MCAUSE_IRQ_MASK);
if (sbi_hart_has_extension(sbi_scratch_thishart_ptr(),
SBI_HART_EXT_SMAIA))
rc = sbi_trap_aia_irq();
@@ -306,35 +308,42 @@ struct sbi_trap_context *sbi_trap_handler(struct sbi_trap_context *tcntx)
switch (mcause) {
case CAUSE_ILLEGAL_INSTRUCTION:
+ sbi_printf("I");
rc = sbi_illegal_insn_handler(tcntx);
msg = "illegal instruction handler failed";
break;
case CAUSE_MISALIGNED_LOAD:
+ sbi_printf("L");
sbi_pmu_ctr_incr_fw(SBI_PMU_FW_MISALIGNED_LOAD);
rc = sbi_misaligned_load_handler(tcntx);
msg = "misaligned load handler failed";
break;
case CAUSE_MISALIGNED_STORE:
+ sbi_printf("S");
sbi_pmu_ctr_incr_fw(SBI_PMU_FW_MISALIGNED_STORE);
rc = sbi_misaligned_store_handler(tcntx);
msg = "misaligned store handler failed";
break;
case CAUSE_SUPERVISOR_ECALL:
case CAUSE_MACHINE_ECALL:
+ sbi_printf("E");
rc = sbi_ecall_handler(tcntx);
msg = "ecall handler failed";
break;
case CAUSE_LOAD_ACCESS:
+ sbi_printf("l");
sbi_pmu_ctr_incr_fw(SBI_PMU_FW_ACCESS_LOAD);
rc = sbi_load_access_handler(tcntx);
msg = "load fault handler failed";
break;
case CAUSE_STORE_ACCESS:
+ sbi_printf("s");
sbi_pmu_ctr_incr_fw(SBI_PMU_FW_ACCESS_STORE);
rc = sbi_store_access_handler(tcntx);
msg = "store fault handler failed";
break;
default:
+ sbi_printf("R");
/* If the trap came from S or U mode, redirect it there */
msg = "trap redirect failed";
rc = sbi_trap_redirect(regs, trap);
@@ -344,6 +353,8 @@ struct sbi_trap_context *sbi_trap_handler(struct sbi_trap_context *tcntx)
trap_done:
if (rc)
sbi_trap_error(msg, rc, tcntx);
+ else
+ sbi_printf(">");
if (((regs->mstatus & MSTATUS_MPP) >> MSTATUS_MPP_SHIFT) != PRV_M)
sbi_sse_process_pending_events(regs);
diff --git a/lib/utils/timer/fdt_timer.c b/lib/utils/timer/fdt_timer.c
index f468730..db20526 100644
--- a/lib/utils/timer/fdt_timer.c
+++ b/lib/utils/timer/fdt_timer.c
@@ -7,6 +7,7 @@
* Anup Patel <anup.patel@wdc.com>
*/
+#include <sbi/sbi_console.h>
#include <sbi/sbi_error.h>
#include <sbi/sbi_scratch.h>
#include <sbi_utils/fdt/fdt_helper.h>
@@ -39,19 +40,26 @@ static int fdt_timer_cold_init(void)
void *fdt = fdt_get_address();
for (pos = 0; pos < fdt_timer_drivers_size; pos++) {
+ sbi_printf("fdt_timer_cold_init: pos = %d\n", pos);
drv = fdt_timer_drivers[pos];
noff = -1;
while ((noff = fdt_find_match(fdt, noff,
drv->match_table, &match)) >= 0) {
+
+ sbi_printf("fdt_timer_cold_init: got match, name = %s\n", match->compatible);
if (!fdt_node_is_enabled(fdt, noff))
continue;
+ sbi_printf("fdt_timer_cold_init: enabled\n");
+
/* drv->cold_init must not be NULL */
if (drv->cold_init == NULL)
return SBI_EFAIL;
rc = drv->cold_init(fdt, noff, match);
+ sbi_printf("fdt_timer_cold_init: drc->cold_init = %d\n", rc);
+
if (rc == SBI_ENODEV)
continue;
if (rc)
@@ -69,6 +77,7 @@ static int fdt_timer_cold_init(void)
* We can't fail here since systems with Sstc might not provide
* mtimer/clint DT node in the device tree.
*/
+ sbi_printf("fdt_timer_cold_init: returns 0\n");
return 0;
}
@@ -78,9 +87,15 @@ int fdt_timer_init(bool cold_boot)
if (cold_boot) {
rc = fdt_timer_cold_init();
- if (rc)
+ if (rc) {
+ sbi_printf("fdt_timer_init: fdt_timer_cold_init failed (%d)\n", rc);
return rc;
+ }
}
- return fdt_timer_warm_init();
+ rc = fdt_timer_warm_init();
+ if (rc)
+ sbi_printf("fdt_timer_init: fdt_timer_warm_init failed (%d)\n", rc);
+
+ return rc;
}
diff --git a/lib/utils/timer/fdt_timer_mtimer.c b/lib/utils/timer/fdt_timer_mtimer.c
index 9e27e3a..cef2ee6 100644
--- a/lib/utils/timer/fdt_timer_mtimer.c
+++ b/lib/utils/timer/fdt_timer_mtimer.c
@@ -8,6 +8,7 @@
*/
#include <libfdt.h>
+#include <sbi/sbi_console.h>
#include <sbi/sbi_error.h>
#include <sbi/sbi_heap.h>
#include <sbi/sbi_list.h>
@@ -33,6 +34,7 @@ static struct aclint_mtimer_data *mt_reference = NULL;
static int timer_mtimer_cold_init(void *fdt, int nodeoff,
const struct fdt_match *match)
{
+
int rc;
unsigned long addr[2], size[2];
struct timer_mtimer_node *mtn, *n;
@@ -40,6 +42,8 @@ static int timer_mtimer_cold_init(void *fdt, int nodeoff,
const struct timer_mtimer_quirks *quirks = match->data;
bool is_clint = quirks && quirks->is_clint;
+ sbi_printf("timer_mtimer_cold_init: begins, is_clint = %d\n", (int) is_clint);
+
mtn = sbi_zalloc(sizeof(*mtn));
if (!mtn)
return SBI_ENOMEM;
@@ -49,6 +53,7 @@ static int timer_mtimer_cold_init(void *fdt, int nodeoff,
&addr[0], &size[0], &addr[1], &size[1],
&mt->first_hartid, &mt->hart_count);
if (rc) {
+ sbi_printf("timer_mtimer_cold_init: fdt_parse_aclint_node failed (%d)\n", rc);
sbi_free(mtn);
return rc;
}
@@ -57,6 +62,7 @@ static int timer_mtimer_cold_init(void *fdt, int nodeoff,
rc = fdt_parse_timebase_frequency(fdt, &mt->mtime_freq);
if (rc) {
+ sbi_printf("timer_mtimer_cold_init: fdt_parse_timebase_frequency failed (%d)\n", rc);
sbi_free(mtn);
return rc;
}
@@ -83,6 +89,11 @@ static int timer_mtimer_cold_init(void *fdt, int nodeoff,
mt->mtimecmp_size = size[1];
}
+ sbi_printf("timer_mtimer_cold_init: mtime_addr = 0x%08lx\n", mt->mtime_addr);
+ sbi_printf("timer_mtimer_cold_init: mtime_size = 0x%08lx\n", mt->mtime_size);
+ sbi_printf("timer_mtimer_cold_init: mtimecmp_addr = 0x%08lx\n", mt->mtimecmp_addr);
+ sbi_printf("timer_mtimer_cold_init: mtimecmp_size = 0x%08lx\n", mt->mtimecmp_size);
+
/* Apply additional quirks */
if (quirks) {
mt->has_64bit_mmio = quirks->has_64bit_mmio;

View File

@@ -0,0 +1,167 @@
diff --git a/platform/fpga/ox_alveo/Kconfig b/platform/fpga/ox_alveo/Kconfig
new file mode 100644
index 0000000..bf3e7e6
--- /dev/null
+++ b/platform/fpga/ox_alveo/Kconfig
@@ -0,0 +1,5 @@
+config PLATFORM_OX_ALVEO_FPGA
+ bool
+ select SERIAL_UART8250
+ select IRQCHIP_PLIC
+ default y
diff --git a/platform/fpga/ox_alveo/configs/defconfig b/platform/fpga/ox_alveo/configs/defconfig
new file mode 100644
index 0000000..e69de29
diff --git a/platform/fpga/ox_alveo/objects.mk b/platform/fpga/ox_alveo/objects.mk
new file mode 100644
index 0000000..d444abe
--- /dev/null
+++ b/platform/fpga/ox_alveo/objects.mk
@@ -0,0 +1,19 @@
+platform-cppflags-y =
+platform-cflags-y =
+platform-asflags-y =
+platform-ldflags-y =
+PLATFORM_RISCV_XLEN = 64
+PLATFORM_RISCV_ABI = lp64d
+PLATFORM_RISCV_ISA = rv64g
+PLATFORM_RISCV_CODE_MODEL = medany
+
+platform-objs-y += platform.o
+
+FW_TEXT_START=0x80000000
+
+FW_DYNAMIC=n
+FW_JUMP=n
+FW_PAYLOAD=y
+
+FW_PAYLOAD_OFFSET=0x200000
+FW_PAYLOAD_ALIGN=0x1000
diff --git a/platform/fpga/ox_alveo/platform.c b/platform/fpga/ox_alveo/platform.c
new file mode 100644
index 0000000..a359b34
--- /dev/null
+++ b/platform/fpga/ox_alveo/platform.c
@@ -0,0 +1,122 @@
+#include <sbi/riscv_asm.h>
+#include <sbi/riscv_encoding.h>
+#include <sbi/sbi_const.h>
+#include <sbi/sbi_platform.h>
+#include <sbi_utils/serial/uart8250.h>
+#include <sbi/sbi_timer.h>
+#include <sbi_utils/irqchip/plic.h>
+
+#define OX_ALVEO_HART_COUNT 1
+
+#define OX_ALVEO_UART_BASE_ADDR 0x40000000
+#define OX_ALVEO_UART_OFFSET 0x1000
+#define OX_ALVEO_UART_INPUT_FREQ 50000000
+#define OX_ALVEO_UART_BAUDRATE 115200
+#define OX_ALVEO_PLIC_ADDR 0x40800000
+#define OX_ALVEO_PLIC_NUM_SOURCES 3
+
+#define OX_ALVEO_TIMER_BASE 0x40170000
+#define ADDR_TIME_L 0x0u // 32 lower bits of the time register
+#define ADDR_TIME_H 0x1u // 32 higher bits of the time register
+#define ADDR_TIMECMP_L 0x2u // 32 lower bits of the time comparator
+#define ADDR_TIMECMP_H 0x3u // 32 higher bits of the time comparator
+
+volatile uint32_t *timer_base_ptr = (uint32_t *)(OX_ALVEO_TIMER_BASE);
+
+static struct plic_data plic = {
+ .addr = OX_ALVEO_PLIC_ADDR,
+ .num_src = OX_ALVEO_PLIC_NUM_SOURCES,
+};
+
+static int ox_alveo_early_init(bool cold_boot) // Platform early initialization.
+{
+ return 0;
+}
+
+static int ox_alveo_final_init(bool cold_boot) // Platform final initialization.
+{
+ return 0;
+}
+
+static int ox_alveo_console_init(void) // Initialize the platform console.
+{
+ return uart8250_init(OX_ALVEO_UART_BASE_ADDR,
+ OX_ALVEO_UART_INPUT_FREQ,
+ OX_ALVEO_UART_BAUDRATE,
+ 2, 4,
+ OX_ALVEO_UART_OFFSET);
+}
+
+static int ox_alveo_irqchip_init(bool cold_boot) // Initialize the platform interrupt controller for current HART.
+{
+ u32 hartid = current_hartid();
+ int ret;
+
+ /* Example if the generic PLIC driver is used */
+ if (cold_boot) {
+ ret = plic_cold_irqchip_init(&plic);
+ if (ret)
+ return ret;
+ }
+
+ return plic_warm_irqchip_init(&plic, 2 * hartid, -1);
+}
+
+static int ox_alveo_ipi_init(bool cold_boot) // Initialize IPI for current HART.
+{
+ return 0;
+}
+
+static u64 ox_alveo_timer_value(void) // Get platform timer value.
+{
+ return ((u64)*(timer_base_ptr + ADDR_TIME_H) << 32) + *(timer_base_ptr + ADDR_TIME_L);
+}
+
+static void ox_alveo_timer_event_start(u64 next_event) // Start platform timer event for current HART.
+{
+ *(timer_base_ptr + ADDR_TIMECMP_H) = next_event >> 32;
+ *(timer_base_ptr + ADDR_TIMECMP_L) = next_event;
+}
+
+static void ox_alveo_timer_event_stop(void) // Stop platform timer event for current HART.
+{
+
+ *(timer_base_ptr + ADDR_TIMECMP_H) = 0;
+ *(timer_base_ptr + ADDR_TIMECMP_L) = 0;
+}
+
+static struct sbi_timer_device mtimer = {
+ .name = "axi_timer",
+ .timer_freq = OX_ALVEO_UART_INPUT_FREQ,
+ .timer_value = ox_alveo_timer_value,
+ .timer_event_start = ox_alveo_timer_event_start,
+ .timer_event_stop = ox_alveo_timer_event_stop
+};
+
+static int ox_alveo_timer_init(bool cold_boot) // Initialize platform timer for current HART.
+{
+ *(timer_base_ptr + ADDR_TIMECMP_H) = 0;
+ *(timer_base_ptr + ADDR_TIMECMP_L) = 0;
+ sbi_timer_set_device(&mtimer);
+ return 0;
+}
+
+const struct sbi_platform_operations ox_alveo_ops = { // Platform descriptor.
+ .early_init = ox_alveo_early_init,
+ .final_init = ox_alveo_final_init,
+ .console_init = ox_alveo_console_init,
+ .irqchip_init = ox_alveo_irqchip_init,
+ .ipi_init = ox_alveo_ipi_init,
+ .timer_init = ox_alveo_timer_init
+};
+
+const struct sbi_platform platform = {
+ .opensbi_version = OPENSBI_VERSION,
+ .platform_version = SBI_PLATFORM_VERSION(0x0, 0x01),
+ .name = "ox (Rodrigo NixOS version)",
+ .features = SBI_PLATFORM_DEFAULT_FEATURES,
+ .hart_count = OX_ALVEO_HART_COUNT,
+ .hart_stack_size = SBI_PLATFORM_DEFAULT_HART_STACK_SIZE,
+ .heap_size = SBI_PLATFORM_DEFAULT_HEAP_SIZE(OX_ALVEO_HART_COUNT),
+ .platform_ops_addr = (unsigned long)&ox_alveo_ops
+};

View File

@@ -0,0 +1,148 @@
diff --git a/platform/fpga/ox_alveo/Kconfig b/platform/fpga/ox_alveo/Kconfig
new file mode 100644
index 0000000..bf3e7e6
--- /dev/null
+++ b/platform/fpga/ox_alveo/Kconfig
@@ -0,0 +1,4 @@
+config PLATFORM_OX_ALVEO_FPGA
+ bool
+ select SERIAL_UART8250
+ default y
diff --git a/platform/fpga/ox_alveo/configs/defconfig b/platform/fpga/ox_alveo/configs/defconfig
new file mode 100644
index 0000000..e69de29
diff --git a/platform/fpga/ox_alveo/objects.mk b/platform/fpga/ox_alveo/objects.mk
new file mode 100644
index 0000000..d444abe
--- /dev/null
+++ b/platform/fpga/ox_alveo/objects.mk
@@ -0,0 +1,19 @@
+platform-cppflags-y =
+platform-cflags-y =
+platform-asflags-y =
+platform-ldflags-y =
+PLATFORM_RISCV_XLEN = 64
+PLATFORM_RISCV_ABI = lp64d
+PLATFORM_RISCV_ISA = rv64imafd
+PLATFORM_RISCV_CODE_MODEL = medany
+
+platform-objs-y += platform.o
+
+FW_TEXT_START=0x80000000
+
+FW_DYNAMIC=n
+FW_JUMP=n
+FW_PAYLOAD=y
+
+FW_PAYLOAD_OFFSET=0x200000
+FW_PAYLOAD_ALIGN=0x1000
diff --git a/platform/fpga/ox_alveo/platform.c b/platform/fpga/ox_alveo/platform.c
new file mode 100644
index 0000000..a359b34
--- /dev/null
+++ b/platform/fpga/ox_alveo/platform.c
@@ -0,0 +1,104 @@
+#include <sbi/riscv_asm.h>
+#include <sbi/riscv_encoding.h>
+#include <sbi/sbi_const.h>
+#include <sbi/sbi_platform.h>
+#include <sbi_utils/serial/uart8250.h>
+#include <sbi/sbi_timer.h>
+
+#define OX_ALVEO_HART_COUNT 1
+
+#define OX_ALVEO_UART_BASE_ADDR 0x40000000
+#define OX_ALVEO_UART_OFFSET 0x1000
+#define OX_ALVEO_UART_INPUT_FREQ 50000000
+#define OX_ALVEO_UART_BAUDRATE 115200
+
+#define OX_ALVEO_TIMER_BASE 0x40170000
+#define ADDR_TIME_L 0x0u // 32 lower bits of the time register
+#define ADDR_TIME_H 0x1u // 32 higher bits of the time register
+#define ADDR_TIMECMP_L 0x2u // 32 lower bits of the time comparator
+#define ADDR_TIMECMP_H 0x3u // 32 higher bits of the time comparator
+
+volatile uint32_t *timer_base_ptr = (uint32_t *)(OX_ALVEO_TIMER_BASE);
+
+static int ox_alveo_early_init(bool cold_boot) // Platform early initialization.
+{
+ return 0;
+}
+
+static int ox_alveo_final_init(bool cold_boot) // Platform final initialization.
+{
+ return 0;
+}
+
+static int ox_alveo_console_init(void) // Initialize the platform console.
+{
+ return uart8250_init(OX_ALVEO_UART_BASE_ADDR,
+ OX_ALVEO_UART_INPUT_FREQ,
+ OX_ALVEO_UART_BAUDRATE,
+ 2, 4,
+ OX_ALVEO_UART_OFFSET);
+}
+
+static int ox_alveo_irqchip_init(bool cold_boot) // Initialize the platform interrupt controller for current HART.
+{
+ u32 hartid = current_hartid();
+ return hartid;
+}
+
+static int ox_alveo_ipi_init(bool cold_boot) // Initialize IPI for current HART.
+{
+ return 0;
+}
+
+static u64 ox_alveo_timer_value(void) // Get platform timer value.
+{
+ return ((u64)*(timer_base_ptr + ADDR_TIME_H) << 32) + *(timer_base_ptr + ADDR_TIME_L);
+}
+
+static void ox_alveo_timer_event_start(u64 next_event) // Start platform timer event for current HART.
+{
+ *(timer_base_ptr + ADDR_TIMECMP_H) = next_event >> 32;
+ *(timer_base_ptr + ADDR_TIMECMP_L) = next_event;
+}
+
+static void ox_alveo_timer_event_stop(void) // Stop platform timer event for current HART.
+{
+
+ *(timer_base_ptr + ADDR_TIMECMP_H) = 0;
+ *(timer_base_ptr + ADDR_TIMECMP_L) = 0;
+}
+
+static struct sbi_timer_device mtimer = {
+ .name = "axi_timer",
+ .timer_freq = OX_ALVEO_UART_INPUT_FREQ,
+ .timer_value = ox_alveo_timer_value,
+ .timer_event_start = ox_alveo_timer_event_start,
+ .timer_event_stop = ox_alveo_timer_event_stop
+};
+
+static int ox_alveo_timer_init(bool cold_boot) // Initialize platform timer for current HART.
+{
+ *(timer_base_ptr + ADDR_TIMECMP_H) = 0;
+ *(timer_base_ptr + ADDR_TIMECMP_L) = 0;
+ sbi_timer_set_device(&mtimer);
+ return 0;
+}
+
+const struct sbi_platform_operations ox_alveo_ops = { // Platform descriptor.
+ .early_init = ox_alveo_early_init,
+ .final_init = ox_alveo_final_init,
+ .console_init = ox_alveo_console_init,
+ .irqchip_init = ox_alveo_irqchip_init,
+ .ipi_init = ox_alveo_ipi_init,
+ .timer_init = ox_alveo_timer_init
+};
+
+const struct sbi_platform platform = {
+ .opensbi_version = OPENSBI_VERSION,
+ .platform_version = SBI_PLATFORM_VERSION(0x0, 0x01),
+ .name = "ox (for Xilinx Alveo FPGA)",
+ .features = SBI_PLATFORM_DEFAULT_FEATURES,
+ .hart_count = OX_ALVEO_HART_COUNT,
+ .hart_stack_size = SBI_PLATFORM_DEFAULT_HART_STACK_SIZE,
+ .platform_ops_addr = (unsigned long)&ox_alveo_ops
+};

15
patches/sa-fpga-crt.patch Normal file
View File

@@ -0,0 +1,15 @@
diff --git a/fpga_core_bridge/simulator/tests/c_tests/common/crt.S b/fpga_core_bridge/simulator/tests/c_tests/common/crt.S
index 3f5bb2c..bd738b1 100644
--- a/fpga_core_bridge/simulator/tests/c_tests/common/crt.S
+++ b/fpga_core_bridge/simulator/tests/c_tests/common/crt.S
@@ -59,10 +59,6 @@ _start:
#else
bltz t0, 1f
#endif
-2:
- li a0, 1
- sw a0, tohost, t0
- j 2b
1:
#ifdef __riscv_flen

View File

@@ -0,0 +1,92 @@
diff --git a/fpga_core_bridge/simulator/tests/c_tests/plic_supervisor/plic_supervisor_test.c b/fpga_core_bridge/simulator/tests/c_tests/plic_supervisor/plic_supervisor_test.c
index 0cfa681..78d97cb 100644
--- a/fpga_core_bridge/simulator/tests/c_tests/plic_supervisor/plic_supervisor_test.c
+++ b/fpga_core_bridge/simulator/tests/c_tests/plic_supervisor/plic_supervisor_test.c
@@ -68,6 +68,48 @@ uintptr_t handle_trap(uint64_t cause, uint64_t epc, uintptr_t regs[32])
return epc;
}
+static void dumpregs(int machine)
+{
+ printf("Registers:");
+ if (machine) {
+ uint64_t mie;
+ asm volatile("csrr %0, mie" : "=r"(mie));
+ printf("\n MIE: ");
+ printhex(mie);
+
+ uint64_t mip;
+ asm volatile("csrr %0, mip" : "=r"(mip));
+ printf("\n MIP: ");
+ printhex(mip);
+
+ uint64_t mstatus;
+ asm volatile("csrr %0, mstatus" : "=r"(mstatus));
+ printf("\nMSTATUS: ");
+ printhex(mstatus);
+
+ uint64_t mideleg;
+ asm volatile("csrr %0, mideleg" : "=r"(mideleg));
+ printf("\nMIDELEG: ");
+ printhex(mideleg);
+ }
+
+ uint64_t sie;
+ asm volatile("csrr %0, sie" : "=r"(sie));
+ printf("\n SIE: ");
+ printhex(sie);
+
+ uint64_t sip;
+ asm volatile("csrr %0, sip" : "=r"(sip));
+ printf("\n SIP: ");
+ printhex(sip);
+
+ uint64_t sstatus;
+ asm volatile("csrr %0, sstatus" : "=r"(sstatus));
+ printf("\nSSTATUS: ");
+ printhex(sstatus);
+ printf("\n");
+}
+
// Define the bit positions for the external interrupt enable in mie and mideleg registers
#define SIE_SEIE (1 << 9) // Supervisor External Interrupt Enable
#define MIDELEG_MEIE (1 << 11) // Delegate Machine External Interrupt to Supervisor
@@ -156,16 +198,19 @@ void __attribute__((optimize("O0"))) switch_to_supervisor_mode(uint64_t* target_
asm volatile("mret");
}
-uint64_t supervisor_mode_code() {
- int count = 0;
- while (1) {
- if (count == 10000) {
- uart_write_string("\nWaiting for interrupt in supervisor mode...");
- count = 0;
- }
- count++;
- }
- return 0;
+uint64_t supervisor_mode_code()
+{
+ uart_write_string("\nHello from supervisor mode...");
+ dumpregs(0);
+ int count = 0;
+ while (1) {
+ if (count == 10000) {
+ uart_write_string("\nWaiting for interrupt in supervisor mode...");
+ count = 0;
+ }
+ count++;
+ }
+ return 0;
}
void main(void) {
@@ -181,6 +226,8 @@ void main(void) {
// Enable external timer interrupts
// enable_external_timer_interrupt();
+ dumpregs(1);
+
// Switch to supervisor mode and execute supervisor_mode_code
switch_to_supervisor_mode(&supervisor_mode_code);

View File

@@ -0,0 +1,13 @@
diff --git a/fpga_core_bridge/simulator/tests/c_tests/common/test.ld b/fpga_core_bridge/simulator/tests/c_tests/common/test.ld
index 8321d86..f83a9ee 100644
--- a/fpga_core_bridge/simulator/tests/c_tests/common/test.ld
+++ b/fpga_core_bridge/simulator/tests/c_tests/common/test.ld
@@ -26,7 +26,7 @@ SECTIONS
.tohost : { *(.tohost) }
/* text: test code section */
- . = 0x80000000;
+ . = 0x20020000;
.text.init : { *(.text.init) }
. = ALIGN(0x1000);

View File

@@ -0,0 +1,31 @@
diff --git a/fpga_core_bridge/simulator/tests/c_tests/common/syscalls.c b/fpga_core_bridge/simulator/tests/c_tests/common/syscalls.c
index 278ea97..287e5fc 100644
--- a/fpga_core_bridge/simulator/tests/c_tests/common/syscalls.c
+++ b/fpga_core_bridge/simulator/tests/c_tests/common/syscalls.c
@@ -592,8 +592,18 @@ int uart_is_transmit_empty() {
// Function to write a character to the UART
void uart_write_char(char c) {
- while (!uart_is_transmit_empty());
+ //while (!uart_is_transmit_empty());
+
+ /* Delay it a bit, as checking the transmit holding register doesn't seem to
+ * work in the FPGA */
+ for (volatile long i = 0; i < 10000; i++)
+ ;
+
*(volatile uint8_t *)(UART_BASE + UART_THR) = c;
+
+ /* Make new line go back to the start of the line */
+ if (c == '\n')
+ uart_write_char('\r');
}
// Function to write a string to the UART
@@ -602,4 +612,4 @@ void uart_write_string(const char* str) {
uart_write_char(*str++);
asm("fence");
}
-}
\ No newline at end of file
+}

View File

@@ -0,0 +1,83 @@
diff --git a/common/board_f.c b/common/board_f.c
index 1688e27071..216839febb 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -978,6 +978,8 @@ static const init_fnc_t init_sequence_f[] = {
void board_init_f(ulong boot_flags)
{
+ puts("board_init_f() called\n");
+
gd->flags = boot_flags;
gd->have_console = 0;
@@ -990,6 +992,7 @@ void board_init_f(ulong boot_flags)
/* NOTREACHED - jump_to_copy() does not return */
hang();
#endif
+ puts("board_init_f() ends ok\n");
}
#if defined(CONFIG_X86) || defined(CONFIG_ARC)
diff --git a/common/board_r.c b/common/board_r.c
index d798c00a80..cb8119a603 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -786,6 +786,8 @@ static init_fnc_t init_sequence_r[] = {
void board_init_r(gd_t *new_gd, ulong dest_addr)
{
+ puts("board_init_r called\n");
+
/*
* The pre-relocation drivers may be using memory that has now gone
* away. Mark serial as unavailable - this will fall back to the debug
diff --git a/drivers/cpu/riscv_cpu.c b/drivers/cpu/riscv_cpu.c
index d6484d7f4b..64a507248d 100644
--- a/drivers/cpu/riscv_cpu.c
+++ b/drivers/cpu/riscv_cpu.c
@@ -92,10 +92,13 @@ static int riscv_cpu_get_count(const struct udevice *dev)
static int riscv_cpu_bind(struct udevice *dev)
{
+ puts("riscv_cpu_bind called()\n");
+
struct cpu_plat *plat = dev_get_parent_plat(dev);
struct driver *drv;
int ret;
+ puts("looking for timebase-frequency\n");
/* save the hart id */
plat->cpu_id = dev_read_addr(dev);
/* first examine the property in current cpu node */
@@ -105,6 +108,8 @@ static int riscv_cpu_bind(struct udevice *dev)
dev_read_u32(dev->parent, "timebase-frequency",
&plat->timebase_freq);
+ printf("timebase-frequency=%lu\n", (unsigned long) plat->timebase_freq);
+
/*
* Bind riscv-timer driver on boot hart.
*
@@ -125,6 +130,8 @@ static int riscv_cpu_bind(struct udevice *dev)
device_bind_with_driver_data(dev, drv, "riscv_timer",
plat->timebase_freq, ofnode_null(),
NULL);
+ } else {
+ printf("ignoring cpu_id=%d\n", plat->cpu_id);
}
return 0;
diff --git a/lib/hang.c b/lib/hang.c
index 2735774f9a..84eff21ffc 100644
--- a/lib/hang.c
+++ b/lib/hang.c
@@ -22,6 +22,8 @@
*/
void hang(void)
{
+ puts("oh no, we are in hang()\n");
+
#if !defined(CONFIG_SPL_BUILD) || \
(CONFIG_IS_ENABLED(LIBCOMMON_SUPPORT) && \
CONFIG_IS_ENABLED(SERIAL))

View File

@@ -0,0 +1,31 @@
diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S
index 6cecadfac5..f649844b23 100644
--- a/arch/riscv/cpu/start.S
+++ b/arch/riscv/cpu/start.S
@@ -81,7 +81,7 @@ _start:
#if CONFIG_IS_ENABLED(RISCV_MMODE)
li t0, MIE_MSIE
#else
- li t0, SIE_SSIE
+ li t0, (SIE_SSIE + SIE_SEIE + SIE_STIE)
#endif
csrs MODE_PREFIX(ie), t0
#endif
diff --git a/arch/riscv/lib/interrupts.c b/arch/riscv/lib/interrupts.c
index a26ccc721f..b8d2a71223 100644
--- a/arch/riscv/lib/interrupts.c
+++ b/arch/riscv/lib/interrupts.c
@@ -193,10 +193,13 @@ ulong handle_trap(ulong cause, ulong epc, ulong tval, struct pt_regs *regs)
switch (irq) {
case IRQ_M_EXT:
case IRQ_S_EXT:
+ printf("u-boot: got ext interrupt %lu\n", irq);
+ show_regs(regs);
external_interrupt(0); /* handle external interrupt */
break;
case IRQ_M_TIMER:
case IRQ_S_TIMER:
+ printf("u-boot: got timer interrupt %lu\n", irq);
timer_interrupt(0); /* handle timer interrupt */
break;
default:

View File

@@ -0,0 +1,65 @@
diff --git a/cmd/riscv/exception.c b/cmd/riscv/exception.c
index f38f454a0b..9de4effe47 100644
--- a/cmd/riscv/exception.c
+++ b/cmd/riscv/exception.c
@@ -56,6 +56,40 @@ static int do_undefined(struct cmd_tbl *cmdtp, int flag, int argc,
return CMD_RET_FAILURE;
}
+static int do_sregs(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ ulong stvec, sie, sip, sstatus;
+
+ asm volatile ("fence");
+ asm volatile ("csrr %0, stvec" : "=r"(stvec) : );
+ asm volatile ("csrr %0, sie" : "=r"(sie) : );
+ asm volatile ("csrr %0, sip" : "=r"(sip) : );
+ asm volatile ("csrr %0, sstatus" : "=r"(sstatus) : );
+
+ printf("stvec : 0x%016lx\n", stvec);
+ printf("sie : 0x%016lx\n", sie);
+ printf("sip : 0x%016lx\n", sip);
+ printf("sstatus : 0x%016lx\n", sstatus);
+
+ return CMD_RET_SUCCESS;
+}
+
+static int do_enable(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ ulong which = SIE_SSIE | SIE_SEIE | SIE_STIE;
+
+ asm volatile (
+ "csrsi sstatus, 2\n" /* Enable SIE */
+ "csrs sie, %0\n" /* Enable selected interrupts */
+ : /* no output */
+ : "r" (which)
+ );
+
+ return CMD_RET_SUCCESS;
+}
+
static struct cmd_tbl cmd_sub[] = {
U_BOOT_CMD_MKENT(compressed, CONFIG_SYS_MAXARGS, 1, do_compressed,
"", ""),
@@ -67,6 +101,10 @@ static struct cmd_tbl cmd_sub[] = {
"", ""),
U_BOOT_CMD_MKENT(undefined, CONFIG_SYS_MAXARGS, 1, do_undefined,
"", ""),
+ U_BOOT_CMD_MKENT(sregs, CONFIG_SYS_MAXARGS, 1, do_sregs,
+ "", ""),
+ U_BOOT_CMD_MKENT(enable, CONFIG_SYS_MAXARGS, 1, do_enable,
+ "", ""),
};
static char exception_help_text[] =
@@ -77,6 +115,8 @@ static char exception_help_text[] =
" ialign16 - 16 bit aligned instruction\n"
" undefined - illegal instruction\n"
" unaligned - load address misaligned\n"
+ " sregs - print supervisor registers\n"
+ " enable - enable supervisor interrupts\n"
;
#include <exception.h>