Line 82... |
Line 82... |
# error Processor has no data MMU. Cannot run this test without it.
|
# error Processor has no data MMU. Cannot run this test without it.
|
# error
|
# error
|
#endif
|
#endif
|
|
|
|
|
// Reduce the number of sets tested
|
// Define to run only tests on SHORT_TEST_NUM TLB sets
|
#define SHORT_TEST
|
#define SHORT_TEST
|
|
#define SHORT_TEST_NUM 4
|
|
|
|
// Defines useful when wishing to skip instruction or data MMU tests when doing
|
|
// development on one or the other.
|
|
|
|
// Set this to 1 to enable the IMMU tests
|
|
#define DO_IMMU_TESTS 1
|
// Set this to 1 to enable the DMMU tests
|
// Set this to 1 to enable the DMMU tests
|
#define DO_DMMU_TESTS 1
|
#define DO_DMMU_TESTS 1
|
|
|
// Symbols defined in linker script
|
// Symbols defined in linker script
|
extern unsigned long _endtext;
|
extern unsigned long _endtext;
|
Line 945... |
Line 951... |
*/
|
*/
|
int dtlb_dcache_test (int set)
|
int dtlb_dcache_test (int set)
|
{
|
{
|
int i, j;
|
int i, j;
|
unsigned long ea, ta, vmea;
|
unsigned long ea, ta, vmea;
|
|
unsigned long testwrite_to_be_cached, testwrite_not_to_be_cached;
|
|
|
|
// This test can't be run if set==DTLB_SETS-1
|
|
if (set==(DTLB_SETS-1))
|
|
return 0;
|
|
|
// Check data cache is present and enabled
|
// Check data cache is present and enabled
|
if (!(mfspr(SPR_UPR)& SPR_UPR_DCP))
|
if (!(mfspr(SPR_UPR)& SPR_UPR_DCP))
|
return 0;
|
return 0;
|
|
|
Line 974... |
Line 985... |
ta = RAM_START + (i*PAGE_SIZE);
|
ta = RAM_START + (i*PAGE_SIZE);
|
mtspr (SPR_DTLBMR_BASE(0) + i, ea | SPR_DTLBMR_V);
|
mtspr (SPR_DTLBMR_BASE(0) + i, ea | SPR_DTLBMR_V);
|
mtspr (SPR_DTLBTR_BASE(0) + i, ta | DTLB_PR_NOLIMIT);
|
mtspr (SPR_DTLBTR_BASE(0) + i, ta | DTLB_PR_NOLIMIT);
|
}
|
}
|
|
|
|
/* Use (RAM_START + (RAM_SIZE/2)) as location we'll poke via MMUs */
|
|
/* Configure a 1-1 mapping for it, and a high->low mapping for it */
|
|
|
/* Testing page */
|
/* Testing page */
|
ea = RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE);
|
ea = RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE);
|
|
|
|
/* Ultimate physical address */
|
ta = RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE);
|
ta = RAM_START + (RAM_SIZE/2) + (set*PAGE_SIZE);
|
|
|
|
/* Set a virtual address to translate via last TLB cache set */
|
vmea = VM_BASE + RAM_START + (RAM_SIZE/2) + ((DTLB_SETS-1)*PAGE_SIZE);
|
vmea = VM_BASE + RAM_START + (RAM_SIZE/2) + ((DTLB_SETS-1)*PAGE_SIZE);
|
|
|
// Set a 1-1 translation for this page without cache inhibited
|
// Set a 1-1 translation for this page without cache inhibited
|
|
|
/* Set match register */
|
/* Set match register */
|
mtspr (SPR_DTLBMR_BASE(0) + set, ea | SPR_DTLBMR_V);
|
mtspr (SPR_DTLBMR_BASE(0) + set, ea | SPR_DTLBMR_V);
|
/* Set translate register */
|
/* Set translate register */
|
mtspr (SPR_DTLBTR_BASE(0) + set, ta | DTLB_PR_NOLIMIT);
|
mtspr (SPR_DTLBTR_BASE(0) + set, ta | DTLB_PR_NOLIMIT);
|
|
|
// Now set a far-off translation, VM_BASE, for this page with cache inhibited
|
/* Now set a far-off translation, VM_BASE, for this page with cache
|
// Use the last set
|
using the last set */
|
|
|
/* Set match register */
|
/* Set match register */
|
mtspr (SPR_DTLBMR_BASE(0) + (DTLB_SETS-1),
|
mtspr (SPR_DTLBMR_BASE(0) + (DTLB_SETS-1), vmea | SPR_DTLBMR_V);
|
vmea | SPR_DTLBMR_V);
|
|
/* Set translate register */
|
/* Set translate register */
|
mtspr (SPR_DTLBTR_BASE(0) + (DTLB_SETS-1),
|
mtspr (SPR_DTLBTR_BASE(0) + (DTLB_SETS-1), ta | DTLB_PR_NOLIMIT |
|
ta | DTLB_PR_NOLIMIT | SPR_DTLBTR_CI);
|
SPR_DTLBTR_CI);
|
|
|
|
/* Invalidate this location in cache, to force reload when we read */
|
|
mtspr (/*SPR_DCR_BASE(0) +*/ SPR_DCBIR, ea);
|
|
|
/* Enable DMMU */
|
/* Enable DMMU */
|
dmmu_enable();
|
dmmu_enable();
|
|
|
// First do a write with the cache inhibited mapping
|
// First do a write with the cache inhibited mapping
|
unsigned long int testwrite_to_be_cached = 0xfeca1d0d ^ set;
|
testwrite_to_be_cached = 0xfeca1d0d ^ set;
|
|
|
REG32((vmea)) = testwrite_to_be_cached;
|
REG32((vmea)) = testwrite_to_be_cached;
|
|
|
// Read it back to check that it's the same, this read should get cached
|
// Read it back to check that it's the same, this read should get cached
|
ASSERT(REG32(ea) == testwrite_to_be_cached);
|
ASSERT(REG32(ea) == testwrite_to_be_cached);
|
|
|
// Now write again to the cache inhibited location
|
// Now write again to the cache inhibited location
|
unsigned long int testwrite_not_to_be_cached = 0xbaadbeef ^ set;
|
testwrite_not_to_be_cached = 0xbaadbeef ^ set;
|
|
|
REG32((vmea)) = testwrite_not_to_be_cached;
|
REG32((vmea)) = testwrite_not_to_be_cached;
|
|
|
// Now check that the cached mapping doesn't read this value back
|
// Now check that the cached mapping doesn't read this value back
|
ASSERT(REG32(ea) == testwrite_to_be_cached);
|
ASSERT(REG32(ea) == testwrite_to_be_cached);
|
|
|
// Now disable cache inhibition on the 1-1 mapping
|
// Now disable cache inhibition on the 1-1 mapping
|
/* Set translate register */
|
/* Set translate register */
|
mtspr (SPR_DTLBTR_BASE(0) + set,
|
mtspr (SPR_DTLBTR_BASE(0) + set,
|
ea | DTLB_PR_NOLIMIT | SPR_DTLBTR_CI);
|
ea | DTLB_PR_NOLIMIT | SPR_DTLBTR_CI);
|
|
|
// Check that we now get the second value we wrote
|
// Check that we now get the second value we wrote
|
testwrite_to_be_cached = testwrite_not_to_be_cached;
|
testwrite_to_be_cached = testwrite_not_to_be_cached;
|
|
|
ASSERT(REG32(ea) == testwrite_to_be_cached);
|
ASSERT(REG32(ea) == testwrite_to_be_cached);
|
|
|
/* Disable DMMU */
|
/* Disable DMMU */
|
dmmu_disable();
|
dmmu_disable();
|
|
|
Line 1422... |
Line 1445... |
|
|
int main (void)
|
int main (void)
|
{
|
{
|
int i, j;
|
int i, j;
|
|
|
start_text_addr = (unsigned long*)&_stext;
|
start_text_addr = (unsigned long)&_stext;
|
end_text_addr = (unsigned long*)&_endtext;
|
end_text_addr = (unsigned long)&_endtext;
|
end_data_addr = (unsigned long*)&_stack;
|
end_data_addr = (unsigned long)&_stack;
|
end_data_addr += 4;
|
end_data_addr += 4;
|
|
|
#ifndef TLB_BOTTOM_TEST_PAGE_HARDSET
|
#ifndef TLB_BOTTOM_TEST_PAGE_HARDSET
|
|
/* Set the botom MMU page (and thus TLB set) we'll begin tests at, hopefully
|
|
avoiding pages with program text, data and stack. Determined by
|
|
determining page after one top of stack is on. */
|
TLB_TEXT_SET_NB = TLB_DATA_SET_NB = (end_data_addr+PAGE_SIZE) / PAGE_SIZE;
|
TLB_TEXT_SET_NB = TLB_DATA_SET_NB = (end_data_addr+PAGE_SIZE) / PAGE_SIZE;
|
#endif
|
#endif
|
|
|
#ifdef _UART_H_
|
#ifdef _UART_H_
|
uart_init(DEFAULT_UART);
|
uart_init(DEFAULT_UART);
|
Line 1455... |
Line 1481... |
dtlb_translation_test ();
|
dtlb_translation_test ();
|
|
|
/* Virtual address match test */
|
/* Virtual address match test */
|
for (j = 0; j < DTLB_WAYS; j++) {
|
for (j = 0; j < DTLB_WAYS; j++) {
|
#ifdef SHORT_TEST
|
#ifdef SHORT_TEST
|
for (i = TLB_DATA_SET_NB; i < (TLB_DATA_SET_NB+4 - 1); i++)
|
for (i = TLB_DATA_SET_NB; i < (TLB_DATA_SET_NB + SHORT_TEST_NUM - 1); i++)
|
#else
|
#else
|
for (i = TLB_DATA_SET_NB; i < (DTLB_SETS - 1); i++)
|
for (i = TLB_DATA_SET_NB; i < (DTLB_SETS - 1); i++)
|
#endif
|
#endif
|
dtlb_match_test (j, i);
|
dtlb_match_test (j, i);
|
}
|
}
|
|
|
/* Valid bit testing */
|
/* Valid bit testing */
|
|
|
#ifdef SHORT_TEST
|
#ifdef SHORT_TEST
|
for (i = TLB_DATA_SET_NB; i < (TLB_DATA_SET_NB+4 - 1); i++)
|
for (i = TLB_DATA_SET_NB; i < (TLB_DATA_SET_NB + SHORT_TEST_NUM - 1); i++)
|
#else
|
#else
|
for (i = TLB_DATA_SET_NB; i < (DTLB_SETS - 1); i++)
|
for (i = TLB_DATA_SET_NB; i < (DTLB_SETS - 1); i++)
|
#endif
|
#endif
|
dtlb_valid_bit_test (i);
|
dtlb_valid_bit_test (i);
|
|
|
/* Permission test */
|
/* Permission test */
|
#ifdef SHORT_TEST
|
#ifdef SHORT_TEST
|
for (i = TLB_DATA_SET_NB; i < (TLB_DATA_SET_NB+4 - 1); i++)
|
for (i = TLB_DATA_SET_NB; i < (TLB_DATA_SET_NB + SHORT_TEST_NUM - 1); i++)
|
#else
|
#else
|
for (i = TLB_DATA_SET_NB; i < (DTLB_SETS - 1); i++)
|
for (i = TLB_DATA_SET_NB; i < (DTLB_SETS - 1); i++)
|
#endif
|
#endif
|
dtlb_permission_test (i);
|
dtlb_permission_test (i);
|
|
|
/* Data cache test */
|
/* Data cache test */
|
|
|
#ifndef OR1200_NO_DC
|
#ifndef OR1200_NO_DC
|
#ifdef SHORT_TEST
|
#ifdef SHORT_TEST
|
for (i = TLB_DATA_SET_NB; i < (TLB_DATA_SET_NB+4 - 1); i++)
|
for (i = TLB_DATA_SET_NB; i < (TLB_DATA_SET_NB + SHORT_TEST_NUM - 1); i++)
|
#else
|
#else
|
for (i = TLB_DATA_SET_NB; i < (DTLB_SETS - 2); i++)
|
for (i = TLB_DATA_SET_NB; i < (DTLB_SETS - 2); i++)
|
#endif
|
#endif
|
dtlb_dcache_test (i);
|
dtlb_dcache_test (i);
|
#endif // ifndef OR1200_NO_DC
|
#endif // ifndef OR1200_NO_DC
|
|
|
|
|
#endif
|
#endif
|
|
|
|
#if DO_IMMU_TESTS==1
|
|
|
/* Translation test */
|
/* Translation test */
|
itlb_translation_test ();
|
itlb_translation_test ();
|
|
|
/* Virtual address match test */
|
/* Virtual address match test */
|
|
|
for (j = 0; j < DTLB_WAYS; j++) {
|
for (j = 0; j < DTLB_WAYS; j++) {
|
#ifdef SHORT_TEST
|
#ifdef SHORT_TEST
|
for (i = TLB_DATA_SET_NB + 1; i < (TLB_DATA_SET_NB+4 - 1); i++)
|
for (i = TLB_DATA_SET_NB + 1; i < (TLB_DATA_SET_NB + SHORT_TEST_NUM - 1); i++)
|
#else
|
#else
|
for (i = TLB_DATA_SET_NB + 1; i < (ITLB_SETS - 1); i++)
|
for (i = TLB_DATA_SET_NB + 1; i < (ITLB_SETS - 1); i++)
|
#endif
|
#endif
|
itlb_match_test (j, i);
|
itlb_match_test (j, i);
|
}
|
}
|
|
|
/* Valid bit testing */
|
/* Valid bit testing */
|
#ifdef SHORT_TEST
|
#ifdef SHORT_TEST
|
for (i = TLB_DATA_SET_NB; i < (TLB_DATA_SET_NB+4 - 1); i++)
|
for (i = TLB_DATA_SET_NB; i < (TLB_DATA_SET_NB + SHORT_TEST_NUM - 1); i++)
|
#else
|
#else
|
for (i = TLB_DATA_SET_NB; i < (ITLB_SETS - 1); i++)
|
for (i = TLB_DATA_SET_NB; i < (ITLB_SETS - 1); i++)
|
#endif
|
#endif
|
itlb_valid_bit_test (i);
|
itlb_valid_bit_test (i);
|
|
|
|
|
|
|
/* Permission test */
|
/* Permission test */
|
#ifdef SHORT_TEST
|
#ifdef SHORT_TEST
|
for (i = TLB_TEXT_SET_NB; i < (TLB_TEXT_SET_NB + 4); i++)
|
for (i = TLB_TEXT_SET_NB; i < (TLB_TEXT_SET_NB + SHORT_TEST_NUM); i++)
|
#else
|
#else
|
for (i = TLB_TEXT_SET_NB; i < (ITLB_SETS - 1); i++)
|
for (i = TLB_TEXT_SET_NB; i < (ITLB_SETS - 1); i++)
|
#endif
|
#endif
|
itlb_permission_test (i);
|
itlb_permission_test (i);
|
|
|
|
#endif
|
|
|
printf("Tests completed\n");
|
printf("Tests completed\n");
|
report (0xdeaddead);
|
report (0xdeaddead);
|
report (0x8000000d);
|
report (0x8000000d);
|
exit (0);
|
exit (0);
|