aboutsummaryrefslogtreecommitdiffstats
path: root/roms/opensbi/include/sbi
diff options
context:
space:
mode:
Diffstat (limited to 'roms/opensbi/include/sbi')
-rw-r--r--roms/opensbi/include/sbi/fw_dynamic.h79
-rw-r--r--roms/opensbi/include/sbi/riscv_asm.h187
-rw-r--r--roms/opensbi/include/sbi/riscv_atomic.h70
-rw-r--r--roms/opensbi/include/sbi/riscv_barrier.h57
-rw-r--r--roms/opensbi/include/sbi/riscv_encoding.h699
-rw-r--r--roms/opensbi/include/sbi/riscv_fp.h94
-rw-r--r--roms/opensbi/include/sbi/riscv_io.h114
-rw-r--r--roms/opensbi/include/sbi/riscv_locks.h34
-rw-r--r--roms/opensbi/include/sbi/sbi_bitmap.h128
-rw-r--r--roms/opensbi/include/sbi/sbi_bitops.h320
-rw-r--r--roms/opensbi/include/sbi/sbi_console.h39
-rw-r--r--roms/opensbi/include/sbi/sbi_const.h48
-rw-r--r--roms/opensbi/include/sbi/sbi_csr_detect.h50
-rw-r--r--roms/opensbi/include/sbi/sbi_domain.h165
-rw-r--r--roms/opensbi/include/sbi/sbi_ecall.h61
-rw-r--r--roms/opensbi/include/sbi/sbi_ecall_interface.h98
-rw-r--r--roms/opensbi/include/sbi/sbi_emulate_csr.h23
-rw-r--r--roms/opensbi/include/sbi/sbi_error.h38
-rw-r--r--roms/opensbi/include/sbi/sbi_fifo.h42
-rw-r--r--roms/opensbi/include/sbi/sbi_hart.h56
-rw-r--r--roms/opensbi/include/sbi/sbi_hartmask.h141
-rw-r--r--roms/opensbi/include/sbi/sbi_hfence.h38
-rw-r--r--roms/opensbi/include/sbi/sbi_hsm.h38
-rw-r--r--roms/opensbi/include/sbi/sbi_illegal_insn.h19
-rw-r--r--roms/opensbi/include/sbi/sbi_init.h23
-rw-r--r--roms/opensbi/include/sbi/sbi_ipi.h70
-rw-r--r--roms/opensbi/include/sbi/sbi_list.h152
-rw-r--r--roms/opensbi/include/sbi/sbi_math.h15
-rw-r--r--roms/opensbi/include/sbi/sbi_misaligned_ldst.h23
-rw-r--r--roms/opensbi/include/sbi/sbi_platform.h757
-rw-r--r--roms/opensbi/include/sbi/sbi_scratch.h128
-rw-r--r--roms/opensbi/include/sbi/sbi_string.h46
-rw-r--r--roms/opensbi/include/sbi/sbi_system.h19
-rw-r--r--roms/opensbi/include/sbi/sbi_timer.h44
-rw-r--r--roms/opensbi/include/sbi/sbi_tlb.h60
-rw-r--r--roms/opensbi/include/sbi/sbi_trap.h214
-rw-r--r--roms/opensbi/include/sbi/sbi_types.h109
-rw-r--r--roms/opensbi/include/sbi/sbi_unpriv.h41
-rw-r--r--roms/opensbi/include/sbi/sbi_version.h24
39 files changed, 4363 insertions, 0 deletions
diff --git a/roms/opensbi/include/sbi/fw_dynamic.h b/roms/opensbi/include/sbi/fw_dynamic.h
new file mode 100644
index 000000000..3c088311f
--- /dev/null
+++ b/roms/opensbi/include/sbi/fw_dynamic.h
@@ -0,0 +1,79 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#ifndef __FW_DYNAMIC_H__
+#define __FW_DYNAMIC_H__
+
+#include <sbi/riscv_asm.h>
+
+/* clang-format off */
+
+/** Offset of magic member in fw_dynamic_info */
+#define FW_DYNAMIC_INFO_MAGIC_OFFSET (0 * __SIZEOF_POINTER__)
+/** Offset of version member in fw_dynamic_info */
+#define FW_DYNAMIC_INFO_VERSION_OFFSET (1 * __SIZEOF_POINTER__)
+/** Offset of next_addr member in fw_dynamic_info (version >= 1) */
+#define FW_DYNAMIC_INFO_NEXT_ADDR_OFFSET (2 * __SIZEOF_POINTER__)
+/** Offset of next_mode member in fw_dynamic_info (version >= 1) */
+#define FW_DYNAMIC_INFO_NEXT_MODE_OFFSET (3 * __SIZEOF_POINTER__)
+/** Offset of options member in fw_dynamic_info (version >= 1) */
+#define FW_DYNAMIC_INFO_OPTIONS_OFFSET (4 * __SIZEOF_POINTER__)
+/** Offset of boot_hart member in fw_dynamic_info (version >= 2) */
+#define FW_DYNAMIC_INFO_BOOT_HART_OFFSET (5 * __SIZEOF_POINTER__)
+
+/** Expected value of info magic ('OSBI' ascii string in hex) */
+#define FW_DYNAMIC_INFO_MAGIC_VALUE 0x4942534f
+
+/** Maximum supported info version */
+#define FW_DYNAMIC_INFO_VERSION_MAX 0x2
+
+/** Possible next mode values */
+#define FW_DYNAMIC_INFO_NEXT_MODE_U 0x0
+#define FW_DYNAMIC_INFO_NEXT_MODE_S 0x1
+#define FW_DYNAMIC_INFO_NEXT_MODE_M 0x3
+
+/* clang-format on */
+
+#ifndef __ASSEMBLY__
+
+#include <sbi/sbi_types.h>
+
+/** Representation dynamic info passed by previous booting stage */
+struct fw_dynamic_info {
+ /** Info magic */
+ unsigned long magic;
+ /** Info version */
+ unsigned long version;
+ /** Next booting stage address */
+ unsigned long next_addr;
+ /** Next booting stage mode */
+ unsigned long next_mode;
+ /** Options for OpenSBI library */
+ unsigned long options;
+ /**
+ * Preferred boot HART id
+ *
+ * It is possible that the previous booting stage uses same link
+ * address as the FW_DYNAMIC firmware. In this case, the relocation
+ * lottery mechanism can potentially overwrite the previous booting
+ * stage while other HARTs are still running in the previous booting
+ * stage leading to boot-time crash. To avoid this boot-time crash,
+ * the previous booting stage can specify last HART that will jump
+ * to the FW_DYNAMIC firmware as the preferred boot HART.
+ *
+ * To avoid specifying a preferred boot HART, the previous booting
+ * stage can set it to -1UL which will force the FW_DYNAMIC firmware
+ * to use the relocation lottery mechanism.
+ */
+ unsigned long boot_hart;
+} __packed;
+
+#endif
+
+#endif
diff --git a/roms/opensbi/include/sbi/riscv_asm.h b/roms/opensbi/include/sbi/riscv_asm.h
new file mode 100644
index 000000000..10f31a7fc
--- /dev/null
+++ b/roms/opensbi/include/sbi/riscv_asm.h
@@ -0,0 +1,187 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#ifndef __RISCV_ASM_H__
+#define __RISCV_ASM_H__
+
+#include <sbi/riscv_encoding.h>
+
+/* clang-format off */
+
+#ifdef __ASSEMBLY__
+#define __ASM_STR(x) x
+#else
+#define __ASM_STR(x) #x
+#endif
+
+#if __riscv_xlen == 64
+#define __REG_SEL(a, b) __ASM_STR(a)
+#elif __riscv_xlen == 32
+#define __REG_SEL(a, b) __ASM_STR(b)
+#else
+#error "Unexpected __riscv_xlen"
+#endif
+
+#define PAGE_SHIFT (12)
+#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
+#define PAGE_MASK (~(PAGE_SIZE - 1))
+
+#define REG_L __REG_SEL(ld, lw)
+#define REG_S __REG_SEL(sd, sw)
+#define SZREG __REG_SEL(8, 4)
+#define LGREG __REG_SEL(3, 2)
+
+#if __SIZEOF_POINTER__ == 8
+#ifdef __ASSEMBLY__
+#define RISCV_PTR .dword
+#define RISCV_SZPTR 8
+#define RISCV_LGPTR 3
+#else
+#define RISCV_PTR ".dword"
+#define RISCV_SZPTR "8"
+#define RISCV_LGPTR "3"
+#endif
+#elif __SIZEOF_POINTER__ == 4
+#ifdef __ASSEMBLY__
+#define RISCV_PTR .word
+#define RISCV_SZPTR 4
+#define RISCV_LGPTR 2
+#else
+#define RISCV_PTR ".word"
+#define RISCV_SZPTR "4"
+#define RISCV_LGPTR "2"
+#endif
+#else
+#error "Unexpected __SIZEOF_POINTER__"
+#endif
+
+#if (__SIZEOF_INT__ == 4)
+#define RISCV_INT __ASM_STR(.word)
+#define RISCV_SZINT __ASM_STR(4)
+#define RISCV_LGINT __ASM_STR(2)
+#else
+#error "Unexpected __SIZEOF_INT__"
+#endif
+
+#if (__SIZEOF_SHORT__ == 2)
+#define RISCV_SHORT __ASM_STR(.half)
+#define RISCV_SZSHORT __ASM_STR(2)
+#define RISCV_LGSHORT __ASM_STR(1)
+#else
+#error "Unexpected __SIZEOF_SHORT__"
+#endif
+
+/* clang-format on */
+
+#ifndef __ASSEMBLY__
+
+#define csr_swap(csr, val) \
+ ({ \
+ unsigned long __v = (unsigned long)(val); \
+ __asm__ __volatile__("csrrw %0, " __ASM_STR(csr) ", %1" \
+ : "=r"(__v) \
+ : "rK"(__v) \
+ : "memory"); \
+ __v; \
+ })
+
+#define csr_read(csr) \
+ ({ \
+ register unsigned long __v; \
+ __asm__ __volatile__("csrr %0, " __ASM_STR(csr) \
+ : "=r"(__v) \
+ : \
+ : "memory"); \
+ __v; \
+ })
+
+#define csr_write(csr, val) \
+ ({ \
+ unsigned long __v = (unsigned long)(val); \
+ __asm__ __volatile__("csrw " __ASM_STR(csr) ", %0" \
+ : \
+ : "rK"(__v) \
+ : "memory"); \
+ })
+
+#define csr_read_set(csr, val) \
+ ({ \
+ unsigned long __v = (unsigned long)(val); \
+ __asm__ __volatile__("csrrs %0, " __ASM_STR(csr) ", %1" \
+ : "=r"(__v) \
+ : "rK"(__v) \
+ : "memory"); \
+ __v; \
+ })
+
+#define csr_set(csr, val) \
+ ({ \
+ unsigned long __v = (unsigned long)(val); \
+ __asm__ __volatile__("csrs " __ASM_STR(csr) ", %0" \
+ : \
+ : "rK"(__v) \
+ : "memory"); \
+ })
+
+#define csr_read_clear(csr, val) \
+ ({ \
+ unsigned long __v = (unsigned long)(val); \
+ __asm__ __volatile__("csrrc %0, " __ASM_STR(csr) ", %1" \
+ : "=r"(__v) \
+ : "rK"(__v) \
+ : "memory"); \
+ __v; \
+ })
+
+#define csr_clear(csr, val) \
+ ({ \
+ unsigned long __v = (unsigned long)(val); \
+ __asm__ __volatile__("csrc " __ASM_STR(csr) ", %0" \
+ : \
+ : "rK"(__v) \
+ : "memory"); \
+ })
+
+unsigned long csr_read_num(int csr_num);
+
+void csr_write_num(int csr_num, unsigned long val);
+
+#define wfi() \
+ do { \
+ __asm__ __volatile__("wfi" ::: "memory"); \
+ } while (0)
+
+/* Get current HART id */
+#define current_hartid() ((unsigned int)csr_read(CSR_MHARTID))
+
+/* determine CPU extension, return non-zero support */
+int misa_extension_imp(char ext);
+
+#define misa_extension(c)\
+({\
+ _Static_assert(((c >= 'A') && (c <= 'Z')),\
+ "The parameter of misa_extension must be [A-Z]");\
+ misa_extension_imp(c);\
+})
+
+/* Get MXL field of misa, return -1 on error */
+int misa_xlen(void);
+
+/* Get RISC-V ISA string representation */
+void misa_string(int xlen, char *out, unsigned int out_sz);
+
+int pmp_set(unsigned int n, unsigned long prot, unsigned long addr,
+ unsigned long log2len);
+
+int pmp_get(unsigned int n, unsigned long *prot_out, unsigned long *addr_out,
+ unsigned long *log2len);
+
+#endif /* !__ASSEMBLY__ */
+
+#endif
diff --git a/roms/opensbi/include/sbi/riscv_atomic.h b/roms/opensbi/include/sbi/riscv_atomic.h
new file mode 100644
index 000000000..3972e0b72
--- /dev/null
+++ b/roms/opensbi/include/sbi/riscv_atomic.h
@@ -0,0 +1,70 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#ifndef __RISCV_ATOMIC_H__
+#define __RISCV_ATOMIC_H__
+
+typedef struct {
+ volatile long counter;
+} atomic_t;
+
+#define ATOMIC_INIT(_lptr, val) (_lptr)->counter = (val)
+
+#define ATOMIC_INITIALIZER(val) \
+ { \
+ .counter = (val), \
+ }
+
+long atomic_read(atomic_t *atom);
+
+void atomic_write(atomic_t *atom, long value);
+
+long atomic_add_return(atomic_t *atom, long value);
+
+long atomic_sub_return(atomic_t *atom, long value);
+
+long atomic_cmpxchg(atomic_t *atom, long oldval, long newval);
+
+long atomic_xchg(atomic_t *atom, long newval);
+
+unsigned int atomic_raw_xchg_uint(volatile unsigned int *ptr,
+ unsigned int newval);
+
+unsigned long atomic_raw_xchg_ulong(volatile unsigned long *ptr,
+ unsigned long newval);
+/**
+ * Set a bit in an atomic variable and return the new value.
+ * @nr : Bit to set.
+ * @atom: atomic variable to modify
+ */
+int atomic_set_bit(int nr, atomic_t *atom);
+
+/**
+ * Clear a bit in an atomic variable and return the new value.
+ * @nr : Bit to set.
+ * @atom: atomic variable to modify
+ */
+
+int atomic_clear_bit(int nr, atomic_t *atom);
+
+/**
+ * Set a bit in any address and return the new value .
+ * @nr : Bit to set.
+ * @addr: Address to modify
+ */
+int atomic_raw_set_bit(int nr, volatile unsigned long *addr);
+
+/**
+ * Clear a bit in any address and return the new value .
+ * @nr : Bit to set.
+ * @addr: Address to modify
+ */
+int atomic_raw_clear_bit(int nr, volatile unsigned long *addr);
+
+#endif
diff --git a/roms/opensbi/include/sbi/riscv_barrier.h b/roms/opensbi/include/sbi/riscv_barrier.h
new file mode 100644
index 000000000..905ecb40f
--- /dev/null
+++ b/roms/opensbi/include/sbi/riscv_barrier.h
@@ -0,0 +1,57 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#ifndef __RISCV_BARRIER_H__
+#define __RISCV_BARRIER_H__
+
+/* clang-format off */
+
+#define RISCV_ACQUIRE_BARRIER "\tfence r , rw\n"
+#define RISCV_RELEASE_BARRIER "\tfence rw, w\n"
+
+#define RISCV_FENCE(p, s) \
+ __asm__ __volatile__ ("fence " #p "," #s : : : "memory")
+
+/* Read & Write Memory barrier */
+#define mb() RISCV_FENCE(iorw,iorw)
+
+/* Read Memory barrier */
+#define rmb() RISCV_FENCE(ir,ir)
+
+/* Write Memory barrier */
+#define wmb() RISCV_FENCE(ow,ow)
+
+/* SMP Read & Write Memory barrier */
+#define smp_mb() RISCV_FENCE(rw,rw)
+
+/* SMP Read Memory barrier */
+#define smp_rmb() RISCV_FENCE(r,r)
+
+/* SMP Write Memory barrier */
+#define smp_wmb() RISCV_FENCE(w,w)
+
+/* CPU relax for busy loop */
+#define cpu_relax() asm volatile ("" : : : "memory")
+
+/* clang-format on */
+
+#define __smp_store_release(p, v) \
+ do { \
+ RISCV_FENCE(rw, w); \
+ *(p) = (v); \
+ } while (0)
+
+#define __smp_load_acquire(p) \
+ ({ \
+ typeof(*p) ___p1 = *(p); \
+ RISCV_FENCE(r, rw); \
+ ___p1; \
+ })
+
+#endif
diff --git a/roms/opensbi/include/sbi/riscv_encoding.h b/roms/opensbi/include/sbi/riscv_encoding.h
new file mode 100644
index 000000000..e1d0b463c
--- /dev/null
+++ b/roms/opensbi/include/sbi/riscv_encoding.h
@@ -0,0 +1,699 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#ifndef __RISCV_ENCODING_H__
+#define __RISCV_ENCODING_H__
+
+#include <sbi/sbi_const.h>
+
+/* clang-format off */
+#define MSTATUS_SIE _UL(0x00000002)
+#define MSTATUS_MIE _UL(0x00000008)
+#define MSTATUS_SPIE_SHIFT 5
+#define MSTATUS_SPIE (_UL(1) << MSTATUS_SPIE_SHIFT)
+#define MSTATUS_UBE _UL(0x00000040)
+#define MSTATUS_MPIE _UL(0x00000080)
+#define MSTATUS_SPP_SHIFT 8
+#define MSTATUS_SPP (_UL(1) << MSTATUS_SPP_SHIFT)
+#define MSTATUS_MPP_SHIFT 11
+#define MSTATUS_MPP (_UL(3) << MSTATUS_MPP_SHIFT)
+#define MSTATUS_FS _UL(0x00006000)
+#define MSTATUS_XS _UL(0x00018000)
+#define MSTATUS_VS _UL(0x01800000)
+#define MSTATUS_MPRV _UL(0x00020000)
+#define MSTATUS_SUM _UL(0x00040000)
+#define MSTATUS_MXR _UL(0x00080000)
+#define MSTATUS_TVM _UL(0x00100000)
+#define MSTATUS_TW _UL(0x00200000)
+#define MSTATUS_TSR _UL(0x00400000)
+#define MSTATUS32_SD _UL(0x80000000)
+#if __riscv_xlen == 64
+#define MSTATUS_UXL _ULL(0x0000000300000000)
+#define MSTATUS_SXL _ULL(0x0000000C00000000)
+#define MSTATUS_SBE _ULL(0x0000001000000000)
+#define MSTATUS_MBE _ULL(0x0000002000000000)
+#define MSTATUS_MPV _ULL(0x0000008000000000)
+#else
+#define MSTATUSH_SBE _UL(0x00000010)
+#define MSTATUSH_MBE _UL(0x00000020)
+#define MSTATUSH_MPV _UL(0x00000080)
+#endif
+#define MSTATUS32_SD _UL(0x80000000)
+#define MSTATUS64_SD _ULL(0x8000000000000000)
+
+#define SSTATUS_SIE MSTATUS_SIE
+#define SSTATUS_SPIE_SHIFT MSTATUS_SPIE_SHIFT
+#define SSTATUS_SPIE MSTATUS_SPIE
+#define SSTATUS_SPP_SHIFT MSTATUS_SPP_SHIFT
+#define SSTATUS_SPP MSTATUS_SPP
+#define SSTATUS_FS MSTATUS_FS
+#define SSTATUS_XS MSTATUS_XS
+#define SSTATUS_VS MSTATUS_VS
+#define SSTATUS_SUM MSTATUS_SUM
+#define SSTATUS_MXR MSTATUS_MXR
+#define SSTATUS32_SD MSTATUS32_SD
+#define SSTATUS64_UXL MSTATUS_UXL
+#define SSTATUS64_SD MSTATUS64_SD
+
+#if __riscv_xlen == 64
+#define HSTATUS_VSXL _UL(0x300000000)
+#define HSTATUS_VSXL_SHIFT 32
+#endif
+#define HSTATUS_VTSR _UL(0x00400000)
+#define HSTATUS_VTW _UL(0x00200000)
+#define HSTATUS_VTVM _UL(0x00100000)
+#define HSTATUS_VGEIN _UL(0x0003f000)
+#define HSTATUS_VGEIN_SHIFT 12
+#define HSTATUS_HU _UL(0x00000200)
+#define HSTATUS_SPVP _UL(0x00000100)
+#define HSTATUS_SPV _UL(0x00000080)
+#define HSTATUS_GVA _UL(0x00000040)
+#define HSTATUS_VSBE _UL(0x00000020)
+
+#define IRQ_S_SOFT 1
+#define IRQ_VS_SOFT 2
+#define IRQ_M_SOFT 3
+#define IRQ_S_TIMER 5
+#define IRQ_VS_TIMER 6
+#define IRQ_M_TIMER 7
+#define IRQ_S_EXT 9
+#define IRQ_VS_EXT 10
+#define IRQ_M_EXT 11
+#define IRQ_S_GEXT 12
+
+#define MIP_SSIP (_UL(1) << IRQ_S_SOFT)
+#define MIP_VSSIP (_UL(1) << IRQ_VS_SOFT)
+#define MIP_MSIP (_UL(1) << IRQ_M_SOFT)
+#define MIP_STIP (_UL(1) << IRQ_S_TIMER)
+#define MIP_VSTIP (_UL(1) << IRQ_VS_TIMER)
+#define MIP_MTIP (_UL(1) << IRQ_M_TIMER)
+#define MIP_SEIP (_UL(1) << IRQ_S_EXT)
+#define MIP_VSEIP (_UL(1) << IRQ_VS_EXT)
+#define MIP_MEIP (_UL(1) << IRQ_M_EXT)
+#define MIP_SGEIP (_UL(1) << IRQ_S_GEXT)
+
+#define SIP_SSIP MIP_SSIP
+#define SIP_STIP MIP_STIP
+
+#define PRV_U _UL(0)
+#define PRV_S _UL(1)
+#define PRV_M _UL(3)
+
+#define SATP32_MODE _UL(0x80000000)
+#define SATP32_ASID _UL(0x7FC00000)
+#define SATP32_PPN _UL(0x003FFFFF)
+#define SATP64_MODE _ULL(0xF000000000000000)
+#define SATP64_ASID _ULL(0x0FFFF00000000000)
+#define SATP64_PPN _ULL(0x00000FFFFFFFFFFF)
+
+#define SATP_MODE_OFF _UL(0)
+#define SATP_MODE_SV32 _UL(1)
+#define SATP_MODE_SV39 _UL(8)
+#define SATP_MODE_SV48 _UL(9)
+#define SATP_MODE_SV57 _UL(10)
+#define SATP_MODE_SV64 _UL(11)
+
+#define HGATP_MODE_OFF _UL(0)
+#define HGATP_MODE_SV32X4 _UL(1)
+#define HGATP_MODE_SV39X4 _UL(8)
+#define HGATP_MODE_SV48X4 _UL(9)
+
+#define HGATP32_MODE_SHIFT 31
+#define HGATP32_VMID_SHIFT 22
+#define HGATP32_VMID_MASK _UL(0x1FC00000)
+#define HGATP32_PPN _UL(0x003FFFFF)
+
+#define HGATP64_MODE_SHIFT 60
+#define HGATP64_VMID_SHIFT 44
+#define HGATP64_VMID_MASK _ULL(0x03FFF00000000000)
+#define HGATP64_PPN _ULL(0x00000FFFFFFFFFFF)
+
+#define PMP_R _UL(0x01)
+#define PMP_W _UL(0x02)
+#define PMP_X _UL(0x04)
+#define PMP_A _UL(0x18)
+#define PMP_A_TOR _UL(0x08)
+#define PMP_A_NA4 _UL(0x10)
+#define PMP_A_NAPOT _UL(0x18)
+#define PMP_L _UL(0x80)
+
+#define PMP_SHIFT 2
+#define PMP_COUNT 64
+#if __riscv_xlen == 64
+#define PMP_ADDR_MASK ((_ULL(0x1) << 54) - 1)
+#else
+#define PMP_ADDR_MASK _UL(0xFFFFFFFF)
+#endif
+
+#if __riscv_xlen == 64
+#define MSTATUS_SD MSTATUS64_SD
+#define SSTATUS_SD SSTATUS64_SD
+#define SATP_MODE SATP64_MODE
+
+#define HGATP_PPN HGATP64_PPN
+#define HGATP_VMID_SHIFT HGATP64_VMID_SHIFT
+#define HGATP_VMID_MASK HGATP64_VMID_MASK
+#define HGATP_MODE_SHIFT HGATP64_MODE_SHIFT
+#else
+#define MSTATUS_SD MSTATUS32_SD
+#define SSTATUS_SD SSTATUS32_SD
+#define SATP_MODE SATP32_MODE
+
+#define HGATP_PPN HGATP32_PPN
+#define HGATP_VMID_SHIFT HGATP32_VMID_SHIFT
+#define HGATP_VMID_MASK HGATP32_VMID_MASK
+#define HGATP_MODE_SHIFT HGATP32_MODE_SHIFT
+#endif
+
+/* ===== User-level CSRs ===== */
+
+/* User Trap Setup (N-extension) */
+#define CSR_USTATUS 0x000
+#define CSR_UIE 0x004
+#define CSR_UTVEC 0x005
+
+/* User Trap Handling (N-extension) */
+#define CSR_USCRATCH 0x040
+#define CSR_UEPC 0x041
+#define CSR_UCAUSE 0x042
+#define CSR_UTVAL 0x043
+#define CSR_UIP 0x044
+
+/* User Floating-point CSRs */
+#define CSR_FFLAGS 0x001
+#define CSR_FRM 0x002
+#define CSR_FCSR 0x003
+
+/* User Counters/Timers */
+#define CSR_CYCLE 0xc00
+#define CSR_TIME 0xc01
+#define CSR_INSTRET 0xc02
+#define CSR_HPMCOUNTER3 0xc03
+#define CSR_HPMCOUNTER4 0xc04
+#define CSR_HPMCOUNTER5 0xc05
+#define CSR_HPMCOUNTER6 0xc06
+#define CSR_HPMCOUNTER7 0xc07
+#define CSR_HPMCOUNTER8 0xc08
+#define CSR_HPMCOUNTER9 0xc09
+#define CSR_HPMCOUNTER10 0xc0a
+#define CSR_HPMCOUNTER11 0xc0b
+#define CSR_HPMCOUNTER12 0xc0c
+#define CSR_HPMCOUNTER13 0xc0d
+#define CSR_HPMCOUNTER14 0xc0e
+#define CSR_HPMCOUNTER15 0xc0f
+#define CSR_HPMCOUNTER16 0xc10
+#define CSR_HPMCOUNTER17 0xc11
+#define CSR_HPMCOUNTER18 0xc12
+#define CSR_HPMCOUNTER19 0xc13
+#define CSR_HPMCOUNTER20 0xc14
+#define CSR_HPMCOUNTER21 0xc15
+#define CSR_HPMCOUNTER22 0xc16
+#define CSR_HPMCOUNTER23 0xc17
+#define CSR_HPMCOUNTER24 0xc18
+#define CSR_HPMCOUNTER25 0xc19
+#define CSR_HPMCOUNTER26 0xc1a
+#define CSR_HPMCOUNTER27 0xc1b
+#define CSR_HPMCOUNTER28 0xc1c
+#define CSR_HPMCOUNTER29 0xc1d
+#define CSR_HPMCOUNTER30 0xc1e
+#define CSR_HPMCOUNTER31 0xc1f
+#define CSR_CYCLEH 0xc80
+#define CSR_TIMEH 0xc81
+#define CSR_INSTRETH 0xc82
+#define CSR_HPMCOUNTER3H 0xc83
+#define CSR_HPMCOUNTER4H 0xc84
+#define CSR_HPMCOUNTER5H 0xc85
+#define CSR_HPMCOUNTER6H 0xc86
+#define CSR_HPMCOUNTER7H 0xc87
+#define CSR_HPMCOUNTER8H 0xc88
+#define CSR_HPMCOUNTER9H 0xc89
+#define CSR_HPMCOUNTER10H 0xc8a
+#define CSR_HPMCOUNTER11H 0xc8b
+#define CSR_HPMCOUNTER12H 0xc8c
+#define CSR_HPMCOUNTER13H 0xc8d
+#define CSR_HPMCOUNTER14H 0xc8e
+#define CSR_HPMCOUNTER15H 0xc8f
+#define CSR_HPMCOUNTER16H 0xc90
+#define CSR_HPMCOUNTER17H 0xc91
+#define CSR_HPMCOUNTER18H 0xc92
+#define CSR_HPMCOUNTER19H 0xc93
+#define CSR_HPMCOUNTER20H 0xc94
+#define CSR_HPMCOUNTER21H 0xc95
+#define CSR_HPMCOUNTER22H 0xc96
+#define CSR_HPMCOUNTER23H 0xc97
+#define CSR_HPMCOUNTER24H 0xc98
+#define CSR_HPMCOUNTER25H 0xc99
+#define CSR_HPMCOUNTER26H 0xc9a
+#define CSR_HPMCOUNTER27H 0xc9b
+#define CSR_HPMCOUNTER28H 0xc9c
+#define CSR_HPMCOUNTER29H 0xc9d
+#define CSR_HPMCOUNTER30H 0xc9e
+#define CSR_HPMCOUNTER31H 0xc9f
+
+/* ===== Supervisor-level CSRs ===== */
+
+/* Supervisor Trap Setup */
+#define CSR_SSTATUS 0x100
+#define CSR_SEDELEG 0x102
+#define CSR_SIDELEG 0x103
+#define CSR_SIE 0x104
+#define CSR_STVEC 0x105
+#define CSR_SCOUNTEREN 0x106
+
+/* Supervisor Trap Handling */
+#define CSR_SSCRATCH 0x140
+#define CSR_SEPC 0x141
+#define CSR_SCAUSE 0x142
+#define CSR_STVAL 0x143
+#define CSR_SIP 0x144
+
+/* Supervisor Protection and Translation */
+#define CSR_SATP 0x180
+
+/* ===== Hypervisor-level CSRs ===== */
+
+/* Hypervisor Trap Setup (H-extension) */
+#define CSR_HSTATUS 0x600
+#define CSR_HEDELEG 0x602
+#define CSR_HIDELEG 0x603
+#define CSR_HIE 0x604
+#define CSR_HCOUNTEREN 0x606
+#define CSR_HGEIE 0x607
+
+/* Hypervisor Trap Handling (H-extension) */
+#define CSR_HTVAL 0x643
+#define CSR_HIP 0x644
+#define CSR_HVIP 0x645
+#define CSR_HTINST 0x64a
+#define CSR_HGEIP 0xe12
+
+/* Hypervisor Protection and Translation (H-extension) */
+#define CSR_HGATP 0x680
+
+/* Hypervisor Counter/Timer Virtualization Registers (H-extension) */
+#define CSR_HTIMEDELTA 0x605
+#define CSR_HTIMEDELTAH 0x615
+
+/* Virtual Supervisor Registers (H-extension) */
+#define CSR_VSSTATUS 0x200
+#define CSR_VSIE 0x204
+#define CSR_VSTVEC 0x205
+#define CSR_VSSCRATCH 0x240
+#define CSR_VSEPC 0x241
+#define CSR_VSCAUSE 0x242
+#define CSR_VSTVAL 0x243
+#define CSR_VSIP 0x244
+#define CSR_VSATP 0x280
+
+/* ===== Machine-level CSRs ===== */
+
+/* Machine Information Registers */
+#define CSR_MVENDORID 0xf11
+#define CSR_MARCHID 0xf12
+#define CSR_MIMPID 0xf13
+#define CSR_MHARTID 0xf14
+
+/* Machine Trap Setup */
+#define CSR_MSTATUS 0x300
+#define CSR_MISA 0x301
+#define CSR_MEDELEG 0x302
+#define CSR_MIDELEG 0x303
+#define CSR_MIE 0x304
+#define CSR_MTVEC 0x305
+#define CSR_MCOUNTEREN 0x306
+#define CSR_MSTATUSH 0x310
+
+/* Machine Trap Handling */
+#define CSR_MSCRATCH 0x340
+#define CSR_MEPC 0x341
+#define CSR_MCAUSE 0x342
+#define CSR_MTVAL 0x343
+#define CSR_MIP 0x344
+#define CSR_MTINST 0x34a
+#define CSR_MTVAL2 0x34b
+
+/* Machine Memory Protection */
+#define CSR_PMPCFG0 0x3a0
+#define CSR_PMPCFG1 0x3a1
+#define CSR_PMPCFG2 0x3a2
+#define CSR_PMPCFG3 0x3a3
+#define CSR_PMPCFG4 0x3a4
+#define CSR_PMPCFG5 0x3a5
+#define CSR_PMPCFG6 0x3a6
+#define CSR_PMPCFG7 0x3a7
+#define CSR_PMPCFG8 0x3a8
+#define CSR_PMPCFG9 0x3a9
+#define CSR_PMPCFG10 0x3aa
+#define CSR_PMPCFG11 0x3ab
+#define CSR_PMPCFG12 0x3ac
+#define CSR_PMPCFG13 0x3ad
+#define CSR_PMPCFG14 0x3ae
+#define CSR_PMPCFG15 0x3af
+#define CSR_PMPADDR0 0x3b0
+#define CSR_PMPADDR1 0x3b1
+#define CSR_PMPADDR2 0x3b2
+#define CSR_PMPADDR3 0x3b3
+#define CSR_PMPADDR4 0x3b4
+#define CSR_PMPADDR5 0x3b5
+#define CSR_PMPADDR6 0x3b6
+#define CSR_PMPADDR7 0x3b7
+#define CSR_PMPADDR8 0x3b8
+#define CSR_PMPADDR9 0x3b9
+#define CSR_PMPADDR10 0x3ba
+#define CSR_PMPADDR11 0x3bb
+#define CSR_PMPADDR12 0x3bc
+#define CSR_PMPADDR13 0x3bd
+#define CSR_PMPADDR14 0x3be
+#define CSR_PMPADDR15 0x3bf
+#define CSR_PMPADDR16 0x3c0
+#define CSR_PMPADDR17 0x3c1
+#define CSR_PMPADDR18 0x3c2
+#define CSR_PMPADDR19 0x3c3
+#define CSR_PMPADDR20 0x3c4
+#define CSR_PMPADDR21 0x3c5
+#define CSR_PMPADDR22 0x3c6
+#define CSR_PMPADDR23 0x3c7
+#define CSR_PMPADDR24 0x3c8
+#define CSR_PMPADDR25 0x3c9
+#define CSR_PMPADDR26 0x3ca
+#define CSR_PMPADDR27 0x3cb
+#define CSR_PMPADDR28 0x3cc
+#define CSR_PMPADDR29 0x3cd
+#define CSR_PMPADDR30 0x3ce
+#define CSR_PMPADDR31 0x3cf
+#define CSR_PMPADDR32 0x3d0
+#define CSR_PMPADDR33 0x3d1
+#define CSR_PMPADDR34 0x3d2
+#define CSR_PMPADDR35 0x3d3
+#define CSR_PMPADDR36 0x3d4
+#define CSR_PMPADDR37 0x3d5
+#define CSR_PMPADDR38 0x3d6
+#define CSR_PMPADDR39 0x3d7
+#define CSR_PMPADDR40 0x3d8
+#define CSR_PMPADDR41 0x3d9
+#define CSR_PMPADDR42 0x3da
+#define CSR_PMPADDR43 0x3db
+#define CSR_PMPADDR44 0x3dc
+#define CSR_PMPADDR45 0x3dd
+#define CSR_PMPADDR46 0x3de
+#define CSR_PMPADDR47 0x3df
+#define CSR_PMPADDR48 0x3e0
+#define CSR_PMPADDR49 0x3e1
+#define CSR_PMPADDR50 0x3e2
+#define CSR_PMPADDR51 0x3e3
+#define CSR_PMPADDR52 0x3e4
+#define CSR_PMPADDR53 0x3e5
+#define CSR_PMPADDR54 0x3e6
+#define CSR_PMPADDR55 0x3e7
+#define CSR_PMPADDR56 0x3e8
+#define CSR_PMPADDR57 0x3e9
+#define CSR_PMPADDR58 0x3ea
+#define CSR_PMPADDR59 0x3eb
+#define CSR_PMPADDR60 0x3ec
+#define CSR_PMPADDR61 0x3ed
+#define CSR_PMPADDR62 0x3ee
+#define CSR_PMPADDR63 0x3ef
+
+/* Machine Counters/Timers */
+#define CSR_MCYCLE 0xb00
+#define CSR_MINSTRET 0xb02
+#define CSR_MHPMCOUNTER3 0xb03
+#define CSR_MHPMCOUNTER4 0xb04
+#define CSR_MHPMCOUNTER5 0xb05
+#define CSR_MHPMCOUNTER6 0xb06
+#define CSR_MHPMCOUNTER7 0xb07
+#define CSR_MHPMCOUNTER8 0xb08
+#define CSR_MHPMCOUNTER9 0xb09
+#define CSR_MHPMCOUNTER10 0xb0a
+#define CSR_MHPMCOUNTER11 0xb0b
+#define CSR_MHPMCOUNTER12 0xb0c
+#define CSR_MHPMCOUNTER13 0xb0d
+#define CSR_MHPMCOUNTER14 0xb0e
+#define CSR_MHPMCOUNTER15 0xb0f
+#define CSR_MHPMCOUNTER16 0xb10
+#define CSR_MHPMCOUNTER17 0xb11
+#define CSR_MHPMCOUNTER18 0xb12
+#define CSR_MHPMCOUNTER19 0xb13
+#define CSR_MHPMCOUNTER20 0xb14
+#define CSR_MHPMCOUNTER21 0xb15
+#define CSR_MHPMCOUNTER22 0xb16
+#define CSR_MHPMCOUNTER23 0xb17
+#define CSR_MHPMCOUNTER24 0xb18
+#define CSR_MHPMCOUNTER25 0xb19
+#define CSR_MHPMCOUNTER26 0xb1a
+#define CSR_MHPMCOUNTER27 0xb1b
+#define CSR_MHPMCOUNTER28 0xb1c
+#define CSR_MHPMCOUNTER29 0xb1d
+#define CSR_MHPMCOUNTER30 0xb1e
+#define CSR_MHPMCOUNTER31 0xb1f
+#define CSR_MCYCLEH 0xb80
+#define CSR_MINSTRETH 0xb82
+#define CSR_MHPMCOUNTER3H 0xb83
+#define CSR_MHPMCOUNTER4H 0xb84
+#define CSR_MHPMCOUNTER5H 0xb85
+#define CSR_MHPMCOUNTER6H 0xb86
+#define CSR_MHPMCOUNTER7H 0xb87
+#define CSR_MHPMCOUNTER8H 0xb88
+#define CSR_MHPMCOUNTER9H 0xb89
+#define CSR_MHPMCOUNTER10H 0xb8a
+#define CSR_MHPMCOUNTER11H 0xb8b
+#define CSR_MHPMCOUNTER12H 0xb8c
+#define CSR_MHPMCOUNTER13H 0xb8d
+#define CSR_MHPMCOUNTER14H 0xb8e
+#define CSR_MHPMCOUNTER15H 0xb8f
+#define CSR_MHPMCOUNTER16H 0xb90
+#define CSR_MHPMCOUNTER17H 0xb91
+#define CSR_MHPMCOUNTER18H 0xb92
+#define CSR_MHPMCOUNTER19H 0xb93
+#define CSR_MHPMCOUNTER20H 0xb94
+#define CSR_MHPMCOUNTER21H 0xb95
+#define CSR_MHPMCOUNTER22H 0xb96
+#define CSR_MHPMCOUNTER23H 0xb97
+#define CSR_MHPMCOUNTER24H 0xb98
+#define CSR_MHPMCOUNTER25H 0xb99
+#define CSR_MHPMCOUNTER26H 0xb9a
+#define CSR_MHPMCOUNTER27H 0xb9b
+#define CSR_MHPMCOUNTER28H 0xb9c
+#define CSR_MHPMCOUNTER29H 0xb9d
+#define CSR_MHPMCOUNTER30H 0xb9e
+#define CSR_MHPMCOUNTER31H 0xb9f
+
+/* Machine Counter Setup */
+#define CSR_MCOUNTINHIBIT 0x320
+#define CSR_MHPMEVENT3 0x323
+#define CSR_MHPMEVENT4 0x324
+#define CSR_MHPMEVENT5 0x325
+#define CSR_MHPMEVENT6 0x326
+#define CSR_MHPMEVENT7 0x327
+#define CSR_MHPMEVENT8 0x328
+#define CSR_MHPMEVENT9 0x329
+#define CSR_MHPMEVENT10 0x32a
+#define CSR_MHPMEVENT11 0x32b
+#define CSR_MHPMEVENT12 0x32c
+#define CSR_MHPMEVENT13 0x32d
+#define CSR_MHPMEVENT14 0x32e
+#define CSR_MHPMEVENT15 0x32f
+#define CSR_MHPMEVENT16 0x330
+#define CSR_MHPMEVENT17 0x331
+#define CSR_MHPMEVENT18 0x332
+#define CSR_MHPMEVENT19 0x333
+#define CSR_MHPMEVENT20 0x334
+#define CSR_MHPMEVENT21 0x335
+#define CSR_MHPMEVENT22 0x336
+#define CSR_MHPMEVENT23 0x337
+#define CSR_MHPMEVENT24 0x338
+#define CSR_MHPMEVENT25 0x339
+#define CSR_MHPMEVENT26 0x33a
+#define CSR_MHPMEVENT27 0x33b
+#define CSR_MHPMEVENT28 0x33c
+#define CSR_MHPMEVENT29 0x33d
+#define CSR_MHPMEVENT30 0x33e
+#define CSR_MHPMEVENT31 0x33f
+
+/* Debug/Trace Registers */
+#define CSR_TSELECT 0x7a0
+#define CSR_TDATA1 0x7a1
+#define CSR_TDATA2 0x7a2
+#define CSR_TDATA3 0x7a3
+
+/* Debug Mode Registers */
+#define CSR_DCSR 0x7b0
+#define CSR_DPC 0x7b1
+#define CSR_DSCRATCH0 0x7b2
+#define CSR_DSCRATCH1 0x7b3
+
+/* ===== Trap/Exception Causes ===== */
+
+#define CAUSE_MISALIGNED_FETCH 0x0
+#define CAUSE_FETCH_ACCESS 0x1
+#define CAUSE_ILLEGAL_INSTRUCTION 0x2
+#define CAUSE_BREAKPOINT 0x3
+#define CAUSE_MISALIGNED_LOAD 0x4
+#define CAUSE_LOAD_ACCESS 0x5
+#define CAUSE_MISALIGNED_STORE 0x6
+#define CAUSE_STORE_ACCESS 0x7
+#define CAUSE_USER_ECALL 0x8
+#define CAUSE_SUPERVISOR_ECALL 0x9
+#define CAUSE_VIRTUAL_SUPERVISOR_ECALL 0xa
+#define CAUSE_MACHINE_ECALL 0xb
+#define CAUSE_FETCH_PAGE_FAULT 0xc
+#define CAUSE_LOAD_PAGE_FAULT 0xd
+#define CAUSE_STORE_PAGE_FAULT 0xf
+#define CAUSE_FETCH_GUEST_PAGE_FAULT 0x14
+#define CAUSE_LOAD_GUEST_PAGE_FAULT 0x15
+#define CAUSE_VIRTUAL_INST_FAULT 0x16
+#define CAUSE_STORE_GUEST_PAGE_FAULT 0x17
+
+/* ===== Instruction Encodings ===== */
+
+#define INSN_MATCH_LB 0x3
+#define INSN_MASK_LB 0x707f
+#define INSN_MATCH_LH 0x1003
+#define INSN_MASK_LH 0x707f
+#define INSN_MATCH_LW 0x2003
+#define INSN_MASK_LW 0x707f
+#define INSN_MATCH_LD 0x3003
+#define INSN_MASK_LD 0x707f
+#define INSN_MATCH_LBU 0x4003
+#define INSN_MASK_LBU 0x707f
+#define INSN_MATCH_LHU 0x5003
+#define INSN_MASK_LHU 0x707f
+#define INSN_MATCH_LWU 0x6003
+#define INSN_MASK_LWU 0x707f
+#define INSN_MATCH_SB 0x23
+#define INSN_MASK_SB 0x707f
+#define INSN_MATCH_SH 0x1023
+#define INSN_MASK_SH 0x707f
+#define INSN_MATCH_SW 0x2023
+#define INSN_MASK_SW 0x707f
+#define INSN_MATCH_SD 0x3023
+#define INSN_MASK_SD 0x707f
+
+#define INSN_MATCH_FLW 0x2007
+#define INSN_MASK_FLW 0x707f
+#define INSN_MATCH_FLD 0x3007
+#define INSN_MASK_FLD 0x707f
+#define INSN_MATCH_FLQ 0x4007
+#define INSN_MASK_FLQ 0x707f
+#define INSN_MATCH_FSW 0x2027
+#define INSN_MASK_FSW 0x707f
+#define INSN_MATCH_FSD 0x3027
+#define INSN_MASK_FSD 0x707f
+#define INSN_MATCH_FSQ 0x4027
+#define INSN_MASK_FSQ 0x707f
+
+#define INSN_MATCH_C_LD 0x6000
+#define INSN_MASK_C_LD 0xe003
+#define INSN_MATCH_C_SD 0xe000
+#define INSN_MASK_C_SD 0xe003
+#define INSN_MATCH_C_LW 0x4000
+#define INSN_MASK_C_LW 0xe003
+#define INSN_MATCH_C_SW 0xc000
+#define INSN_MASK_C_SW 0xe003
+#define INSN_MATCH_C_LDSP 0x6002
+#define INSN_MASK_C_LDSP 0xe003
+#define INSN_MATCH_C_SDSP 0xe002
+#define INSN_MASK_C_SDSP 0xe003
+#define INSN_MATCH_C_LWSP 0x4002
+#define INSN_MASK_C_LWSP 0xe003
+#define INSN_MATCH_C_SWSP 0xc002
+#define INSN_MASK_C_SWSP 0xe003
+
+#define INSN_MATCH_C_FLD 0x2000
+#define INSN_MASK_C_FLD 0xe003
+#define INSN_MATCH_C_FLW 0x6000
+#define INSN_MASK_C_FLW 0xe003
+#define INSN_MATCH_C_FSD 0xa000
+#define INSN_MASK_C_FSD 0xe003
+#define INSN_MATCH_C_FSW 0xe000
+#define INSN_MASK_C_FSW 0xe003
+#define INSN_MATCH_C_FLDSP 0x2002
+#define INSN_MASK_C_FLDSP 0xe003
+#define INSN_MATCH_C_FSDSP 0xa002
+#define INSN_MASK_C_FSDSP 0xe003
+#define INSN_MATCH_C_FLWSP 0x6002
+#define INSN_MASK_C_FLWSP 0xe003
+#define INSN_MATCH_C_FSWSP 0xe002
+#define INSN_MASK_C_FSWSP 0xe003
+
+#define INSN_MASK_WFI 0xffffff00
+#define INSN_MATCH_WFI 0x10500000
+
+#define INSN_16BIT_MASK 0x3
+#define INSN_32BIT_MASK 0x1c
+
+#define INSN_IS_16BIT(insn) \
+ (((insn) & INSN_16BIT_MASK) != INSN_16BIT_MASK)
+#define INSN_IS_32BIT(insn) \
+ (((insn) & INSN_16BIT_MASK) == INSN_16BIT_MASK && \
+ ((insn) & INSN_32BIT_MASK) != INSN_32BIT_MASK)
+
+#define INSN_LEN(insn) (INSN_IS_16BIT(insn) ? 2 : 4)
+
+#if __riscv_xlen == 64
+#define LOG_REGBYTES 3
+#else
+#define LOG_REGBYTES 2
+#endif
+#define REGBYTES (1 << LOG_REGBYTES)
+
+#define SH_RD 7
+#define SH_RS1 15
+#define SH_RS2 20
+#define SH_RS2C 2
+
+#define RV_X(x, s, n) (((x) >> (s)) & ((1 << (n)) - 1))
+#define RVC_LW_IMM(x) ((RV_X(x, 6, 1) << 2) | \
+ (RV_X(x, 10, 3) << 3) | \
+ (RV_X(x, 5, 1) << 6))
+#define RVC_LD_IMM(x) ((RV_X(x, 10, 3) << 3) | \
+ (RV_X(x, 5, 2) << 6))
+#define RVC_LWSP_IMM(x) ((RV_X(x, 4, 3) << 2) | \
+ (RV_X(x, 12, 1) << 5) | \
+ (RV_X(x, 2, 2) << 6))
+#define RVC_LDSP_IMM(x) ((RV_X(x, 5, 2) << 3) | \
+ (RV_X(x, 12, 1) << 5) | \
+ (RV_X(x, 2, 3) << 6))
+#define RVC_SWSP_IMM(x) ((RV_X(x, 9, 4) << 2) | \
+ (RV_X(x, 7, 2) << 6))
+#define RVC_SDSP_IMM(x) ((RV_X(x, 10, 3) << 3) | \
+ (RV_X(x, 7, 3) << 6))
+#define RVC_RS1S(insn) (8 + RV_X(insn, SH_RD, 3))
+#define RVC_RS2S(insn) (8 + RV_X(insn, SH_RS2C, 3))
+#define RVC_RS2(insn) RV_X(insn, SH_RS2C, 5)
+
+#define SHIFT_RIGHT(x, y) \
+ ((y) < 0 ? ((x) << -(y)) : ((x) >> (y)))
+
+#define REG_MASK \
+ ((1 << (5 + LOG_REGBYTES)) - (1 << LOG_REGBYTES))
+
+#define REG_OFFSET(insn, pos) \
+ (SHIFT_RIGHT((insn), (pos) - LOG_REGBYTES) & REG_MASK)
+
+#define REG_PTR(insn, pos, regs) \
+ (ulong *)((ulong)(regs) + REG_OFFSET(insn, pos))
+
+#define GET_RM(insn) (((insn) >> 12) & 7)
+
+#define GET_RS1(insn, regs) (*REG_PTR(insn, SH_RS1, regs))
+#define GET_RS2(insn, regs) (*REG_PTR(insn, SH_RS2, regs))
+#define GET_RS1S(insn, regs) (*REG_PTR(RVC_RS1S(insn), 0, regs))
+#define GET_RS2S(insn, regs) (*REG_PTR(RVC_RS2S(insn), 0, regs))
+#define GET_RS2C(insn, regs) (*REG_PTR(insn, SH_RS2C, regs))
+#define GET_SP(regs) (*REG_PTR(2, 0, regs))
+#define SET_RD(insn, regs, val) (*REG_PTR(insn, SH_RD, regs) = (val))
+#define IMM_I(insn) ((s32)(insn) >> 20)
+#define IMM_S(insn) (((s32)(insn) >> 25 << 5) | \
+ (s32)(((insn) >> 7) & 0x1f))
+#define MASK_FUNCT3 0x7000
+
+/* clang-format on */
+
+#endif
diff --git a/roms/opensbi/include/sbi/riscv_fp.h b/roms/opensbi/include/sbi/riscv_fp.h
new file mode 100644
index 000000000..a685884a5
--- /dev/null
+++ b/roms/opensbi/include/sbi/riscv_fp.h
@@ -0,0 +1,94 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#ifndef __RISCV_FP_H__
+#define __RISCV_FP_H__
+
+#include <sbi/riscv_asm.h>
+#include <sbi/riscv_encoding.h>
+#include <sbi/sbi_types.h>
+
+#define GET_PRECISION(insn) (((insn) >> 25) & 3)
+#define GET_RM(insn) (((insn) >> 12) & 7)
+#define PRECISION_S 0
+#define PRECISION_D 1
+
+#ifdef __riscv_flen
+
+#define GET_F32_REG(insn, pos, regs) \
+ ({ \
+ register s32 value asm("a0") = \
+ SHIFT_RIGHT(insn, (pos)-3) & 0xf8; \
+ ulong tmp; \
+ asm("1: auipc %0, %%pcrel_hi(get_f32_reg); add %0, %0, %1; jalr t0, %0, %%pcrel_lo(1b)" \
+ : "=&r"(tmp), "+&r"(value)::"t0"); \
+ value; \
+ })
+#define SET_F32_REG(insn, pos, regs, val) \
+ ({ \
+ register u32 value asm("a0") = (val); \
+ ulong offset = SHIFT_RIGHT(insn, (pos)-3) & 0xf8; \
+ ulong tmp; \
+ asm volatile( \
+ "1: auipc %0, %%pcrel_hi(put_f32_reg); add %0, %0, %2; jalr t0, %0, %%pcrel_lo(1b)" \
+ : "=&r"(tmp) \
+ : "r"(value), "r"(offset) \
+ : "t0"); \
+ })
+#define init_fp_reg(i) SET_F32_REG((i) << 3, 3, 0, 0)
+#define GET_F64_REG(insn, pos, regs) \
+ ({ \
+ register ulong value asm("a0") = \
+ SHIFT_RIGHT(insn, (pos)-3) & 0xf8; \
+ ulong tmp; \
+ asm("1: auipc %0, %%pcrel_hi(get_f64_reg); add %0, %0, %1; jalr t0, %0, %%pcrel_lo(1b)" \
+ : "=&r"(tmp), "+&r"(value)::"t0"); \
+ sizeof(ulong) == 4 ? *(int64_t *)value : (int64_t)value; \
+ })
+#define SET_F64_REG(insn, pos, regs, val) \
+ ({ \
+ uint64_t __val = (val); \
+ register ulong value asm("a0") = \
+ sizeof(ulong) == 4 ? (ulong)&__val : (ulong)__val; \
+ ulong offset = SHIFT_RIGHT(insn, (pos)-3) & 0xf8; \
+ ulong tmp; \
+ asm volatile( \
+ "1: auipc %0, %%pcrel_hi(put_f64_reg); add %0, %0, %2; jalr t0, %0, %%pcrel_lo(1b)" \
+ : "=&r"(tmp) \
+ : "r"(value), "r"(offset) \
+ : "t0"); \
+ })
+#define GET_FCSR() csr_read(CSR_FCSR)
+#define SET_FCSR(value) csr_write(CSR_FCSR, (value))
+#define GET_FRM() csr_read(CSR_FRM)
+#define SET_FRM(value) csr_write(CSR_FRM, (value))
+#define GET_FFLAGS() csr_read(CSR_FFLAGS)
+#define SET_FFLAGS(value) csr_write(CSR_FFLAGS, (value))
+
+#define SET_FS_DIRTY() ((void)0)
+
+#define GET_F32_RS1(insn, regs) (GET_F32_REG(insn, 15, regs))
+#define GET_F32_RS2(insn, regs) (GET_F32_REG(insn, 20, regs))
+#define GET_F32_RS3(insn, regs) (GET_F32_REG(insn, 27, regs))
+#define GET_F64_RS1(insn, regs) (GET_F64_REG(insn, 15, regs))
+#define GET_F64_RS2(insn, regs) (GET_F64_REG(insn, 20, regs))
+#define GET_F64_RS3(insn, regs) (GET_F64_REG(insn, 27, regs))
+#define SET_F32_RD(insn, regs, val) \
+ (SET_F32_REG(insn, 7, regs, val), SET_FS_DIRTY())
+#define SET_F64_RD(insn, regs, val) \
+ (SET_F64_REG(insn, 7, regs, val), SET_FS_DIRTY())
+
+#define GET_F32_RS2C(insn, regs) (GET_F32_REG(insn, 2, regs))
+#define GET_F32_RS2S(insn, regs) (GET_F32_REG(RVC_RS2S(insn), 0, regs))
+#define GET_F64_RS2C(insn, regs) (GET_F64_REG(insn, 2, regs))
+#define GET_F64_RS2S(insn, regs) (GET_F64_REG(RVC_RS2S(insn), 0, regs))
+
+#endif
+
+#endif
diff --git a/roms/opensbi/include/sbi/riscv_io.h b/roms/opensbi/include/sbi/riscv_io.h
new file mode 100644
index 000000000..491323283
--- /dev/null
+++ b/roms/opensbi/include/sbi/riscv_io.h
@@ -0,0 +1,114 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#ifndef __RISCV_IO_H__
+#define __RISCV_IO_H__
+
+#include <sbi/riscv_barrier.h>
+#include <sbi/sbi_types.h>
+
+static inline void __raw_writeb(u8 val, volatile void *addr)
+{
+ asm volatile("sb %0, 0(%1)" : : "r"(val), "r"(addr));
+}
+
+static inline void __raw_writew(u16 val, volatile void *addr)
+{
+ asm volatile("sh %0, 0(%1)" : : "r"(val), "r"(addr));
+}
+
+static inline void __raw_writel(u32 val, volatile void *addr)
+{
+ asm volatile("sw %0, 0(%1)" : : "r"(val), "r"(addr));
+}
+
+#if __riscv_xlen != 32
+static inline void __raw_writeq(u64 val, volatile void *addr)
+{
+ asm volatile("sd %0, 0(%1)" : : "r"(val), "r"(addr));
+}
+#endif
+
+static inline u8 __raw_readb(const volatile void *addr)
+{
+ u8 val;
+
+ asm volatile("lb %0, 0(%1)" : "=r"(val) : "r"(addr));
+ return val;
+}
+
+static inline u16 __raw_readw(const volatile void *addr)
+{
+ u16 val;
+
+ asm volatile("lh %0, 0(%1)" : "=r"(val) : "r"(addr));
+ return val;
+}
+
+static inline u32 __raw_readl(const volatile void *addr)
+{
+ u32 val;
+
+ asm volatile("lw %0, 0(%1)" : "=r"(val) : "r"(addr));
+ return val;
+}
+
+#if __riscv_xlen != 32
+static inline u64 __raw_readq(const volatile void *addr)
+{
+ u64 val;
+
+ asm volatile("ld %0, 0(%1)" : "=r"(val) : "r"(addr));
+ return val;
+}
+#endif
+
+/* FIXME: These are now the same as asm-generic */
+
+/* clang-format off */
+
+#define __io_rbr() do {} while (0)
+#define __io_rar() do {} while (0)
+#define __io_rbw() do {} while (0)
+#define __io_raw() do {} while (0)
+
+#define readb_relaxed(c) ({ u8 __v; __io_rbr(); __v = __raw_readb(c); __io_rar(); __v; })
+#define readw_relaxed(c) ({ u16 __v; __io_rbr(); __v = __raw_readw(c); __io_rar(); __v; })
+#define readl_relaxed(c) ({ u32 __v; __io_rbr(); __v = __raw_readl(c); __io_rar(); __v; })
+
+#define writeb_relaxed(v,c) ({ __io_rbw(); __raw_writeb((v),(c)); __io_raw(); })
+#define writew_relaxed(v,c) ({ __io_rbw(); __raw_writew((v),(c)); __io_raw(); })
+#define writel_relaxed(v,c) ({ __io_rbw(); __raw_writel((v),(c)); __io_raw(); })
+
+#if __riscv_xlen != 32
+#define readq_relaxed(c) ({ u64 __v; __io_rbr(); __v = __raw_readq(c); __io_rar(); __v; })
+#define writeq_relaxed(v,c) ({ __io_rbw(); __raw_writeq((v),(c)); __io_raw(); })
+#endif
+
+#define __io_br() do {} while (0)
+#define __io_ar() __asm__ __volatile__ ("fence i,r" : : : "memory");
+#define __io_bw() __asm__ __volatile__ ("fence w,o" : : : "memory");
+#define __io_aw() do {} while (0)
+
+#define readb(c) ({ u8 __v; __io_br(); __v = __raw_readb(c); __io_ar(); __v; })
+#define readw(c) ({ u16 __v; __io_br(); __v = __raw_readw(c); __io_ar(); __v; })
+#define readl(c) ({ u32 __v; __io_br(); __v = __raw_readl(c); __io_ar(); __v; })
+
+#define writeb(v,c) ({ __io_bw(); __raw_writeb((v),(c)); __io_aw(); })
+#define writew(v,c) ({ __io_bw(); __raw_writew((v),(c)); __io_aw(); })
+#define writel(v,c) ({ __io_bw(); __raw_writel((v),(c)); __io_aw(); })
+
+#if __riscv_xlen != 32
+#define readq(c) ({ u64 __v; __io_br(); __v = __raw_readq(c); __io_ar(); __v; })
+#define writeq(v,c) ({ __io_bw(); __raw_writeq((v),(c)); __io_aw(); })
+#endif
+
+/* clang-format on */
+
+#endif
diff --git a/roms/opensbi/include/sbi/riscv_locks.h b/roms/opensbi/include/sbi/riscv_locks.h
new file mode 100644
index 000000000..55da7c01c
--- /dev/null
+++ b/roms/opensbi/include/sbi/riscv_locks.h
@@ -0,0 +1,34 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#ifndef __RISCV_LOCKS_H__
+#define __RISCV_LOCKS_H__
+
+typedef struct {
+ volatile long lock;
+} spinlock_t;
+
+#define __RISCV_SPIN_UNLOCKED 0
+
+#define SPIN_LOCK_INIT(_lptr) (_lptr)->lock = __RISCV_SPIN_UNLOCKED
+
+#define SPIN_LOCK_INITIALIZER \
+ { \
+ .lock = __RISCV_SPIN_UNLOCKED, \
+ }
+
+int spin_lock_check(spinlock_t *lock);
+
+int spin_trylock(spinlock_t *lock);
+
+void spin_lock(spinlock_t *lock);
+
+void spin_unlock(spinlock_t *lock);
+
+#endif
diff --git a/roms/opensbi/include/sbi/sbi_bitmap.h b/roms/opensbi/include/sbi/sbi_bitmap.h
new file mode 100644
index 000000000..4f0ebb63a
--- /dev/null
+++ b/roms/opensbi/include/sbi/sbi_bitmap.h
@@ -0,0 +1,128 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2020 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#ifndef __SBI_BITMAP_H__
+#define __SBI_BITMAP_H__
+
+#include <sbi/sbi_bitops.h>
+
+#define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) % BITS_PER_LONG))
+#define BITMAP_LAST_WORD_MASK(nbits) \
+( \
+ ((nbits) % BITS_PER_LONG) ? \
+ ((1UL << ((nbits) % BITS_PER_LONG)) - 1) : ~0UL \
+)
+
+#define small_const_nbits(nbits) \
+ (__builtin_constant_p(nbits) && (nbits) <= BITS_PER_LONG)
+
+#define DECLARE_BITMAP(name, nbits) unsigned long name[BITS_TO_LONGS(nbits)]
+#define DEFINE_BITMAP(name) extern unsigned long name[]
+
+static inline unsigned long bitmap_estimate_size(int nbits)
+{
+ return (BITS_TO_LONGS(nbits) * sizeof(unsigned long));
+}
+
+void __bitmap_and(unsigned long *dst, const unsigned long *bitmap1,
+ const unsigned long *bitmap2, int bits);
+void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1,
+ const unsigned long *bitmap2, int bits);
+void __bitmap_xor(unsigned long *dst, const unsigned long *bitmap1,
+ const unsigned long *bitmap2, int bits);
+
+static inline void bitmap_set(unsigned long *bmap, int start, int len)
+{
+ int bit;
+ for (bit = start; bit < (start + len); bit++)
+ bmap[BIT_WORD(bit)] |= (0x1UL << BIT_WORD_OFFSET(bit));
+}
+
+static inline void bitmap_clear(unsigned long *bmap, int start, int len)
+{
+ int bit;
+ for (bit = start; bit < (start + len); bit++)
+ bmap[BIT_WORD(bit)] &= ~(0x1UL << BIT_WORD_OFFSET(bit));
+}
+
+static inline void bitmap_zero(unsigned long *dst, int nbits)
+{
+ if (small_const_nbits(nbits))
+ *dst = 0UL;
+ else {
+ size_t i, len = BITS_TO_LONGS(nbits);
+ for (i = 0; i < len; i++)
+ dst[i] = 0;
+ }
+}
+
+static inline void bitmap_zero_except(unsigned long *dst,
+ int exception, int nbits)
+{
+ if (small_const_nbits(nbits))
+ *dst = 0UL;
+ else {
+ size_t i, len = BITS_TO_LONGS(nbits);
+ for (i = 0; i < len; i++)
+ dst[i] = 0;
+ }
+ if (exception < nbits)
+ __set_bit(exception, dst);
+}
+
+static inline void bitmap_fill(unsigned long *dst, int nbits)
+{
+ size_t i, nlongs = BITS_TO_LONGS(nbits);
+ if (!small_const_nbits(nbits)) {
+ for (i = 0; i < (nlongs - 1); i++)
+ dst[i] = -1UL;
+ }
+ dst[nlongs - 1] = BITMAP_LAST_WORD_MASK(nbits);
+}
+
+static inline void bitmap_copy(unsigned long *dst,
+ const unsigned long *src, int nbits)
+{
+ if (small_const_nbits(nbits))
+ *dst = *src;
+ else {
+ size_t i, len = BITS_TO_LONGS(nbits);
+ for (i = 0; i < len; i++)
+ dst[i] = src[i];
+ }
+}
+
+static inline void bitmap_and(unsigned long *dst, const unsigned long *src1,
+ const unsigned long *src2, int nbits)
+{
+ if (small_const_nbits(nbits))
+ *dst = *src1 & *src2;
+ else
+ __bitmap_and(dst, src1, src2, nbits);
+}
+
+static inline void bitmap_or(unsigned long *dst, const unsigned long *src1,
+ const unsigned long *src2, int nbits)
+{
+ if (small_const_nbits(nbits))
+ *dst = *src1 | *src2;
+ else
+ __bitmap_or(dst, src1, src2, nbits);
+}
+
+static inline void bitmap_xor(unsigned long *dst, const unsigned long *src1,
+ const unsigned long *src2, int nbits)
+{
+ if (small_const_nbits(nbits))
+ *dst = *src1 ^ *src2;
+ else
+ __bitmap_xor(dst, src1, src2, nbits);
+}
+
+#endif
diff --git a/roms/opensbi/include/sbi/sbi_bitops.h b/roms/opensbi/include/sbi/sbi_bitops.h
new file mode 100644
index 000000000..879430d4b
--- /dev/null
+++ b/roms/opensbi/include/sbi/sbi_bitops.h
@@ -0,0 +1,320 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Atish Patra <atish.patra@wdc.com>
+ */
+
+#ifndef __SBI_BITOPS_H__
+#define __SBI_BITOPS_H__
+
+#include <sbi/sbi_types.h>
+
+#if __SIZEOF_POINTER__ == 8
+#define BITS_PER_LONG 64
+#elif __SIZEOF_POINTER__ == 4
+#define BITS_PER_LONG 32
+#else
+#error "Unexpected __SIZEOF_POINTER__"
+#endif
+
+#define EXTRACT_FIELD(val, which) \
+ (((val) & (which)) / ((which) & ~((which)-1)))
+#define INSERT_FIELD(val, which, fieldval) \
+ (((val) & ~(which)) | ((fieldval) * ((which) & ~((which)-1))))
+
+#define BITS_TO_LONGS(nbits) (((nbits) + BITS_PER_LONG - 1) / \
+ BITS_PER_LONG)
+
+#define BIT(nr) (1UL << (nr))
+#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
+#define BIT_WORD(bit) ((bit) / BITS_PER_LONG)
+#define BIT_WORD_OFFSET(bit) ((bit) & (BITS_PER_LONG - 1))
+
+#define GENMASK(h, l) \
+ (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
+
+/**
+ * ffs - Find first bit set
+ * @x: the word to search
+ *
+ * This is defined the same way as
+ * the libc and compiler builtin ffs routines, therefore
+ * differs in spirit from the above ffz (man ffs).
+ */
+static inline int ffs(int x)
+{
+ int r = 1;
+
+ if (!x)
+ return 0;
+ if (!(x & 0xffff)) {
+ x >>= 16;
+ r += 16;
+ }
+ if (!(x & 0xff)) {
+ x >>= 8;
+ r += 8;
+ }
+ if (!(x & 0xf)) {
+ x >>= 4;
+ r += 4;
+ }
+ if (!(x & 3)) {
+ x >>= 2;
+ r += 2;
+ }
+ if (!(x & 1))
+ r += 1;
+ return r;
+}
+
+/**
+ * __ffs - find first bit in word.
+ * @word: The word to search
+ *
+ * Undefined if no bit exists, so code should check against 0 first.
+ */
+static inline int __ffs(unsigned long word)
+{
+ int num = 0;
+
+#if BITS_PER_LONG == 64
+ if ((word & 0xffffffff) == 0) {
+ num += 32;
+ word >>= 32;
+ }
+#endif
+ if ((word & 0xffff) == 0) {
+ num += 16;
+ word >>= 16;
+ }
+ if ((word & 0xff) == 0) {
+ num += 8;
+ word >>= 8;
+ }
+ if ((word & 0xf) == 0) {
+ num += 4;
+ word >>= 4;
+ }
+ if ((word & 0x3) == 0) {
+ num += 2;
+ word >>= 2;
+ }
+ if ((word & 0x1) == 0)
+ num += 1;
+ return num;
+}
+
+/*
+ * ffz - find first zero in word.
+ * @word: The word to search
+ *
+ * Undefined if no zero exists, so code should check against ~0UL first.
+ */
+#define ffz(x) __ffs(~(x))
+
+/**
+ * fls - find last (most-significant) bit set
+ * @x: the word to search
+ *
+ * This is defined the same way as ffs.
+ * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
+ */
+
+static inline int fls(int x)
+{
+ int r = 32;
+
+ if (!x)
+ return 0;
+ if (!(x & 0xffff0000u)) {
+ x <<= 16;
+ r -= 16;
+ }
+ if (!(x & 0xff000000u)) {
+ x <<= 8;
+ r -= 8;
+ }
+ if (!(x & 0xf0000000u)) {
+ x <<= 4;
+ r -= 4;
+ }
+ if (!(x & 0xc0000000u)) {
+ x <<= 2;
+ r -= 2;
+ }
+ if (!(x & 0x80000000u))
+ r -= 1;
+ return r;
+}
+
+/**
+ * __fls - find last (most-significant) set bit in a long word
+ * @word: the word to search
+ *
+ * Undefined if no set bit exists, so code should check against 0 first.
+ */
+static inline unsigned long __fls(unsigned long word)
+{
+ int num = BITS_PER_LONG - 1;
+
+#if BITS_PER_LONG == 64
+ if (!(word & (~0ul << 32))) {
+ num -= 32;
+ word <<= 32;
+ }
+#endif
+ if (!(word & (~0ul << (BITS_PER_LONG-16)))) {
+ num -= 16;
+ word <<= 16;
+ }
+ if (!(word & (~0ul << (BITS_PER_LONG-8)))) {
+ num -= 8;
+ word <<= 8;
+ }
+ if (!(word & (~0ul << (BITS_PER_LONG-4)))) {
+ num -= 4;
+ word <<= 4;
+ }
+ if (!(word & (~0ul << (BITS_PER_LONG-2)))) {
+ num -= 2;
+ word <<= 2;
+ }
+ if (!(word & (~0ul << (BITS_PER_LONG-1))))
+ num -= 1;
+ return num;
+}
+
+#define for_each_set_bit(bit, addr, size) \
+ for ((bit) = find_first_bit((addr), (size)); \
+ (bit) < (size); \
+ (bit) = find_next_bit((addr), (size), (bit) + 1))
+
+/* same as for_each_set_bit() but use bit as value to start with */
+#define for_each_set_bit_from(bit, addr, size) \
+ for ((bit) = find_next_bit((addr), (size), (bit)); \
+ (bit) < (size); \
+ (bit) = find_next_bit((addr), (size), (bit) + 1))
+
+#define for_each_clear_bit(bit, addr, size) \
+ for ((bit) = find_first_zero_bit((addr), (size)); \
+ (bit) < (size); \
+ (bit) = find_next_zero_bit((addr), (size), (bit) + 1))
+
+/* same as for_each_clear_bit() but use bit as value to start with */
+#define for_each_clear_bit_from(bit, addr, size) \
+ for ((bit) = find_next_zero_bit((addr), (size), (bit)); \
+ (bit) < (size); \
+ (bit) = find_next_zero_bit((addr), (size), (bit) + 1))
+
+unsigned long find_first_bit(const unsigned long *addr,
+ unsigned long size);
+
+unsigned long find_first_zero_bit(const unsigned long *addr,
+ unsigned long size);
+
+unsigned long find_last_bit(const unsigned long *addr,
+ unsigned long size);
+
+unsigned long find_next_bit(const unsigned long *addr,
+ unsigned long size, unsigned long offset);
+
+unsigned long find_next_zero_bit(const unsigned long *addr,
+ unsigned long size,
+ unsigned long offset);
+
+/**
+ * __set_bit - Set a bit in memory
+ * @nr: the bit to set
+ * @addr: the address to start counting from
+ *
+ * This function is non-atomic and may be reordered.
+ */
+static inline void __set_bit(int nr, volatile unsigned long *addr)
+{
+ unsigned long mask = BIT_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
+
+ *p |= mask;
+}
+
+/**
+ * __clear_bit - Clear a bit in memory
+ * @nr: the bit to clear
+ * @addr: the address to start counting from
+ *
+ * This function is non-atomic and may be reordered.
+ */
+static inline void __clear_bit(int nr, volatile unsigned long *addr)
+{
+ unsigned long mask = BIT_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
+
+ *p &= ~mask;
+}
+
+/**
+ * __change_bit - Toggle a bit in memory
+ * @nr: the bit to change
+ * @addr: the address to start counting from
+ *
+ * This function is non-atomic and may be reordered.
+ */
+static inline void __change_bit(int nr, volatile unsigned long *addr)
+{
+ unsigned long mask = BIT_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
+
+ *p ^= mask;
+}
+
+/**
+ * __test_and_set_bit - Set a bit and return its old value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is non-atomic and can be reordered.
+ */
+static inline int __test_and_set_bit(int nr, volatile unsigned long *addr)
+{
+ unsigned long mask = BIT_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
+ unsigned long old = *p;
+
+ *p = old | mask;
+ return (old & mask) != 0;
+}
+
+/**
+ * __test_and_clear_bit - Clear a bit and return its old value
+ * @nr: Bit to clear
+ * @addr: Address to count from
+ *
+ * This operation is non-atomic and can be reordered.
+ */
+static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr)
+{
+ unsigned long mask = BIT_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
+ unsigned long old = *p;
+
+ *p = old & ~mask;
+ return (old & mask) != 0;
+}
+
+/**
+ * __test_bit - Determine whether a bit is set
+ * @nr: bit number to test
+ * @addr: Address to start counting from
+ *
+ * This operation is non-atomic and can be reordered.
+ */
+static inline int __test_bit(int nr, const volatile unsigned long *addr)
+{
+ return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
+}
+
+#endif
diff --git a/roms/opensbi/include/sbi/sbi_console.h b/roms/opensbi/include/sbi/sbi_console.h
new file mode 100644
index 000000000..7d648f0b5
--- /dev/null
+++ b/roms/opensbi/include/sbi/sbi_console.h
@@ -0,0 +1,39 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#ifndef __SBI_CONSOLE_H__
+#define __SBI_CONSOLE_H__
+
+#include <sbi/sbi_types.h>
+
+#define __printf(a, b) __attribute__((format(printf, a, b)))
+
+bool sbi_isprintable(char ch);
+
+int sbi_getc(void);
+
+void sbi_putc(char ch);
+
+void sbi_puts(const char *str);
+
+void sbi_gets(char *s, int maxwidth, char endchar);
+
+int __printf(2, 3) sbi_sprintf(char *out, const char *format, ...);
+
+int __printf(3, 4) sbi_snprintf(char *out, u32 out_sz, const char *format, ...);
+
+int __printf(1, 2) sbi_printf(const char *format, ...);
+
+int __printf(1, 2) sbi_dprintf(const char *format, ...);
+
+struct sbi_scratch;
+
+int sbi_console_init(struct sbi_scratch *scratch);
+
+#endif
diff --git a/roms/opensbi/include/sbi/sbi_const.h b/roms/opensbi/include/sbi/sbi_const.h
new file mode 100644
index 000000000..37866546a
--- /dev/null
+++ b/roms/opensbi/include/sbi/sbi_const.h
@@ -0,0 +1,48 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#ifndef __SBI_CONST_H__
+#define __SBI_CONST_H__
+
+/*
+ * Some constant macros are used in both assembler and
+ * C code. Therefore we cannot annotate them always with
+ * 'UL' and other type specifiers unilaterally. We
+ * use the following macros to deal with this.
+ *
+ * Similarly, _AT() will cast an expression with a type in C, but
+ * leave it unchanged in asm.
+ */
+
+/* clang-format off */
+
+#ifdef __ASSEMBLY__
+#define _AC(X,Y) X
+#define _AT(T,X) X
+#else
+#define __AC(X,Y) (X##Y)
+#define _AC(X,Y) __AC(X,Y)
+#define _AT(T,X) ((T)(X))
+#endif
+
+#define _UL(x) (_AC(x, UL))
+#define _ULL(x) (_AC(x, ULL))
+
+#define _BITUL(x) (_UL(1) << (x))
+#define _BITULL(x) (_ULL(1) << (x))
+
+#define UL(x) (_UL(x))
+#define ULL(x) (_ULL(x))
+
+#define __STR(s) #s
+#define STRINGIFY(s) __STR(s)
+
+/* clang-format on */
+
+#endif
diff --git a/roms/opensbi/include/sbi/sbi_csr_detect.h b/roms/opensbi/include/sbi/sbi_csr_detect.h
new file mode 100644
index 000000000..f29488845
--- /dev/null
+++ b/roms/opensbi/include/sbi/sbi_csr_detect.h
@@ -0,0 +1,50 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2020 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Atish Patra <atish.patra@wdc.com>
+ */
+
+#ifndef __SBI_CSR_DETECT__H
+#define __SBI_CSR_DETECT__H
+
+#include <sbi/riscv_encoding.h>
+#include <sbi/sbi_hart.h>
+
+#define csr_read_allowed(csr_num, trap) \
+ ({ \
+ register ulong tinfo asm("a3") = (ulong)trap; \
+ register ulong ttmp asm("a4"); \
+ register ulong mtvec = sbi_hart_expected_trap_addr(); \
+ register ulong ret = 0; \
+ asm volatile( \
+ "add %[ttmp], %[tinfo], zero\n" \
+ "csrrw %[mtvec], " STR(CSR_MTVEC) ", %[mtvec]\n" \
+ "csrr %[ret], %[csr]\n" \
+ "csrw " STR(CSR_MTVEC) ", %[mtvec]" \
+ : [mtvec] "+&r"(mtvec), [tinfo] "+&r"(tinfo), \
+ [ttmp] "+&r"(ttmp), [ret] "=&r" (ret) \
+ : [csr] "i" (csr_num) \
+ : "memory"); \
+ ret; \
+ }) \
+
+#define csr_write_allowed(csr_num, trap, value) \
+ ({ \
+ register ulong tinfo asm("a3") = (ulong)trap; \
+ register ulong ttmp asm("a4"); \
+ register ulong mtvec = sbi_hart_expected_trap_addr(); \
+ asm volatile( \
+ "add %[ttmp], %[tinfo], zero\n" \
+ "csrrw %[mtvec], " STR(CSR_MTVEC) ", %[mtvec]\n" \
+ "csrw %[csr], %[val]\n" \
+ "csrw " STR(CSR_MTVEC) ", %[mtvec]" \
+ : [mtvec] "+&r"(mtvec), \
+ [tinfo] "+&r"(tinfo), [ttmp] "+&r"(ttmp) \
+ : [csr] "i" (csr_num), [val] "r" (value) \
+ : "memory"); \
+ }) \
+
+#endif
diff --git a/roms/opensbi/include/sbi/sbi_domain.h b/roms/opensbi/include/sbi/sbi_domain.h
new file mode 100644
index 000000000..1f8b942c4
--- /dev/null
+++ b/roms/opensbi/include/sbi/sbi_domain.h
@@ -0,0 +1,165 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2020 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#ifndef __SBI_DOMAIN_H__
+#define __SBI_DOMAIN_H__
+
+#include <sbi/sbi_types.h>
+#include <sbi/sbi_hartmask.h>
+
+struct sbi_scratch;
+
+/** Domain access types */
+enum sbi_domain_access {
+ SBI_DOMAIN_READ = (1UL << 0),
+ SBI_DOMAIN_WRITE = (1UL << 1),
+ SBI_DOMAIN_EXECUTE = (1UL << 2),
+ SBI_DOMAIN_MMIO = (1UL << 3)
+};
+
+/** Representation of OpenSBI domain memory region */
+struct sbi_domain_memregion {
+ /**
+ * Size of memory region as power of 2
+ * It has to be minimum 3 and maximum __riscv_xlen
+ */
+ unsigned long order;
+ /**
+ * Base address of memory region
+ * It must be 2^order aligned address
+ */
+ unsigned long base;
+ /** Flags representing memory region attributes */
+#define SBI_DOMAIN_MEMREGION_READABLE (1UL << 0)
+#define SBI_DOMAIN_MEMREGION_WRITEABLE (1UL << 1)
+#define SBI_DOMAIN_MEMREGION_EXECUTABLE (1UL << 2)
+#define SBI_DOMAIN_MEMREGION_MMODE (1UL << 3)
+#define SBI_DOMAIN_MEMREGION_ACCESS_MASK (0xfUL)
+
+#define SBI_DOMAIN_MEMREGION_MMIO (1UL << 31)
+ unsigned long flags;
+};
+
+/** Maximum number of domains */
+#define SBI_DOMAIN_MAX_INDEX 32
+
+/** Representation of OpenSBI domain */
+struct sbi_domain {
+ /**
+ * Logical index of this domain
+ * Note: This set by sbi_domain_finalize() in the coldboot path
+ */
+ u32 index;
+ /**
+ * HARTs assigned to this domain
+ * Note: This set by sbi_domain_init() and sbi_domain_finalize()
+ * in the coldboot path
+ */
+ struct sbi_hartmask assigned_harts;
+ /** Name of this domain */
+ char name[64];
+ /** Possible HARTs in this domain */
+ const struct sbi_hartmask *possible_harts;
+ /** Array of memory regions terminated by a region with order zero */
+ struct sbi_domain_memregion *regions;
+ /** HART id of the HART booting this domain */
+ u32 boot_hartid;
+ /** Arg1 (or 'a1' register) of next booting stage for this domain */
+ unsigned long next_arg1;
+ /** Address of next booting stage for this domain */
+ unsigned long next_addr;
+ /** Privilege mode of next booting stage for this domain */
+ unsigned long next_mode;
+ /** Is domain allowed to reset the system */
+ bool system_reset_allowed;
+};
+
+/** HART id to domain table */
+extern struct sbi_domain *hartid_to_domain_table[];
+
+/** Get pointer to sbi_domain from HART id */
+#define sbi_hartid_to_domain(__hartid) \
+ hartid_to_domain_table[__hartid]
+
+/** Get pointer to sbi_domain for current HART */
+#define sbi_domain_thishart_ptr() \
+ sbi_hartid_to_domain(current_hartid())
+
+/** Index to domain table */
+extern struct sbi_domain *domidx_to_domain_table[];
+
+/** Get pointer to sbi_domain from index */
+#define sbi_index_to_domain(__index) \
+ domidx_to_domain_table[__index]
+
+/** Iterate over each domain */
+#define sbi_domain_for_each(__i, __d) \
+ for ((__i) = 0; ((__d) = sbi_index_to_domain(__i)); (__i)++)
+
+/** Iterate over each memory region of a domain */
+#define sbi_domain_for_each_memregion(__d, __r) \
+ for ((__r) = (__d)->regions; (__r)->order; (__r)++)
+
+/**
+ * Check whether given HART is assigned to specified domain
+ * @param dom pointer to domain
+ * @param hartid the HART ID
+ * @return TRUE if HART is assigned to domain otherwise FALSE
+ */
+bool sbi_domain_is_assigned_hart(const struct sbi_domain *dom, u32 hartid);
+
+/**
+ * Get ulong assigned HART mask for given domain and HART base ID
+ * @param dom pointer to domain
+ * @param hbase the HART base ID
+ * @return ulong possible HART mask
+ * Note: the return ulong mask will be set to zero on failure.
+ */
+ulong sbi_domain_get_assigned_hartmask(const struct sbi_domain *dom,
+ ulong hbase);
+
+/** Initialize a domain memory region as firmware region */
+void sbi_domain_memregion_initfw(struct sbi_domain_memregion *reg);
+
+/**
+ * Check whether we can access specified address for given mode and
+ * memory region flags under a domain
+ * @param dom pointer to domain
+ * @param addr the address to be checked
+ * @param mode the privilege mode of access
+ * @param access_flags bitmask of domain access types (enum sbi_domain_access)
+ * @return TRUE if access allowed otherwise FALSE
+ */
+bool sbi_domain_check_addr(const struct sbi_domain *dom,
+ unsigned long addr, unsigned long mode,
+ unsigned long access_flags);
+
+/** Dump domain details on the console */
+void sbi_domain_dump(const struct sbi_domain *dom, const char *suffix);
+
+/** Dump all domain details on the console */
+void sbi_domain_dump_all(const char *suffix);
+
+/**
+ * Register a new domain
+ * @param dom pointer to domain
+ * @param assign_mask pointer to HART mask of HARTs assigned to the domain
+ *
+ * @return 0 on success and negative error code on failure
+ */
+int sbi_domain_register(struct sbi_domain *dom,
+ const struct sbi_hartmask *assign_mask);
+
+/** Finalize domain tables and startup non-root domains */
+int sbi_domain_finalize(struct sbi_scratch *scratch, u32 cold_hartid);
+
+/** Initialize domains */
+int sbi_domain_init(struct sbi_scratch *scratch, u32 cold_hartid);
+
+#endif
diff --git a/roms/opensbi/include/sbi/sbi_ecall.h b/roms/opensbi/include/sbi/sbi_ecall.h
new file mode 100644
index 000000000..d35708544
--- /dev/null
+++ b/roms/opensbi/include/sbi/sbi_ecall.h
@@ -0,0 +1,61 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#ifndef __SBI_ECALL_H__
+#define __SBI_ECALL_H__
+
+#include <sbi/sbi_types.h>
+#include <sbi/sbi_list.h>
+
+#define SBI_ECALL_VERSION_MAJOR 0
+#define SBI_ECALL_VERSION_MINOR 2
+#define SBI_OPENSBI_IMPID 1
+
+struct sbi_trap_regs;
+struct sbi_trap_info;
+
+struct sbi_ecall_extension {
+ struct sbi_dlist head;
+ unsigned long extid_start;
+ unsigned long extid_end;
+ int (* probe)(unsigned long extid, unsigned long *out_val);
+ int (* handle)(unsigned long extid, unsigned long funcid,
+ const struct sbi_trap_regs *regs,
+ unsigned long *out_val,
+ struct sbi_trap_info *out_trap);
+};
+
+extern struct sbi_ecall_extension ecall_base;
+extern struct sbi_ecall_extension ecall_legacy;
+extern struct sbi_ecall_extension ecall_time;
+extern struct sbi_ecall_extension ecall_rfence;
+extern struct sbi_ecall_extension ecall_ipi;
+extern struct sbi_ecall_extension ecall_vendor;
+extern struct sbi_ecall_extension ecall_hsm;
+extern struct sbi_ecall_extension ecall_srst;
+
+u16 sbi_ecall_version_major(void);
+
+u16 sbi_ecall_version_minor(void);
+
+unsigned long sbi_ecall_get_impid(void);
+
+void sbi_ecall_set_impid(unsigned long impid);
+
+struct sbi_ecall_extension *sbi_ecall_find_extension(unsigned long extid);
+
+int sbi_ecall_register_extension(struct sbi_ecall_extension *ext);
+
+void sbi_ecall_unregister_extension(struct sbi_ecall_extension *ext);
+
+int sbi_ecall_handler(struct sbi_trap_regs *regs);
+
+int sbi_ecall_init(void);
+
+#endif
diff --git a/roms/opensbi/include/sbi/sbi_ecall_interface.h b/roms/opensbi/include/sbi/sbi_ecall_interface.h
new file mode 100644
index 000000000..002c6f9cb
--- /dev/null
+++ b/roms/opensbi/include/sbi/sbi_ecall_interface.h
@@ -0,0 +1,98 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#ifndef __SBI_ECALL_INTERFACE_H__
+#define __SBI_ECALL_INTERFACE_H__
+
+/* clang-format off */
+
+/* SBI Extension IDs */
+#define SBI_EXT_0_1_SET_TIMER 0x0
+#define SBI_EXT_0_1_CONSOLE_PUTCHAR 0x1
+#define SBI_EXT_0_1_CONSOLE_GETCHAR 0x2
+#define SBI_EXT_0_1_CLEAR_IPI 0x3
+#define SBI_EXT_0_1_SEND_IPI 0x4
+#define SBI_EXT_0_1_REMOTE_FENCE_I 0x5
+#define SBI_EXT_0_1_REMOTE_SFENCE_VMA 0x6
+#define SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID 0x7
+#define SBI_EXT_0_1_SHUTDOWN 0x8
+#define SBI_EXT_BASE 0x10
+#define SBI_EXT_TIME 0x54494D45
+#define SBI_EXT_IPI 0x735049
+#define SBI_EXT_RFENCE 0x52464E43
+#define SBI_EXT_HSM 0x48534D
+#define SBI_EXT_SRST 0x53525354
+
+/* SBI function IDs for BASE extension*/
+#define SBI_EXT_BASE_GET_SPEC_VERSION 0x0
+#define SBI_EXT_BASE_GET_IMP_ID 0x1
+#define SBI_EXT_BASE_GET_IMP_VERSION 0x2
+#define SBI_EXT_BASE_PROBE_EXT 0x3
+#define SBI_EXT_BASE_GET_MVENDORID 0x4
+#define SBI_EXT_BASE_GET_MARCHID 0x5
+#define SBI_EXT_BASE_GET_MIMPID 0x6
+
+/* SBI function IDs for TIME extension*/
+#define SBI_EXT_TIME_SET_TIMER 0x0
+
+/* SBI function IDs for IPI extension*/
+#define SBI_EXT_IPI_SEND_IPI 0x0
+
+/* SBI function IDs for RFENCE extension*/
+#define SBI_EXT_RFENCE_REMOTE_FENCE_I 0x0
+#define SBI_EXT_RFENCE_REMOTE_SFENCE_VMA 0x1
+#define SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID 0x2
+#define SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA 0x3
+#define SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA_VMID 0x4
+#define SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA 0x5
+#define SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID 0x6
+
+/* SBI function IDs for HSM extension */
+#define SBI_EXT_HSM_HART_START 0x0
+#define SBI_EXT_HSM_HART_STOP 0x1
+#define SBI_EXT_HSM_HART_GET_STATUS 0x2
+
+#define SBI_HSM_HART_STATUS_STARTED 0x0
+#define SBI_HSM_HART_STATUS_STOPPED 0x1
+#define SBI_HSM_HART_STATUS_START_PENDING 0x2
+#define SBI_HSM_HART_STATUS_STOP_PENDING 0x3
+
+/* SBI function IDs for SRST extension */
+#define SBI_EXT_SRST_RESET 0x0
+
+#define SBI_SRST_RESET_TYPE_SHUTDOWN 0x0
+#define SBI_SRST_RESET_TYPE_COLD_REBOOT 0x1
+#define SBI_SRST_RESET_TYPE_WARM_REBOOT 0x2
+#define SBI_SRST_RESET_TYPE_LAST SBI_SRST_RESET_TYPE_WARM_REBOOT
+
+#define SBI_SRST_RESET_REASON_NONE 0x0
+#define SBI_SRST_RESET_REASON_SYSFAIL 0x1
+
+#define SBI_SPEC_VERSION_MAJOR_OFFSET 24
+#define SBI_SPEC_VERSION_MAJOR_MASK 0x7f
+#define SBI_SPEC_VERSION_MINOR_MASK 0xffffff
+#define SBI_EXT_VENDOR_START 0x09000000
+#define SBI_EXT_VENDOR_END 0x09FFFFFF
+#define SBI_EXT_FIRMWARE_START 0x0A000000
+#define SBI_EXT_FIRMWARE_END 0x0AFFFFFF
+
+/* SBI return error codes */
+#define SBI_SUCCESS 0
+#define SBI_ERR_FAILED -1
+#define SBI_ERR_NOT_SUPPORTED -2
+#define SBI_ERR_INVALID_PARAM -3
+#define SBI_ERR_DENIED -4
+#define SBI_ERR_INVALID_ADDRESS -5
+#define SBI_ERR_ALREADY_AVAILABLE -6
+
+#define SBI_LAST_ERR SBI_ERR_ALREADY_AVAILABLE
+
+/* clang-format on */
+
+#endif
diff --git a/roms/opensbi/include/sbi/sbi_emulate_csr.h b/roms/opensbi/include/sbi/sbi_emulate_csr.h
new file mode 100644
index 000000000..548056a11
--- /dev/null
+++ b/roms/opensbi/include/sbi/sbi_emulate_csr.h
@@ -0,0 +1,23 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#ifndef __SBI_EMULATE_CSR_H__
+#define __SBI_EMULATE_CSR_H__
+
+#include <sbi/sbi_types.h>
+
+struct sbi_trap_regs;
+
+int sbi_emulate_csr_read(int csr_num, struct sbi_trap_regs *regs,
+ ulong *csr_val);
+
+int sbi_emulate_csr_write(int csr_num, struct sbi_trap_regs *regs,
+ ulong csr_val);
+
+#endif
diff --git a/roms/opensbi/include/sbi/sbi_error.h b/roms/opensbi/include/sbi/sbi_error.h
new file mode 100644
index 000000000..3655d1220
--- /dev/null
+++ b/roms/opensbi/include/sbi/sbi_error.h
@@ -0,0 +1,38 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#ifndef __SBI_ERROR_H__
+#define __SBI_ERROR_H__
+
+#include <sbi/sbi_ecall_interface.h>
+
+/* clang-format off */
+
+#define SBI_OK 0
+#define SBI_EFAIL SBI_ERR_FAILED
+#define SBI_ENOTSUPP SBI_ERR_NOT_SUPPORTED
+#define SBI_EINVAL SBI_ERR_INVALID_PARAM
+#define SBI_EDENIED SBI_ERR_DENIED
+#define SBI_EINVALID_ADDR SBI_ERR_INVALID_ADDRESS
+#define SBI_EALREADY SBI_ERR_ALREADY_AVAILABLE
+
+#define SBI_ENODEV -1000
+#define SBI_ENOSYS -1001
+#define SBI_ETIMEDOUT -1002
+#define SBI_EIO -1003
+#define SBI_EILL -1004
+#define SBI_ENOSPC -1005
+#define SBI_ENOMEM -1006
+#define SBI_ETRAP -1007
+#define SBI_EUNKNOWN -1008
+#define SBI_ENOENT -1009
+
+/* clang-format on */
+
+#endif
diff --git a/roms/opensbi/include/sbi/sbi_fifo.h b/roms/opensbi/include/sbi/sbi_fifo.h
new file mode 100644
index 000000000..bc8f8f600
--- /dev/null
+++ b/roms/opensbi/include/sbi/sbi_fifo.h
@@ -0,0 +1,42 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Atish Patra<atish.patra@wdc.com>
+ *
+ */
+
+#ifndef __SBI_FIFO_H__
+#define __SBI_FIFO_H__
+
+#include <sbi/riscv_locks.h>
+#include <sbi/sbi_types.h>
+
+struct sbi_fifo {
+ void *queue;
+ spinlock_t qlock;
+ u16 entry_size;
+ u16 num_entries;
+ u16 avail;
+ u16 tail;
+};
+
+enum sbi_fifo_inplace_update_types {
+ SBI_FIFO_SKIP,
+ SBI_FIFO_UPDATED,
+ SBI_FIFO_UNCHANGED,
+};
+
+int sbi_fifo_dequeue(struct sbi_fifo *fifo, void *data);
+int sbi_fifo_enqueue(struct sbi_fifo *fifo, void *data);
+void sbi_fifo_init(struct sbi_fifo *fifo, void *queue_mem, u16 entries,
+ u16 entry_size);
+bool sbi_fifo_is_empty(struct sbi_fifo *fifo);
+bool sbi_fifo_is_full(struct sbi_fifo *fifo);
+int sbi_fifo_inplace_update(struct sbi_fifo *fifo, void *in,
+ int (*fptr)(void *in, void *data));
+u16 sbi_fifo_avail(struct sbi_fifo *fifo);
+
+#endif
diff --git a/roms/opensbi/include/sbi/sbi_hart.h b/roms/opensbi/include/sbi/sbi_hart.h
new file mode 100644
index 000000000..ec9e30f91
--- /dev/null
+++ b/roms/opensbi/include/sbi/sbi_hart.h
@@ -0,0 +1,56 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#ifndef __SBI_HART_H__
+#define __SBI_HART_H__
+
+#include <sbi/sbi_types.h>
+
+/** Possible feature flags of a hart */
+enum sbi_hart_features {
+ /** Hart has S-mode counter enable */
+ SBI_HART_HAS_SCOUNTEREN = (1 << 0),
+ /** Hart has M-mode counter enable */
+ SBI_HART_HAS_MCOUNTEREN = (1 << 1),
+ /** HART has timer csr implementation in hardware */
+ SBI_HART_HAS_TIME = (1 << 2),
+
+ /** Last index of Hart features*/
+ SBI_HART_HAS_LAST_FEATURE = SBI_HART_HAS_TIME,
+};
+
+struct sbi_scratch;
+
+int sbi_hart_init(struct sbi_scratch *scratch, bool cold_boot);
+
+extern void (*sbi_hart_expected_trap)(void);
+static inline ulong sbi_hart_expected_trap_addr(void)
+{
+ return (ulong)sbi_hart_expected_trap;
+}
+
+unsigned int sbi_hart_mhpm_count(struct sbi_scratch *scratch);
+void sbi_hart_delegation_dump(struct sbi_scratch *scratch,
+ const char *prefix, const char *suffix);
+unsigned int sbi_hart_pmp_count(struct sbi_scratch *scratch);
+unsigned long sbi_hart_pmp_granularity(struct sbi_scratch *scratch);
+unsigned int sbi_hart_pmp_addrbits(struct sbi_scratch *scratch);
+int sbi_hart_pmp_configure(struct sbi_scratch *scratch);
+bool sbi_hart_has_feature(struct sbi_scratch *scratch, unsigned long feature);
+void sbi_hart_get_features_str(struct sbi_scratch *scratch,
+ char *features_str, int nfstr);
+
+void __attribute__((noreturn)) sbi_hart_hang(void);
+
+void __attribute__((noreturn))
+sbi_hart_switch_mode(unsigned long arg0, unsigned long arg1,
+ unsigned long next_addr, unsigned long next_mode,
+ bool next_virt);
+
+#endif
diff --git a/roms/opensbi/include/sbi/sbi_hartmask.h b/roms/opensbi/include/sbi/sbi_hartmask.h
new file mode 100644
index 000000000..f1cef0c2a
--- /dev/null
+++ b/roms/opensbi/include/sbi/sbi_hartmask.h
@@ -0,0 +1,141 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2020 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#ifndef __SBI_HARTMASK_H__
+#define __SBI_HARTMASK_H__
+
+#include <sbi/sbi_bitmap.h>
+
+/**
+ * Maximum number of bits in a hartmask
+ *
+ * The hartmask is indexed using physical HART id so this define
+ * also represents the maximum number of HART ids generic OpenSBI
+ * can handle.
+ */
+#define SBI_HARTMASK_MAX_BITS 128
+
+/** Representation of hartmask */
+struct sbi_hartmask {
+ DECLARE_BITMAP(bits, SBI_HARTMASK_MAX_BITS);
+};
+
+/** Initialize hartmask to zero */
+#define SBI_HARTMASK_INIT(__m) \
+ bitmap_zero(((__m)->bits), SBI_HARTMASK_MAX_BITS)
+
+/** Initialize hartmask to zero except a particular HART id */
+#define SBI_HARTMASK_INIT_EXCEPT(__m, __h) \
+ bitmap_zero_except(((__m)->bits), (__h), SBI_HARTMASK_MAX_BITS)
+
+/**
+ * Get underlying bitmap of hartmask
+ * @param m the hartmask pointer
+ */
+#define sbi_hartmask_bits(__m) ((__m)->bits)
+
+/**
+ * Set a HART in hartmask
+ * @param h HART id to set
+ * @param m the hartmask pointer
+ */
+static inline void sbi_hartmask_set_hart(u32 h, struct sbi_hartmask *m)
+{
+ if (h < SBI_HARTMASK_MAX_BITS)
+ __set_bit(h, m->bits);
+}
+
+/**
+ * Clear a HART in hartmask
+ * @param h HART id to clear
+ * @param m the hartmask pointer
+ */
+static inline void sbi_hartmask_clear_hart(u32 h, struct sbi_hartmask *m)
+{
+ if (h < SBI_HARTMASK_MAX_BITS)
+ __clear_bit(h, m->bits);
+}
+
+/**
+ * Test a HART in hartmask
+ * @param h HART id to test
+ * @param m the hartmask pointer
+ */
+static inline int sbi_hartmask_test_hart(u32 h, const struct sbi_hartmask *m)
+{
+ if (h < SBI_HARTMASK_MAX_BITS)
+ return __test_bit(h, m->bits);
+ return 0;
+}
+
+/**
+ * Set all HARTs in a hartmask
+ * @param dstp the hartmask pointer
+ */
+static inline void sbi_hartmask_set_all(struct sbi_hartmask *dstp)
+{
+ bitmap_fill(sbi_hartmask_bits(dstp), SBI_HARTMASK_MAX_BITS);
+}
+
+/**
+ * Clear all HARTs in a hartmask
+ * @param dstp the hartmask pointer
+ */
+static inline void sbi_hartmask_clear_all(struct sbi_hartmask *dstp)
+{
+ bitmap_zero(sbi_hartmask_bits(dstp), SBI_HARTMASK_MAX_BITS);
+}
+
+/**
+ * *dstp = *src1p & *src2p
+ * @param dstp the hartmask result
+ * @param src1p the first input
+ * @param src2p the second input
+ */
+static inline void sbi_hartmask_and(struct sbi_hartmask *dstp,
+ const struct sbi_hartmask *src1p,
+ const struct sbi_hartmask *src2p)
+{
+ bitmap_and(sbi_hartmask_bits(dstp), sbi_hartmask_bits(src1p),
+ sbi_hartmask_bits(src2p), SBI_HARTMASK_MAX_BITS);
+}
+
+/**
+ * *dstp = *src1p | *src2p
+ * @param dstp the hartmask result
+ * @param src1p the first input
+ * @param src2p the second input
+ */
+static inline void sbi_hartmask_or(struct sbi_hartmask *dstp,
+ const struct sbi_hartmask *src1p,
+ const struct sbi_hartmask *src2p)
+{
+ bitmap_or(sbi_hartmask_bits(dstp), sbi_hartmask_bits(src1p),
+ sbi_hartmask_bits(src2p), SBI_HARTMASK_MAX_BITS);
+}
+
+/**
+ * *dstp = *src1p ^ *src2p
+ * @param dstp the hartmask result
+ * @param src1p the first input
+ * @param src2p the second input
+ */
+static inline void sbi_hartmask_xor(struct sbi_hartmask *dstp,
+ const struct sbi_hartmask *src1p,
+ const struct sbi_hartmask *src2p)
+{
+ bitmap_xor(sbi_hartmask_bits(dstp), sbi_hartmask_bits(src1p),
+ sbi_hartmask_bits(src2p), SBI_HARTMASK_MAX_BITS);
+}
+
+/** Iterate over each HART in hartmask */
+#define sbi_hartmask_for_each_hart(__h, __m) \
+ for_each_set_bit(__h, (__m)->bits, SBI_HARTMASK_MAX_BITS)
+
+#endif
diff --git a/roms/opensbi/include/sbi/sbi_hfence.h b/roms/opensbi/include/sbi/sbi_hfence.h
new file mode 100644
index 000000000..4420f2793
--- /dev/null
+++ b/roms/opensbi/include/sbi/sbi_hfence.h
@@ -0,0 +1,38 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Atish Patra <atish.patra@wdc.com>
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#ifndef __SBI_FENCE_H__
+#define __SBI_FENCE_H__
+
+/** Invalidate Stage2 TLBs for given VMID and guest physical address */
+void __sbi_hfence_gvma_vmid_gpa(unsigned long gpa, unsigned long vmid);
+
+/** Invalidate Stage2 TLBs for given VMID */
+void __sbi_hfence_gvma_vmid(unsigned long vmid);
+
+/** Invalidate Stage2 TLBs for given guest physical address */
+void __sbi_hfence_gvma_gpa(unsigned long gpa);
+
+/** Invalidate all possible Stage2 TLBs */
+void __sbi_hfence_gvma_all(void);
+
+/** Invalidate unified TLB entries for given asid and guest virtual address */
+void __sbi_hfence_vvma_asid_va(unsigned long va, unsigned long asid);
+
+/** Invalidate unified TLB entries for given ASID for a guest*/
+void __sbi_hfence_vvma_asid(unsigned long asid);
+
+/** Invalidate unified TLB entries for a given guest virtual address */
+void __sbi_hfence_vvma_va(unsigned long va);
+
+/** Invalidate all possible Stage2 TLBs */
+void __sbi_hfence_vvma_all(void);
+
+#endif
diff --git a/roms/opensbi/include/sbi/sbi_hsm.h b/roms/opensbi/include/sbi/sbi_hsm.h
new file mode 100644
index 000000000..482338309
--- /dev/null
+++ b/roms/opensbi/include/sbi/sbi_hsm.h
@@ -0,0 +1,38 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2020 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Atish Patra <atish.patra@wdc.com>
+ */
+
+#ifndef __SBI_HSM_H__
+#define __SBI_HSM_H__
+
+#include <sbi/sbi_types.h>
+
+/** Hart state values **/
+#define SBI_HART_STOPPED 0
+#define SBI_HART_STOPPING 1
+#define SBI_HART_STARTING 2
+#define SBI_HART_STARTED 3
+#define SBI_HART_UNKNOWN 4
+
+struct sbi_domain;
+struct sbi_scratch;
+
+int sbi_hsm_init(struct sbi_scratch *scratch, u32 hartid, bool cold_boot);
+void __noreturn sbi_hsm_exit(struct sbi_scratch *scratch);
+
+int sbi_hsm_hart_start(struct sbi_scratch *scratch,
+ const struct sbi_domain *dom,
+ u32 hartid, ulong saddr, ulong smode, ulong priv);
+int sbi_hsm_hart_stop(struct sbi_scratch *scratch, bool exitnow);
+int sbi_hsm_hart_get_state(const struct sbi_domain *dom, u32 hartid);
+int sbi_hsm_hart_state_to_status(int state);
+int sbi_hsm_hart_started_mask(const struct sbi_domain *dom,
+ ulong hbase, ulong *out_hmask);
+void sbi_hsm_prepare_next_jump(struct sbi_scratch *scratch, u32 hartid);
+
+#endif
diff --git a/roms/opensbi/include/sbi/sbi_illegal_insn.h b/roms/opensbi/include/sbi/sbi_illegal_insn.h
new file mode 100644
index 000000000..0397935e2
--- /dev/null
+++ b/roms/opensbi/include/sbi/sbi_illegal_insn.h
@@ -0,0 +1,19 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#ifndef __SBI_ILLEGAl_INSN_H__
+#define __SBI_ILLEGAl_INSN_H__
+
+#include <sbi/sbi_types.h>
+
+struct sbi_trap_regs;
+
+int sbi_illegal_insn_handler(ulong insn, struct sbi_trap_regs *regs);
+
+#endif
diff --git a/roms/opensbi/include/sbi/sbi_init.h b/roms/opensbi/include/sbi/sbi_init.h
new file mode 100644
index 000000000..74eb1c075
--- /dev/null
+++ b/roms/opensbi/include/sbi/sbi_init.h
@@ -0,0 +1,23 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#ifndef __SBI_INIT_H__
+#define __SBI_INIT_H__
+
+#include <sbi/sbi_types.h>
+
+struct sbi_scratch;
+
+void __noreturn sbi_init(struct sbi_scratch *scratch);
+
+unsigned long sbi_init_count(u32 hartid);
+
+void __noreturn sbi_exit(struct sbi_scratch *scratch);
+
+#endif
diff --git a/roms/opensbi/include/sbi/sbi_ipi.h b/roms/opensbi/include/sbi/sbi_ipi.h
new file mode 100644
index 000000000..617872c1b
--- /dev/null
+++ b/roms/opensbi/include/sbi/sbi_ipi.h
@@ -0,0 +1,70 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#ifndef __SBI_IPI_H__
+#define __SBI_IPI_H__
+
+#include <sbi/sbi_types.h>
+
+/* clang-format off */
+
+#define SBI_IPI_EVENT_MAX __riscv_xlen
+
+/* clang-format on */
+
+struct sbi_scratch;
+
+/** IPI event operations or callbacks */
+struct sbi_ipi_event_ops {
+ /** Name of the IPI event operations */
+ char name[32];
+
+ /**
+ * Update callback to save/enqueue data for remote HART
+ * Note: This is an optional callback and it is called just before
+ * triggering IPI to remote HART.
+ */
+ int (* update)(struct sbi_scratch *scratch,
+ struct sbi_scratch *remote_scratch,
+ u32 remote_hartid, void *data);
+
+ /**
+ * Sync callback to wait for remote HART
+ * Note: This is an optional callback and it is called just after
+ * triggering IPI to remote HART.
+ */
+ void (* sync)(struct sbi_scratch *scratch);
+
+ /**
+ * Process callback to handle IPI event
+ * Note: This is a mandatory callback and it is called on the
+ * remote HART after IPI is triggered.
+ */
+ void (* process)(struct sbi_scratch *scratch);
+};
+
+int sbi_ipi_send_many(ulong hmask, ulong hbase, u32 event, void *data);
+
+int sbi_ipi_event_create(const struct sbi_ipi_event_ops *ops);
+
+void sbi_ipi_event_destroy(u32 event);
+
+int sbi_ipi_send_smode(ulong hmask, ulong hbase);
+
+void sbi_ipi_clear_smode(void);
+
+int sbi_ipi_send_halt(ulong hmask, ulong hbase);
+
+void sbi_ipi_process(void);
+
+int sbi_ipi_init(struct sbi_scratch *scratch, bool cold_boot);
+
+void sbi_ipi_exit(struct sbi_scratch *scratch);
+
+#endif
diff --git a/roms/opensbi/include/sbi/sbi_list.h b/roms/opensbi/include/sbi/sbi_list.h
new file mode 100644
index 000000000..1174ad274
--- /dev/null
+++ b/roms/opensbi/include/sbi/sbi_list.h
@@ -0,0 +1,152 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Simple doubly-linked list library.
+ *
+ * Adapted from Xvisor source file libs/include/libs/list.h
+ *
+ * Copyright (c) 2020 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#ifndef __SBI_LIST_H__
+#define __SBI_LIST_H__
+
+#include <sbi/sbi_types.h>
+
+#define SBI_LIST_POISON_PREV 0xDEADBEEF
+#define SBI_LIST_POISON_NEXT 0xFADEBABE
+
+struct sbi_dlist {
+ struct sbi_dlist *next, *prev;
+};
+
+#define SBI_LIST_HEAD_INIT(__lname) { &(__lname), &(__lname) }
+
+#define SBI_LIST_HEAD(_lname) \
+struct sbi_dlist _lname = SBI_LIST_HEAD_INIT(_lname)
+
+#define SBI_INIT_LIST_HEAD(ptr) \
+do { \
+ (ptr)->next = ptr; (ptr)->prev = ptr; \
+} while (0);
+
+static inline void __sbi_list_add(struct sbi_dlist *new,
+ struct sbi_dlist *prev,
+ struct sbi_dlist *next)
+{
+ new->prev = prev;
+ new->next = next;
+ prev->next = new;
+ next->prev = new;
+}
+
+/**
+ * Adds the new node after the given head.
+ * @param new New node that needs to be added to list.
+ * @param head List head after which the "new" node should be added.
+ * Note: the new node is added after the head.
+ */
+static inline void sbi_list_add(struct sbi_dlist *new, struct sbi_dlist *head)
+{
+ __sbi_list_add(new, head, head->next);
+}
+
+/**
+ * Adds a node at the tail where tnode points to tail node.
+ * @param new The new node to be added before tail.
+ * @param tnode The current tail node.
+ * Note: the new node is added before tail node.
+ */
+static inline void sbi_list_add_tail(struct sbi_dlist *new,
+ struct sbi_dlist *tnode)
+{
+ __sbi_list_add(new, tnode->prev, tnode);
+}
+
+static inline void __sbi_list_del(struct sbi_dlist *prev,
+ struct sbi_dlist *next)
+{
+ prev->next = next;
+ next->prev = prev;
+}
+
+static inline void __sbi_list_del_entry(struct sbi_dlist *entry)
+{
+ __sbi_list_del(entry->prev, entry->next);
+}
+
+/**
+ * Deletes a given entry from list.
+ * @param node Node to be deleted.
+ */
+static inline void sbi_list_del(struct sbi_dlist *entry)
+{
+ __sbi_list_del(entry->prev, entry->next);
+ entry->next = (void *)SBI_LIST_POISON_NEXT;
+ entry->prev = (void *)SBI_LIST_POISON_PREV;
+}
+
+/**
+ * Deletes entry from list and reinitialize it.
+ * @param entry the element to delete from the list.
+ */
+static inline void sbi_list_del_init(struct sbi_dlist *entry)
+{
+ __sbi_list_del_entry(entry);
+ SBI_INIT_LIST_HEAD(entry);
+}
+
+/**
+ * Get the struct for this entry
+ * @param ptr the &struct list_head pointer.
+ * @param type the type of the struct this is embedded in.
+ * @param member the name of the list_struct within the struct.
+ */
+#define sbi_list_entry(ptr, type, member) \
+ container_of(ptr, type, member)
+
+/**
+ * Get the first element from a list
+ * @param ptr the list head to take the element from.
+ * @param type the type of the struct this is embedded in.
+ * @param member the name of the list_struct within the struct.
+ *
+ * Note: that list is expected to be not empty.
+ */
+#define sbi_list_first_entry(ptr, type, member) \
+ sbi_list_entry((ptr)->next, type, member)
+
+/**
+ * Get the last element from a list
+ * @param ptr the list head to take the element from.
+ * @param type the type of the struct this is embedded in.
+ * @param member the name of the list_head within the struct.
+ *
+ * Note: that list is expected to be not empty.
+ */
+#define sbi_list_last_entry(ptr, type, member) \
+ sbi_list_entry((ptr)->prev, type, member)
+
+/**
+ * Iterate over a list
+ * @param pos the &struct list_head to use as a loop cursor.
+ * @param head the head for your list.
+ */
+#define sbi_list_for_each(pos, head) \
+ for (pos = (head)->next; pos != (head); pos = pos->next)
+
+/**
+ * Iterate over list of given type
+ * @param pos the type * to use as a loop cursor.
+ * @param head the head for your list.
+ * @param member the name of the list_struct within the struct.
+ */
+#define sbi_list_for_each_entry(pos, head, member) \
+ for (pos = sbi_list_entry((head)->next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = sbi_list_entry(pos->member.next, typeof(*pos), member))
+
+#endif
diff --git a/roms/opensbi/include/sbi/sbi_math.h b/roms/opensbi/include/sbi/sbi_math.h
new file mode 100644
index 000000000..564fd585c
--- /dev/null
+++ b/roms/opensbi/include/sbi/sbi_math.h
@@ -0,0 +1,15 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2020 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Atish Patra <atish.patra@wdc.com>
+ */
+
+#ifndef __SBI_MATH_H__
+#define __SBI_MATH_H__
+
+unsigned long log2roundup(unsigned long x);
+
+#endif
diff --git a/roms/opensbi/include/sbi/sbi_misaligned_ldst.h b/roms/opensbi/include/sbi/sbi_misaligned_ldst.h
new file mode 100644
index 000000000..ab27eb422
--- /dev/null
+++ b/roms/opensbi/include/sbi/sbi_misaligned_ldst.h
@@ -0,0 +1,23 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#ifndef __SBI_MISALIGNED_LDST_H__
+#define __SBI_MISALIGNED_LDST_H__
+
+#include <sbi/sbi_types.h>
+
+struct sbi_trap_regs;
+
+int sbi_misaligned_load_handler(ulong addr, ulong tval2, ulong tinst,
+ struct sbi_trap_regs *regs);
+
+int sbi_misaligned_store_handler(ulong addr, ulong tval2, ulong tinst,
+ struct sbi_trap_regs *regs);
+
+#endif
diff --git a/roms/opensbi/include/sbi/sbi_platform.h b/roms/opensbi/include/sbi/sbi_platform.h
new file mode 100644
index 000000000..cc7e3ff99
--- /dev/null
+++ b/roms/opensbi/include/sbi/sbi_platform.h
@@ -0,0 +1,757 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#ifndef __SBI_PLATFORM_H__
+#define __SBI_PLATFORM_H__
+
+/**
+ * OpenSBI 32-bit platform version with:
+ * 1. upper 16-bits as major number
+ * 2. lower 16-bits as minor number
+ */
+#define SBI_PLATFORM_VERSION(Major, Minor) ((Major << 16) | Minor)
+
+/** Offset of opensbi_version in struct sbi_platform */
+#define SBI_PLATFORM_OPENSBI_VERSION_OFFSET (0x00)
+/** Offset of platform_version in struct sbi_platform */
+#define SBI_PLATFORM_VERSION_OFFSET (0x04)
+/** Offset of name in struct sbi_platform */
+#define SBI_PLATFORM_NAME_OFFSET (0x08)
+/** Offset of features in struct sbi_platform */
+#define SBI_PLATFORM_FEATURES_OFFSET (0x48)
+/** Offset of hart_count in struct sbi_platform */
+#define SBI_PLATFORM_HART_COUNT_OFFSET (0x50)
+/** Offset of hart_stack_size in struct sbi_platform */
+#define SBI_PLATFORM_HART_STACK_SIZE_OFFSET (0x54)
+/** Offset of platform_ops_addr in struct sbi_platform */
+#define SBI_PLATFORM_OPS_OFFSET (0x58)
+/** Offset of firmware_context in struct sbi_platform */
+#define SBI_PLATFORM_FIRMWARE_CONTEXT_OFFSET (0x58 + __SIZEOF_POINTER__)
+/** Offset of hart_index2id in struct sbi_platform */
+#define SBI_PLATFORM_HART_INDEX2ID_OFFSET (0x58 + (__SIZEOF_POINTER__ * 2))
+
+#define SBI_PLATFORM_TLB_RANGE_FLUSH_LIMIT_DEFAULT (1UL << 12)
+
+#ifndef __ASSEMBLY__
+
+#include <sbi/sbi_ecall_interface.h>
+#include <sbi/sbi_error.h>
+#include <sbi/sbi_scratch.h>
+#include <sbi/sbi_version.h>
+
+struct sbi_domain_memregion;
+struct sbi_trap_info;
+struct sbi_trap_regs;
+
+/** Possible feature flags of a platform */
+enum sbi_platform_features {
+ /** Platform has timer value */
+ SBI_PLATFORM_HAS_TIMER_VALUE = (1 << 0),
+ /** Platform has HART hotplug support */
+ SBI_PLATFORM_HAS_HART_HOTPLUG = (1 << 1),
+ /** Platform has fault delegation support */
+ SBI_PLATFORM_HAS_MFAULTS_DELEGATION = (1 << 2),
+ /** Platform has custom secondary hart booting support */
+ SBI_PLATFORM_HAS_HART_SECONDARY_BOOT = (1 << 3),
+
+ /** Last index of Platform features*/
+ SBI_PLATFORM_HAS_LAST_FEATURE = SBI_PLATFORM_HAS_HART_SECONDARY_BOOT,
+};
+
+/** Default feature set for a platform */
+#define SBI_PLATFORM_DEFAULT_FEATURES \
+ (SBI_PLATFORM_HAS_TIMER_VALUE | SBI_PLATFORM_HAS_MFAULTS_DELEGATION)
+
+/** Platform functions */
+struct sbi_platform_operations {
+ /** Platform early initialization */
+ int (*early_init)(bool cold_boot);
+ /** Platform final initialization */
+ int (*final_init)(bool cold_boot);
+
+ /** Platform early exit */
+ void (*early_exit)(void);
+ /** Platform final exit */
+ void (*final_exit)(void);
+
+ /**
+ * For platforms that do not implement misa, non-standard
+ * methods are needed to determine cpu extension.
+ */
+ int (*misa_check_extension)(char ext);
+
+ /**
+ * For platforms that do not implement misa, non-standard
+ * methods are needed to get MXL field of misa.
+ */
+ int (*misa_get_xlen)(void);
+
+ /** Get platform specific root domain memory regions */
+ struct sbi_domain_memregion *(*domains_root_regions)(void);
+ /** Initialize (or populate) domains for the platform */
+ int (*domains_init)(void);
+
+ /** Write a character to the platform console output */
+ void (*console_putc)(char ch);
+ /** Read a character from the platform console input */
+ int (*console_getc)(void);
+ /** Initialize the platform console */
+ int (*console_init)(void);
+
+ /** Initialize the platform interrupt controller for current HART */
+ int (*irqchip_init)(bool cold_boot);
+ /** Exit the platform interrupt controller for current HART */
+ void (*irqchip_exit)(void);
+
+ /** Send IPI to a target HART */
+ void (*ipi_send)(u32 target_hart);
+ /** Clear IPI for a target HART */
+ void (*ipi_clear)(u32 target_hart);
+ /** Initialize IPI for current HART */
+ int (*ipi_init)(bool cold_boot);
+ /** Exit IPI for current HART */
+ void (*ipi_exit)(void);
+
+ /** Get tlb flush limit value **/
+ u64 (*get_tlbr_flush_limit)(void);
+
+ /** Get platform timer value */
+ u64 (*timer_value)(void);
+ /** Start platform timer event for current HART */
+ void (*timer_event_start)(u64 next_event);
+ /** Stop platform timer event for current HART */
+ void (*timer_event_stop)(void);
+ /** Initialize platform timer for current HART */
+ int (*timer_init)(bool cold_boot);
+ /** Exit platform timer for current HART */
+ void (*timer_exit)(void);
+
+ /** Bringup the given hart */
+ int (*hart_start)(u32 hartid, ulong saddr);
+ /**
+ * Stop the current hart from running. This call doesn't expect to
+ * return if success.
+ */
+ int (*hart_stop)(void);
+
+ /* Check whether reset type and reason supported by the platform */
+ int (*system_reset_check)(u32 reset_type, u32 reset_reason);
+ /** Reset the platform */
+ void (*system_reset)(u32 reset_type, u32 reset_reason);
+
+ /** platform specific SBI extension implementation probe function */
+ int (*vendor_ext_check)(long extid);
+ /** platform specific SBI extension implementation provider */
+ int (*vendor_ext_provider)(long extid, long funcid,
+ const struct sbi_trap_regs *regs,
+ unsigned long *out_value,
+ struct sbi_trap_info *out_trap);
+};
+
+/** Platform default per-HART stack size for exception/interrupt handling */
+#define SBI_PLATFORM_DEFAULT_HART_STACK_SIZE 8192
+
+/** Representation of a platform */
+struct sbi_platform {
+ /**
+ * OpenSBI version this sbi_platform is based on.
+ * It's a 32-bit value where upper 16-bits are major number
+ * and lower 16-bits are minor number
+ */
+ u32 opensbi_version;
+ /**
+ * OpenSBI platform version released by vendor.
+ * It's a 32-bit value where upper 16-bits are major number
+ * and lower 16-bits are minor number
+ */
+ u32 platform_version;
+ /** Name of the platform */
+ char name[64];
+ /** Supported features */
+ u64 features;
+ /** Total number of HARTs */
+ u32 hart_count;
+ /** Per-HART stack size for exception/interrupt handling */
+ u32 hart_stack_size;
+ /** Pointer to sbi platform operations */
+ unsigned long platform_ops_addr;
+ /** Pointer to system firmware specific context */
+ unsigned long firmware_context;
+ /**
+ * HART index to HART id table
+ *
+ * For used HART index <abc>:
+ * hart_index2id[<abc>] = some HART id
+ * For unused HART index <abc>:
+ * hart_index2id[<abc>] = -1U
+ *
+ * If hart_index2id == NULL then we assume identity mapping
+ * hart_index2id[<abc>] = <abc>
+ *
+ * We have only two restrictions:
+ * 1. HART index < sbi_platform hart_count
+ * 2. HART id < SBI_HARTMASK_MAX_BITS
+ */
+ const u32 *hart_index2id;
+};
+
+/** Get pointer to sbi_platform for sbi_scratch pointer */
+#define sbi_platform_ptr(__s) \
+ ((const struct sbi_platform *)((__s)->platform_addr))
+/** Get pointer to sbi_platform for current HART */
+#define sbi_platform_thishart_ptr() ((const struct sbi_platform *) \
+ (sbi_scratch_thishart_ptr()->platform_addr))
+/** Get pointer to platform_ops_addr from platform pointer **/
+#define sbi_platform_ops(__p) \
+ ((const struct sbi_platform_operations *)(__p)->platform_ops_addr)
+
+/** Check whether the platform supports timer value */
+#define sbi_platform_has_timer_value(__p) \
+ ((__p)->features & SBI_PLATFORM_HAS_TIMER_VALUE)
+/** Check whether the platform supports HART hotplug */
+#define sbi_platform_has_hart_hotplug(__p) \
+ ((__p)->features & SBI_PLATFORM_HAS_HART_HOTPLUG)
+/** Check whether the platform supports fault delegation */
+#define sbi_platform_has_mfaults_delegation(__p) \
+ ((__p)->features & SBI_PLATFORM_HAS_MFAULTS_DELEGATION)
+/** Check whether the platform supports custom secondary hart booting support */
+#define sbi_platform_has_hart_secondary_boot(__p) \
+ ((__p)->features & SBI_PLATFORM_HAS_HART_SECONDARY_BOOT)
+
+/**
+ * Get HART index for the given HART
+ *
+ * @param plat pointer to struct sbi_platform
+ * @param hartid HART ID
+ *
+ * @return 0 <= value < hart_count for valid HART otherwise -1U
+ */
+u32 sbi_platform_hart_index(const struct sbi_platform *plat, u32 hartid);
+
+/**
+ * Get the platform features in string format
+ *
+ * @param plat pointer to struct sbi_platform
+ * @param features_str pointer to a char array where the features string will be
+ * updated
+ * @param nfstr length of the features_str. The feature string will be truncated
+ * if nfstr is not long enough.
+ */
+void sbi_platform_get_features_str(const struct sbi_platform *plat,
+ char *features_str, int nfstr);
+
+/**
+ * Get name of the platform
+ *
+ * @param plat pointer to struct sbi_platform
+ *
+ * @return pointer to platform name on success and "Unknown" on failure
+ */
+static inline const char *sbi_platform_name(const struct sbi_platform *plat)
+{
+ if (plat)
+ return plat->name;
+ return "Unknown";
+}
+
+/**
+ * Get the platform features
+ *
+ * @param plat pointer to struct sbi_platform
+ *
+ * @return the features value currently set for the given platform
+ */
+static inline unsigned long sbi_platform_get_features(
+ const struct sbi_platform *plat)
+{
+ if (plat)
+ return plat->features;
+ return 0;
+}
+
+/**
+ * Get platform specific tlb range flush maximum value. Any request with size
+ * higher than this is upgraded to a full flush.
+ *
+ * @param plat pointer to struct sbi_platform
+ *
+ * @return tlb range flush limit value. Returns a default (page size) if not
+ * defined by platform.
+ */
+static inline u64 sbi_platform_tlbr_flush_limit(const struct sbi_platform *plat)
+{
+ if (plat && sbi_platform_ops(plat)->get_tlbr_flush_limit)
+ return sbi_platform_ops(plat)->get_tlbr_flush_limit();
+ return SBI_PLATFORM_TLB_RANGE_FLUSH_LIMIT_DEFAULT;
+}
+
+/**
+ * Get total number of HARTs supported by the platform
+ *
+ * @param plat pointer to struct sbi_platform
+ *
+ * @return total number of HARTs
+ */
+static inline u32 sbi_platform_hart_count(const struct sbi_platform *plat)
+{
+ if (plat)
+ return plat->hart_count;
+ return 0;
+}
+
+/**
+ * Get per-HART stack size for exception/interrupt handling
+ *
+ * @param plat pointer to struct sbi_platform
+ *
+ * @return stack size in bytes
+ */
+static inline u32 sbi_platform_hart_stack_size(const struct sbi_platform *plat)
+{
+ if (plat)
+ return plat->hart_stack_size;
+ return 0;
+}
+
+/**
+ * Check whether given HART is invalid
+ *
+ * @param plat pointer to struct sbi_platform
+ * @param hartid HART ID
+ *
+ * @return TRUE if HART is invalid and FALSE otherwise
+ */
+static inline bool sbi_platform_hart_invalid(const struct sbi_platform *plat,
+ u32 hartid)
+{
+ if (!plat)
+ return TRUE;
+ if (plat->hart_count <= sbi_platform_hart_index(plat, hartid))
+ return TRUE;
+ return FALSE;
+}
+
+/**
+ * Bringup a given hart from previous stage. Platform should implement this
+ * operation if they support a custom mechanism to start a hart. Otherwise,
+ * a generic WFI based approach will be used to start/stop a hart in OpenSBI.
+ *
+ * @param plat pointer to struct sbi_platform
+ * @param hartid HART id
+ * @param saddr M-mode start physical address for the HART
+ *
+ * @return 0 if sucessful and negative error code on failure
+ */
+static inline int sbi_platform_hart_start(const struct sbi_platform *plat,
+ u32 hartid, ulong saddr)
+{
+ if (plat && sbi_platform_ops(plat)->hart_start)
+ return sbi_platform_ops(plat)->hart_start(hartid, saddr);
+ return SBI_ENOTSUPP;
+}
+
+/**
+ * Stop the current hart in OpenSBI.
+ *
+ * @param plat pointer to struct sbi_platform
+ *
+ * @return Negative error code on failure. It doesn't return on success.
+ */
+static inline int sbi_platform_hart_stop(const struct sbi_platform *plat)
+{
+ if (plat && sbi_platform_ops(plat)->hart_stop)
+ return sbi_platform_ops(plat)->hart_stop();
+ return SBI_ENOTSUPP;
+}
+
+/**
+ * Early initialization for current HART
+ *
+ * @param plat pointer to struct sbi_platform
+ * @param cold_boot whether cold boot (TRUE) or warm_boot (FALSE)
+ *
+ * @return 0 on success and negative error code on failure
+ */
+static inline int sbi_platform_early_init(const struct sbi_platform *plat,
+ bool cold_boot)
+{
+ if (plat && sbi_platform_ops(plat)->early_init)
+ return sbi_platform_ops(plat)->early_init(cold_boot);
+ return 0;
+}
+
+/**
+ * Final initialization for current HART
+ *
+ * @param plat pointer to struct sbi_platform
+ * @param cold_boot whether cold boot (TRUE) or warm_boot (FALSE)
+ *
+ * @return 0 on success and negative error code on failure
+ */
+static inline int sbi_platform_final_init(const struct sbi_platform *plat,
+ bool cold_boot)
+{
+ if (plat && sbi_platform_ops(plat)->final_init)
+ return sbi_platform_ops(plat)->final_init(cold_boot);
+ return 0;
+}
+
+/**
+ * Early exit for current HART
+ *
+ * @param plat pointer to struct sbi_platform
+ */
+static inline void sbi_platform_early_exit(const struct sbi_platform *plat)
+{
+ if (plat && sbi_platform_ops(plat)->early_exit)
+ sbi_platform_ops(plat)->early_exit();
+}
+
+/**
+ * Final exit for current HART
+ *
+ * @param plat pointer to struct sbi_platform
+ */
+static inline void sbi_platform_final_exit(const struct sbi_platform *plat)
+{
+ if (plat && sbi_platform_ops(plat)->final_exit)
+ sbi_platform_ops(plat)->final_exit();
+}
+
+/**
+ * Check CPU extension in MISA
+ *
+ * @param plat pointer to struct sbi_platform
+ * @param ext shorthand letter for CPU extensions
+ *
+ * @return zero for not-supported and non-zero for supported
+ */
+static inline int sbi_platform_misa_extension(const struct sbi_platform *plat,
+ char ext)
+{
+ if (plat && sbi_platform_ops(plat)->misa_check_extension)
+ return sbi_platform_ops(plat)->misa_check_extension(ext);
+ return 0;
+}
+
+/**
+ * Get MXL field of MISA
+ *
+ * @param plat pointer to struct sbi_platform
+ *
+ * @return 1/2/3 on success and error code on failure
+ */
+static inline int sbi_platform_misa_xlen(const struct sbi_platform *plat)
+{
+ if (plat && sbi_platform_ops(plat)->misa_get_xlen)
+ return sbi_platform_ops(plat)->misa_get_xlen();
+ return -1;
+}
+
+/**
+ * Get platform specific root domain memory regions
+ *
+ * @param plat pointer to struct sbi_platform
+ *
+ * @return an array of memory regions terminated by a region with order zero
+ * or NULL for no memory regions
+ */
+static inline struct sbi_domain_memregion *
+sbi_platform_domains_root_regions(const struct sbi_platform *plat)
+{
+ if (plat && sbi_platform_ops(plat)->domains_root_regions)
+ return sbi_platform_ops(plat)->domains_root_regions();
+ return NULL;
+}
+
+/**
+ * Initialize (or populate) domains for the platform
+ *
+ * @param plat pointer to struct sbi_platform
+ *
+ * @return 0 on success and negative error code on failure
+ */
+static inline int sbi_platform_domains_init(const struct sbi_platform *plat)
+{
+ if (plat && sbi_platform_ops(plat)->domains_init)
+ return sbi_platform_ops(plat)->domains_init();
+ return 0;
+}
+
+/**
+ * Write a character to the platform console output
+ *
+ * @param plat pointer to struct sbi_platform
+ * @param ch character to write
+ */
+static inline void sbi_platform_console_putc(const struct sbi_platform *plat,
+ char ch)
+{
+ if (plat && sbi_platform_ops(plat)->console_putc)
+ sbi_platform_ops(plat)->console_putc(ch);
+}
+
+/**
+ * Read a character from the platform console input
+ *
+ * @param plat pointer to struct sbi_platform
+ *
+ * @return character read from console input
+ */
+static inline int sbi_platform_console_getc(const struct sbi_platform *plat)
+{
+ if (plat && sbi_platform_ops(plat)->console_getc)
+ return sbi_platform_ops(plat)->console_getc();
+ return -1;
+}
+
+/**
+ * Initialize the platform console
+ *
+ * @param plat pointer to struct sbi_platform
+ *
+ * @return 0 on success and negative error code on failure
+ */
+static inline int sbi_platform_console_init(const struct sbi_platform *plat)
+{
+ if (plat && sbi_platform_ops(plat)->console_init)
+ return sbi_platform_ops(plat)->console_init();
+ return 0;
+}
+
+/**
+ * Initialize the platform interrupt controller for current HART
+ *
+ * @param plat pointer to struct sbi_platform
+ * @param cold_boot whether cold boot (TRUE) or warm_boot (FALSE)
+ *
+ * @return 0 on success and negative error code on failure
+ */
+static inline int sbi_platform_irqchip_init(const struct sbi_platform *plat,
+ bool cold_boot)
+{
+ if (plat && sbi_platform_ops(plat)->irqchip_init)
+ return sbi_platform_ops(plat)->irqchip_init(cold_boot);
+ return 0;
+}
+
+/**
+ * Exit the platform interrupt controller for current HART
+ *
+ * @param plat pointer to struct sbi_platform
+ */
+static inline void sbi_platform_irqchip_exit(const struct sbi_platform *plat)
+{
+ if (plat && sbi_platform_ops(plat)->irqchip_exit)
+ sbi_platform_ops(plat)->irqchip_exit();
+}
+
+/**
+ * Send IPI to a target HART
+ *
+ * @param plat pointer to struct sbi_platform
+ * @param target_hart HART ID of IPI target
+ */
+static inline void sbi_platform_ipi_send(const struct sbi_platform *plat,
+ u32 target_hart)
+{
+ if (plat && sbi_platform_ops(plat)->ipi_send)
+ sbi_platform_ops(plat)->ipi_send(target_hart);
+}
+
+/**
+ * Clear IPI for a target HART
+ *
+ * @param plat pointer to struct sbi_platform
+ * @param target_hart HART ID of IPI target
+ */
+static inline void sbi_platform_ipi_clear(const struct sbi_platform *plat,
+ u32 target_hart)
+{
+ if (plat && sbi_platform_ops(plat)->ipi_clear)
+ sbi_platform_ops(plat)->ipi_clear(target_hart);
+}
+
+/**
+ * Initialize the platform IPI support for current HART
+ *
+ * @param plat pointer to struct sbi_platform
+ * @param cold_boot whether cold boot (TRUE) or warm_boot (FALSE)
+ *
+ * @return 0 on success and negative error code on failure
+ */
+static inline int sbi_platform_ipi_init(const struct sbi_platform *plat,
+ bool cold_boot)
+{
+ if (plat && sbi_platform_ops(plat)->ipi_init)
+ return sbi_platform_ops(plat)->ipi_init(cold_boot);
+ return 0;
+}
+
+/**
+ * Exit the platform IPI support for current HART
+ *
+ * @param plat pointer to struct sbi_platform
+ */
+static inline void sbi_platform_ipi_exit(const struct sbi_platform *plat)
+{
+ if (plat && sbi_platform_ops(plat)->ipi_exit)
+ sbi_platform_ops(plat)->ipi_exit();
+}
+
+/**
+ * Get platform timer value
+ *
+ * @param plat pointer to struct sbi_platform
+ *
+ * @return 64-bit timer value
+ */
+static inline u64 sbi_platform_timer_value(const struct sbi_platform *plat)
+{
+ if (plat && sbi_platform_ops(plat)->timer_value)
+ return sbi_platform_ops(plat)->timer_value();
+ return 0;
+}
+
+/**
+ * Start platform timer event for current HART
+ *
+ * @param plat pointer to struct struct sbi_platform
+ * @param next_event timer value when timer event will happen
+ */
+static inline void
+sbi_platform_timer_event_start(const struct sbi_platform *plat, u64 next_event)
+{
+ if (plat && sbi_platform_ops(plat)->timer_event_start)
+ sbi_platform_ops(plat)->timer_event_start(next_event);
+}
+
+/**
+ * Stop platform timer event for current HART
+ *
+ * @param plat pointer to struct sbi_platform
+ */
+static inline void
+sbi_platform_timer_event_stop(const struct sbi_platform *plat)
+{
+ if (plat && sbi_platform_ops(plat)->timer_event_stop)
+ sbi_platform_ops(plat)->timer_event_stop();
+}
+
+/**
+ * Initialize the platform timer for current HART
+ *
+ * @param plat pointer to struct sbi_platform
+ * @param cold_boot whether cold boot (TRUE) or warm_boot (FALSE)
+ *
+ * @return 0 on success and negative error code on failure
+ */
+static inline int sbi_platform_timer_init(const struct sbi_platform *plat,
+ bool cold_boot)
+{
+ if (plat && sbi_platform_ops(plat)->timer_init)
+ return sbi_platform_ops(plat)->timer_init(cold_boot);
+ return 0;
+}
+
+/**
+ * Exit the platform timer for current HART
+ *
+ * @param plat pointer to struct sbi_platform
+ */
+static inline void sbi_platform_timer_exit(const struct sbi_platform *plat)
+{
+ if (plat && sbi_platform_ops(plat)->timer_exit)
+ sbi_platform_ops(plat)->timer_exit();
+}
+
+/**
+ * Check whether reset type and reason supported by the platform
+ *
+ * @param plat pointer to struct sbi_platform
+ * @param reset_type type of reset
+ * @param reset_reason reason for reset
+ *
+ * @return 0 if reset type and reason not supported and 1 if supported
+ */
+static inline int sbi_platform_system_reset_check(
+ const struct sbi_platform *plat,
+ u32 reset_type, u32 reset_reason)
+{
+ if (plat && sbi_platform_ops(plat)->system_reset_check)
+ return sbi_platform_ops(plat)->system_reset_check(reset_type,
+ reset_reason);
+ return 0;
+}
+
+/**
+ * Reset the platform
+ *
+ * This function will not return for supported reset type and reset reason
+ *
+ * @param plat pointer to struct sbi_platform
+ * @param reset_type type of reset
+ * @param reset_reason reason for reset
+ */
+static inline void sbi_platform_system_reset(const struct sbi_platform *plat,
+ u32 reset_type, u32 reset_reason)
+{
+ if (plat && sbi_platform_ops(plat)->system_reset)
+ sbi_platform_ops(plat)->system_reset(reset_type, reset_reason);
+}
+
+/**
+ * Check if a vendor extension is implemented or not.
+ *
+ * @param plat pointer to struct sbi_platform
+ * @param extid vendor SBI extension id
+ *
+ * @return 0 if extid is not implemented and 1 if implemented
+ */
+static inline int sbi_platform_vendor_ext_check(const struct sbi_platform *plat,
+ long extid)
+{
+ if (plat && sbi_platform_ops(plat)->vendor_ext_check)
+ return sbi_platform_ops(plat)->vendor_ext_check(extid);
+
+ return 0;
+}
+
+/**
+ * Invoke platform specific vendor SBI extension implementation.
+ *
+ * @param plat pointer to struct sbi_platform
+ * @param extid vendor SBI extension id
+ * @param funcid SBI function id within the extension id
+ * @param regs pointer to trap registers passed by the caller
+ * @param out_value output value that can be filled by the callee
+ * @param out_trap trap info that can be filled by the callee
+ *
+ * @return 0 on success and negative error code on failure
+ */
+static inline int sbi_platform_vendor_ext_provider(
+ const struct sbi_platform *plat,
+ long extid, long funcid,
+ const struct sbi_trap_regs *regs,
+ unsigned long *out_value,
+ struct sbi_trap_info *out_trap)
+{
+ if (plat && sbi_platform_ops(plat)->vendor_ext_provider) {
+ return sbi_platform_ops(plat)->vendor_ext_provider(extid,
+ funcid, regs,
+ out_value,
+ out_trap);
+ }
+
+ return SBI_ENOTSUPP;
+}
+
+#endif
+
+#endif
diff --git a/roms/opensbi/include/sbi/sbi_scratch.h b/roms/opensbi/include/sbi/sbi_scratch.h
new file mode 100644
index 000000000..e35122bed
--- /dev/null
+++ b/roms/opensbi/include/sbi/sbi_scratch.h
@@ -0,0 +1,128 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#ifndef __SBI_SCRATCH_H__
+#define __SBI_SCRATCH_H__
+
+#include <sbi/riscv_asm.h>
+
+/* clang-format off */
+
+/** Offset of fw_start member in sbi_scratch */
+#define SBI_SCRATCH_FW_START_OFFSET (0 * __SIZEOF_POINTER__)
+/** Offset of fw_size member in sbi_scratch */
+#define SBI_SCRATCH_FW_SIZE_OFFSET (1 * __SIZEOF_POINTER__)
+/** Offset of next_arg1 member in sbi_scratch */
+#define SBI_SCRATCH_NEXT_ARG1_OFFSET (2 * __SIZEOF_POINTER__)
+/** Offset of next_addr member in sbi_scratch */
+#define SBI_SCRATCH_NEXT_ADDR_OFFSET (3 * __SIZEOF_POINTER__)
+/** Offset of next_mode member in sbi_scratch */
+#define SBI_SCRATCH_NEXT_MODE_OFFSET (4 * __SIZEOF_POINTER__)
+/** Offset of warmboot_addr member in sbi_scratch */
+#define SBI_SCRATCH_WARMBOOT_ADDR_OFFSET (5 * __SIZEOF_POINTER__)
+/** Offset of platform_addr member in sbi_scratch */
+#define SBI_SCRATCH_PLATFORM_ADDR_OFFSET (6 * __SIZEOF_POINTER__)
+/** Offset of hartid_to_scratch member in sbi_scratch */
+#define SBI_SCRATCH_HARTID_TO_SCRATCH_OFFSET (7 * __SIZEOF_POINTER__)
+/** Offset of trap_exit member in sbi_scratch */
+#define SBI_SCRATCH_TRAP_EXIT_OFFSET (8 * __SIZEOF_POINTER__)
+/** Offset of tmp0 member in sbi_scratch */
+#define SBI_SCRATCH_TMP0_OFFSET (9 * __SIZEOF_POINTER__)
+/** Offset of options member in sbi_scratch */
+#define SBI_SCRATCH_OPTIONS_OFFSET (10 * __SIZEOF_POINTER__)
+/** Offset of extra space in sbi_scratch */
+#define SBI_SCRATCH_EXTRA_SPACE_OFFSET (11 * __SIZEOF_POINTER__)
+/** Maximum size of sbi_scratch (4KB) */
+#define SBI_SCRATCH_SIZE (0x1000)
+
+/* clang-format on */
+
+#ifndef __ASSEMBLY__
+
+#include <sbi/sbi_types.h>
+
+/** Representation of per-HART scratch space */
+struct sbi_scratch {
+ /** Start (or base) address of firmware linked to OpenSBI library */
+ unsigned long fw_start;
+ /** Size (in bytes) of firmware linked to OpenSBI library */
+ unsigned long fw_size;
+ /** Arg1 (or 'a1' register) of next booting stage for this HART */
+ unsigned long next_arg1;
+ /** Address of next booting stage for this HART */
+ unsigned long next_addr;
+ /** Priviledge mode of next booting stage for this HART */
+ unsigned long next_mode;
+ /** Warm boot entry point address for this HART */
+ unsigned long warmboot_addr;
+ /** Address of sbi_platform */
+ unsigned long platform_addr;
+ /** Address of HART ID to sbi_scratch conversion function */
+ unsigned long hartid_to_scratch;
+ /** Address of trap exit function */
+ unsigned long trap_exit;
+ /** Temporary storage */
+ unsigned long tmp0;
+ /** Options for OpenSBI library */
+ unsigned long options;
+};
+
+/** Possible options for OpenSBI library */
+enum sbi_scratch_options {
+ /** Disable prints during boot */
+ SBI_SCRATCH_NO_BOOT_PRINTS = (1 << 0),
+ /** Enable runtime debug prints */
+ SBI_SCRATCH_DEBUG_PRINTS = (1 << 1),
+};
+
+/** Get pointer to sbi_scratch for current HART */
+#define sbi_scratch_thishart_ptr() \
+ ((struct sbi_scratch *)csr_read(CSR_MSCRATCH))
+
+/** Get Arg1 of next booting stage for current HART */
+#define sbi_scratch_thishart_arg1_ptr() \
+ ((void *)(sbi_scratch_thishart_ptr()->next_arg1))
+
+/** Initialize scratch table and allocator */
+int sbi_scratch_init(struct sbi_scratch *scratch);
+
+/**
+ * Allocate from extra space in sbi_scratch
+ *
+ * @return zero on failure and non-zero (>= SBI_SCRATCH_EXTRA_SPACE_OFFSET)
+ * on success
+ */
+unsigned long sbi_scratch_alloc_offset(unsigned long size, const char *owner);
+
+/** Free-up extra space in sbi_scratch */
+void sbi_scratch_free_offset(unsigned long offset);
+
+/** Get pointer from offset in sbi_scratch */
+#define sbi_scratch_offset_ptr(scratch, offset) ((void *)scratch + (offset))
+
+/** Get pointer from offset in sbi_scratch for current HART */
+#define sbi_scratch_thishart_offset_ptr(offset) \
+ ((void *)sbi_scratch_thishart_ptr() + (offset))
+
+/** HART id to scratch table */
+extern struct sbi_scratch *hartid_to_scratch_table[];
+
+/** Get sbi_scratch from HART id */
+#define sbi_hartid_to_scratch(__hartid) \
+ hartid_to_scratch_table[__hartid]
+
+/** Last HART id having a sbi_scratch pointer */
+extern u32 last_hartid_having_scratch;
+
+/** Get last HART id having a sbi_scratch pointer */
+#define sbi_scratch_last_hartid() last_hartid_having_scratch
+
+#endif
+
+#endif
diff --git a/roms/opensbi/include/sbi/sbi_string.h b/roms/opensbi/include/sbi/sbi_string.h
new file mode 100644
index 000000000..b7c2bc22a
--- /dev/null
+++ b/roms/opensbi/include/sbi/sbi_string.h
@@ -0,0 +1,46 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Atish Patra <atish.patra@wdc.com>
+ */
+
+#ifndef __STRING_H__
+#define __STRING_H__
+
+#include <sbi/sbi_types.h>
+
+/*
+ Provides sbi_strcmp for the completeness of supporting string functions.
+ it is not recommended to use sbi_strcmp() but use sbi_strncmp instead.
+*/
+
+int sbi_strcmp(const char *a, const char *b);
+
+int sbi_strncmp(const char *a, const char *b, size_t count);
+
+size_t sbi_strlen(const char *str);
+
+size_t sbi_strnlen(const char *str, size_t count);
+
+char *sbi_strcpy(char *dest, const char *src);
+
+char *sbi_strncpy(char *dest, const char *src, size_t count);
+
+char *sbi_strchr(const char *s, int c);
+
+char *sbi_strrchr(const char *s, int c);
+
+void *sbi_memset(void *s, int c, size_t count);
+
+void *sbi_memcpy(void *dest, const void *src, size_t count);
+
+void *sbi_memmove(void *dest, const void *src, size_t count);
+
+int sbi_memcmp(const void *s1, const void *s2, size_t count);
+
+void *sbi_memchr(const void *s, int c, size_t count);
+
+#endif
diff --git a/roms/opensbi/include/sbi/sbi_system.h b/roms/opensbi/include/sbi/sbi_system.h
new file mode 100644
index 000000000..34ba7669a
--- /dev/null
+++ b/roms/opensbi/include/sbi/sbi_system.h
@@ -0,0 +1,19 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#ifndef __SBI_SYSTEM_H__
+#define __SBI_SYSTEM_H__
+
+#include <sbi/sbi_types.h>
+
+bool sbi_system_reset_supported(u32 reset_type, u32 reset_reason);
+
+void __noreturn sbi_system_reset(u32 reset_type, u32 reset_reason);
+
+#endif
diff --git a/roms/opensbi/include/sbi/sbi_timer.h b/roms/opensbi/include/sbi/sbi_timer.h
new file mode 100644
index 000000000..87bbdbfa0
--- /dev/null
+++ b/roms/opensbi/include/sbi/sbi_timer.h
@@ -0,0 +1,44 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#ifndef __SBI_TIMER_H__
+#define __SBI_TIMER_H__
+
+#include <sbi/sbi_types.h>
+
+struct sbi_scratch;
+
+/** Get timer value for current HART */
+u64 sbi_timer_value(void);
+
+/** Get virtualized timer value for current HART */
+u64 sbi_timer_virt_value(void);
+
+/** Get timer delta value for current HART */
+u64 sbi_timer_get_delta(void);
+
+/** Set timer delta value for current HART */
+void sbi_timer_set_delta(ulong delta);
+
+/** Set upper 32-bits of timer delta value for current HART */
+void sbi_timer_set_delta_upper(ulong delta_upper);
+
+/** Start timer event for current HART */
+void sbi_timer_event_start(u64 next_event);
+
+/** Process timer event for current HART */
+void sbi_timer_process(void);
+
+/* Initialize timer */
+int sbi_timer_init(struct sbi_scratch *scratch, bool cold_boot);
+
+/* Exit timer */
+void sbi_timer_exit(struct sbi_scratch *scratch);
+
+#endif
diff --git a/roms/opensbi/include/sbi/sbi_tlb.h b/roms/opensbi/include/sbi/sbi_tlb.h
new file mode 100644
index 000000000..48f1962d7
--- /dev/null
+++ b/roms/opensbi/include/sbi/sbi_tlb.h
@@ -0,0 +1,60 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Atish Patra <atish.patra@wdc.com>
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#ifndef __SBI_TLB_H__
+#define __SBI_TLB_H__
+
+#include <sbi/sbi_types.h>
+#include <sbi/sbi_hartmask.h>
+
+/* clang-format off */
+
+#define SBI_TLB_FLUSH_ALL ((unsigned long)-1)
+
+/* clang-format on */
+
+#define SBI_TLB_FIFO_NUM_ENTRIES 8
+
+struct sbi_scratch;
+
+struct sbi_tlb_info {
+ unsigned long start;
+ unsigned long size;
+ unsigned long asid;
+ unsigned long vmid;
+ void (*local_fn)(struct sbi_tlb_info *tinfo);
+ struct sbi_hartmask smask;
+};
+
+void sbi_tlb_local_hfence_vvma(struct sbi_tlb_info *tinfo);
+void sbi_tlb_local_hfence_gvma(struct sbi_tlb_info *tinfo);
+void sbi_tlb_local_sfence_vma(struct sbi_tlb_info *tinfo);
+void sbi_tlb_local_hfence_vvma_asid(struct sbi_tlb_info *tinfo);
+void sbi_tlb_local_hfence_gvma_vmid(struct sbi_tlb_info *tinfo);
+void sbi_tlb_local_sfence_vma_asid(struct sbi_tlb_info *tinfo);
+void sbi_tlb_local_fence_i(struct sbi_tlb_info *tinfo);
+
+#define SBI_TLB_INFO_INIT(__p, __start, __size, __asid, __vmid, __lfn, __src) \
+do { \
+ (__p)->start = (__start); \
+ (__p)->size = (__size); \
+ (__p)->asid = (__asid); \
+ (__p)->vmid = (__vmid); \
+ (__p)->local_fn = (__lfn); \
+ SBI_HARTMASK_INIT_EXCEPT(&(__p)->smask, (__src)); \
+} while (0)
+
+#define SBI_TLB_INFO_SIZE sizeof(struct sbi_tlb_info)
+
+int sbi_tlb_request(ulong hmask, ulong hbase, struct sbi_tlb_info *tinfo);
+
+int sbi_tlb_init(struct sbi_scratch *scratch, bool cold_boot);
+
+#endif
diff --git a/roms/opensbi/include/sbi/sbi_trap.h b/roms/opensbi/include/sbi/sbi_trap.h
new file mode 100644
index 000000000..5fb94f980
--- /dev/null
+++ b/roms/opensbi/include/sbi/sbi_trap.h
@@ -0,0 +1,214 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#ifndef __SBI_TRAP_H__
+#define __SBI_TRAP_H__
+
+/* clang-format off */
+
+/** Index of zero member in sbi_trap_regs */
+#define SBI_TRAP_REGS_zero 0
+/** Index of ra member in sbi_trap_regs */
+#define SBI_TRAP_REGS_ra 1
+/** Index of sp member in sbi_trap_regs */
+#define SBI_TRAP_REGS_sp 2
+/** Index of gp member in sbi_trap_regs */
+#define SBI_TRAP_REGS_gp 3
+/** Index of tp member in sbi_trap_regs */
+#define SBI_TRAP_REGS_tp 4
+/** Index of t0 member in sbi_trap_regs */
+#define SBI_TRAP_REGS_t0 5
+/** Index of t1 member in sbi_trap_regs */
+#define SBI_TRAP_REGS_t1 6
+/** Index of t2 member in sbi_trap_regs */
+#define SBI_TRAP_REGS_t2 7
+/** Index of s0 member in sbi_trap_regs */
+#define SBI_TRAP_REGS_s0 8
+/** Index of s1 member in sbi_trap_regs */
+#define SBI_TRAP_REGS_s1 9
+/** Index of a0 member in sbi_trap_regs */
+#define SBI_TRAP_REGS_a0 10
+/** Index of a1 member in sbi_trap_regs */
+#define SBI_TRAP_REGS_a1 11
+/** Index of a2 member in sbi_trap_regs */
+#define SBI_TRAP_REGS_a2 12
+/** Index of a3 member in sbi_trap_regs */
+#define SBI_TRAP_REGS_a3 13
+/** Index of a4 member in sbi_trap_regs */
+#define SBI_TRAP_REGS_a4 14
+/** Index of a5 member in sbi_trap_regs */
+#define SBI_TRAP_REGS_a5 15
+/** Index of a6 member in sbi_trap_regs */
+#define SBI_TRAP_REGS_a6 16
+/** Index of a7 member in sbi_trap_regs */
+#define SBI_TRAP_REGS_a7 17
+/** Index of s2 member in sbi_trap_regs */
+#define SBI_TRAP_REGS_s2 18
+/** Index of s3 member in sbi_trap_regs */
+#define SBI_TRAP_REGS_s3 19
+/** Index of s4 member in sbi_trap_regs */
+#define SBI_TRAP_REGS_s4 20
+/** Index of s5 member in sbi_trap_regs */
+#define SBI_TRAP_REGS_s5 21
+/** Index of s6 member in sbi_trap_regs */
+#define SBI_TRAP_REGS_s6 22
+/** Index of s7 member in sbi_trap_regs */
+#define SBI_TRAP_REGS_s7 23
+/** Index of s8 member in sbi_trap_regs */
+#define SBI_TRAP_REGS_s8 24
+/** Index of s9 member in sbi_trap_regs */
+#define SBI_TRAP_REGS_s9 25
+/** Index of s10 member in sbi_trap_regs */
+#define SBI_TRAP_REGS_s10 26
+/** Index of s11 member in sbi_trap_regs */
+#define SBI_TRAP_REGS_s11 27
+/** Index of t3 member in sbi_trap_regs */
+#define SBI_TRAP_REGS_t3 28
+/** Index of t4 member in sbi_trap_regs */
+#define SBI_TRAP_REGS_t4 29
+/** Index of t5 member in sbi_trap_regs */
+#define SBI_TRAP_REGS_t5 30
+/** Index of t6 member in sbi_trap_regs */
+#define SBI_TRAP_REGS_t6 31
+/** Index of mepc member in sbi_trap_regs */
+#define SBI_TRAP_REGS_mepc 32
+/** Index of mstatus member in sbi_trap_regs */
+#define SBI_TRAP_REGS_mstatus 33
+/** Index of mstatusH member in sbi_trap_regs */
+#define SBI_TRAP_REGS_mstatusH 34
+/** Last member index in sbi_trap_regs */
+#define SBI_TRAP_REGS_last 35
+
+/** Index of epc member in sbi_trap_info */
+#define SBI_TRAP_INFO_epc 0
+/** Index of cause member in sbi_trap_info */
+#define SBI_TRAP_INFO_cause 1
+/** Index of tval member in sbi_trap_info */
+#define SBI_TRAP_INFO_tval 2
+/** Index of tval2 member in sbi_trap_info */
+#define SBI_TRAP_INFO_tval2 3
+/** Index of tinst member in sbi_trap_info */
+#define SBI_TRAP_INFO_tinst 4
+/** Last member index in sbi_trap_info */
+#define SBI_TRAP_INFO_last 5
+
+/* clang-format on */
+
+/** Get offset of member with name 'x' in sbi_trap_regs */
+#define SBI_TRAP_REGS_OFFSET(x) ((SBI_TRAP_REGS_##x) * __SIZEOF_POINTER__)
+/** Size (in bytes) of sbi_trap_regs */
+#define SBI_TRAP_REGS_SIZE SBI_TRAP_REGS_OFFSET(last)
+
+/** Get offset of member with name 'x' in sbi_trap_info */
+#define SBI_TRAP_INFO_OFFSET(x) ((SBI_TRAP_INFO_##x) * __SIZEOF_POINTER__)
+/** Size (in bytes) of sbi_trap_info */
+#define SBI_TRAP_INFO_SIZE SBI_TRAP_INFO_OFFSET(last)
+
+#ifndef __ASSEMBLY__
+
+#include <sbi/sbi_types.h>
+
+/** Representation of register state at time of trap/interrupt */
+struct sbi_trap_regs {
+ /** zero register state */
+ unsigned long zero;
+ /** ra register state */
+ unsigned long ra;
+ /** sp register state */
+ unsigned long sp;
+ /** gp register state */
+ unsigned long gp;
+ /** tp register state */
+ unsigned long tp;
+ /** t0 register state */
+ unsigned long t0;
+ /** t1 register state */
+ unsigned long t1;
+ /** t2 register state */
+ unsigned long t2;
+ /** s0 register state */
+ unsigned long s0;
+ /** s1 register state */
+ unsigned long s1;
+ /** a0 register state */
+ unsigned long a0;
+ /** a1 register state */
+ unsigned long a1;
+ /** a2 register state */
+ unsigned long a2;
+ /** a3 register state */
+ unsigned long a3;
+ /** a4 register state */
+ unsigned long a4;
+ /** a5 register state */
+ unsigned long a5;
+ /** a6 register state */
+ unsigned long a6;
+ /** a7 register state */
+ unsigned long a7;
+ /** s2 register state */
+ unsigned long s2;
+ /** s3 register state */
+ unsigned long s3;
+ /** s4 register state */
+ unsigned long s4;
+ /** s5 register state */
+ unsigned long s5;
+ /** s6 register state */
+ unsigned long s6;
+ /** s7 register state */
+ unsigned long s7;
+ /** s8 register state */
+ unsigned long s8;
+ /** s9 register state */
+ unsigned long s9;
+ /** s10 register state */
+ unsigned long s10;
+ /** s11 register state */
+ unsigned long s11;
+ /** t3 register state */
+ unsigned long t3;
+ /** t4 register state */
+ unsigned long t4;
+ /** t5 register state */
+ unsigned long t5;
+ /** t6 register state */
+ unsigned long t6;
+ /** mepc register state */
+ unsigned long mepc;
+ /** mstatus register state */
+ unsigned long mstatus;
+ /** mstatusH register state (only for 32-bit) */
+ unsigned long mstatusH;
+};
+
+/** Representation of trap details */
+struct sbi_trap_info {
+ /** epc Trap program counter */
+ unsigned long epc;
+ /** cause Trap exception cause */
+ unsigned long cause;
+ /** tval Trap value */
+ unsigned long tval;
+ /** tval2 Trap value 2 */
+ unsigned long tval2;
+ /** tinst Trap instruction */
+ unsigned long tinst;
+};
+
+int sbi_trap_redirect(struct sbi_trap_regs *regs,
+ struct sbi_trap_info *trap);
+
+void sbi_trap_handler(struct sbi_trap_regs *regs);
+
+void __noreturn sbi_trap_exit(const struct sbi_trap_regs *regs);
+
+#endif
+
+#endif
diff --git a/roms/opensbi/include/sbi/sbi_types.h b/roms/opensbi/include/sbi/sbi_types.h
new file mode 100644
index 000000000..0952d5c82
--- /dev/null
+++ b/roms/opensbi/include/sbi/sbi_types.h
@@ -0,0 +1,109 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#ifndef __SBI_TYPES_H__
+#define __SBI_TYPES_H__
+
+#ifndef OPENSBI_EXTERNAL_SBI_TYPES
+
+/* clang-format off */
+
+typedef char s8;
+typedef unsigned char u8;
+typedef unsigned char uint8_t;
+
+typedef short s16;
+typedef unsigned short u16;
+typedef short int16_t;
+typedef unsigned short uint16_t;
+
+typedef int s32;
+typedef unsigned int u32;
+typedef int int32_t;
+typedef unsigned int uint32_t;
+
+#if __riscv_xlen == 64
+typedef long s64;
+typedef unsigned long u64;
+typedef long int64_t;
+typedef unsigned long uint64_t;
+#define PRILX "016lx"
+#elif __riscv_xlen == 32
+typedef long long s64;
+typedef unsigned long long u64;
+typedef long long int64_t;
+typedef unsigned long long uint64_t;
+#define PRILX "08lx"
+#else
+#error "Unexpected __riscv_xlen"
+#endif
+
+typedef int bool;
+typedef unsigned long ulong;
+typedef unsigned long uintptr_t;
+typedef unsigned long size_t;
+typedef long ssize_t;
+typedef unsigned long virtual_addr_t;
+typedef unsigned long virtual_size_t;
+typedef unsigned long physical_addr_t;
+typedef unsigned long physical_size_t;
+
+#define TRUE 1
+#define FALSE 0
+#define true TRUE
+#define false FALSE
+
+#define NULL ((void *)0)
+
+#define __packed __attribute__((packed))
+#define __noreturn __attribute__((noreturn))
+
+#define likely(x) __builtin_expect((x), 1)
+#define unlikely(x) __builtin_expect((x), 0)
+
+#undef offsetof
+#ifdef __compiler_offsetof
+#define offsetof(TYPE, MEMBER) __compiler_offsetof(TYPE,MEMBER)
+#else
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+
+#define container_of(ptr, type, member) ({ \
+ const typeof(((type *)0)->member) * __mptr = (ptr); \
+ (type *)((char *)__mptr - offsetof(type, member)); })
+
+#define array_size(x) (sizeof(x) / sizeof((x)[0]))
+
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#define CLAMP(a, lo, hi) MIN(MAX(a, lo), hi)
+
+#define STR(x) XSTR(x)
+#define XSTR(x) #x
+
+#define ROUNDUP(a, b) ((((a)-1) / (b) + 1) * (b))
+#define ROUNDDOWN(a, b) ((a) / (b) * (b))
+
+/* clang-format on */
+
+#else
+/*
+ * OPENSBI_EXTERNAL_SBI_TYPES could be defined in CFLAGS for using the
+ * external definitions of data types and common macros.
+ * OPENSBI_EXTERNAL_SBI_TYPES is the file name to external header file,
+ * the external build system should address the additional include
+ * directory ccordingly.
+ */
+
+#define XSTR(x) #x
+#define STR(x) XSTR(x)
+#include STR(OPENSBI_EXTERNAL_SBI_TYPES)
+#endif
+
+#endif
diff --git a/roms/opensbi/include/sbi/sbi_unpriv.h b/roms/opensbi/include/sbi/sbi_unpriv.h
new file mode 100644
index 000000000..8cbd3de0c
--- /dev/null
+++ b/roms/opensbi/include/sbi/sbi_unpriv.h
@@ -0,0 +1,41 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#ifndef __SBI_UNPRIV_H__
+#define __SBI_UNPRIV_H__
+
+#include <sbi/sbi_types.h>
+
+struct sbi_scratch;
+struct sbi_trap_info;
+
+#define DECLARE_UNPRIVILEGED_LOAD_FUNCTION(type) \
+ type sbi_load_##type(const type *addr, \
+ struct sbi_trap_info *trap);
+
+#define DECLARE_UNPRIVILEGED_STORE_FUNCTION(type) \
+ void sbi_store_##type(type *addr, type val, \
+ struct sbi_trap_info *trap);
+
+DECLARE_UNPRIVILEGED_LOAD_FUNCTION(u8)
+DECLARE_UNPRIVILEGED_LOAD_FUNCTION(u16)
+DECLARE_UNPRIVILEGED_LOAD_FUNCTION(s8)
+DECLARE_UNPRIVILEGED_LOAD_FUNCTION(s16)
+DECLARE_UNPRIVILEGED_LOAD_FUNCTION(s32)
+DECLARE_UNPRIVILEGED_STORE_FUNCTION(u8)
+DECLARE_UNPRIVILEGED_STORE_FUNCTION(u16)
+DECLARE_UNPRIVILEGED_STORE_FUNCTION(u32)
+DECLARE_UNPRIVILEGED_LOAD_FUNCTION(u32)
+DECLARE_UNPRIVILEGED_LOAD_FUNCTION(u64)
+DECLARE_UNPRIVILEGED_STORE_FUNCTION(u64)
+DECLARE_UNPRIVILEGED_LOAD_FUNCTION(ulong)
+
+ulong sbi_get_insn(ulong mepc, struct sbi_trap_info *trap);
+
+#endif
diff --git a/roms/opensbi/include/sbi/sbi_version.h b/roms/opensbi/include/sbi/sbi_version.h
new file mode 100644
index 000000000..3f734fe9d
--- /dev/null
+++ b/roms/opensbi/include/sbi/sbi_version.h
@@ -0,0 +1,24 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel@wdc.com>
+ */
+
+#ifndef __SBI_VERSION_H__
+#define __SBI_VERSION_H__
+
+#define OPENSBI_VERSION_MAJOR 0
+#define OPENSBI_VERSION_MINOR 9
+
+/**
+ * OpenSBI 32-bit version with:
+ * 1. upper 16-bits as major number
+ * 2. lower 16-bits as minor number
+ */
+#define OPENSBI_VERSION ((OPENSBI_VERSION_MAJOR << 16) | \
+ (OPENSBI_VERSION_MINOR))
+
+#endif