+ printf_filtered ("CPU Type.......................%s", u.machine);
+ if (cpuid_vendor[0])
+ printf_filtered (" (%s)", cpuid_vendor);
+ puts_filtered ("\n");
+
+ /* CPUID with EAX = 1 returns processor signature and features. */
+ if (cpuid_max >= 1)
+ {
+ static const char *brand_name[] = {
+ "",
+ " Celeron",
+ " III",
+ " III Xeon",
+ "", "", "", "",
+ " 4"
+ };
+ char cpu_string[80];
+ char cpu_brand[20];
+ unsigned brand_idx;
+ int intel_p = strcmp (cpuid_vendor, "GenuineIntel") == 0;
+ int amd_p = strcmp (cpuid_vendor, "AuthenticAMD") == 0;
+ unsigned cpu_family, cpu_model;
+
+#if 0
+ /* See comment above about cpuid usage. */
+ x86_cpuid (1, &cpuid_eax, &cpuid_ebx, NULL, &cpuid_edx);
+#else
+ __asm__ __volatile__ ("movl $1, %%eax;"
+ "cpuid;"
+ : "=a" (cpuid_eax),
+ "=b" (cpuid_ebx),
+ "=d" (cpuid_edx)
+ :
+ : "%ecx");
+#endif
+ brand_idx = cpuid_ebx & 0xff;
+ cpu_family = (cpuid_eax >> 8) & 0xf;
+ cpu_model = (cpuid_eax >> 4) & 0xf;
+ cpu_brand[0] = '\0';
+ if (intel_p)
+ {
+ if (brand_idx > 0
+ && brand_idx < sizeof(brand_name)/sizeof(brand_name[0])
+ && *brand_name[brand_idx])
+ strcpy (cpu_brand, brand_name[brand_idx]);
+ else if (cpu_family == 5)
+ {
+ if (((cpuid_eax >> 12) & 3) == 0 && cpu_model == 4)
+ strcpy (cpu_brand, " MMX");
+ else if (cpu_model > 1 && ((cpuid_eax >> 12) & 3) == 1)
+ strcpy (cpu_brand, " OverDrive");
+ else if (cpu_model > 1 && ((cpuid_eax >> 12) & 3) == 2)
+ strcpy (cpu_brand, " Dual");
+ }
+ else if (cpu_family == 6 && cpu_model < 8)
+ {
+ switch (cpu_model)
+ {
+ case 1:
+ strcpy (cpu_brand, " Pro");
+ break;
+ case 3:
+ strcpy (cpu_brand, " II");
+ break;
+ case 5:
+ strcpy (cpu_brand, " II Xeon");
+ break;
+ case 6:
+ strcpy (cpu_brand, " Celeron");
+ break;
+ case 7:
+ strcpy (cpu_brand, " III");
+ break;
+ }
+ }
+ }
+ else if (amd_p)
+ {
+ switch (cpu_family)
+ {
+ case 4:
+ strcpy (cpu_brand, "486/5x86");
+ break;
+ case 5:
+ switch (cpu_model)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ strcpy (cpu_brand, "-K5");
+ break;
+ case 6:
+ case 7:
+ strcpy (cpu_brand, "-K6");
+ break;
+ case 8:
+ strcpy (cpu_brand, "-K6-2");
+ break;
+ case 9:
+ strcpy (cpu_brand, "-K6-III");
+ break;
+ }
+ break;
+ case 6:
+ switch (cpu_model)
+ {
+ case 1:
+ case 2:
+ case 4:
+ strcpy (cpu_brand, " Athlon");
+ break;
+ case 3:
+ strcpy (cpu_brand, " Duron");
+ break;
+ }
+ break;
+ }
+ }
+ xsnprintf (cpu_string, sizeof (cpu_string), "%s%s Model %d Stepping %d",
+ intel_p ? "Pentium" : (amd_p ? "AMD" : "ix86"),
+ cpu_brand, cpu_model, cpuid_eax & 0xf);
+ printfi_filtered (31, "%s\n", cpu_string);
+ if (((cpuid_edx & (6 | (0x0d << 23))) != 0)
+ || ((cpuid_edx & 1) == 0)
+ || (amd_p && (cpuid_edx & (3 << 30)) != 0))
+ {
+ puts_filtered ("CPU Features...................");
+ /* We only list features which might be useful in the DPMI
+ environment. */
+ if ((cpuid_edx & 1) == 0)
+ puts_filtered ("No FPU "); /* It's unusual to not have an FPU. */
+ if ((cpuid_edx & (1 << 1)) != 0)
+ puts_filtered ("VME ");
+ if ((cpuid_edx & (1 << 2)) != 0)
+ puts_filtered ("DE ");
+ if ((cpuid_edx & (1 << 4)) != 0)
+ puts_filtered ("TSC ");
+ if ((cpuid_edx & (1 << 23)) != 0)
+ puts_filtered ("MMX ");
+ if ((cpuid_edx & (1 << 25)) != 0)
+ puts_filtered ("SSE ");
+ if ((cpuid_edx & (1 << 26)) != 0)
+ puts_filtered ("SSE2 ");
+ if (amd_p)
+ {
+ if ((cpuid_edx & (1 << 31)) != 0)
+ puts_filtered ("3DNow! ");
+ if ((cpuid_edx & (1 << 30)) != 0)
+ puts_filtered ("3DNow!Ext");
+ }
+ puts_filtered ("\n");
+ }
+ }
+ puts_filtered ("\n");
+ printf_filtered ("DOS Version....................%s %s.%s",
+ _os_flavor, u.release, u.version);
+ if (true_dos_version != advertized_dos_version)
+ printf_filtered (" (disguised as v%d.%d)", _osmajor, _osminor);
+ puts_filtered ("\n");
+ if (!windows_major)
+ go32_get_windows_version ();
+ if (windows_major != 0xff)
+ {
+ const char *windows_flavor;
+
+ printf_filtered ("Windows Version................%d.%02d (Windows ",
+ windows_major, windows_minor);
+ switch (windows_major)
+ {
+ case 3:
+ windows_flavor = "3.X";
+ break;
+ case 4:
+ switch (windows_minor)
+ {
+ case 0:
+ windows_flavor = "95, 95A, or 95B";
+ break;
+ case 3:
+ windows_flavor = "95B OSR2.1 or 95C OSR2.5";
+ break;
+ case 10:
+ windows_flavor = "98 or 98 SE";
+ break;
+ case 90:
+ windows_flavor = "ME";
+ break;
+ default:
+ windows_flavor = "9X";
+ break;
+ }
+ break;
+ default:
+ windows_flavor = "??";
+ break;
+ }
+ printf_filtered ("%s)\n", windows_flavor);
+ }
+ else if (true_dos_version == 0x532 && advertized_dos_version == 0x500)
+ printf_filtered ("Windows Version................"
+ "Windows NT family (W2K/XP/W2K3/Vista/W2K8)\n");
+ puts_filtered ("\n");
+ /* On some versions of Windows, __dpmi_get_capabilities returns
+ zero, but the buffer is not filled with info, so we fill the
+ buffer with a known pattern and test for it afterwards. */
+ memcpy (dpmi_vendor_info, test_pattern, sizeof(dpmi_vendor_info));
+ dpmi_vendor_available =
+ __dpmi_get_capabilities (&dpmi_flags, dpmi_vendor_info);
+ if (dpmi_vendor_available == 0
+ && memcmp (dpmi_vendor_info, test_pattern,
+ sizeof(dpmi_vendor_info)) != 0)
+ {
+ /* The DPMI spec says the vendor string should be ASCIIZ, but
+ I don't trust the vendors to follow that... */
+ if (!memchr (&dpmi_vendor_info[2], 0, 126))
+ dpmi_vendor_info[128] = '\0';
+ printf_filtered ("DPMI Host......................"
+ "%s v%d.%d (capabilities: %#x)\n",
+ &dpmi_vendor_info[2],
+ (unsigned)dpmi_vendor_info[0],
+ (unsigned)dpmi_vendor_info[1],
+ ((unsigned)dpmi_flags & 0x7f));
+ }
+ else
+ printf_filtered ("DPMI Host......................(Info not available)\n");
+ __dpmi_get_version (&dpmi_version_data);
+ printf_filtered ("DPMI Version...................%d.%02d\n",
+ dpmi_version_data.major, dpmi_version_data.minor);
+ printf_filtered ("DPMI Info......................"
+ "%s-bit DPMI, with%s Virtual Memory support\n",
+ (dpmi_version_data.flags & 1) ? "32" : "16",
+ (dpmi_version_data.flags & 4) ? "" : "out");
+ printfi_filtered (31, "Interrupts reflected to %s mode\n",
+ (dpmi_version_data.flags & 2) ? "V86" : "Real");
+ printfi_filtered (31, "Processor type: i%d86\n",
+ dpmi_version_data.cpu);
+ printfi_filtered (31, "PIC base interrupt: Master: %#x Slave: %#x\n",
+ dpmi_version_data.master_pic, dpmi_version_data.slave_pic);
+
+ /* a_tss is only initialized when the debuggee is first run. */
+ if (prog_has_started)
+ {
+ __asm__ __volatile__ ("pushfl ; popl %0" : "=g" (eflags));
+ printf_filtered ("Protection....................."
+ "Ring %d (in %s), with%s I/O protection\n",
+ a_tss.tss_cs & 3, (a_tss.tss_cs & 4) ? "LDT" : "GDT",
+ (a_tss.tss_cs & 3) > ((eflags >> 12) & 3) ? "" : "out");
+ }
+ puts_filtered ("\n");
+ __dpmi_get_free_memory_information (&mem_info);
+ print_mem (mem_info.total_number_of_physical_pages,
+ "DPMI Total Physical Memory.....", 1);
+ print_mem (mem_info.total_number_of_free_pages,
+ "DPMI Free Physical Memory......", 1);
+ print_mem (mem_info.size_of_paging_file_partition_in_pages,
+ "DPMI Swap Space................", 1);
+ print_mem (mem_info.linear_address_space_size_in_pages,
+ "DPMI Total Linear Address Size.", 1);
+ print_mem (mem_info.free_linear_address_space_in_pages,
+ "DPMI Free Linear Address Size..", 1);
+ print_mem (mem_info.largest_available_free_block_in_bytes,
+ "DPMI Largest Free Memory Block.", 0);
+
+ regs.h.ah = 0x48;
+ regs.x.bx = 0xffff;
+ __dpmi_int (0x21, ®s);
+ print_mem (regs.x.bx << 4, "Free DOS Memory................", 0);
+ regs.x.ax = 0x5800;
+ __dpmi_int (0x21, ®s);
+ if ((regs.x.flags & 1) == 0)
+ {
+ static const char *dos_hilo[] = {
+ "Low", "", "", "", "High", "", "", "", "High, then Low"
+ };
+ static const char *dos_fit[] = {
+ "First", "Best", "Last"
+ };
+ int hilo_idx = (regs.x.ax >> 4) & 0x0f;
+ int fit_idx = regs.x.ax & 0x0f;
+
+ if (hilo_idx > 8)
+ hilo_idx = 0;
+ if (fit_idx > 2)
+ fit_idx = 0;
+ printf_filtered ("DOS Memory Allocation..........%s memory, %s fit\n",
+ dos_hilo[hilo_idx], dos_fit[fit_idx]);
+ regs.x.ax = 0x5802;
+ __dpmi_int (0x21, ®s);
+ if ((regs.x.flags & 1) != 0)
+ regs.h.al = 0;
+ printfi_filtered (31, "UMBs %sin DOS memory chain\n",
+ regs.h.al == 0 ? "not " : "");
+ }