From bb79ee5c1232d7efe91791047ba769243655103a Mon Sep 17 00:00:00 2001 From: devenrao Date: Mon, 27 Nov 2023 16:53:04 +0530 Subject: [PATCH] cater for odyssey get and put scom 1) Uses the device path configured in the bmc backend device tree to perform get and put scom on odyssey ddr5 chip 2) Checks attribute chip-id of the ocmb target to differentiate between ddr4 and ddr5 ocmb chips for get/put scom 3) For ddr5 ocmb targets parent proc sbefifo device path is used for get/put scom 4) For ddr5 ocmb targets its corresponding sbefifo device path is used for get/put scom Tested: root@ever6bmc:/tmp# getscom odyssey c0002040 -pall odyssey k0:n0:s0:p02 0x0040010002000640 odyssey k0:n0:s0:p03 0x0040010002000640 odyssey k0:n0:s0:p34 0x0040010002000640 odyssey k0:n0:s0:p35 0x0040010002000640 /usr/bin/edbg getscom odyssey c0002040 -pall Signed-off-by: Marri Devender Rao Change-Id: I55d438619b87b04e014bb6d8eaaef9aee986ae1b --- libpdbg/dtb.c | 17 +++++++++++++++++ libpdbg/ocmb.c | 48 +++++++++++++++++++++++++++++------------------ libpdbg/sbefifo.c | 26 +++++++++++++++++++++++++ libpdbg/target.c | 29 ++++++++++++++++++++++++++++ libpdbg/target.h | 3 +++ 5 files changed, 105 insertions(+), 18 deletions(-) diff --git a/libpdbg/dtb.c b/libpdbg/dtb.c index c65d2003b4..1079d32740 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 ef929f9b72..51e62c7443 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 98d46a7e4d..43bd697fba 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 5b517ca56a..2756b1204e 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 679f0a12a0..2bc5392f62 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