[adiv5] Improvements in ADIv5
* Reference latest version of the ARM specification * ROM tables - more debug information, including printing SYSMEM bit * MEM-AP - reject when Debug Base Address entry is not present/invalid. These would only have errored in adiv5_component_probe. * Fix maximum number of entries in Class 0x1 ROM Table to 960. See ARM IHI 0031E Table D3-1 ROM Table register summary. * Resolve note in STM32H7 driver with explaination blackmagic PR #474
This commit is contained in:
parent
703f88a969
commit
61e9607594
@ -18,8 +18,10 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* This file implements the transport generic functions of the
|
/* This file implements the transport generic functions.
|
||||||
* ARM Debug Interface v5 Architecure Specification, ARM doc IHI0031A.
|
* See the following ARM Reference Documents:
|
||||||
|
*
|
||||||
|
* ARM Debug Interface v5 Architecure Specification, ARM IHI 0031E
|
||||||
*/
|
*/
|
||||||
#include "general.h"
|
#include "general.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
@ -287,8 +289,22 @@ static bool adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr)
|
|||||||
/* Extract Component ID class nibble */
|
/* Extract Component ID class nibble */
|
||||||
uint32_t cid_class = (cidr & CID_CLASS_MASK) >> CID_CLASS_SHIFT;
|
uint32_t cid_class = (cidr & CID_CLASS_MASK) >> CID_CLASS_SHIFT;
|
||||||
|
|
||||||
if (cid_class == cidc_romtab) { /* ROM table, probe recursively */
|
/* ROM table */
|
||||||
for (int i = 0; i < 256; i++) {
|
if (cid_class == cidc_romtab) {
|
||||||
|
/* Check SYSMEM bit */
|
||||||
|
#ifdef ENABLE_DEBUG
|
||||||
|
uint32_t memtype = adiv5_mem_read32(ap, addr | ADIV5_ROM_MEMTYPE) &
|
||||||
|
ADIV5_ROM_MEMTYPE_SYSMEM;
|
||||||
|
|
||||||
|
if (adiv5_dp_error(ap->dp)) {
|
||||||
|
DEBUG("Fault reading ROM table entry\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG("\nROM: Table BASE=0x%"PRIx32" SYSMEM=0x%"PRIx32"\n",
|
||||||
|
addr, memtype);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (int i = 0; i < 960; i++) {
|
||||||
uint32_t entry = adiv5_mem_read32(ap, addr + i*4);
|
uint32_t entry = adiv5_mem_read32(ap, addr + i*4);
|
||||||
if (adiv5_dp_error(ap->dp)) {
|
if (adiv5_dp_error(ap->dp)) {
|
||||||
DEBUG("Fault reading ROM table entry\n");
|
DEBUG("Fault reading ROM table entry\n");
|
||||||
@ -297,11 +313,19 @@ static bool adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr)
|
|||||||
if (entry == 0)
|
if (entry == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if ((entry & 1) == 0)
|
if (!(entry & ADIV5_ROM_ROMENTRY_PRESENT)) {
|
||||||
|
DEBUG("%d Entry 0x%"PRIx32" -> Not present\n", i, entry);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
res |= adiv5_component_probe(ap, addr + (entry & ~0xfff));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEBUG("%d Entry 0x%"PRIx32" -> 0x%"PRIx32"\n",
|
||||||
|
i, entry, addr + (entry & ADIV5_ROM_ROMENTRY_OFFSET));
|
||||||
|
|
||||||
|
/* Probe recursively */
|
||||||
|
res |= adiv5_component_probe(ap,
|
||||||
|
addr + (entry & ADIV5_ROM_ROMENTRY_OFFSET));
|
||||||
|
}
|
||||||
|
DEBUG("ROM: Table END\n\n");
|
||||||
} else {
|
} else {
|
||||||
/* Check if the component was designed by ARM, we currently do not support,
|
/* Check if the component was designed by ARM, we currently do not support,
|
||||||
* any components by other designers.
|
* any components by other designers.
|
||||||
@ -320,10 +344,10 @@ static bool adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr)
|
|||||||
int i;
|
int i;
|
||||||
for (i = 0; pidr_pn_bits[i].arch != aa_end; i++) {
|
for (i = 0; pidr_pn_bits[i].arch != aa_end; i++) {
|
||||||
if (pidr_pn_bits[i].part_number == part_number) {
|
if (pidr_pn_bits[i].part_number == part_number) {
|
||||||
DEBUG("0x%"PRIx32": %s - %s %s\n", addr,
|
DEBUG("0x%"PRIx32": %s - %s %s (PIDR = 0x%"PRIx64")\n", addr,
|
||||||
cidc_debug_strings[cid_class],
|
cidc_debug_strings[cid_class],
|
||||||
pidr_pn_bits[i].type,
|
pidr_pn_bits[i].type,
|
||||||
pidr_pn_bits[i].full);
|
pidr_pn_bits[i].full, pidr);
|
||||||
/* Perform sanity check, if we know what to expect as component ID
|
/* Perform sanity check, if we know what to expect as component ID
|
||||||
* class.
|
* class.
|
||||||
*/
|
*/
|
||||||
@ -366,8 +390,9 @@ ADIv5_AP_t *adiv5_new_ap(ADIv5_DP_t *dp, uint8_t apsel)
|
|||||||
tmpap.dp = dp;
|
tmpap.dp = dp;
|
||||||
tmpap.apsel = apsel;
|
tmpap.apsel = apsel;
|
||||||
tmpap.idr = adiv5_ap_read(&tmpap, ADIV5_AP_IDR);
|
tmpap.idr = adiv5_ap_read(&tmpap, ADIV5_AP_IDR);
|
||||||
|
tmpap.base = adiv5_ap_read(&tmpap, ADIV5_AP_BASE);
|
||||||
|
|
||||||
if(!tmpap.idr) /* IDR Invalid - Should we not continue here? */
|
if(!tmpap.idr) /* IDR Invalid */
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* It's valid to so create a heap copy */
|
/* It's valid to so create a heap copy */
|
||||||
@ -459,7 +484,11 @@ void adiv5_dp_init(ADIv5_DP_t *dp)
|
|||||||
extern void nrf51_mdm_probe(ADIv5_AP_t *);
|
extern void nrf51_mdm_probe(ADIv5_AP_t *);
|
||||||
nrf51_mdm_probe(ap);
|
nrf51_mdm_probe(ap);
|
||||||
|
|
||||||
if (ap->base == 0xffffffff) {
|
/* Check the Debug Base Address register. See ADIv5
|
||||||
|
* Specification C2.6.1 */
|
||||||
|
if (!(ap->base & ADIV5_AP_BASE_PRESENT) ||
|
||||||
|
(ap->base == 0xffffffff)) {
|
||||||
|
/* Debug Base Address not present in this MEM-AP */
|
||||||
/* No debug entries... useless AP */
|
/* No debug entries... useless AP */
|
||||||
adiv5_ap_unref(ap);
|
adiv5_ap_unref(ap);
|
||||||
continue;
|
continue;
|
||||||
|
@ -106,6 +106,18 @@
|
|||||||
#define ADIV5_AP_CSW_SIZE_WORD (2u << 0)
|
#define ADIV5_AP_CSW_SIZE_WORD (2u << 0)
|
||||||
#define ADIV5_AP_CSW_SIZE_MASK (7u << 0)
|
#define ADIV5_AP_CSW_SIZE_MASK (7u << 0)
|
||||||
|
|
||||||
|
/* AP Debug Base Address Register (BASE) */
|
||||||
|
#define ADIV5_AP_BASE_BASEADDR (0xFFFFF000u)
|
||||||
|
#define ADIV5_AP_BASE_PRESENT (1u << 0)
|
||||||
|
|
||||||
|
|
||||||
|
/* ADIv5 Class 0x1 ROM Table Registers */
|
||||||
|
#define ADIV5_ROM_MEMTYPE 0xFCC
|
||||||
|
#define ADIV5_ROM_MEMTYPE_SYSMEM (1u << 0)
|
||||||
|
#define ADIV5_ROM_ROMENTRY_PRESENT (1u << 0)
|
||||||
|
#define ADIV5_ROM_ROMENTRY_OFFSET (0xFFFFF000u)
|
||||||
|
|
||||||
|
|
||||||
/* Constants to make RnW parameters more clear in code */
|
/* Constants to make RnW parameters more clear in code */
|
||||||
#define ADIV5_LOW_WRITE 0
|
#define ADIV5_LOW_WRITE 0
|
||||||
#define ADIV5_LOW_READ 1
|
#define ADIV5_LOW_READ 1
|
||||||
@ -190,4 +202,3 @@ void adiv5_mem_write_sized(ADIv5_AP_t *ap, uint32_t dest, const void *src,
|
|||||||
size_t len, enum align align);
|
size_t len, enum align align);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -129,7 +129,8 @@ enum stm32h7_regs
|
|||||||
#define OPTKEY2 0x4C5D6E7F
|
#define OPTKEY2 0x4C5D6E7F
|
||||||
|
|
||||||
#define DBGMCU_IDCODE 0x5c001000
|
#define DBGMCU_IDCODE 0x5c001000
|
||||||
/* Access via 0xe00e1000 does not show device! */
|
/* Access from processor address space.
|
||||||
|
* Access via the APB-D is at 0xe00e1000 */
|
||||||
#define DBGMCU_IDC (DBGMCU_IDCODE + 0)
|
#define DBGMCU_IDC (DBGMCU_IDCODE + 0)
|
||||||
#define DBGMCU_CR (DBGMCU_IDCODE + 4)
|
#define DBGMCU_CR (DBGMCU_IDCODE + 4)
|
||||||
#define DBGSLEEP_D1 (1 << 0)
|
#define DBGSLEEP_D1 (1 << 0)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user