mirror of
				https://github.com/riscv-software-src/opensbi
				synced 2025-11-03 21:48:45 +00:00 
			
		
		
		
	lib: sbi: sse: handle missing writable attributes
The spec states that a6, a7, flags and sepc are writable but the implementation was not allowing that. Add support for these 4 writable attributes. Signed-off-by: Clément Léger <cleger@rivosinc.com> Reviewed-by: Samuel Holland <samuel.holland@sifive.com> Reviewed-by: Anup Patel <anup@brainfault.org>
This commit is contained in:
		
							parent
							
								
									858754a544
								
							
						
					
					
						commit
						ae5ef1848d
					
				@ -335,30 +335,49 @@ static int sse_event_set_hart_id_check(struct sbi_sse_event *e,
 | 
			
		||||
static int sse_event_set_attr_check(struct sbi_sse_event *e, uint32_t attr_id,
 | 
			
		||||
				    unsigned long val)
 | 
			
		||||
{
 | 
			
		||||
	int ret = SBI_OK;
 | 
			
		||||
 | 
			
		||||
	switch (attr_id) {
 | 
			
		||||
	case SBI_SSE_ATTR_CONFIG:
 | 
			
		||||
		if (val & ~SBI_SSE_ATTR_CONFIG_ONESHOT)
 | 
			
		||||
			ret = SBI_EINVAL;
 | 
			
		||||
		break;
 | 
			
		||||
	case SBI_SSE_ATTR_PRIO:
 | 
			
		||||
#if __riscv_xlen > 32
 | 
			
		||||
		if (val != (uint32_t)val) {
 | 
			
		||||
			ret = SBI_EINVAL;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
		break;
 | 
			
		||||
	case SBI_SSE_ATTR_PREFERRED_HART:
 | 
			
		||||
		ret = sse_event_set_hart_id_check(e, val);
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		ret = SBI_EBAD_RANGE;
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
		if (sse_event_state(e) >= SBI_SSE_STATE_ENABLED)
 | 
			
		||||
			return SBI_EINVALID_STATE;
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
		if (val & ~SBI_SSE_ATTR_CONFIG_ONESHOT)
 | 
			
		||||
			return SBI_EINVAL;
 | 
			
		||||
 | 
			
		||||
		return SBI_OK;
 | 
			
		||||
	case SBI_SSE_ATTR_PRIO:
 | 
			
		||||
		if (sse_event_state(e) >= SBI_SSE_STATE_ENABLED)
 | 
			
		||||
			return SBI_EINVALID_STATE;
 | 
			
		||||
 | 
			
		||||
#if __riscv_xlen > 32
 | 
			
		||||
		if (val != (uint32_t)val)
 | 
			
		||||
			return SBI_EINVAL;
 | 
			
		||||
#endif
 | 
			
		||||
		return SBI_OK;
 | 
			
		||||
	case SBI_SSE_ATTR_PREFERRED_HART:
 | 
			
		||||
		if (sse_event_state(e) >= SBI_SSE_STATE_ENABLED)
 | 
			
		||||
			return SBI_EINVALID_STATE;
 | 
			
		||||
 | 
			
		||||
		return sse_event_set_hart_id_check(e, val);
 | 
			
		||||
	case SBI_SSE_ATTR_INTERRUPTED_FLAGS:
 | 
			
		||||
		if (val & ~(SBI_SSE_ATTR_INTERRUPTED_FLAGS_STATUS_SPP |
 | 
			
		||||
			    SBI_SSE_ATTR_INTERRUPTED_FLAGS_STATUS_SPIE |
 | 
			
		||||
			    SBI_SSE_ATTR_INTERRUPTED_FLAGS_HSTATUS_SPV |
 | 
			
		||||
			    SBI_SSE_ATTR_INTERRUPTED_FLAGS_HSTATUS_SPVP))
 | 
			
		||||
			return SBI_EINVAL;
 | 
			
		||||
		__attribute__((__fallthrough__));
 | 
			
		||||
	case SBI_SSE_ATTR_INTERRUPTED_SEPC:
 | 
			
		||||
	case SBI_SSE_ATTR_INTERRUPTED_A6:
 | 
			
		||||
	case SBI_SSE_ATTR_INTERRUPTED_A7:
 | 
			
		||||
		if (sse_event_state(e) != SBI_SSE_STATE_RUNNING)
 | 
			
		||||
			return SBI_EINVALID_STATE;
 | 
			
		||||
 | 
			
		||||
		if (current_hartid() != e->attrs.hartid)
 | 
			
		||||
			return SBI_EINVAL;
 | 
			
		||||
 | 
			
		||||
		return SBI_OK;
 | 
			
		||||
	default:
 | 
			
		||||
		return SBI_EBAD_RANGE;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void sse_event_set_attr(struct sbi_sse_event *e, uint32_t attr_id,
 | 
			
		||||
@ -375,6 +394,19 @@ static void sse_event_set_attr(struct sbi_sse_event *e, uint32_t attr_id,
 | 
			
		||||
		e->attrs.hartid = val;
 | 
			
		||||
		sse_event_invoke_cb(e, set_hartid_cb, val);
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case SBI_SSE_ATTR_INTERRUPTED_SEPC:
 | 
			
		||||
		e->attrs.interrupted.sepc = val;
 | 
			
		||||
		break;
 | 
			
		||||
	case SBI_SSE_ATTR_INTERRUPTED_FLAGS:
 | 
			
		||||
		e->attrs.interrupted.flags = val;
 | 
			
		||||
		break;
 | 
			
		||||
	case SBI_SSE_ATTR_INTERRUPTED_A6:
 | 
			
		||||
		e->attrs.interrupted.a6 = val;
 | 
			
		||||
		break;
 | 
			
		||||
	case SBI_SSE_ATTR_INTERRUPTED_A7:
 | 
			
		||||
		e->attrs.interrupted.a7 = val;
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -903,9 +935,6 @@ static int sse_write_attrs(struct sbi_sse_event *e, uint32_t base_attr_id,
 | 
			
		||||
	uint32_t id, end_id = base_attr_id + attr_count;
 | 
			
		||||
	unsigned long *attrs = (unsigned long *)input_phys;
 | 
			
		||||
 | 
			
		||||
	if (sse_event_state(e) >= SBI_SSE_STATE_ENABLED)
 | 
			
		||||
		return SBI_EINVALID_STATE;
 | 
			
		||||
 | 
			
		||||
	sbi_hart_map_saddr(input_phys, sizeof(unsigned long) * attr_count);
 | 
			
		||||
 | 
			
		||||
	for (id = base_attr_id; id < end_id; id++) {
 | 
			
		||||
@ -944,7 +973,6 @@ int sbi_sse_write_attrs(uint32_t event_id, uint32_t base_attr_id,
 | 
			
		||||
		return SBI_EINVAL;
 | 
			
		||||
 | 
			
		||||
	ret = sse_write_attrs(e, base_attr_id, attr_count, input_phys_lo);
 | 
			
		||||
 | 
			
		||||
	sse_event_put(e);
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user