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
32 changes: 23 additions & 9 deletions examples/htool_jtag.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,11 @@ static int jtag_read_idcode(struct libhoth_device* dev,
}

uint32_t idcode = 0;
int ret = libhoth_jtag_read_idcode(dev, interface_id, clk_idiv, &idcode);
if (ret != 0) {
return ret;
libhoth_error err =
libhoth_jtag_read_idcode(dev, interface_id, clk_idiv, &idcode);
if (err != HOTH_SUCCESS) {
htool_report_error("jtag read_idcode", err);
return -1;
}

printf("IDCODE: 0x%08x\n", idcode);
Expand Down Expand Up @@ -150,10 +152,11 @@ static int jtag_test_bypass(struct libhoth_device* dev,
printf("\n");

uint8_t tdo_bytes[HOTH_JTAG_TEST_BYPASS_PATTERN_LEN] = {0};
ret = libhoth_jtag_test_bypass(dev, interface_id, clk_idiv, tdi_bytes,
tdo_bytes);
if (ret != 0) {
return ret;
libhoth_error err = libhoth_jtag_test_bypass(dev, interface_id, clk_idiv,
tdi_bytes, tdo_bytes);
if (err != HOTH_SUCCESS) {
htool_report_error("jtag test_bypass", err);
return -1;
}

bool tdo_matches_tdi = true;
Expand Down Expand Up @@ -188,7 +191,13 @@ static int jtag_program_and_verify_pld(struct libhoth_device* dev,
return -1;
}

return libhoth_jtag_program_and_verify_pld(dev, interface_id, offset);
libhoth_error err =
libhoth_jtag_program_and_verify_pld(dev, interface_id, offset);
if (err != HOTH_SUCCESS) {
htool_report_error("jtag program_and_verify_pld", err);
return -1;
}
return 0;
}

static int jtag_verify_pld(struct libhoth_device* dev,
Expand All @@ -208,7 +217,12 @@ static int jtag_verify_pld(struct libhoth_device* dev,
return -1;
}

return libhoth_jtag_verify_pld(dev, interface_id, offset);
libhoth_error err = libhoth_jtag_verify_pld(dev, interface_id, offset);
if (err != HOTH_SUCCESS) {
htool_report_error("jtag verify_pld", err);
return -1;
}
return 0;
}

int htool_jtag_run(const struct htool_invocation* inv) {
Expand Down
2 changes: 2 additions & 0 deletions protocol/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,7 @@ cc_library(
hdrs = ["jtag.h"],
deps = [
":host_cmd",
":libhoth_status",
"//transports:libhoth_device",
],
)
Expand All @@ -410,6 +411,7 @@ cc_test(
srcs = ["jtag_test.cc"],
deps = [
":jtag",
":libhoth_status",
"//protocol/test:libhoth_device_mock",
"//transports:libhoth_device",
"@googletest//:gtest",
Expand Down
105 changes: 67 additions & 38 deletions protocol/jtag.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,23 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#include "jtag.h"
#include "protocol/jtag.h"

#include <stdint.h>
#include <stdio.h>
#include <string.h>

#include "host_cmd.h"
#include "protocol/status.h"
#include "transports/libhoth_device.h"

int libhoth_jtag_read_idcode(struct libhoth_device* dev, uint8_t interface_id,
uint16_t clk_idiv, uint32_t* idcode) {
libhoth_error libhoth_jtag_read_idcode(struct libhoth_device* dev,
uint8_t interface_id, uint16_t clk_idiv,
uint32_t* idcode) {
if (dev == NULL || idcode == NULL) {
return LIBHOTH_ERR_CONSTRUCT(HOTH_CTX_CMD_EXEC, HOTH_HOST_SPACE_LIBHOTH,
LIBHOTH_ERR_INVALID_PARAMETER);
}
const struct hoth_request_jtag_operation request = {
.clk_idiv = clk_idiv,
.operation = HOTH_JTAG_OP_READ_IDCODE,
Expand All @@ -31,31 +37,38 @@ int libhoth_jtag_read_idcode(struct libhoth_device* dev, uint8_t interface_id,
struct hoth_response_jtag_read_idcode_operation response;

size_t response_length = 0;
int ret = libhoth_hostcmd_exec(
libhoth_error ret = libhoth_hostcmd_exec_v2(
dev, HOTH_CMD_BOARD_SPECIFIC_BASE + HOTH_PRV_CMD_HOTH_JTAG_OPERATION,
/*version=*/0, &request, sizeof(request), &response, sizeof(response),
&response_length);

if (ret != 0) {
fprintf(stderr, "HOTH_JTAG_OPERATION error code: %d\n", ret);
return -1;
if (ret != HOTH_SUCCESS) {
fprintf(stderr, "HOTH_JTAG_OPERATION error code: 0x%016llx\n",
(unsigned long long)ret);
return ret;
}

if (response_length != sizeof(response)) {
fprintf(stderr,
"HOTH_JTAG_OPERATION expected exactly %zu reseponse bytes, got %zu",
sizeof(response), response_length);
return -1;
fprintf(
stderr,
"HOTH_JTAG_OPERATION expected exactly %zu response bytes, got %zu\n",
sizeof(response), response_length);
return LIBHOTH_ERR_CONSTRUCT(HOTH_CTX_CMD_EXEC, HOTH_HOST_SPACE_LIBHOTH,
LIBHOTH_ERR_FAIL);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Would it be a good idea to create a different error code for this condition? It can be done in a separate PR if you prefer to do so

}

*idcode = response.idcode;
return 0;
return HOTH_SUCCESS;
}

int libhoth_jtag_test_bypass(
libhoth_error libhoth_jtag_test_bypass(
struct libhoth_device* dev, uint8_t interface_id, uint16_t clk_idiv,
const uint8_t tdi_bytes[HOTH_JTAG_TEST_BYPASS_PATTERN_LEN],
uint8_t tdo_bytes[HOTH_JTAG_TEST_BYPASS_PATTERN_LEN]) {
if (dev == NULL || tdi_bytes == NULL || tdo_bytes == NULL) {
return LIBHOTH_ERR_CONSTRUCT(HOTH_CTX_CMD_EXEC, HOTH_HOST_SPACE_LIBHOTH,
LIBHOTH_ERR_INVALID_PARAMETER);
}
struct {
struct hoth_request_jtag_operation operation;
struct hoth_request_jtag_test_bypass_operation params;
Expand All @@ -73,29 +86,37 @@ int libhoth_jtag_test_bypass(

struct hoth_response_jtag_test_bypass_operation response;
size_t response_len = 0;
int ret = libhoth_hostcmd_exec(
libhoth_error ret = libhoth_hostcmd_exec_v2(
dev, HOTH_CMD_BOARD_SPECIFIC_BASE + HOTH_PRV_CMD_HOTH_JTAG_OPERATION,
/*version=*/0, &request, sizeof(request), &response, sizeof(response),
&response_len);

if (ret != 0) {
fprintf(stderr, "HOTH_JTAG_OPERATION error code: %d\n", ret);
return -1;
if (ret != HOTH_SUCCESS) {
fprintf(stderr, "HOTH_JTAG_OPERATION error code: 0x%016llx\n",
(unsigned long long)ret);
return ret;
}

if (response_len != sizeof(response)) {
fprintf(stderr,
"HOTH_JTAG_OPERATION expected exactly %zu response bytes, got %zu",
sizeof(response), response_len);
return -1;
fprintf(
stderr,
"HOTH_JTAG_OPERATION expected exactly %zu response bytes, got %zu\n",
sizeof(response), response_len);
return LIBHOTH_ERR_CONSTRUCT(HOTH_CTX_CMD_EXEC, HOTH_HOST_SPACE_LIBHOTH,
LIBHOTH_ERR_FAIL);
}

memcpy(tdo_bytes, response.tdo_pattern, HOTH_JTAG_TEST_BYPASS_PATTERN_LEN);
return 0;
return HOTH_SUCCESS;
}

int libhoth_jtag_program_and_verify_pld(struct libhoth_device* dev,
uint8_t interface_id, uint32_t offset) {
libhoth_error libhoth_jtag_program_and_verify_pld(struct libhoth_device* dev,
uint8_t interface_id,
uint32_t offset) {
if (dev == NULL) {
return LIBHOTH_ERR_CONSTRUCT(HOTH_CTX_CMD_EXEC, HOTH_HOST_SPACE_LIBHOTH,
LIBHOTH_ERR_INVALID_PARAMETER);
}
struct {
struct hoth_request_jtag_operation operation;
struct hoth_request_jtag_program_and_verify_pld_operation params;
Expand All @@ -113,28 +134,34 @@ int libhoth_jtag_program_and_verify_pld(struct libhoth_device* dev,
};

size_t response_length = 0;
int ret = libhoth_hostcmd_exec(
libhoth_error ret = libhoth_hostcmd_exec_v2(
dev, HOTH_CMD_BOARD_SPECIFIC_BASE + HOTH_PRV_CMD_HOTH_JTAG_OPERATION,
/*version=*/0, &request, sizeof(request), /*resp_buf=*/NULL,
/*resp_buf_size=*/0, &response_length);

if (ret != 0) {
fprintf(stderr, "HOTH_JTAG_OPERATION error code: %d\n", ret);
return -1;
if (ret != HOTH_SUCCESS) {
fprintf(stderr, "HOTH_JTAG_OPERATION error code: 0x%016llx\n",
(unsigned long long)ret);
return ret;
}

if (response_length != 0) {
fprintf(stderr,
"HOTH_JTAG_OPERATION expected exactly %u response bytes, got %zu\n",
0, response_length);
return -1;
return LIBHOTH_ERR_CONSTRUCT(HOTH_CTX_CMD_EXEC, HOTH_HOST_SPACE_LIBHOTH,
LIBHOTH_ERR_FAIL);
}

return 0;
return HOTH_SUCCESS;
}

int libhoth_jtag_verify_pld(struct libhoth_device* dev, uint8_t interface_id,
uint32_t offset) {
libhoth_error libhoth_jtag_verify_pld(struct libhoth_device* dev,
uint8_t interface_id, uint32_t offset) {
if (dev == NULL) {
return LIBHOTH_ERR_CONSTRUCT(HOTH_CTX_CMD_EXEC, HOTH_HOST_SPACE_LIBHOTH,
LIBHOTH_ERR_INVALID_PARAMETER);
}
struct {
struct hoth_request_jtag_operation operation;
struct hoth_request_jtag_program_and_verify_pld_operation params;
Expand All @@ -152,22 +179,24 @@ int libhoth_jtag_verify_pld(struct libhoth_device* dev, uint8_t interface_id,
};

size_t response_length = 0;
int ret = libhoth_hostcmd_exec(
libhoth_error ret = libhoth_hostcmd_exec_v2(
dev, HOTH_CMD_BOARD_SPECIFIC_BASE + HOTH_PRV_CMD_HOTH_JTAG_OPERATION,
/*version=*/0, &request, sizeof(request), /*resp_buf=*/NULL,
/*resp_buf_size=*/0, &response_length);

if (ret != 0) {
fprintf(stderr, "HOTH_JTAG_OPERATION error code: %d\n", ret);
return -1;
if (ret != HOTH_SUCCESS) {
fprintf(stderr, "HOTH_JTAG_OPERATION error code: 0x%016llx\n",
(unsigned long long)ret);
return ret;
}

if (response_length != 0) {
fprintf(stderr,
"HOTH_JTAG_OPERATION expected exactly %u response bytes, got %zu\n",
0, response_length);
return -1;
return LIBHOTH_ERR_CONSTRUCT(HOTH_CTX_CMD_EXEC, HOTH_HOST_SPACE_LIBHOTH,
LIBHOTH_ERR_FAIL);
}

return 0;
return HOTH_SUCCESS;
}
17 changes: 10 additions & 7 deletions protocol/jtag.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include <stdint.h>

#include "protocol/status.h"
#include "transports/libhoth_device.h"

#ifdef __cplusplus
Expand Down Expand Up @@ -83,19 +84,21 @@ struct hoth_response_jtag_test_bypass_operation {
uint8_t tdo_pattern[HOTH_JTAG_TEST_BYPASS_PATTERN_LEN];
} __attribute__((packed, aligned(4)));

int libhoth_jtag_read_idcode(struct libhoth_device* dev, uint8_t interface_id,
uint16_t clk_idiv, uint32_t* idcode);
libhoth_error libhoth_jtag_read_idcode(struct libhoth_device* dev,
uint8_t interface_id, uint16_t clk_idiv,
uint32_t* idcode);

int libhoth_jtag_test_bypass(
libhoth_error libhoth_jtag_test_bypass(
struct libhoth_device* dev, uint8_t interface_id, uint16_t clk_idiv,
const uint8_t tdi_bytes[HOTH_JTAG_TEST_BYPASS_PATTERN_LEN],
uint8_t tdo_bytes[HOTH_JTAG_TEST_BYPASS_PATTERN_LEN]);

int libhoth_jtag_program_and_verify_pld(struct libhoth_device* dev,
uint8_t interface_id, uint32_t offset);
libhoth_error libhoth_jtag_program_and_verify_pld(struct libhoth_device* dev,
uint8_t interface_id,
uint32_t offset);

int libhoth_jtag_verify_pld(struct libhoth_device* dev, uint8_t interface_id,
uint32_t offset);
libhoth_error libhoth_jtag_verify_pld(struct libhoth_device* dev,
uint8_t interface_id, uint32_t offset);

#ifdef __cplusplus
}
Expand Down
Loading
Loading