2 * This code works perfectly on most test systems I have.
3 * Some systems do provide interesting insight though when they do fail.
5 * Test: Oracle VirtualBox 4.1.8 with 64-bit guest and AMD VT-X acceleration:
6 * Result: VirtualBox reports PAE and PSE, and 32-bit test program works perfectly.
7 * The 16-bit real mode builds however, cause the virtual machine to hang
8 * when attempting to use the PSE method. This hang does not occur when
9 * AMD VT-x is disabled.
11 * Test: Dell netbook with Intel Atom processor
12 * Result: Processor reports via CPUID that it has 32-bit linear and 32-bit physical
13 * address space. And it means it. The minute this program steps beyond 4GB,
14 * the CPU faults and the system resets. This is true regardless of whether
15 * the 16-bit real mode or the 32-bit protected mode version is used. This is
16 * true whether you use PSE-36 or PAE.
18 * So apparently, they don't do what 386/486/pentium systems USED to do and just
19 * silently wrap the addresses, eh?
21 * That means this code should make use of the "extended CPUID" to read those
22 * limits and then llmemcpy() should enforce them. */
25 #include <conio.h> /* this is where Open Watcom hides the outp() etc. functions */
34 #include <hw/cpu/cpu.h>
35 #include <hw/dos/dos.h>
36 #include <hw/llmem/llmem.h>
37 #include <hw/cpu/cpuidext.h>
39 static unsigned char temp1[256],temp2[256];
41 static void print_contents(unsigned char *t,unsigned int len) {
44 len = (len + 15U) >> 4U;
47 for (x=0;x < 16;x++) printf("%02X ",t[x]);
54 fprintf(stderr,"Long-Long memory copy test program\n");
55 fprintf(stderr,"llmem [options]\n");
56 fprintf(stderr," /PAE Prefer PAE if both are available\n");
57 fprintf(stderr," /PSE Prefer PSE if both are available\n");
60 int main(int argc,char **argv) {
61 int i,pref_pse=0,pref_pae=0;
67 if (*a == '/' || *a == '-') {
68 do { a++; } while (*a == '/' || *a == '-');
70 if (!strcmp(a,"h") || !strcmp(a,"help")) {
74 else if (!strcmp(a,"pse")) {
77 else if (!strcmp(a,"pae")) {
86 fprintf(stderr,"Unknown arg '%s'\n",a);
92 printf("Your system is not suitable to use with the Long-Long memory access library\n");
93 printf("Reason: %s\n",llmem_reason);
97 if (pref_pse && llmem_meth_pse)
99 if (pref_pae && llmem_meth_pae)
102 printf("Long-Long memory access is usable on this machine.\n");
103 printf(" - PSE method: %d\n",llmem_meth_pse);
104 printf(" - PAE method: %d\n",llmem_meth_pae);
106 memset(temp1,0xAA,sizeof(temp1));
107 if (llmemcpy(llmem_ptr2ofs(temp1),0x000000000UL,256UL)) { /* At lowest address */
108 printf("Memory @ 0MB:\n");
109 print_contents(temp1,256);
112 printf("! Cannot read memory @ 0MB: '%s'\n",llmem_reason);
114 while (getch() != 13);
116 memset(temp1,0xAA,sizeof(temp1));
117 if (llmemcpy(llmem_ptr2ofs(temp1),0xFFFFFF00UL,256UL)) { /* Just below the 4GB boundary */
118 printf("Memory @ 4096MB-256b:\n");
119 print_contents(temp1,256);
122 printf("! Cannot read memory @ 4096MB-256B: '%s'\n",llmem_reason);
124 while (getch() != 13);
126 memset(temp2,0xAA,sizeof(temp2));
127 if (llmemcpy(llmem_ptr2ofs(temp2),0x100000000UL,256UL)) { /* At the 4GB boundary */
128 printf("Memory @ 4096MB:\n");
129 print_contents(temp2,256);
132 printf("! Cannot read memory @ 4096MB: '%s'\n",llmem_reason);
134 while (getch() != 13);
136 memset(temp2,0xAA,sizeof(temp2));
137 if (llmemcpy(llmem_ptr2ofs(temp2),0x200000000UL,256UL)) { /* At the 8GB boundary */
138 printf("Memory @ 8192MB:\n");
139 print_contents(temp2,256);
142 printf("! Cannot read memory @ 8192MB: '%s'\n",llmem_reason);
144 while (getch() != 13);
147 cpu_extended_cpuid_info_free();