diff options
-rw-r--r-- | memtestEDK/MdeModulePkg.dsc | 2 | ||||
-rw-r--r-- | memtestEDK/Memtest/Test1/doTest1.c | 2 | ||||
-rw-r--r-- | memtestEDK/Memtest/Test1/doTest1.inf | 1 | ||||
-rw-r--r-- | memtestEDK/Memtest/Test1/memoryMap.c | 0 | ||||
-rw-r--r-- | memtestEDK/Memtest/Test1/memoryMap.h | 41 | ||||
-rw-r--r-- | memtestEDK/Memtest/Test1/test.c | 135 |
6 files changed, 154 insertions, 27 deletions
diff --git a/memtestEDK/MdeModulePkg.dsc b/memtestEDK/MdeModulePkg.dsc index 574aef6..09bc5a1 100644 --- a/memtestEDK/MdeModulePkg.dsc +++ b/memtestEDK/MdeModulePkg.dsc @@ -209,7 +209,7 @@ Memtest/GetRootSystemDescriptionPointer/GetRootSystemDescriptionPointer.inf
# Memtest/GraphicsOutput/GraphicsOutputProtocol.inf
Memtest/GraphicsOutput/TextOutput.inf
- # Memtest/Test1/doTest1.inf
+ Memtest/Test1/doTest1.inf
# MdeModulePkg/Application/HelloWorld/HelloWorld.inf
# MdeModulePkg/Application/DumpDynPcd/DumpDynPcd.inf
diff --git a/memtestEDK/Memtest/Test1/doTest1.c b/memtestEDK/Memtest/Test1/doTest1.c index 11babee..e6883ff 100644 --- a/memtestEDK/Memtest/Test1/doTest1.c +++ b/memtestEDK/Memtest/Test1/doTest1.c @@ -1,6 +1,6 @@ -#include <stdio.h> #include <stdint.h> + #include <Uefi.h> #include <Library/UefiLib.h> #include <Library/UefiApplicationEntryPoint.h> diff --git a/memtestEDK/Memtest/Test1/doTest1.inf b/memtestEDK/Memtest/Test1/doTest1.inf index 5a15050..c376397 100644 --- a/memtestEDK/Memtest/Test1/doTest1.inf +++ b/memtestEDK/Memtest/Test1/doTest1.inf @@ -14,6 +14,7 @@ [Sources] doTest1.c test.c + memoryMap.c [Packages] MdePkg/MdePkg.dec diff --git a/memtestEDK/Memtest/Test1/memoryMap.c b/memtestEDK/Memtest/Test1/memoryMap.c new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/memtestEDK/Memtest/Test1/memoryMap.c diff --git a/memtestEDK/Memtest/Test1/memoryMap.h b/memtestEDK/Memtest/Test1/memoryMap.h new file mode 100644 index 0000000..e887a4a --- /dev/null +++ b/memtestEDK/Memtest/Test1/memoryMap.h @@ -0,0 +1,41 @@ + +struct vars variables = {}; +struct vars * const vv = &variables; + +/* Define common variables across relocations of memtest86 */ +struct vars { + int pass; + int msg_line; + int ecount; + int ecc_ecount; + int msegs; // number of entries in pmap[] + int testsel; + int scroll_start; + int pass_ticks; + int total_ticks; + int pptr; + int tptr; + struct err_info erri; + // PA ranges from e820 table: + struct pmap pmap[MAX_MEM_SEGMENTS]; + // VA mappings: + volatile struct mmap map[MAX_MEM_SEGMENTS]; + ulong plim_lower; // phys page number + ulong plim_upper; // phys page number + ulong clks_msec; + ulong starth; + ulong startl; + ulong snaph; + ulong snapl; + int printmode; + int numpatn; + struct pair patn [BADRAM_MAXPATNS]; + ulong test_pages; + ulong selected_pages; + ulong reserved_pages; + int check_temp; + int fail_safe; + int each_sec; + int beepmode; + int debugging; // Set in selftest only +};
\ No newline at end of file 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); +} + + + |