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);
}
|