forked from Mirrors/opensbi

Currently pmp_get() returns the log2 length of the PMP memory region size. The caller has to calculate the size based on that and the same codes are duplicated. Update this function to return decoded size directly. Signed-off-by: Bin Meng <bmeng.cn@gmail.com> Reviewed-by: Atish Patra <atish.patra@wdc.com>
199 lines
5.5 KiB
C
199 lines
5.5 KiB
C
/*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*
|
|
* Copyright (c) 2019 Western Digital Corporation or its affiliates.
|
|
*
|
|
* Authors:
|
|
* Anup Patel <anup.patel@wdc.com>
|
|
*/
|
|
|
|
#ifndef __RISCV_ASM_H__
|
|
#define __RISCV_ASM_H__
|
|
|
|
#include <sbi/riscv_encoding.h>
|
|
|
|
/* clang-format off */
|
|
|
|
#ifdef __ASSEMBLY__
|
|
#define __ASM_STR(x) x
|
|
#else
|
|
#define __ASM_STR(x) #x
|
|
#endif
|
|
|
|
#if __riscv_xlen == 64
|
|
#define __REG_SEL(a, b) __ASM_STR(a)
|
|
#elif __riscv_xlen == 32
|
|
#define __REG_SEL(a, b) __ASM_STR(b)
|
|
#else
|
|
#error "Unexpected __riscv_xlen"
|
|
#endif
|
|
|
|
#define PAGE_SHIFT (12)
|
|
#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
|
|
#define PAGE_MASK (~(PAGE_SIZE - 1))
|
|
|
|
#define REG_L __REG_SEL(ld, lw)
|
|
#define REG_S __REG_SEL(sd, sw)
|
|
#define SZREG __REG_SEL(8, 4)
|
|
#define LGREG __REG_SEL(3, 2)
|
|
|
|
#if __SIZEOF_POINTER__ == 8
|
|
#ifdef __ASSEMBLY__
|
|
#define RISCV_PTR .dword
|
|
#define RISCV_SZPTR 8
|
|
#define RISCV_LGPTR 3
|
|
#else
|
|
#define RISCV_PTR ".dword"
|
|
#define RISCV_SZPTR "8"
|
|
#define RISCV_LGPTR "3"
|
|
#endif
|
|
#elif __SIZEOF_POINTER__ == 4
|
|
#ifdef __ASSEMBLY__
|
|
#define RISCV_PTR .word
|
|
#define RISCV_SZPTR 4
|
|
#define RISCV_LGPTR 2
|
|
#else
|
|
#define RISCV_PTR ".word"
|
|
#define RISCV_SZPTR "4"
|
|
#define RISCV_LGPTR "2"
|
|
#endif
|
|
#else
|
|
#error "Unexpected __SIZEOF_POINTER__"
|
|
#endif
|
|
|
|
#if (__SIZEOF_INT__ == 4)
|
|
#define RISCV_INT __ASM_STR(.word)
|
|
#define RISCV_SZINT __ASM_STR(4)
|
|
#define RISCV_LGINT __ASM_STR(2)
|
|
#else
|
|
#error "Unexpected __SIZEOF_INT__"
|
|
#endif
|
|
|
|
#if (__SIZEOF_SHORT__ == 2)
|
|
#define RISCV_SHORT __ASM_STR(.half)
|
|
#define RISCV_SZSHORT __ASM_STR(2)
|
|
#define RISCV_LGSHORT __ASM_STR(1)
|
|
#else
|
|
#error "Unexpected __SIZEOF_SHORT__"
|
|
#endif
|
|
|
|
/* clang-format on */
|
|
|
|
#ifndef __ASSEMBLY__
|
|
|
|
#define csr_swap(csr, val) \
|
|
({ \
|
|
unsigned long __v = (unsigned long)(val); \
|
|
__asm__ __volatile__("csrrw %0, " __ASM_STR(csr) ", %1" \
|
|
: "=r"(__v) \
|
|
: "rK"(__v) \
|
|
: "memory"); \
|
|
__v; \
|
|
})
|
|
|
|
#define csr_read(csr) \
|
|
({ \
|
|
register unsigned long __v; \
|
|
__asm__ __volatile__("csrr %0, " __ASM_STR(csr) \
|
|
: "=r"(__v) \
|
|
: \
|
|
: "memory"); \
|
|
__v; \
|
|
})
|
|
|
|
#define csr_write(csr, val) \
|
|
({ \
|
|
unsigned long __v = (unsigned long)(val); \
|
|
__asm__ __volatile__("csrw " __ASM_STR(csr) ", %0" \
|
|
: \
|
|
: "rK"(__v) \
|
|
: "memory"); \
|
|
})
|
|
|
|
#define csr_read_set(csr, val) \
|
|
({ \
|
|
unsigned long __v = (unsigned long)(val); \
|
|
__asm__ __volatile__("csrrs %0, " __ASM_STR(csr) ", %1" \
|
|
: "=r"(__v) \
|
|
: "rK"(__v) \
|
|
: "memory"); \
|
|
__v; \
|
|
})
|
|
|
|
#define csr_set(csr, val) \
|
|
({ \
|
|
unsigned long __v = (unsigned long)(val); \
|
|
__asm__ __volatile__("csrs " __ASM_STR(csr) ", %0" \
|
|
: \
|
|
: "rK"(__v) \
|
|
: "memory"); \
|
|
})
|
|
|
|
#define csr_read_clear(csr, val) \
|
|
({ \
|
|
unsigned long __v = (unsigned long)(val); \
|
|
__asm__ __volatile__("csrrc %0, " __ASM_STR(csr) ", %1" \
|
|
: "=r"(__v) \
|
|
: "rK"(__v) \
|
|
: "memory"); \
|
|
__v; \
|
|
})
|
|
|
|
#define csr_clear(csr, val) \
|
|
({ \
|
|
unsigned long __v = (unsigned long)(val); \
|
|
__asm__ __volatile__("csrc " __ASM_STR(csr) ", %0" \
|
|
: \
|
|
: "rK"(__v) \
|
|
: "memory"); \
|
|
})
|
|
|
|
unsigned long csr_read_num(int csr_num);
|
|
|
|
void csr_write_num(int csr_num, unsigned long val);
|
|
|
|
#define wfi() \
|
|
do { \
|
|
__asm__ __volatile__("wfi" ::: "memory"); \
|
|
} while (0)
|
|
|
|
/* Get current HART id */
|
|
#define current_hartid() ((unsigned int)csr_read(CSR_MHARTID))
|
|
|
|
/* determine CPU extension, return non-zero support */
|
|
int misa_extension_imp(char ext);
|
|
|
|
#define misa_extension(c)\
|
|
({\
|
|
_Static_assert(((c >= 'A') && (c <= 'Z')),\
|
|
"The parameter of misa_extension must be [A-Z]");\
|
|
misa_extension_imp(c);\
|
|
})
|
|
|
|
/* Get MXL field of misa, return -1 on error */
|
|
int misa_xlen(void);
|
|
|
|
static inline void misa_string(char *out, unsigned int out_sz)
|
|
{
|
|
unsigned long i;
|
|
|
|
for (i = 0; i < 26; i++) {
|
|
if (misa_extension_imp('A' + i)) {
|
|
*out = 'A' + i;
|
|
out++;
|
|
}
|
|
}
|
|
*out = '\0';
|
|
out++;
|
|
}
|
|
|
|
int pmp_set(unsigned int n, unsigned long prot, unsigned long addr,
|
|
unsigned long log2len);
|
|
|
|
int pmp_get(unsigned int n, unsigned long *prot_out, unsigned long *addr_out,
|
|
unsigned long *size);
|
|
|
|
#endif /* !__ASSEMBLY__ */
|
|
|
|
#endif
|