From: Xiang W <wxjstz@126.com>
To: opensbi@lists.infradead.org
Subject: [RFC PATCH 2/2] lib: sbi: add support for Supervisor Software Events extension
Date: Tue, 05 Dec 2023 13:19:16 +0800 [thread overview]
Message-ID: <b75f06c8451fb9948d6f5c9831ca5e0f6e498ca5.camel@126.com> (raw)
In-Reply-To: <20231130091319.1223849-3-cleger@rivosinc.com>
? 2023-11-30???? 10:13 +0100?Cl?ment L?ger???
> This extension [1] allows to deliver events from SBI to supervisor via a
> software mecanism. This extensions defines events (either local or
> global) which are signaled by the SBI on specific signal sources (IRQ,
> traps, etc) and are injected to be executed in supervisor mode.
>
> [1] https://lists.riscv.org/g/tech-prs/message/515
>
> Signed-off-by: Cl?ment L?ger <cleger@rivosinc.com>
> ---
>
> +struct sbi_sse_cb_ops {
> + /**
> + * Called when hart_id is changed on the event.
> + */
> + void (*set_hartid_cb)(uint32_t event_id, unsigned long hart_id);
> +
Maybe should add a callback before running. This callback can be used to?
access sensitive resources, such as keys.
> + /**
> + * Called when the SBI_EXT_SSE_COMPLETE is invoked on the event.
> + */
> + void (*complete_cb)(uint32_t event_id);
> +
> + /**
> + * Called when the SBI_EXT_SSE_REGISTER is invoked on the event.
> + */
> + void (*register_cb)(uint32_t event_id);
> +
> + /**
> + * Called when the SBI_EXT_SSE_UNREGISTER is invoked on the event.
> + */
> + void (*unregister_cb)(uint32_t event_id);
> +};
> +
>
> +static void sse_event_set_state(struct sbi_sse_event *e,
> + enum sbi_sse_state new_state)
> +{
> + enum sbi_sse_state prev_state = e->state;
> +
> + e->state = new_state;
Do not change before checking.
> + switch (new_state) {
> + case SSE_STATE_UNUSED:
> + if (prev_state == SSE_STATE_REGISTERED)
> + return;
> + break;
> + case SSE_STATE_REGISTERED:
> + if (prev_state == SSE_STATE_UNUSED ||
> + ??? prev_state == SSE_STATE_ENABLED) {
> + return;
> + }
> + break;
> + case SSE_STATE_ENABLED:
> + if (prev_state == SSE_STATE_REGISTERED ||
> + ??? prev_state == SSE_STATE_RUNNING)
> + return;
> + break;
> + case SSE_STATE_RUNNING:
> + if (prev_state == SSE_STATE_ENABLED)
> + return;
> + break;
> + }
This state machine is characterized by the difference between the old and new
states being 1. So the code can be simplified as follows:
if ((new_state - prev_state == 1) || (prev_state - new_state == 1)) {
e->state = new_state;
return;
}
> +
> + sbi_panic("Invalid SSE state transition: %d -> %d\n", prev_state,
> + ? new_state);
> +}
> +
>
> +
> +static int sse_event_set_hart_id(struct sbi_sse_event *e, uint32_t event_id,
> + unsigned long new_hartid)
> +{
> + int hstate;
> + unsigned int hartid = (uint32_t) new_hartid;
> + struct sbi_domain * hd = sbi_domain_thishart_ptr();
> +
> + if (!sse_event_is_global(e))
> + return SBI_EDENIED;
> +
> + if (e->state == SSE_STATE_RUNNING)
> + return SBI_EBUSY;
> +
> + if (!sbi_domain_is_assigned_hart(hd, new_hartid))
> + return SBI_EINVAL;
> +
> + hstate = sbi_hsm_hart_get_state(hd, hartid);
> + if (hstate != SBI_HSM_STATE_STARTED)
> + return SBI_EINVAL;
> +
> + if (new_hartid == e->hartid)
> + return SBI_OK;
> +
> + if (e->state >= SSE_STATE_ENABLED)
> + sse_event_remove_from_list(e);
> +
> + e->hartid = hartid;
> +
> + if (e->cb_ops && e->cb_ops->set_hartid_cb)
> + e->cb_ops->set_hartid_cb(event_id, e->hartid);
> +
> + if (e->state >= SSE_STATE_ENABLED)
> + sse_event_add_to_list(e);
> +
> + if (e->pending)
> + sbi_ipi_send_many(BIT(e->hartid), 0, sse_ipi_inject_event, NULL);
hartid can't big then XLEN. change to:
sbi_ipi_send_many(1, e->hartid, sse_ipi_inject_event, NULL);
> +
> + return 0;
> +}
> +
>
> +
> +static int sse_ipi_inject_send(unsigned long hartid, uint32_t event_id)
> +{
> + int ret;
> + struct sbi_scratch *remote_scratch = NULL;
> + struct sse_ipi_inject_data evt = {event_id};
> + struct sbi_fifo *sse_inject_fifo_r;
> +
> + remote_scratch = sbi_hartid_to_scratch(hartid);
> + if (!remote_scratch)
> + return SBI_EINVAL;
> + sse_inject_fifo_r = sbi_scratch_offset_ptr(remote_scratch,
> + ?? sse_inject_fifo_off);
> +
> + ret = sbi_fifo_enqueue(sse_inject_fifo_r, &evt);
> + if (ret)
> + return SBI_EFAIL;
> +
> + ret = sbi_ipi_send_many(BIT(hartid), 0, sse_ipi_inject_event, NULL);
hartid can't big then XLEN. change to:
ret = sbi_ipi_send_many(1, hartid, sse_ipi_inject_event, NULL);
> + if (ret)
> + return SBI_EFAIL;
> +
> + return SBI_OK;
> +}
> +
>
> +}
> --
> 2.42.0
>
>
Regards,
Xiang W
next prev parent reply other threads:[~2023-12-05 5:19 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-11-30 9:13 [RFC PATCH 0/2] Add support for Supervisor Software Events extension Clément Léger
2023-11-30 9:13 ` [RFC PATCH 1/2] lib: sbi: provides regs to sbi_ipi_process() Clément Léger
2023-11-30 9:13 ` [RFC PATCH 2/2] lib: sbi: add support for Supervisor Software Events extension Clément Léger
2023-12-05 5:19 ` Xiang W [this message]
2023-11-30 18:13 ` [RFC PATCH 0/2] Add " Deepak Gupta
2023-11-30 18:18 ` Jessica Clarke
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=b75f06c8451fb9948d6f5c9831ca5e0f6e498ca5.camel@126.com \
--to=wxjstz@126.com \
--cc=opensbi@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox