diff --git a/libpdbg/dtb.c b/libpdbg/dtb.c index c65d2003b..1079d3274 100644 --- a/libpdbg/dtb.c +++ b/libpdbg/dtb.c @@ -57,6 +57,8 @@ static enum pdbg_proc pdbg_proc = PDBG_PROC_UNKNOWN; static enum pdbg_backend pdbg_backend = PDBG_DEFAULT_BACKEND; static const char *pdbg_backend_option; +static const uint16_t ODYSSEY_CHIP_ID = 0x60C0; + static struct pdbg_dtb pdbg_dtb = { .backend = { .fd = -1, @@ -607,6 +609,21 @@ static void close_dtb(struct pdbg_mfile *mfile) close(mfile->fd); } } +static const uint8_t ATTR_TYPE_OCMB_CHIP = 75; +bool is_ody_ocmb_chip(struct pdbg_target *target) +{ + uint8_t type; + pdbg_target_get_attribute(target, "ATTR_TYPE", 1, 1, &type); + if(type != ATTR_TYPE_OCMB_CHIP) { + return false; + } + uint32_t chipId = 0; + pdbg_target_get_attribute(target, "ATTR_CHIP_ID", 4, 1, &chipId); + if(chipId == ODYSSEY_CHIP_ID) { + return true; + } + return false; +} __attribute__((destructor)) static void pdbg_close_targets(void) diff --git a/libpdbg/ocmb.c b/libpdbg/ocmb.c index ef929f9b7..51e62c744 100644 --- a/libpdbg/ocmb.c +++ b/libpdbg/ocmb.c @@ -39,32 +39,44 @@ static struct sbefifo *ocmb_to_sbefifo(struct ocmb *ocmb) static int sbefifo_ocmb_getscom(struct ocmb *ocmb, uint64_t addr, uint64_t *value) { - struct sbefifo *sbefifo = ocmb_to_sbefifo(ocmb); - struct sbefifo_context *sctx = sbefifo->get_sbefifo_context(sbefifo); - uint8_t instance_id; + if(is_ody_ocmb_chip(&ocmb->target)) { + struct sbefifo *sbefifo = ody_ocmb_to_sbefifo(&ocmb->target); + struct sbefifo_context *sctx = sbefifo->get_sbefifo_context(sbefifo); + return sbefifo_scom_get(sctx, addr, value); + } else { + struct sbefifo *sbefifo = ocmb_to_sbefifo(ocmb); + struct sbefifo_context *sctx = sbefifo->get_sbefifo_context(sbefifo); + uint8_t instance_id; - instance_id = pdbg_target_index(&ocmb->target) & 0xff; + instance_id = pdbg_target_index(&ocmb->target) & 0xff; - return sbefifo_hw_register_get(sctx, - SBEFIFO_TARGET_TYPE_OCMB, - instance_id, - addr, - value); + return sbefifo_hw_register_get(sctx, + SBEFIFO_TARGET_TYPE_OCMB, + instance_id, + addr, + value); + } } static int sbefifo_ocmb_putscom(struct ocmb *ocmb, uint64_t addr, uint64_t value) { - struct sbefifo *sbefifo = ocmb_to_sbefifo(ocmb); - struct sbefifo_context *sctx = sbefifo->get_sbefifo_context(sbefifo); - uint8_t instance_id; + if(is_ody_ocmb_chip(&ocmb->target)) { + struct sbefifo *sbefifo = ody_ocmb_to_sbefifo(&ocmb->target); + struct sbefifo_context *sctx = sbefifo->get_sbefifo_context(sbefifo); + return sbefifo_scom_put(sctx, addr, value); + } else { + struct sbefifo *sbefifo = ocmb_to_sbefifo(ocmb); + struct sbefifo_context *sctx = sbefifo->get_sbefifo_context(sbefifo); + uint8_t instance_id; - instance_id = pdbg_target_index(&ocmb->target) & 0xff; + instance_id = pdbg_target_index(&ocmb->target) & 0xff; - return sbefifo_hw_register_put(sctx, - SBEFIFO_TARGET_TYPE_OCMB, - instance_id, - addr, - value); + return sbefifo_hw_register_put(sctx, + SBEFIFO_TARGET_TYPE_OCMB, + instance_id, + addr, + value); + } } static struct ocmb sbefifo_ocmb = { diff --git a/libpdbg/sbefifo.c b/libpdbg/sbefifo.c index 98d46a7e4..43bd697fb 100644 --- a/libpdbg/sbefifo.c +++ b/libpdbg/sbefifo.c @@ -784,6 +784,7 @@ static struct sbefifo_context *sbefifo_op_get_context(struct sbefifo *sbefifo) static int sbefifo_probe(struct pdbg_target *target) { struct sbefifo *sf = target_to_sbefifo(target); + const char *sbefifo_path; int rc, proc; @@ -813,6 +814,31 @@ static int sbefifo_probe(struct pdbg_target *target) return 0; } +struct sbefifo *ody_ocmb_to_sbefifo(struct pdbg_target *target) +{ + assert(is_ody_ocmb_chip(target)); + + uint32_t ocmb_proc = pdbg_target_index(pdbg_target_parent("proc", + target)); + uint32_t ocmb_index = pdbg_target_index(target) % 0x8; + struct pdbg_target *ltarget; + + struct sbefifo *sbefifo = NULL; + pdbg_for_each_class_target("sbefifo", ltarget) { + uint32_t index = pdbg_target_index(ltarget); + uint32_t proc = 0; + if(!pdbg_target_u32_property(ltarget, "proc", &proc)) { + if(index == ocmb_index && proc == ocmb_proc) { + sbefifo = target_to_sbefifo(ltarget); + break; + } + } + } + assert(sbefifo); + + return sbefifo; +} + static void sbefifo_release(struct pdbg_target *target) { /* diff --git a/libpdbg/target.c b/libpdbg/target.c index 5b517ca56..2756b1204 100644 --- a/libpdbg/target.c +++ b/libpdbg/target.c @@ -492,6 +492,28 @@ struct pdbg_target_class *get_target_class(struct pdbg_target *target) return target_class; } +/*ddr5 ocmb is itself a chip but in device tree as it is kept under + perv, mc, mcc, omi probing parent chips might fail */ +enum pdbg_target_status pdbg_target_probe_ody_ocmb(struct pdbg_target *target) +{ + assert(is_ody_ocmb_chip(target)); + //find the corresponding sbefifo, probe and if probe is sucess return enabled + //TODO:run some scom on the target to see if it can communicate + struct sbefifo *sbefifo = ody_ocmb_to_sbefifo(target); + if (sbefifo->target.probe && sbefifo->target.probe(&sbefifo->target)) { + sbefifo->target.status = PDBG_TARGET_NONEXISTENT; + return PDBG_TARGET_NONEXISTENT; + } + if (target->probe && target->probe(target)) { + target->status = PDBG_TARGET_NONEXISTENT; + return PDBG_TARGET_NONEXISTENT; + } + + target->status = PDBG_TARGET_ENABLED; + sbefifo->target.status = PDBG_TARGET_ENABLED; + return PDBG_TARGET_ENABLED; +} + /* We walk the tree root down disabling targets which might/should * exist but don't */ enum pdbg_target_status pdbg_target_probe(struct pdbg_target *target) @@ -510,6 +532,13 @@ enum pdbg_target_status pdbg_target_probe(struct pdbg_target *target) * it's status won't have changed */ return status; + /* ddr5 is a chip itself but in device tree it is put under chiplet, + mc, mcc, omi so do not probe targets above ddr5 ocmb + */ + if(is_ody_ocmb_chip(target)){ + return pdbg_target_probe_ody_ocmb(target); + } + parent = get_parent(target, false); if (parent) { /* Recurse up the tree to probe and set parent target status */ diff --git a/libpdbg/target.h b/libpdbg/target.h index 679f0a12a..2bc5392f6 100644 --- a/libpdbg/target.h +++ b/libpdbg/target.h @@ -108,4 +108,7 @@ bool pdbg_context_is_short(void); */ void clear_target_classes(); +bool is_ody_ocmb_chip(struct pdbg_target *target); + +struct sbefifo *ody_ocmb_to_sbefifo(struct pdbg_target *target); #endif