summaryrefslogtreecommitdiffstats
path: root/memtestEDK/Memtest/Test1/test.c
blob: 818a1938132e9431b2039bdf57b95198cb8de6ee (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
typedef void(*segment_fn)(ulong* start,  // start address
                          ulong len_dw,  // length of segment in dwords
                          const void* ctx);  // any context data needed

static const void* const nullptr = 0x0;
 int me = 0; // my_cpu_num in main.c

/*
 * Memory address test, walking ones
 */
void addr_tst1(int me) // TODO TEST STARTS HERE
{
    unsliced_foreach_segment(nullptr, me, addr_tst1_seg);
}


/* Calls segment_fn() for each segment in vv->map.
 *
 * Does not slice by CPU number, so it covers the entire memory.
 * Contrast to sliced_foreach_segment().
 */
STATIC void unsliced_foreach_segment
(const void* ctx, int me, segment_fn func) {
    int j;
    for (j=0; j<segs; j++) {
        foreach_segment(vv->map[j].start,
                        vv->map[j].end,
                        me, ctx, func);
    }
}

/* Call segment_fn() for each up-to-SPINSZ segment between
 * 'start' and 'end'.
 */
void foreach_segment
(ulong* start, ulong* end,
 int me, const void* ctx, segment_fn func) {

    ASSERT(start < end);

    // Confirm 'start' points to an even dword, and 'end'
    // should point to an odd dword
    ASSERT(0   == (((ulong)start) & 0x7));
    ASSERT(0x4 == (((ulong)end)   & 0x7));

    // 'end' may be exactly 0xfffffffc, right at the 4GB boundary.
    //
    // To avoid overflow in our loop tests and length calculations,
    // use dword indices (the '_dw' vars) to avoid overflows.
    ulong start_dw = ((ulong)start) >> 2;
    ulong   end_dw = ((ulong)  end) >> 2;

    // end is always xxxxxffc, but increment end_dw to an
    // address beyond the segment for easier boundary calculations.
    ++end_dw;

    ulong seg_dw     = start_dw;
    ulong seg_end_dw = start_dw;

    int done = 0;
    do {
        do_tick(me);
        { BAILR }

        // ensure no overflow
        ASSERT((seg_end_dw + SPINSZ_DWORDS) > seg_end_dw);
        seg_end_dw += SPINSZ_DWORDS;

        if (seg_end_dw >= end_dw) {
            seg_end_dw = end_dw;
            done++;
        }
        if (seg_dw == seg_end_dw) {
            break;
        }

        ASSERT(((ulong)seg_end_dw) <= 0x40000000);
        ASSERT(seg_end_dw > seg_dw);
        ulong seg_len_dw = seg_end_dw - seg_dw;

        func((ulong*)(seg_dw << 2), seg_len_dw, ctx);

        seg_dw = seg_end_dw;
    } while (!done);
}