aboutsummaryrefslogtreecommitdiffstats
path: root/roms/opensbi/platform/thead/c910/platform.c
diff options
context:
space:
mode:
Diffstat (limited to 'roms/opensbi/platform/thead/c910/platform.c')
-rw-r--r--roms/opensbi/platform/thead/c910/platform.c156
1 files changed, 156 insertions, 0 deletions
diff --git a/roms/opensbi/platform/thead/c910/platform.c b/roms/opensbi/platform/thead/c910/platform.c
new file mode 100644
index 000000000..dfa484ad2
--- /dev/null
+++ b/roms/opensbi/platform/thead/c910/platform.c
@@ -0,0 +1,156 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <sbi/riscv_encoding.h>
+#include <sbi/riscv_io.h>
+#include <sbi/sbi_console.h>
+#include <sbi/sbi_const.h>
+#include <sbi/sbi_hart.h>
+#include <sbi/sbi_platform.h>
+#include <sbi_utils/irqchip/plic.h>
+#include <sbi_utils/serial/uart8250.h>
+#include <sbi_utils/sys/clint.h>
+#include "platform.h"
+
+static struct c910_regs_struct c910_regs;
+
+static struct clint_data clint = {
+ .addr = 0, /* Updated at cold boot time */
+ .first_hartid = 0,
+ .hart_count = C910_HART_COUNT,
+ .has_64bit_mmio = FALSE,
+};
+
+static int c910_early_init(bool cold_boot)
+{
+ if (cold_boot) {
+ /* Load from boot core */
+ c910_regs.pmpaddr0 = csr_read(CSR_PMPADDR0);
+ c910_regs.pmpaddr1 = csr_read(CSR_PMPADDR1);
+ c910_regs.pmpaddr2 = csr_read(CSR_PMPADDR2);
+ c910_regs.pmpaddr3 = csr_read(CSR_PMPADDR3);
+ c910_regs.pmpaddr4 = csr_read(CSR_PMPADDR4);
+ c910_regs.pmpaddr5 = csr_read(CSR_PMPADDR5);
+ c910_regs.pmpaddr6 = csr_read(CSR_PMPADDR6);
+ c910_regs.pmpaddr7 = csr_read(CSR_PMPADDR7);
+ c910_regs.pmpcfg0 = csr_read(CSR_PMPCFG0);
+
+ c910_regs.mcor = csr_read(CSR_MCOR);
+ c910_regs.mhcr = csr_read(CSR_MHCR);
+ c910_regs.mccr2 = csr_read(CSR_MCCR2);
+ c910_regs.mhint = csr_read(CSR_MHINT);
+ c910_regs.mxstatus = csr_read(CSR_MXSTATUS);
+
+ c910_regs.plic_base_addr = csr_read(CSR_PLIC_BASE);
+ c910_regs.clint_base_addr =
+ c910_regs.plic_base_addr + C910_PLIC_CLINT_OFFSET;
+ } else {
+ /* Store to other core */
+ csr_write(CSR_PMPADDR0, c910_regs.pmpaddr0);
+ csr_write(CSR_PMPADDR1, c910_regs.pmpaddr1);
+ csr_write(CSR_PMPADDR2, c910_regs.pmpaddr2);
+ csr_write(CSR_PMPADDR3, c910_regs.pmpaddr3);
+ csr_write(CSR_PMPADDR4, c910_regs.pmpaddr4);
+ csr_write(CSR_PMPADDR5, c910_regs.pmpaddr5);
+ csr_write(CSR_PMPADDR6, c910_regs.pmpaddr6);
+ csr_write(CSR_PMPADDR7, c910_regs.pmpaddr7);
+ csr_write(CSR_PMPCFG0, c910_regs.pmpcfg0);
+
+ csr_write(CSR_MCOR, c910_regs.mcor);
+ csr_write(CSR_MHCR, c910_regs.mhcr);
+ csr_write(CSR_MHINT, c910_regs.mhint);
+ csr_write(CSR_MXSTATUS, c910_regs.mxstatus);
+ }
+
+ return 0;
+}
+
+static int c910_final_init(bool cold_boot)
+{
+ return 0;
+}
+
+static int c910_irqchip_init(bool cold_boot)
+{
+ /* Delegate plic enable into S-mode */
+ writel(C910_PLIC_DELEG_ENABLE,
+ (void *)c910_regs.plic_base_addr + C910_PLIC_DELEG_OFFSET);
+
+ return 0;
+}
+
+static int c910_ipi_init(bool cold_boot)
+{
+ int rc;
+
+ if (cold_boot) {
+ clint.addr = c910_regs.clint_base_addr;
+ rc = clint_cold_ipi_init(&clint);
+ if (rc)
+ return rc;
+ }
+
+ return clint_warm_ipi_init();
+}
+
+static int c910_timer_init(bool cold_boot)
+{
+ int ret;
+
+ if (cold_boot) {
+ clint.addr = c910_regs.clint_base_addr;
+ ret = clint_cold_timer_init(&clint, NULL);
+ if (ret)
+ return ret;
+ }
+
+ return clint_warm_timer_init();
+}
+
+static int c910_system_reset_check(u32 type, u32 reason)
+{
+ return 1;
+}
+
+static void c910_system_reset(u32 type, u32 reason)
+{
+ asm volatile ("ebreak");
+}
+
+int c910_hart_start(u32 hartid, ulong saddr)
+{
+ csr_write(CSR_MRVBR, saddr);
+ csr_write(CSR_MRMR, csr_read(CSR_MRMR) | (1 << hartid));
+
+ return 0;
+}
+
+const struct sbi_platform_operations platform_ops = {
+ .early_init = c910_early_init,
+ .final_init = c910_final_init,
+
+ .irqchip_init = c910_irqchip_init,
+
+ .ipi_init = c910_ipi_init,
+ .ipi_send = clint_ipi_send,
+ .ipi_clear = clint_ipi_clear,
+
+ .timer_init = c910_timer_init,
+ .timer_event_start = clint_timer_event_start,
+
+ .system_reset_check = c910_system_reset_check,
+ .system_reset = c910_system_reset,
+
+ .hart_start = c910_hart_start,
+};
+
+const struct sbi_platform platform = {
+ .opensbi_version = OPENSBI_VERSION,
+ .platform_version = SBI_PLATFORM_VERSION(0x0, 0x01),
+ .name = "T-HEAD Xuantie c910",
+ .features = SBI_THEAD_FEATURES,
+ .hart_count = C910_HART_COUNT,
+ .hart_stack_size = SBI_PLATFORM_DEFAULT_HART_STACK_SIZE,
+ .platform_ops_addr = (unsigned long)&platform_ops
+};