diff --git a/libpdbg/libpdbg_sbe.h b/libpdbg/libpdbg_sbe.h index c8ef82bdd..989516c9f 100644 --- a/libpdbg/libpdbg_sbe.h +++ b/libpdbg/libpdbg_sbe.h @@ -104,6 +104,18 @@ int sbe_dump(struct pdbg_target *target, uint8_t type, uint8_t clock, uint8_t fa */ int sbe_get_state(struct pdbg_target *target, enum sbe_state *state); +/** + * @brief Get Odyssey sbe state + * + * Get the current state of Odyssey SBE + * + * @param[in] target fsi target to operate on + * @param[out] state sbe state + * + * @return 0 on success, -1 on failure + */ +int sbe_ody_get_state(struct pdbg_target *fsi, enum sbe_state *state); + /** * @brief Set sbe state * diff --git a/libpdbg/sbe_api.c b/libpdbg/sbe_api.c index 72c293a73..6caf19db2 100644 --- a/libpdbg/sbe_api.c +++ b/libpdbg/sbe_api.c @@ -308,6 +308,43 @@ static int sbe_read_state_register(struct pdbg_target *pib, uint32_t *value) return 0; } +static int sbe_ody_read_msg_register(struct pdbg_target *fsi, uint32_t *value) +{ + int rc; + + assert(fsi); + assert(pdbg_target_is_class(fsi, "fsi-ody")); + + if (pdbg_target_status(fsi) != PDBG_TARGET_ENABLED) + return -1; + + rc = fsi_ody_read(fsi, SBE_MSG_REG, value); + if (rc) { + PR_NOTICE("Failed to read sbe mailbox register\n"); + return rc; + } + + return 0; +} + +static int sbe_ody_read_state_register(struct pdbg_target *fsi, uint32_t *value) +{ + int rc; + + assert(fsi); + assert(pdbg_target_is_class(fsi, "fsi-ody")); + + if (pdbg_target_status(fsi) != PDBG_TARGET_ENABLED) + return -1; + + rc = fsi_ody_read(fsi, SBE_STATE_REG, value); + if (rc) { + PR_NOTICE("Failed to read sbe state register\n"); + return rc; + } + return 0; +} + static int sbe_write_state_register(struct pdbg_target *pib, uint32_t value) { struct pdbg_target *fsi = pdbg_target_parent_virtual("fsi", pib); @@ -351,6 +388,27 @@ int sbe_get_state(struct pdbg_target *pib, enum sbe_state *state) return 0; } +int sbe_ody_get_state(struct pdbg_target *fsi, enum sbe_state *state) +{ + union sbe_msg_register msg; + uint32_t value; + int rc; + + rc = sbe_ody_read_state_register(fsi, &value); + if (rc) + return -1; + if (value == SBE_STATE_CHECK_CFAM) { + rc = sbe_ody_read_msg_register(fsi, &msg.reg); + if (rc) + return -1; + *state = msg.sbe_booted ? SBE_STATE_BOOTED : SBE_STATE_CHECK_CFAM; + } else { + *state = value; + } + + return 0; +} + int sbe_set_state(struct pdbg_target *pib, enum sbe_state state) { uint32_t value = state; diff --git a/libpdbg/target.c b/libpdbg/target.c index 9a4cfb62a..6961f8649 100644 --- a/libpdbg/target.c +++ b/libpdbg/target.c @@ -644,6 +644,7 @@ enum pdbg_target_status pdbg_target_probe_ody_ocmb(struct pdbg_target *target) return PDBG_TARGET_NONEXISTENT; } + fsitarget->status = PDBG_TARGET_ENABLED; target->status = PDBG_TARGET_ENABLED; pibtarget->status = PDBG_TARGET_ENABLED; }