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;
}
Beispiel #2
0
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;
}