[PATCH umr 15/17] Add umr_sq_cmd_singlestep
Nicolai Hähnle
nicolai.haehnle at amd.com
Tue Jun 6 09:17:23 UTC 2023
Allow single-stepping a wave that is selected by HW ID.
Signed-off-by: Nicolai Hähnle <nicolai.haehnle at amd.com>
---
src/lib/sq_cmd_halt_waves.c | 75 ++++++++++++++++++++++++++++++++-----
src/umr.h | 1 +
2 files changed, 67 insertions(+), 9 deletions(-)
diff --git a/src/lib/sq_cmd_halt_waves.c b/src/lib/sq_cmd_halt_waves.c
index 841b1d3..9a0ae69 100644
--- a/src/lib/sq_cmd_halt_waves.c
+++ b/src/lib/sq_cmd_halt_waves.c
@@ -17,45 +17,51 @@
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: Tom St Denis <tom.stdenis at amd.com>
*
*/
#include "umr.h"
+static struct umr_reg *find_sq_cmd(struct umr_asic *asic)
+{
+ // SQ_CMD is not present on SI
+ if (asic->family == FAMILY_SI)
+ return 0;
+
+ struct umr_reg *reg = umr_find_reg_data_by_ip_by_instance(asic, "gfx", asic->options.vm_partition,
+ asic->family >= FAMILY_GFX11 ? "regSQ_CMD" : "mmSQ_CMD");
+ if (!reg)
+ asic->err_msg("[BUG]: Cannot find SQ_CMD register in umr_sq_cmd_halt_waves()\n");
+ return reg;
+}
+
/**
* umr_sq_cmd_halt_waves - Attempt to halt or resume waves
*
* @mode: Use UMR_SQ_CMD_HALT to halt waves and
* UMR_SQ_CMD_RESUME to resume waves.
*/
int umr_sq_cmd_halt_waves(struct umr_asic *asic, enum umr_sq_cmd_halt_resume mode)
{
struct umr_reg *reg;
uint32_t value;
uint64_t addr;
struct {
uint32_t se, sh, instance, use_grbm;
} grbm;
- // SQ_CMD is not present on SI
- if (asic->family == FAMILY_SI)
- return 0;
-
- reg = umr_find_reg_data_by_ip_by_instance(asic, "gfx", asic->options.vm_partition,
- asic->family >= FAMILY_GFX11 ? "regSQ_CMD" : "mmSQ_CMD");
- if (!reg) {
- asic->err_msg("[BUG]: Cannot find SQ_CMD register in umr_sq_cmd_halt_waves()\n");
+ reg = find_sq_cmd(asic);
+ if (!reg)
return -1;
- }
// compose value
if (asic->family == FAMILY_CIK) {
value = umr_bitslice_compose_value(asic, reg, "CMD", mode == UMR_SQ_CMD_HALT ? 1 : 2); // SETHALT
} else {
value = umr_bitslice_compose_value(asic, reg, "CMD", 1); // SETHALT
value |= umr_bitslice_compose_value(asic, reg, "DATA", mode == UMR_SQ_CMD_HALT ? 1 : 0);
}
value |= umr_bitslice_compose_value(asic, reg, "MODE", 1); // BROADCAST
@@ -76,10 +82,61 @@ int umr_sq_cmd_halt_waves(struct umr_asic *asic, enum umr_sq_cmd_halt_resume mod
asic->reg_funcs.write_reg(asic, addr, value, reg->type);
/* restore whatever the user had picked */
asic->options.use_bank = grbm.use_grbm;
asic->options.bank.grbm.se = grbm.se;
asic->options.bank.grbm.sh = grbm.sh;
asic->options.bank.grbm.instance = grbm.instance;
return 0;
}
+
+/**
+ * umr_sq_cmd_singlestep - Attempt to single-step a single wave
+ *
+ * The wave is assumed to be halted.
+ */
+int umr_sq_cmd_singlestep(struct umr_asic *asic, uint32_t se, uint32_t sh, uint32_t wgp, uint32_t simd, uint32_t wave)
+{
+ struct umr_reg *reg;
+ uint32_t value;
+ uint64_t addr;
+ struct {
+ uint32_t se, sh, instance, use_grbm;
+ } grbm;
+
+ if (asic->family < FAMILY_NV)
+ return -1; // Only supported on gfx10+
+
+ reg = find_sq_cmd(asic);
+ if (!reg)
+ return -1;
+
+ // compose value
+ value = umr_bitslice_compose_value(asic, reg, "CMD", 8); // SINGLE_STEP
+ value |= umr_bitslice_compose_value(asic, reg, "MODE", 0); // single wave
+ value |= umr_bitslice_compose_value(asic, reg, "WAVE_ID", wave);
+
+ /* copy grbm options to restore later */
+ grbm.use_grbm = asic->options.use_bank;
+ grbm.se = asic->options.bank.grbm.se;
+ grbm.sh = asic->options.bank.grbm.sh;
+ grbm.instance = asic->options.bank.grbm.instance;
+
+ /* set GRBM banking options */
+ asic->options.use_bank = 1;
+ asic->options.bank.grbm.se = se;
+ asic->options.bank.grbm.sh = sh;
+ asic->options.bank.grbm.instance = (wgp << 2) | simd;
+
+ // compose address
+ addr = reg->addr * 4;
+ asic->reg_funcs.write_reg(asic, addr, value, reg->type);
+
+ /* restore whatever the user had picked */
+ asic->options.use_bank = grbm.use_grbm;
+ asic->options.bank.grbm.se = grbm.se;
+ asic->options.bank.grbm.sh = grbm.sh;
+ asic->options.bank.grbm.instance = grbm.instance;
+
+ return 0;
+}
diff --git a/src/umr.h b/src/umr.h
index 616b9cc..8981986 100644
--- a/src/umr.h
+++ b/src/umr.h
@@ -1466,20 +1466,21 @@ uint64_t umr_bitslice_compose_value_by_name_by_ip_by_instance(struct umr_asic *a
// bank switching
uint64_t umr_apply_bank_selection_address(struct umr_asic *asic);
// select a GRBM_GFX_IDX
int umr_grbm_select_index(struct umr_asic *asic, uint32_t se, uint32_t sh, uint32_t instance);
int umr_srbm_select_index(struct umr_asic *asic, uint32_t me, uint32_t pipe, uint32_t queue, uint32_t vmid);
// halt/resume SQ waves
int umr_sq_cmd_halt_waves(struct umr_asic *asic, enum umr_sq_cmd_halt_resume mode);
+int umr_sq_cmd_singlestep(struct umr_asic *asic, uint32_t se, uint32_t sh, uint32_t wgp, uint32_t simd, uint32_t wave);
/* IB/ring decoding/dumping/etc */
enum umr_ring_type {
UMR_RING_PM4,
UMR_RING_PM4_LITE,
UMR_RING_SDMA,
UMR_RING_MES,
UMR_RING_GUESS,
UMR_RING_UNK=0xFF, // if unknown
--
2.40.0
More information about the amd-gfx
mailing list