forked from Mirrors/opensbi
		
	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>
This commit is contained in:
		
							
								
								
									
										19
									
								
								include/sbi_utils/sys/htif.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								include/sbi_utils/sys/htif.h
									
									
									
									
									
										Normal file
									
								
							@@ -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
									
								
								lib/utils/sys/htif.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								lib/utils/sys/htif.c
									
									
									
									
									
										Normal file
									
								
							@@ -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;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -8,3 +8,4 @@
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
libsbiutils-objs-y += sys/clint.o
 | 
			
		||||
libsbiutils-objs-y += sys/htif.o
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										36
									
								
								platform/spike/config.mk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								platform/spike/config.mk
									
									
									
									
									
										Normal file
									
								
							@@ -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
									
								
								platform/spike/objects.mk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								platform/spike/objects.mk
									
									
									
									
									
										Normal file
									
								
							@@ -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
									
								
								platform/spike/platform.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								platform/spike/platform.c
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
};
 | 
			
		||||
		Reference in New Issue
	
	Block a user