nixos-riscv/ox-alveo-platform.patch

149 lines
4.3 KiB
Diff

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
+};