summaryrefslogtreecommitdiff
path: root/lib/utils
diff options
context:
space:
mode:
authorAnup Patel <apatel@ventanamicro.com>2022-01-06 06:46:55 +0300
committerAnup Patel <anup@brainfault.org>2022-01-11 15:47:49 +0300
commit6dde43584f185f71a8dd713deb438d7c724a9ad5 (patch)
tree46a01fc502ec87a7210f81bf8a000e08f73e67a8 /lib/utils
parent5b9960379fae14b554c953b0d4139f4b1a57cd5e (diff)
downloadopensbi-6dde43584f185f71a8dd713deb438d7c724a9ad5.tar.xz
lib: utils/sys: Extend HTIF library to allow custom base addressSDK_v2.0.0
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>
Diffstat (limited to 'lib/utils')
-rw-r--r--lib/utils/reset/fdt_reset_htif.c12
-rw-r--r--lib/utils/serial/fdt_serial_htif.c12
-rw-r--r--lib/utils/sys/htif.c85
3 files changed, 97 insertions, 12 deletions
diff --git a/lib/utils/reset/fdt_reset_htif.c b/lib/utils/reset/fdt_reset_htif.c
index dd08660..2cc52dd 100644
--- a/lib/utils/reset/fdt_reset_htif.c
+++ b/lib/utils/reset/fdt_reset_htif.c
@@ -14,7 +14,17 @@
static int htif_reset_init(void *fdt, int nodeoff,
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[] = {
diff --git a/lib/utils/serial/fdt_serial_htif.c b/lib/utils/serial/fdt_serial_htif.c
index fae55b8..61f66d6 100644
--- a/lib/utils/serial/fdt_serial_htif.c
+++ b/lib/utils/serial/fdt_serial_htif.c
@@ -19,7 +19,17 @@ static const struct fdt_match serial_htif_match[] = {
static int serial_htif_init(void *fdt, int nodeoff,
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 = {
diff --git a/lib/utils/sys/htif.c b/lib/utils/sys/htif.c
index 7c69c7f..d7cbeaf 100644
--- a/lib/utils/sys/htif.c
+++ b/lib/utils/sys/htif.c
@@ -7,6 +7,7 @@
#include <sbi/riscv_locks.h>
#include <sbi/sbi_console.h>
+#include <sbi/sbi_error.h>
#include <sbi/sbi_system.h>
#include <sbi_utils/sys/htif.h>
@@ -47,15 +48,46 @@
volatile uint64_t tohost __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 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()
{
- uint64_t fh = fromhost;
+ uint64_t fh = __read_fromhost();
if (!fh)
return;
- fromhost = 0;
+ __write_fromhost(0);
/* this should be from the 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)
{
- while (tohost)
+ while (__read_tohost())
__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
@@ -148,10 +197,18 @@ static struct sbi_console_device htif_console = {
.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;
}
@@ -163,8 +220,8 @@ static int htif_system_reset_check(u32 type, u32 reason)
static void htif_system_reset(u32 type, u32 reason)
{
while (1) {
- fromhost = 0;
- tohost = 1;
+ __write_fromhost(0);
+ __write_tohost(1);
}
}
@@ -174,9 +231,17 @@ static struct sbi_system_reset_device htif_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;
}