Skip to content

Commit

Permalink
cater for odyssey get and put scom
Browse files Browse the repository at this point in the history
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 <devenrao@in.ibm.com>
Change-Id: I55d438619b87b04e014bb6d8eaaef9aee986ae1b
  • Loading branch information
devenrao committed Dec 4, 2023
1 parent 8a3dc20 commit 79b2665
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 18 deletions.
15 changes: 15 additions & 0 deletions libpdbg/dtb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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)
{
Expand Down
51 changes: 33 additions & 18 deletions libpdbg/ocmb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down
43 changes: 43 additions & 0 deletions libpdbg/sbefifo.c
Original file line number Diff line number Diff line change
Expand Up @@ -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()) {
Expand All @@ -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)
{
/*
Expand Down Expand Up @@ -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);
Expand Down
26 changes: 26 additions & 0 deletions libpdbg/target.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand All @@ -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 */
Expand Down
3 changes: 3 additions & 0 deletions libpdbg/target.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 79b2665

Please sign in to comment.