platform: Add T-head C910 initial support

This commit provides basic support for the Thead/C910 platform.

Signed-off-by: Liu Yibin <yibin_liu@c-sky.com>
Reviewed-by: Atish Patra <atish.patra@wdc.com>
Reviewed-by: Anup Patel <anup.patel@wdc.com>
This commit is contained in:
Liu Yibin
2020-01-02 12:21:36 +08:00
committed by Anup Patel
parent 46a90d90e7
commit c0849cd731
6 changed files with 266 additions and 0 deletions

View File

@@ -26,6 +26,8 @@ OpenSBI currently supports the following virtual and hardware platforms:
* **Andes AE350 SoC**: Platform support for the Andes's SoC (AE350). * **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 The code for these supported platforms can be used as example to implement
support for other platforms. The *platform/template* directory also provides support for other platforms. The *platform/template* directory also provides
template files for implementing support for a new platform. The *object.mk*, 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 [sifive_fu540.md]: sifive_fu540.md
[ariane-fpga.md]: ariane-fpga.md [ariane-fpga.md]: ariane-fpga.md
[andes_ae350.md]: andes-ae350.md [andes_ae350.md]: andes-ae350.md
[thead-c910.md]: thead-c910.md

View File

@@ -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.

View File

@@ -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

View File

@@ -0,0 +1,5 @@
#
# SPDX-License-Identifier: BSD-2-Clause
#
platform-objs-y += platform.o

View File

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

View File

@@ -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_ */