public inbox for opensbi@lists.infradead.org
 help / color / mirror / Atom feed
From: Nicholas Piggin <npiggin@gmail.com>
To: opensbi@lists.infradead.org
Cc: Nicholas Piggin <npiggin@gmail.com>,
	Himanshu Chauhan <hchauhan@ventanamicro.com>
Subject: [PATCH 16/18] dbtr: Heterogeneous trigger type support
Date: Fri, 13 Mar 2026 15:19:45 +1000	[thread overview]
Message-ID: <20260313051948.4017134-17-npiggin@gmail.com> (raw)
In-Reply-To: <20260313051948.4017134-1-npiggin@gmail.com>

The Tenstorrent Ascalon core has 8 triggers that support the mcontrol6
type and another that supports the icount type.

When installing SBI triggers, allocate HW triggers to them that satisfy
their type requirement. A first pass is made over the requested SBI
triggers which checks that all can be satisfied with available hardware
triggers. If yes, then a second pass allocates each HW trigger and maps
the corresponding SBI trigger to it.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 lib/sbi/sbi_dbtr.c | 104 ++++++++++++++++++++++++++++++++-------------
 1 file changed, 74 insertions(+), 30 deletions(-)

diff --git a/lib/sbi/sbi_dbtr.c b/lib/sbi/sbi_dbtr.c
index 77162efe..f91a2b0d 100644
--- a/lib/sbi/sbi_dbtr.c
+++ b/lib/sbi/sbi_dbtr.c
@@ -93,6 +93,31 @@ static bool sbi_hw_trigger_supports(struct sbi_hw_trigger *hw_trig,
 	return true;
 }
 
+static struct sbi_hw_trigger *sbi_alloc_hw_trigger(
+				unsigned long type, unsigned long tdata1)
+{
+	int i;
+	struct sbi_dbtr_hart_triggers_state *hart_state;
+
+	hart_state = dbtr_thishart_state_ptr();
+	if (!hart_state)
+		return NULL;
+
+	for (i = 0; i < hart_state->total_trigs; i++) {
+		struct sbi_hw_trigger *hw_trig = INDEX_TO_HW_TRIGGER(i);
+
+		if (hw_trig->inuse)
+			continue;
+		if (!sbi_hw_trigger_supports(hw_trig, type, tdata1))
+			continue;
+		hw_trig->inuse = true;
+
+		return hw_trig;
+	}
+
+	return NULL;
+}
+
 static inline struct sbi_dbtr_trigger *sbi_alloc_trigger(void)
 {
 	int i;
@@ -357,8 +382,6 @@ static void dbtr_trigger_setup(struct sbi_dbtr_trigger *trig,
 
 	SET_TRIG_HW_INDEX(trig->state, hw_trig->index);
 
-	hw_trig->inuse = true;
-
 	switch (TDATA1_GET_TYPE(tdata1)) {
 	case RISCV_DBTR_TRIG_MCONTROL:
 		if (__test_bit(RV_DBTR_BIT(MC, U), &tdata1))
@@ -654,8 +677,10 @@ int sbi_dbtr_install_trig(unsigned long smode,
 	struct sbi_dbtr_data_msg *recv;
 	struct sbi_dbtr_id_msg *xmit;
 	struct sbi_dbtr_trigger *trig;
+	struct sbi_hw_trigger *hw_trig;
+	struct sbi_hw_trigger **hw_trigs;
 	struct sbi_dbtr_hart_triggers_state *hs = NULL;
-	int err;
+	int err, i;
 
 	hs = dbtr_thishart_state_ptr();
 	if (!hs)
@@ -671,64 +696,83 @@ int sbi_dbtr_install_trig(unsigned long smode,
 	sbi_hart_protection_map_range((unsigned long)shmem_base,
 				      trig_count * sizeof(*entry));
 
-	/* Check requested triggers configuration */
+	/*
+	 * The first pass checks requested triggers configuration and allocates
+	 * HW triggers, putting them into an array indexed by the recv'ed
+	 * triggers. The second pass allocates DBTR triggers and maps them to
+	 * the HW triggers.
+	 */
+	hw_trigs = sbi_zalloc(sizeof(hw_trigs[0]) * trig_count);
+	i = 0;
 	for_each_trig_entry(shmem_base, trig_count, typeof(*entry), entry) {
-		unsigned long tdata1;
+		unsigned long tdata1, type;
 
 		recv = (struct sbi_dbtr_data_msg *)(&entry->data);
 		tdata1 = lle_to_cpu(recv->tdata1);
+		type = TDATA1_GET_TYPE(tdata1);
 
-		if (!dbtr_trigger_supported(TDATA1_GET_TYPE(tdata1), tdata1)) {
+		if (!dbtr_trigger_supported(type, tdata1)) {
 			*out = _idx;
 			err = SBI_ERR_NOT_SUPPORTED;
-			goto out_unmap;
+			goto out_free_hw;
+		}
+
+		if (!dbtr_trigger_valid(type, tdata1)) {
+			*out = _idx;
+			err = SBI_ERR_INVALID_PARAM;
+			goto out_free_hw;
 		}
 
-		if (!dbtr_trigger_valid(TDATA1_GET_TYPE(tdata1), tdata1)) {
+		hw_trig = sbi_alloc_hw_trigger(type, tdata1);
+		if (!hw_trig) {
 			*out = _idx;
 			err = SBI_ERR_FAILED;
-			goto out_unmap;
+			goto out_free_hw;
 		}
-	}
 
-	if (hs->available_trigs < trig_count) {
-		*out = hs->available_trigs;
-		err = SBI_ERR_FAILED;
-		goto out_unmap;
+		hw_trigs[i] = hw_trig;
+		i++;
 	}
 
 	/* Install triggers */
+	i = 0;
 	for_each_trig_entry(shmem_base, trig_count, typeof(*entry), entry) {
-		struct sbi_hw_trigger *hw_trig;
-		/*
-		 * Since we have already checked if enough triggers are
-		 * available, trigger allocation must succeed.
-		 */
-		trig = sbi_alloc_trigger();
-
 		recv = (struct sbi_dbtr_data_msg *)(&entry->data);
 		xmit = (struct sbi_dbtr_id_msg *)(&entry->id);
 
-		hw_trig = INDEX_TO_HW_TRIGGER(trig->index); /* 1:1 trig / HW idx */
-		if (hw_trig->inuse) {
-			*out = hs->available_trigs;
-			sbi_hart_protection_unmap_range((unsigned long)shmem_base,
-					trig_count * sizeof(*entry));
-			sbi_printf("DBTR error: Hardware trigger already inuse\n");
-			return SBI_ERR_FAILED;
-		}
+		/*
+		 * HW triggers were all allocated in the previous pass. Now
+		 * allocate and map dbtr triggers to them.
+		 */
+		hw_trig = hw_trigs[i++];
+
+		/*
+		 * Since we have already checked if enough HW triggers are
+		 * available, dbtr trig allocation must succeed here.
+		 */
+		trig = sbi_alloc_trigger();
 
 		dbtr_trigger_setup(trig, hw_trig, recv);
 		dbtr_trigger_enable(trig);
 		xmit->idx = cpu_to_lle(trig->index);
 	}
 
+	sbi_free(hw_trigs);
 	sbi_hart_protection_unmap_range((unsigned long)shmem_base,
 					trig_count * sizeof(*entry));
 
 	return SBI_SUCCESS;
 
-out_unmap:
+out_free_hw:
+	/* Free unused HW allocations */
+	for (i = 0; i < trig_count; i++) {
+		hw_trig = hw_trigs[i];
+		if (!hw_trig)
+			break;
+		hw_trig->inuse = false;
+	}
+
+	sbi_free(hw_trigs);
 	sbi_hart_protection_unmap_range((unsigned long)shmem_base,
 					trig_count * sizeof(*entry));
 
-- 
2.51.0


-- 
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi

  parent reply	other threads:[~2026-03-13  5:21 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-13  5:19 [PATCH 00/18] dbtr: Fixes and heterogeneous trigger types Nicholas Piggin
2026-03-13  5:19 ` [PATCH 01/18] dbtr: Add consistent range checks to trigger ecalls Nicholas Piggin
2026-03-20 12:46   ` Ilya Mamay
2026-04-07  5:22   ` Himanshu Chauhan
2026-03-13  5:19 ` [PATCH 02/18] dbtr: Trigger update should set sbiret.value on failure Nicholas Piggin
2026-03-13  5:19 ` [PATCH 03/18] dbtr: Fix endian conversion in trigger install handler Nicholas Piggin
2026-03-13  5:19 ` [PATCH 04/18] dbtr: Return correct error on install not supported Nicholas Piggin
2026-03-13  5:19 ` [PATCH 05/18] dbtr: Do not support chain bit Nicholas Piggin
2026-03-13  5:19 ` [PATCH 06/18] dbtr: Improve trigger update error checking Nicholas Piggin
2026-03-13  5:19 ` [PATCH 07/18] dbtr: Check for invalid and unsupported triggers in update Nicholas Piggin
2026-03-13  5:19 ` [PATCH 08/18] dbtr: Improve error handling for trigger enable, disable, uninstall Nicholas Piggin
2026-03-13  5:19 ` [PATCH 09/18] dbtr: Read triggers should not read HW trigger if not mapped Nicholas Piggin
2026-03-13  5:19 ` [PATCH 10/18] dbtr: Avoid crash in sbi_debug_read_triggers Nicholas Piggin
2026-03-13  5:19 ` [PATCH 11/18] dbtr: Succeed operations with no triggers in mask Nicholas Piggin
2026-03-13  5:19 ` [PATCH 12/18] dbtr: Move hardware trigger probing to a function Nicholas Piggin
2026-03-13  5:19 ` [PATCH 13/18] dbtr: Rework install and update error handling Nicholas Piggin
2026-03-13  5:19 ` [PATCH 14/18] dbtr: Decouple dbtr trigger index from hardware trigger number Nicholas Piggin
2026-03-13  5:19 ` [PATCH 15/18] dbtr: Move trigger feature support test into a function Nicholas Piggin
2026-03-13  5:19 ` Nicholas Piggin [this message]
2026-03-13  5:19 ` [PATCH 17/18] dbtr: Heterogeneous access type matching for mcontrol triggers Nicholas Piggin
2026-03-13  5:19 ` [PATCH 18/18] dbtr: Work around specification bug in range checks Nicholas Piggin

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=20260313051948.4017134-17-npiggin@gmail.com \
    --to=npiggin@gmail.com \
    --cc=hchauhan@ventanamicro.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