forked from Mirrors/opensbi
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:

committed by
Anup Patel

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,
|
static int sse_event_set_attr_check(struct sbi_sse_event *e, uint32_t attr_id,
|
||||||
unsigned long val)
|
unsigned long val)
|
||||||
{
|
{
|
||||||
int ret = SBI_OK;
|
|
||||||
|
|
||||||
switch (attr_id) {
|
switch (attr_id) {
|
||||||
case SBI_SSE_ATTR_CONFIG:
|
case SBI_SSE_ATTR_CONFIG:
|
||||||
if (val & ~SBI_SSE_ATTR_CONFIG_ONESHOT)
|
if (sse_event_state(e) >= SBI_SSE_STATE_ENABLED)
|
||||||
ret = SBI_EINVAL;
|
return SBI_EINVALID_STATE;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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,
|
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;
|
e->attrs.hartid = val;
|
||||||
sse_event_invoke_cb(e, set_hartid_cb, val);
|
sse_event_invoke_cb(e, set_hartid_cb, val);
|
||||||
break;
|
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;
|
uint32_t id, end_id = base_attr_id + attr_count;
|
||||||
unsigned long *attrs = (unsigned long *)input_phys;
|
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);
|
sbi_hart_map_saddr(input_phys, sizeof(unsigned long) * attr_count);
|
||||||
|
|
||||||
for (id = base_attr_id; id < end_id; id++) {
|
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;
|
return SBI_EINVAL;
|
||||||
|
|
||||||
ret = sse_write_attrs(e, base_attr_id, attr_count, input_phys_lo);
|
ret = sse_write_attrs(e, base_attr_id, attr_count, input_phys_lo);
|
||||||
|
|
||||||
sse_event_put(e);
|
sse_event_put(e);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
Reference in New Issue
Block a user