mirror of
				https://github.com/riscv-software-src/opensbi
				synced 2025-10-30 19:48:23 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			245 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			245 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * Copyright (c) 2018 Western Digital Corporation or its affiliates.
 | |
|  *
 | |
|  * Authors:
 | |
|  *   Anup Patel <anup.patel@wdc.com>
 | |
|  *
 | |
|  * SPDX-License-Identifier: BSD-2-Clause
 | |
|  */
 | |
| 
 | |
| #ifndef __RISCV_ASM_H__
 | |
| #define __RISCV_ASM_H__
 | |
| 
 | |
| #ifdef __ASSEMBLY__
 | |
| #define __ASM_STR(x)	x
 | |
| #else
 | |
| #define __ASM_STR(x)	#x
 | |
| #endif
 | |
| 
 | |
| #if __riscv_xlen == 64
 | |
| #define __REG_SEL(a, b)	__ASM_STR(a)
 | |
| #elif __riscv_xlen == 32
 | |
| #define __REG_SEL(a, b)	__ASM_STR(b)
 | |
| #else
 | |
| #error "Unexpected __riscv_xlen"
 | |
| #endif
 | |
| 
 | |
| #define REG_L		__REG_SEL(ld, lw)
 | |
| #define REG_S		__REG_SEL(sd, sw)
 | |
| #define SZREG		__REG_SEL(8, 4)
 | |
| #define LGREG		__REG_SEL(3, 2)
 | |
| 
 | |
| #if __SIZEOF_POINTER__ == 8
 | |
| #ifdef __ASSEMBLY__
 | |
| #define RISCV_PTR		.dword
 | |
| #define RISCV_SZPTR		8
 | |
| #define RISCV_LGPTR		3
 | |
| #else
 | |
| #define RISCV_PTR		".dword"
 | |
| #define RISCV_SZPTR		"8"
 | |
| #define RISCV_LGPTR		"3"
 | |
| #endif
 | |
| #elif __SIZEOF_POINTER__ == 4
 | |
| #ifdef __ASSEMBLY__
 | |
| #define RISCV_PTR		.word
 | |
| #define RISCV_SZPTR		4
 | |
| #define RISCV_LGPTR		2
 | |
| #else
 | |
| #define RISCV_PTR		".word"
 | |
| #define RISCV_SZPTR		"4"
 | |
| #define RISCV_LGPTR		"2"
 | |
| #endif
 | |
| #else
 | |
| #error "Unexpected __SIZEOF_POINTER__"
 | |
| #endif
 | |
| 
 | |
| #if (__SIZEOF_INT__ == 4)
 | |
| #define RISCV_INT		__ASM_STR(.word)
 | |
| #define RISCV_SZINT		__ASM_STR(4)
 | |
| #define RISCV_LGINT		__ASM_STR(2)
 | |
| #else
 | |
| #error "Unexpected __SIZEOF_INT__"
 | |
| #endif
 | |
| 
 | |
| #if (__SIZEOF_SHORT__ == 2)
 | |
| #define RISCV_SHORT		__ASM_STR(.half)
 | |
| #define RISCV_SZSHORT		__ASM_STR(2)
 | |
| #define RISCV_LGSHORT		__ASM_STR(1)
 | |
| #else
 | |
| #error "Unexpected __SIZEOF_SHORT__"
 | |
| #endif
 | |
| 
 | |
| #define RISCV_SCRATCH_TMP0_OFFSET		(0 * __SIZEOF_POINTER__)
 | |
| #define RISCV_SCRATCH_FW_START_OFFSET		(1 * __SIZEOF_POINTER__)
 | |
| #define RISCV_SCRATCH_FW_SIZE_OFFSET		(2 * __SIZEOF_POINTER__)
 | |
| #define RISCV_SCRATCH_NEXT_ARG1_OFFSET		(3 * __SIZEOF_POINTER__)
 | |
| #define RISCV_SCRATCH_NEXT_ADDR_OFFSET		(4 * __SIZEOF_POINTER__)
 | |
| #define RISCV_SCRATCH_NEXT_MODE_OFFSET		(5 * __SIZEOF_POINTER__)
 | |
| #define RISCV_SCRATCH_WARMBOOT_ADDR_OFFSET	(6 * __SIZEOF_POINTER__)
 | |
| #define RISCV_SCRATCH_PLATFORM_ADDR_OFFSET	(7 * __SIZEOF_POINTER__)
 | |
| #define RISCV_SCRATCH_HARTID_TO_SCRATCH_OFFSET	(8 * __SIZEOF_POINTER__)
 | |
| #define RISCV_SCRATCH_IPI_TYPE_OFFSET		(9 * __SIZEOF_POINTER__)
 | |
| #define RISCV_SCRATCH_SIZE			256
 | |
| 
 | |
| #define RISCV_TRAP_REGS_zero			0
 | |
| #define RISCV_TRAP_REGS_ra			1
 | |
| #define RISCV_TRAP_REGS_sp			2
 | |
| #define RISCV_TRAP_REGS_gp			3
 | |
| #define RISCV_TRAP_REGS_tp			4
 | |
| #define RISCV_TRAP_REGS_t0			5
 | |
| #define RISCV_TRAP_REGS_t1			6
 | |
| #define RISCV_TRAP_REGS_t2			7
 | |
| #define RISCV_TRAP_REGS_s0			8
 | |
| #define RISCV_TRAP_REGS_s1			9
 | |
| #define RISCV_TRAP_REGS_a0			10
 | |
| #define RISCV_TRAP_REGS_a1			11
 | |
| #define RISCV_TRAP_REGS_a2			12
 | |
| #define RISCV_TRAP_REGS_a3			13
 | |
| #define RISCV_TRAP_REGS_a4			14
 | |
| #define RISCV_TRAP_REGS_a5			15
 | |
| #define RISCV_TRAP_REGS_a6			16
 | |
| #define RISCV_TRAP_REGS_a7			17
 | |
| #define RISCV_TRAP_REGS_s2			18
 | |
| #define RISCV_TRAP_REGS_s3			19
 | |
| #define RISCV_TRAP_REGS_s4			20
 | |
| #define RISCV_TRAP_REGS_s5			21
 | |
| #define RISCV_TRAP_REGS_s6			22
 | |
| #define RISCV_TRAP_REGS_s7			23
 | |
| #define RISCV_TRAP_REGS_s8			24
 | |
| #define RISCV_TRAP_REGS_s9			25
 | |
| #define RISCV_TRAP_REGS_s10			26
 | |
| #define RISCV_TRAP_REGS_s11			27
 | |
| #define RISCV_TRAP_REGS_t3			28
 | |
| #define RISCV_TRAP_REGS_t4			29
 | |
| #define RISCV_TRAP_REGS_t5			30
 | |
| #define RISCV_TRAP_REGS_t6			31
 | |
| #define RISCV_TRAP_REGS_mepc			32
 | |
| #define RISCV_TRAP_REGS_mstatus			33
 | |
| #define RISCV_TRAP_REGS_last			34
 | |
| 
 | |
| #define RISCV_TRAP_REGS_OFFSET(x)		\
 | |
| 				((RISCV_TRAP_REGS_##x) * __SIZEOF_POINTER__)
 | |
| #define RISCV_TRAP_REGS_SIZE			RISCV_TRAP_REGS_OFFSET(last)
 | |
| 
 | |
| #ifndef __ASSEMBLY__
 | |
| 
 | |
| #define csr_swap(csr, val)					\
 | |
| ({								\
 | |
| 	unsigned long __v = (unsigned long)(val);		\
 | |
| 	__asm__ __volatile__ ("csrrw %0, " #csr ", %1"		\
 | |
| 			      : "=r" (__v) : "rK" (__v)		\
 | |
| 			      : "memory");			\
 | |
| 	__v;							\
 | |
| })
 | |
| 
 | |
| #define csr_read(csr)						\
 | |
| ({								\
 | |
| 	register unsigned long __v;				\
 | |
| 	__asm__ __volatile__ ("csrr %0, " #csr			\
 | |
| 			      : "=r" (__v) :			\
 | |
| 			      : "memory");			\
 | |
| 	__v;							\
 | |
| })
 | |
| 
 | |
| #define csr_read_n(csr_num)					\
 | |
| ({								\
 | |
| 	register unsigned long __v;				\
 | |
| 	__asm__ __volatile__ ("csrr %0, " __ASM_STR(csr_num)	\
 | |
| 			      : "=r" (__v) :			\
 | |
| 			      : "memory");			\
 | |
| 	__v;							\
 | |
| })
 | |
| 
 | |
| #define csr_write(csr, val)					\
 | |
| ({								\
 | |
| 	unsigned long __v = (unsigned long)(val);		\
 | |
| 	__asm__ __volatile__ ("csrw " #csr ", %0"		\
 | |
| 			      : : "rK" (__v)			\
 | |
| 			      : "memory");			\
 | |
| })
 | |
| 
 | |
| #define csr_write_n(csr_num, val)				\
 | |
| ({								\
 | |
| 	unsigned long __v = (unsigned long)(val);		\
 | |
| 	__asm__ __volatile__ ("csrw " __ASM_STR(csr_num) ", %0"	\
 | |
| 			      : : "rK" (__v)			\
 | |
| 			      : "memory");			\
 | |
| })
 | |
| 
 | |
| #define csr_read_set(csr, val)					\
 | |
| ({								\
 | |
| 	unsigned long __v = (unsigned long)(val);		\
 | |
| 	__asm__ __volatile__ ("csrrs %0, " #csr ", %1"		\
 | |
| 			      : "=r" (__v) : "rK" (__v)		\
 | |
| 			      : "memory");			\
 | |
| 	__v;							\
 | |
| })
 | |
| 
 | |
| #define csr_set(csr, val)					\
 | |
| ({								\
 | |
| 	unsigned long __v = (unsigned long)(val);		\
 | |
| 	__asm__ __volatile__ ("csrs " #csr ", %0"		\
 | |
| 			      : : "rK" (__v)			\
 | |
| 			      : "memory");			\
 | |
| })
 | |
| 
 | |
| #define csr_read_clear(csr, val)				\
 | |
| ({								\
 | |
| 	unsigned long __v = (unsigned long)(val);		\
 | |
| 	__asm__ __volatile__ ("csrrc %0, " #csr ", %1"		\
 | |
| 			      : "=r" (__v) : "rK" (__v)		\
 | |
| 			      : "memory");			\
 | |
| 	__v;							\
 | |
| })
 | |
| 
 | |
| #define csr_clear(csr, val)					\
 | |
| ({								\
 | |
| 	unsigned long __v = (unsigned long)(val);		\
 | |
| 	__asm__ __volatile__ ("csrc " #csr ", %0"		\
 | |
| 			      : : "rK" (__v)			\
 | |
| 			      : "memory");			\
 | |
| })
 | |
| 
 | |
| unsigned long csr_read_num(int csr_num);
 | |
| 
 | |
| void csr_write_num(int csr_num, unsigned long val);
 | |
| 
 | |
| #define wfi()							\
 | |
| do {								\
 | |
| 	__asm__ __volatile__ ("wfi" ::: "memory");		\
 | |
| } while (0)
 | |
| 
 | |
| static inline int misa_extension(char ext)
 | |
| {
 | |
| 	return csr_read(misa) & (1 << (ext - 'A'));
 | |
| }
 | |
| 
 | |
| static inline int misa_xlen(void)
 | |
| {
 | |
| 	return ((long)csr_read(misa) < 0) ? 64 : 32;
 | |
| }
 | |
| 
 | |
| static inline void misa_string(char *out, unsigned int out_sz)
 | |
| {
 | |
| 	unsigned long i, val = csr_read(misa);
 | |
| 
 | |
| 	for (i = 0; i < 26; i++) {
 | |
| 		if (val & (1 << i)) {
 | |
| 			*out = 'A' + i;
 | |
| 			out++;
 | |
| 		}
 | |
| 	}
 | |
| 	*out = '\0';
 | |
| 	out++;
 | |
| }
 | |
| 
 | |
| int pmp_set(unsigned int n, unsigned long prot,
 | |
| 	    unsigned long addr, unsigned long log2len);
 | |
| 
 | |
| int pmp_get(unsigned int n, unsigned long *prot_out,
 | |
| 	    unsigned long *addr_out, unsigned long *log2len_out);
 | |
| 
 | |
| #endif /* !__ASSEMBLY__ */
 | |
| 
 | |
| #endif
 |