Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions libpdbg/hwunit.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,20 @@ struct chipop {
int (*mpipl_continue)(struct chipop *);
int (*mpipl_get_ti_info)(struct chipop *, uint8_t **, uint32_t *);
int (*dump)(struct chipop *, uint8_t, uint8_t, uint8_t, uint8_t **, uint32_t *);
int (*operation)(struct chipop*, uint8_t* msg, uint32_t msg_len,
uint8_t** out, uint32_t* out_len);
int (*lpc_timeout)(struct chipop *, uint32_t *);
int (*set_fifo_timeout)(struct chipop*, uint32_t timeout_ms);
};
#define target_to_chipop(x) container_of(x, struct chipop, target)

struct chipop_ody {
struct pdbg_target target;
uint32_t (*ffdc_get)(struct chipop_ody*, struct pdbg_target*, const uint8_t **, uint32_t *);
int (*dump)(struct chipop_ody *, uint8_t, uint8_t, uint8_t, uint8_t **, uint32_t *);
int (*operation)(struct chipop_ody*, uint8_t* msg, uint32_t msg_len,
uint8_t** out, uint32_t* out_len);
int (*set_fifo_timeout)(struct chipop_ody*, uint32_t timeout_ms);
};
#define target_to_chipop_ody(x) container_of(x, struct chipop_ody, target)

Expand Down
6 changes: 6 additions & 0 deletions libpdbg/libpdbg_sbe.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,12 @@ int sbe_mpipl_get_ti_info(struct pdbg_target *target, uint8_t **data, uint32_t *
*/
int sbe_dump(struct pdbg_target *target, uint8_t type, uint8_t clock, uint8_t fa_collect, uint8_t **data, uint32_t *data_len);

int sbe_operation(struct pdbg_target* target,
uint8_t* msg, uint32_t msg_len,
uint8_t** out, uint32_t* out_len);

int sbe_set_chipop_timeout(struct pdbg_target* target, uint32_t timeout_ms);

/**
* @brief Get sbe state
*
Expand Down
48 changes: 48 additions & 0 deletions libpdbg/sbe_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,54 @@ int sbe_dump(struct pdbg_target *target, uint8_t type, uint8_t clock,
return 0;
}


int sbe_operation(struct pdbg_target* target,
uint8_t* msg, uint32_t msg_len,
uint8_t** out, uint32_t* out_len)
{
PR_ERROR("In sbe_operation");
if (!is_ody_ocmb_chip(target)) {
struct chipop* chipop = pib_to_chipop(target);
if (!chipop || !chipop->operation) {
PR_ERROR("operation() not implemented for the target\n");
return -1;
}
PR_ERROR("In sbe_operation: calling chipop->operation");
return chipop->operation(chipop, msg, msg_len, out, out_len);
} else {
struct chipop_ody* chipop;
struct pdbg_target* co_target = get_ody_chipop_target(target);
chipop = target_to_chipop_ody(co_target);
if (!chipop || !chipop->operation) {
PR_ERROR("operation() not implemented for the ODY target\n");
return -1;
}
return chipop->operation(chipop, msg, msg_len, out, out_len);
}
}

int sbe_set_chipop_timeout(struct pdbg_target* target, uint32_t timeout_ms)
{
if (!is_ody_ocmb_chip(target)) {

struct chipop* chipop = pib_to_chipop(target);
if (!chipop || !chipop->set_fifo_timeout) {
PR_ERROR("FIFO timeout not supported for the target\n");
return -1;
}
return chipop->set_fifo_timeout(chipop, timeout_ms);
} else {
struct chipop_ody* chipop;
struct pdbg_target* co_target = get_ody_chipop_target(target);
chipop = target_to_chipop_ody(co_target);
if (!chipop || !chipop->set_fifo_timeout) {
PR_ERROR("FIFO timeout not supported for the ODY target\n");
return -1;
}
return chipop->set_fifo_timeout((struct chipop_ody*)chipop, timeout_ms);
}
}

int sbe_ffdc_get(struct pdbg_target *target, uint32_t *status, uint8_t **ffdc,
uint32_t *ffdc_len)
{
Expand Down
30 changes: 30 additions & 0 deletions libpdbg/sbefifo.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,34 @@ static int sbefifo_op_dump(struct chipop *chipop, uint8_t type, uint8_t clock, u

return sbefifo_get_dump(sctx, type, clock, fa_collect, data, data_len);
}

static int sbefifo_op_operation(struct chipop* chipop,
uint8_t* msg, uint32_t msg_len,
uint8_t** out, uint32_t* out_len)
{
PR_ERROR("in sbefifo_op_operation\n");
struct sbefifo* sbefifo = target_to_sbefifo(chipop->target.parent);
if (!sbefifo)
{
PR_ERROR("sbefifo is NULL\n");
}
PR_ERROR("sbefifo is NOT NULL\n");
struct sbefifo_context* sctx = sbefifo->get_sbefifo_context(sbefifo);
if (!sctx)
{
PR_ERROR("in sbefifo_context is NULL\n");
}
PR_ERROR("in sbefifo_context is NOT NULL\n");
return sbefifo_operation(sctx, msg, msg_len, out, out_len);
}

static int sbefifo_op_set_fifo_timeout(struct chipop* chipop, uint32_t timeout_ms)
{
struct sbefifo* sbefifo = target_to_sbefifo(chipop->target.parent);
struct sbefifo_context* ctx = sbefifo->get_sbefifo_context(sbefifo);
return sbefifo_set_timeout(ctx, timeout_ms);
}

static int sbefifo_op_ody_dump(struct chipop_ody *chipop, uint8_t type, uint8_t clock, uint8_t fa_collect, uint8_t **data, uint32_t *data_len)
{
struct sbefifo *sbefifo = target_to_sbefifo(chipop->target.parent);
Expand Down Expand Up @@ -904,7 +932,9 @@ static struct chipop sbefifo_chipop = {
.mpipl_continue = sbefifo_op_mpipl_continue,
.mpipl_get_ti_info = sbefifo_op_mpipl_get_ti_info,
.dump = sbefifo_op_dump,
.operation = sbefifo_op_operation,
.lpc_timeout = sbefifo_op_lpc_timeout,
.set_fifo_timeout = sbefifo_op_set_fifo_timeout,
};
DECLARE_HW_UNIT(sbefifo_chipop);

Expand Down
15 changes: 15 additions & 0 deletions libsbefifo/connect.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,21 @@ int sbefifo_proc(struct sbefifo_context *sctx)
return sctx->proc;
}

int sbefifo_set_timeout(struct sbefifo_context *sctx, unsigned int timeout_ms)
{
unsigned int timeout = timeout_ms/1000;
int rc;

LOG("long_timeout: %u sec\n", timeout);
rc = ioctl(sctx->fd, FSI_SBEFIFO_READ_TIMEOUT, &timeout);
if (rc == -1 && errno == ENOTTY) {
/* Do not fail if kernel does not implement ioctl */
rc = 0;
}

return rc;
}

int sbefifo_set_long_timeout(struct sbefifo_context *sctx)
{
unsigned int long_timeout = 30;
Expand Down
7 changes: 7 additions & 0 deletions libsbefifo/libsbefifo.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,4 +203,11 @@ int sbefifo_mpipl_get_ti_info(struct sbefifo_context *sctx, uint8_t **data, uint

int sbefifo_get_dump(struct sbefifo_context *sctx, uint8_t type, uint8_t clock, uint8_t fa_collect, uint8_t **data, uint32_t *data_len);


int sbefifo_operation(struct sbefifo_context *sctx,
uint8_t *msg, uint32_t msg_len,
uint8_t **out, uint32_t *out_len);

int sbefifo_set_timeout(struct sbefifo_context *sctx, unsigned int timeout_ms);

#endif /* __LIBSBEFIFO_H__ */
76 changes: 36 additions & 40 deletions libsbefifo/operation.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,17 +66,18 @@ static int sbefifo_transport(struct sbefifo_context *sctx, uint8_t *msg, uint32_
buflen = msg_len;
rc = sbefifo_write(sctx, msg, buflen);
if (rc) {
LOG("write: cmd=%08x, rc=%d\n", be32toh(*(uint32_t *)(msg+4)), rc);
fprintf(stderr,"write: cmd=%08x, rc=%d\n", be32toh(*(uint32_t *)(msg+4)), rc);
return rc;
}
fprintf(stderr,"write: cmd=%08x, rc=%d\n", be32toh(*(uint32_t *)(msg+4)), rc);

buflen = *out_len;
rc = sbefifo_read(sctx, out, &buflen);
if (rc) {
LOG("read: cmd=%08x, buflen=%zu, rc=%d\n", be32toh(*(uint32_t *)(msg+4)), buflen, rc);
fprintf(stderr,"read: cmd=%08x, buflen=%zu, rc=%d\n", be32toh(*(uint32_t *)(msg+4)), buflen, rc);
return rc;
}

fprintf(stderr,"read: cmd=%08x, buflen=%zu, rc=%d\n", be32toh(*(uint32_t *)(msg+4)), buflen, rc);
*out_len = buflen;
return 0;
}
Expand Down Expand Up @@ -118,7 +119,7 @@ int sbefifo_parse_output(struct sbefifo_context *sctx, uint32_t cmd,
return EPROTO;
}

LOG("reply: cmd=%08x, len=%u, status=%08x\n", cmd, buflen, status_word);
fprintf(stderr,"reply: cmd=%08x, len=%u, status=%08x\n", cmd, buflen, status_word);

if (status_word) {
sbefifo_ffdc_set(sctx, status_word, buf + offset, buflen - offset-4);
Expand All @@ -143,52 +144,47 @@ int sbefifo_parse_output(struct sbefifo_context *sctx, uint32_t cmd,
}

int sbefifo_operation(struct sbefifo_context *sctx,
uint8_t *msg, uint32_t msg_len,
uint8_t **out, uint32_t *out_len)
uint8_t *msg, uint32_t msg_len,
uint8_t **out, uint32_t *out_len)
{
uint8_t *buf;
uint32_t buflen;
uint32_t cmd;
int rc;
assert(msg);
assert(msg_len > 0);

assert(msg);
assert(msg_len > 0);
if (!sctx || (!sctx->transport && sctx->fd == -1)) {
fprintf(stderr, "sbefifo_operation: transport or fd not valid. fd=%d\n", sctx ? sctx->fd : -1);
return ENOTCONN;
}

if (!sctx->transport && sctx->fd == -1)
return ENOTCONN;
// Allocate buffer with headroom for possible FFDC
uint32_t buflen = (*out_len + SBEFIFO_MAX_FFDC_SIZE + 3) & ~(uint32_t)3;
uint8_t *buf = malloc(buflen);
if (!buf) {
return ENOMEM;
}

/*
* Allocate extra memory for FFDC (SBEFIFO_MAX_FFDC_SIZE = 0x8000)32kb
* Use *out_len as a hint to expected reply length
*/
buflen = (*out_len + SBEFIFO_MAX_FFDC_SIZE + 3) & ~(uint32_t)3;
buf = malloc(buflen);
if (!buf)
return ENOMEM;
fprintf(stderr, "sbefifo_operation: fd=%d, sending cmd=0x%08x, msg_len=%u\n",
sctx->fd, be32toh(*(uint32_t *)(msg + 4)), msg_len);

cmd = be32toh(*(uint32_t *)(msg + 4));
int rc;

LOG("request: cmd=%08x, len=%u\n", cmd, msg_len);
rc = sbefifo_transport(sctx, msg, msg_len, buf, &buflen);

if (sctx->transport)
rc = sctx->transport(msg, msg_len, buf, &buflen, sctx->priv);
else
rc = sbefifo_transport(sctx, msg, msg_len, buf, &buflen);

if (rc) {
free(buf);
if (rc) {
free(buf);

if (rc == ETIMEDOUT) {
uint32_t status;
if (rc == ETIMEDOUT) {
uint32_t status = SBEFIFO_PRI_UNKNOWN_ERROR | SBEFIFO_SEC_HW_TIMEOUT;
sbefifo_ffdc_set(sctx, status, NULL, 0);
}

status = SBEFIFO_PRI_UNKNOWN_ERROR | SBEFIFO_SEC_HW_TIMEOUT;
sbefifo_ffdc_set(sctx, status, NULL, 0);
}
return rc;
}

return rc;
}
// Return raw buffer to caller
*out = buf;
*out_len = buflen;

rc = sbefifo_parse_output(sctx, cmd, buf, buflen, out, out_len);
free(buf);
return rc;
return 0;
}

4 changes: 2 additions & 2 deletions libsbefifo/sbefifo_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,10 @@ void sbefifo_debug(const char *fmt, ...);
void sbefifo_ffdc_clear(struct sbefifo_context *sctx);
void sbefifo_ffdc_set(struct sbefifo_context *sctx, uint32_t status, uint8_t *ffdc, uint32_t ffdc_len);

int sbefifo_operation(struct sbefifo_context *sctx,
/*int sbefifo_operation(struct sbefifo_context *sctx,
uint8_t *msg, uint32_t msg_len,
uint8_t **out, uint32_t *out_len);

*/
#ifdef LIBSBEFIFO_DEBUG
#define LOG(fmt, args...) sbefifo_debug(fmt, ##args)
#else
Expand Down