nkeynes@976 | 1 | #include "utlb.h"
|
nkeynes@976 | 2 | #include "../lib.h"
|
nkeynes@976 | 3 |
|
nkeynes@976 | 4 | struct utlb_test_case {
|
nkeynes@976 | 5 | const char *name;
|
nkeynes@976 | 6 | uint32_t vma;
|
nkeynes@976 | 7 | uint32_t pma;
|
nkeynes@976 | 8 | int read_exc;
|
nkeynes@976 | 9 | int write_exc;
|
nkeynes@976 | 10 | };
|
nkeynes@976 | 11 |
|
nkeynes@976 | 12 | #define OK 0
|
nkeynes@976 | 13 |
|
nkeynes@976 | 14 | #define MAX_BATCH_ENTRIES 4
|
nkeynes@976 | 15 | #define MAX_BATCH_TESTS 8
|
nkeynes@976 | 16 |
|
nkeynes@976 | 17 | uint32_t dummy;
|
nkeynes@976 | 18 |
|
nkeynes@976 | 19 | #define LOAD(ent,asid,vpn,ppn,mode) load_utlb_entry( ent, vpn, ppn, asid, mode )
|
nkeynes@976 | 20 | #define TEST(name,asid,vma,pma,sr,sw,ur,uw) run_utlb_test_case(name,asid,vma,pma,sr,sw,ur,uw)
|
nkeynes@976 | 21 |
|
nkeynes@976 | 22 | int run_utlb_priv_test( struct utlb_test_case *test );
|
nkeynes@976 | 23 | int run_utlb_user_test( struct utlb_test_case *test );
|
nkeynes@976 | 24 |
|
nkeynes@976 | 25 | int cases_failed;
|
nkeynes@976 | 26 | int cases_run;
|
nkeynes@976 | 27 | int tests_failed;
|
nkeynes@976 | 28 | int tests_run;
|
nkeynes@976 | 29 | int tests_skipped;
|
nkeynes@976 | 30 |
|
nkeynes@976 | 31 | int run_utlb_test_case( const char *name, int asid, unsigned int vma, unsigned int pma,
|
nkeynes@976 | 32 | int sr, int sw, int ur, int uw )
|
nkeynes@976 | 33 | {
|
nkeynes@976 | 34 | char tmp[64];
|
nkeynes@976 | 35 | struct utlb_test_case test = { tmp, vma, pma, sr, sw };
|
nkeynes@976 | 36 | int fails = 0;
|
nkeynes@976 | 37 |
|
nkeynes@976 | 38 | cases_run++;
|
nkeynes@976 | 39 |
|
nkeynes@976 | 40 | set_asid( asid );
|
nkeynes@976 | 41 | if( sr == OTLBMULTIHIT || sw == OTLBMULTIHIT ) {
|
nkeynes@976 | 42 | fprintf( stderr, "%s: Skipping system test (multihit)\n", name );
|
nkeynes@976 | 43 | tests_skipped += 2;
|
nkeynes@976 | 44 | } else {
|
nkeynes@976 | 45 | snprintf(tmp,sizeof(tmp), "%s (System)", name );
|
nkeynes@976 | 46 | tests_run += 2;
|
nkeynes@976 | 47 | fails += run_utlb_priv_test( &test );
|
nkeynes@976 | 48 | }
|
nkeynes@976 | 49 |
|
nkeynes@976 | 50 | if( ur == OTLBMULTIHIT || uw == OTLBMULTIHIT ) {
|
nkeynes@976 | 51 | fprintf( stderr, "%s: Skipping user test '%s' (multihit)\n", name );
|
nkeynes@976 | 52 | tests_skipped += 2;
|
nkeynes@976 | 53 | } else {
|
nkeynes@976 | 54 | snprintf(tmp,sizeof(tmp), "%s (User)", name );
|
nkeynes@976 | 55 | test.read_exc = ur;
|
nkeynes@976 | 56 | test.write_exc = uw;
|
nkeynes@976 | 57 | tests_run += 2;
|
nkeynes@976 | 58 | fails += run_utlb_user_test( &test );
|
nkeynes@976 | 59 | }
|
nkeynes@976 | 60 | if( fails != 0 ) {
|
nkeynes@976 | 61 | cases_failed++;
|
nkeynes@976 | 62 | tests_failed += fails;
|
nkeynes@976 | 63 | }
|
nkeynes@976 | 64 | return fails;
|
nkeynes@976 | 65 | }
|
nkeynes@976 | 66 |
|
nkeynes@976 | 67 | int main()
|
nkeynes@976 | 68 | {
|
nkeynes@976 | 69 | /* Non-TLB behaviour tests */
|
nkeynes@976 | 70 |
|
nkeynes@976 | 71 |
|
nkeynes@976 | 72 | /* TLB tests */
|
nkeynes@976 | 73 | install_utlb_test_handler();
|
nkeynes@976 | 74 | invalidate_tlb();
|
nkeynes@976 | 75 | /* Permanently map the first and last MB of RAM into userspace - without
|
nkeynes@976 | 76 | * this it's a bit hard to actually run any user-mode tests.
|
nkeynes@976 | 77 | */
|
nkeynes@976 | 78 | LOAD(62, 0, 0x0C000000, 0x0C000000, TLB_VALID|TLB_USERMODE|TLB_WRITABLE|TLB_SIZE_1M|TLB_CACHEABLE|TLB_DIRTY|TLB_SHARE);
|
nkeynes@976 | 79 | LOAD(63, 0, 0x0CF00000, 0x0CF00000, TLB_VALID|TLB_USERMODE|TLB_WRITABLE|TLB_SIZE_1M|TLB_CACHEABLE|TLB_DIRTY|TLB_SHARE);
|
nkeynes@976 | 80 | set_tlb_enabled(1);
|
nkeynes@976 | 81 |
|
nkeynes@976 | 82 | /* Test miss */
|
nkeynes@976 | 83 | TEST( "U0", 0, 0x12345008, 0x0c000018, RTLBMISS, WTLBMISS, RTLBMISS, WTLBMISS );
|
nkeynes@976 | 84 | TEST( "P1", 0, 0x8c000018, 0x0c000018, OK, OK, RADDERR, WADDERR );
|
nkeynes@976 | 85 | TEST( "P1", 0, 0xac000018, 0x0c000018, OK, OK, RADDERR, WADDERR );
|
nkeynes@976 | 86 | TEST( "P3", 0, 0xC4345008, 0x0c000018, RTLBMISS, WTLBMISS, RADDERR, WADDERR );
|
nkeynes@976 | 87 |
|
nkeynes@976 | 88 | /* Test flags with 1K pages */
|
nkeynes@976 | 89 | LOAD( 0, 0, 0x12345C00, 0x0C000000, TLB_VALID|TLB_USERMODE|TLB_WRITABLE|TLB_SIZE_1K|TLB_CACHEABLE|TLB_DIRTY );
|
nkeynes@976 | 90 | LOAD( 1, 1, 0x12345C00, 0x0CFFFC00, TLB_VALID|TLB_USERMODE|TLB_WRITABLE|TLB_SIZE_1K|TLB_CACHEABLE|TLB_DIRTY );
|
nkeynes@976 | 91 | LOAD( 2, 0, 0x12345800, 0x0C000800, TLB_VALID|TLB_WRITABLE|TLB_SIZE_1K|TLB_CACHEABLE|TLB_DIRTY );
|
nkeynes@976 | 92 | LOAD( 3, 0, 0x12345400, 0x0C000400, TLB_VALID|TLB_USERMODE|TLB_SIZE_1K|TLB_CACHEABLE|TLB_DIRTY );
|
nkeynes@976 | 93 | LOAD( 4, 0, 0x12345000, 0x0C000000, TLB_VALID|TLB_SIZE_1K|TLB_CACHEABLE|TLB_DIRTY );
|
nkeynes@976 | 94 | LOAD( 5, 1, 0x12345800, 0x0CF01800, TLB_VALID|TLB_USERMODE|TLB_WRITABLE|TLB_SIZE_1K|TLB_CACHEABLE );
|
nkeynes@976 | 95 | LOAD( 6, 1, 0x12346000, 0x0C000000, TLB_VALID|TLB_WRITABLE|TLB_SIZE_1K|TLB_CACHEABLE );
|
nkeynes@976 | 96 | LOAD( 7, 2, 0x12346800, 0x0C000400, TLB_VALID|TLB_USERMODE|TLB_WRITABLE|TLB_SIZE_1K|TLB_CACHEABLE|TLB_SHARE|TLB_DIRTY );
|
nkeynes@976 | 97 | TEST( "1K ASID 0", 0, 0x12345C18, 0x0C000018, OK, OK, OK, OK );
|
nkeynes@976 | 98 | TEST( "1K ASID 1", 1, 0x12345C18, 0x0CFFFC18, OK, OK, OK, OK );
|
nkeynes@976 | 99 | TEST( "1K ASID 2", 2, 0x12345C18, 0x0C000018, RTLBMISS, WTLBMISS, RTLBMISS, WTLBMISS );
|
nkeynes@976 | 100 | TEST( "1K PRIV", 0, 0x12345818, 0x0C000818, OK, OK, READPROT, WRITEPROT );
|
nkeynes@976 | 101 | TEST( "1K READONLY", 0, 0x12345418, 0x0C000418, OK, WRITEPROT, OK, WRITEPROT );
|
nkeynes@976 | 102 | TEST( "1K PRIVREAD", 0, 0x12345018, 0x0C000018, OK, WRITEPROT, READPROT, WRITEPROT );
|
nkeynes@976 | 103 | TEST( "1K FIRSTWR", 1, 0x12345818, 0x0CF01818, OK, FIRSTWRITE, OK, FIRSTWRITE );
|
nkeynes@976 | 104 | TEST( "1K PRIVFWR", 1, 0x12346018, 0x0C000018, OK, FIRSTWRITE, READPROT, WRITEPROT );
|
nkeynes@976 | 105 | TEST( "1K MISS", 1, 0x12346418, 0x0C000018, RTLBMISS, WTLBMISS, RTLBMISS, WTLBMISS );
|
nkeynes@976 | 106 | TEST( "1K SHARED 0", 0, 0x12346818, 0x0C000418, OK, OK, OK, OK );
|
nkeynes@976 | 107 | TEST( "1K SHARED 2", 2, 0x12346818, 0x0C000418, OK, OK, OK, OK );
|
nkeynes@976 | 108 |
|
nkeynes@976 | 109 |
|
nkeynes@976 | 110 | uninstall_utlb_test_handler();
|
nkeynes@976 | 111 |
|
nkeynes@976 | 112 |
|
nkeynes@976 | 113 | printf( "--> %d/%d Test cases passed (%d%%)\n", cases_run-cases_failed, cases_run, ( (cases_run-cases_failed)*100/cases_run) );
|
nkeynes@976 | 114 | printf( "--> %d/%d Tests passed (%d%%)\n", tests_run-tests_failed, tests_run, ( (tests_run-tests_failed)*100/tests_run) );
|
nkeynes@976 | 115 |
|
nkeynes@976 | 116 | return cases_failed == 0 ? 0 : 1;
|
nkeynes@976 | 117 | }
|