瀏覽代碼

platform: Add Spike initial support

This patch adds initial platform support Spike emulator.

Signed-off-by: James Clarke <jrtc27@jrtc27.com>
Signed-off-by: Anup Patel <anup.patel@wdc.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Atish Patra <atish.patra@wdc.com>
James Clarke 4 年之前
父節點
當前提交
c2f23cc6ed
共有 6 個文件被更改,包括 327 次插入0 次删除
  1. 19 0
      include/sbi_utils/sys/htif.h
  2. 149 0
      lib/utils/sys/htif.c
  3. 1 0
      lib/utils/sys/objects.mk
  4. 36 0
      platform/spike/config.mk
  5. 7 0
      platform/spike/objects.mk
  6. 115 0
      platform/spike/platform.c

+ 19 - 0
include/sbi_utils/sys/htif.h

@@ -0,0 +1,19 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 2010-2020, The Regents of the University of California
+ * (Regents).  All Rights Reserved.
+ */
+
+#ifndef __SYS_HTIF_H__
+#define __SYS_HTIF_H__
+
+#include <sbi/sbi_types.h>
+
+void htif_putc(char ch);
+
+int htif_getc(void);
+
+int htif_system_down(u32 type);
+
+#endif

+ 149 - 0
lib/utils/sys/htif.c

@@ -0,0 +1,149 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 2010-2020, The Regents of the University of California
+ * (Regents).  All Rights Reserved.
+ */
+
+#include <sbi/riscv_locks.h>
+#include <sbi_utils/sys/htif.h>
+
+#define HTIF_DATA_BITS		48
+#define HTIF_DATA_MASK		((1UL << HTIF_DATA_BITS) - 1)
+#define HTIF_DATA_SHIFT		0
+#define HTIF_CMD_BITS		8
+#define HTIF_CMD_MASK		((1UL << HTIF_CMD_BITS) - 1)
+#define HTIF_CMD_SHIFT		48
+#define HTIF_DEV_BITS		8
+#define HTIF_DEV_MASK		((1UL << HTIF_DEV_BITS) - 1)
+#define HTIF_DEV_SHIFT		56
+
+#define HTIF_DEV_SYSTEM		0
+#define HTIF_DEV_CONSOLE	1
+
+#define HTIF_CONSOLE_CMD_GETC	0
+#define HTIF_CONSOLE_CMD_PUTC	1
+
+#if __riscv_xlen == 64
+# define TOHOST_CMD(dev, cmd, payload) \
+	(((uint64_t)(dev) << HTIF_DEV_SHIFT) | \
+	 ((uint64_t)(cmd) << HTIF_CMD_SHIFT) | \
+	 (uint64_t)(payload))
+#else
+# define TOHOST_CMD(dev, cmd, payload) ({ \
+  if ((dev) || (cmd)) __builtin_trap(); \
+  (payload); })
+#endif
+#define FROMHOST_DEV(fromhost_value) \
+	((uint64_t)((fromhost_value) >> HTIF_DEV_SHIFT) & HTIF_DEV_MASK)
+#define FROMHOST_CMD(fromhost_value) \
+	((uint64_t)((fromhost_value) >> HTIF_CMD_SHIFT) & HTIF_CMD_MASK)
+#define FROMHOST_DATA(fromhost_value) \
+	((uint64_t)((fromhost_value) >> HTIF_DATA_SHIFT) & HTIF_DATA_MASK)
+
+#define PK_SYS_write 64
+
+volatile uint64_t tohost __attribute__((section(".htif")));
+volatile uint64_t fromhost __attribute__((section(".htif")));
+static int htif_console_buf;
+static spinlock_t htif_lock = SPIN_LOCK_INITIALIZER;
+
+static void __check_fromhost()
+{
+	uint64_t fh = fromhost;
+	if (!fh)
+		return;
+	fromhost = 0;
+
+	/* this should be from the console */
+	if (FROMHOST_DEV(fh) != HTIF_DEV_CONSOLE)
+		__builtin_trap();
+	switch (FROMHOST_CMD(fh)) {
+		case HTIF_CONSOLE_CMD_GETC:
+			htif_console_buf = 1 + (uint8_t)FROMHOST_DATA(fh);
+			break;
+		case HTIF_CONSOLE_CMD_PUTC:
+			break;
+		default:
+			__builtin_trap();
+	}
+}
+
+static void __set_tohost(uint64_t dev, uint64_t cmd, uint64_t data)
+{
+	while (tohost)
+		__check_fromhost();
+	tohost = TOHOST_CMD(dev, cmd, data);
+}
+
+#if __riscv_xlen == 32
+static void do_tohost_fromhost(uint64_t dev, uint64_t cmd, uint64_t data)
+{
+	spin_lock(&htif_lock);
+
+	__set_tohost(HTIF_DEV_SYSTEM, cmd, data);
+
+	while (1) {
+		uint64_t fh = fromhost;
+		if (fh) {
+			if (FROMHOST_DEV(fh) == HTIF_DEV_SYSTEM &&
+			    FROMHOST_CMD(fh) == cmd) {
+				fromhost = 0;
+				break;
+			}
+			__check_fromhost();
+		}
+	}
+
+	spin_unlock(&htif_lock);
+}
+
+void htif_putc(char ch)
+{
+	/* HTIF devices are not supported on RV32, so do a proxy write call */
+	volatile uint64_t magic_mem[8];
+	magic_mem[0] = PK_SYS_write;
+	magic_mem[1] = HTIF_DEV_CONSOLE;
+	magic_mem[2] = (uint64_t)(uintptr_t)&ch;
+	magic_mem[3] = HTIF_CONSOLE_CMD_PUTC;
+	do_tohost_fromhost(HTIF_DEV_SYSTEM, 0, (uint64_t)(uintptr_t)magic_mem);
+}
+#else
+void htif_putc(char ch)
+{
+	spin_lock(&htif_lock);
+	__set_tohost(HTIF_DEV_CONSOLE, HTIF_CONSOLE_CMD_PUTC, ch);
+	spin_unlock(&htif_lock);
+}
+#endif
+
+int htif_getc(void)
+{
+	int ch;
+
+#if __riscv_xlen == 32
+	/* HTIF devices are not supported on RV32 */
+	return -1;
+#endif
+
+	spin_lock(&htif_lock);
+
+	__check_fromhost();
+	ch = htif_console_buf;
+	if (ch >= 0) {
+		htif_console_buf = -1;
+		__set_tohost(HTIF_DEV_CONSOLE, HTIF_CONSOLE_CMD_GETC, 0);
+	}
+
+	spin_unlock(&htif_lock);
+
+	return ch - 1;
+}
+
+int htif_system_down(u32 type)
+{
+	while (1) {
+		fromhost = 0;
+		tohost = 1;
+	}
+}

+ 1 - 0
lib/utils/sys/objects.mk

@@ -8,3 +8,4 @@
 #
 
 libsbiutils-objs-y += sys/clint.o
+libsbiutils-objs-y += sys/htif.o

+ 36 - 0
platform/spike/config.mk

@@ -0,0 +1,36 @@
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2020 Western Digital Corporation or its affiliates.
+#
+
+# Compiler flags
+platform-cppflags-y =
+platform-cflags-y =
+platform-asflags-y =
+platform-ldflags-y =
+
+# Command for platform specific "make run"
+platform-runcmd = spike \
+  $(build_dir)/platform/spike/firmware/fw_payload.elf
+
+# Blobs to build
+FW_TEXT_START=0x80000000
+FW_JUMP=y
+ifeq ($(PLATFORM_RISCV_XLEN), 32)
+  # This needs to be 4MB aligned for 32-bit system
+  FW_JUMP_ADDR=0x80400000
+else
+  # This needs to be 2MB aligned for 64-bit system
+  FW_JUMP_ADDR=0x80200000
+endif
+FW_JUMP_FDT_ADDR=0x82200000
+FW_PAYLOAD=y
+ifeq ($(PLATFORM_RISCV_XLEN), 32)
+  # This needs to be 4MB aligned for 32-bit system
+  FW_PAYLOAD_OFFSET=0x400000
+else
+  # This needs to be 2MB aligned for 64-bit system
+  FW_PAYLOAD_OFFSET=0x200000
+endif
+FW_PAYLOAD_FDT_ADDR=0x82200000

+ 7 - 0
platform/spike/objects.mk

@@ -0,0 +1,7 @@
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2020 Western Digital Corporation or its affiliates.
+#
+
+platform-objs-y += platform.o

+ 115 - 0
platform/spike/platform.c

@@ -0,0 +1,115 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2020 Western Digital Corporation or its affiliates.
+ */
+
+#include <sbi/sbi_platform.h>
+#include <sbi_utils/sys/htif.h>
+#include <sbi_utils/sys/clint.h>
+
+/* clang-format off */
+
+#define SPIKE_HART_COUNT			8
+#define SPIKE_HART_STACK_SIZE			8192
+
+#define SPIKE_CLINT_ADDR			0x2000000
+
+/* clang-format on */
+
+static int spike_final_init(bool cold_boot)
+{
+	return 0;
+}
+
+static u32 spike_pmp_region_count(u32 hartid)
+{
+	return 1;
+}
+
+static int spike_pmp_region_info(u32 hartid, u32 index, ulong *prot, ulong *addr,
+				ulong *log2size)
+{
+	int ret = 0;
+
+	switch (index) {
+	case 0:
+		*prot	  = PMP_R | PMP_W | PMP_X;
+		*addr	  = 0;
+		*log2size = __riscv_xlen;
+		break;
+	default:
+		ret = -1;
+		break;
+	};
+
+	return ret;
+}
+
+static int spike_console_init(void)
+{
+	return 0;
+}
+
+static int spike_irqchip_init(bool cold_boot)
+{
+	return 0;
+}
+
+static int spike_ipi_init(bool cold_boot)
+{
+	int ret;
+
+	if (cold_boot) {
+		ret = clint_cold_ipi_init(SPIKE_CLINT_ADDR,
+					  SPIKE_HART_COUNT);
+		if (ret)
+			return ret;
+	}
+
+	return clint_warm_ipi_init();
+}
+
+static int spike_timer_init(bool cold_boot)
+{
+	int rc;
+
+	if (cold_boot) {
+		rc = clint_cold_timer_init(SPIKE_CLINT_ADDR,
+					   SPIKE_HART_COUNT, TRUE);
+		if (rc)
+			return rc;
+	}
+
+	return clint_warm_timer_init();
+}
+
+const struct sbi_platform_operations platform_ops = {
+	.pmp_region_count	= spike_pmp_region_count,
+	.pmp_region_info	= spike_pmp_region_info,
+	.final_init		= spike_final_init,
+	.console_putc		= htif_putc,
+	.console_getc		= htif_getc,
+	.console_init		= spike_console_init,
+	.irqchip_init		= spike_irqchip_init,
+	.ipi_send		= clint_ipi_send,
+	.ipi_clear		= clint_ipi_clear,
+	.ipi_init		= spike_ipi_init,
+	.timer_value		= clint_timer_value,
+	.timer_event_stop	= clint_timer_event_stop,
+	.timer_event_start	= clint_timer_event_start,
+	.timer_init		= spike_timer_init,
+	.system_reboot		= htif_system_down,
+	.system_shutdown	= htif_system_down
+};
+
+const struct sbi_platform platform = {
+	.opensbi_version	= OPENSBI_VERSION,
+	.platform_version	= SBI_PLATFORM_VERSION(0x0, 0x01),
+	.name			= "Spike",
+	.features		= SBI_PLATFORM_DEFAULT_FEATURES,
+	.hart_count		= SPIKE_HART_COUNT,
+	.hart_stack_size	= SPIKE_HART_STACK_SIZE,
+	.disabled_hart_mask	= 0,
+	.platform_ops_addr	= (unsigned long)&platform_ops
+};