mirror of
https://github.com/Fishwaldo/opensbi.git
synced 2025-07-03 11:38:22 +00:00
lib: utils/sys: Extend HTIF library to allow custom base address
Some of RISC-V emulators provide HTIF at fixed base address so for such emulators users have to hard-code HTIF base address in the linker script. To address this problem, we let users optionally provide fixed HTIF base address via platform support (or device tree). Signed-off-by: Anup Patel <apatel@ventanamicro.com> Reviewed-by: Dong Du <Dd_nirvana@sjtu.edu.cn> Reviewed-by: Atish Patra <atishp@rivosinc.com>
This commit is contained in:
parent
5b9960379f
commit
6dde43584f
4 changed files with 103 additions and 14 deletions
|
@ -10,8 +10,12 @@
|
||||||
|
|
||||||
#include <sbi/sbi_types.h>
|
#include <sbi/sbi_types.h>
|
||||||
|
|
||||||
int htif_serial_init(void);
|
int htif_serial_init(bool custom_addr,
|
||||||
|
unsigned long custom_fromhost_addr,
|
||||||
|
unsigned long custom_tohost_addr);
|
||||||
|
|
||||||
int htif_system_reset_init(void);
|
int htif_system_reset_init(bool custom_addr,
|
||||||
|
unsigned long custom_fromhost_addr,
|
||||||
|
unsigned long custom_tohost_addr);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -14,7 +14,17 @@
|
||||||
static int htif_reset_init(void *fdt, int nodeoff,
|
static int htif_reset_init(void *fdt, int nodeoff,
|
||||||
const struct fdt_match *match)
|
const struct fdt_match *match)
|
||||||
{
|
{
|
||||||
return htif_system_reset_init();
|
bool custom = false;
|
||||||
|
uint64_t fromhost_addr = 0, tohost_addr = 0;
|
||||||
|
|
||||||
|
if (!fdt_get_node_addr_size(fdt, nodeoff, 0, &fromhost_addr, NULL)) {
|
||||||
|
custom = true;
|
||||||
|
tohost_addr = fromhost_addr + sizeof(uint64_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
fdt_get_node_addr_size(fdt, nodeoff, 1, &tohost_addr, NULL);
|
||||||
|
|
||||||
|
return htif_system_reset_init(custom, fromhost_addr, tohost_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct fdt_match htif_reset_match[] = {
|
static const struct fdt_match htif_reset_match[] = {
|
||||||
|
|
|
@ -19,7 +19,17 @@ static const struct fdt_match serial_htif_match[] = {
|
||||||
static int serial_htif_init(void *fdt, int nodeoff,
|
static int serial_htif_init(void *fdt, int nodeoff,
|
||||||
const struct fdt_match *match)
|
const struct fdt_match *match)
|
||||||
{
|
{
|
||||||
return htif_serial_init();
|
bool custom = false;
|
||||||
|
uint64_t fromhost_addr = 0, tohost_addr = 0;
|
||||||
|
|
||||||
|
if (!fdt_get_node_addr_size(fdt, nodeoff, 0, &fromhost_addr, NULL)) {
|
||||||
|
custom = true;
|
||||||
|
tohost_addr = fromhost_addr + sizeof(uint64_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
fdt_get_node_addr_size(fdt, nodeoff, 1, &tohost_addr, NULL);
|
||||||
|
|
||||||
|
return htif_serial_init(custom, fromhost_addr, tohost_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct fdt_serial fdt_serial_htif = {
|
struct fdt_serial fdt_serial_htif = {
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include <sbi/riscv_locks.h>
|
#include <sbi/riscv_locks.h>
|
||||||
#include <sbi/sbi_console.h>
|
#include <sbi/sbi_console.h>
|
||||||
|
#include <sbi/sbi_error.h>
|
||||||
#include <sbi/sbi_system.h>
|
#include <sbi/sbi_system.h>
|
||||||
#include <sbi_utils/sys/htif.h>
|
#include <sbi_utils/sys/htif.h>
|
||||||
|
|
||||||
|
@ -47,15 +48,46 @@
|
||||||
|
|
||||||
volatile uint64_t tohost __attribute__((section(".htif")));
|
volatile uint64_t tohost __attribute__((section(".htif")));
|
||||||
volatile uint64_t fromhost __attribute__((section(".htif")));
|
volatile uint64_t fromhost __attribute__((section(".htif")));
|
||||||
|
|
||||||
|
static uint64_t *htif_fromhost = NULL;
|
||||||
|
static uint64_t *htif_tohost = NULL;
|
||||||
|
static bool htif_custom = false;
|
||||||
|
|
||||||
static int htif_console_buf;
|
static int htif_console_buf;
|
||||||
static spinlock_t htif_lock = SPIN_LOCK_INITIALIZER;
|
static spinlock_t htif_lock = SPIN_LOCK_INITIALIZER;
|
||||||
|
|
||||||
|
static inline uint64_t __read_tohost(void)
|
||||||
|
{
|
||||||
|
return (htif_custom) ? *htif_tohost : tohost;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void __write_tohost(uint64_t val)
|
||||||
|
{
|
||||||
|
if (htif_custom)
|
||||||
|
*htif_tohost = val;
|
||||||
|
else
|
||||||
|
tohost = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint64_t __read_fromhost(void)
|
||||||
|
{
|
||||||
|
return (htif_custom) ? *htif_fromhost : fromhost;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void __write_fromhost(uint64_t val)
|
||||||
|
{
|
||||||
|
if (htif_custom)
|
||||||
|
*htif_fromhost = val;
|
||||||
|
else
|
||||||
|
fromhost = val;
|
||||||
|
}
|
||||||
|
|
||||||
static void __check_fromhost()
|
static void __check_fromhost()
|
||||||
{
|
{
|
||||||
uint64_t fh = fromhost;
|
uint64_t fh = __read_fromhost();
|
||||||
if (!fh)
|
if (!fh)
|
||||||
return;
|
return;
|
||||||
fromhost = 0;
|
__write_fromhost(0);
|
||||||
|
|
||||||
/* this should be from the console */
|
/* this should be from the console */
|
||||||
if (FROMHOST_DEV(fh) != HTIF_DEV_CONSOLE)
|
if (FROMHOST_DEV(fh) != HTIF_DEV_CONSOLE)
|
||||||
|
@ -73,9 +105,26 @@ static void __check_fromhost()
|
||||||
|
|
||||||
static void __set_tohost(uint64_t dev, uint64_t cmd, uint64_t data)
|
static void __set_tohost(uint64_t dev, uint64_t cmd, uint64_t data)
|
||||||
{
|
{
|
||||||
while (tohost)
|
while (__read_tohost())
|
||||||
__check_fromhost();
|
__check_fromhost();
|
||||||
tohost = TOHOST_CMD(dev, cmd, data);
|
__write_tohost(TOHOST_CMD(dev, cmd, data));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int set_custom_addr(bool custom_addr,
|
||||||
|
unsigned long custom_fromhost_addr,
|
||||||
|
unsigned long custom_tohost_addr)
|
||||||
|
{
|
||||||
|
if (custom_addr) {
|
||||||
|
if (htif_custom &&
|
||||||
|
((custom_fromhost_addr != (unsigned long)htif_fromhost) ||
|
||||||
|
(custom_tohost_addr != (unsigned long)htif_tohost)))
|
||||||
|
return SBI_EINVAL;
|
||||||
|
htif_fromhost = (uint64_t *)custom_fromhost_addr;
|
||||||
|
htif_tohost = (uint64_t *)custom_tohost_addr;
|
||||||
|
htif_custom = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if __riscv_xlen == 32
|
#if __riscv_xlen == 32
|
||||||
|
@ -148,10 +197,18 @@ static struct sbi_console_device htif_console = {
|
||||||
.console_getc = htif_getc
|
.console_getc = htif_getc
|
||||||
};
|
};
|
||||||
|
|
||||||
int htif_serial_init(void)
|
int htif_serial_init(bool custom_addr,
|
||||||
|
unsigned long custom_fromhost_addr,
|
||||||
|
unsigned long custom_tohost_addr)
|
||||||
{
|
{
|
||||||
sbi_console_set_device(&htif_console);
|
int rc;
|
||||||
|
|
||||||
|
rc = set_custom_addr(custom_addr, custom_fromhost_addr,
|
||||||
|
custom_tohost_addr);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
sbi_console_set_device(&htif_console);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,8 +220,8 @@ static int htif_system_reset_check(u32 type, u32 reason)
|
||||||
static void htif_system_reset(u32 type, u32 reason)
|
static void htif_system_reset(u32 type, u32 reason)
|
||||||
{
|
{
|
||||||
while (1) {
|
while (1) {
|
||||||
fromhost = 0;
|
__write_fromhost(0);
|
||||||
tohost = 1;
|
__write_tohost(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,9 +231,17 @@ static struct sbi_system_reset_device htif_reset = {
|
||||||
.system_reset = htif_system_reset
|
.system_reset = htif_system_reset
|
||||||
};
|
};
|
||||||
|
|
||||||
int htif_system_reset_init(void)
|
int htif_system_reset_init(bool custom_addr,
|
||||||
|
unsigned long custom_fromhost_addr,
|
||||||
|
unsigned long custom_tohost_addr)
|
||||||
{
|
{
|
||||||
sbi_system_reset_add_device(&htif_reset);
|
int rc;
|
||||||
|
|
||||||
|
rc = set_custom_addr(custom_addr, custom_fromhost_addr,
|
||||||
|
custom_tohost_addr);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
sbi_system_reset_add_device(&htif_reset);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue