1
0
Files
2022-09-29 17:59:04 +03:00

171 lines
5.4 KiB
C

#ident "IP22diags/pon/pon_caches.c: $Revision: 1.2 $"
#include "sys/cpu.h"
#include "sys/sbd.h"
#include "sys/types.h"
/*
* pon_caches: verify minimal functionality of the caches
*
* checks for:
* stuck data lines
* shorted data lines
* stuck address lines
* shorted address lines
* basic spill/fill functionality
*
* verify that we can walk ones and zeros across the
* entire width of each cache bank, that we can walk
* ones and zeros across the width of the address lines
* to each cache ram, and that we can select cache
* banks properly.
*/
typedef unsigned short cdata_t; /* interesting data size for cache tests */
#define CACHE_BANK 0x080000 /* banks are at least half a megabyte */
#define CACHE_SIZE 0x400000 /* caches are at most four megabytes */
#define CACHE_WIDE (256/(8 * sizeof (cdata_t))) /* data paths are up to 256 bits wide */
#define CACHE_MAXIX (CACHE_SIZE/(sizeof (cdata_t)))
#define BANK_MAXIX (CACHE_BANK/(sizeof (cdata_t)))
#define MEMORY_ARENA_OFFSET 0xC00000 /* memory offset we can scribble on */
#define MEMORY_ARENA_ADDR (K0_RAMBASE + 0xC00000)
static void
report_cache_error(cdata_t addr, unsigned exp, unsigned act, char *tname)
{
uncache_K0();
puts(tname);
cache_K0();
}
#define EXPECT(base, index, expr, tname) \
{ \
cdata_t *addr = (cdata_t *)((base)+(index)); \
cdata_t exp = (expr); \
cdata_t act = *addr; \
if (exp != act) { \
report_cache_error(addr, exp, act, tname); \
error ++; \
} \
}
volatile cdata_t flush_dummy;
pon_caches()
{
unsigned bank_offset;
volatile cdata_t *bank_ptr;
volatile cdata_t *flush_ptr;
unsigned test_index;
cdata_t test_data;
int i;
int error = 0;
puts("Secondary and primary caches address/data test\n");
cache_K0();
for (bank_offset = 0; bank_offset < CACHE_SIZE; bank_offset += CACHE_BANK) {
bank_ptr = (cdata_t *)(MEMORY_ARENA_ADDR + bank_offset);
flush_ptr = (cdata_t *)((unsigned)bank_ptr ^ CACHE_SIZE);
/* CACHE RAM DATA AND SPILL/FILL TESTS */
for (test_index = 0; test_index < CACHE_WIDE; ++test_index) {
for (test_data = 1; test_data != 0; test_data <<= 1) {
/* Walking Data Ones tests */
for (i=0; i<CACHE_WIDE; i++)
bank_ptr[i] = 0; /* - clear across the data lines */
bank_ptr[test_index] = test_data; /* - write a single bit to "1" */
for (i=0; i<CACHE_WIDE; i++)
if (i != test_index) /* - verify the data */
EXPECT(bank_ptr, i, 0, "d1");
EXPECT(bank_ptr, test_index, test_data, "d2");
flush_dummy = flush_ptr[test_index]; /* - force the data to memory */
for (i=0; i<CACHE_WIDE; i++)
if (i != test_index) /* - verify the data */
EXPECT(bank_ptr, i, 0, "d3");
EXPECT(bank_ptr, test_index, test_data, "d4");
/* Walking Data Zeros tests */
for (i=0; i<CACHE_WIDE; i++)
bank_ptr[i] = ~0; /* - fill across the data lines */
bank_ptr[test_index] = ~test_data; /* - write a single bit to "0" */
for (i=0; i<CACHE_WIDE; i++)
if (i != test_index) /* - verify the data */
EXPECT(bank_ptr, i, ~0, "d5");
EXPECT(bank_ptr, test_index, ~test_data, "d6");
flush_dummy = flush_ptr[test_index]; /* - force the data to memory */
for (i=0; i<CACHE_WIDE; i++)
if (i != test_index) /* - verify the data */
EXPECT(bank_ptr, i, ~0, "d7");
EXPECT(bank_ptr, test_index, ~test_data, "d8");
}
}
/* CACHE RAM BANK ADDRESSING TESTS */
/* walk a "1" across the index lines, writing distinct data */
test_data = 0x10;
test_index = 0;
for (i=0; i<CACHE_WIDE; ++i)
bank_ptr[test_index+i] = test_data++;
for (test_index = CACHE_WIDE;
test_index < BANK_MAXIX;
test_index <<= 1) {
for (i=0; i<CACHE_WIDE; ++i)
bank_ptr[test_index+i] = test_data++;
}
/* Verify that the data looks OK */
test_data = 0x10;
test_index = 0;
for (i=0; i<CACHE_WIDE; ++i)
EXPECT(bank_ptr, test_index+i, test_data++, "a1");
for (test_index = CACHE_WIDE;
test_index < BANK_MAXIX;
test_index <<= 1) {
for (i=0; i<CACHE_WIDE; ++i)
EXPECT(bank_ptr, test_index+i, test_data++, "a2");
}
/* walk a "0" across the index lines, writing distinct data */
test_data = 0x10;
for (test_index = CACHE_WIDE;
test_index < BANK_MAXIX;
test_index <<= 1) {
for (i=0; i<CACHE_WIDE; ++i)
bank_ptr[BANK_MAXIX-test_index+i] = test_data++;
}
test_index = BANK_MAXIX;
for (i=0; i<CACHE_WIDE; ++i)
bank_ptr[BANK_MAXIX-test_index+i] = test_data++;
/* Verify that the data looks OK */
test_data = 0x10;
for (test_index = CACHE_WIDE;
test_index < BANK_MAXIX;
test_index <<= 1) {
for (i=0; i<CACHE_WIDE; ++i)
EXPECT(bank_ptr, BANK_MAXIX-test_index+i, test_data++, "a3");
}
test_index = BANK_MAXIX;
for (i=0; i<CACHE_WIDE; ++i)
EXPECT(bank_ptr, BANK_MAXIX-test_index+i, test_data++, "a4");
}
/* CACHE RAM INTER-BANK ADDRESSING TESTS */
bank_ptr = (cdata_t *)(MEMORY_ARENA_ADDR);
/* write distinct data at the start of each bank */
test_data = 0x10;
for (test_index = 0; test_index < CACHE_MAXIX; test_index += BANK_MAXIX)
for (i=0; i<CACHE_WIDE; ++i)
bank_ptr[test_index+i] = test_data++;
/* Verify that the data looks OK */
test_data = 0x10;
for (test_index = 0; test_index < CACHE_MAXIX; test_index += BANK_MAXIX)
for (i=0; i<CACHE_WIDE; ++i)
EXPECT(bank_ptr, test_index+i, test_data++, "a5");
puts("9");
/*cache_init();*/
flush_cache2();
/*uncache_K0();*/
puts("a");
return(0);
}