all: run clang-format and update checked-in files
Noisy commit, no functional changes. Generated with an current upstream clang-format and: clang-format -i $(find . -name \*.[ch]) Signed-off-by: Olof Johansson <olof@lixom.net>
This commit is contained in:
parent
fbf986ac2a
commit
10baa64c02
|
@ -9,10 +9,10 @@
|
|||
|
||||
#include <sbi/sbi_ecall_interface.h>
|
||||
|
||||
#define wfi() \
|
||||
do { \
|
||||
__asm__ __volatile__ ("wfi" ::: "memory"); \
|
||||
} while (0)
|
||||
#define wfi() \
|
||||
do { \
|
||||
__asm__ __volatile__("wfi" ::: "memory"); \
|
||||
} while (0)
|
||||
|
||||
void test_main(unsigned long a0, unsigned long a1)
|
||||
{
|
||||
|
|
|
@ -84,74 +84,81 @@
|
|||
|
||||
#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_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_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_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_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_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_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"); \
|
||||
})
|
||||
#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)
|
||||
#define wfi() \
|
||||
do { \
|
||||
__asm__ __volatile__("wfi" ::: "memory"); \
|
||||
} while (0)
|
||||
|
||||
static inline int misa_extension(char ext)
|
||||
{
|
||||
|
@ -177,11 +184,11 @@ static inline void misa_string(char *out, unsigned int out_sz)
|
|||
out++;
|
||||
}
|
||||
|
||||
int pmp_set(unsigned int n, unsigned long prot,
|
||||
unsigned long addr, unsigned long log2len);
|
||||
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);
|
||||
int pmp_get(unsigned int n, unsigned long *prot_out, unsigned long *addr_out,
|
||||
unsigned long *log2len_out);
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
|
|
|
@ -14,11 +14,12 @@ typedef struct {
|
|||
volatile long counter;
|
||||
} atomic_t;
|
||||
|
||||
#define ATOMIC_INIT(_lptr, val) \
|
||||
(_lptr)->counter = (val)
|
||||
#define ATOMIC_INIT(_lptr, val) (_lptr)->counter = (val)
|
||||
|
||||
#define ATOMIC_INITIALIZER(val) \
|
||||
{ .counter = (val), }
|
||||
#define ATOMIC_INITIALIZER(val) \
|
||||
{ \
|
||||
.counter = (val), \
|
||||
}
|
||||
|
||||
long atomic_read(atomic_t *atom);
|
||||
|
||||
|
|
|
@ -41,17 +41,17 @@
|
|||
|
||||
/* clang-format on */
|
||||
|
||||
#define __smp_store_release(p, v) \
|
||||
do { \
|
||||
RISCV_FENCE(rw,w); \
|
||||
*(p) = (v); \
|
||||
} while (0)
|
||||
#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; \
|
||||
})
|
||||
#define __smp_load_acquire(p) \
|
||||
({ \
|
||||
typeof(*p) ___p1 = *(p); \
|
||||
RISCV_FENCE(r, rw); \
|
||||
___p1; \
|
||||
})
|
||||
|
||||
#endif
|
||||
|
|
|
@ -21,28 +21,49 @@
|
|||
|
||||
#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 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_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)
|
||||
|
@ -50,7 +71,7 @@
|
|||
#define GET_FFLAGS() csr_read(CSR_FFLAGS)
|
||||
#define SET_FFLAGS(value) csr_write(CSR_FFLAGS, (value))
|
||||
|
||||
#define SET_FS_DIRTY() ((void) 0)
|
||||
#define SET_FS_DIRTY() ((void)0)
|
||||
|
||||
#else
|
||||
#error "Floating point emulation not supported.\n"
|
||||
|
@ -62,8 +83,10 @@
|
|||
#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 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))
|
||||
|
|
|
@ -15,23 +15,23 @@
|
|||
|
||||
static inline void __raw_writeb(u8 val, volatile void *addr)
|
||||
{
|
||||
asm volatile("sb %0, 0(%1)" : : "r" (val), "r" (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));
|
||||
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));
|
||||
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));
|
||||
asm volatile("sd %0, 0(%1)" : : "r"(val), "r"(addr));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -39,7 +39,7 @@ static inline u8 __raw_readb(const volatile void *addr)
|
|||
{
|
||||
u8 val;
|
||||
|
||||
asm volatile("lb %0, 0(%1)" : "=r" (val) : "r" (addr));
|
||||
asm volatile("lb %0, 0(%1)" : "=r"(val) : "r"(addr));
|
||||
return val;
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ static inline u16 __raw_readw(const volatile void *addr)
|
|||
{
|
||||
u16 val;
|
||||
|
||||
asm volatile("lh %0, 0(%1)" : "=r" (val) : "r" (addr));
|
||||
asm volatile("lh %0, 0(%1)" : "=r"(val) : "r"(addr));
|
||||
return val;
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,7 @@ static inline u32 __raw_readl(const volatile void *addr)
|
|||
{
|
||||
u32 val;
|
||||
|
||||
asm volatile("lw %0, 0(%1)" : "=r" (val) : "r" (addr));
|
||||
asm volatile("lw %0, 0(%1)" : "=r"(val) : "r"(addr));
|
||||
return val;
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,7 @@ static inline u64 __raw_readq(const volatile void *addr)
|
|||
{
|
||||
u64 val;
|
||||
|
||||
asm volatile("ld %0, 0(%1)" : "=r" (val) : "r" (addr));
|
||||
asm volatile("ld %0, 0(%1)" : "=r"(val) : "r"(addr));
|
||||
return val;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -14,13 +14,14 @@ typedef struct {
|
|||
volatile long lock;
|
||||
} spinlock_t;
|
||||
|
||||
#define __RISCV_SPIN_UNLOCKED 0
|
||||
#define __RISCV_SPIN_UNLOCKED 0
|
||||
|
||||
#define SPIN_LOCK_INIT(_lptr) \
|
||||
(_lptr)->lock = __RISCV_SPIN_UNLOCKED
|
||||
#define SPIN_LOCK_INIT(_lptr) (_lptr)->lock = __RISCV_SPIN_UNLOCKED
|
||||
|
||||
#define SPIN_LOCK_INITIALIZER \
|
||||
{ .lock = __RISCV_SPIN_UNLOCKED, }
|
||||
#define SPIN_LOCK_INITIALIZER \
|
||||
{ \
|
||||
.lock = __RISCV_SPIN_UNLOCKED, \
|
||||
}
|
||||
|
||||
int spin_lock_check(spinlock_t *lock);
|
||||
|
||||
|
|
|
@ -14,29 +14,30 @@
|
|||
#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) \
|
||||
{ \
|
||||
register ulong __mstatus asm ("a2"); \
|
||||
type val; \
|
||||
asm ("csrrs %0, "STR(CSR_MSTATUS)", %3\n" \
|
||||
#insn " %1, %2\n" \
|
||||
"csrw "STR(CSR_MSTATUS)", %0" \
|
||||
: "+&r" (__mstatus), "=&r" (val) \
|
||||
: "m" (*addr), "r" (MSTATUS_MPRV)); \
|
||||
return val; \
|
||||
}
|
||||
#define DECLARE_UNPRIVILEGED_LOAD_FUNCTION(type, insn) \
|
||||
static inline type load_##type(const type *addr) \
|
||||
{ \
|
||||
register ulong __mstatus asm("a2"); \
|
||||
type val; \
|
||||
asm("csrrs %0, " STR(CSR_MSTATUS) ", %3\n" #insn " %1, %2\n" \
|
||||
"csrw " STR( \
|
||||
CSR_MSTATUS) ", %0" \
|
||||
: "+&r"(__mstatus), "=&r"(val) \
|
||||
: "m"(*addr), "r"(MSTATUS_MPRV)); \
|
||||
return val; \
|
||||
}
|
||||
|
||||
#define DECLARE_UNPRIVILEGED_STORE_FUNCTION(type, insn) \
|
||||
static inline void store_##type(type *addr, type val) \
|
||||
{ \
|
||||
register ulong __mstatus asm ("a3"); \
|
||||
asm volatile ("csrrs %0, "STR(CSR_MSTATUS)", %3\n" \
|
||||
#insn " %1, %2\n" \
|
||||
"csrw "STR(CSR_MSTATUS)", %0" \
|
||||
: "+&r" (__mstatus) \
|
||||
: "r" (val), "m" (*addr), "r" (MSTATUS_MPRV)); \
|
||||
}
|
||||
#define DECLARE_UNPRIVILEGED_STORE_FUNCTION(type, insn) \
|
||||
static inline void store_##type(type *addr, type val) \
|
||||
{ \
|
||||
register ulong __mstatus asm("a3"); \
|
||||
asm volatile( \
|
||||
"csrrs %0, " STR( \
|
||||
CSR_MSTATUS) ", %3\n" #insn " %1, %2\n" \
|
||||
"csrw " STR(CSR_MSTATUS) ", %0" \
|
||||
: "+&r"(__mstatus) \
|
||||
: "r"(val), "m"(*addr), "r"(MSTATUS_MPRV)); \
|
||||
}
|
||||
|
||||
DECLARE_UNPRIVILEGED_LOAD_FUNCTION(u8, lbu)
|
||||
DECLARE_UNPRIVILEGED_LOAD_FUNCTION(u16, lhu)
|
||||
|
@ -57,8 +58,7 @@ DECLARE_UNPRIVILEGED_LOAD_FUNCTION(ulong, lw)
|
|||
|
||||
static inline u64 load_u64(const u64 *addr)
|
||||
{
|
||||
return load_u32((u32 *)addr)
|
||||
+ ((u64)load_u32((u32 *)addr + 1) << 32);
|
||||
return load_u32((u32 *)addr) + ((u64)load_u32((u32 *)addr + 1) << 32);
|
||||
}
|
||||
|
||||
static inline void store_u64(u64 *addr, u64 val)
|
||||
|
@ -70,45 +70,45 @@ static inline void store_u64(u64 *addr, u64 val)
|
|||
|
||||
static inline ulong get_insn(ulong mepc, ulong *mstatus)
|
||||
{
|
||||
register ulong __mepc asm ("a2") = mepc;
|
||||
register ulong __mstatus asm ("a3");
|
||||
register ulong __mepc asm("a2") = mepc;
|
||||
register ulong __mstatus asm("a3");
|
||||
ulong val;
|
||||
#ifndef __riscv_compressed
|
||||
asm ("csrrs %[mstatus], "STR(CSR_MSTATUS)", %[mprv]\n"
|
||||
asm("csrrs %[mstatus], " STR(CSR_MSTATUS) ", %[mprv]\n"
|
||||
#if __riscv_xlen == 64
|
||||
STR(LWU) " %[insn], (%[addr])\n"
|
||||
STR(LWU) " %[insn], (%[addr])\n"
|
||||
#else
|
||||
STR(LW) " %[insn], (%[addr])\n"
|
||||
STR(LW) " %[insn], (%[addr])\n"
|
||||
#endif
|
||||
"csrw "STR(CSR_MSTATUS)", %[mstatus]"
|
||||
: [mstatus] "+&r" (__mstatus), [insn] "=&r" (val)
|
||||
: [mprv] "r" (MSTATUS_MPRV|MSTATUS_MXR), [addr] "r" (__mepc));
|
||||
"csrw " STR(CSR_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], "STR(CSR_MSTATUS)", %[mprv]\n"
|
||||
"and %[tmp], %[addr], 2\n"
|
||||
"bnez %[tmp], 1f\n"
|
||||
asm("csrrs %[mstatus], " STR(CSR_MSTATUS) ", %[mprv]\n"
|
||||
"and %[tmp], %[addr], 2\n"
|
||||
"bnez %[tmp], 1f\n"
|
||||
#if __riscv_xlen == 64
|
||||
STR(LWU) " %[insn], (%[addr])\n"
|
||||
STR(LWU) " %[insn], (%[addr])\n"
|
||||
#else
|
||||
STR(LW) " %[insn], (%[addr])\n"
|
||||
STR(LW) " %[insn], (%[addr])\n"
|
||||
#endif
|
||||
"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 "STR(CSR_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));
|
||||
"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 " STR(CSR_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
|
||||
if (mstatus)
|
||||
*mstatus = __mstatus;
|
||||
|
|
|
@ -93,6 +93,6 @@ static inline int __ffs(unsigned long word)
|
|||
*
|
||||
* Undefined if no zero exists, so code should check against ~0UL first.
|
||||
*/
|
||||
#define ffz(x) __ffs(~(x))
|
||||
#define ffz(x) __ffs(~(x))
|
||||
|
||||
#endif
|
||||
|
|
|
@ -13,19 +13,20 @@
|
|||
#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 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 INSERT_FIELD(val, which, fieldval) \
|
||||
(((val) & ~(which)) | ((fieldval) * ((which) & ~((which)-1))))
|
||||
|
||||
#define STR(x) XSTR(x)
|
||||
#define XSTR(x) #x
|
||||
|
||||
#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
|
||||
#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
|
||||
#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
|
||||
#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
|
||||
#endif
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
#include <sbi/sbi_types.h>
|
||||
|
||||
#define __printf(a, b) __attribute__((format(printf, a, b)))
|
||||
#define __printf(a, b) __attribute__((format(printf, a, b)))
|
||||
|
||||
bool sbi_isprintable(char ch);
|
||||
|
||||
|
@ -26,8 +26,7 @@ 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(3, 4) sbi_snprintf(char *out, u32 out_sz, const char *format, ...);
|
||||
|
||||
int __printf(1, 2) sbi_printf(const char *format, ...);
|
||||
|
||||
|
|
|
@ -19,8 +19,7 @@ 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,
|
||||
int sbi_ecall_handler(u32 hartid, ulong mcause, struct sbi_trap_regs *regs,
|
||||
struct sbi_scratch *scratch);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -24,24 +24,24 @@
|
|||
|
||||
/* clang-format on */
|
||||
|
||||
#define SBI_ECALL(__num, __a0, __a1, __a2) ({ \
|
||||
register unsigned long a0 asm ("a0") = (unsigned long)(__a0); \
|
||||
register unsigned long a1 asm ("a1") = (unsigned long)(__a1); \
|
||||
register unsigned long a2 asm ("a2") = (unsigned long)(__a2); \
|
||||
register unsigned long a7 asm ("a7") = (unsigned long)(__num); \
|
||||
asm volatile ("ecall" \
|
||||
: "+r" (a0) \
|
||||
: "r" (a1), "r" (a2), "r" (a7) \
|
||||
: "memory"); \
|
||||
a0; \
|
||||
})
|
||||
#define SBI_ECALL(__num, __a0, __a1, __a2) \
|
||||
({ \
|
||||
register unsigned long a0 asm("a0") = (unsigned long)(__a0); \
|
||||
register unsigned long a1 asm("a1") = (unsigned long)(__a1); \
|
||||
register unsigned long a2 asm("a2") = (unsigned long)(__a2); \
|
||||
register unsigned long a7 asm("a7") = (unsigned long)(__num); \
|
||||
asm volatile("ecall" \
|
||||
: "+r"(a0) \
|
||||
: "r"(a1), "r"(a2), "r"(a7) \
|
||||
: "memory"); \
|
||||
a0; \
|
||||
})
|
||||
|
||||
#define SBI_ECALL_0(__num) SBI_ECALL(__num, 0, 0, 0)
|
||||
#define SBI_ECALL_1(__num, __a0) SBI_ECALL(__num, __a0, 0, 0)
|
||||
#define SBI_ECALL_2(__num, __a0, __a1) SBI_ECALL(__num, __a0, __a1, 0)
|
||||
#define SBI_ECALL_0(__num) SBI_ECALL(__num, 0, 0, 0)
|
||||
#define SBI_ECALL_1(__num, __a0) SBI_ECALL(__num, __a0, 0, 0)
|
||||
#define SBI_ECALL_2(__num, __a0, __a1) SBI_ECALL(__num, __a0, __a1, 0)
|
||||
|
||||
#define sbi_ecall_console_putc(c) \
|
||||
SBI_ECALL_1(SBI_ECALL_CONSOLE_PUTCHAR, (c));
|
||||
#define sbi_ecall_console_putc(c) SBI_ECALL_1(SBI_ECALL_CONSOLE_PUTCHAR, (c));
|
||||
|
||||
static inline void sbi_ecall_console_puts(const char *str)
|
||||
{
|
||||
|
|
|
@ -14,14 +14,10 @@
|
|||
|
||||
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_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);
|
||||
int sbi_emulate_csr_write(int csr_num, u32 hartid, ulong mstatus,
|
||||
struct sbi_scratch *scratch, ulong csr_val);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -32,12 +32,12 @@ enum sbi_fifo_inplace_update_types {
|
|||
|
||||
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);
|
||||
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));
|
||||
int (*fptr)(void *in, void *data));
|
||||
u16 sbi_fifo_avail(struct sbi_fifo *fifo);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -20,10 +20,9 @@ void sbi_hart_pmp_dump(struct sbi_scratch *scratch);
|
|||
|
||||
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);
|
||||
void __attribute__((noreturn))
|
||||
sbi_hart_switch_mode(unsigned long arg0, unsigned long arg1,
|
||||
unsigned long next_addr, unsigned long next_mode);
|
||||
|
||||
void sbi_hart_mark_available(u32 hartid);
|
||||
|
||||
|
|
|
@ -44,8 +44,8 @@ struct sbi_tlb_info {
|
|||
|
||||
#define SBI_TLB_INFO_SIZE sizeof(struct sbi_tlb_info)
|
||||
|
||||
int sbi_ipi_send_many(struct sbi_scratch *scratch,
|
||||
ulong *pmask, u32 event, void *data);
|
||||
int sbi_ipi_send_many(struct sbi_scratch *scratch, ulong *pmask, u32 event,
|
||||
void *data);
|
||||
|
||||
void sbi_ipi_clear_smode(struct sbi_scratch *scratch);
|
||||
|
||||
|
|
|
@ -11,13 +11,13 @@
|
|||
#define __SBI_PLATFORM_H__
|
||||
|
||||
/** Offset of name in struct sbi_platform */
|
||||
#define SBI_PLATFORM_NAME_OFFSET (0x0)
|
||||
#define SBI_PLATFORM_NAME_OFFSET (0x0)
|
||||
/** Offset of features in struct sbi_platform */
|
||||
#define SBI_PLATFORM_FEATURES_OFFSET (0x40)
|
||||
#define SBI_PLATFORM_FEATURES_OFFSET (0x40)
|
||||
/** Offset of hart_count in struct sbi_platform */
|
||||
#define SBI_PLATFORM_HART_COUNT_OFFSET (0x48)
|
||||
#define SBI_PLATFORM_HART_COUNT_OFFSET (0x48)
|
||||
/** Offset of hart_stack_size in struct sbi_platform */
|
||||
#define SBI_PLATFORM_HART_STACK_SIZE_OFFSET (0x4c)
|
||||
#define SBI_PLATFORM_HART_STACK_SIZE_OFFSET (0x4c)
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
|
@ -26,25 +26,23 @@
|
|||
/** Possible feature flags of a platform */
|
||||
enum sbi_platform_features {
|
||||
/** Platform has timer value */
|
||||
SBI_PLATFORM_HAS_TIMER_VALUE = (1 << 0),
|
||||
SBI_PLATFORM_HAS_TIMER_VALUE = (1 << 0),
|
||||
/** Platform has HART hotplug support */
|
||||
SBI_PLATFORM_HAS_HART_HOTPLUG = (1 << 1),
|
||||
SBI_PLATFORM_HAS_HART_HOTPLUG = (1 << 1),
|
||||
/** Platform has PMP support */
|
||||
SBI_PLATFORM_HAS_PMP = (1 << 2),
|
||||
SBI_PLATFORM_HAS_PMP = (1 << 2),
|
||||
/** Platform has S-mode counter enable */
|
||||
SBI_PLATFORM_HAS_SCOUNTEREN = (1 << 3),
|
||||
SBI_PLATFORM_HAS_SCOUNTEREN = (1 << 3),
|
||||
/** Platform has M-mode counter enable */
|
||||
SBI_PLATFORM_HAS_MCOUNTEREN = (1 << 4),
|
||||
SBI_PLATFORM_HAS_MCOUNTEREN = (1 << 4),
|
||||
/** Platform has fault delegation support */
|
||||
SBI_PLATFORM_HAS_MFAULTS_DELEGATION = (1 << 5),
|
||||
SBI_PLATFORM_HAS_MFAULTS_DELEGATION = (1 << 5),
|
||||
};
|
||||
|
||||
/** Default feature set for a platform */
|
||||
#define SBI_PLATFORM_DEFAULT_FEATURES \
|
||||
(SBI_PLATFORM_HAS_TIMER_VALUE | \
|
||||
SBI_PLATFORM_HAS_PMP | \
|
||||
SBI_PLATFORM_HAS_SCOUNTEREN | \
|
||||
SBI_PLATFORM_HAS_MCOUNTEREN | \
|
||||
#define SBI_PLATFORM_DEFAULT_FEATURES \
|
||||
(SBI_PLATFORM_HAS_TIMER_VALUE | SBI_PLATFORM_HAS_PMP | \
|
||||
SBI_PLATFORM_HAS_SCOUNTEREN | SBI_PLATFORM_HAS_MCOUNTEREN | \
|
||||
SBI_PLATFORM_HAS_MFAULTS_DELEGATION)
|
||||
|
||||
/** Representation of a platform */
|
||||
|
@ -71,8 +69,8 @@ struct sbi_platform {
|
|||
* Get PMP regions details (namely: protection, base address,
|
||||
* and size) for given HART
|
||||
*/
|
||||
int (*pmp_region_info)(u32 hartid, u32 index,
|
||||
ulong *prot, ulong *addr, ulong *log2size);
|
||||
int (*pmp_region_info)(u32 hartid, u32 index, ulong *prot, ulong *addr,
|
||||
ulong *log2size);
|
||||
|
||||
/** Write a character to the platform console output */
|
||||
void (*console_putc)(char ch);
|
||||
|
@ -109,28 +107,28 @@ struct sbi_platform {
|
|||
} __packed;
|
||||
|
||||
/** Get pointer to sbi_platform for sbi_scratch pointer */
|
||||
#define sbi_platform_ptr(__s) \
|
||||
#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))
|
||||
#define sbi_platform_thishart_ptr() \
|
||||
((const struct sbi_platform *)(sbi_scratch_thishart_ptr() \
|
||||
->platform_addr))
|
||||
/** Check whether the platform supports timer value */
|
||||
#define sbi_platform_has_timer_value(__p) \
|
||||
#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) \
|
||||
#define sbi_platform_has_hart_hotplug(__p) \
|
||||
((__p)->features & SBI_PLATFORM_HAS_HART_HOTPLUG)
|
||||
/** Check whether the platform has PMP support */
|
||||
#define sbi_platform_has_pmp(__p) \
|
||||
((__p)->features & SBI_PLATFORM_HAS_PMP)
|
||||
#define sbi_platform_has_pmp(__p) ((__p)->features & SBI_PLATFORM_HAS_PMP)
|
||||
/** Check whether the platform supports scounteren CSR */
|
||||
#define sbi_platform_has_scounteren(__p) \
|
||||
#define sbi_platform_has_scounteren(__p) \
|
||||
((__p)->features & SBI_PLATFORM_HAS_SCOUNTEREN)
|
||||
/** Check whether the platform supports mcounteren CSR */
|
||||
#define sbi_platform_has_mcounteren(__p) \
|
||||
#define sbi_platform_has_mcounteren(__p) \
|
||||
((__p)->features & SBI_PLATFORM_HAS_MCOUNTEREN)
|
||||
/** Check whether the platform supports fault delegation */
|
||||
#define sbi_platform_has_mfaults_delegation(__p) \
|
||||
#define sbi_platform_has_mfaults_delegation(__p) \
|
||||
((__p)->features & SBI_PLATFORM_HAS_MFAULTS_DELEGATION)
|
||||
|
||||
/**
|
||||
|
@ -258,8 +256,8 @@ static inline int sbi_platform_pmp_region_info(const struct sbi_platform *plat,
|
|||
ulong *log2size)
|
||||
{
|
||||
if (plat && plat->pmp_region_info)
|
||||
return plat->pmp_region_info(hartid, index,
|
||||
prot, addr, log2size);
|
||||
return plat->pmp_region_info(hartid, index, prot, addr,
|
||||
log2size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -395,9 +393,8 @@ static inline u64 sbi_platform_timer_value(const struct sbi_platform *plat)
|
|||
* @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)
|
||||
static inline void
|
||||
sbi_platform_timer_event_start(const struct sbi_platform *plat, u64 next_event)
|
||||
{
|
||||
if (plat && plat->timer_event_start)
|
||||
plat->timer_event_start(next_event);
|
||||
|
@ -408,8 +405,8 @@ static inline void sbi_platform_timer_event_start(
|
|||
*
|
||||
* @param plat pointer to struct sbi_platform
|
||||
*/
|
||||
static inline void sbi_platform_timer_event_stop(
|
||||
const struct sbi_platform *plat)
|
||||
static inline void
|
||||
sbi_platform_timer_event_stop(const struct sbi_platform *plat)
|
||||
{
|
||||
if (plat && plat->timer_event_stop)
|
||||
plat->timer_event_stop();
|
||||
|
|
|
@ -79,28 +79,28 @@ struct sbi_scratch {
|
|||
/** Possible options for OpenSBI library */
|
||||
enum sbi_scratch_options {
|
||||
/** Disable prints during boot */
|
||||
SBI_SCRATCH_NO_BOOT_PRINTS = (1 << 0),
|
||||
SBI_SCRATCH_NO_BOOT_PRINTS = (1 << 0),
|
||||
};
|
||||
|
||||
/** Get pointer to sbi_scratch for current HART */
|
||||
#define sbi_scratch_thishart_ptr() \
|
||||
((struct sbi_scratch *)csr_read(CSR_MSCRATCH))
|
||||
#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))
|
||||
#define sbi_scratch_thishart_arg1_ptr() \
|
||||
((void *)(sbi_scratch_thishart_ptr()->next_arg1))
|
||||
|
||||
/** Get pointer to sbi_ipi_data from sbi_scratch */
|
||||
#define sbi_ipi_data_ptr(scratch) \
|
||||
((struct sbi_ipi_data *)(void*)scratch + SBI_IPI_DATA_IPI_TYPE_OFFSET)
|
||||
#define sbi_ipi_data_ptr(scratch) \
|
||||
((struct sbi_ipi_data *)(void *)scratch + SBI_IPI_DATA_IPI_TYPE_OFFSET)
|
||||
|
||||
/** Get pointer to tlb flush info fifo header from sbi_scratch */
|
||||
#define sbi_tlb_fifo_head_ptr(scratch) \
|
||||
((struct sbi_fifo *)(void*)scratch + SBI_SCRATCH_TLB_QUEUE_HEAD_OFFSET)
|
||||
#define sbi_tlb_fifo_head_ptr(scratch) \
|
||||
((struct sbi_fifo *)(void *)scratch + SBI_SCRATCH_TLB_QUEUE_HEAD_OFFSET)
|
||||
|
||||
/** Get pointer to tlb flush info fifo queue address from sbi_scratch */
|
||||
#define sbi_tlb_fifo_mem_ptr(scratch) \
|
||||
(void *)((void*)scratch + SBI_SCRATCH_TLB_QUEUE_MEM_OFFSET)
|
||||
#define sbi_tlb_fifo_mem_ptr(scratch) \
|
||||
(void *)((void *)scratch + SBI_SCRATCH_TLB_QUEUE_MEM_OFFSET)
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -18,10 +18,10 @@ int sbi_system_early_init(struct sbi_scratch *scratch, bool cold_boot);
|
|||
|
||||
int sbi_system_final_init(struct sbi_scratch *scratch, bool cold_boot);
|
||||
|
||||
void __attribute__((noreturn)) sbi_system_reboot(struct sbi_scratch *scratch,
|
||||
u32 type);
|
||||
void __attribute__((noreturn))
|
||||
sbi_system_reboot(struct sbi_scratch *scratch, u32 type);
|
||||
|
||||
void __attribute__((noreturn)) sbi_system_shutdown(struct sbi_scratch *scratch,
|
||||
u32 type);
|
||||
void __attribute__((noreturn))
|
||||
sbi_system_shutdown(struct sbi_scratch *scratch, u32 type);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -86,10 +86,9 @@
|
|||
/* 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__)
|
||||
#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)
|
||||
#define SBI_TRAP_REGS_SIZE SBI_TRAP_REGS_OFFSET(last)
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
|
@ -169,12 +168,10 @@ struct sbi_trap_regs {
|
|||
|
||||
struct sbi_scratch;
|
||||
|
||||
int sbi_trap_redirect(struct sbi_trap_regs *regs,
|
||||
struct sbi_scratch *scratch,
|
||||
int sbi_trap_redirect(struct sbi_trap_regs *regs, struct sbi_scratch *scratch,
|
||||
ulong epc, ulong cause, ulong tval);
|
||||
|
||||
void sbi_trap_handler(struct sbi_trap_regs *regs,
|
||||
struct sbi_scratch *scratch);
|
||||
void sbi_trap_handler(struct sbi_trap_regs *regs, struct sbi_scratch *scratch);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#ifndef __SBI_VERSION_H__
|
||||
#define __SBI_VERSION_H__
|
||||
|
||||
#define OPENSBI_VERSION_MAJOR 0
|
||||
#define OPENSBI_VERSION_MINOR 3
|
||||
#define OPENSBI_VERSION_MAJOR 0
|
||||
#define OPENSBI_VERSION_MINOR 3
|
||||
|
||||
#endif
|
||||
|
|
|
@ -163,28 +163,26 @@ static unsigned long ctz(unsigned long x)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int pmp_set(unsigned int n, unsigned long prot,
|
||||
unsigned long addr, unsigned long log2len)
|
||||
int pmp_set(unsigned int n, unsigned long prot, unsigned long addr,
|
||||
unsigned long log2len)
|
||||
{
|
||||
int pmpcfg_csr, pmpcfg_shift, pmpaddr_csr;
|
||||
unsigned long cfgmask, pmpcfg;
|
||||
unsigned long addrmask, pmpaddr;
|
||||
|
||||
/* check parameters */
|
||||
if (n >= PMP_COUNT ||
|
||||
log2len > __riscv_xlen ||
|
||||
log2len < PMP_SHIFT)
|
||||
if (n >= PMP_COUNT || log2len > __riscv_xlen || log2len < PMP_SHIFT)
|
||||
return SBI_EINVAL;
|
||||
|
||||
/* calculate PMP register and offset */
|
||||
/* calculate PMP register and offset */
|
||||
#if __riscv_xlen == 32
|
||||
pmpcfg_csr = CSR_PMPCFG0 + (n >> 2);
|
||||
pmpcfg_csr = CSR_PMPCFG0 + (n >> 2);
|
||||
pmpcfg_shift = (n & 3) << 3;
|
||||
#elif __riscv_xlen == 64
|
||||
pmpcfg_csr = (CSR_PMPCFG0 + (n >> 2)) & ~1;
|
||||
pmpcfg_csr = (CSR_PMPCFG0 + (n >> 2)) & ~1;
|
||||
pmpcfg_shift = (n & 7) << 3;
|
||||
#else
|
||||
pmpcfg_csr = -1;
|
||||
pmpcfg_csr = -1;
|
||||
pmpcfg_shift = -1;
|
||||
#endif
|
||||
pmpaddr_csr = CSR_PMPADDR0 + n;
|
||||
|
@ -194,7 +192,7 @@ int pmp_set(unsigned int n, unsigned long prot,
|
|||
/* encode PMP config */
|
||||
prot |= (log2len == PMP_SHIFT) ? PMP_A_NA4 : PMP_A_NAPOT;
|
||||
cfgmask = ~(0xff << pmpcfg_shift);
|
||||
pmpcfg = (csr_read_num(pmpcfg_csr) & cfgmask);
|
||||
pmpcfg = (csr_read_num(pmpcfg_csr) & cfgmask);
|
||||
pmpcfg |= ((prot << pmpcfg_shift) & ~cfgmask);
|
||||
|
||||
/* encode PMP address */
|
||||
|
@ -205,7 +203,7 @@ int pmp_set(unsigned int n, unsigned long prot,
|
|||
pmpaddr = -1UL;
|
||||
} else {
|
||||
addrmask = (1UL << (log2len - PMP_SHIFT)) - 1;
|
||||
pmpaddr = ((addr >> PMP_SHIFT) & ~addrmask);
|
||||
pmpaddr = ((addr >> PMP_SHIFT) & ~addrmask);
|
||||
pmpaddr |= (addrmask >> 1);
|
||||
}
|
||||
}
|
||||
|
@ -217,28 +215,27 @@ int pmp_set(unsigned int n, unsigned long prot,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int pmp_get(unsigned int n, unsigned long *prot_out,
|
||||
unsigned long *addr_out, unsigned long *log2len_out)
|
||||
int pmp_get(unsigned int n, unsigned long *prot_out, unsigned long *addr_out,
|
||||
unsigned long *log2len_out)
|
||||
{
|
||||
int pmpcfg_csr, pmpcfg_shift, pmpaddr_csr;
|
||||
unsigned long cfgmask, pmpcfg, prot;
|
||||
unsigned long t1, addr, log2len;
|
||||
|
||||
/* check parameters */
|
||||
if (n >= PMP_COUNT || !prot_out ||
|
||||
!addr_out || !log2len_out)
|
||||
if (n >= PMP_COUNT || !prot_out || !addr_out || !log2len_out)
|
||||
return SBI_EINVAL;
|
||||
*prot_out = *addr_out = *log2len_out = 0;
|
||||
|
||||
/* calculate PMP register and offset */
|
||||
#if __riscv_xlen == 32
|
||||
pmpcfg_csr = CSR_PMPCFG0 + (n >> 2);
|
||||
pmpcfg_csr = CSR_PMPCFG0 + (n >> 2);
|
||||
pmpcfg_shift = (n & 3) << 3;
|
||||
#elif __riscv_xlen == 64
|
||||
pmpcfg_csr = (CSR_PMPCFG0 + (n >> 2)) & ~1;
|
||||
pmpcfg_csr = (CSR_PMPCFG0 + (n >> 2)) & ~1;
|
||||
pmpcfg_shift = (n & 7) << 3;
|
||||
#else
|
||||
pmpcfg_csr = -1;
|
||||
pmpcfg_csr = -1;
|
||||
pmpcfg_shift = -1;
|
||||
#endif
|
||||
pmpaddr_csr = CSR_PMPADDR0 + n;
|
||||
|
@ -247,28 +244,28 @@ int pmp_get(unsigned int n, unsigned long *prot_out,
|
|||
|
||||
/* decode PMP config */
|
||||
cfgmask = (0xff << pmpcfg_shift);
|
||||
pmpcfg = csr_read_num(pmpcfg_csr) & cfgmask;
|
||||
prot = pmpcfg >> pmpcfg_shift;
|
||||
pmpcfg = csr_read_num(pmpcfg_csr) & cfgmask;
|
||||
prot = pmpcfg >> pmpcfg_shift;
|
||||
|
||||
/* decode PMP address */
|
||||
if ((prot & PMP_A) == PMP_A_NAPOT) {
|
||||
addr = csr_read_num(pmpaddr_csr);
|
||||
if (addr == -1UL) {
|
||||
addr = 0;
|
||||
addr = 0;
|
||||
log2len = __riscv_xlen;
|
||||
} else {
|
||||
t1 = ctz(~addr);
|
||||
addr = (addr & ~((1UL << t1) - 1)) << PMP_SHIFT;
|
||||
t1 = ctz(~addr);
|
||||
addr = (addr & ~((1UL << t1) - 1)) << PMP_SHIFT;
|
||||
log2len = (t1 + PMP_SHIFT + 1);
|
||||
}
|
||||
} else {
|
||||
addr = csr_read_num(pmpaddr_csr) << PMP_SHIFT;
|
||||
addr = csr_read_num(pmpaddr_csr) << PMP_SHIFT;
|
||||
log2len = PMP_SHIFT;
|
||||
}
|
||||
|
||||
/* return details */
|
||||
*prot_out = prot;
|
||||
*addr_out = addr;
|
||||
*prot_out = prot;
|
||||
*addr_out = addr;
|
||||
*log2len_out = log2len;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -30,11 +30,10 @@ long atomic_add_return(atomic_t *atom, long value)
|
|||
{
|
||||
long ret;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
" amoadd.w.aqrl %1, %2, %0"
|
||||
: "+A" (atom->counter), "=r" (ret)
|
||||
: "r" (value)
|
||||
: "memory");
|
||||
__asm__ __volatile__(" amoadd.w.aqrl %1, %2, %0"
|
||||
: "+A"(atom->counter), "=r"(ret)
|
||||
: "r"(value)
|
||||
: "memory");
|
||||
|
||||
return ret + value;
|
||||
}
|
||||
|
@ -43,99 +42,98 @@ long atomic_sub_return(atomic_t *atom, long value)
|
|||
{
|
||||
long ret;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
" amoadd.w.aqrl %1, %2, %0"
|
||||
: "+A" (atom->counter), "=r" (ret)
|
||||
: "r" (-value)
|
||||
: "memory");
|
||||
__asm__ __volatile__(" amoadd.w.aqrl %1, %2, %0"
|
||||
: "+A"(atom->counter), "=r"(ret)
|
||||
: "r"(-value)
|
||||
: "memory");
|
||||
|
||||
return ret - value;
|
||||
}
|
||||
|
||||
#define __xchg(ptr, new, size) \
|
||||
({ \
|
||||
__typeof__(ptr) __ptr = (ptr); \
|
||||
__typeof__(*(ptr)) __new = (new); \
|
||||
__typeof__(*(ptr)) __ret; \
|
||||
register unsigned int __rc; \
|
||||
switch (size) { \
|
||||
case 4: \
|
||||
__asm__ __volatile__ ( \
|
||||
"0: lr.w %0, %2\n" \
|
||||
" sc.w.rl %1, %z3, %2\n" \
|
||||
" bnez %1, 0b\n" \
|
||||
" fence rw, rw\n" \
|
||||
: "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \
|
||||
: "rJ" (__new) \
|
||||
: "memory"); \
|
||||
break; \
|
||||
case 8: \
|
||||
__asm__ __volatile__ ( \
|
||||
"0: lr.d %0, %2\n" \
|
||||
" sc.d.rl %1, %z3, %2\n" \
|
||||
" bnez %1, 0b\n" \
|
||||
" fence rw, rw\n" \
|
||||
: "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \
|
||||
: "rJ" (__new) \
|
||||
: "memory"); \
|
||||
break; \
|
||||
default: \
|
||||
break; \
|
||||
} \
|
||||
__ret; \
|
||||
})
|
||||
#define __xchg(ptr, new, size) \
|
||||
({ \
|
||||
__typeof__(ptr) __ptr = (ptr); \
|
||||
__typeof__(*(ptr)) __new = (new); \
|
||||
__typeof__(*(ptr)) __ret; \
|
||||
register unsigned int __rc; \
|
||||
switch (size) { \
|
||||
case 4: \
|
||||
__asm__ __volatile__("0: lr.w %0, %2\n" \
|
||||
" sc.w.rl %1, %z3, %2\n" \
|
||||
" bnez %1, 0b\n" \
|
||||
" fence rw, rw\n" \
|
||||
: "=&r"(__ret), "=&r"(__rc), \
|
||||
"+A"(*__ptr) \
|
||||
: "rJ"(__new) \
|
||||
: "memory"); \
|
||||
break; \
|
||||
case 8: \
|
||||
__asm__ __volatile__("0: lr.d %0, %2\n" \
|
||||
" sc.d.rl %1, %z3, %2\n" \
|
||||
" bnez %1, 0b\n" \
|
||||
" fence rw, rw\n" \
|
||||
: "=&r"(__ret), "=&r"(__rc), \
|
||||
"+A"(*__ptr) \
|
||||
: "rJ"(__new) \
|
||||
: "memory"); \
|
||||
break; \
|
||||
default: \
|
||||
break; \
|
||||
} \
|
||||
__ret; \
|
||||
})
|
||||
|
||||
#define xchg(ptr, n) \
|
||||
({ \
|
||||
__typeof__(*(ptr)) _n_ = (n); \
|
||||
(__typeof__(*(ptr))) __xchg((ptr), _n_, sizeof(*(ptr))); \
|
||||
})
|
||||
#define xchg(ptr, n) \
|
||||
({ \
|
||||
__typeof__(*(ptr)) _n_ = (n); \
|
||||
(__typeof__(*(ptr))) __xchg((ptr), _n_, sizeof(*(ptr))); \
|
||||
})
|
||||
|
||||
#define __cmpxchg(ptr, old, new, size) \
|
||||
({ \
|
||||
__typeof__(ptr) __ptr = (ptr); \
|
||||
__typeof__(*(ptr)) __old = (old); \
|
||||
__typeof__(*(ptr)) __new = (new); \
|
||||
__typeof__(*(ptr)) __ret; \
|
||||
register unsigned int __rc; \
|
||||
switch (size) { \
|
||||
case 4: \
|
||||
__asm__ __volatile__ ( \
|
||||
"0: lr.w %0, %2\n" \
|
||||
" bne %0, %z3, 1f\n" \
|
||||
" sc.w.rl %1, %z4, %2\n" \
|
||||
" bnez %1, 0b\n" \
|
||||
" fence rw, rw\n" \
|
||||
"1:\n" \
|
||||
: "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \
|
||||
: "rJ" (__old), "rJ" (__new) \
|
||||
: "memory"); \
|
||||
break; \
|
||||
case 8: \
|
||||
__asm__ __volatile__ ( \
|
||||
"0: lr.d %0, %2\n" \
|
||||
" bne %0, %z3, 1f\n" \
|
||||
" sc.d.rl %1, %z4, %2\n" \
|
||||
" bnez %1, 0b\n" \
|
||||
" fence rw, rw\n" \
|
||||
"1:\n" \
|
||||
: "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \
|
||||
: "rJ" (__old), "rJ" (__new) \
|
||||
: "memory"); \
|
||||
break; \
|
||||
default: \
|
||||
break; \
|
||||
} \
|
||||
__ret; \
|
||||
})
|
||||
#define __cmpxchg(ptr, old, new, size) \
|
||||
({ \
|
||||
__typeof__(ptr) __ptr = (ptr); \
|
||||
__typeof__(*(ptr)) __old = (old); \
|
||||
__typeof__(*(ptr)) __new = (new); \
|
||||
__typeof__(*(ptr)) __ret; \
|
||||
register unsigned int __rc; \
|
||||
switch (size) { \
|
||||
case 4: \
|
||||
__asm__ __volatile__("0: lr.w %0, %2\n" \
|
||||
" bne %0, %z3, 1f\n" \
|
||||
" sc.w.rl %1, %z4, %2\n" \
|
||||
" bnez %1, 0b\n" \
|
||||
" fence rw, rw\n" \
|
||||
"1:\n" \
|
||||
: "=&r"(__ret), "=&r"(__rc), \
|
||||
"+A"(*__ptr) \
|
||||
: "rJ"(__old), "rJ"(__new) \
|
||||
: "memory"); \
|
||||
break; \
|
||||
case 8: \
|
||||
__asm__ __volatile__("0: lr.d %0, %2\n" \
|
||||
" bne %0, %z3, 1f\n" \
|
||||
" sc.d.rl %1, %z4, %2\n" \
|
||||
" bnez %1, 0b\n" \
|
||||
" fence rw, rw\n" \
|
||||
"1:\n" \
|
||||
: "=&r"(__ret), "=&r"(__rc), \
|
||||
"+A"(*__ptr) \
|
||||
: "rJ"(__old), "rJ"(__new) \
|
||||
: "memory"); \
|
||||
break; \
|
||||
default: \
|
||||
break; \
|
||||
} \
|
||||
__ret; \
|
||||
})
|
||||
|
||||
#define cmpxchg(ptr, o, n) \
|
||||
({ \
|
||||
__typeof__(*(ptr)) _o_ = (o); \
|
||||
__typeof__(*(ptr)) _n_ = (n); \
|
||||
(__typeof__(*(ptr))) __cmpxchg((ptr), \
|
||||
_o_, _n_, sizeof(*(ptr))); \
|
||||
})
|
||||
#define cmpxchg(ptr, o, n) \
|
||||
({ \
|
||||
__typeof__(*(ptr)) _o_ = (o); \
|
||||
__typeof__(*(ptr)) _n_ = (n); \
|
||||
(__typeof__(*(ptr))) \
|
||||
__cmpxchg((ptr), _o_, _n_, sizeof(*(ptr))); \
|
||||
})
|
||||
|
||||
long arch_atomic_cmpxchg(atomic_t *atom, long oldval, long newval)
|
||||
{
|
||||
|
@ -178,31 +176,30 @@ unsigned int atomic_raw_xchg_uint(volatile unsigned int *ptr,
|
|||
}
|
||||
|
||||
#if (BITS_PER_LONG == 64)
|
||||
#define __AMO(op) "amo" #op ".d"
|
||||
#define __AMO(op) "amo" #op ".d"
|
||||
#elif (BITS_PER_LONG == 32)
|
||||
#define __AMO(op) "amo" #op ".w"
|
||||
#define __AMO(op) "amo" #op ".w"
|
||||
#else
|
||||
#error "Unexpected BITS_PER_LONG"
|
||||
#endif
|
||||
|
||||
#define __atomic_op_bit_ord(op, mod, nr, addr, ord) \
|
||||
({ \
|
||||
unsigned long __res, __mask; \
|
||||
__mask = BIT_MASK(nr); \
|
||||
__asm__ __volatile__ ( \
|
||||
__AMO(op) #ord " %0, %2, %1" \
|
||||
: "=r" (__res), "+A" (addr[BIT_WORD(nr)]) \
|
||||
: "r" (mod(__mask)) \
|
||||
: "memory"); \
|
||||
__res; \
|
||||
})
|
||||
#define __atomic_op_bit_ord(op, mod, nr, addr, ord) \
|
||||
({ \
|
||||
unsigned long __res, __mask; \
|
||||
__mask = BIT_MASK(nr); \
|
||||
__asm__ __volatile__(__AMO(op) #ord " %0, %2, %1" \
|
||||
: "=r"(__res), "+A"(addr[BIT_WORD(nr)]) \
|
||||
: "r"(mod(__mask)) \
|
||||
: "memory"); \
|
||||
__res; \
|
||||
})
|
||||
|
||||
#define __atomic_op_bit(op, mod, nr, addr) \
|
||||
#define __atomic_op_bit(op, mod, nr, addr) \
|
||||
__atomic_op_bit_ord(op, mod, nr, addr, .aqrl)
|
||||
|
||||
/* Bitmask modifiers */
|
||||
#define __NOP(x) (x)
|
||||
#define __NOT(x) (~(x))
|
||||
#define __NOP(x) (x)
|
||||
#define __NOT(x) (~(x))
|
||||
|
||||
inline int atomic_raw_set_bit(int nr, volatile unsigned long *addr)
|
||||
{
|
||||
|
|
|
@ -19,11 +19,10 @@ int spin_trylock(spinlock_t *lock)
|
|||
{
|
||||
int tmp = 1, busy;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
" amoswap.w %0, %2, %1\n"
|
||||
RISCV_ACQUIRE_BARRIER
|
||||
: "=r" (busy), "+A" (lock->lock)
|
||||
: "r" (tmp)
|
||||
__asm__ __volatile__(
|
||||
" amoswap.w %0, %2, %1\n" RISCV_ACQUIRE_BARRIER
|
||||
: "=r"(busy), "+A"(lock->lock)
|
||||
: "r"(tmp)
|
||||
: "memory");
|
||||
|
||||
return !busy;
|
||||
|
|
|
@ -12,15 +12,12 @@
|
|||
#include <sbi/riscv_locks.h>
|
||||
|
||||
static const struct sbi_platform *console_plat = NULL;
|
||||
static spinlock_t console_out_lock = SPIN_LOCK_INITIALIZER;
|
||||
static spinlock_t console_out_lock = SPIN_LOCK_INITIALIZER;
|
||||
|
||||
bool sbi_isprintable(char c)
|
||||
{
|
||||
if (((31 < c) && (c < 127)) ||
|
||||
(c == '\f') ||
|
||||
(c == '\r') ||
|
||||
(c == '\n') ||
|
||||
(c == '\t')) {
|
||||
if (((31 < c) && (c < 127)) || (c == '\f') || (c == '\r') ||
|
||||
(c == '\n') || (c == '\t')) {
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
|
@ -54,22 +51,22 @@ void sbi_gets(char *s, int maxwidth, char endchar)
|
|||
char *retval = s;
|
||||
|
||||
while ((ch = sbi_getc()) != endchar && ch >= 0 && maxwidth > 1) {
|
||||
*retval = (char) ch;
|
||||
*retval = (char)ch;
|
||||
retval++;
|
||||
maxwidth--;
|
||||
}
|
||||
*retval = '\0';
|
||||
}
|
||||
|
||||
#define PAD_RIGHT 1
|
||||
#define PAD_ZERO 2
|
||||
#define PAD_ALTERNATE 4
|
||||
#define PRINT_BUF_LEN 64
|
||||
#define PAD_RIGHT 1
|
||||
#define PAD_ZERO 2
|
||||
#define PAD_ALTERNATE 4
|
||||
#define PRINT_BUF_LEN 64
|
||||
|
||||
#define va_start(v,l) __builtin_va_start((v),l)
|
||||
#define va_end __builtin_va_end
|
||||
#define va_arg __builtin_va_arg
|
||||
typedef __builtin_va_list va_list;
|
||||
#define va_start(v, l) __builtin_va_start((v), l)
|
||||
#define va_end __builtin_va_end
|
||||
#define va_arg __builtin_va_arg
|
||||
typedef __builtin_va_list va_list;
|
||||
|
||||
static void printc(char **out, u32 *out_len, char ch)
|
||||
{
|
||||
|
@ -89,9 +86,10 @@ static void printc(char **out, u32 *out_len, char ch)
|
|||
}
|
||||
}
|
||||
|
||||
static int prints(char **out, u32 *out_len, const char *string, int width, int flags)
|
||||
static int prints(char **out, u32 *out_len, const char *string, int width,
|
||||
int flags)
|
||||
{
|
||||
int pc = 0;
|
||||
int pc = 0;
|
||||
char padchar = ' ';
|
||||
|
||||
if (width > 0) {
|
||||
|
@ -135,10 +133,10 @@ static int printi(char **out, u32 *out_len, long long i, int b, int sg,
|
|||
|
||||
if (sg && b == 10 && i < 0) {
|
||||
neg = 1;
|
||||
u = -i;
|
||||
u = -i;
|
||||
}
|
||||
|
||||
s = print_buf + PRINT_BUF_LEN - 1;
|
||||
s = print_buf + PRINT_BUF_LEN - 1;
|
||||
*s = '\0';
|
||||
|
||||
if (!u) {
|
||||
|
@ -211,59 +209,59 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
|
|||
if (*format == 's') {
|
||||
char *s = va_arg(args, char *);
|
||||
acnt += sizeof(char *);
|
||||
pc += prints(out, out_len,
|
||||
s ? s : "(null)", width, flags);
|
||||
pc += prints(out, out_len, s ? s : "(null)",
|
||||
width, flags);
|
||||
continue;
|
||||
}
|
||||
if ((*format == 'd') || (*format == 'i')) {
|
||||
pc += printi(out, out_len,
|
||||
va_arg(args, int),
|
||||
10, 1, width, flags, '0');
|
||||
pc += printi(out, out_len, va_arg(args, int),
|
||||
10, 1, width, flags, '0');
|
||||
acnt += sizeof(int);
|
||||
continue;
|
||||
}
|
||||
if (*format == 'x') {
|
||||
pc += printi(out, out_len,
|
||||
va_arg(args, unsigned int),
|
||||
16, 0, width, flags, 'a');
|
||||
va_arg(args, unsigned int), 16, 0,
|
||||
width, flags, 'a');
|
||||
acnt += sizeof(unsigned int);
|
||||
continue;
|
||||
}
|
||||
if (*format == 'X') {
|
||||
pc += printi(out, out_len,
|
||||
va_arg(args, unsigned int),
|
||||
16, 0, width, flags, 'A');
|
||||
va_arg(args, unsigned int), 16, 0,
|
||||
width, flags, 'A');
|
||||
acnt += sizeof(unsigned int);
|
||||
continue;
|
||||
}
|
||||
if (*format == 'u') {
|
||||
pc += printi(out, out_len,
|
||||
va_arg(args, unsigned int),
|
||||
10, 0, width, flags, 'a');
|
||||
va_arg(args, unsigned int), 10, 0,
|
||||
width, flags, 'a');
|
||||
acnt += sizeof(unsigned int);
|
||||
continue;
|
||||
}
|
||||
if (*format == 'p') {
|
||||
pc += printi(out, out_len,
|
||||
va_arg(args, unsigned long),
|
||||
16, 0, width, flags, 'a');
|
||||
va_arg(args, unsigned long), 16, 0,
|
||||
width, flags, 'a');
|
||||
acnt += sizeof(unsigned long);
|
||||
continue;
|
||||
}
|
||||
if (*format == 'P') {
|
||||
pc += printi(out, out_len,
|
||||
va_arg(args, unsigned long),
|
||||
16, 0, width, flags, 'A');
|
||||
va_arg(args, unsigned long), 16, 0,
|
||||
width, flags, 'A');
|
||||
acnt += sizeof(unsigned long);
|
||||
continue;
|
||||
}
|
||||
if (*format == 'l' && *(format + 1) == 'l') {
|
||||
while (acnt & (sizeof(unsigned long long)-1)) {
|
||||
while (acnt &
|
||||
(sizeof(unsigned long long) - 1)) {
|
||||
va_arg(args, int);
|
||||
acnt += sizeof(int);
|
||||
}
|
||||
if (sizeof(unsigned long long) ==
|
||||
sizeof(unsigned long)) {
|
||||
sizeof(unsigned long)) {
|
||||
tmp = va_arg(args, unsigned long long);
|
||||
acnt += sizeof(unsigned long long);
|
||||
} else {
|
||||
|
@ -271,48 +269,51 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
|
|||
va_arg(args, unsigned long);
|
||||
((unsigned long *)&tmp)[1] =
|
||||
va_arg(args, unsigned long);
|
||||
acnt += 2*sizeof(unsigned long);
|
||||
acnt += 2 * sizeof(unsigned long);
|
||||
}
|
||||
if (*(format + 2) == 'u') {
|
||||
format += 2;
|
||||
pc += printi(out, out_len, tmp,
|
||||
10, 0, width, flags, 'a');
|
||||
pc += printi(out, out_len, tmp, 10, 0,
|
||||
width, flags, 'a');
|
||||
} else if (*(format + 2) == 'x') {
|
||||
format += 2;
|
||||
pc += printi(out, out_len, tmp,
|
||||
16, 0, width, flags, 'a');
|
||||
pc += printi(out, out_len, tmp, 16, 0,
|
||||
width, flags, 'a');
|
||||
} else if (*(format + 2) == 'X') {
|
||||
format += 2;
|
||||
pc += printi(out, out_len, tmp,
|
||||
16, 0, width, flags, 'A');
|
||||
pc += printi(out, out_len, tmp, 16, 0,
|
||||
width, flags, 'A');
|
||||
} else {
|
||||
format += 1;
|
||||
pc += printi(out, out_len, tmp,
|
||||
10, 1, width, flags, '0');
|
||||
pc += printi(out, out_len, tmp, 10, 1,
|
||||
width, flags, '0');
|
||||
}
|
||||
continue;
|
||||
} else if (*format == 'l') {
|
||||
if (*(format + 1) == 'u') {
|
||||
format += 1;
|
||||
pc += printi(out, out_len,
|
||||
va_arg(args, unsigned long),
|
||||
10, 0, width, flags, 'a');
|
||||
pc += printi(
|
||||
out, out_len,
|
||||
va_arg(args, unsigned long), 10,
|
||||
0, width, flags, 'a');
|
||||
} else if (*(format + 1) == 'x') {
|
||||
format += 1;
|
||||
pc += printi(out, out_len,
|
||||
va_arg(args, unsigned long),
|
||||
16, 0, width, flags, 'a');
|
||||
pc += printi(
|
||||
out, out_len,
|
||||
va_arg(args, unsigned long), 16,
|
||||
0, width, flags, 'a');
|
||||
acnt += sizeof(unsigned long);
|
||||
} else if (*(format + 1) == 'X') {
|
||||
format += 1;
|
||||
pc += printi(out, out_len,
|
||||
va_arg(args, unsigned long),
|
||||
16, 0, width, flags, 'A');
|
||||
pc += printi(
|
||||
out, out_len,
|
||||
va_arg(args, unsigned long), 16,
|
||||
0, width, flags, 'A');
|
||||
acnt += sizeof(unsigned long);
|
||||
} else {
|
||||
pc += printi(out, out_len,
|
||||
va_arg(args, long),
|
||||
10, 1, width, flags, '0');
|
||||
va_arg(args, long), 10, 1,
|
||||
width, flags, '0');
|
||||
acnt += sizeof(long);
|
||||
}
|
||||
}
|
||||
|
@ -325,7 +326,7 @@ static int print(char **out, u32 *out_len, const char *format, va_list args)
|
|||
continue;
|
||||
}
|
||||
} else {
|
||||
out:
|
||||
out:
|
||||
printc(out, out_len, *format);
|
||||
++pc;
|
||||
}
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
#include <sbi/sbi_timer.h>
|
||||
#include <sbi/sbi_trap.h>
|
||||
|
||||
#define SBI_ECALL_VERSION_MAJOR 0
|
||||
#define SBI_ECALL_VERSION_MINOR 1
|
||||
#define SBI_ECALL_VERSION_MAJOR 0
|
||||
#define SBI_ECALL_VERSION_MINOR 1
|
||||
|
||||
u16 sbi_ecall_version_major(void)
|
||||
{
|
||||
|
@ -29,8 +29,7 @@ u16 sbi_ecall_version_minor(void)
|
|||
return SBI_ECALL_VERSION_MINOR;
|
||||
}
|
||||
|
||||
int sbi_ecall_handler(u32 hartid, ulong mcause,
|
||||
struct sbi_trap_regs *regs,
|
||||
int sbi_ecall_handler(u32 hartid, ulong mcause, struct sbi_trap_regs *regs,
|
||||
struct sbi_scratch *scratch)
|
||||
{
|
||||
int ret = SBI_ENOTSUPP;
|
||||
|
@ -40,7 +39,7 @@ int sbi_ecall_handler(u32 hartid, ulong mcause,
|
|||
case SBI_ECALL_SET_TIMER:
|
||||
#if __riscv_xlen == 32
|
||||
sbi_timer_event_start(scratch,
|
||||
(((u64)regs->a1 << 32) | (u64)regs->a0));
|
||||
(((u64)regs->a1 << 32) | (u64)regs->a0));
|
||||
#else
|
||||
sbi_timer_event_start(scratch, (u64)regs->a0);
|
||||
#endif
|
||||
|
@ -52,7 +51,7 @@ int sbi_ecall_handler(u32 hartid, ulong mcause,
|
|||
break;
|
||||
case SBI_ECALL_CONSOLE_GETCHAR:
|
||||
regs->a0 = sbi_getc();
|
||||
ret = 0;
|
||||
ret = 0;
|
||||
break;
|
||||
case SBI_ECALL_CLEAR_IPI:
|
||||
sbi_ipi_clear_smode(scratch);
|
||||
|
@ -68,20 +67,21 @@ int sbi_ecall_handler(u32 hartid, ulong mcause,
|
|||
break;
|
||||
case SBI_ECALL_REMOTE_SFENCE_VMA:
|
||||
tlb_info.start = (unsigned long)regs->a1;
|
||||
tlb_info.size = (unsigned long)regs->a2;
|
||||
tlb_info.type = SBI_TLB_FLUSH_VMA;
|
||||
tlb_info.size = (unsigned long)regs->a2;
|
||||
tlb_info.type = SBI_TLB_FLUSH_VMA;
|
||||
|
||||
ret = sbi_ipi_send_many(scratch, (ulong *)regs->a0,
|
||||
SBI_IPI_EVENT_SFENCE_VMA, &tlb_info);
|
||||
break;
|
||||
case SBI_ECALL_REMOTE_SFENCE_VMA_ASID:
|
||||
tlb_info.start = (unsigned long)regs->a1;
|
||||
tlb_info.size = (unsigned long)regs->a2;
|
||||
tlb_info.asid = (unsigned long)regs->a3;
|
||||
tlb_info.type = SBI_TLB_FLUSH_VMA_ASID;
|
||||
tlb_info.size = (unsigned long)regs->a2;
|
||||
tlb_info.asid = (unsigned long)regs->a3;
|
||||
tlb_info.type = SBI_TLB_FLUSH_VMA_ASID;
|
||||
|
||||
ret = sbi_ipi_send_many(scratch, (ulong *)regs->a0,
|
||||
SBI_IPI_EVENT_SFENCE_VMA_ASID, &tlb_info);
|
||||
SBI_IPI_EVENT_SFENCE_VMA_ASID,
|
||||
&tlb_info);
|
||||
break;
|
||||
case SBI_ECALL_SHUTDOWN:
|
||||
sbi_system_shutdown(scratch, 0);
|
||||
|
@ -89,7 +89,7 @@ int sbi_ecall_handler(u32 hartid, ulong mcause,
|
|||
break;
|
||||
default:
|
||||
regs->a0 = SBI_ENOTSUPP;
|
||||
ret = 0;
|
||||
ret = 0;
|
||||
break;
|
||||
};
|
||||
|
||||
|
|
|
@ -15,10 +15,8 @@
|
|||
#include <sbi/sbi_error.h>
|
||||
#include <sbi/sbi_timer.h>
|
||||
|
||||
int sbi_emulate_csr_read(int csr_num,
|
||||
u32 hartid, ulong mstatus,
|
||||
struct sbi_scratch *scratch,
|
||||
ulong *csr_val)
|
||||
int sbi_emulate_csr_read(int csr_num, u32 hartid, ulong mstatus,
|
||||
struct sbi_scratch *scratch, ulong *csr_val)
|
||||
{
|
||||
ulong cen = -1UL;
|
||||
|
||||
|
@ -85,18 +83,16 @@ int sbi_emulate_csr_read(int csr_num,
|
|||
*csr_val = csr_read(CSR_MHPMEVENT4);
|
||||
break;
|
||||
default:
|
||||
sbi_printf("%s: hartid%d: invalid csr_num=0x%x\n",
|
||||
__func__, hartid, csr_num);
|
||||
sbi_printf("%s: hartid%d: invalid csr_num=0x%x\n", __func__,
|
||||
hartid, csr_num);
|
||||
return SBI_ENOTSUPP;
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sbi_emulate_csr_write(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)
|
||||
{
|
||||
switch (csr_num) {
|
||||
case CSR_CYCLE:
|
||||
|
@ -132,8 +128,8 @@ int sbi_emulate_csr_write(int csr_num,
|
|||
csr_write(CSR_MHPMEVENT4, csr_val);
|
||||
break;
|
||||
default:
|
||||
sbi_printf("%s: hartid%d: invalid csr_num=0x%x\n",
|
||||
__func__, hartid, csr_num);
|
||||
sbi_printf("%s: hartid%d: invalid csr_num=0x%x\n", __func__,
|
||||
hartid, csr_num);
|
||||
return SBI_ENOTSUPP;
|
||||
};
|
||||
|
||||
|
|
|
@ -12,12 +12,12 @@
|
|||
#include <sbi/sbi_fifo.h>
|
||||
#include <plat/string.h>
|
||||
|
||||
void sbi_fifo_init(struct sbi_fifo *fifo, void *queue_mem,
|
||||
u16 entries, u16 entry_size)
|
||||
void sbi_fifo_init(struct sbi_fifo *fifo, void *queue_mem, u16 entries,
|
||||
u16 entry_size)
|
||||
{
|
||||
fifo->queue = queue_mem;
|
||||
fifo->queue = queue_mem;
|
||||
fifo->num_entries = entries;
|
||||
fifo->entry_size = entry_size;
|
||||
fifo->entry_size = entry_size;
|
||||
SPIN_LOCK_INIT(&fifo->qlock);
|
||||
fifo->avail = fifo->tail = 0;
|
||||
memset(fifo->queue, 0, entries * entry_size);
|
||||
|
@ -75,7 +75,7 @@ bool sbi_fifo_is_empty(struct sbi_fifo *fifo)
|
|||
static inline void __sbi_fifo_reset(struct sbi_fifo *fifo)
|
||||
{
|
||||
fifo->avail = 0;
|
||||
fifo->tail = 0;
|
||||
fifo->tail = 0;
|
||||
memset(fifo->queue, 0, fifo->num_entries * fifo->entry_size);
|
||||
}
|
||||
|
||||
|
@ -99,13 +99,13 @@ bool sbi_fifo_reset(struct sbi_fifo *fifo)
|
|||
* lead to deadlock.
|
||||
*/
|
||||
int sbi_fifo_inplace_update(struct sbi_fifo *fifo, void *in,
|
||||
int (*fptr)(void *in, void *data))
|
||||
int (*fptr)(void *in, void *data))
|
||||
{
|
||||
int i, index = 0;
|
||||
int ret = SBI_FIFO_UNCHANGED;
|
||||
void *entry;
|
||||
|
||||
if (!fifo || !in )
|
||||
if (!fifo || !in)
|
||||
return ret;
|
||||
spin_lock(&fifo->qlock);
|
||||
if (__sbi_fifo_is_empty(fifo)) {
|
||||
|
@ -113,12 +113,12 @@ int sbi_fifo_inplace_update(struct sbi_fifo *fifo, void *in,
|
|||
return ret;
|
||||
}
|
||||
|
||||
for (i = 0; i < fifo->avail; i ++) {
|
||||
for (i = 0; i < fifo->avail; i++) {
|
||||
index = fifo->tail + i;
|
||||
if (index >= fifo->num_entries)
|
||||
index = index - fifo->num_entries;
|
||||
entry = (void *)fifo->queue + (u32) index * fifo->entry_size;
|
||||
ret = fptr(in, entry);
|
||||
entry = (void *)fifo->queue + (u32)index * fifo->entry_size;
|
||||
ret = fptr(in, entry);
|
||||
if (ret == SBI_FIFO_SKIP || ret == SBI_FIFO_UPDATED) {
|
||||
break;
|
||||
} else if (ret == SBI_FIFO_RESET) {
|
||||
|
|
|
@ -35,8 +35,7 @@ static void mstatus_init(struct sbi_scratch *scratch, u32 hartid)
|
|||
csr_write(CSR_MSTATUS, MSTATUS_FS);
|
||||
|
||||
/* Enable user/supervisor use of perf counters */
|
||||
if (misa_extension('S') &&
|
||||
sbi_platform_has_scounteren(plat))
|
||||
if (misa_extension('S') && sbi_platform_has_scounteren(plat))
|
||||
csr_write(CSR_SCOUNTEREN, -1);
|
||||
if (sbi_platform_has_mcounteren(plat))
|
||||
csr_write(CSR_MCOUNTEREN, -1);
|
||||
|
@ -88,8 +87,7 @@ static int delegate_traps(struct sbi_scratch *scratch, u32 hartid)
|
|||
|
||||
/* Send M-mode interrupts and most exceptions to S-mode */
|
||||
interrupts = MIP_SSIP | MIP_STIP | MIP_SEIP;
|
||||
exceptions = (1U << CAUSE_MISALIGNED_FETCH) |
|
||||
(1U << CAUSE_BREAKPOINT) |
|
||||
exceptions = (1U << CAUSE_MISALIGNED_FETCH) | (1U << CAUSE_BREAKPOINT) |
|
||||
(1U << CAUSE_USER_ECALL);
|
||||
if (sbi_platform_has_mfaults_delegation(plat))
|
||||
exceptions |= (1U << CAUSE_FETCH_PAGE_FAULT) |
|
||||
|
@ -166,7 +164,7 @@ static int pmp_init(struct sbi_scratch *scratch, u32 hartid)
|
|||
return 0;
|
||||
|
||||
fw_size_log2 = log2roundup(scratch->fw_size);
|
||||
fw_start = scratch->fw_start & ~((1UL << fw_size_log2) - 1UL);
|
||||
fw_start = scratch->fw_start & ~((1UL << fw_size_log2) - 1UL);
|
||||
|
||||
pmp_set(0, 0, fw_start, fw_size_log2);
|
||||
|
||||
|
@ -175,8 +173,8 @@ static int pmp_init(struct sbi_scratch *scratch, u32 hartid)
|
|||
count = (PMP_COUNT - 1);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (sbi_platform_pmp_region_info(plat, hartid, i,
|
||||
&prot, &addr, &log2size))
|
||||
if (sbi_platform_pmp_region_info(plat, hartid, i, &prot, &addr,
|
||||
&log2size))
|
||||
continue;
|
||||
pmp_set(i + 1, prot, addr, log2size);
|
||||
}
|
||||
|
@ -208,10 +206,9 @@ void __attribute__((noreturn)) sbi_hart_hang(void)
|
|||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
void __attribute__((noreturn)) sbi_hart_switch_mode(unsigned long arg0,
|
||||
unsigned long arg1,
|
||||
unsigned long next_addr,
|
||||
unsigned long next_mode)
|
||||
void __attribute__((noreturn))
|
||||
sbi_hart_switch_mode(unsigned long arg0, unsigned long arg1,
|
||||
unsigned long next_addr, unsigned long next_mode)
|
||||
{
|
||||
unsigned long val;
|
||||
|
||||
|
@ -248,13 +245,13 @@ void __attribute__((noreturn)) sbi_hart_switch_mode(unsigned long arg0,
|
|||
csr_write(CSR_UIE, 0);
|
||||
}
|
||||
|
||||
register unsigned long a0 asm ("a0") = arg0;
|
||||
register unsigned long a1 asm ("a1") = arg1;
|
||||
__asm__ __volatile__ ("mret" : : "r" (a0), "r" (a1));
|
||||
register unsigned long a0 asm("a0") = arg0;
|
||||
register unsigned long a1 asm("a1") = arg1;
|
||||
__asm__ __volatile__("mret" : : "r"(a0), "r"(a1));
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
static spinlock_t avail_hart_mask_lock = SPIN_LOCK_INITIALIZER;
|
||||
static spinlock_t avail_hart_mask_lock = SPIN_LOCK_INITIALIZER;
|
||||
static volatile unsigned long avail_hart_mask = 0;
|
||||
|
||||
void sbi_hart_mark_available(u32 hartid)
|
||||
|
@ -290,9 +287,9 @@ struct sbi_scratch *sbi_hart_id_to_scratch(struct sbi_scratch *scratch,
|
|||
return ((h2s)scratch->hartid_to_scratch)(hartid);
|
||||
}
|
||||
|
||||
#define COLDBOOT_WAIT_BITMAP_SIZE __riscv_xlen
|
||||
#define COLDBOOT_WAIT_BITMAP_SIZE __riscv_xlen
|
||||
static spinlock_t coldboot_wait_bitmap_lock = SPIN_LOCK_INITIALIZER;
|
||||
static unsigned long coldboot_wait_bitmap = 0;
|
||||
static unsigned long coldboot_wait_bitmap = 0;
|
||||
|
||||
void sbi_hart_wait_for_coldboot(struct sbi_scratch *scratch, u32 hartid)
|
||||
{
|
||||
|
@ -302,7 +299,7 @@ void sbi_hart_wait_for_coldboot(struct sbi_scratch *scratch, u32 hartid)
|
|||
if ((sbi_platform_hart_count(plat) <= hartid) ||
|
||||
(COLDBOOT_WAIT_BITMAP_SIZE <= hartid))
|
||||
sbi_hart_hang();
|
||||
|
||||
|
||||
/* Set MSIE bit to receive IPI */
|
||||
csr_set(CSR_MIE, MIP_MSIP);
|
||||
|
||||
|
@ -325,9 +322,9 @@ void sbi_hart_wait_for_coldboot(struct sbi_scratch *scratch, u32 hartid)
|
|||
void sbi_hart_wake_coldboot_harts(struct sbi_scratch *scratch, u32 hartid)
|
||||
{
|
||||
const struct sbi_platform *plat = sbi_platform_ptr(scratch);
|
||||
int max_hart = sbi_platform_hart_count(plat);
|
||||
int max_hart = sbi_platform_hart_count(plat);
|
||||
|
||||
for(int i = 0; i < max_hart ; i++) {
|
||||
for (int i = 0; i < max_hart; i++) {
|
||||
/* send an IPI to every other hart */
|
||||
spin_lock(&coldboot_wait_bitmap_lock);
|
||||
if ((i != hartid) && (coldboot_wait_bitmap & (1UL << i)))
|
||||
|
|
|
@ -16,48 +16,45 @@
|
|||
#include <sbi/sbi_illegal_insn.h>
|
||||
#include <sbi/sbi_trap.h>
|
||||
|
||||
typedef int (*illegal_insn_func)(ulong insn,
|
||||
u32 hartid, ulong mcause,
|
||||
typedef int (*illegal_insn_func)(ulong insn, u32 hartid, ulong mcause,
|
||||
struct sbi_trap_regs *regs,
|
||||
struct sbi_scratch *scratch);
|
||||
|
||||
static int truly_illegal_insn(ulong insn,
|
||||
u32 hartid, ulong mcause,
|
||||
static int truly_illegal_insn(ulong insn, u32 hartid, ulong mcause,
|
||||
struct sbi_trap_regs *regs,
|
||||
struct sbi_scratch *scratch)
|
||||
{
|
||||
return sbi_trap_redirect(regs, scratch, regs->mepc, mcause, insn);
|
||||
}
|
||||
|
||||
static int system_opcode_insn(ulong insn,
|
||||
u32 hartid, ulong mcause,
|
||||
static int system_opcode_insn(ulong insn, u32 hartid, ulong mcause,
|
||||
struct sbi_trap_regs *regs,
|
||||
struct sbi_scratch *scratch)
|
||||
{
|
||||
int do_write, rs1_num = (insn >> 15) & 0x1f;
|
||||
ulong rs1_val = GET_RS1(insn, regs);
|
||||
int csr_num = (u32)insn >> 20;
|
||||
int csr_num = (u32)insn >> 20;
|
||||
ulong csr_val, new_csr_val;
|
||||
|
||||
if (sbi_emulate_csr_read(csr_num, hartid, regs->mstatus,
|
||||
scratch, &csr_val))
|
||||
return truly_illegal_insn(insn, hartid, mcause,
|
||||
regs, scratch);
|
||||
if (sbi_emulate_csr_read(csr_num, hartid, regs->mstatus, scratch,
|
||||
&csr_val))
|
||||
return truly_illegal_insn(insn, hartid, mcause, regs, scratch);
|
||||
|
||||
do_write = rs1_num;
|
||||
switch (GET_RM(insn)) {
|
||||
case 1:
|
||||
new_csr_val = rs1_val;
|
||||
do_write = 1;
|
||||
do_write = 1;
|
||||
break;
|
||||
case 2:
|
||||
new_csr_val = csr_val | rs1_val;
|
||||
break;
|
||||
case 3: new_csr_val = csr_val & ~rs1_val;
|
||||
case 3:
|
||||
new_csr_val = csr_val & ~rs1_val;
|
||||
break;
|
||||
case 5:
|
||||
new_csr_val = rs1_num;
|
||||
do_write = 1;
|
||||
do_write = 1;
|
||||
break;
|
||||
case 6:
|
||||
new_csr_val = csr_val | rs1_num;
|
||||
|
@ -66,15 +63,12 @@ static int system_opcode_insn(ulong insn,
|
|||
new_csr_val = csr_val & ~rs1_num;
|
||||
break;
|
||||
default:
|
||||
return truly_illegal_insn(insn, hartid, mcause,
|
||||
regs, scratch);
|
||||
return truly_illegal_insn(insn, hartid, mcause, regs, scratch);
|
||||
};
|
||||
|
||||
if (do_write &&
|
||||
sbi_emulate_csr_write(csr_num, hartid, regs->mstatus,
|
||||
scratch, new_csr_val))
|
||||
return truly_illegal_insn(insn, hartid, mcause,
|
||||
regs, scratch);
|
||||
if (do_write && sbi_emulate_csr_write(csr_num, hartid, regs->mstatus,
|
||||
scratch, new_csr_val))
|
||||
return truly_illegal_insn(insn, hartid, mcause, regs, scratch);
|
||||
|
||||
SET_RD(insn, regs, csr_val);
|
||||
|
||||
|
@ -128,8 +122,8 @@ int sbi_illegal_insn_handler(u32 hartid, ulong mcause,
|
|||
if (insn == 0)
|
||||
insn = get_insn(regs->mepc, NULL);
|
||||
if ((insn & 3) != 3)
|
||||
return truly_illegal_insn(insn, hartid, mcause,
|
||||
regs, scratch);
|
||||
return truly_illegal_insn(insn, hartid, mcause, regs,
|
||||
scratch);
|
||||
}
|
||||
|
||||
return illegal_insn_table[(insn & 0x7c) >> 2](insn, hartid, mcause,
|
||||
|
|
|
@ -18,14 +18,14 @@
|
|||
#include <sbi/sbi_timer.h>
|
||||
#include <sbi/sbi_version.h>
|
||||
|
||||
#define BANNER \
|
||||
" ____ _____ ____ _____\n" \
|
||||
" / __ \\ / ____| _ \\_ _|\n" \
|
||||
" | | | |_ __ ___ _ __ | (___ | |_) || |\n" \
|
||||
#define BANNER \
|
||||
" ____ _____ ____ _____\n" \
|
||||
" / __ \\ / ____| _ \\_ _|\n" \
|
||||
" | | | |_ __ ___ _ __ | (___ | |_) || |\n" \
|
||||
" | | | | '_ \\ / _ \\ '_ \\ \\___ \\| _ < | |\n" \
|
||||
" | |__| | |_) | __/ | | |____) | |_) || |_\n" \
|
||||
" \\____/| .__/ \\___|_| |_|_____/|____/_____|\n" \
|
||||
" | |\n" \
|
||||
" | |__| | |_) | __/ | | |____) | |_) || |_\n" \
|
||||
" \\____/| .__/ \\___|_| |_|_____/|____/_____|\n" \
|
||||
" | |\n" \
|
||||
" |_|\n\n"
|
||||
|
||||
static void sbi_boot_prints(struct sbi_scratch *scratch, u32 hartid)
|
||||
|
@ -34,9 +34,8 @@ static void sbi_boot_prints(struct sbi_scratch *scratch, u32 hartid)
|
|||
const struct sbi_platform *plat = sbi_platform_ptr(scratch);
|
||||
|
||||
misa_string(str, sizeof(str));
|
||||
sbi_printf("\nOpenSBI v%d.%d (%s %s)\n",
|
||||
OPENSBI_VERSION_MAJOR, OPENSBI_VERSION_MINOR,
|
||||
__DATE__, __TIME__);
|
||||
sbi_printf("\nOpenSBI v%d.%d (%s %s)\n", OPENSBI_VERSION_MAJOR,
|
||||
OPENSBI_VERSION_MINOR, __DATE__, __TIME__);
|
||||
|
||||
sbi_printf(BANNER);
|
||||
|
||||
|
@ -97,8 +96,8 @@ static void __noreturn init_coldboot(struct sbi_scratch *scratch, u32 hartid)
|
|||
if (!sbi_platform_has_hart_hotplug(plat))
|
||||
sbi_hart_wake_coldboot_harts(scratch, hartid);
|
||||
sbi_hart_mark_available(hartid);
|
||||
sbi_hart_switch_mode(hartid, scratch->next_arg1,
|
||||
scratch->next_addr, scratch->next_mode);
|
||||
sbi_hart_switch_mode(hartid, scratch->next_arg1, scratch->next_addr,
|
||||
scratch->next_mode);
|
||||
}
|
||||
|
||||
static void __noreturn init_warmboot(struct sbi_scratch *scratch, u32 hartid)
|
||||
|
@ -162,13 +161,13 @@ static atomic_t coldboot_lottery = ATOMIC_INITIALIZER(0);
|
|||
*/
|
||||
void __noreturn sbi_init(struct sbi_scratch *scratch)
|
||||
{
|
||||
bool coldboot = FALSE;
|
||||
u32 hartid = sbi_current_hartid();
|
||||
bool coldboot = FALSE;
|
||||
u32 hartid = sbi_current_hartid();
|
||||
const struct sbi_platform *plat = sbi_platform_ptr(scratch);
|
||||
|
||||
if (sbi_platform_hart_disabled(plat, hartid))
|
||||
sbi_hart_hang();
|
||||
|
||||
|
||||
if (atomic_add_return(&coldboot_lottery, 1) == 1)
|
||||
coldboot = TRUE;
|
||||
|
||||
|
|
|
@ -34,10 +34,9 @@ static inline int __sbi_tlb_fifo_range_check(struct sbi_tlb_info *curr,
|
|||
curr_end = curr->start + curr->size;
|
||||
if (next->start <= curr->start && next_end > curr_end) {
|
||||
curr->start = next->start;
|
||||
curr->size = next->size;
|
||||
ret = SBI_FIFO_UPDATED;
|
||||
} else if (next->start >= curr->start &&
|
||||
next_end <= curr_end) {
|
||||
curr->size = next->size;
|
||||
ret = SBI_FIFO_UPDATED;
|
||||
} else if (next->start >= curr->start && next_end <= curr_end) {
|
||||
ret = SBI_FIFO_SKIP;
|
||||
}
|
||||
|
||||
|
@ -69,8 +68,8 @@ int sbi_tlb_fifo_update_cb(void *in, void *data)
|
|||
if (!in && !!data)
|
||||
return ret;
|
||||
|
||||
curr = (struct sbi_tlb_info *) data;
|
||||
next = (struct sbi_tlb_info *) in;
|
||||
curr = (struct sbi_tlb_info *)data;
|
||||
next = (struct sbi_tlb_info *)in;
|
||||
if (next->type == SBI_TLB_FLUSH_VMA_ASID &&
|
||||
curr->type == SBI_TLB_FLUSH_VMA_ASID) {
|
||||
if (next->asid == curr->asid)
|
||||
|
@ -86,11 +85,11 @@ int sbi_tlb_fifo_update_cb(void *in, void *data)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int sbi_ipi_send(struct sbi_scratch *scratch, u32 hartid,
|
||||
u32 event, void *data)
|
||||
static int sbi_ipi_send(struct sbi_scratch *scratch, u32 hartid, u32 event,
|
||||
void *data)
|
||||
{
|
||||
struct sbi_scratch *remote_scratch = NULL;
|
||||
const struct sbi_platform *plat = sbi_platform_ptr(scratch);
|
||||
const struct sbi_platform *plat = sbi_platform_ptr(scratch);
|
||||
struct sbi_fifo *ipi_tlb_fifo;
|
||||
int ret = SBI_FIFO_UNCHANGED;
|
||||
|
||||
|
@ -104,12 +103,12 @@ static int sbi_ipi_send(struct sbi_scratch *scratch, u32 hartid,
|
|||
if (event == SBI_IPI_EVENT_SFENCE_VMA ||
|
||||
event == SBI_IPI_EVENT_SFENCE_VMA_ASID) {
|
||||
ipi_tlb_fifo = sbi_tlb_fifo_head_ptr(remote_scratch);
|
||||
ret = sbi_fifo_inplace_update(ipi_tlb_fifo, data,
|
||||
sbi_tlb_fifo_update_cb);
|
||||
ret = sbi_fifo_inplace_update(ipi_tlb_fifo, data,
|
||||
sbi_tlb_fifo_update_cb);
|
||||
if (ret == SBI_FIFO_SKIP || ret == SBI_FIFO_UPDATED) {
|
||||
goto done;
|
||||
}
|
||||
while(sbi_fifo_enqueue(ipi_tlb_fifo, data) < 0) {
|
||||
while (sbi_fifo_enqueue(ipi_tlb_fifo, data) < 0) {
|
||||
/**
|
||||
* For now, Busy loop until there is space in the fifo.
|
||||
* There may be case where target hart is also
|
||||
|
@ -132,8 +131,8 @@ done:
|
|||
return 0;
|
||||
}
|
||||
|
||||
int sbi_ipi_send_many(struct sbi_scratch *scratch,
|
||||
ulong *pmask, u32 event, void *data)
|
||||
int sbi_ipi_send_many(struct sbi_scratch *scratch, ulong *pmask, u32 event,
|
||||
void *data)
|
||||
{
|
||||
ulong i, m;
|
||||
ulong mask = sbi_hart_available_mask();
|
||||
|
@ -153,7 +152,6 @@ int sbi_ipi_send_many(struct sbi_scratch *scratch,
|
|||
if (mask & (1UL << hartid))
|
||||
sbi_ipi_send(scratch, hartid, event, data);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -170,7 +168,7 @@ static void sbi_ipi_tlb_flush_all()
|
|||
static void sbi_ipi_sfence_vma(struct sbi_tlb_info *tinfo)
|
||||
{
|
||||
unsigned long start = tinfo->start;
|
||||
unsigned long size = tinfo->size;
|
||||
unsigned long size = tinfo->size;
|
||||
unsigned long i;
|
||||
|
||||
if ((start == 0 && size == 0) || (size == SBI_TLB_FLUSH_ALL)) {
|
||||
|
@ -179,17 +177,18 @@ static void sbi_ipi_sfence_vma(struct sbi_tlb_info *tinfo)
|
|||
}
|
||||
|
||||
for (i = 0; i < size; i += PAGE_SIZE) {
|
||||
__asm__ __volatile__ ("sfence.vma %0"
|
||||
: : "r" (start + i)
|
||||
: "memory");
|
||||
__asm__ __volatile__("sfence.vma %0"
|
||||
:
|
||||
: "r"(start + i)
|
||||
: "memory");
|
||||
}
|
||||
}
|
||||
|
||||
static void sbi_ipi_sfence_vma_asid(struct sbi_tlb_info *tinfo)
|
||||
{
|
||||
unsigned long start = tinfo->start;
|
||||
unsigned long size = tinfo->size;
|
||||
unsigned long asid = tinfo->asid;
|
||||
unsigned long size = tinfo->size;
|
||||
unsigned long asid = tinfo->asid;
|
||||
unsigned long i;
|
||||
|
||||
if (start == 0 && size == 0) {
|
||||
|
@ -199,16 +198,18 @@ static void sbi_ipi_sfence_vma_asid(struct sbi_tlb_info *tinfo)
|
|||
|
||||
/* Flush entire MM context for a given ASID */
|
||||
if (size == SBI_TLB_FLUSH_ALL) {
|
||||
__asm__ __volatile__ ("sfence.vma x0, %0"
|
||||
: : "r" (asid)
|
||||
: "memory");
|
||||
__asm__ __volatile__("sfence.vma x0, %0"
|
||||
:
|
||||
: "r"(asid)
|
||||
: "memory");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < size; i += PAGE_SIZE) {
|
||||
__asm__ __volatile__ ("sfence.vma %0, %1"
|
||||
: : "r" (start + i), "r" (asid)
|
||||
: "memory");
|
||||
__asm__ __volatile__("sfence.vma %0, %1"
|
||||
:
|
||||
: "r"(start + i), "r"(asid)
|
||||
: "memory");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -218,7 +219,7 @@ void sbi_ipi_process(struct sbi_scratch *scratch)
|
|||
struct sbi_tlb_info tinfo;
|
||||
unsigned int ipi_event;
|
||||
const struct sbi_platform *plat = sbi_platform_ptr(scratch);
|
||||
struct sbi_fifo *ipi_tlb_fifo = sbi_tlb_fifo_head_ptr(scratch);
|
||||
struct sbi_fifo *ipi_tlb_fifo = sbi_tlb_fifo_head_ptr(scratch);
|
||||
|
||||
u32 hartid = sbi_current_hartid();
|
||||
sbi_platform_ipi_clear(plat, hartid);
|
||||
|
@ -236,7 +237,7 @@ void sbi_ipi_process(struct sbi_scratch *scratch)
|
|||
break;
|
||||
case SBI_IPI_EVENT_SFENCE_VMA:
|
||||
case SBI_IPI_EVENT_SFENCE_VMA_ASID:
|
||||
while(!sbi_fifo_dequeue(ipi_tlb_fifo, &tinfo)) {
|
||||
while (!sbi_fifo_dequeue(ipi_tlb_fifo, &tinfo)) {
|
||||
if (tinfo.type == SBI_TLB_FLUSH_VMA)
|
||||
sbi_ipi_sfence_vma(&tinfo);
|
||||
else if (tinfo.type == SBI_TLB_FLUSH_VMA_ASID)
|
||||
|
@ -248,8 +249,9 @@ void sbi_ipi_process(struct sbi_scratch *scratch)
|
|||
sbi_hart_hang();
|
||||
break;
|
||||
};
|
||||
ipi_type = atomic_raw_clear_bit(ipi_event, &sbi_ipi_data_ptr(scratch)->ipi_type);
|
||||
} while(ipi_type > 0);
|
||||
ipi_type = atomic_raw_clear_bit(
|
||||
ipi_event, &sbi_ipi_data_ptr(scratch)->ipi_type);
|
||||
} while (ipi_type > 0);
|
||||
}
|
||||
|
||||
int sbi_ipi_init(struct sbi_scratch *scratch, bool cold_boot)
|
||||
|
@ -263,6 +265,5 @@ int sbi_ipi_init(struct sbi_scratch *scratch, bool cold_boot)
|
|||
/* Enable software interrupts */
|
||||
csr_set(CSR_MIE, MIP_MSIP);
|
||||
|
||||
return sbi_platform_ipi_init(sbi_platform_ptr(scratch),
|
||||
cold_boot);
|
||||
return sbi_platform_ipi_init(sbi_platform_ptr(scratch), cold_boot);
|
||||
}
|
||||
|
|
|
@ -31,61 +31,61 @@ int sbi_misaligned_load_handler(u32 hartid, ulong mcause,
|
|||
int i, fp = 0, shift = 0, len = 0;
|
||||
|
||||
if ((insn & INSN_MASK_LW) == INSN_MATCH_LW) {
|
||||
len = 4;
|
||||
len = 4;
|
||||
shift = 8 * (sizeof(ulong) - len);
|
||||
#if __riscv_xlen == 64
|
||||
} else if ((insn & INSN_MASK_LD) == INSN_MATCH_LD) {
|
||||
len = 8;
|
||||
len = 8;
|
||||
shift = 8 * (sizeof(ulong) - len);
|
||||
} else if ((insn & INSN_MASK_LWU) == INSN_MATCH_LWU) {
|
||||
len = 4;
|
||||
#endif
|
||||
} else if ((insn & INSN_MASK_FLD) == INSN_MATCH_FLD) {
|
||||
fp = 1;
|
||||
fp = 1;
|
||||
len = 8;
|
||||
} else if ((insn & INSN_MASK_FLW) == INSN_MATCH_FLW) {
|
||||
fp = 1;
|
||||
fp = 1;
|
||||
len = 4;
|
||||
} else if ((insn & INSN_MASK_LH) == INSN_MATCH_LH) {
|
||||
len = 2;
|
||||
len = 2;
|
||||
shift = 8 * (sizeof(ulong) - len);
|
||||
} else if ((insn & INSN_MASK_LHU) == INSN_MATCH_LHU) {
|
||||
len = 2;
|
||||
#ifdef __riscv_compressed
|
||||
# if __riscv_xlen >= 64
|
||||
#if __riscv_xlen >= 64
|
||||
} else if ((insn & INSN_MASK_C_LD) == INSN_MATCH_C_LD) {
|
||||
len = 8;
|
||||
len = 8;
|
||||
shift = 8 * (sizeof(ulong) - len);
|
||||
insn = RVC_RS2S(insn) << SH_RD;
|
||||
insn = RVC_RS2S(insn) << SH_RD;
|
||||
} else if ((insn & INSN_MASK_C_LDSP) == INSN_MATCH_C_LDSP &&
|
||||
((insn >> SH_RD) & 0x1f)) {
|
||||
len = 8;
|
||||
len = 8;
|
||||
shift = 8 * (sizeof(ulong) - len);
|
||||
# endif
|
||||
} else if ((insn & INSN_MASK_C_LW) ==INSN_MATCH_C_LW) {
|
||||
len = 4;
|
||||
#endif
|
||||
} else if ((insn & INSN_MASK_C_LW) == INSN_MATCH_C_LW) {
|
||||
len = 4;
|
||||
shift = 8 * (sizeof(ulong) - len);
|
||||
insn = RVC_RS2S(insn) << SH_RD;
|
||||
insn = RVC_RS2S(insn) << SH_RD;
|
||||
} else if ((insn & INSN_MASK_C_LWSP) == INSN_MATCH_C_LWSP &&
|
||||
((insn >> SH_RD) & 0x1f)) {
|
||||
len = 4;
|
||||
len = 4;
|
||||
shift = 8 * (sizeof(ulong) - len);
|
||||
} else if ((insn & INSN_MASK_C_FLD) == INSN_MATCH_C_FLD) {
|
||||
fp = 1;
|
||||
len = 8;
|
||||
fp = 1;
|
||||
len = 8;
|
||||
insn = RVC_RS2S(insn) << SH_RD;
|
||||
} else if ((insn & INSN_MASK_C_FLDSP) == INSN_MATCH_C_FLDSP) {
|
||||
fp = 1;
|
||||
fp = 1;
|
||||
len = 8;
|
||||
# if __riscv_xlen == 32
|
||||
#if __riscv_xlen == 32
|
||||
} else if ((insn & INSN_MASK_C_FLW) == INSN_MATCH_C_FLW) {
|
||||
fp = 1;
|
||||
len = 4;
|
||||
fp = 1;
|
||||
len = 4;
|
||||
insn = RVC_RS2S(insn) << SH_RD;
|
||||
} else if ((insn & INSN_MASK_C_FLWSP) == INSN_MATCH_C_FLWSP) {
|
||||
fp = 1;
|
||||
fp = 1;
|
||||
len = 4;
|
||||
# endif
|
||||
#endif
|
||||
#endif
|
||||
} else
|
||||
return SBI_EILL;
|
||||
|
@ -124,44 +124,44 @@ int sbi_misaligned_store_handler(u32 hartid, ulong mcause,
|
|||
len = 8;
|
||||
#endif
|
||||
} else if ((insn & INSN_MASK_FSD) == INSN_MATCH_FSD) {
|
||||
len = 8;
|
||||
len = 8;
|
||||
val.data_u64 = GET_F64_RS2(insn, regs);
|
||||
} else if ((insn & INSN_MASK_FSW) == INSN_MATCH_FSW) {
|
||||
len = 4;
|
||||
len = 4;
|
||||
val.data_ulong = GET_F32_RS2(insn, regs);
|
||||
} else if ((insn & INSN_MASK_SH) == INSN_MATCH_SH) {
|
||||
len = 2;
|
||||
#ifdef __riscv_compressed
|
||||
# if __riscv_xlen >= 64
|
||||
#if __riscv_xlen >= 64
|
||||
} else if ((insn & INSN_MASK_C_SD) == INSN_MATCH_C_SD) {
|
||||
len = 8;
|
||||
len = 8;
|
||||
val.data_ulong = GET_RS2S(insn, regs);
|
||||
} else if ((insn & INSN_MASK_C_SDSP) == INSN_MATCH_C_SDSP &&
|
||||
((insn >> SH_RD) & 0x1f)) {
|
||||
len = 8;
|
||||
len = 8;
|
||||
val.data_ulong = GET_RS2C(insn, regs);
|
||||
# endif
|
||||
#endif
|
||||
} else if ((insn & INSN_MASK_C_SW) == INSN_MATCH_C_SW) {
|
||||
len = 4;
|
||||
len = 4;
|
||||
val.data_ulong = GET_RS2S(insn, regs);
|
||||
} else if ((insn & INSN_MASK_C_SWSP) == INSN_MATCH_C_SWSP &&
|
||||
((insn >> SH_RD) & 0x1f)) {
|
||||
len = 4;
|
||||
len = 4;
|
||||
val.data_ulong = GET_RS2C(insn, regs);
|
||||
} else if ((insn & INSN_MASK_C_FSD) == INSN_MATCH_C_FSD) {
|
||||
len = 8;
|
||||
len = 8;
|
||||
val.data_u64 = GET_F64_RS2S(insn, regs);
|
||||
} else if ((insn & INSN_MASK_C_FSDSP) == INSN_MATCH_C_FSDSP) {
|
||||
len = 8;
|
||||
len = 8;
|
||||
val.data_u64 = GET_F64_RS2C(insn, regs);
|
||||
# if __riscv_xlen == 32
|
||||
#if __riscv_xlen == 32
|
||||
} else if ((insn & INSN_MASK_C_FSW) == INSN_MATCH_C_FSW) {
|
||||
len = 4;
|
||||
len = 4;
|
||||
val.data_ulong = GET_F32_RS2S(insn, regs);
|
||||
} else if ((insn & INSN_MASK_C_FSWSP) == INSN_MATCH_C_FSWSP) {
|
||||
len = 4;
|
||||
len = 4;
|
||||
val.data_ulong = GET_F32_RS2C(insn, regs);
|
||||
# endif
|
||||
#endif
|
||||
#endif
|
||||
} else
|
||||
return SBI_EILL;
|
||||
|
|
|
@ -15,26 +15,24 @@
|
|||
|
||||
int sbi_system_early_init(struct sbi_scratch *scratch, bool cold_boot)
|
||||
{
|
||||
return sbi_platform_early_init(sbi_platform_ptr(scratch),
|
||||
cold_boot);
|
||||
return sbi_platform_early_init(sbi_platform_ptr(scratch), cold_boot);
|
||||
}
|
||||
|
||||
int sbi_system_final_init(struct sbi_scratch *scratch, bool cold_boot)
|
||||
{
|
||||
return sbi_platform_final_init(sbi_platform_ptr(scratch),
|
||||
cold_boot);
|
||||
return sbi_platform_final_init(sbi_platform_ptr(scratch), cold_boot);
|
||||
}
|
||||
|
||||
void __attribute__((noreturn)) sbi_system_reboot(struct sbi_scratch *scratch,
|
||||
u32 type)
|
||||
void __attribute__((noreturn))
|
||||
sbi_system_reboot(struct sbi_scratch *scratch, u32 type)
|
||||
|
||||
{
|
||||
sbi_platform_system_reboot(sbi_platform_ptr(scratch), type);
|
||||
sbi_hart_hang();
|
||||
}
|
||||
|
||||
void __attribute__((noreturn)) sbi_system_shutdown(struct sbi_scratch *scratch,
|
||||
u32 type)
|
||||
void __attribute__((noreturn))
|
||||
sbi_system_shutdown(struct sbi_scratch *scratch, u32 type)
|
||||
{
|
||||
/* First try the platform-specific method */
|
||||
sbi_platform_system_shutdown(sbi_platform_ptr(scratch), type);
|
||||
|
|
|
@ -16,13 +16,12 @@
|
|||
u64 get_ticks(void)
|
||||
{
|
||||
u32 lo, hi, tmp;
|
||||
__asm__ __volatile__ (
|
||||
"1:\n"
|
||||
"rdtimeh %0\n"
|
||||
"rdtime %1\n"
|
||||
"rdtimeh %2\n"
|
||||
"bne %0, %2, 1b"
|
||||
: "=&r" (hi), "=&r" (lo), "=&r" (tmp));
|
||||
__asm__ __volatile__("1:\n"
|
||||
"rdtimeh %0\n"
|
||||
"rdtime %1\n"
|
||||
"rdtimeh %2\n"
|
||||
"bne %0, %2, 1b"
|
||||
: "=&r"(hi), "=&r"(lo), "=&r"(tmp));
|
||||
return ((u64)hi << 32) | lo;
|
||||
}
|
||||
#else
|
||||
|
@ -30,9 +29,7 @@ u64 get_ticks(void)
|
|||
{
|
||||
unsigned long n;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
"rdtime %0"
|
||||
: "=r" (n));
|
||||
__asm__ __volatile__("rdtime %0" : "=r"(n));
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
|
@ -54,8 +51,7 @@ void sbi_timer_event_stop(struct sbi_scratch *scratch)
|
|||
|
||||
void sbi_timer_event_start(struct sbi_scratch *scratch, u64 next_event)
|
||||
{
|
||||
sbi_platform_timer_event_start(sbi_platform_ptr(scratch),
|
||||
next_event);
|
||||
sbi_platform_timer_event_start(sbi_platform_ptr(scratch), next_event);
|
||||
csr_clear(CSR_MIP, MIP_STIP);
|
||||
csr_set(CSR_MIE, MIP_MTIP);
|
||||
}
|
||||
|
@ -68,6 +64,5 @@ void sbi_timer_process(struct sbi_scratch *scratch)
|
|||
|
||||
int sbi_timer_init(struct sbi_scratch *scratch, bool cold_boot)
|
||||
{
|
||||
return sbi_platform_timer_init(sbi_platform_ptr(scratch),
|
||||
cold_boot);
|
||||
return sbi_platform_timer_init(sbi_platform_ptr(scratch), cold_boot);
|
||||
}
|
||||
|
|
|
@ -19,49 +19,47 @@
|
|||
#include <sbi/sbi_timer.h>
|
||||
#include <sbi/sbi_trap.h>
|
||||
|
||||
static void __noreturn sbi_trap_error(const char *msg,
|
||||
int rc, u32 hartid,
|
||||
static void __noreturn sbi_trap_error(const char *msg, int rc, u32 hartid,
|
||||
ulong mcause, ulong mtval,
|
||||
struct sbi_trap_regs *regs)
|
||||
{
|
||||
sbi_printf("%s: hart%d: %s (error %d)\n",
|
||||
__func__, hartid, msg, rc);
|
||||
sbi_printf("%s: hart%d: mcause=0x%"PRILX" mtval=0x%"PRILX"\n",
|
||||
sbi_printf("%s: hart%d: %s (error %d)\n", __func__, hartid, msg, rc);
|
||||
sbi_printf("%s: hart%d: mcause=0x%" PRILX " mtval=0x%" PRILX "\n",
|
||||
__func__, hartid, mcause, mtval);
|
||||
sbi_printf("%s: hart%d: mepc=0x%"PRILX" mstatus=0x%"PRILX"\n",
|
||||
sbi_printf("%s: hart%d: mepc=0x%" PRILX " mstatus=0x%" PRILX "\n",
|
||||
__func__, hartid, regs->mepc, regs->mstatus);
|
||||
sbi_printf("%s: hart%d: %s=0x%"PRILX" %s=0x%"PRILX"\n",
|
||||
__func__, hartid, "ra", regs->ra, "sp", regs->sp);
|
||||
sbi_printf("%s: hart%d: %s=0x%"PRILX" %s=0x%"PRILX"\n",
|
||||
__func__, hartid, "gp", regs->gp, "tp", regs->tp);
|
||||
sbi_printf("%s: hart%d: %s=0x%"PRILX" %s=0x%"PRILX"\n",
|
||||
__func__, hartid, "s0", regs->s0, "s1", regs->s1);
|
||||
sbi_printf("%s: hart%d: %s=0x%"PRILX" %s=0x%"PRILX"\n",
|
||||
__func__, hartid, "a0", regs->a0, "a1", regs->a1);
|
||||
sbi_printf("%s: hart%d: %s=0x%"PRILX" %s=0x%"PRILX"\n",
|
||||
__func__, hartid, "a2", regs->a2, "a3", regs->a3);
|
||||
sbi_printf("%s: hart%d: %s=0x%"PRILX" %s=0x%"PRILX"\n",
|
||||
__func__, hartid, "a4", regs->a4, "a5", regs->a5);
|
||||
sbi_printf("%s: hart%d: %s=0x%"PRILX" %s=0x%"PRILX"\n",
|
||||
__func__, hartid, "a6", regs->a6, "a7", regs->a7);
|
||||
sbi_printf("%s: hart%d: %s=0x%"PRILX" %s=0x%"PRILX"\n",
|
||||
__func__, hartid, "s2", regs->s2, "s3", regs->s3);
|
||||
sbi_printf("%s: hart%d: %s=0x%"PRILX" %s=0x%"PRILX"\n",
|
||||
__func__, hartid, "s4", regs->s4, "s5", regs->s5);
|
||||
sbi_printf("%s: hart%d: %s=0x%"PRILX" %s=0x%"PRILX"\n",
|
||||
__func__, hartid, "s6", regs->s6, "s7", regs->s7);
|
||||
sbi_printf("%s: hart%d: %s=0x%"PRILX" %s=0x%"PRILX"\n",
|
||||
__func__, hartid, "s8", regs->s8, "s9", regs->s9);
|
||||
sbi_printf("%s: hart%d: %s=0x%"PRILX" %s=0x%"PRILX"\n",
|
||||
__func__, hartid, "s10", regs->s10, "s11", regs->s11);
|
||||
sbi_printf("%s: hart%d: %s=0x%"PRILX" %s=0x%"PRILX"\n",
|
||||
__func__, hartid, "t0", regs->t0, "t1", regs->t1);
|
||||
sbi_printf("%s: hart%d: %s=0x%"PRILX" %s=0x%"PRILX"\n",
|
||||
__func__, hartid, "t2", regs->t2, "t3", regs->t3);
|
||||
sbi_printf("%s: hart%d: %s=0x%"PRILX" %s=0x%"PRILX"\n",
|
||||
__func__, hartid, "t4", regs->t4, "t5", regs->t5);
|
||||
sbi_printf("%s: hart%d: %s=0x%"PRILX"\n",
|
||||
__func__, hartid, "t6", regs->t6);
|
||||
sbi_printf("%s: hart%d: %s=0x%" PRILX " %s=0x%" PRILX "\n", __func__,
|
||||
hartid, "ra", regs->ra, "sp", regs->sp);
|
||||
sbi_printf("%s: hart%d: %s=0x%" PRILX " %s=0x%" PRILX "\n", __func__,
|
||||
hartid, "gp", regs->gp, "tp", regs->tp);
|
||||
sbi_printf("%s: hart%d: %s=0x%" PRILX " %s=0x%" PRILX "\n", __func__,
|
||||
hartid, "s0", regs->s0, "s1", regs->s1);
|
||||
sbi_printf("%s: hart%d: %s=0x%" PRILX " %s=0x%" PRILX "\n", __func__,
|
||||
hartid, "a0", regs->a0, "a1", regs->a1);
|
||||
sbi_printf("%s: hart%d: %s=0x%" PRILX " %s=0x%" PRILX "\n", __func__,
|
||||
hartid, "a2", regs->a2, "a3", regs->a3);
|
||||
sbi_printf("%s: hart%d: %s=0x%" PRILX " %s=0x%" PRILX "\n", __func__,
|
||||
hartid, "a4", regs->a4, "a5", regs->a5);
|
||||
sbi_printf("%s: hart%d: %s=0x%" PRILX " %s=0x%" PRILX "\n", __func__,
|
||||
hartid, "a6", regs->a6, "a7", regs->a7);
|
||||
sbi_printf("%s: hart%d: %s=0x%" PRILX " %s=0x%" PRILX "\n", __func__,
|
||||
hartid, "s2", regs->s2, "s3", regs->s3);
|
||||
sbi_printf("%s: hart%d: %s=0x%" PRILX " %s=0x%" PRILX "\n", __func__,
|
||||
hartid, "s4", regs->s4, "s5", regs->s5);
|
||||
sbi_printf("%s: hart%d: %s=0x%" PRILX " %s=0x%" PRILX "\n", __func__,
|
||||
hartid, "s6", regs->s6, "s7", regs->s7);
|
||||
sbi_printf("%s: hart%d: %s=0x%" PRILX " %s=0x%" PRILX "\n", __func__,
|
||||
hartid, "s8", regs->s8, "s9", regs->s9);
|
||||
sbi_printf("%s: hart%d: %s=0x%" PRILX " %s=0x%" PRILX "\n", __func__,
|
||||
hartid, "s10", regs->s10, "s11", regs->s11);
|
||||
sbi_printf("%s: hart%d: %s=0x%" PRILX " %s=0x%" PRILX "\n", __func__,
|
||||
hartid, "t0", regs->t0, "t1", regs->t1);
|
||||
sbi_printf("%s: hart%d: %s=0x%" PRILX " %s=0x%" PRILX "\n", __func__,
|
||||
hartid, "t2", regs->t2, "t3", regs->t3);
|
||||
sbi_printf("%s: hart%d: %s=0x%" PRILX " %s=0x%" PRILX "\n", __func__,
|
||||
hartid, "t4", regs->t4, "t5", regs->t5);
|
||||
sbi_printf("%s: hart%d: %s=0x%" PRILX "\n", __func__, hartid, "t6",
|
||||
regs->t6);
|
||||
|
||||
sbi_hart_hang();
|
||||
}
|
||||
|
@ -77,8 +75,7 @@ static void __noreturn sbi_trap_error(const char *msg,
|
|||
*
|
||||
* @return 0 on success and negative error code on failure
|
||||
*/
|
||||
int sbi_trap_redirect(struct sbi_trap_regs *regs,
|
||||
struct sbi_scratch *scratch,
|
||||
int sbi_trap_redirect(struct sbi_trap_regs *regs, struct sbi_scratch *scratch,
|
||||
ulong epc, ulong cause, ulong tval)
|
||||
{
|
||||
ulong new_mstatus, prev_mode;
|
||||
|
@ -100,8 +97,8 @@ int sbi_trap_redirect(struct sbi_trap_regs *regs,
|
|||
new_mstatus = regs->mstatus;
|
||||
|
||||
/* Clear MPP, SPP, SPIE, and SIE */
|
||||
new_mstatus &= ~(MSTATUS_MPP |
|
||||
MSTATUS_SPP | MSTATUS_SPIE | MSTATUS_SIE);
|
||||
new_mstatus &=
|
||||
~(MSTATUS_MPP | MSTATUS_SPP | MSTATUS_SPIE | MSTATUS_SIE);
|
||||
|
||||
/* Set SPP */
|
||||
if (prev_mode == PRV_S)
|
||||
|
@ -135,10 +132,9 @@ int sbi_trap_redirect(struct sbi_trap_regs *regs,
|
|||
* @param regs pointer to register state
|
||||
* @param scratch pointer to sbi_scratch of current HART
|
||||
*/
|
||||
void sbi_trap_handler(struct sbi_trap_regs *regs,
|
||||
struct sbi_scratch *scratch)
|
||||
void sbi_trap_handler(struct sbi_trap_regs *regs, struct sbi_scratch *scratch)
|
||||
{
|
||||
int rc = SBI_ENOTSUPP;
|
||||
int rc = SBI_ENOTSUPP;
|
||||
const char *msg = "trap handler failed";
|
||||
u32 hartid = sbi_current_hartid();
|
||||
ulong mcause = csr_read(CSR_MCAUSE);
|
||||
|
@ -162,7 +158,7 @@ void sbi_trap_handler(struct sbi_trap_regs *regs,
|
|||
|
||||
switch (mcause) {
|
||||
case CAUSE_ILLEGAL_INSTRUCTION:
|
||||
rc = sbi_illegal_insn_handler(hartid, mcause, regs, scratch);
|
||||
rc = sbi_illegal_insn_handler(hartid, mcause, regs, scratch);
|
||||
msg = "illegal instruction handler failed";
|
||||
break;
|
||||
case CAUSE_MISALIGNED_LOAD:
|
||||
|
@ -170,12 +166,13 @@ void sbi_trap_handler(struct sbi_trap_regs *regs,
|
|||
msg = "misaligned load handler failed";
|
||||
break;
|
||||
case CAUSE_MISALIGNED_STORE:
|
||||
rc = sbi_misaligned_store_handler(hartid, mcause, regs, scratch);
|
||||
rc = sbi_misaligned_store_handler(hartid, mcause, regs,
|
||||
scratch);
|
||||
msg = "misaligned store handler failed";
|
||||
break;
|
||||
case CAUSE_SUPERVISOR_ECALL:
|
||||
case CAUSE_HYPERVISOR_ECALL:
|
||||
rc = sbi_ecall_handler(hartid, mcause, regs, scratch);
|
||||
rc = sbi_ecall_handler(hartid, mcause, regs, scratch);
|
||||
msg = "ecall handler failed";
|
||||
break;
|
||||
default:
|
||||
|
@ -186,6 +183,7 @@ void sbi_trap_handler(struct sbi_trap_regs *regs,
|
|||
|
||||
trap_error:
|
||||
if (rc) {
|
||||
sbi_trap_error(msg, rc, hartid, mcause, csr_read(CSR_MTVAL), regs);
|
||||
sbi_trap_error(msg, rc, hartid, mcause, csr_read(CSR_MTVAL),
|
||||
regs);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,10 +14,8 @@
|
|||
|
||||
void plic_fdt_fixup(void *fdt, const char *compat);
|
||||
|
||||
int plic_warm_irqchip_init(u32 target_hart,
|
||||
int m_cntx_id, int s_cntx_id);
|
||||
int plic_warm_irqchip_init(u32 target_hart, int m_cntx_id, int s_cntx_id);
|
||||
|
||||
int plic_cold_irqchip_init(unsigned long base,
|
||||
u32 num_sources, u32 hart_count);
|
||||
int plic_cold_irqchip_init(unsigned long base, u32 num_sources, u32 hart_count);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -16,7 +16,6 @@ void sifive_uart_putc(char ch);
|
|||
|
||||
int sifive_uart_getc(void);
|
||||
|
||||
int sifive_uart_init(unsigned long base,
|
||||
u32 in_freq, u32 baudrate);
|
||||
int sifive_uart_init(unsigned long base, u32 in_freq, u32 baudrate);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -16,8 +16,7 @@ void uart8250_putc(char ch);
|
|||
|
||||
int uart8250_getc(void);
|
||||
|
||||
int uart8250_init(unsigned long base,
|
||||
u32 in_freq, u32 baudrate,
|
||||
u32 reg_shift, u32 reg_width);
|
||||
int uart8250_init(unsigned long base, u32 in_freq, u32 baudrate, u32 reg_shift,
|
||||
u32 reg_width);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,7 +18,7 @@ size_t strlen(const char *str);
|
|||
|
||||
size_t strnlen(const char *str, size_t count);
|
||||
|
||||
char *strcpy(char *dest,const char *src);
|
||||
char *strcpy(char *dest, const char *src);
|
||||
|
||||
char *strncpy(char *dest, const char *src, size_t count);
|
||||
|
||||
|
@ -26,13 +26,13 @@ char *strchr(const char *s, int c);
|
|||
|
||||
char *strrchr(const char *s, int c);
|
||||
|
||||
void *memset(void *s,int c,size_t count);
|
||||
void *memset(void *s, int c, size_t count);
|
||||
|
||||
void *memcpy(void *dest, const void *src, size_t count);
|
||||
|
||||
void *memmove(void *dest,const void *src, size_t count);
|
||||
void *memmove(void *dest, const void *src, size_t count);
|
||||
|
||||
int memcmp(const void *s1,const void *s2, size_t count);
|
||||
int memcmp(const void *s1, const void *s2, size_t count);
|
||||
|
||||
void *memchr(const void *s, int c, size_t count);
|
||||
|
||||
|
|
|
@ -38,33 +38,27 @@ ulong fdt_strlen(const char *str);
|
|||
int fdt_strcmp(const char *a, const char *b);
|
||||
|
||||
/* Find index of matching string from a list of strings */
|
||||
int fdt_prop_string_index(const struct fdt_prop *prop,
|
||||
const char *str);
|
||||
int fdt_prop_string_index(const struct fdt_prop *prop, const char *str);
|
||||
|
||||
/* Iterate over each property of matching node */
|
||||
int fdt_match_node_prop(void *fdt,
|
||||
int (*match)(const struct fdt_node *node,
|
||||
const struct fdt_prop *prop,
|
||||
void *priv),
|
||||
const struct fdt_prop *prop, void *priv),
|
||||
void *match_priv,
|
||||
void (*fn)(const struct fdt_node *node,
|
||||
const struct fdt_prop *prop,
|
||||
void *priv),
|
||||
const struct fdt_prop *prop, void *priv),
|
||||
void *fn_priv);
|
||||
|
||||
/* Iterate over each property of compatible node */
|
||||
int fdt_compat_node_prop(void *fdt,
|
||||
const char *compat,
|
||||
int fdt_compat_node_prop(void *fdt, const char *compat,
|
||||
void (*fn)(const struct fdt_node *node,
|
||||
const struct fdt_prop *prop,
|
||||
void *priv),
|
||||
const struct fdt_prop *prop, void *priv),
|
||||
void *fn_priv);
|
||||
|
||||
/* Iterate over each node and property */
|
||||
int fdt_walk(void *fdt,
|
||||
void (*fn)(const struct fdt_node *node,
|
||||
const struct fdt_prop *prop,
|
||||
void *priv),
|
||||
const struct fdt_prop *prop, void *priv),
|
||||
void *fn_priv);
|
||||
|
||||
/* Get size of FDT */
|
||||
|
|
|
@ -14,12 +14,12 @@
|
|||
#include <plat/tinyfdt.h>
|
||||
#include <plat/irqchip/plic.h>
|
||||
|
||||
#define PLIC_PRIORITY_BASE 0x0
|
||||
#define PLIC_PENDING_BASE 0x1000
|
||||
#define PLIC_ENABLE_BASE 0x2000
|
||||
#define PLIC_ENABLE_STRIDE 0x80
|
||||
#define PLIC_CONTEXT_BASE 0x200000
|
||||
#define PLIC_CONTEXT_STRIDE 0x1000
|
||||
#define PLIC_PRIORITY_BASE 0x0
|
||||
#define PLIC_PENDING_BASE 0x1000
|
||||
#define PLIC_ENABLE_BASE 0x2000
|
||||
#define PLIC_ENABLE_STRIDE 0x80
|
||||
#define PLIC_CONTEXT_BASE 0x200000
|
||||
#define PLIC_CONTEXT_STRIDE 0x1000
|
||||
|
||||
static u32 plic_hart_count;
|
||||
static u32 plic_num_sources;
|
||||
|
@ -27,31 +27,27 @@ static volatile void *plic_base;
|
|||
|
||||
static void plic_set_priority(u32 source, u32 val)
|
||||
{
|
||||
volatile void *plic_priority = plic_base +
|
||||
PLIC_PRIORITY_BASE +
|
||||
4 * source;
|
||||
volatile void *plic_priority =
|
||||
plic_base + PLIC_PRIORITY_BASE + 4 * source;
|
||||
writel(val, plic_priority);
|
||||
}
|
||||
|
||||
static void plic_set_thresh(u32 cntxid, u32 val)
|
||||
{
|
||||
volatile void *plic_thresh = plic_base +
|
||||
PLIC_CONTEXT_BASE +
|
||||
PLIC_CONTEXT_STRIDE * cntxid;
|
||||
volatile void *plic_thresh =
|
||||
plic_base + PLIC_CONTEXT_BASE + PLIC_CONTEXT_STRIDE * cntxid;
|
||||
writel(val, plic_thresh);
|
||||
}
|
||||
|
||||
static void plic_set_ie(u32 cntxid, u32 word_index, u32 val)
|
||||
{
|
||||
volatile void *plic_ie = plic_base +
|
||||
PLIC_ENABLE_BASE +
|
||||
PLIC_ENABLE_STRIDE * cntxid;
|
||||
volatile void *plic_ie =
|
||||
plic_base + PLIC_ENABLE_BASE + PLIC_ENABLE_STRIDE * cntxid;
|
||||
writel(val, plic_ie + word_index * 4);
|
||||
}
|
||||
|
||||
static void plic_fdt_fixup_prop(const struct fdt_node *node,
|
||||
const struct fdt_prop *prop,
|
||||
void *priv)
|
||||
const struct fdt_prop *prop, void *priv)
|
||||
{
|
||||
u32 *cells;
|
||||
u32 i, cells_count;
|
||||
|
@ -61,15 +57,15 @@ static void plic_fdt_fixup_prop(const struct fdt_node *node,
|
|||
if (strcmp(prop->name, "interrupts-extended"))
|
||||
return;
|
||||
|
||||
cells = prop->value;
|
||||
cells = prop->value;
|
||||
cells_count = prop->len / sizeof(u32);
|
||||
|
||||
if (!cells_count)
|
||||
return;
|
||||
|
||||
for (i = 0; i < (cells_count/2); i++) {
|
||||
if (fdt_rev32(cells[2*i+1]) == IRQ_M_EXT)
|
||||
cells[2*i+1] = fdt_rev32(0xffffffff);
|
||||
for (i = 0; i < (cells_count / 2); i++) {
|
||||
if (fdt_rev32(cells[2 * i + 1]) == IRQ_M_EXT)
|
||||
cells[2 * i + 1] = fdt_rev32(0xffffffff);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -78,14 +74,13 @@ void plic_fdt_fixup(void *fdt, const char *compat)
|
|||
fdt_compat_node_prop(fdt, compat, plic_fdt_fixup_prop, NULL);
|
||||
}
|
||||
|
||||
int plic_warm_irqchip_init(u32 target_hart,
|
||||
int m_cntx_id, int s_cntx_id)
|
||||
int plic_warm_irqchip_init(u32 target_hart, int m_cntx_id, int s_cntx_id)
|
||||
{
|
||||
size_t i, ie_words = plic_num_sources / 32 + 1;
|
||||
|
||||
if (plic_hart_count <= target_hart)
|
||||
return -1;
|
||||
|
||||
|
||||
/* By default, disable all IRQs for M-mode of target HART */
|
||||
if (m_cntx_id > -1) {
|
||||
for (i = 0; i < ie_words; i++)
|
||||
|
@ -109,14 +104,13 @@ int plic_warm_irqchip_init(u32 target_hart,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int plic_cold_irqchip_init(unsigned long base,
|
||||
u32 num_sources, u32 hart_count)
|
||||
int plic_cold_irqchip_init(unsigned long base, u32 num_sources, u32 hart_count)
|
||||
{
|
||||
int i;
|
||||
|
||||
plic_hart_count = hart_count;
|
||||
plic_hart_count = hart_count;
|
||||
plic_num_sources = num_sources;
|
||||
plic_base = (void *)base;
|
||||
plic_base = (void *)base;
|
||||
|
||||
/* Configure default priorities of all IRQs */
|
||||
for (i = 1; i <= plic_num_sources; i++)
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
int strcmp(const char *a, const char *b)
|
||||
{
|
||||
/* search first diff or end of string */
|
||||
for (; *a == *b && *a != '\0'; a++, b++);
|
||||
for (; *a == *b && *a != '\0'; a++, b++)
|
||||
;
|
||||
|
||||
return *a - *b;
|
||||
}
|
||||
|
@ -51,7 +52,7 @@ char *strcpy(char *dest, const char *src)
|
|||
{
|
||||
char *ret = dest;
|
||||
|
||||
while(*src != '\0') {
|
||||
while (*src != '\0') {
|
||||
*dest++ = *src++;
|
||||
}
|
||||
|
||||
|
@ -62,7 +63,7 @@ char *strncpy(char *dest, const char *src, size_t count)
|
|||
{
|
||||
char *ret = dest;
|
||||
|
||||
while(count-- && *src != '\0') {
|
||||
while (count-- && *src != '\0') {
|
||||
*dest++ = *src++;
|
||||
}
|
||||
|
||||
|
@ -71,7 +72,7 @@ char *strncpy(char *dest, const char *src, size_t count)
|
|||
|
||||
char *strchr(const char *s, int c)
|
||||
{
|
||||
while(*s != '\0' && *s != (char)c)
|
||||
while (*s != '\0' && *s != (char)c)
|
||||
s++;
|
||||
|
||||
if (*s == '\0')
|
||||
|
@ -96,7 +97,7 @@ void *memset(void *s, int c, size_t count)
|
|||
{
|
||||
char *temp = s;
|
||||
|
||||
while(count > 0 ){
|
||||
while (count > 0) {
|
||||
count--;
|
||||
*temp++ = c;
|
||||
}
|
||||
|
@ -106,7 +107,7 @@ void *memset(void *s, int c, size_t count)
|
|||
|
||||
void *memcpy(void *dest, const void *src, size_t count)
|
||||
{
|
||||
char *temp1 = dest;
|
||||
char *temp1 = dest;
|
||||
const char *temp2 = src;
|
||||
|
||||
while (count > 0) {
|
||||
|
@ -119,14 +120,14 @@ void *memcpy(void *dest, const void *src, size_t count)
|
|||
|
||||
void *memmove(void *dest, const void *src, size_t count)
|
||||
{
|
||||
char *temp1 = (char *)dest;
|
||||
char *temp1 = (char *)dest;
|
||||
const char *temp2 = (char *)src;
|
||||
|
||||
if (src == dest)
|
||||
return dest;
|
||||
|
||||
if (dest < src) {
|
||||
while(count > 0) {
|
||||
while (count > 0) {
|
||||
*temp1++ = *temp2++;
|
||||
count--;
|
||||
}
|
||||
|
@ -134,7 +135,7 @@ void *memmove(void *dest, const void *src, size_t count)
|
|||
temp1 = dest + count - 1;
|
||||
temp2 = src + count - 1;
|
||||
|
||||
while(count > 0) {
|
||||
while (count > 0) {
|
||||
*temp1-- = *temp2--;
|
||||
count--;
|
||||
}
|
||||
|
@ -165,7 +166,7 @@ void *memchr(const void *s, int c, size_t count)
|
|||
|
||||
while (count > 0) {
|
||||
if ((unsigned char)c == *temp++) {
|
||||
return (void *)(temp-1);
|
||||
return (void *)(temp - 1);
|
||||
}
|
||||
count--;
|
||||
}
|
||||
|
|
|
@ -51,8 +51,8 @@
|
|||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <libfdt_env.h>
|
||||
#include <fdt.h>
|
||||
#include <libfdt_env.h>
|
||||
|
||||
#define FDT_FIRST_SUPPORTED_VERSION 0x02
|
||||
#define FDT_LAST_SUPPORTED_VERSION 0x11
|
||||
|
|
|
@ -52,8 +52,8 @@
|
|||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sbi/sbi_types.h>
|
||||
#include <plat/string.h>
|
||||
#include <sbi/sbi_types.h>
|
||||
|
||||
#define INT_MAX ((int)(~0U >> 1))
|
||||
#define UINT_MAX ((unsigned int)~0U)
|
||||
|
|
|
@ -68,7 +68,8 @@ static void set_reg(u32 num, u32 val)
|
|||
|
||||
void sifive_uart_putc(char ch)
|
||||
{
|
||||
while (get_reg(UART_REG_TXFIFO) & UART_TXFIFO_FULL);
|
||||
while (get_reg(UART_REG_TXFIFO) & UART_TXFIFO_FULL)
|
||||
;
|
||||
|
||||
set_reg(UART_REG_TXFIFO, ch);
|
||||
}
|
||||
|
@ -81,11 +82,10 @@ int sifive_uart_getc(void)
|
|||
return -1;
|
||||
}
|
||||
|
||||
int sifive_uart_init(unsigned long base,
|
||||
u32 in_freq, u32 baudrate)
|
||||
int sifive_uart_init(unsigned long base, u32 in_freq, u32 baudrate)
|
||||
{
|
||||
uart_base = (volatile void *)base;
|
||||
uart_in_freq = in_freq;
|
||||
uart_base = (volatile void *)base;
|
||||
uart_in_freq = in_freq;
|
||||
uart_baudrate = baudrate;
|
||||
|
||||
/* Configure baudrate */
|
||||
|
|
|
@ -70,7 +70,8 @@ static void set_reg(u32 num, u32 val)
|
|||
|
||||
void uart8250_putc(char ch)
|
||||
{
|
||||
while ((get_reg(UART_LSR_OFFSET) & UART_LSR_THRE) == 0);
|
||||
while ((get_reg(UART_LSR_OFFSET) & UART_LSR_THRE) == 0)
|
||||
;
|
||||
|
||||
set_reg(UART_THR_OFFSET, ch);
|
||||
}
|
||||
|
@ -82,17 +83,16 @@ int uart8250_getc(void)
|
|||
return -1;
|
||||
}
|
||||
|
||||
int uart8250_init(unsigned long base,
|
||||
u32 in_freq, u32 baudrate,
|
||||
u32 reg_shift, u32 reg_width)
|
||||
int uart8250_init(unsigned long base, u32 in_freq, u32 baudrate, u32 reg_shift,
|
||||
u32 reg_width)
|
||||
{
|
||||
u16 bdiv;
|
||||
|
||||
uart8250_base = (volatile void *)base;
|
||||
uart8250_base = (volatile void *)base;
|
||||
uart8250_reg_shift = reg_shift;
|
||||
uart8250_reg_width = reg_width;
|
||||
uart8250_in_freq = in_freq;
|
||||
uart8250_baudrate = baudrate;
|
||||
uart8250_in_freq = in_freq;
|
||||
uart8250_baudrate = baudrate;
|
||||
|
||||
bdiv = uart8250_in_freq / (16 * uart8250_baudrate);
|
||||
|
||||
|
|
|
@ -74,8 +74,8 @@ int clint_cold_ipi_init(unsigned long base, u32 hart_count)
|
|||
{
|
||||
/* Figure-out CLINT IPI register address */
|
||||
clint_ipi_hart_count = hart_count;
|
||||
clint_ipi_base = (void *)base;
|
||||
clint_ipi = (u32 *)clint_ipi_base;
|
||||
clint_ipi_base = (void *)base;
|
||||
clint_ipi = (u32 *)clint_ipi_base;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -105,7 +105,7 @@ void clint_timer_event_stop(void)
|
|||
if (clint_time_hart_count <= target_hart)
|
||||
return;
|
||||
|
||||
/* Clear CLINT Time Compare */
|
||||
/* Clear CLINT Time Compare */
|
||||
#if __riscv_xlen == 64
|
||||
writeq_relaxed(-1ULL, &clint_time_cmp[target_hart]);
|
||||
#else
|
||||
|
@ -121,13 +121,14 @@ void clint_timer_event_start(u64 next_event)
|
|||
if (clint_time_hart_count <= target_hart)
|
||||
return;
|
||||
|
||||
/* Program CLINT Time Compare */
|
||||
/* Program CLINT Time Compare */
|
||||
#if __riscv_xlen == 64
|
||||
writeq_relaxed(next_event, &clint_time_cmp[target_hart]);
|
||||
#else
|
||||
u32 mask = -1UL;
|
||||
writel_relaxed(next_event & mask, &clint_time_cmp[target_hart]);
|
||||
writel_relaxed(next_event >> 32, (void *)(&clint_time_cmp[target_hart]) + 0x04);
|
||||
writel_relaxed(next_event >> 32,
|
||||
(void *)(&clint_time_cmp[target_hart]) + 0x04);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -135,11 +136,10 @@ int clint_warm_timer_init(void)
|
|||
{
|
||||
u32 target_hart = sbi_current_hartid();
|
||||
|
||||
if (clint_time_hart_count <= target_hart ||
|
||||
!clint_time_base)
|
||||
if (clint_time_hart_count <= target_hart || !clint_time_base)
|
||||
return -1;
|
||||
|
||||
/* Clear CLINT Time Compare */
|
||||
/* Clear CLINT Time Compare */
|
||||
#if __riscv_xlen == 64
|
||||
writeq_relaxed(-1ULL, &clint_time_cmp[target_hart]);
|
||||
#else
|
||||
|
@ -154,9 +154,9 @@ int clint_cold_timer_init(unsigned long base, u32 hart_count)
|
|||
{
|
||||
/* Figure-out CLINT Time register address */
|
||||
clint_time_hart_count = hart_count;
|
||||
clint_time_base = (void *)base;
|
||||
clint_time_val = (u64 *)(clint_time_base + 0xbff8);
|
||||
clint_time_cmp = (u64 *)(clint_time_base + 0x4000);
|
||||
clint_time_base = (void *)base;
|
||||
clint_time_val = (u64 *)(clint_time_base + 0xbff8);
|
||||
clint_time_cmp = (u64 *)(clint_time_base + 0x4000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
#include <plat/string.h>
|
||||
#include <plat/tinyfdt.h>
|
||||
|
||||
#define FDT_MAGIC 0xd00dfeed
|
||||
#define FDT_VERSION 17
|
||||
#define FDT_MAGIC 0xd00dfeed
|
||||
#define FDT_VERSION 17
|
||||
|
||||
struct fdt_header {
|
||||
u32 magic;
|
||||
|
@ -26,28 +26,25 @@ struct fdt_header {
|
|||
u32 size_dt_struct;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define FDT_BEGIN_NODE 1
|
||||
#define FDT_END_NODE 2
|
||||
#define FDT_PROP 3
|
||||
#define FDT_NOP 4
|
||||
#define FDT_END 9
|
||||
#define FDT_BEGIN_NODE 1
|
||||
#define FDT_END_NODE 2
|
||||
#define FDT_PROP 3
|
||||
#define FDT_NOP 4
|
||||
#define FDT_END 9
|
||||
|
||||
u32 fdt_rev32(u32 v)
|
||||
{
|
||||
return ((v & 0x000000FF) << 24) |
|
||||
((v & 0x0000FF00) << 8) |
|
||||
((v & 0x00FF0000) >> 8) |
|
||||
((v & 0xFF000000) >> 24);
|
||||
return ((v & 0x000000FF) << 24) | ((v & 0x0000FF00) << 8) |
|
||||
((v & 0x00FF0000) >> 8) | ((v & 0xFF000000) >> 24);
|
||||
}
|
||||
|
||||
int fdt_prop_string_index(const struct fdt_prop *prop,
|
||||
const char *str)
|
||||
int fdt_prop_string_index(const struct fdt_prop *prop, const char *str)
|
||||
{
|
||||
int i;
|
||||
ulong l = 0;
|
||||
const char *p, *end;
|
||||
|
||||
p = prop->value;
|
||||
p = prop->value;
|
||||
end = p + prop->len;
|
||||
|
||||
for (i = 0; p < end; i++, p += l) {
|
||||
|
@ -62,14 +59,13 @@ int fdt_prop_string_index(const struct fdt_prop *prop,
|
|||
}
|
||||
|
||||
struct recursive_iter_info {
|
||||
void (*fn)(const struct fdt_node *node,
|
||||
const struct fdt_prop *prop,
|
||||
void (*fn)(const struct fdt_node *node, const struct fdt_prop *prop,
|
||||
void *priv);
|
||||
void *fn_priv;
|
||||
const char *str;
|
||||
};
|
||||
|
||||
#define DATA32(ptr) fdt_rev32(*((u32*)ptr))
|
||||
#define DATA32(ptr) fdt_rev32(*((u32 *)ptr))
|
||||
|
||||
static void recursive_iter(char **data, struct recursive_iter_info *info,
|
||||
const struct fdt_node *parent)
|
||||
|
@ -85,7 +81,7 @@ static void recursive_iter(char **data, struct recursive_iter_info *info,
|
|||
(*data) += sizeof(u32);
|
||||
|
||||
node.parent = parent;
|
||||
node.name = *data;
|
||||
node.name = *data;
|
||||
|
||||
*data += strlen(*data) + 1;
|
||||
while ((ulong)(*data) % sizeof(u32) != 0)
|
||||
|
@ -95,7 +91,7 @@ static void recursive_iter(char **data, struct recursive_iter_info *info,
|
|||
|
||||
/* Default cell counts, as per the FDT spec */
|
||||
node.address_cells = 2;
|
||||
node.size_cells = 1;
|
||||
node.size_cells = 1;
|
||||
|
||||
info->fn(&node, NULL, info->fn_priv);
|
||||
|
||||
|
@ -129,19 +125,16 @@ static void recursive_iter(char **data, struct recursive_iter_info *info,
|
|||
}
|
||||
|
||||
struct match_iter_info {
|
||||
int (*match)(const struct fdt_node *node,
|
||||
const struct fdt_prop *prop,
|
||||
int (*match)(const struct fdt_node *node, const struct fdt_prop *prop,
|
||||
void *priv);
|
||||
void *match_priv;
|
||||
void (*fn)(const struct fdt_node *node,
|
||||
const struct fdt_prop *prop,
|
||||
void (*fn)(const struct fdt_node *node, const struct fdt_prop *prop,
|
||||
void *priv);
|
||||
void *fn_priv;
|
||||
const char *str;
|
||||
};
|
||||
|
||||
static void match_iter(const struct fdt_node *node,
|
||||
const struct fdt_prop *prop,
|
||||
static void match_iter(const struct fdt_node *node, const struct fdt_prop *prop,
|
||||
void *priv)
|
||||
{
|
||||
char *data;
|
||||
|
@ -185,12 +178,10 @@ static void match_iter(const struct fdt_node *node,
|
|||
|
||||
int fdt_match_node_prop(void *fdt,
|
||||
int (*match)(const struct fdt_node *node,
|
||||
const struct fdt_prop *prop,
|
||||
void *priv),
|
||||
const struct fdt_prop *prop, void *priv),
|
||||
void *match_priv,
|
||||
void (*fn)(const struct fdt_node *node,
|
||||
const struct fdt_prop *prop,
|
||||
void *priv),
|
||||
const struct fdt_prop *prop, void *priv),
|
||||
void *fn_priv)
|
||||
{
|
||||
char *data;
|
||||
|
@ -201,23 +192,23 @@ int fdt_match_node_prop(void *fdt,
|
|||
|
||||
if (!fdt || !match)
|
||||
return -1;
|
||||
|
||||
|
||||
header = fdt;
|
||||
if (fdt_rev32(header->magic) != FDT_MAGIC ||
|
||||
fdt_rev32(header->last_comp_version) > FDT_VERSION)
|
||||
return -1;
|
||||
string_offset = fdt_rev32(header->off_dt_strings);
|
||||
data_offset = fdt_rev32(header->off_dt_struct);
|
||||
data_offset = fdt_rev32(header->off_dt_struct);
|
||||
|
||||
minfo.match = match;
|
||||
minfo.match = match;
|
||||
minfo.match_priv = match_priv;
|
||||
minfo.fn = fn;
|
||||
minfo.fn_priv = fn_priv;
|
||||
minfo.str = (const char *)(fdt + string_offset);
|
||||
minfo.fn = fn;
|
||||
minfo.fn_priv = fn_priv;
|
||||
minfo.str = (const char *)(fdt + string_offset);
|
||||
|
||||
rinfo.fn = match_iter;
|
||||
rinfo.fn = match_iter;
|
||||
rinfo.fn_priv = &minfo;
|
||||
rinfo.str = minfo.str;
|
||||
rinfo.str = minfo.str;
|
||||
|
||||
data = (char *)(fdt + data_offset);
|
||||
recursive_iter(&data, &rinfo, NULL);
|
||||
|
@ -230,8 +221,7 @@ struct match_compat_info {
|
|||
};
|
||||
|
||||
static int match_compat(const struct fdt_node *node,
|
||||
const struct fdt_prop *prop,
|
||||
void *priv)
|
||||
const struct fdt_prop *prop, void *priv)
|
||||
{
|
||||
struct match_compat_info *cinfo = priv;
|
||||
|
||||
|
@ -247,21 +237,17 @@ static int match_compat(const struct fdt_node *node,
|
|||
return 1;
|
||||
}
|
||||
|
||||
int fdt_compat_node_prop(void *fdt,
|
||||
const char *compat,
|
||||
int fdt_compat_node_prop(void *fdt, const char *compat,
|
||||
void (*fn)(const struct fdt_node *node,
|
||||
const struct fdt_prop *prop,
|
||||
void *priv),
|
||||
const struct fdt_prop *prop, void *priv),
|
||||
void *fn_priv)
|
||||
{
|
||||
struct match_compat_info cinfo = { .compat = compat };
|
||||
|
||||
return fdt_match_node_prop(fdt, match_compat, &cinfo,
|
||||
fn, fn_priv);
|
||||
return fdt_match_node_prop(fdt, match_compat, &cinfo, fn, fn_priv);
|
||||
}
|
||||
|
||||
static int match_walk(const struct fdt_node *node,
|
||||
const struct fdt_prop *prop,
|
||||
static int match_walk(const struct fdt_node *node, const struct fdt_prop *prop,
|
||||
void *priv)
|
||||
{
|
||||
if (!prop)
|
||||
|
@ -272,12 +258,10 @@ static int match_walk(const struct fdt_node *node,
|
|||
|
||||
int fdt_walk(void *fdt,
|
||||
void (*fn)(const struct fdt_node *node,
|
||||
const struct fdt_prop *prop,
|
||||
void *priv),
|
||||
const struct fdt_prop *prop, void *priv),
|
||||
void *fn_priv)
|
||||
{
|
||||
return fdt_match_node_prop(fdt, match_walk, NULL,
|
||||
fn, fn_priv);
|
||||
return fdt_match_node_prop(fdt, match_walk, NULL, fn, fn_priv);
|
||||
}
|
||||
|
||||
u32 fdt_size(void *fdt)
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include "platform.h"
|
||||
#include "uarths.h"
|
||||
|
||||
#define K210_UART_BAUDRATE 115200
|
||||
#define K210_UART_BAUDRATE 115200
|
||||
|
||||
static int k210_console_init(void)
|
||||
{
|
||||
|
@ -42,16 +42,13 @@ static int k210_irqchip_init(bool cold_boot)
|
|||
u32 hartid = sbi_current_hartid();
|
||||
|
||||
if (cold_boot) {
|
||||
rc = plic_cold_irqchip_init(PLIC_BASE_ADDR,
|
||||
PLIC_NUM_SOURCES,
|
||||
rc = plic_cold_irqchip_init(PLIC_BASE_ADDR, PLIC_NUM_SOURCES,
|
||||
K210_HART_COUNT);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
return plic_warm_irqchip_init(hartid,
|
||||
(2 * hartid),
|
||||
(2 * hartid + 1));
|
||||
return plic_warm_irqchip_init(hartid, (2 * hartid), (2 * hartid + 1));
|
||||
}
|
||||
|
||||
static int k210_ipi_init(bool cold_boot)
|
||||
|
@ -59,8 +56,7 @@ static int k210_ipi_init(bool cold_boot)
|
|||
int rc;
|
||||
|
||||
if (cold_boot) {
|
||||
rc = clint_cold_ipi_init(CLINT_BASE_ADDR,
|
||||
K210_HART_COUNT);
|
||||
rc = clint_cold_ipi_init(CLINT_BASE_ADDR, K210_HART_COUNT);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
@ -73,8 +69,7 @@ static int k210_timer_init(bool cold_boot)
|
|||
int rc;
|
||||
|
||||
if (cold_boot) {
|
||||
rc = clint_cold_timer_init(CLINT_BASE_ADDR,
|
||||
K210_HART_COUNT);
|
||||
rc = clint_cold_timer_init(CLINT_BASE_ADDR, K210_HART_COUNT);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
@ -100,11 +95,11 @@ static int k210_system_shutdown(u32 type)
|
|||
|
||||
const struct sbi_platform platform = {
|
||||
|
||||
.name = "Kendryte K210",
|
||||
.name = "Kendryte K210",
|
||||
.features = SBI_PLATFORM_HAS_TIMER_VALUE,
|
||||
|
||||
.hart_count = K210_HART_COUNT,
|
||||
.hart_stack_size = K210_HART_STACK_SIZE,
|
||||
.hart_count = K210_HART_COUNT,
|
||||
.hart_stack_size = K210_HART_STACK_SIZE,
|
||||
.disabled_hart_mask = 0,
|
||||
|
||||
.console_init = k210_console_init,
|
||||
|
@ -113,16 +108,16 @@ const struct sbi_platform platform = {
|
|||
|
||||
.irqchip_init = k210_irqchip_init,
|
||||
|
||||
.ipi_init = k210_ipi_init,
|
||||
.ipi_send = clint_ipi_send,
|
||||
.ipi_sync = clint_ipi_sync,
|
||||
.ipi_init = k210_ipi_init,
|
||||
.ipi_send = clint_ipi_send,
|
||||
.ipi_sync = clint_ipi_sync,
|
||||
.ipi_clear = clint_ipi_clear,
|
||||
|
||||
.timer_init = k210_timer_init,
|
||||
.timer_value = clint_timer_value,
|
||||
.timer_event_stop = clint_timer_event_stop,
|
||||
.timer_init = k210_timer_init,
|
||||
.timer_value = clint_timer_value,
|
||||
.timer_event_stop = clint_timer_event_stop,
|
||||
.timer_event_start = clint_timer_event_start,
|
||||
|
||||
.system_reboot = k210_system_reboot,
|
||||
.system_reboot = k210_system_reboot,
|
||||
.system_shutdown = k210_system_shutdown
|
||||
};
|
||||
|
|
|
@ -28,9 +28,9 @@ static u32 sysctl_pll0_get_freq(void)
|
|||
u32 freq_in, nr, nf, od;
|
||||
|
||||
freq_in = SYSCTRL_CLOCK_FREQ_IN0;
|
||||
nr = sysctl->pll0.clkr0 + 1;
|
||||
nf = sysctl->pll0.clkf0 + 1;
|
||||
od = sysctl->pll0.clkod0 + 1;
|
||||
nr = sysctl->pll0.clkr0 + 1;
|
||||
nf = sysctl->pll0.clkf0 + 1;
|
||||
od = sysctl->pll0.clkod0 + 1;
|
||||
|
||||
/*
|
||||
* Get final PLL output freq
|
||||
|
@ -50,9 +50,8 @@ u32 sysctl_get_cpu_freq(void)
|
|||
return SYSCTRL_CLOCK_FREQ_IN0;
|
||||
case 1:
|
||||
return sysctl_pll0_get_freq() /
|
||||
(2ULL << (int)sysctl->clk_sel0.aclk_divider_sel);
|
||||
(2ULL << (int)sysctl->clk_sel0.aclk_divider_sel);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -588,7 +588,7 @@ typedef struct _sysctl_clk_th6 {
|
|||
typedef struct _sysctl_misc {
|
||||
u32 debug_sel : 6;
|
||||
u32 reserved0 : 4;
|
||||
u32 spi_dvp_data_enable: 1;
|
||||
u32 spi_dvp_data_enable : 1;
|
||||
u32 reserved1 : 21;
|
||||
} __attribute__((packed, aligned(4))) sysctl_misc_t;
|
||||
|
||||
|
|
|
@ -26,19 +26,19 @@ static volatile struct uarths *const uarths =
|
|||
void uarths_init(u32 baud_rate, enum uarths_stopbit stopbit)
|
||||
{
|
||||
u32 freq = sysctl_get_cpu_freq();
|
||||
u16 div = freq / baud_rate - 1;
|
||||
u16 div = freq / baud_rate - 1;
|
||||
|
||||
/* Set UART registers */
|
||||
uarths->div.div = div;
|
||||
uarths->div.div = div;
|
||||
uarths->txctrl.nstop = stopbit;
|
||||
uarths->txctrl.txen = 1;
|
||||
uarths->rxctrl.rxen = 1;
|
||||
uarths->txctrl.txen = 1;
|
||||
uarths->rxctrl.rxen = 1;
|
||||
uarths->txctrl.txcnt = 0;
|
||||
uarths->rxctrl.rxcnt = 0;
|
||||
uarths->ip.txwm = 1;
|
||||
uarths->ip.rxwm = 0;
|
||||
uarths->ie.txwm = 1;
|
||||
uarths->ie.rxwm = 0;
|
||||
uarths->ip.txwm = 1;
|
||||
uarths->ip.rxwm = 0;
|
||||
uarths->ie.txwm = 1;
|
||||
uarths->ie.rxwm = 0;
|
||||
|
||||
/* Clear input */
|
||||
if (!uarths->rxdata.empty)
|
||||
|
@ -47,7 +47,8 @@ void uarths_init(u32 baud_rate, enum uarths_stopbit stopbit)
|
|||
|
||||
void uarths_putc(char c)
|
||||
{
|
||||
while (uarths->txdata.full);
|
||||
while (uarths->txdata.full)
|
||||
;
|
||||
|
||||
uarths->txdata.data = (u8)c;
|
||||
}
|
||||
|
@ -61,4 +62,3 @@ int uarths_getc(void)
|
|||
|
||||
return rx.data;
|
||||
}
|
||||
|
||||
|
|
|
@ -162,10 +162,7 @@ struct uarths {
|
|||
struct uarths_div div;
|
||||
} __attribute__((packed, aligned(4)));
|
||||
|
||||
enum uarths_stopbit {
|
||||
UARTHS_STOP_1,
|
||||
UARTHS_STOP_2
|
||||
};
|
||||
enum uarths_stopbit { UARTHS_STOP_1, UARTHS_STOP_2 };
|
||||
|
||||
void uarths_init(u32 baud_rate, enum uarths_stopbit stopbit);
|
||||
void uarths_putc(char c);
|
||||
|
|
|
@ -52,15 +52,15 @@ static u32 sifive_u_pmp_region_count(u32 hartid)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int sifive_u_pmp_region_info(u32 hartid, u32 index,
|
||||
ulong *prot, ulong *addr, ulong *log2size)
|
||||
static int sifive_u_pmp_region_info(u32 hartid, u32 index, ulong *prot,
|
||||
ulong *addr, ulong *log2size)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
switch (index) {
|
||||
case 0:
|
||||
*prot = PMP_R | PMP_W | PMP_X;
|
||||
*addr = 0;
|
||||
*prot = PMP_R | PMP_W | PMP_X;
|
||||
*addr = 0;
|
||||
*log2size = __riscv_xlen;
|
||||
break;
|
||||
default:
|
||||
|
@ -73,8 +73,8 @@ static int sifive_u_pmp_region_info(u32 hartid, u32 index,
|
|||
|
||||
static int sifive_u_console_init(void)
|
||||
{
|
||||
return sifive_uart_init(SIFIVE_U_UART0_ADDR,
|
||||
SIFIVE_U_PERIPH_CLK, 115200);
|
||||
return sifive_uart_init(SIFIVE_U_UART0_ADDR, SIFIVE_U_PERIPH_CLK,
|
||||
115200);
|
||||
}
|
||||
|
||||
static int sifive_u_irqchip_init(bool cold_boot)
|
||||
|
@ -90,9 +90,7 @@ static int sifive_u_irqchip_init(bool cold_boot)
|
|||
return rc;
|
||||
}
|
||||
|
||||
return plic_warm_irqchip_init(hartid,
|
||||
(2 * hartid),
|
||||
(2 * hartid + 1));
|
||||
return plic_warm_irqchip_init(hartid, (2 * hartid), (2 * hartid + 1));
|
||||
}
|
||||
|
||||
static int sifive_u_ipi_init(bool cold_boot)
|
||||
|
@ -130,26 +128,26 @@ static int sifive_u_system_down(u32 type)
|
|||
}
|
||||
|
||||
const struct sbi_platform platform = {
|
||||
.name = "QEMU SiFive Unleashed",
|
||||
.features = SBI_PLATFORM_DEFAULT_FEATURES,
|
||||
.hart_count = SIFIVE_U_HART_COUNT,
|
||||
.hart_stack_size = SIFIVE_U_HART_STACK_SIZE,
|
||||
.name = "QEMU SiFive Unleashed",
|
||||
.features = SBI_PLATFORM_DEFAULT_FEATURES,
|
||||
.hart_count = SIFIVE_U_HART_COUNT,
|
||||
.hart_stack_size = SIFIVE_U_HART_STACK_SIZE,
|
||||
.disabled_hart_mask = 0,
|
||||
.pmp_region_count = sifive_u_pmp_region_count,
|
||||
.pmp_region_info = sifive_u_pmp_region_info,
|
||||
.final_init = sifive_u_final_init,
|
||||
.console_putc = sifive_uart_putc,
|
||||
.console_getc = sifive_uart_getc,
|
||||
.console_init = sifive_u_console_init,
|
||||
.irqchip_init = sifive_u_irqchip_init,
|
||||
.ipi_send = clint_ipi_send,
|
||||
.ipi_sync = clint_ipi_sync,
|
||||
.ipi_clear = clint_ipi_clear,
|
||||
.ipi_init = sifive_u_ipi_init,
|
||||
.timer_value = clint_timer_value,
|
||||
.timer_event_stop = clint_timer_event_stop,
|
||||
.timer_event_start = clint_timer_event_start,
|
||||
.timer_init = sifive_u_timer_init,
|
||||
.system_reboot = sifive_u_system_down,
|
||||
.system_shutdown = sifive_u_system_down
|
||||
.pmp_region_count = sifive_u_pmp_region_count,
|
||||
.pmp_region_info = sifive_u_pmp_region_info,
|
||||
.final_init = sifive_u_final_init,
|
||||
.console_putc = sifive_uart_putc,
|
||||
.console_getc = sifive_uart_getc,
|
||||
.console_init = sifive_u_console_init,
|
||||
.irqchip_init = sifive_u_irqchip_init,
|
||||
.ipi_send = clint_ipi_send,
|
||||
.ipi_sync = clint_ipi_sync,
|
||||
.ipi_clear = clint_ipi_clear,
|
||||
.ipi_init = sifive_u_ipi_init,
|
||||
.timer_value = clint_timer_value,
|
||||
.timer_event_stop = clint_timer_event_stop,
|
||||
.timer_event_start = clint_timer_event_start,
|
||||
.timer_init = sifive_u_timer_init,
|
||||
.system_reboot = sifive_u_system_down,
|
||||
.system_shutdown = sifive_u_system_down
|
||||
};
|
||||
|
|
|
@ -56,15 +56,15 @@ static u32 virt_pmp_region_count(u32 hartid)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int virt_pmp_region_info(u32 hartid, u32 index,
|
||||
ulong *prot, ulong *addr, ulong *log2size)
|
||||
static int virt_pmp_region_info(u32 hartid, u32 index, ulong *prot, ulong *addr,
|
||||
ulong *log2size)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
switch (index) {
|
||||
case 0:
|
||||
*prot = PMP_R | PMP_W | PMP_X;
|
||||
*addr = 0;
|
||||
*prot = PMP_R | PMP_W | PMP_X;
|
||||
*addr = 0;
|
||||
*log2size = __riscv_xlen;
|
||||
break;
|
||||
default:
|
||||
|
@ -77,8 +77,7 @@ static int virt_pmp_region_info(u32 hartid, u32 index,
|
|||
|
||||
static int virt_console_init(void)
|
||||
{
|
||||
return uart8250_init(VIRT_UART16550_ADDR,
|
||||
VIRT_UART_SHIFTREG_ADDR,
|
||||
return uart8250_init(VIRT_UART16550_ADDR, VIRT_UART_SHIFTREG_ADDR,
|
||||
VIRT_UART_BAUDRATE, 0, 1);
|
||||
}
|
||||
|
||||
|
@ -88,16 +87,13 @@ static int virt_irqchip_init(bool cold_boot)
|
|||
u32 hartid = sbi_current_hartid();
|
||||
|
||||
if (cold_boot) {
|
||||
rc = plic_cold_irqchip_init(VIRT_PLIC_ADDR,
|
||||
VIRT_PLIC_NUM_SOURCES,
|
||||
VIRT_HART_COUNT);
|
||||
rc = plic_cold_irqchip_init(
|
||||
VIRT_PLIC_ADDR, VIRT_PLIC_NUM_SOURCES, VIRT_HART_COUNT);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
return plic_warm_irqchip_init(hartid,
|
||||
(2 * hartid),
|
||||
(2 * hartid + 1));
|
||||
return plic_warm_irqchip_init(hartid, (2 * hartid), (2 * hartid + 1));
|
||||
}
|
||||
|
||||
static int virt_ipi_init(bool cold_boot)
|
||||
|
@ -105,8 +101,7 @@ static int virt_ipi_init(bool cold_boot)
|
|||
int rc;
|
||||
|
||||
if (cold_boot) {
|
||||
rc = clint_cold_ipi_init(VIRT_CLINT_ADDR,
|
||||
VIRT_HART_COUNT);
|
||||
rc = clint_cold_ipi_init(VIRT_CLINT_ADDR, VIRT_HART_COUNT);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
@ -119,8 +114,7 @@ static int virt_timer_init(bool cold_boot)
|
|||
int rc;
|
||||
|
||||
if (cold_boot) {
|
||||
rc = clint_cold_timer_init(VIRT_CLINT_ADDR,
|
||||
VIRT_HART_COUNT);
|
||||
rc = clint_cold_timer_init(VIRT_CLINT_ADDR, VIRT_HART_COUNT);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
@ -139,26 +133,26 @@ static int virt_system_down(u32 type)
|
|||
}
|
||||
|
||||
const struct sbi_platform platform = {
|
||||
.name = "QEMU Virt Machine",
|
||||
.features = SBI_PLATFORM_DEFAULT_FEATURES,
|
||||
.hart_count = VIRT_HART_COUNT,
|
||||
.hart_stack_size = VIRT_HART_STACK_SIZE,
|
||||
.name = "QEMU Virt Machine",
|
||||
.features = SBI_PLATFORM_DEFAULT_FEATURES,
|
||||
.hart_count = VIRT_HART_COUNT,
|
||||
.hart_stack_size = VIRT_HART_STACK_SIZE,
|
||||
.disabled_hart_mask = 0,
|
||||
.pmp_region_count = virt_pmp_region_count,
|
||||
.pmp_region_info = virt_pmp_region_info,
|
||||
.final_init = virt_final_init,
|
||||
.console_putc = uart8250_putc,
|
||||
.console_getc = uart8250_getc,
|
||||
.console_init = virt_console_init,
|
||||
.irqchip_init = virt_irqchip_init,
|
||||
.ipi_send = clint_ipi_send,
|
||||
.ipi_sync = clint_ipi_sync,
|
||||
.ipi_clear = clint_ipi_clear,
|
||||
.ipi_init = virt_ipi_init,
|
||||
.timer_value = clint_timer_value,
|
||||
.timer_event_stop = clint_timer_event_stop,
|
||||
.timer_event_start = clint_timer_event_start,
|
||||
.timer_init = virt_timer_init,
|
||||
.system_reboot = virt_system_down,
|
||||
.system_shutdown = virt_system_down
|
||||
.pmp_region_count = virt_pmp_region_count,
|
||||
.pmp_region_info = virt_pmp_region_info,
|
||||
.final_init = virt_final_init,
|
||||
.console_putc = uart8250_putc,
|
||||
.console_getc = uart8250_getc,
|
||||
.console_init = virt_console_init,
|
||||
.irqchip_init = virt_irqchip_init,
|
||||
.ipi_send = clint_ipi_send,
|
||||
.ipi_sync = clint_ipi_sync,
|
||||
.ipi_clear = clint_ipi_clear,
|
||||
.ipi_init = virt_ipi_init,
|
||||
.timer_value = clint_timer_value,
|
||||
.timer_event_stop = clint_timer_event_stop,
|
||||
.timer_event_start = clint_timer_event_start,
|
||||
.timer_init = virt_timer_init,
|
||||
.system_reboot = virt_system_down,
|
||||
.system_shutdown = virt_system_down
|
||||
};
|
||||
|
|
|
@ -65,18 +65,19 @@ static void fu540_modify_dt(void *fdt)
|
|||
for (i = 0; i < FU540_HART_COUNT; i++) {
|
||||
sbi_sprintf(cpu_node, "/cpus/cpu@%d", i);
|
||||
cpu_offset = fdt_path_offset(fdt, cpu_node);
|
||||
mmu_type = fdt_getprop(fdt, cpu_offset, "mmu-type", NULL);
|
||||
mmu_type = fdt_getprop(fdt, cpu_offset, "mmu-type", NULL);
|
||||
if (mmu_type && (!strcmp(mmu_type, "riscv,sv39") ||
|
||||
!strcmp(mmu_type,"riscv,sv48")))
|
||||
!strcmp(mmu_type, "riscv,sv48")))
|
||||
continue;
|
||||
else
|
||||
fdt_setprop_string(fdt, cpu_offset, "status", "masked");
|
||||
memset(cpu_node, 0, sizeof(cpu_node));
|
||||
}
|
||||
size = fdt_totalsize(fdt);
|
||||
err = fdt_open_into(fdt, fdt, size + 256);
|
||||
err = fdt_open_into(fdt, fdt, size + 256);
|
||||
if (err < 0)
|
||||
sbi_printf("Device Tree can't be expanded to accmodate new node");
|
||||
sbi_printf(
|
||||
"Device Tree can't be expanded to accmodate new node");
|
||||
|
||||
chosen_offset = fdt_path_offset(fdt, "/chosen");
|
||||
fdt_setprop_string(fdt, chosen_offset, "stdout-path",
|
||||
|
@ -103,15 +104,15 @@ static u32 fu540_pmp_region_count(u32 hartid)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int fu540_pmp_region_info(u32 hartid, u32 index,
|
||||
ulong *prot, ulong *addr, ulong *log2size)
|
||||
static int fu540_pmp_region_info(u32 hartid, u32 index, ulong *prot,
|
||||
ulong *addr, ulong *log2size)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
switch (index) {
|
||||
case 0:
|
||||
*prot = PMP_R | PMP_W | PMP_X;
|
||||
*addr = 0;
|
||||
*prot = PMP_R | PMP_W | PMP_X;
|
||||
*addr = 0;
|
||||
*log2size = __riscv_xlen;
|
||||
break;
|
||||
default:
|
||||
|
@ -128,14 +129,14 @@ static int fu540_console_init(void)
|
|||
|
||||
if (readl((volatile void *)FU540_PRCI_BASE_ADDR +
|
||||
FU540_PRCI_CLKMUXSTATUSREG) &
|
||||
FU540_PRCI_CLKMUX_STATUS_TLCLKSEL) {
|
||||
FU540_PRCI_CLKMUX_STATUS_TLCLKSEL) {
|
||||
peri_in_freq = FU540_SYS_CLK;
|
||||
} else {
|
||||
peri_in_freq = FU540_SYS_CLK / 2;
|
||||
}
|
||||
|
||||
return sifive_uart_init(FU540_UART0_ADDR,
|
||||
peri_in_freq, FU540_UART_BAUDRATE);
|
||||
return sifive_uart_init(FU540_UART0_ADDR, peri_in_freq,
|
||||
FU540_UART_BAUDRATE);
|
||||
}
|
||||
|
||||
static int fu540_irqchip_init(bool cold_boot)
|
||||
|
@ -151,9 +152,8 @@ static int fu540_irqchip_init(bool cold_boot)
|
|||
return rc;
|
||||
}
|
||||
|
||||
return plic_warm_irqchip_init(hartid,
|
||||
(hartid) ? (2 * hartid - 1) : 0,
|
||||
(hartid) ? (2 * hartid) : -1);
|
||||
return plic_warm_irqchip_init(hartid, (hartid) ? (2 * hartid - 1) : 0,
|
||||
(hartid) ? (2 * hartid) : -1);
|
||||
}
|
||||
|
||||
static int fu540_ipi_init(bool cold_boot)
|
||||
|
@ -161,11 +161,9 @@ static int fu540_ipi_init(bool cold_boot)
|
|||
int rc;
|
||||
|
||||
if (cold_boot) {
|
||||
rc = clint_cold_ipi_init(FU540_CLINT_ADDR,
|
||||
FU540_HART_COUNT);
|
||||
rc = clint_cold_ipi_init(FU540_CLINT_ADDR, FU540_HART_COUNT);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
}
|
||||
|
||||
return clint_warm_ipi_init();
|
||||
|
@ -176,8 +174,7 @@ static int fu540_timer_init(bool cold_boot)
|
|||
int rc;
|
||||
|
||||
if (cold_boot) {
|
||||
rc = clint_cold_timer_init(FU540_CLINT_ADDR,
|
||||
FU540_HART_COUNT);
|
||||
rc = clint_cold_timer_init(FU540_CLINT_ADDR, FU540_HART_COUNT);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
@ -192,26 +189,26 @@ static int fu540_system_down(u32 type)
|
|||
}
|
||||
|
||||
const struct sbi_platform platform = {
|
||||
.name = "SiFive Freedom U540",
|
||||
.features = SBI_PLATFORM_DEFAULT_FEATURES,
|
||||
.hart_count = FU540_HART_COUNT,
|
||||
.hart_stack_size = FU540_HART_STACK_SIZE,
|
||||
.name = "SiFive Freedom U540",
|
||||
.features = SBI_PLATFORM_DEFAULT_FEATURES,
|
||||
.hart_count = FU540_HART_COUNT,
|
||||
.hart_stack_size = FU540_HART_STACK_SIZE,
|
||||
.disabled_hart_mask = FU540_HARITD_DISABLED,
|
||||
.pmp_region_count = fu540_pmp_region_count,
|
||||
.pmp_region_info = fu540_pmp_region_info,
|
||||
.final_init = fu540_final_init,
|
||||
.console_putc = sifive_uart_putc,
|
||||
.console_getc = sifive_uart_getc,
|
||||
.console_init = fu540_console_init,
|
||||
.irqchip_init = fu540_irqchip_init,
|
||||
.ipi_send = clint_ipi_send,
|
||||
.ipi_sync = clint_ipi_sync,
|
||||
.ipi_clear = clint_ipi_clear,
|
||||
.ipi_init = fu540_ipi_init,
|
||||
.timer_value = clint_timer_value,
|
||||
.timer_event_stop = clint_timer_event_stop,
|
||||
.timer_event_start = clint_timer_event_start,
|
||||
.timer_init = fu540_timer_init,
|
||||
.system_reboot = fu540_system_down,
|
||||
.system_shutdown = fu540_system_down
|
||||
.pmp_region_count = fu540_pmp_region_count,
|
||||
.pmp_region_info = fu540_pmp_region_info,
|
||||
.final_init = fu540_final_init,
|
||||
.console_putc = sifive_uart_putc,
|
||||
.console_getc = sifive_uart_getc,
|
||||
.console_init = fu540_console_init,
|
||||
.irqchip_init = fu540_irqchip_init,
|
||||
.ipi_send = clint_ipi_send,
|
||||
.ipi_sync = clint_ipi_sync,
|
||||
.ipi_clear = clint_ipi_clear,
|
||||
.ipi_init = fu540_ipi_init,
|
||||
.timer_value = clint_timer_value,
|
||||
.timer_event_stop = clint_timer_event_stop,
|
||||
.timer_event_start = clint_timer_event_start,
|
||||
.timer_init = fu540_timer_init,
|
||||
.system_reboot = fu540_system_down,
|
||||
.system_shutdown = fu540_system_down
|
||||
};
|
||||
|
|
|
@ -44,8 +44,8 @@ static u32 platform_pmp_region_count(u32 hartid)
|
|||
* Get PMP regions details (namely: protection, base address, and size) for
|
||||
* a given HART.
|
||||
*/
|
||||
static int platform_pmp_region_info(u32 hartid, u32 index,
|
||||
ulong *prot, ulong *addr, ulong *log2size)
|
||||
static int platform_pmp_region_info(u32 hartid, u32 index, ulong *prot,
|
||||
ulong *addr, ulong *log2size)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -56,8 +56,7 @@ static int platform_pmp_region_info(u32 hartid, u32 index,
|
|||
static int platform_console_init(void)
|
||||
{
|
||||
/* Example if the generic UART8250 driver is used */
|
||||
return uart8250_init(PLATFORM_UART_ADDR,
|
||||
PLATFORM_UART_SHIFTREG_ADDR,
|
||||
return uart8250_init(PLATFORM_UART_ADDR, PLATFORM_UART_SHIFTREG_ADDR,
|
||||
PLATFORM_UART_BAUDRATE, 0, 1);
|
||||
}
|
||||
|
||||
|
@ -209,34 +208,33 @@ static int platform_system_shutdown(u32 type)
|
|||
*/
|
||||
const struct sbi_platform platform = {
|
||||
|
||||
.name = "platform-name",
|
||||
.features = SBI_PLATFORM_DEFAULT_FEATURES,
|
||||
.hart_count = 1,
|
||||
.hart_stack_size = 4096,
|
||||
.name = "platform-name",
|
||||
.features = SBI_PLATFORM_DEFAULT_FEATURES,
|
||||
.hart_count = 1,
|
||||
.hart_stack_size = 4096,
|
||||
.disabled_hart_mask = 0,
|
||||
|
||||
.early_init = platform_early_init,
|
||||
.final_init = platform_final_init,
|
||||
|
||||
.pmp_region_count = platform_pmp_region_count,
|
||||
.pmp_region_info = platform_pmp_region_info,
|
||||
.pmp_region_info = platform_pmp_region_info,
|
||||
|
||||
.console_init = platform_console_init,
|
||||
.console_putc = platform_console_putc,
|
||||
.console_getc = platform_console_getc,
|
||||
|
||||
.irqchip_init = platform_irqchip_init,
|
||||
.ipi_init = platform_ipi_init,
|
||||
.ipi_send = platform_ipi_send,
|
||||
.ipi_sync = platform_ipi_sync,
|
||||
.ipi_clear = platform_ipi_clear,
|
||||
.ipi_init = platform_ipi_init,
|
||||
.ipi_send = platform_ipi_send,
|
||||
.ipi_sync = platform_ipi_sync,
|
||||
.ipi_clear = platform_ipi_clear,
|
||||
|
||||
.timer_init = platform_timer_init,
|
||||
.timer_value = platform_timer_value,
|
||||
.timer_init = platform_timer_init,
|
||||
.timer_value = platform_timer_value,
|
||||
.timer_event_start = platform_timer_event_start,
|
||||
.timer_event_stop = platform_timer_event_stop,
|
||||
.timer_event_stop = platform_timer_event_stop,
|
||||
|
||||
.system_reboot = platform_system_reboot,
|
||||
.system_reboot = platform_system_reboot,
|
||||
.system_shutdown = platform_system_shutdown
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue