platform: Add Spike initial support
authorJames Clarke <jrtc27@jrtc27.com>
Sat, 1 Feb 2020 01:07:51 +0000 (01:07 +0000)
committerAnup Patel <anup@brainfault.org>
Mon, 17 Feb 2020 12:12:52 +0000 (17:42 +0530)
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>
include/sbi_utils/sys/htif.h [new file with mode: 0644]
lib/utils/sys/htif.c [new file with mode: 0644]
lib/utils/sys/objects.mk
platform/spike/config.mk [new file with mode: 0644]
platform/spike/objects.mk [new file with mode: 0644]
platform/spike/platform.c [new file with mode: 0644]

diff --git a/include/sbi_utils/sys/htif.h b/include/sbi_utils/sys/htif.h
new file mode 100644 (file)
index 0000000..42903e8
--- /dev/null
@@ -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
diff --git a/lib/utils/sys/htif.c b/lib/utils/sys/htif.c
new file mode 100644 (file)
index 0000000..f0ba814
--- /dev/null
@@ -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;
+       }
+}
index baed884..c6df2bd 100644 (file)
@@ -8,3 +8,4 @@
 #
 
 libsbiutils-objs-y += sys/clint.o
+libsbiutils-objs-y += sys/htif.o
diff --git a/platform/spike/config.mk b/platform/spike/config.mk
new file mode 100644 (file)
index 0000000..4bde3fd
--- /dev/null
@@ -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
diff --git a/platform/spike/objects.mk b/platform/spike/objects.mk
new file mode 100644 (file)
index 0000000..30a3c4f
--- /dev/null
@@ -0,0 +1,7 @@
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2020 Western Digital Corporation or its affiliates.
+#
+
+platform-objs-y += platform.o
diff --git a/platform/spike/platform.c b/platform/spike/platform.c
new file mode 100644 (file)
index 0000000..c0f93e2
--- /dev/null
@@ -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
+};