summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/platform/platform.md3
-rw-r--r--docs/platform/thead-c910.md34
-rw-r--r--platform/thead/c910/config.mk14
-rw-r--r--platform/thead/c910/objects.mk5
-rw-r--r--platform/thead/c910/platform.c159
-rw-r--r--platform/thead/c910/platform.h51
6 files changed, 266 insertions, 0 deletions
diff --git a/docs/platform/platform.md b/docs/platform/platform.md
index 424efe9..17cbfb8 100644
--- a/docs/platform/platform.md
+++ b/docs/platform/platform.md
@@ -26,6 +26,8 @@ OpenSBI currently supports the following virtual and hardware platforms:
* **Andes AE350 SoC**: Platform support for the Andes's SoC (AE350).
+* **T-HEAD C910**: Platform support for the T-HEAD C910 Processor.
+
The code for these supported platforms can be used as example to implement
support for other platforms. The *platform/template* directory also provides
template files for implementing support for a new platform. The *object.mk*,
@@ -37,3 +39,4 @@ facilitate the implementation.
[sifive_fu540.md]: sifive_fu540.md
[ariane-fpga.md]: ariane-fpga.md
[andes_ae350.md]: andes-ae350.md
+[thead-c910.md]: thead-c910.md
diff --git a/docs/platform/thead-c910.md b/docs/platform/thead-c910.md
new file mode 100644
index 0000000..3ba0b96
--- /dev/null
+++ b/docs/platform/thead-c910.md
@@ -0,0 +1,34 @@
+T-HEAD C910 Processor
+=====================
+C910 is a 12-stage, 3 issues, 8 executions, out-of-order 64-bit RISC-V CPU which
+supports 16 cores, runs with 2.5GHz, and is capable of running Linux.
+
+To build platform specific library and firmwares, provide the *PLATFORM=thead/c910*
+parameter to the top level make command.
+
+Platform Options
+----------------
+
+The *T-HEAD C910* platform does not have any platform-specific options.
+
+Building T-HEAD C910 Platform
+-----------------------------
+
+```
+make PLATFORM=thead/c910
+```
+
+Booting T-HEAD C910 Platform
+-----------------------------
+
+**No Payload**
+
+As there's no payload, you may download vmlinux or u-boot to FW_JUMP_ADDR which
+specified in config.mk or compile commands with GDB. And the execution flow will
+turn to vmlinux or u-boot when opensbi ends.
+
+**Linux Kernel Payload**
+
+You can also choose to use Linux kernel as payload by enabling FW_PAYLOAD=y
+along with specifying FW_PAYLOAD_OFFSET. The kernel image will be embedded in
+the OPENSBI firmware binary, T-head will directly boot into Linux after OpenSBI.
diff --git a/platform/thead/c910/config.mk b/platform/thead/c910/config.mk
new file mode 100644
index 0000000..bd5eab7
--- /dev/null
+++ b/platform/thead/c910/config.mk
@@ -0,0 +1,14 @@
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+# Compiler flags
+platform-cppflags-y =
+platform-cflags-y =
+platform-asflags-y =
+platform-ldflags-y =
+
+# Blobs to build
+FW_TEXT_START?=0x0
+FW_JUMP=y
+FW_JUMP_ADDR?=0x00200000
diff --git a/platform/thead/c910/objects.mk b/platform/thead/c910/objects.mk
new file mode 100644
index 0000000..d025a36
--- /dev/null
+++ b/platform/thead/c910/objects.mk
@@ -0,0 +1,5 @@
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+platform-objs-y += platform.o
diff --git a/platform/thead/c910/platform.c b/platform/thead/c910/platform.c
new file mode 100644
index 0000000..1ad3e49
--- /dev/null
+++ b/platform/thead/c910/platform.c
@@ -0,0 +1,159 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <sbi/riscv_encoding.h>
+#include <sbi/riscv_io.h>
+#include <sbi/sbi_const.h>
+#include <sbi/sbi_hart.h>
+#include <sbi/sbi_platform.h>
+#include <sbi/sbi_console.h>
+#include <sbi_utils/irqchip/plic.h>
+#include <sbi_utils/sys/clint.h>
+#include <sbi_utils/serial/uart8250.h>
+#include "platform.h"
+
+static struct c910_regs_struct c910_regs;
+
+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);
+ } 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_MCCR2, c910_regs.mccr2);
+ csr_write(CSR_MHINT, c910_regs.mhint);
+ csr_write(CSR_MXSTATUS, c910_regs.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;
+
+ 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) {
+ rc = clint_cold_ipi_init(c910_regs.clint_base_addr, C910_HART_COUNT);
+ if (rc)
+ return rc;
+ }
+
+ return clint_warm_ipi_init();
+}
+
+static int c910_timer_init(bool cold_boot)
+{
+ int ret;
+
+ if (cold_boot) {
+ ret = clint_cold_timer_init(c910_regs.clint_base_addr,
+ C910_HART_COUNT, FALSE);
+ if (ret)
+ return ret;
+ }
+
+ return clint_warm_timer_init();
+}
+
+static int c910_system_shutdown(u32 type)
+{
+ asm volatile ("ebreak");
+ return 0;
+}
+
+void sbi_boot_other_core(int hartid)
+{
+ csr_write(CSR_MRVBR, FW_TEXT_START);
+ csr_write(CSR_MRMR, csr_read(CSR_MRMR) | (1 << hartid));
+}
+
+static int c910_vendor_ext_provider(long extid, long funcid,
+ unsigned long *args,
+ unsigned long *out_value,
+ struct sbi_trap_info *out_trap)
+{
+ switch (extid) {
+ case SBI_EXT_VENDOR_C910_BOOT_OTHER_CORE:
+ sbi_boot_other_core((int)args[0]);
+ break;
+ default:
+ sbi_printf("Unsupported private sbi call: %ld\n", extid);
+ asm volatile ("ebreak");
+ }
+ 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_shutdown = c910_system_shutdown,
+
+ .vendor_ext_provider = c910_vendor_ext_provider,
+};
+
+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 = C910_HART_STACK_SIZE,
+ .disabled_hart_mask = 0,
+ .platform_ops_addr = (unsigned long)&platform_ops
+};
diff --git a/platform/thead/c910/platform.h b/platform/thead/c910/platform.h
new file mode 100644
index 0000000..bc176e5
--- /dev/null
+++ b/platform/thead/c910/platform.h
@@ -0,0 +1,51 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#ifndef _C910_PLATFORM_H_
+#define _C910_PLATFORM_H_
+
+#define C910_HART_COUNT 16
+#define C910_HART_STACK_SIZE 8192
+
+#define SBI_THEAD_FEATURES \
+ (SBI_PLATFORM_HAS_PMP | \
+ SBI_PLATFORM_HAS_SCOUNTEREN | \
+ SBI_PLATFORM_HAS_MCOUNTEREN | \
+ SBI_PLATFORM_HAS_MFAULTS_DELEGATION)
+
+#define CSR_MCOR 0x7c2
+#define CSR_MHCR 0x7c1
+#define CSR_MCCR2 0x7c3
+#define CSR_MHINT 0x7c5
+#define CSR_MXSTATUS 0x7c0
+#define CSR_PLIC_BASE 0xfc1
+#define CSR_MRMR 0x7c6
+#define CSR_MRVBR 0x7c7
+
+#define SBI_EXT_VENDOR_C910_BOOT_OTHER_CORE 0x09000003
+
+#define C910_PLIC_CLINT_OFFSET 0x04000000 /* 64M */
+#define C910_PLIC_DELEG_OFFSET 0x001ffffc
+#define C910_PLIC_DELEG_ENABLE 0x1
+
+struct c910_regs_struct {
+ u64 pmpaddr0;
+ u64 pmpaddr1;
+ u64 pmpaddr2;
+ u64 pmpaddr3;
+ u64 pmpaddr4;
+ u64 pmpaddr5;
+ u64 pmpaddr6;
+ u64 pmpaddr7;
+ u64 pmpcfg0;
+ u64 mcor;
+ u64 mhcr;
+ u64 mccr2;
+ u64 mhint;
+ u64 mxstatus;
+ u64 plic_base_addr;
+ u64 clint_base_addr;
+};
+
+#endif /* _C910_PLATFORM_H_ */