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,121 @@ +#include +#include +#include +#include +#include +#include +#include + +#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, + .platform_ops_addr = (unsigned long)&ox_alveo_ops +};