forked from Mirrors/opensbi
		
	lib: sbi: add zicfilp/zicfiss and elp cfi state reflect back in status
This patch adds support to check for zicfilp / zicfiss extension. zicfilp record status of hart's ELP state in *status csr. Missing landing pad sets MPELP in mstatus. When SBI is redirecting back to S/VS/HS, SPELP is set in sstatus/vsstatus. Signed-off-by: Deepak Gupta <debug@rivosinc.com> Reviewed-by: Atish Patra <atishp@rivosinc.com> Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
This commit is contained in:
		@@ -69,6 +69,10 @@ enum sbi_hart_extensions {
 | 
			
		||||
	SBI_HART_EXT_SVADU,
 | 
			
		||||
	/** Hart has Smnpm extension */
 | 
			
		||||
	SBI_HART_EXT_SMNPM,
 | 
			
		||||
	/** HART has zicfilp extension */
 | 
			
		||||
	SBI_HART_EXT_ZICFILP,
 | 
			
		||||
	/** HART has zicfiss extension */
 | 
			
		||||
	SBI_HART_EXT_ZICFISS,
 | 
			
		||||
 | 
			
		||||
	/** Maximum index of Hart extension */
 | 
			
		||||
	SBI_HART_EXT_MAX,
 | 
			
		||||
 
 | 
			
		||||
@@ -681,6 +681,8 @@ const struct sbi_hart_ext_data sbi_hart_ext[] = {
 | 
			
		||||
	__SBI_HART_EXT_DATA(svade, SBI_HART_EXT_SVADE),
 | 
			
		||||
	__SBI_HART_EXT_DATA(svadu, SBI_HART_EXT_SVADU),
 | 
			
		||||
	__SBI_HART_EXT_DATA(smnpm, SBI_HART_EXT_SMNPM),
 | 
			
		||||
	__SBI_HART_EXT_DATA(zicfilp, SBI_HART_EXT_ZICFILP),
 | 
			
		||||
	__SBI_HART_EXT_DATA(zicfiss, SBI_HART_EXT_ZICFISS),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
_Static_assert(SBI_HART_EXT_MAX == array_size(sbi_hart_ext),
 | 
			
		||||
 
 | 
			
		||||
@@ -103,6 +103,7 @@ int sbi_trap_redirect(struct sbi_trap_regs *regs,
 | 
			
		||||
		      const struct sbi_trap_info *trap)
 | 
			
		||||
{
 | 
			
		||||
	ulong hstatus, vsstatus, prev_mode;
 | 
			
		||||
	bool elp = false;
 | 
			
		||||
#if __riscv_xlen == 32
 | 
			
		||||
	bool prev_virt = (regs->mstatusH & MSTATUSH_MPV) ? true : false;
 | 
			
		||||
#else
 | 
			
		||||
@@ -116,6 +117,17 @@ int sbi_trap_redirect(struct sbi_trap_regs *regs,
 | 
			
		||||
	if (prev_mode != PRV_S && prev_mode != PRV_U)
 | 
			
		||||
		return SBI_ENOTSUPP;
 | 
			
		||||
 | 
			
		||||
	/* If hart support for zicfilp, clear MPELP because redirecting to VS or (H)S */
 | 
			
		||||
	if (sbi_hart_has_extension(sbi_scratch_thishart_ptr(), SBI_HART_EXT_ZICFILP)) {
 | 
			
		||||
#if __riscv_xlen == 32
 | 
			
		||||
		elp = regs->mstatusH & MSTATUSH_MPELP;
 | 
			
		||||
		regs->mstatusH &= ~MSTATUSH_MPELP;
 | 
			
		||||
#else
 | 
			
		||||
		elp = regs->mstatus & MSTATUS_MPELP;
 | 
			
		||||
		regs->mstatus &= ~MSTATUS_MPELP;
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* If exceptions came from VS/VU-mode, redirect to VS-mode if
 | 
			
		||||
	 * delegated in hedeleg
 | 
			
		||||
	 */
 | 
			
		||||
@@ -169,6 +181,10 @@ int sbi_trap_redirect(struct sbi_trap_regs *regs,
 | 
			
		||||
		/* Get VS-mode SSTATUS CSR */
 | 
			
		||||
		vsstatus = csr_read(CSR_VSSTATUS);
 | 
			
		||||
 | 
			
		||||
		/* If elp was set, set it back in vsstatus */
 | 
			
		||||
		if (elp)
 | 
			
		||||
			vsstatus |= MSTATUS_SPELP;
 | 
			
		||||
 | 
			
		||||
		/* Set SPP for VS-mode */
 | 
			
		||||
		vsstatus &= ~SSTATUS_SPP;
 | 
			
		||||
		if (prev_mode == PRV_S)
 | 
			
		||||
@@ -209,6 +225,10 @@ int sbi_trap_redirect(struct sbi_trap_regs *regs,
 | 
			
		||||
 | 
			
		||||
		/* Clear SIE for S-mode */
 | 
			
		||||
		regs->mstatus &= ~MSTATUS_SIE;
 | 
			
		||||
 | 
			
		||||
		/* If elp was set, set it back in mstatus */
 | 
			
		||||
		if (elp)
 | 
			
		||||
			regs->mstatus |= MSTATUS_SPELP;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user