/**
 * \brief Test the address bus
 *
 * Tests the address bus for stuck and coupled lines.
 *
 * The bytes at base and all power-of-two locations are initialized with the
 * value 0x55 before any testing of the address bus is done.
 *
 * The first test of the address bus is for lines that are stuck high. This is
 * done by writing the value 0xAA to the base, then verifying that all
 * power-of-two locations still contain 0x55.
 *
 * The address bus is then checked for lines that are stuck low or coupled. The
 * base location is reinitialized with the value 0x55 before this test. The
 * value 0xAA is then temporarily written to the individual power-of-two
 * locations while the content of the others (base and power-of-two) are
 * verified to still contain 0x55.
 *
 * \param test Current test case.
 */
void run_address_bus_test(const struct test_case *test)
{
	struct ebi_test_params *params;
	hugemem_ptr_t          base;
	uint32_t               size;
	uint32_t               offset;

	params = (struct ebi_test_params *)test_get_data();
	base = params->base;
	size = params->size;

	// Initialize all power-of-two locations with 0x55
	hugemem_write8(base, 0x55);
	for (offset = 1; offset < size; offset <<= 1) {
		hugemem_ptr_t p;

		p = (hugemem_ptr_t)((uint32_t)base + offset);
		hugemem_write8(p, 0x55);
	}

	// Check for address lines stuck high
	hugemem_write8(base, 0xaa);
	for (offset = 1; offset < size; offset <<= 1) {
		hugemem_ptr_t p;
		uint8_t       actual;

		p = (hugemem_ptr_t)((uint32_t)base + offset);
		actual = hugemem_read8(p);
		test_assert_true(test, actual == 0x55,
				"Read 0x%02x @ 0x%08lx, expected 0x55 (stuck "
				"high)",
				actual, (uint32_t)p);
	}

	// Check for address lines stuck low or shorted
	hugemem_write8(base, 0x55);
	for (offset = 1; offset < size; offset <<= 1) {
		hugemem_ptr_t p;
		uint32_t      offset2;
		uint8_t       actual;

		p = (hugemem_ptr_t)((uint32_t)base + offset);
		hugemem_write8(p, 0xaa);

		actual = hugemem_read8(base);
		test_assert_true(test, actual == 0x55,
				"Read 0x%02x @ 0x%08lx after writing 0xaa @ "
				"0x%08lx, expected 0x55 (stuck low or coupled)",
				actual, (uint32_t)base, (uint32_t)p);

		for (offset2 = 1; offset2 < size; offset2 <<= 1) {
			hugemem_ptr_t q;

			if (offset2 == offset)
				continue;

			q = (hugemem_ptr_t)((uint32_t)base + offset2);
			actual = hugemem_read8(q);
			test_assert_true(test, actual == 0x55,
					"Read 0x%02x @ 0x%08lx after writing 0xaa"
					" @ 0x%08lx, expected 0x55 (stuck low or "
					"coupled)",
					actual, (uint32_t)q, (uint32_t)p);
		}

		hugemem_write8(p, 0x55);
	}
}
Example #2
0
/**
 * \brief Test the EBI address bus wired to the SDRAM
 *
 * This function will perform an address bus test to locate any shorts or open
 * leads to the SDRAM device.
 *
 * \param base Base address of the external memory device
 * \param size Size of the external memory device
 *
 * \retval STATUS_OK on success, and \ref status_code_t error code on failure
 */
static status_code_t ebi_test_addr_bus(hugemem_ptr_t base, uint32_t size)
{
	uint32_t        offset;
	uint_fast8_t    i;

	/* Initialize all power-of-two locations with 0x55 */
	hugemem_write8(base, 0x55);
	for (offset = 1; offset < size; offset <<= 1) {
		hugemem_ptr_t   p;

		p = (hugemem_ptr_t)((uint32_t)base + offset);
		hugemem_write8(p, 0x55);
	}

	/* Check for address lines stuck high */
	hugemem_write8(base, 0xaa);
	for (i = 0, offset = 1; offset < size; offset <<= 1, i++) {
		hugemem_ptr_t   p;
		uint8_t         actual;

		p = (hugemem_ptr_t)((uint32_t)base + offset);
		actual = hugemem_read8(p);
		if (actual != 0x55) {
			return ERR_IO_ERROR;
		}
	}

	/* Check for address lines stuck low or shorted */
	hugemem_write8(base, 0x55);
	for (i = 0, offset = 1; offset < size; offset <<= 1, i++) {
		hugemem_ptr_t   p;
		uint32_t        offset2;
		uint_fast8_t    j;
		uint8_t         actual;

		p = (hugemem_ptr_t)((uint32_t)base + offset);
		hugemem_write8(p, 0xaa);

		actual = hugemem_read8(base);
		if (actual != 0x55) {
			return ERR_IO_ERROR;
		}

		for (j = 0, offset2 = 1; offset2 < size; offset2 <<= 1, j++) {
			hugemem_ptr_t   q;

			if (offset2 == offset)
				continue;

			q = (hugemem_ptr_t)((uint32_t)base + offset2);
			actual = hugemem_read8(q);
			if (actual != 0x55) {
				return ERR_IO_ERROR;
			}
		}

		hugemem_write8(p, 0x55);
	}

	return STATUS_OK;
}