summaryrefslogtreecommitdiffstats
path: root/memtestEDK/Memtest/Test1/test.c
diff options
context:
space:
mode:
Diffstat (limited to 'memtestEDK/Memtest/Test1/test.c')
-rw-r--r--memtestEDK/Memtest/Test1/test.c135
1 files changed, 110 insertions, 25 deletions
diff --git a/memtestEDK/Memtest/Test1/test.c b/memtestEDK/Memtest/Test1/test.c
index 818a193..c9bc36b 100644
--- a/memtestEDK/Memtest/Test1/test.c
+++ b/memtestEDK/Memtest/Test1/test.c
@@ -1,33 +1,38 @@
+
+#include <Uefi.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiApplicationEntryPoint.h>
+
+#include "test.h"
+#include "memoryMap.h"
+
+extern EFI_SYSTEM_TABLE *gST;
+
+typedef unsigned long ulong;
+
+#define ASSERT(n) do { \
+ if (!(n)) { \
+ gST->ConOut->OutputString(gST->ConOut, L"ASSERT FAIL\n"); \
+ } } while(0)
+
+volatile int segs; // TODO compute segs in main.c
+volatile int bail; // TODO compute in main.c
+
+
+#define LINE_PAT 5
+#define COL_PAT 41
+#define SPINSZ_DWORDS 0x4000000 /* 256 MB; units are dwords (32-bit words) */
+#define BAILR if (bail) return;
+
+
+
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);
-}
-
+int me = 0; // my_cpu_num in main.c
-/* 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'.
@@ -82,4 +87,84 @@ void foreach_segment
seg_dw = seg_end_dw;
} while (!done);
-} \ No newline at end of file
+}
+
+/* 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);
+ }
+}
+STATIC void addr_tst1_seg(ulong* restrict buf,
+ ulong len_dw, const void* unused) {
+ // Within each segment:
+ // - choose a low dword offset 'off'
+ // - write pat to *off
+ // - write ~pat to addresses that are above off by
+ // 1, 2, 4, ... dwords up to the top of the segment. None
+ // should alias to the original dword.
+ // - write ~pat to addresses that are below off by
+ // 1, 2, 4, etc dwords, down to the start of the segment. None
+ // should alias to the original dword. If adding a given offset
+ // doesn't produce a single bit address flip (because it produced
+ // a carry) subtracting the same offset should give a single bit flip.
+ // - repeat this, moving off ahead in increments of 1MB;
+ // this covers address bits within physical memory banks, we hope?
+
+ ulong pat;
+ int k;
+
+ for (pat=0x5555aaaa, k=0; k<2; k++) {
+ Print(L"Pat: %u\n");
+ // hprint(LINE_PAT, COL_PAT, pat);
+
+ for (ulong off_dw = 0; off_dw < len_dw; off_dw += (1 << 18)) {
+ buf[off_dw] = pat;
+ pat = ~pat;
+
+ for (ulong more_off_dw = 1; off_dw + more_off_dw < len_dw;
+ more_off_dw = more_off_dw << 1) {
+ ASSERT(more_off_dw); // it should never get to zero
+ buf[off_dw + more_off_dw] = pat;
+ //ulong bad;
+ /* if ((bad = buf[off_dw]) != ~pat) {
+ ad_err1(buf + off_dw,
+ buf + off_dw + more_off_dw,
+ bad, ~pat);
+ break;
+ }*/
+ }
+ for (ulong more_off_dw = 1; off_dw > more_off_dw;
+ more_off_dw = more_off_dw << 1) {
+ ASSERT(more_off_dw); // it should never get to zero
+ buf[off_dw - more_off_dw] = pat;
+ //ulong bad;
+ /* if ((bad = buf[off_dw]) != ~pat) {
+ ad_err1(buf + off_dw,
+ buf + off_dw - more_off_dw,
+ bad, ~pat);
+ break;
+ }*/
+ }
+ }
+ }
+}
+
+/*
+ * Memory address test, walking ones
+ */
+void addr_tst1(int me) // TODO TEST STARTS HERE
+{
+ unsliced_foreach_segment(nullptr, me, addr_tst1_seg);
+}
+
+
+