mirror of
https://github.com/riscv-software-src/opensbi.git
synced 2025-08-24 15:31:22 +01:00

One of the shortcomings of clang-format is that it doesn't allow for aligned define tables, which is used for a number of constants. Add annotation to disable the automatic formatting where needed. Signed-off-by: Olof Johansson <olof@lixom.net>
189 lines
4.0 KiB
C
189 lines
4.0 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 SBI_TLB_FLUSH_ALL ((unsigned long)-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
|
|
#define BITS_PER_LONG 64
|
|
#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
|
|
#define BITS_PER_LONG 32
|
|
#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)
|
|
|
|
static inline int misa_extension(char ext)
|
|
{
|
|
return csr_read(CSR_MISA) & (1 << (ext - 'A'));
|
|
}
|
|
|
|
static inline int misa_xlen(void)
|
|
{
|
|
return ((long)csr_read(CSR_MISA) < 0) ? 64 : 32;
|
|
}
|
|
|
|
static inline void misa_string(char *out, unsigned int out_sz)
|
|
{
|
|
unsigned long i, val = csr_read(CSR_MISA);
|
|
|
|
for (i = 0; i < 26; i++) {
|
|
if (val & (1 << i)) {
|
|
*out = 'A' + i;
|
|
out++;
|
|
}
|
|
}
|
|
*out = '\0';
|
|
out++;
|
|
}
|
|
|
|
int pmp_set(unsigned int n, unsigned long prot,
|
|
unsigned long addr, unsigned long log2len);
|
|
|
|
int pmp_get(unsigned int n, unsigned long *prot_out,
|
|
unsigned long *addr_out, unsigned long *log2len_out);
|
|
|
|
#endif /* !__ASSEMBLY__ */
|
|
|
|
#endif
|