[Pdbg] [PATCH] libpdbg: Don't release special wakeup when threads are quiesced
Alistair Popple
alistair at popple.id.au
Mon Aug 13 15:02:19 AEST 2018
Signed-off-by: Alistair Popple <alistair at popple.id.au>
---
libpdbg/p9chip.c | 40 ++++++++++++++++++++++++++++++++++++++++
libpdbg/target.h | 1 +
2 files changed, 41 insertions(+)
diff --git a/libpdbg/p9chip.c b/libpdbg/p9chip.c
index 2585f11..189d80a 100644
--- a/libpdbg/p9chip.c
+++ b/libpdbg/p9chip.c
@@ -125,6 +125,15 @@ static int p9_thread_probe(struct pdbg_target *target)
return 0;
}
+static void p9_thread_release(struct pdbg_target *target)
+{
+ struct core *core = target_to_core(pdbg_target_require_parent("core", target));
+ struct thread *thread = target_to_thread(target);
+
+ if (thread->status.quiesced)
+ /* This thread is still quiesced so don't release spwkup */
+ core->release_spwkup = false;}
+
static int p9_thread_start(struct thread *thread)
{
if (!(thread->status.quiesced))
@@ -392,6 +401,7 @@ static struct thread p9_thread = {
.compatible = "ibm,power9-thread",
.class = "thread",
.probe = p9_thread_probe,
+ .release = p9_thread_release,
},
.start = p9_thread_start,
.stop = p9_thread_stop,
@@ -472,6 +482,7 @@ static int p9_chiplet_getring(struct chiplet *chiplet, uint64_t ring_addr, int64
static int p9_core_probe(struct pdbg_target *target)
{
+ struct core *core = target_to_core(target);
int i = 0;
uint64_t value;
@@ -493,12 +504,41 @@ static int p9_core_probe(struct pdbg_target *target)
}
} while (!(value & SPECIAL_WKUP_DONE));
+ /* Child threads will set this to false if they are released while quiesced */
+ core->release_spwkup = true;
+
return 0;
}
static void p9_core_release(struct pdbg_target *target)
{
+ struct pdbg_target *child;
+ struct core *core = target_to_core(target);
+ enum pdbg_target_status status;
+
usleep(1); /* enforce small delay before and after it is cleared */
+
+ /* Probe and release all threads to ensure release_spwkup is up to
+ * date */
+ pdbg_for_each_target("thread", target, child) {
+ status = pdbg_target_status(child);
+
+ /* This thread has already been release so should have set
+ * release_spwkup to false if it was quiesced, */
+ if (status == PDBG_TARGET_RELEASED)
+ continue;
+
+ status = pdbg_target_probe(child);
+ if (status != PDBG_TARGET_ENABLED)
+ continue;
+
+ /* Release the thread to ensure release_spwkup is updated. */
+ pdbg_target_release(child);
+ }
+
+ if (!core->release_spwkup)
+ return;
+
pib_write(target, PPM_SPWKUP_FSP, 0);
usleep(10000);
}
diff --git a/libpdbg/target.h b/libpdbg/target.h
index 6c2fa17..9f055ac 100644
--- a/libpdbg/target.h
+++ b/libpdbg/target.h
@@ -131,6 +131,7 @@ struct fsi {
struct core {
struct pdbg_target target;
+ bool release_spwkup;
};
#define target_to_core(x) container_of(x, struct core, target)
--
2.11.0
More information about the Pdbg
mailing list