forked from rarias/nixos-riscv
Move patches to its own directory
This commit is contained in:
438
patches/alveo-uart-sbi-hack.patch
Normal file
438
patches/alveo-uart-sbi-hack.patch
Normal 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
|
||||
+};
|
||||
68
patches/busybox-debug.patch
Normal file
68
patches/busybox-debug.patch
Normal 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]);
|
||||
}
|
||||
21
patches/ethernet-driver-build.patch
Normal file
21
patches/ethernet-driver-build.patch
Normal 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;
|
||||
}
|
||||
7
patches/ethernet-driver-kbuild.patch
Normal file
7
patches/ethernet-driver-kbuild.patch
Normal 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
|
||||
23
patches/ethernet-driver-poll.patch
Normal file
23
patches/ethernet-driver-poll.patch
Normal 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
|
||||
|
||||
37
patches/opensbi-dont-delegate.patch
Normal file
37
patches/opensbi-dont-delegate.patch
Normal 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);
|
||||
}
|
||||
19
patches/opensbi-dump-mregs.patch
Normal file
19
patches/opensbi-dump-mregs.patch
Normal 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)
|
||||
24
patches/opensbi-enable-meip.patch
Normal file
24
patches/opensbi-enable-meip.patch
Normal 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);
|
||||
}
|
||||
26
patches/opensbi-enable-seip.patch
Normal file
26
patches/opensbi-enable-seip.patch
Normal 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);
|
||||
}
|
||||
13
patches/opensbi-lagarto-hun.patch
Normal file
13
patches/opensbi-lagarto-hun.patch
Normal 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 \
|
||||
200
patches/opensbi-test-plic.patch
Normal file
200
patches/opensbi-test-plic.patch
Normal 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);
|
||||
+}
|
||||
+
|
||||
+
|
||||
229
patches/opensbi-timer-debug.patch
Normal file
229
patches/opensbi-timer-debug.patch
Normal 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;
|
||||
167
patches/ox-alveo-platform-plic.patch
Normal file
167
patches/ox-alveo-platform-plic.patch
Normal 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
|
||||
+};
|
||||
148
patches/ox-alveo-platform.patch
Normal file
148
patches/ox-alveo-platform.patch
Normal 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
15
patches/sa-fpga-crt.patch
Normal 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
|
||||
92
patches/sa-fpga-plic-registers.patch
Normal file
92
patches/sa-fpga-plic-registers.patch
Normal 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);
|
||||
|
||||
13
patches/sa-fpga-text-address.patch
Normal file
13
patches/sa-fpga-text-address.patch
Normal 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);
|
||||
31
patches/sa-fpga-uart.patch
Normal file
31
patches/sa-fpga-uart.patch
Normal 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
|
||||
+}
|
||||
83
patches/u-boot-debug.patch
Normal file
83
patches/u-boot-debug.patch
Normal 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))
|
||||
31
patches/uboot-debug-ext-interrupts.patch
Normal file
31
patches/uboot-debug-ext-interrupts.patch
Normal 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:
|
||||
65
patches/uboot-exception-extras.patch
Normal file
65
patches/uboot-exception-extras.patch
Normal 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>
|
||||
Reference in New Issue
Block a user