qemu/tests/tcg/i386/system/memory.c
<<
>>
Prefs
   1/*
   2 * Memory Test
   3 *
   4 * This is intended to test the softmmu code and ensure we properly
   5 * behave across normal and unaligned accesses across several pages.
   6 * We are not replicating memory tests for stuck bits and other
   7 * hardware level failures but looking for issues with different size
   8 * accesses when:
   9
  10 *
  11 */
  12
  13#include <inttypes.h>
  14#include <minilib.h>
  15
  16#define TEST_SIZE (4096 * 4)  /* 4 pages */
  17
  18static uint8_t test_data[TEST_SIZE];
  19
  20static void pdot(int count)
  21{
  22    if (count % 128 == 0) {
  23        ml_printf(".");
  24    }
  25}
  26
  27
  28/*
  29 * Fill the data with ascending value bytes. As x86 is a LE machine we
  30 * write in ascending order and then read and high byte should either
  31 * be zero or higher than the lower bytes.
  32 */
  33
  34static void init_test_data_u8(void)
  35{
  36    uint8_t count = 0, *ptr = &test_data[0];
  37    int i;
  38
  39    ml_printf("Filling test area with u8:");
  40    for (i = 0; i < TEST_SIZE; i++) {
  41        *ptr++ = count++;
  42        pdot(i);
  43    }
  44    ml_printf("done\n");
  45}
  46
  47static void init_test_data_u16(int offset)
  48{
  49    uint8_t count = 0;
  50    uint16_t word, *ptr = (uint16_t *) &test_data[0];
  51    const int max = (TEST_SIZE - offset) / sizeof(word);
  52    int i;
  53
  54    ml_printf("Filling test area with u16 (offset %d):", offset);
  55
  56    /* Leading zeros */
  57    for (i = 0; i < offset; i++) {
  58        *ptr = 0;
  59    }
  60
  61    ptr = (uint16_t *) &test_data[offset];
  62    for (i = 0; i < max; i++) {
  63        uint8_t high, low;
  64        low = count++;
  65        high = count++;
  66        word = (high << 8) | low;
  67        *ptr++ = word;
  68        pdot(i);
  69    }
  70    ml_printf("done\n");
  71}
  72
  73static void init_test_data_u32(int offset)
  74{
  75    uint8_t count = 0;
  76    uint32_t word, *ptr = (uint32_t *) &test_data[0];
  77    const int max = (TEST_SIZE - offset) / sizeof(word);
  78    int i;
  79
  80    ml_printf("Filling test area with u32 (offset %d):", offset);
  81
  82    /* Leading zeros */
  83    for (i = 0; i < offset; i++) {
  84        *ptr = 0;
  85    }
  86
  87    ptr = (uint32_t *) &test_data[offset];
  88    for (i = 0; i < max; i++) {
  89        uint8_t b1, b2, b3, b4;
  90        b4 = count++;
  91        b3 = count++;
  92        b2 = count++;
  93        b1 = count++;
  94        word = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
  95        *ptr++ = word;
  96        pdot(i);
  97    }
  98    ml_printf("done\n");
  99}
 100
 101
 102static int read_test_data_u16(int offset)
 103{
 104    uint16_t word, *ptr = (uint16_t *)&test_data[offset];
 105    int i;
 106    const int max = (TEST_SIZE - offset) / sizeof(word);
 107
 108    ml_printf("Reading u16 from %#lx (offset %d):", ptr, offset);
 109
 110    for (i = 0; i < max; i++) {
 111        uint8_t high, low;
 112        word = *ptr++;
 113        high = (word >> 8) & 0xff;
 114        low = word & 0xff;
 115        if (high < low && high != 0) {
 116            ml_printf("Error %d < %d\n", high, low);
 117            return 1;
 118        } else {
 119            pdot(i);
 120        }
 121
 122    }
 123    ml_printf("done\n");
 124    return 0;
 125}
 126
 127static int read_test_data_u32(int offset)
 128{
 129    uint32_t word, *ptr = (uint32_t *)&test_data[offset];
 130    int i;
 131    const int max = (TEST_SIZE - offset) / sizeof(word);
 132
 133    ml_printf("Reading u32 from %#lx (offset %d):", ptr, offset);
 134
 135    for (i = 0; i < max; i++) {
 136        uint8_t b1, b2, b3, b4;
 137        word = *ptr++;
 138
 139        b1 = word >> 24 & 0xff;
 140        b2 = word >> 16 & 0xff;
 141        b3 = word >> 8 & 0xff;
 142        b4 = word & 0xff;
 143
 144        if ((b1 < b2 && b1 != 0) ||
 145            (b2 < b3 && b2 != 0) ||
 146            (b3 < b4 && b3 != 0)) {
 147            ml_printf("Error %d, %d, %d, %d", b1, b2, b3, b4);
 148            return 2;
 149        } else {
 150            pdot(i);
 151        }
 152    }
 153    ml_printf("done\n");
 154    return 0;
 155}
 156
 157static int read_test_data_u64(int offset)
 158{
 159    uint64_t word, *ptr = (uint64_t *)&test_data[offset];
 160    int i;
 161    const int max = (TEST_SIZE - offset) / sizeof(word);
 162
 163    ml_printf("Reading u64 from %#lx (offset %d):", ptr, offset);
 164
 165    for (i = 0; i < max; i++) {
 166        uint8_t b1, b2, b3, b4, b5, b6, b7, b8;
 167        word = *ptr++;
 168
 169        b1 = ((uint64_t) (word >> 56)) & 0xff;
 170        b2 = ((uint64_t) (word >> 48)) & 0xff;
 171        b3 = ((uint64_t) (word >> 40)) & 0xff;
 172        b4 = (word >> 32) & 0xff;
 173        b5 = (word >> 24) & 0xff;
 174        b6 = (word >> 16) & 0xff;
 175        b7 = (word >> 8)  & 0xff;
 176        b8 = (word >> 0)  & 0xff;
 177
 178        if ((b1 < b2 && b1 != 0) ||
 179            (b2 < b3 && b2 != 0) ||
 180            (b3 < b4 && b3 != 0) ||
 181            (b4 < b5 && b4 != 0) ||
 182            (b5 < b6 && b5 != 0) ||
 183            (b6 < b7 && b6 != 0) ||
 184            (b7 < b8 && b7 != 0)) {
 185            ml_printf("Error %d, %d, %d, %d, %d, %d, %d, %d",
 186                      b1, b2, b3, b4, b5, b6, b7, b8);
 187            return 2;
 188        } else {
 189            pdot(i);
 190        }
 191    }
 192    ml_printf("done\n");
 193    return 0;
 194}
 195
 196/* Read the test data and verify at various offsets */
 197int do_reads(void)
 198{
 199    int r = 0;
 200    int off = 0;
 201
 202    while (r == 0 && off < 8) {
 203        r = read_test_data_u16(off);
 204        r |= read_test_data_u32(off);
 205        r |= read_test_data_u64(off);
 206        off++;
 207    }
 208
 209    return r;
 210}
 211
 212int main(void)
 213{
 214    int i, r = 0;
 215
 216
 217    init_test_data_u8();
 218    r = do_reads();
 219    if (r) {
 220        return r;
 221    }
 222
 223    for (i = 0; i < 8; i++) {
 224        init_test_data_u16(i);
 225
 226        r = do_reads();
 227        if (r) {
 228            return r;
 229        }
 230    }
 231
 232    for (i = 0; i < 8; i++) {
 233        init_test_data_u32(i);
 234
 235        r = do_reads();
 236        if (r) {
 237            return r;
 238        }
 239    }
 240
 241    ml_printf("Test complete: %s\n", r == 0 ? "PASSED" : "FAILED");
 242    return r;
 243}
 244