Skip to content

Commit

Permalink
lib: sbi: Introduce the SBI debug triggers extension support
Browse files Browse the repository at this point in the history
RISC-V Debug specification includes Sdtrig ISA extension
which describes Trigger Module. Triggers can cause
a breakpoint exception or trace action without execution
of a special instruction. They can be used to implement
hardware breakpoints and watchpoints for native debugging.

The SBI Debut Trigger extension (Draft v6) can be found at:
https://lists.riscv.org/g/tech-debug/topic/99825362#1302

This patch is an initial implementation of SBI Debug
Trigger Extension (Draft v6) in OpenSBI.

The following features are supported:
 * mcontrol, mcontrol6 triggers
 * Breakpoint and trace actions

NOTE: Chained triggers are not supported

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
  • Loading branch information
hschauhan authored and avpatel committed Jan 10, 2024
1 parent 40dac6b commit 97f234f
Show file tree
Hide file tree
Showing 4 changed files with 863 additions and 0 deletions.
125 changes: 125 additions & 0 deletions include/sbi/sbi_dbtr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2023 Ventana Micro Systems, Inc.
*
* Authors:
* Himanshu Chauhan <hchauhan@ventanamicro.com>
*/

#ifndef __SBI_DBTR_H__
#define __SBI_DBTR_H__

#include <sbi/riscv_dbtr.h>
#include <sbi/sbi_types.h>

struct sbi_domain;

enum {
RV_DBTR_DECLARE_BIT(TS, MAPPED, 0), /* trigger mapped to hw trigger */
RV_DBTR_DECLARE_BIT(TS, U, 1),
RV_DBTR_DECLARE_BIT(TS, S, 2),
RV_DBTR_DECLARE_BIT(TS, VU, 3),
RV_DBTR_DECLARE_BIT(TS, VS, 4),
RV_DBTR_DECLARE_BIT(TS, HAVE_TRIG, 5), /* H/w dbtr details available */
RV_DBTR_DECLARE_BIT(TS, HW_IDX, 8), /* Hardware index of trigger */
};

enum {
RV_DBTR_DECLARE_BIT_MASK(TS, MAPPED, 1),
RV_DBTR_DECLARE_BIT_MASK(TS, U, 1),
RV_DBTR_DECLARE_BIT_MASK(TS, S, 1),
RV_DBTR_DECLARE_BIT_MASK(TS, VU, 1),
RV_DBTR_DECLARE_BIT_MASK(TS, VS, 1),
RV_DBTR_DECLARE_BIT_MASK(TS, HAVE_TRIG, 1),
RV_DBTR_DECLARE_BIT_MASK(TS, HW_IDX, (__riscv_xlen-9)),
};

#if __riscv_xlen == 64
#define SBI_DBTR_SHMEM_INVALID_ADDR 0xFFFFFFFFFFFFFFFFUL
#elif __riscv_xlen == 32
#define SBI_DBTR_SHMEM_INVALID_ADDR 0xFFFFFFFFUL
#else
#error "Unexpected __riscv_xlen"
#endif

struct sbi_dbtr_shmem {
unsigned long phys_lo;
unsigned long phys_hi;
};

struct sbi_dbtr_trigger {
unsigned long index;
unsigned long type_mask;
unsigned long state;
unsigned long tdata1;
unsigned long tdata2;
unsigned long tdata3;
};

struct sbi_dbtr_data_msg {
unsigned long tstate;
unsigned long tdata1;
unsigned long tdata2;
unsigned long tdata3;
};

struct sbi_dbtr_id_msg {
unsigned long idx;
};

struct sbi_dbtr_hart_triggers_state {
struct sbi_dbtr_trigger triggers[RV_MAX_TRIGGERS];
struct sbi_dbtr_shmem shmem;
u32 total_trigs;
u32 available_trigs;
u32 hartid;
u32 probed;
};

#define TDATA1_GET_TYPE(_t1) \
EXTRACT_FIELD(_t1, RV_DBTR_BIT_MASK(TDATA1, TYPE))

/* Set the hardware index of trigger in logical trigger state */
#define SET_TRIG_HW_INDEX(_state, _idx) \
do { \
_state &= ~RV_DBTR_BIT_MASK(TS, HW_IDX); \
_state |= (((unsigned long)_idx \
<< RV_DBTR_BIT(TS, HW_IDX)) \
& RV_DBTR_BIT_MASK(TS, HW_IDX)); \
}while (0);

/** SBI shared mem messages layout */
struct sbi_dbtr_shmem_entry {
struct sbi_dbtr_data_msg data;
struct sbi_dbtr_id_msg id;
};

#define SBI_DBTR_SHMEM_ALIGN_MASK ((__riscv_xlen / 8) - 1)

/** Initialize debug triggers */
int sbi_dbtr_init(struct sbi_scratch *scratch, bool coldboot);

/** SBI DBTR extension functions */
int sbi_dbtr_supported(void);
int sbi_dbtr_setup_shmem(const struct sbi_domain *dom, unsigned long smode,
unsigned long shmem_phys_lo,
unsigned long shmem_phys_hi);
int sbi_dbtr_num_trig(unsigned long trig_tdata1, unsigned long *out);
int sbi_dbtr_read_trig(unsigned long smode,
unsigned long trig_idx_base, unsigned long trig_count);
int sbi_dbtr_install_trig(unsigned long smode,
unsigned long trig_count, unsigned long *out);
int sbi_dbtr_uninstall_trig(unsigned long trig_idx_base,
unsigned long trig_idx_mask);
int sbi_dbtr_enable_trig(unsigned long trig_idx_base,
unsigned long trig_idx_mask);
int sbi_dbtr_update_trig(unsigned long smode,
unsigned long trig_idx_base,
unsigned long trig_idx_mask);
int sbi_dbtr_disable_trig(unsigned long trig_idx_base,
unsigned long trig_idx_mask);

int sbi_dbtr_get_total_triggers(void);

#endif
1 change: 1 addition & 0 deletions lib/sbi/objects.mk
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ libsbi-objs-y += sbi_irqchip.o
libsbi-objs-y += sbi_misaligned_ldst.o
libsbi-objs-y += sbi_platform.o
libsbi-objs-y += sbi_pmu.o
libsbi-objs-y += sbi_dbtr.o
libsbi-objs-y += sbi_scratch.o
libsbi-objs-y += sbi_string.o
libsbi-objs-y += sbi_system.o
Expand Down

0 comments on commit 97f234f

Please sign in to comment.