Initial commit.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
This commit is contained in:
Anup Patel
2018-12-11 19:24:06 +05:30
committed by Anup Patel
commit 9e8ff05cb6
67 changed files with 6084 additions and 0 deletions

244
include/sbi/riscv_asm.h Normal file
View File

@@ -0,0 +1,244 @@
/*
* Copyright (c) 2018 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#ifndef __RISCV_ASM_H__
#define __RISCV_ASM_H__
#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 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
#define RISCV_SCRATCH_TMP0_OFFSET (0 * __SIZEOF_POINTER__)
#define RISCV_SCRATCH_FW_START_OFFSET (1 * __SIZEOF_POINTER__)
#define RISCV_SCRATCH_FW_SIZE_OFFSET (2 * __SIZEOF_POINTER__)
#define RISCV_SCRATCH_NEXT_ARG1_OFFSET (3 * __SIZEOF_POINTER__)
#define RISCV_SCRATCH_NEXT_ADDR_OFFSET (4 * __SIZEOF_POINTER__)
#define RISCV_SCRATCH_NEXT_MODE_OFFSET (5 * __SIZEOF_POINTER__)
#define RISCV_SCRATCH_WARMBOOT_ADDR_OFFSET (6 * __SIZEOF_POINTER__)
#define RISCV_SCRATCH_PLATFORM_ADDR_OFFSET (7 * __SIZEOF_POINTER__)
#define RISCV_SCRATCH_HARTID_TO_SCRATCH_OFFSET (8 * __SIZEOF_POINTER__)
#define RISCV_SCRATCH_IPI_TYPE_OFFSET (9 * __SIZEOF_POINTER__)
#define RISCV_SCRATCH_SIZE 256
#define RISCV_TRAP_REGS_zero 0
#define RISCV_TRAP_REGS_ra 1
#define RISCV_TRAP_REGS_sp 2
#define RISCV_TRAP_REGS_gp 3
#define RISCV_TRAP_REGS_tp 4
#define RISCV_TRAP_REGS_t0 5
#define RISCV_TRAP_REGS_t1 6
#define RISCV_TRAP_REGS_t2 7
#define RISCV_TRAP_REGS_s0 8
#define RISCV_TRAP_REGS_s1 9
#define RISCV_TRAP_REGS_a0 10
#define RISCV_TRAP_REGS_a1 11
#define RISCV_TRAP_REGS_a2 12
#define RISCV_TRAP_REGS_a3 13
#define RISCV_TRAP_REGS_a4 14
#define RISCV_TRAP_REGS_a5 15
#define RISCV_TRAP_REGS_a6 16
#define RISCV_TRAP_REGS_a7 17
#define RISCV_TRAP_REGS_s2 18
#define RISCV_TRAP_REGS_s3 19
#define RISCV_TRAP_REGS_s4 20
#define RISCV_TRAP_REGS_s5 21
#define RISCV_TRAP_REGS_s6 22
#define RISCV_TRAP_REGS_s7 23
#define RISCV_TRAP_REGS_s8 24
#define RISCV_TRAP_REGS_s9 25
#define RISCV_TRAP_REGS_s10 26
#define RISCV_TRAP_REGS_s11 27
#define RISCV_TRAP_REGS_t3 28
#define RISCV_TRAP_REGS_t4 29
#define RISCV_TRAP_REGS_t5 30
#define RISCV_TRAP_REGS_t6 31
#define RISCV_TRAP_REGS_mepc 32
#define RISCV_TRAP_REGS_mstatus 33
#define RISCV_TRAP_REGS_last 34
#define RISCV_TRAP_REGS_OFFSET(x) \
((RISCV_TRAP_REGS_##x) * __SIZEOF_POINTER__)
#define RISCV_TRAP_REGS_SIZE RISCV_TRAP_REGS_OFFSET(last)
#ifndef __ASSEMBLY__
#define csr_swap(csr, val) \
({ \
unsigned long __v = (unsigned long)(val); \
__asm__ __volatile__ ("csrrw %0, " #csr ", %1" \
: "=r" (__v) : "rK" (__v) \
: "memory"); \
__v; \
})
#define csr_read(csr) \
({ \
register unsigned long __v; \
__asm__ __volatile__ ("csrr %0, " #csr \
: "=r" (__v) : \
: "memory"); \
__v; \
})
#define csr_read_n(csr_num) \
({ \
register unsigned long __v; \
__asm__ __volatile__ ("csrr %0, " __ASM_STR(csr_num) \
: "=r" (__v) : \
: "memory"); \
__v; \
})
#define csr_write(csr, val) \
({ \
unsigned long __v = (unsigned long)(val); \
__asm__ __volatile__ ("csrw " #csr ", %0" \
: : "rK" (__v) \
: "memory"); \
})
#define csr_write_n(csr_num, val) \
({ \
unsigned long __v = (unsigned long)(val); \
__asm__ __volatile__ ("csrw " __ASM_STR(csr_num) ", %0" \
: : "rK" (__v) \
: "memory"); \
})
#define csr_read_set(csr, val) \
({ \
unsigned long __v = (unsigned long)(val); \
__asm__ __volatile__ ("csrrs %0, " #csr ", %1" \
: "=r" (__v) : "rK" (__v) \
: "memory"); \
__v; \
})
#define csr_set(csr, val) \
({ \
unsigned long __v = (unsigned long)(val); \
__asm__ __volatile__ ("csrs " #csr ", %0" \
: : "rK" (__v) \
: "memory"); \
})
#define csr_read_clear(csr, val) \
({ \
unsigned long __v = (unsigned long)(val); \
__asm__ __volatile__ ("csrrc %0, " #csr ", %1" \
: "=r" (__v) : "rK" (__v) \
: "memory"); \
__v; \
})
#define csr_clear(csr, val) \
({ \
unsigned long __v = (unsigned long)(val); \
__asm__ __volatile__ ("csrc " #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)
static inline int misa_extension(char ext)
{
return csr_read(misa) & (1 << (ext - 'A'));
}
static inline int misa_xlen(void)
{
return ((long)csr_read(misa) < 0) ? 64 : 32;
}
static inline void misa_string(char *out, unsigned int out_sz)
{
unsigned long i, val = csr_read(misa);
for (i = 0; i < 26; i++) {
if (val & (1 << i)) {
*out = 'A' + i;
out++;
}
}
*out = '\0';
out++;
}
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_out);
#endif /* !__ASSEMBLY__ */
#endif

View File

@@ -0,0 +1,38 @@
/*
* Copyright (c) 2018 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#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 arch_atomic_cmpxchg(atomic_t *atom, long oldval, long newval);
long arch_atomic_xchg(atomic_t *atom, long newval);
unsigned int atomic_raw_xchg_uint(volatile unsigned int *ptr,
unsigned int newval);
#endif

View File

@@ -0,0 +1,53 @@
/*
* Copyright (c) 2018 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#ifndef __RISCV_BARRIER_H__
#define __RISCV_BARRIER_H__
#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")
#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

View File

@@ -0,0 +1,423 @@
/*
* Copyright (c) 2018 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#ifndef __RISCV_ENCODING_H__
#define __RISCV_ENCODING_H__
#include <sbi/sbi_const.h>
/* TODO: Make constants usable in assembly with _AC() macro */
#define MSTATUS_UIE 0x00000001
#define MSTATUS_SIE 0x00000002
#define MSTATUS_HIE 0x00000004
#define MSTATUS_MIE 0x00000008
#define MSTATUS_UPIE 0x00000010
#define MSTATUS_SPIE 0x00000020
#define MSTATUS_HPIE 0x00000040
#define MSTATUS_MPIE 0x00000080
#define MSTATUS_SPP 0x00000100
#define MSTATUS_HPP 0x00000600
#define MSTATUS_MPP 0x00001800
#define MSTATUS_FS 0x00006000
#define MSTATUS_XS 0x00018000
#define MSTATUS_MPRV 0x00020000
#define MSTATUS_SUM 0x00040000
#define MSTATUS_MXR 0x00080000
#define MSTATUS_TVM 0x00100000
#define MSTATUS_TW 0x00200000
#define MSTATUS_TSR 0x00400000
#define MSTATUS32_SD 0x80000000
#define MSTATUS_UXL 0x0000000300000000
#define MSTATUS_SXL 0x0000000C00000000
#define MSTATUS64_SD 0x8000000000000000
#define SSTATUS_UIE 0x00000001
#define SSTATUS_SIE 0x00000002
#define SSTATUS_UPIE 0x00000010
#define SSTATUS_SPIE 0x00000020
#define SSTATUS_SPP 0x00000100
#define SSTATUS_FS 0x00006000
#define SSTATUS_XS 0x00018000
#define SSTATUS_SUM 0x00040000
#define SSTATUS_MXR 0x00080000
#define SSTATUS32_SD 0x80000000
#define SSTATUS_UXL 0x0000000300000000
#define SSTATUS64_SD 0x8000000000000000
#define DCSR_XDEBUGVER (3U<<30)
#define DCSR_NDRESET (1<<29)
#define DCSR_FULLRESET (1<<28)
#define DCSR_EBREAKM (1<<15)
#define DCSR_EBREAKH (1<<14)
#define DCSR_EBREAKS (1<<13)
#define DCSR_EBREAKU (1<<12)
#define DCSR_STOPCYCLE (1<<10)
#define DCSR_STOPTIME (1<<9)
#define DCSR_CAUSE (7<<6)
#define DCSR_DEBUGINT (1<<5)
#define DCSR_HALT (1<<3)
#define DCSR_STEP (1<<2)
#define DCSR_PRV (3<<0)
#define DCSR_CAUSE_NONE 0
#define DCSR_CAUSE_SWBP 1
#define DCSR_CAUSE_HWBP 2
#define DCSR_CAUSE_DEBUGINT 3
#define DCSR_CAUSE_STEP 4
#define DCSR_CAUSE_HALT 5
#define MCONTROL_TYPE(xlen) (0xfULL<<((xlen)-4))
#define MCONTROL_DMODE(xlen) (1ULL<<((xlen)-5))
#define MCONTROL_MASKMAX(xlen) (0x3fULL<<((xlen)-11))
#define MCONTROL_SELECT (1<<19)
#define MCONTROL_TIMING (1<<18)
#define MCONTROL_ACTION (0x3f<<12)
#define MCONTROL_CHAIN (1<<11)
#define MCONTROL_MATCH (0xf<<7)
#define MCONTROL_M (1<<6)
#define MCONTROL_H (1<<5)
#define MCONTROL_S (1<<4)
#define MCONTROL_U (1<<3)
#define MCONTROL_EXECUTE (1<<2)
#define MCONTROL_STORE (1<<1)
#define MCONTROL_LOAD (1<<0)
#define MCONTROL_TYPE_NONE 0
#define MCONTROL_TYPE_MATCH 2
#define MCONTROL_ACTION_DEBUG_EXCEPTION 0
#define MCONTROL_ACTION_DEBUG_MODE 1
#define MCONTROL_ACTION_TRACE_START 2
#define MCONTROL_ACTION_TRACE_STOP 3
#define MCONTROL_ACTION_TRACE_EMIT 4
#define MCONTROL_MATCH_EQUAL 0
#define MCONTROL_MATCH_NAPOT 1
#define MCONTROL_MATCH_GE 2
#define MCONTROL_MATCH_LT 3
#define MCONTROL_MATCH_MASK_LOW 4
#define MCONTROL_MATCH_MASK_HIGH 5
#define IRQ_S_SOFT 1
#define IRQ_H_SOFT 2
#define IRQ_M_SOFT 3
#define IRQ_S_TIMER 5
#define IRQ_H_TIMER 6
#define IRQ_M_TIMER 7
#define IRQ_S_EXT 9
#define IRQ_H_EXT 10
#define IRQ_M_EXT 11
#define IRQ_COP 12
#define IRQ_HOST 13
#define MIP_SSIP (1 << IRQ_S_SOFT)
#define MIP_HSIP (1 << IRQ_H_SOFT)
#define MIP_MSIP (1 << IRQ_M_SOFT)
#define MIP_STIP (1 << IRQ_S_TIMER)
#define MIP_HTIP (1 << IRQ_H_TIMER)
#define MIP_MTIP (1 << IRQ_M_TIMER)
#define MIP_SEIP (1 << IRQ_S_EXT)
#define MIP_HEIP (1 << IRQ_H_EXT)
#define MIP_MEIP (1 << IRQ_M_EXT)
#define SIP_SSIP MIP_SSIP
#define SIP_STIP MIP_STIP
#define PRV_U 0
#define PRV_S 1
#define PRV_H 2
#define PRV_M 3
#define SATP32_MODE 0x80000000
#define SATP32_ASID 0x7FC00000
#define SATP32_PPN 0x003FFFFF
#define SATP64_MODE 0xF000000000000000
#define SATP64_ASID 0x0FFFF00000000000
#define SATP64_PPN 0x00000FFFFFFFFFFF
#define SATP_MODE_OFF 0
#define SATP_MODE_SV32 1
#define SATP_MODE_SV39 8
#define SATP_MODE_SV48 9
#define SATP_MODE_SV57 10
#define SATP_MODE_SV64 11
#define PMP_R 0x01
#define PMP_W 0x02
#define PMP_X 0x04
#define PMP_A 0x18
#define PMP_A_TOR 0x08
#define PMP_A_NA4 0x10
#define PMP_A_NAPOT 0x18
#define PMP_L 0x80
#define PMP_SHIFT 2
#define PMP_COUNT 16
/* page table entry (PTE) fields */
#define PTE_V 0x001 /* Valid */
#define PTE_R 0x002 /* Read */
#define PTE_W 0x004 /* Write */
#define PTE_X 0x008 /* Execute */
#define PTE_U 0x010 /* User */
#define PTE_G 0x020 /* Global */
#define PTE_A 0x040 /* Accessed */
#define PTE_D 0x080 /* Dirty */
#define PTE_SOFT 0x300 /* Reserved for Software */
#define PTE_PPN_SHIFT 10
#define PTE_TABLE(PTE) \
(((PTE) & (PTE_V | PTE_R | PTE_W | PTE_X)) == PTE_V)
#if __riscv_xlen == 64
#define MSTATUS_SD MSTATUS64_SD
#define SSTATUS_SD SSTATUS64_SD
#define RISCV_PGLEVEL_BITS 9
#define SATP_MODE SATP64_MODE
#else
#define MSTATUS_SD MSTATUS32_SD
#define SSTATUS_SD SSTATUS32_SD
#define RISCV_PGLEVEL_BITS 10
#define SATP_MODE SATP32_MODE
#endif
#define RISCV_PGSHIFT 12
#define RISCV_PGSIZE (1 << RISCV_PGSHIFT)
#define CSR_FFLAGS 0x1
#define CSR_FRM 0x2
#define CSR_FCSR 0x3
#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_SSTATUS 0x100
#define CSR_SIE 0x104
#define CSR_STVEC 0x105
#define CSR_SCOUNTEREN 0x106
#define CSR_SSCRATCH 0x140
#define CSR_SEPC 0x141
#define CSR_SCAUSE 0x142
#define CSR_STVAL 0x143
#define CSR_SIP 0x144
#define CSR_SATP 0x180
#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_MSCRATCH 0x340
#define CSR_MEPC 0x341
#define CSR_MCAUSE 0x342
#define CSR_MTVAL 0x343
#define CSR_MIP 0x344
#define CSR_PMPCFG0 0x3a0
#define CSR_PMPCFG1 0x3a1
#define CSR_PMPCFG2 0x3a2
#define CSR_PMPCFG3 0x3a3
#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_TSELECT 0x7a0
#define CSR_TDATA1 0x7a1
#define CSR_TDATA2 0x7a2
#define CSR_TDATA3 0x7a3
#define CSR_DCSR 0x7b0
#define CSR_DPC 0x7b1
#define CSR_DSCRATCH 0x7b2
#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_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
#define CSR_MVENDORID 0xf11
#define CSR_MARCHID 0xf12
#define CSR_MIMPID 0xf13
#define CSR_MHARTID 0xf14
#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
#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
#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_HYPERVISOR_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
#endif

109
include/sbi/riscv_io.h Normal file
View File

@@ -0,0 +1,109 @@
/*
* Copyright (c) 2018 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#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 */
#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
#endif

33
include/sbi/riscv_locks.h Normal file
View File

@@ -0,0 +1,33 @@
/*
* Copyright (c) 2018 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#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

44
include/sbi/sbi_bits.h Normal file
View File

@@ -0,0 +1,44 @@
/*
* Copyright (c) 2018 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#ifndef __SBI_BITS_H__
#define __SBI_BITS_H__
#define likely(x) __builtin_expect((x), 1)
#define unlikely(x) __builtin_expect((x), 0)
#define ROUNDUP(a, b) ((((a)-1)/(b)+1)*(b))
#define ROUNDDOWN(a, b) ((a)/(b)*(b))
#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 EXTRACT_FIELD(val, which) (((val) & (which)) / ((which) & ~((which)-1)))
#define INSERT_FIELD(val, which, fieldval) (((val) & ~(which)) | ((fieldval) * ((which) & ~((which)-1))))
#define STR(x) XSTR(x)
#define XSTR(x) #x
#if __riscv_xlen == 64
#define SLL32 sllw
#define STORE sd
#define LOAD ld
#define LWU lwu
#define LOG_REGBYTES 3
#else
#define SLL32 sll
#define STORE sw
#define LOAD lw
#define LWU lw
#define LOG_REGBYTES 2
#endif
#define REGBYTES (1 << LOG_REGBYTES)
#endif

37
include/sbi/sbi_console.h Normal file
View File

@@ -0,0 +1,37 @@
/*
* Copyright (c) 2018 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#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);
char 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, ...);
struct sbi_scratch;
int sbi_console_init(struct sbi_scratch *scratch);
#endif

43
include/sbi/sbi_const.h Normal file
View File

@@ -0,0 +1,43 @@
/*
* Copyright (c) 2018 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#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.
*/
#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)
#endif

26
include/sbi/sbi_ecall.h Normal file
View File

@@ -0,0 +1,26 @@
/*
* Copyright (c) 2018 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#ifndef __SBI_ECALL_H__
#define __SBI_ECALL_H__
#include <sbi/sbi_types.h>
struct sbi_trap_regs;
struct sbi_scratch;
u16 sbi_ecall_version_major(void);
u16 sbi_ecall_version_minor(void);
int sbi_ecall_handler(u32 hartid, ulong mcause,
struct sbi_trap_regs *regs,
struct sbi_scratch *scratch);
#endif

View File

@@ -0,0 +1,27 @@
/*
* Copyright (c) 2018 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#ifndef __SBI_EMULATE_CSR_H__
#define __SBI_EMULATE_CSR_H__
#include <sbi/sbi_types.h>
struct sbi_scratch;
int sbi_emulate_csr_read(int csr_num,
u32 hartid, ulong mstatus,
struct sbi_scratch *scratch,
ulong *csr_val);
int sbi_emulate_csr_write(int csr_num,
u32 hartid, ulong mstatus,
struct sbi_scratch *scratch,
ulong csr_val);
#endif

25
include/sbi/sbi_error.h Normal file
View File

@@ -0,0 +1,25 @@
/*
* Copyright (c) 2018 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#ifndef __SBI_ERROR_H__
#define __SBI_ERROR_H__
#define SBI_OK 0
#define SBI_EUNKNOWN -1
#define SBI_EFAIL -2
#define SBI_EINVAL -3
#define SBI_ENOENT -4
#define SBI_ENOTSUPP -5
#define SBI_ENODEV -6
#define SBI_ENOSYS -7
#define SBI_ETIMEDOUT -8
#define SBI_EIO -9
#define SBI_EILL -10
#endif

41
include/sbi/sbi_hart.h Normal file
View File

@@ -0,0 +1,41 @@
/*
* Copyright (c) 2018 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#ifndef __SBI_HART_H__
#define __SBI_HART_H__
#include <sbi/sbi_types.h>
struct sbi_scratch;
int sbi_hart_init(struct sbi_scratch *scratch, u32 hartid);
void sbi_hart_pmp_dump(void);
void __attribute__((noreturn)) sbi_hart_hang(void);
void __attribute__((noreturn)) sbi_hart_boot_next(unsigned long arg0,
unsigned long arg1,
unsigned long next_addr,
unsigned long next_mode);
void sbi_hart_mark_available(u32 hartid);
ulong sbi_hart_available_mask(void);
void sbi_hart_unmark_available(u32 hartid);
struct sbi_scratch *sbi_hart_id_to_scratch(struct sbi_scratch *scratch,
u32 hartid);
void sbi_hart_wait_for_coldboot(struct sbi_scratch *scratch, u32 hartid);
void sbi_hart_wake_coldboot_harts(struct sbi_scratch *scratch);
#endif

View File

@@ -0,0 +1,22 @@
/*
* Copyright (c) 2018 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#ifndef __SBI_ILLEGAl_INSN_H__
#define __SBI_ILLEGAl_INSN_H__
#include <sbi/sbi_types.h>
struct sbi_trap_regs;
struct sbi_scratch;
int sbi_illegal_insn_handler(u32 hartid, ulong mcause,
struct sbi_trap_regs *regs,
struct sbi_scratch *scratch);
#endif

19
include/sbi/sbi_init.h Normal file
View File

@@ -0,0 +1,19 @@
/*
* Copyright (c) 2018 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#ifndef __SBI_INIT_H__
#define __SBI_INIT_H__
#include <sbi/sbi_types.h>
struct sbi_scratch;
void __attribute__((noreturn)) sbi_init(struct sbi_scratch *scratch);
#endif

33
include/sbi/sbi_ipi.h Normal file
View File

@@ -0,0 +1,33 @@
/*
* Copyright (c) 2018 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#ifndef __SBI_IPI_H__
#define __SBI_IPI_H__
#include <sbi/sbi_types.h>
#define SBI_IPI_EVENT_SOFT 0x1
#define SBI_IPI_EVENT_FENCE_I 0x2
#define SBI_IPI_EVENT_SFENCE_VMA 0x4
#define SBI_IPI_EVENT_HALT 0x8
struct sbi_scratch;
int sbi_ipi_send_many(struct sbi_scratch *scratch,
u32 hartid, ulong *pmask, u32 event);
void sbi_ipi_clear_smode(struct sbi_scratch *scratch, u32 hartid);
void sbi_ipi_process(struct sbi_scratch *scratch, u32 hartid);
int sbi_ipi_warm_init(struct sbi_scratch *scratch, u32 hartid);
int sbi_ipi_cold_init(struct sbi_scratch *scratch);
#endif

258
include/sbi/sbi_platform.h Normal file
View File

@@ -0,0 +1,258 @@
/*
* Copyright (c) 2018 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#ifndef __SBI_PLATFORM_H__
#define __SBI_PLATFORM_H__
#include <sbi/sbi_scratch.h>
enum sbi_platform_features {
SBI_PLATFORM_HAS_MMIO_TIMER_VALUE = (1 << 0),
SBI_PLATFORM_HAS_HART_HOTPLUG = (1 << 1),
};
struct sbi_platform {
char name[64];
u64 features;
u32 hart_count;
u32 hart_stack_size;
int (*cold_early_init)(void);
int (*cold_final_init)(void);
int (*warm_early_init)(u32 target_hart);
int (*warm_final_init)(u32 target_hart);
u32 (*pmp_region_count)(u32 target_hart);
int (*pmp_region_info)(u32 target_hart, u32 index,
ulong *prot, ulong *addr, ulong *log2size);
void (*console_putc)(char ch);
char (*console_getc)(void);
int (*console_init)(void);
int (*cold_irqchip_init)(void);
int (*warm_irqchip_init)(u32 target_hart);
void (*ipi_inject)(u32 target_hart, u32 source_hart);
void (*ipi_sync)(u32 target_hart, u32 source_hart);
void (*ipi_clear)(u32 target_hart);
int (*cold_ipi_init)(void);
int (*warm_ipi_init)(u32 target_hart);
u64 (*timer_value)(void);
void (*timer_event_stop)(u32 target_hart);
void (*timer_event_start)(u32 target_hart, u64 next_event);
int (*cold_timer_init)(void);
int (*warm_timer_init)(u32 target_hart);
int (*system_reboot)(u32 type);
int (*system_shutdown)(u32 type);
} __attribute__((packed));
#define sbi_platform_ptr(__s) \
((struct sbi_platform *)((__s)->platform_addr))
#define sbi_platform_thishart_ptr() \
((struct sbi_platform *)(sbi_scratch_thishart_ptr()->platform_addr))
#define sbi_platform_has_mmio_timer_value(__p) \
((__p)->features & SBI_PLATFORM_HAS_MMIO_TIMER_VALUE)
#define sbi_platform_has_hart_hotplug(__p) \
((__p)->features & SBI_PLATFORM_HAS_HART_HOTPLUG)
static inline const char *sbi_platform_name(struct sbi_platform *plat)
{
if (plat)
return plat->name;
return NULL;
}
static inline u32 sbi_platform_hart_count(struct sbi_platform *plat)
{
if (plat)
return plat->hart_count;
return 0;
}
static inline u32 sbi_platform_hart_stack_size(struct sbi_platform *plat)
{
if (plat)
return plat->hart_stack_size;
return 0;
}
static inline int sbi_platform_cold_early_init(struct sbi_platform *plat)
{
if (plat && plat->cold_early_init)
return plat->cold_early_init();
return 0;
}
static inline int sbi_platform_cold_final_init(struct sbi_platform *plat)
{
if (plat && plat->cold_final_init)
return plat->cold_final_init();
return 0;
}
static inline int sbi_platform_warm_early_init(struct sbi_platform *plat,
u32 target_hart)
{
if (plat && plat->warm_early_init)
return plat->warm_early_init(target_hart);
return 0;
}
static inline int sbi_platform_warm_final_init(struct sbi_platform *plat,
u32 target_hart)
{
if (plat && plat->warm_final_init)
return plat->warm_final_init(target_hart);
return 0;
}
static inline u32 sbi_platform_pmp_region_count(struct sbi_platform *plat,
u32 target_hart)
{
if (plat && plat->pmp_region_count)
return plat->pmp_region_count(target_hart);
return 0;
}
static inline int sbi_platform_pmp_region_info(struct sbi_platform *plat,
u32 target_hart, u32 index,
ulong *prot, ulong *addr,
ulong *log2size)
{
if (plat && plat->pmp_region_info)
return plat->pmp_region_info(target_hart, index,
prot, addr, log2size);
return 0;
}
static inline void sbi_platform_console_putc(struct sbi_platform *plat,
char ch)
{
if (plat && plat->console_putc)
plat->console_putc(ch);
}
static inline char sbi_platform_console_getc(struct sbi_platform *plat)
{
if (plat && plat->console_getc)
return plat->console_getc();
return 0;
}
static inline int sbi_platform_console_init(struct sbi_platform *plat)
{
if (plat && plat->console_init)
return plat->console_init();
return 0;
}
static inline int sbi_platform_warm_irqchip_init(struct sbi_platform *plat,
u32 target_hart)
{
if (plat && plat->warm_irqchip_init)
return plat->warm_irqchip_init(target_hart);
return 0;
}
static inline int sbi_platform_cold_irqchip_init(struct sbi_platform *plat)
{
if (plat && plat->cold_irqchip_init)
return plat->cold_irqchip_init();
return 0;
}
static inline void sbi_platform_ipi_inject(struct sbi_platform *plat,
u32 target_hart, u32 source_hart)
{
if (plat && plat->ipi_inject)
plat->ipi_inject(target_hart, source_hart);
}
static inline void sbi_platform_ipi_sync(struct sbi_platform *plat,
u32 target_hart, u32 source_hart)
{
if (plat && plat->ipi_sync)
plat->ipi_sync(target_hart, source_hart);
}
static inline void sbi_platform_ipi_clear(struct sbi_platform *plat,
u32 target_hart)
{
if (plat && plat->ipi_clear)
plat->ipi_clear(target_hart);
}
static inline int sbi_platform_warm_ipi_init(struct sbi_platform *plat,
u32 target_hart)
{
if (plat && plat->warm_ipi_init)
return plat->warm_ipi_init(target_hart);
return 0;
}
static inline int sbi_platform_cold_ipi_init(struct sbi_platform *plat)
{
if (plat && plat->cold_ipi_init)
return plat->cold_ipi_init();
return 0;
}
static inline u64 sbi_platform_timer_value(struct sbi_platform *plat)
{
if (plat && plat->timer_value)
return plat->timer_value();
return 0;
}
static inline void sbi_platform_timer_event_stop(struct sbi_platform *plat,
u32 target_hart)
{
if (plat && plat->timer_event_stop)
plat->timer_event_stop(target_hart);
}
static inline void sbi_platform_timer_event_start(struct sbi_platform *plat,
u32 target_hart,
u64 next_event)
{
if (plat && plat->timer_event_start)
plat->timer_event_start(target_hart, next_event);
}
static inline int sbi_platform_warm_timer_init(struct sbi_platform *plat,
u32 target_hart)
{
if (plat && plat->warm_timer_init)
return plat->warm_timer_init(target_hart);
return 0;
}
static inline int sbi_platform_cold_timer_init(struct sbi_platform *plat)
{
if (plat && plat->cold_timer_init)
return plat->cold_timer_init();
return 0;
}
static inline int sbi_platform_system_reboot(struct sbi_platform *plat,
u32 type)
{
if (plat && plat->system_reboot)
return plat->system_reboot(type);
return 0;
}
static inline int sbi_platform_system_shutdown(struct sbi_platform *plat,
u32 type)
{
if (plat && plat->system_shutdown)
return plat->system_shutdown(type);
return 0;
}
#endif

35
include/sbi/sbi_scratch.h Normal file
View File

@@ -0,0 +1,35 @@
/*
* Copyright (c) 2018 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#ifndef __SBI_SCRATCH_H__
#define __SBI_SCRATCH_H__
#include <sbi/riscv_asm.h>
#include <sbi/sbi_types.h>
struct sbi_scratch {
unsigned long tmp0;
unsigned long fw_start;
unsigned long fw_size;
unsigned long next_arg1;
unsigned long next_addr;
unsigned long next_mode;
unsigned long warmboot_addr;
unsigned long platform_addr;
unsigned long hartid_to_scratch;
unsigned long ipi_type;
} __attribute__((packed));
#define sbi_scratch_thishart_ptr() \
((struct sbi_scratch *)csr_read(mscratch))
#define sbi_scratch_thishart_arg1_ptr() \
((void *)(sbi_scratch_thishart_ptr()->next_arg1))
#endif

31
include/sbi/sbi_system.h Normal file
View File

@@ -0,0 +1,31 @@
/*
* Copyright (c) 2018 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#ifndef __SBI_SYSTEM_H__
#define __SBI_SYSTEM_H__
#include <sbi/sbi_types.h>
struct sbi_scratch;
int sbi_system_warm_early_init(struct sbi_scratch *scratch, u32 hartid);
int sbi_system_warm_final_init(struct sbi_scratch *scratch, u32 hartid);
int sbi_system_cold_early_init(struct sbi_scratch *scratch);
int sbi_system_cold_final_init(struct sbi_scratch *scratch);
void __attribute__((noreturn)) sbi_system_reboot(struct sbi_scratch *scratch,
u32 type);
void __attribute__((noreturn)) sbi_system_shutdown(struct sbi_scratch *scratch,
u32 type);
#endif

30
include/sbi/sbi_timer.h Normal file
View File

@@ -0,0 +1,30 @@
/*
* Copyright (c) 2018 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#ifndef __SBI_TIMER_H__
#define __SBI_TIMER_H__
#include <sbi/sbi_types.h>
struct sbi_scratch;
u64 sbi_timer_value(struct sbi_scratch *scratch);
void sbi_timer_event_stop(struct sbi_scratch *scratch, u32 hartid);
void sbi_timer_event_start(struct sbi_scratch *scratch, u32 hartid,
u64 next_event);
void sbi_timer_process(struct sbi_scratch *scratch, u32 hartid);
int sbi_timer_warm_init(struct sbi_scratch *scratch, u32 hartid);
int sbi_timer_cold_init(struct sbi_scratch *scratch);
#endif

57
include/sbi/sbi_trap.h Normal file
View File

@@ -0,0 +1,57 @@
/*
* Copyright (c) 2018 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#ifndef __SBI_TRAP_H__
#define __SBI_TRAP_H__
#include <sbi/sbi_types.h>
struct sbi_trap_regs {
unsigned long zero;
unsigned long ra;
unsigned long sp;
unsigned long gp;
unsigned long tp;
unsigned long t0;
unsigned long t1;
unsigned long t2;
unsigned long s0;
unsigned long s1;
unsigned long a0;
unsigned long a1;
unsigned long a2;
unsigned long a3;
unsigned long a4;
unsigned long a5;
unsigned long a6;
unsigned long a7;
unsigned long s2;
unsigned long s3;
unsigned long s4;
unsigned long s5;
unsigned long s6;
unsigned long s7;
unsigned long s8;
unsigned long s9;
unsigned long s10;
unsigned long s11;
unsigned long t3;
unsigned long t4;
unsigned long t5;
unsigned long t6;
unsigned long mepc;
unsigned long mstatus;
} __attribute__((packed));
struct sbi_scratch;
void sbi_trap_handler(struct sbi_trap_regs *regs,
struct sbi_scratch *scratch);
#endif

57
include/sbi/sbi_types.h Normal file
View File

@@ -0,0 +1,57 @@
/*
* Copyright (c) 2018 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#ifndef __SBI_TYPES_H__
#define __SBI_TYPES_H__
typedef char s8;
typedef unsigned char u8;
typedef char int8_t;
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;
#elif __riscv_xlen == 32
typedef long long s64;
typedef unsigned long long u64;
typedef long long int64_t;
typedef unsigned long long uint64_t;
#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 NULL ((void *)0)
#endif

111
include/sbi/sbi_unpriv.h Normal file
View File

@@ -0,0 +1,111 @@
/*
* Copyright (c) 2018 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#ifndef __SBI_UNPRIV_H__
#define __SBI_UNPRIV_H__
#include <sbi/riscv_encoding.h>
#include <sbi/sbi_bits.h>
#include <sbi/sbi_types.h>
#define DECLARE_UNPRIVILEGED_LOAD_FUNCTION(type, insn) \
static inline type load_##type(const type *addr, ulong mepc) \
{ \
register ulong __mepc asm ("a2") = mepc; \
register ulong __mstatus asm ("a3"); \
type val; \
asm ("csrrs %0, mstatus, %3\n" \
#insn " %1, %2\n" \
"csrw mstatus, %0" \
: "+&r" (__mstatus), "=&r" (val) \
: "m" (*addr), "r" (MSTATUS_MPRV), "r" (__mepc)); \
return val; \
}
#define DECLARE_UNPRIVILEGED_STORE_FUNCTION(type, insn) \
static inline void store_##type(type *addr, type val, ulong mepc) \
{ \
register ulong __mepc asm ("a2") = mepc; \
register ulong __mstatus asm ("a3"); \
asm volatile ("csrrs %0, mstatus, %3\n" \
#insn " %1, %2\n" \
"csrw mstatus, %0" \
: "+&r" (__mstatus) \
: "r" (val), "m" (*addr), "r" (MSTATUS_MPRV), "r" (__mepc)); \
}
DECLARE_UNPRIVILEGED_LOAD_FUNCTION(u8, lbu)
DECLARE_UNPRIVILEGED_LOAD_FUNCTION(u16, lhu)
DECLARE_UNPRIVILEGED_LOAD_FUNCTION(s8, lb)
DECLARE_UNPRIVILEGED_LOAD_FUNCTION(s16, lh)
DECLARE_UNPRIVILEGED_LOAD_FUNCTION(s32, lw)
DECLARE_UNPRIVILEGED_STORE_FUNCTION(u8, sb)
DECLARE_UNPRIVILEGED_STORE_FUNCTION(u16, sh)
DECLARE_UNPRIVILEGED_STORE_FUNCTION(u32, sw)
#if __riscv_xlen == 64
DECLARE_UNPRIVILEGED_LOAD_FUNCTION(u32, lwu)
DECLARE_UNPRIVILEGED_LOAD_FUNCTION(u64, ld)
DECLARE_UNPRIVILEGED_STORE_FUNCTION(u64, sd)
DECLARE_UNPRIVILEGED_LOAD_FUNCTION(ulong, ld)
#else
DECLARE_UNPRIVILEGED_LOAD_FUNCTION(u32, lw)
DECLARE_UNPRIVILEGED_LOAD_FUNCTION(ulong, lw)
static inline u64 load_u64(const u64 *addr, ulong mepc)
{
return load_u32((u32 *)addr, mepc)
+ ((u64)load_u32((u32 *)addr + 1, mepc) << 32);
}
static inline void store_u64(u64 *addr, u64 val, ulong mepc)
{
store_u32((u32 *)addr, val, mepc);
store_u32((u32 *)addr + 1, val >> 32, mepc);
}
#endif
static inline ulong get_insn(ulong mepc, ulong *mstatus)
{
register ulong __mepc asm ("a2") = mepc;
register ulong __mstatus asm ("a3");
ulong val;
#ifndef __riscv_compressed
asm ("csrrs %[mstatus], mstatus, %[mprv]\n"
STR(LWU) " %[insn], (%[addr])\n"
"csrw mstatus, %[mstatus]"
: [mstatus] "+&r" (__mstatus), [insn] "=&r" (val)
: [mprv] "r" (MSTATUS_MPRV | MSTATUS_MXR), [addr] "r" (__mepc));
#else
ulong rvc_mask = 3, tmp;
asm ("csrrs %[mstatus], mstatus, %[mprv]\n"
"and %[tmp], %[addr], 2\n"
"bnez %[tmp], 1f\n"
STR(LWU) " %[insn], (%[addr])\n"
"and %[tmp], %[insn], %[rvc_mask]\n"
"beq %[tmp], %[rvc_mask], 2f\n"
"sll %[insn], %[insn], %[xlen_minus_16]\n"
"srl %[insn], %[insn], %[xlen_minus_16]\n"
"j 2f\n"
"1:\n"
"lhu %[insn], (%[addr])\n"
"and %[tmp], %[insn], %[rvc_mask]\n"
"bne %[tmp], %[rvc_mask], 2f\n"
"lhu %[tmp], 2(%[addr])\n"
"sll %[tmp], %[tmp], 16\n"
"add %[insn], %[insn], %[tmp]\n"
"2: csrw mstatus, %[mstatus]"
: [mstatus] "+&r" (__mstatus), [insn] "=&r" (val), [tmp] "=&r" (tmp)
: [mprv] "r" (MSTATUS_MPRV | MSTATUS_MXR), [addr] "r" (__mepc),
[rvc_mask] "r" (rvc_mask), [xlen_minus_16] "i" (__riscv_xlen - 16));
#endif
*mstatus = __mstatus;
return val;
}
#endif