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 93194a6 commit bb79ee5
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 18 deletions.
17 changes: 17 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 @@ -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)
Expand Down
48 changes: 30 additions & 18 deletions libpdbg/ocmb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down
26 changes: 26 additions & 0 deletions libpdbg/sbefifo.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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)
{
/*
Expand Down
29 changes: 29 additions & 0 deletions libpdbg/target.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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 */
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_ocmb_to_sbefifo(struct pdbg_target *target);
#endif

0 comments on commit bb79ee5

Please sign in to comment.