[PATCH v2 4/7] lib: sbi: Introduce the SBI debug triggers extension support
Himanshu Chauhan
hchauhan at ventanamicro.com
Tue Jan 9 07:31:24 PST 2024
Hi Anup,
> On 09-Jan-2024, at 4:02 PM, Anup Patel <anup at brainfault.org> wrote:
>
>>
<snip>
>> +int sbi_dbtr_install_trig(const struct sbi_domain *dom, unsigned long smode,
>> + unsigned long trig_count, unsigned long *out)
>> +{
>> + u32 hartid = current_hartid();
>> + void *shmem_base = NULL;
>> + struct sbi_dbtr_shmem_entry *entry;
>> + struct sbi_dbtr_data_msg *recv;
>> + struct sbi_dbtr_id_msg *xmit;
>> + unsigned long ctrl;
>> + struct sbi_dbtr_trigger *trig;
>> + struct sbi_dbtr_hart_triggers_state *hs = NULL;
>> +
>> + if (smode != PRV_S)
>> + return SBI_ERR_DENIED;
>
> Same as above, drop the smode check and parameter.
We cannot completely drop the smode parameter here because it is used for domain address access validation. The check of S_PRV can be dropped.
Regards
Himanshu
>
>> + if (dom && !sbi_domain_is_assigned_hart(dom, hartid))
>> + return SBI_ERR_DENIED;
>> +
>> + if (sbi_dbtr_shmem_disabled())
>> + return SBI_ERR_NO_SHMEM;
>> +
>> + shmem_base = hart_shmem_base();
>> + hs = dbtr_thishart_state_ptr();
>> +
>> + /* Check requested triggers configuration */
>> + for_each_trig_entry(shmem_base, trig_count, typeof(*entry), entry) {
>> + sbi_hart_map_saddr((unsigned long)entry, sizeof(*entry));
>> + recv = (struct sbi_dbtr_data_msg *)(&entry->data);
>> + ctrl = recv->tdata1;
>> +
>> + if (!dbtr_trigger_supported(TDATA1_GET_TYPE(ctrl))) {
>> + *out = _idx;
>> + sbi_hart_unmap_saddr();
>> + return SBI_ERR_FAILED;
>> + }
>> +
>> + if (!dbtr_trigger_valid(TDATA1_GET_TYPE(ctrl), ctrl)) {
>> + *out = _idx;
>> + sbi_hart_unmap_saddr();
>> + return SBI_ERR_FAILED;
>> + }
>> + sbi_hart_unmap_saddr();
>> + }
>> +
>> + if (hs->available_trigs < trig_count) {
>> + *out = hs->available_trigs;
>> + return SBI_ERR_FAILED;
>> + }
>> +
>> + /* Install triggers */
>> + for_each_trig_entry(shmem_base, trig_count, typeof(*entry), entry) {
>> + /*
>> + * Since we have already checked if enough triggers are
>> + * available, trigger allocation must succeed.
>> + */
>> + trig = sbi_alloc_trigger();
>> +
>> + sbi_hart_map_saddr((unsigned long)entry, sizeof(*entry));
>> +
>> + recv = (struct sbi_dbtr_data_msg *)(&entry->data);
>> + xmit = (struct sbi_dbtr_id_msg *)(&entry->id);
>> +
>> + dbtr_trigger_setup(trig, recv);
>> + dbtr_trigger_enable(trig);
>> + xmit->idx = cpu_to_lle(trig->index);
>> + sbi_hart_unmap_saddr();
>> + }
>> +
>> + return SBI_SUCCESS;
>> +}
>> +
>> +int sbi_dbtr_uninstall_trig(unsigned long trig_idx_base,
>> + unsigned long trig_idx_mask)
>> +{
>> + unsigned long trig_mask = trig_idx_mask << trig_idx_base;
>> + unsigned long idx = trig_idx_base;
>> + struct sbi_dbtr_trigger *trig;
>> + struct sbi_dbtr_hart_triggers_state *hs;
>> +
>> + hs = dbtr_thishart_state_ptr();
>> + if (!hs)
>> + return SBI_ERR_FAILED;
>> +
>> + for_each_set_bit_from(idx, &trig_mask, hs->total_trigs) {
>> + trig = INDEX_TO_TRIGGER(idx);
>> + if (!(trig->state & RV_DBTR_BIT_MASK(TS, MAPPED)))
>> + return SBI_ERR_INVALID_PARAM;
>> +
>> + dbtr_trigger_clear(trig);
>> +
>> + sbi_free_trigger(trig);
>> + }
>> +
>> + return SBI_SUCCESS;
>> +}
>> +
>> +int sbi_dbtr_enable_trig(unsigned long trig_idx_base,
>> + unsigned long trig_idx_mask)
>> +{
>> + unsigned long trig_mask = trig_idx_mask << trig_idx_base;
>> + unsigned long idx = trig_idx_base;
>> + struct sbi_dbtr_trigger *trig;
>> + struct sbi_dbtr_hart_triggers_state *hs;
>> +
>> + hs = dbtr_thishart_state_ptr();
>> + if (!hs)
>> + return SBI_ERR_FAILED;
>> +
>> + for_each_set_bit_from(idx, &trig_mask, hs->total_trigs) {
>> + trig = INDEX_TO_TRIGGER(idx);
>> + sbi_dprintf("%s: enable trigger %lu\n", __func__, idx);
>> + dbtr_trigger_enable(trig);
>> + }
>> +
>> + return SBI_SUCCESS;
>> +}
>> +
>> +int sbi_dbtr_update_trig(const struct sbi_domain *dom,
>> + unsigned long smode,
>> + unsigned long trig_idx_base,
>> + unsigned long trig_idx_mask)
>> +{
>> + unsigned long trig_mask = trig_idx_mask << trig_idx_base;
>> + unsigned long idx = trig_idx_base;
>> + u32 hartid = current_hartid();
>> + struct sbi_dbtr_data_msg *recv;
>> + unsigned long uidx = 0;
>> + struct sbi_dbtr_trigger *trig;
>> + struct sbi_dbtr_shmem_entry *entry;
>> + void *shmem_base = NULL;
>> + struct sbi_dbtr_hart_triggers_state *hs = NULL;
>> +
>> + if (smode != PRV_S)
>> + return SBI_ERR_DENIED;
>
> Same as above, drop the smode check and parameter.
>
>> + if (dom && !sbi_domain_is_assigned_hart(dom, hartid))
>> + return SBI_ERR_DENIED;
>> +
>> + if (sbi_dbtr_shmem_disabled())
>> + return SBI_ERR_NO_SHMEM;
>> +
>> + shmem_base = hart_shmem_base();
>> + hs = dbtr_thishart_state_ptr();
>> + if (!hs)
>> + return SBI_ERR_FAILED;
>> +
>> + for_each_set_bit_from(idx, &trig_mask, hs->total_trigs) {
>> + trig = INDEX_TO_TRIGGER(idx);
>> +
>> + if (!(trig->state & RV_DBTR_BIT_MASK(TS, MAPPED)))
>> + return SBI_ERR_INVALID_PARAM;
>> +
>> + entry = (shmem_base + uidx * sizeof(*entry));
>> + recv = &entry->data;
>> +
>> + trig->tdata2 = lle_to_cpu(recv->tdata2);
>> + dbtr_trigger_enable(trig);
>> + uidx++;
>> + }
>> +
>> + return SBI_SUCCESS;
>> +}
>> +
>> +int sbi_dbtr_disable_trig(unsigned long trig_idx_base,
>> + unsigned long trig_idx_mask)
>> +{
>> + unsigned long trig_mask = trig_idx_mask << trig_idx_base;
>> + unsigned long idx = trig_idx_base;
>> + struct sbi_dbtr_trigger *trig;
>> + struct sbi_dbtr_hart_triggers_state *hs;
>> +
>> + hs = dbtr_thishart_state_ptr();
>> + if (!hs)
>> + return SBI_ERR_FAILED;
>> +
>> + for_each_set_bit_from(idx, &trig_mask, hs->total_trigs) {
>> + trig = INDEX_TO_TRIGGER(idx);
>> + dbtr_trigger_disable(trig);
>> + }
>> +
>> + return SBI_SUCCESS;
>> +}
>> diff --git a/lib/sbi/sbi_init.c b/lib/sbi/sbi_init.c
>> index 6a98e13..0dcde27 100644
>> --- a/lib/sbi/sbi_init.c
>> +++ b/lib/sbi/sbi_init.c
>> @@ -23,6 +23,7 @@
>> #include <sbi/sbi_irqchip.h>
>> #include <sbi/sbi_platform.h>
>> #include <sbi/sbi_pmu.h>
>> +#include <sbi/sbi_dbtr.h>
>> #include <sbi/sbi_system.h>
>> #include <sbi/sbi_string.h>
>> #include <sbi/sbi_timer.h>
>> @@ -322,6 +323,10 @@ static void __noreturn init_coldboot(struct sbi_scratch *scratch, u32 hartid)
>> sbi_hart_hang();
>> }
>>
>> + rc = sbi_dbtr_init(scratch, true);
>> + if (rc)
>> + sbi_hart_hang();
>> +
>> sbi_boot_print_banner(scratch);
>>
>> rc = sbi_irqchip_init(scratch, true);
>> @@ -439,6 +444,10 @@ static void __noreturn init_warm_startup(struct sbi_scratch *scratch,
>> if (rc)
>> sbi_hart_hang();
>>
>> + rc = sbi_dbtr_init(scratch, false);
>> + if (rc)
>> + sbi_hart_hang();
>> +
>> rc = sbi_irqchip_init(scratch, false);
>> if (rc)
>> sbi_hart_hang();
>> --
>> 2.34.1
>>
>>
>> --
>> opensbi mailing list
>> opensbi at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/opensbi
>
> Regards,
> Anup
More information about the opensbi
mailing list