static bool cortexa_check_error(target *t) { struct cortexa_priv *priv = t->priv; ADIv5_AP_t *ahb = priv->ahb; bool err = (ahb && (adiv5_dp_error(ahb->dp)) != 0) || priv->mmu_fault; priv->mmu_fault = false; return err; }
static bool adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr) { addr &= ~3; uint64_t pidr = 0; uint32_t cidr = 0; bool res = false; /* Assemble logical Product ID register value. */ for (int i = 0; i < 4; i++) { uint32_t x = adiv5_mem_read32(ap, addr + PIDR0_OFFSET + 4*i); pidr |= (x & 0xff) << (i * 8); } { uint32_t x = adiv5_mem_read32(ap, addr + PIDR4_OFFSET); pidr |= (uint64_t)x << 32; } /* Assemble logical Component ID register value. */ for (int i = 0; i < 4; i++) { uint32_t x = adiv5_mem_read32(ap, addr + CIDR0_OFFSET + 4*i); cidr |= ((uint64_t)(x & 0xff)) << (i * 8); } if (adiv5_dp_error(ap->dp)) { DEBUG("Fault reading ID registers\n"); return false; } /* CIDR preamble sanity check */ if ((cidr & ~CID_CLASS_MASK) != CID_PREAMBLE) { DEBUG("0x%"PRIx32": 0x%"PRIx32" <- does not match preamble (0x%X)\n", addr, cidr, CID_PREAMBLE); return false; } /* Extract Component ID class nibble */ uint32_t cid_class = (cidr & CID_CLASS_MASK) >> CID_CLASS_SHIFT; if (cid_class == cidc_romtab) { /* ROM table, probe recursively */ for (int i = 0; i < 256; i++) { uint32_t entry = adiv5_mem_read32(ap, addr + i*4); if (adiv5_dp_error(ap->dp)) { DEBUG("Fault reading ROM table entry\n"); } if (entry == 0) break; if ((entry & 1) == 0) continue; res |= adiv5_component_probe(ap, addr + (entry & ~0xfff)); } } else { /* Check if the component was designed by ARM, we currently do not support, * any components by other designers. */ if ((pidr & ~(PIDR_REV_MASK | PIDR_PN_MASK)) != PIDR_ARM_BITS) { DEBUG("0x%"PRIx32": 0x%"PRIx64" <- does not match ARM JEP-106\n", addr, pidr); return false; } /* Extract part number from the part id register. */ uint16_t part_number = pidr & PIDR_PN_MASK; /* Find the part number in our part list and run the appropriate probe * routine if applicable. */ int i; for (i = 0; pidr_pn_bits[i].arch != aa_end; i++) { if (pidr_pn_bits[i].part_number == part_number) { DEBUG("0x%"PRIx32": %s - %s %s\n", addr, cidc_debug_strings[cid_class], pidr_pn_bits[i].type, pidr_pn_bits[i].full); /* Perform sanity check, if we know what to expect as component ID * class. */ if ((pidr_pn_bits[i].cidc != cidc_unknown) && (cid_class != pidr_pn_bits[i].cidc)) { DEBUG("WARNING: \"%s\" !match expected \"%s\"\n", cidc_debug_strings[cid_class], cidc_debug_strings[pidr_pn_bits[i].cidc]); } res = true; switch (pidr_pn_bits[i].arch) { case aa_cortexm: DEBUG("-> cortexm_probe\n"); cortexm_probe(ap, false); break; default: break; } break; } } if (pidr_pn_bits[i].arch == aa_end) { DEBUG("0x%"PRIx32": %s - Unknown (PIDR = 0x%"PRIx64")\n", addr, cidc_debug_strings[cid_class], pidr); } } return res; }