+static int hl_dcc_read(struct hl_interface_s *hl_if, uint8_t *value, uint8_t *ctrl)
+{
+ uint16_t dcrdr;
+ int retval = hl_if->layout->api->read_mem(hl_if->handle,
+ DCB_DCRDR, 1, sizeof(dcrdr), (uint8_t *)&dcrdr);
+ if (retval == ERROR_OK) {
+ *ctrl = (uint8_t)dcrdr;
+ *value = (uint8_t)(dcrdr >> 8);
+
+ LOG_DEBUG("data 0x%x ctrl 0x%x", *value, *ctrl);
+
+ if (dcrdr & 1) {
+ /* write ack back to software dcc register
+ * to signify we have read data */
+ /* atomically clear just the byte containing the busy bit */
+ static const uint8_t zero;
+ retval = hl_if->layout->api->write_mem(hl_if->handle, DCB_DCRDR, 1, 1, &zero);
+ }
+ }
+ return retval;
+}
+
+static int hl_target_request_data(struct target *target,
+ uint32_t size, uint8_t *buffer)
+{
+ struct hl_interface_s *hl_if = target_to_adapter(target);
+ uint8_t data;
+ uint8_t ctrl;
+ uint32_t i;
+
+ for (i = 0; i < (size * 4); i++) {
+ int err = hl_dcc_read(hl_if, &data, &ctrl);
+ if (err != ERROR_OK)
+ return err;
+
+ buffer[i] = data;
+ }
+
+ return ERROR_OK;
+}
+
+static int hl_handle_target_request(void *priv)
+{
+ struct target *target = priv;
+ int err;
+
+ if (!target_was_examined(target))
+ return ERROR_OK;
+ struct hl_interface_s *hl_if = target_to_adapter(target);
+
+ if (!target->dbg_msg_enabled)
+ return ERROR_OK;
+
+ if (target->state == TARGET_RUNNING) {
+ uint8_t data;
+ uint8_t ctrl;
+
+ err = hl_dcc_read(hl_if, &data, &ctrl);
+ if (err != ERROR_OK)
+ return err;
+
+ /* check if we have data */
+ if (ctrl & (1 << 0)) {
+ uint32_t request;
+
+ /* we assume target is quick enough */
+ request = data;
+ err = hl_dcc_read(hl_if, &data, &ctrl);
+ if (err != ERROR_OK)
+ return err;
+
+ request |= (data << 8);
+ err = hl_dcc_read(hl_if, &data, &ctrl);
+ if (err != ERROR_OK)
+ return err;
+
+ request |= (data << 16);
+ err = hl_dcc_read(hl_if, &data, &ctrl);
+ if (err != ERROR_OK)
+ return err;
+
+ request |= (data << 24);
+ target_request(target, request);
+ }
+ }
+
+ return ERROR_OK;
+}
+