Correctly parse dmcontrol.

Change-Id: Ibae425f4ccbe9e504c41e185f264f667e091fca4
This commit is contained in:
Tim Newsome 2017-02-08 19:47:34 -08:00
parent 8af4a9a053
commit 8cac7d0cee
1 changed files with 28 additions and 50 deletions

View File

@ -20,6 +20,7 @@
#include "breakpoints.h" #include "breakpoints.h"
#include "helper/time_support.h" #include "helper/time_support.h"
#include "riscv.h" #include "riscv.h"
#include "debug_defines.h"
/** /**
* Since almost everything can be accomplish by scanning the dbus register, all * Since almost everything can be accomplish by scanning the dbus register, all
@ -88,12 +89,6 @@
/*** JTAG registers. ***/ /*** JTAG registers. ***/
#define DTMCONTROL 0x10
#define DTMCONTROL_DBUS_RESET (1<<16)
#define DTMCONTROL_IDLE (7<<10)
#define DTMCONTROL_ADDRBITS (0xf<<4)
#define DTMCONTROL_VERSION (0xf)
#define DBUS 0x11 #define DBUS 0x11
#define DBUS_OP_START 0 #define DBUS_OP_START 0
#define DBUS_OP_SIZE 2 #define DBUS_OP_SIZE 2
@ -136,20 +131,6 @@ typedef enum slot {
#define DMCONTROL_NDRESET (1<<1) #define DMCONTROL_NDRESET (1<<1)
#define DMCONTROL_FULLRESET 1 #define DMCONTROL_FULLRESET 1
#define DMINFO 0x11
#define DMINFO_ABUSSIZE (0x7fU<<25)
#define DMINFO_SERIALCOUNT (0xf<<21)
#define DMINFO_ACCESS128 (1<<20)
#define DMINFO_ACCESS64 (1<<19)
#define DMINFO_ACCESS32 (1<<18)
#define DMINFO_ACCESS16 (1<<17)
#define DMINFO_ACCESS8 (1<<16)
#define DMINFO_DRAMSIZE (0x3f<<10)
#define DMINFO_AUTHENTICATED (1<<5)
#define DMINFO_AUTHBUSY (1<<4)
#define DMINFO_AUTHTYPE (3<<2)
#define DMINFO_VERSION 3
/*** Info about the core being debugged. ***/ /*** Info about the core being debugged. ***/
#define DBUS_ADDRESS_UNKNOWN 0xffff #define DBUS_ADDRESS_UNKNOWN 0xffff
@ -192,7 +173,7 @@ typedef struct {
/* Number of address bits in the dbus register. */ /* Number of address bits in the dbus register. */
uint8_t addrbits; uint8_t addrbits;
/* Number of words in Debug RAM. */ /* Number of words in Debug RAM. */
unsigned int dramsize; unsigned int dramsize; // TODO: remove
uint64_t dcsr; uint64_t dcsr;
uint64_t dpc; uint64_t dpc;
uint64_t misa; uint64_t misa;
@ -366,7 +347,7 @@ static void increase_dbus_busy_delay(struct target *target)
info->dtmcontrol_idle, info->dbus_busy_delay, info->dtmcontrol_idle, info->dbus_busy_delay,
info->interrupt_high_delay); info->interrupt_high_delay);
dtmcontrol_scan(target, DTMCONTROL_DBUS_RESET); dtmcontrol_scan(target, DTM_DTMCONTROL_DBUSRESET);
} }
static void increase_interrupt_high_delay(struct target *target) static void increase_interrupt_high_delay(struct target *target)
@ -493,7 +474,7 @@ static uint64_t dbus_read(struct target *target, uint16_t address)
if (status == DBUS_STATUS_BUSY) { if (status == DBUS_STATUS_BUSY) {
increase_dbus_busy_delay(target); increase_dbus_busy_delay(target);
} }
} while (((status == DBUS_STATUS_BUSY) || (address_in != address)) && } while (((status != DBUS_STATUS_SUCCESS) || (address_in != address)) &&
i++ < 256); i++ < 256);
if (status != DBUS_STATUS_SUCCESS) { if (status != DBUS_STATUS_SUCCESS) {
@ -1795,22 +1776,24 @@ static int examine(struct target *target)
uint32_t dtmcontrol = dtmcontrol_scan(target, 0); uint32_t dtmcontrol = dtmcontrol_scan(target, 0);
LOG_DEBUG("dtmcontrol=0x%x", dtmcontrol); LOG_DEBUG("dtmcontrol=0x%x", dtmcontrol);
LOG_DEBUG(" addrbits=%d", get_field(dtmcontrol, DTMCONTROL_ADDRBITS)); LOG_DEBUG(" dbusreset=%d", get_field(dtmcontrol, DTM_DTMCONTROL_DBUSRESET));
LOG_DEBUG(" version=%d", get_field(dtmcontrol, DTMCONTROL_VERSION)); LOG_DEBUG(" idle=%d", get_field(dtmcontrol, DTM_DTMCONTROL_IDLE));
LOG_DEBUG(" idle=%d", get_field(dtmcontrol, DTMCONTROL_IDLE)); LOG_DEBUG(" dbusstat=%d", get_field(dtmcontrol, DTM_DTMCONTROL_DBUSSTAT));
LOG_DEBUG(" abits=%d", get_field(dtmcontrol, DTM_DTMCONTROL_ABITS));
LOG_DEBUG(" version=%d", get_field(dtmcontrol, DTM_DTMCONTROL_VERSION));
if (dtmcontrol == 0) { if (dtmcontrol == 0) {
LOG_ERROR("dtmcontrol is 0. Check JTAG connectivity/board power."); LOG_ERROR("dtmcontrol is 0. Check JTAG connectivity/board power.");
return ERROR_FAIL; return ERROR_FAIL;
} }
if (get_field(dtmcontrol, DTMCONTROL_VERSION) != 1) { if (get_field(dtmcontrol, DTM_DTMCONTROL_VERSION) != 1) {
LOG_ERROR("Unsupported DTM version %d. (dtmcontrol=0x%x)", LOG_ERROR("Unsupported DTM version %d. (dtmcontrol=0x%x)",
get_field(dtmcontrol, DTMCONTROL_VERSION), dtmcontrol); get_field(dtmcontrol, DTM_DTMCONTROL_VERSION), dtmcontrol);
return ERROR_FAIL; return ERROR_FAIL;
} }
riscv013_info_t *info = get_info(target); riscv013_info_t *info = get_info(target);
info->addrbits = get_field(dtmcontrol, DTMCONTROL_ADDRBITS); info->addrbits = get_field(dtmcontrol, DTM_DTMCONTROL_ABITS);
info->dtmcontrol_idle = get_field(dtmcontrol, DTMCONTROL_IDLE); info->dtmcontrol_idle = get_field(dtmcontrol, DTM_DTMCONTROL_IDLE);
if (info->dtmcontrol_idle == 0) { if (info->dtmcontrol_idle == 0) {
// Some old SiFive cores don't set idle but need it to be 1. // Some old SiFive cores don't set idle but need it to be 1.
uint32_t idcode = idcode_scan(target); uint32_t idcode = idcode_scan(target);
@ -1818,32 +1801,27 @@ static int examine(struct target *target)
info->dtmcontrol_idle = 1; info->dtmcontrol_idle = 1;
} }
uint32_t dminfo = dbus_read(target, DMINFO); uint32_t dmcontrol = dbus_read(target, DMI_DMCONTROL);
LOG_DEBUG("dminfo: 0x%08x", dminfo); LOG_DEBUG("dmcontrol: 0x%08x", dmcontrol);
LOG_DEBUG(" abussize=0x%x", get_field(dminfo, DMINFO_ABUSSIZE)); LOG_DEBUG(" halt=%d", get_field(dmcontrol, DMI_DMCONTROL_HALT));
LOG_DEBUG(" serialcount=0x%x", get_field(dminfo, DMINFO_SERIALCOUNT)); LOG_DEBUG(" reset=%d", get_field(dmcontrol, DMI_DMCONTROL_RESET));
LOG_DEBUG(" access128=%d", get_field(dminfo, DMINFO_ACCESS128)); LOG_DEBUG(" dmactive=%d", get_field(dmcontrol, DMI_DMCONTROL_DMACTIVE));
LOG_DEBUG(" access64=%d", get_field(dminfo, DMINFO_ACCESS64)); LOG_DEBUG(" hartid=0x%x", get_field(dmcontrol, DMI_DMCONTROL_HARTID));
LOG_DEBUG(" access32=%d", get_field(dminfo, DMINFO_ACCESS32)); LOG_DEBUG(" haltsum=%d", get_field(dmcontrol, DMI_DMCONTROL_HALTSUM));
LOG_DEBUG(" access16=%d", get_field(dminfo, DMINFO_ACCESS16)); LOG_DEBUG(" authenticated=%d", get_field(dmcontrol, DMI_DMCONTROL_AUTHENTICATED));
LOG_DEBUG(" access8=%d", get_field(dminfo, DMINFO_ACCESS8)); LOG_DEBUG(" authbusy=%d", get_field(dmcontrol, DMI_DMCONTROL_AUTHBUSY));
LOG_DEBUG(" dramsize=0x%x", get_field(dminfo, DMINFO_DRAMSIZE)); LOG_DEBUG(" authtype=%d", get_field(dmcontrol, DMI_DMCONTROL_AUTHTYPE));
LOG_DEBUG(" authenticated=0x%x", get_field(dminfo, DMINFO_AUTHENTICATED)); LOG_DEBUG(" version=%d", get_field(dmcontrol, DMI_DMCONTROL_VERSION));
LOG_DEBUG(" authbusy=0x%x", get_field(dminfo, DMINFO_AUTHBUSY));
LOG_DEBUG(" authtype=0x%x", get_field(dminfo, DMINFO_AUTHTYPE));
LOG_DEBUG(" version=0x%x", get_field(dminfo, DMINFO_VERSION));
if (get_field(dminfo, DMINFO_VERSION) != 1) { if (get_field(dmcontrol, DMI_DMCONTROL_VERSION) != 1) {
LOG_ERROR("OpenOCD only supports Debug Module version 1, not %d " LOG_ERROR("OpenOCD only supports Debug Module version 1, not %d "
"(dminfo=0x%x)", get_field(dminfo, DMINFO_VERSION), dminfo); "(dmcontrol=0x%x)", get_field(dmcontrol, DMI_DMCONTROL_VERSION), dmcontrol);
return ERROR_FAIL; return ERROR_FAIL;
} }
info->dramsize = get_field(dminfo, DMINFO_DRAMSIZE) + 1; if (!get_field(dmcontrol, DMI_DMCONTROL_AUTHENTICATED)) {
if (get_field(dminfo, DMINFO_AUTHTYPE) != 0) {
LOG_ERROR("Authentication required by RISC-V core but not " LOG_ERROR("Authentication required by RISC-V core but not "
"supported by OpenOCD. dminfo=0x%x", dminfo); "supported by OpenOCD. dmcontrol=0x%x", dmcontrol);
return ERROR_FAIL; return ERROR_FAIL;
} }