diff --git a/libpdbg/dtb.c b/libpdbg/dtb.c index c65d2003b..442870e38 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, @@ -608,6 +610,19 @@ static void close_dtb(struct pdbg_mfile *mfile) } } +bool is_ody_ocmb_chip(struct pdbg_target *target) +{ + if(!target) + return false; + if(strcmp(target->name, "ocmb") != 0) + 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..a7a4fd2f9 100644 --- a/libpdbg/ocmb.c +++ b/libpdbg/ocmb.c @@ -39,32 +39,47 @@ 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; + printf("sbefifo_ocmb_getscom \n"); + if(is_ody_ocmb_chip(&ocmb->target)) { + printf("sbefifo_ocmb_getscom calling ody_to_sbefifo \n"); + struct sbefifo *sbefifo = ody_to_sbefifo(&ocmb->target); + struct sbefifo_context *sctx = sbefifo->get_sbefifo_context(sbefifo); + return sbefifo_scom_get(sctx, addr, value); + } else { + printf("sbefifo_ocmb_getscom calling ocmb_to_sbefifo \n"); + 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_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..7ba61e3df 100644 --- a/libpdbg/sbefifo.c +++ b/libpdbg/sbefifo.c @@ -783,11 +783,13 @@ static struct sbefifo_context *sbefifo_op_get_context(struct sbefifo *sbefifo) static int sbefifo_probe(struct pdbg_target *target) { + printf("came into sbefifo_probe \n"); struct sbefifo *sf = target_to_sbefifo(target); const char *sbefifo_path; int rc, proc; sbefifo_path = pdbg_target_property(target, "device-path", NULL); + printf("device_path set is %s \n", sbefifo_path ); assert(sbefifo_path); switch (pdbg_get_proc()) { @@ -813,6 +815,32 @@ static int sbefifo_probe(struct pdbg_target *target) return 0; } +struct sbefifo *ody_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_ocmb", 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) { + printf("ody_ocmb_to_sbefifo ocmbproc=%d ocmbindex=%d fifo index=%d fifoproc=%d \n", ocmb_proc, ocmb_index, proc, index); + sbefifo = target_to_sbefifo(ltarget); + break; + } + } + } + assert(sbefifo); + + return sbefifo; +} + static void sbefifo_release(struct pdbg_target *target) { /* @@ -919,10 +947,25 @@ static struct sbefifo kernel_sbefifo = { }; DECLARE_HW_UNIT(kernel_sbefifo); +//for ddr5 ocmb chip has its own sbe instance, different to ddr4 ocmb +//which communicates through proc sbe +//probe = sbefifo_probe, +static struct sbefifo kernel_sbefifo_ody = { + .target = { + .name = "Kernel based FSI SBE FIFO OCMB", + .compatible = "ibm,kernel-sbefifo-ody", + .class = "sbefifo_ody", + .release = sbefifo_release, + }, + .get_sbefifo_context = sbefifo_op_get_context, +}; +DECLARE_HW_UNIT(kernel_sbefifo_ody); + __attribute__((constructor)) static void register_sbefifo(void) { pdbg_hwunit_register(PDBG_DEFAULT_BACKEND, &kernel_sbefifo_hw_unit); + pdbg_hwunit_register(PDBG_DEFAULT_BACKEND, &kernel_sbefifo_ody_hw_unit); pdbg_hwunit_register(PDBG_DEFAULT_BACKEND, &sbefifo_chipop_hw_unit); pdbg_hwunit_register(PDBG_DEFAULT_BACKEND, &sbefifo_pib_hw_unit); pdbg_hwunit_register(PDBG_BACKEND_SBEFIFO, &sbefifo_thread_hw_unit); diff --git a/libpdbg/target.c b/libpdbg/target.c index 5b517ca56..193fd0566 100644 --- a/libpdbg/target.c +++ b/libpdbg/target.c @@ -492,6 +492,25 @@ 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_ocmb(struct pdbg_target *target) +{ + printf("came into pdbg_target_probe_ocmb \n"); + 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_to_sbefifo(target); + if(sbefifo->target.probe) { + target->status = PDBG_TARGET_NONEXISTENT; + sbefifo->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) @@ -502,6 +521,7 @@ enum pdbg_target_status pdbg_target_probe(struct pdbg_target *target) assert(target); status = pdbg_target_status(target); + //printf("pdbg_target_probe target name %s \n", pdbg_target_name(target)); assert(status != PDBG_TARGET_RELEASED); if (status == PDBG_TARGET_DISABLED || status == PDBG_TARGET_NONEXISTENT @@ -510,6 +530,12 @@ 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_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..9b3304aa4 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_to_sbefifo(struct pdbg_target *target); #endif