in common/recipes-core/asd/files/daemon/socket_main.c [724:1005]
STATUS process_jtag_message(struct spi_message *s_message) {
int response_cnt = 0;
JtagStates end_state;
STATUS status = ST_OK;
int size = get_message_size(s_message);
struct packet_data packet;
unsigned char *data_ptr;
uint8_t cmd;
if (size == -1) {
ASD_log(LogType_Error, "Failed to process jtag message because "
"get message size failed.");
return ST_ERR;
}
memset(&out_msg.header, 0, sizeof(struct message_header));
memset(out_msg.buffer, 0, MAX_DATA_SIZE);
ASD_log(LogType_JTAG, "NetReq tag: %d size: %d", s_message->header.tag, size);
ASD_log_buffer(LogType_JTAG, s_message->buffer, size, "NetReq");
packet.next_data = s_message->buffer;
packet.used = 0;
packet.available = size;
while (packet.used < packet.available) {
data_ptr = get_packet_data(&packet, 1);
if (data_ptr == NULL) {
ASD_log(LogType_Error, "no command to read, short packet");
status = ST_ERR;
break;
}
cmd = *data_ptr;
if (cmd == WRITE_EVENT_CONFIG) {
data_ptr = get_packet_data(&packet, 1);
if (data_ptr == NULL) {
ASD_log(LogType_Error, "Failed to read data for WRITE_EVENT_CONFIG, short packet");
status = ST_ERR;
break;
}
status = write_event_config(*data_ptr);
if(status != ST_OK) {
ASD_log(LogType_Error, "write_event_config failed, %d", status);
break;
}
} else if (cmd >= WRITE_CFG_MIN && cmd <= WRITE_CFG_MAX) {
status = write_cfg((writeCfg)cmd, &packet);
if(status != ST_OK) {
ASD_log(LogType_Error, "write_cfg failed, %d", status);
break;
}
} else if (cmd == WRITE_PINS) {
data_ptr = get_packet_data(&packet, 1);
if (data_ptr == NULL) {
ASD_log(LogType_Error, "Failed to read data for WRITE_PINS, short packet");
status = ST_ERR;
break;
}
uint8_t data = *data_ptr;
bool assert = (data >> 7) == 1;
Pin pin = PIN_MIN;
uint8_t index = data & WRITE_PIN_MASK;
if (index > PIN_MIN && index < PIN_MAX) {
pin = (Pin)index;
status = target_write(target_control_handle, pin, assert);
if(status != ST_OK) {
ASD_log(LogType_Error, "target_write failed, %d", status);
break;
}
} else if ((index & SCAN_CHAIN_SELECT) == SCAN_CHAIN_SELECT) {
uint8_t scan_chain = (index & SCAN_CHAIN_SELECT_MASK);
if (scan_chain >= MAX_SCAN_CHAINS) {
ASD_log(LogType_Error, "Unexpected scan chain: 0x%02x", scan_chain);
status = ST_ERR;
break;
}
status = target_jtag_chain_select(target_control_handle, (scanChain)scan_chain);
if(status != ST_OK) {
ASD_log(LogType_Error, "target_jtag_chain_select failed, %d", status);
break;
}
status = JTAG_set_active_chain(jtag_handler, (scanChain)scan_chain);
if(status != ST_OK) {
ASD_log(LogType_Error, "JTAG_set_active_chain failed, %d", status);
break;
}
} else {
ASD_log(LogType_Error, "Unexpected WRITE_PINS index: 0x%02x", index);
status = ST_ERR;
break;
}
} else if (cmd >= READ_STATUS_MIN && cmd <= READ_STATUS_MAX) {
int bytes_written = 0;
ReadType readStatusTypeIndex;
uint8_t index = (cmd & READ_STATUS_MASK);
if (index > READ_TYPE_MIN && index < READ_TYPE_MAX)
readStatusTypeIndex = (ReadType)index;
else {
ASD_log(LogType_Error, "Unexpected READ_STATUS index: 0x%02x", index);
status = ST_ERR;
break;
}
data_ptr = get_packet_data(&packet, 1);
if (data_ptr == NULL) {
ASD_log(LogType_Error, "Failed to read data for Read Status, short packet");
status = ST_ERR;
break;
}
if (response_cnt+2 > MAX_DATA_SIZE) {
ASD_log(LogType_Error, "Failed to process READ_STATUS. "
"Response buffer already full");
status = ST_ERR;
break;
}
uint8_t pin = (*data_ptr & READ_STATUS_PIN_MASK);
status = read_status(readStatusTypeIndex, pin, &out_msg.buffer[response_cnt],
MAX_DATA_SIZE-response_cnt, &bytes_written);
if(status != ST_OK) {
ASD_log(LogType_Error, "read_status failed, %d", status);
break;
}
response_cnt += bytes_written;
} else if (cmd == WAIT_CYCLES_TCK_DISABLE ||
cmd == WAIT_CYCLES_TCK_ENABLE) {
data_ptr = get_packet_data(&packet, 1);
if (data_ptr == NULL) {
ASD_log(LogType_Error, "Failed to read data for WAIT_CYCLES_TCK, short packet");
status = ST_ERR;
break;
}
unsigned int number_of_cycles = *data_ptr;
if (number_of_cycles==0)
number_of_cycles = 256;
ASD_log(LogType_Debug, "Wait cycle of %d", number_of_cycles);
status = JTAG_wait_cycles(jtag_handler, number_of_cycles);
if(status != ST_OK) {
ASD_log(LogType_Error, "JTAG_wait_cycles failed, %d", status);
break;
}
} else if (cmd == WAIT_PRDY) {
status = target_wait_PRDY(target_control_handle, prdy_timeout);
if(status != ST_OK) {
ASD_log(LogType_Error, "target_wait_PRDY failed, %d", status);
break;
}
} else if (cmd == CLEAR_TIMEOUT) {
// Command not yet implemented. This command does not apply to JTAG
// so we will likely not implement it.
ASD_log(LogType_Debug, "Clear Timeout command not yet implemented");
} else if (cmd == TAP_RESET) {
status = JTAG_tap_reset(jtag_handler);
if(status != ST_OK) {
ASD_log(LogType_Error, "JTAG_tap_reset failed, %d", status);
break;
}
} else if (cmd >= TAP_STATE_MIN && cmd <= TAP_STATE_MAX) {
status = JTAG_set_tap_state(jtag_handler, (JtagStates)(cmd & TAP_STATE_MASK));
if(status != ST_OK) {
ASD_log(LogType_Error, "JTAG_set_tap_state failed, %d", status);
break;
}
} else if (cmd >= WRITE_SCAN_MIN && cmd <= WRITE_SCAN_MAX) {
uint8_t num_of_bits = 0;
uint8_t num_of_bytes = 0;
get_scan_length(cmd, &num_of_bits, &num_of_bytes);
data_ptr = get_packet_data(&packet, num_of_bytes);
if (data_ptr == NULL) {
ASD_log(LogType_Error, "Failed to read data from buffer: %d", num_of_bytes);
status = ST_ERR;
break;
}
status = determine_shift_end_state(ScanType_Write, &packet, &end_state);
if(status != ST_OK) {
ASD_log(LogType_Error, "determine_shift_end_state failed, %d", status);
break;
}
status = JTAG_shift(jtag_handler, num_of_bits,
MAX_DATA_SIZE - packet.used - num_of_bytes,
data_ptr, 0, NULL, end_state);
if(status != ST_OK) {
ASD_log(LogType_Error, "JTAG_shift failed, %d", status);
break;
}
} else if (cmd >= READ_SCAN_MIN && cmd <= READ_SCAN_MAX) {
uint8_t num_of_bits = 0;
uint8_t num_of_bytes = 0;
get_scan_length(cmd, &num_of_bits, &num_of_bytes);
if (response_cnt+sizeof(char)+num_of_bytes > MAX_DATA_SIZE) {
ASD_log(LogType_Error, "Failed to process READ_SCAN. "
"Response buffer already full");
status = ST_ERR;
break;
}
out_msg.buffer[response_cnt++] = cmd;
status = determine_shift_end_state(ScanType_Read, &packet, &end_state);
if(status != ST_OK) {
ASD_log(LogType_Error, "determine_shift_end_state failed, %d", status);
break;
}
status = JTAG_shift(jtag_handler, num_of_bits, 0, NULL,
MAX_DATA_SIZE-response_cnt,
(unsigned char*)&(out_msg.buffer[response_cnt]),
end_state);
if(status != ST_OK) {
ASD_log(LogType_Error, "JTAG_shift failed, %d", status);
break;
}
response_cnt += num_of_bytes;
} else if (cmd >= READ_WRITE_SCAN_MIN && cmd <= READ_WRITE_SCAN_MAX) {
uint8_t num_of_bits = 0;
uint8_t num_of_bytes = 0;
get_scan_length(cmd, &num_of_bits, &num_of_bytes);
if (response_cnt+sizeof(char)+num_of_bytes > MAX_DATA_SIZE) {
ASD_log(LogType_Error, "Failed to process READ_WRITE_SCAN. "
"Response buffer already full");
status = ST_ERR;
break;
}
out_msg.buffer[response_cnt++] = cmd;
data_ptr = get_packet_data(&packet, num_of_bytes);
if (data_ptr == NULL) {
ASD_log(LogType_Error, "Failed to read data from buffer: %d", num_of_bytes);
status = ST_ERR;
break;
}
status = determine_shift_end_state(ScanType_ReadWrite, &packet, &end_state);
if(status != ST_OK) {
ASD_log(LogType_Error, "determine_shift_end_state failed, %d", status);
break;
}
status = JTAG_shift(jtag_handler, num_of_bits,
MAX_DATA_SIZE - packet.used + num_of_bytes + 1,
data_ptr, MAX_DATA_SIZE-response_cnt,
(unsigned char*)&(out_msg.buffer[response_cnt]),
end_state);
if(status != ST_OK) {
ASD_log(LogType_Error, "JTAG_shift failed, %d", status);
break;
}
response_cnt += num_of_bytes;
} else {
// Unknown Command
ASD_log(LogType_Error, "Encountered unknown command 0x%02x", (int)cmd);
status = ST_ERR;
break;
}
}
if (status == ST_OK) {
memcpy(&out_msg.header, &s_message->header, sizeof(struct message_header));
out_msg.header.size_lsb = response_cnt & 0xFF;
out_msg.header.size_msb = (response_cnt >> 8) & 0x1F;
out_msg.header.cmd_stat = ASD_SUCCESS;
status = send_out_msg_on_socket(&out_msg);
if (status != ST_OK) {
ASD_log(LogType_Error | LogType_NoRemote, "Failed to send message back on the socket");
}
} else {
// Send error code to client
extnet_conn_t authd_conn;
if (session_get_authenticated_conn(&authd_conn) != ST_OK) {
send_error_message(&authd_conn, s_message, ASD_UNKNOWN_ERROR);
}
}
return status;
}