1 // Windows/SystemInfo.cpp
2
3 #include "StdAfx.h"
4
5 #include "../../C/CpuArch.h"
6
7 #include "../Common/IntToString.h"
8
9 #ifdef _WIN32
10
11 #include "Registry.h"
12
13 #else
14
15 #include <unistd.h>
16 #include <sys/utsname.h>
17 #ifdef __APPLE__
18 #include <sys/sysctl.h>
19 #elif !defined(_AIX)
20
21 #include <sys/auxv.h>
22
23 // #undef AT_HWCAP // to debug
24 // #undef AT_HWCAP2 // to debug
25
26 /* the following patch for some debian systems.
27 Is it OK to define AT_HWCAP and AT_HWCAP2 here with these constant numbers? */
28 /*
29 #if defined(__FreeBSD_kernel__) && defined(__GLIBC__)
30 #ifndef AT_HWCAP
31 #define AT_HWCAP 16
32 #endif
33 #ifndef AT_HWCAP2
34 #define AT_HWCAP2 26
35 #endif
36 #endif
37 */
38
39 #ifdef MY_CPU_ARM_OR_ARM64
40 #include <asm/hwcap.h>
41 #endif
42 #endif
43
44 #ifdef __linux__
45 #include "../Windows/FileIO.h"
46 #endif
47
48 #endif // WIN32
49
50 #include "SystemInfo.h"
51 #include "System.h"
52
53 using namespace NWindows;
54
55 #ifdef __linux__
56
ReadFile_to_Buffer(CFSTR fileName, CByteBuffer &buf)57 static bool ReadFile_to_Buffer(CFSTR fileName, CByteBuffer &buf)
58 {
59 NWindows::NFile::NIO::CInFile file;
60 if (!file.Open(fileName))
61 return false;
62 /*
63 UInt64 size;
64 if (!file.GetLength(size))
65 {
66 // GetLength() doesn't work "/proc/cpuinfo"
67 return false;
68 }
69 if (size >= ((UInt32)1 << 29))
70 return false;
71 */
72 size_t size = 0;
73 size_t addSize = ((size_t)1 << 12);
74 for (;;)
75 {
76 // printf("\nsize = %d\n", (unsigned)size);
77 buf.ChangeSize_KeepData(size + addSize, size);
78 size_t processed;
79 if (!file.ReadFull(buf + size, addSize, processed))
80 return false;
81 if (processed == 0)
82 {
83 buf.ChangeSize_KeepData(size, size);
84 return true;
85 }
86 size += processed;
87 addSize *= 2;
88 }
89 }
90
91 #endif
92
93
94 #if defined(_WIN32) || defined(AT_HWCAP) || defined(AT_HWCAP2)
PrintHex(AString &s, UInt64 v)95 static void PrintHex(AString &s, UInt64 v)
96 {
97 char temp[32];
98 ConvertUInt64ToHex(v, temp);
99 s += temp;
100 }
101 #endif
102
103 #ifdef MY_CPU_X86_OR_AMD64
104
105 Z7_NO_INLINE
PrintCpuChars(AString &s, UInt32 v)106 static void PrintCpuChars(AString &s, UInt32 v)
107 {
108 for (unsigned j = 0; j < 4; j++)
109 {
110 Byte b = (Byte)(v & 0xFF);
111 v >>= 8;
112 if (b == 0)
113 break;
114 if (b >= 0x20 && b <= 0x7f)
115 s += (char)b;
116 else
117 {
118 s += '[';
119 char temp[16];
120 ConvertUInt32ToHex(b, temp);
121 s += temp;
122 s += ']';
123 }
124 }
125 }
126
127
x86cpuid_to_String(AString &s)128 static void x86cpuid_to_String(AString &s)
129 {
130 s.Empty();
131
132 UInt32 a[4];
133 // cpuid was called already. So we don't check for cpuid availability here
134 z7_x86_cpuid(a, 0x80000000);
135
136 if (a[0] >= 0x80000004) // if (maxFunc2 >= hi+4) the full name is available
137 {
138 for (unsigned i = 0; i < 3; i++)
139 {
140 z7_x86_cpuid(a, 0x80000002 + i);
141 for (unsigned j = 0; j < 4; j++)
142 PrintCpuChars(s, a[j]);
143 }
144 }
145
146 s.Trim();
147
148 if (s.IsEmpty())
149 {
150 z7_x86_cpuid(a, 0);
151 for (unsigned i = 1; i < 4; i++)
152 {
153 const unsigned j = (i ^ (i >> 1));
154 PrintCpuChars(s, a[j]);
155 }
156 s.Trim();
157 }
158 }
159
160 /*
161 static void x86cpuid_all_to_String(AString &s)
162 {
163 Cx86cpuid p;
164 if (!x86cpuid_CheckAndRead(&p))
165 return;
166 s += "x86cpuid maxFunc = ";
167 s.Add_UInt32(p.maxFunc);
168 for (unsigned j = 0; j <= p.maxFunc; j++)
169 {
170 s.Add_LF();
171 // s.Add_UInt32(j); // align
172 {
173 char temp[32];
174 ConvertUInt32ToString(j, temp);
175 unsigned len = (unsigned)strlen(temp);
176 while (len < 8)
177 {
178 len++;
179 s.Add_Space();
180 }
181 s += temp;
182 }
183
184 s += ":";
185 UInt32 d[4] = { 0 };
186 MyCPUID(j, &d[0], &d[1], &d[2], &d[3]);
187 for (unsigned i = 0; i < 4; i++)
188 {
189 char temp[32];
190 ConvertUInt32ToHex8Digits(d[i], temp);
191 s.Add_Space();
192 s += temp;
193 }
194 }
195 }
196 */
197
198 #endif
199
200
201
202 #ifdef _WIN32
203
204 static const char * const k_PROCESSOR_ARCHITECTURE[] =
205 {
206 "x86" // "INTEL"
207 , "MIPS"
208 , "ALPHA"
209 , "PPC"
210 , "SHX"
211 , "ARM"
212 , "IA64"
213 , "ALPHA64"
214 , "MSIL"
215 , "x64" // "AMD64"
216 , "IA32_ON_WIN64"
217 , "NEUTRAL"
218 , "ARM64"
219 , "ARM32_ON_WIN64"
220 };
221
222 #define Z7_WIN_PROCESSOR_ARCHITECTURE_INTEL 0
223 #define Z7_WIN_PROCESSOR_ARCHITECTURE_AMD64 9
224
225
226 #define Z7_WIN_PROCESSOR_INTEL_PENTIUM 586
227 #define Z7_WIN_PROCESSOR_AMD_X8664 8664
228
229 /*
230 static const CUInt32PCharPair k_PROCESSOR[] =
231 {
232 { 2200, "IA64" },
233 { 8664, "x64" }
234 };
235
236 #define PROCESSOR_INTEL_386 386
237 #define PROCESSOR_INTEL_486 486
238 #define PROCESSOR_INTEL_PENTIUM 586
239 #define PROCESSOR_INTEL_860 860
240 #define PROCESSOR_INTEL_IA64 2200
241 #define PROCESSOR_AMD_X8664 8664
242 #define PROCESSOR_MIPS_R2000 2000
243 #define PROCESSOR_MIPS_R3000 3000
244 #define PROCESSOR_MIPS_R4000 4000
245 #define PROCESSOR_ALPHA_21064 21064
246 #define PROCESSOR_PPC_601 601
247 #define PROCESSOR_PPC_603 603
248 #define PROCESSOR_PPC_604 604
249 #define PROCESSOR_PPC_620 620
250 #define PROCESSOR_HITACHI_SH3 10003
251 #define PROCESSOR_HITACHI_SH3E 10004
252 #define PROCESSOR_HITACHI_SH4 10005
253 #define PROCESSOR_MOTOROLA_821 821
254 #define PROCESSOR_SHx_SH3 103
255 #define PROCESSOR_SHx_SH4 104
256 #define PROCESSOR_STRONGARM 2577 // 0xA11
257 #define PROCESSOR_ARM720 1824 // 0x720
258 #define PROCESSOR_ARM820 2080 // 0x820
259 #define PROCESSOR_ARM920 2336 // 0x920
260 #define PROCESSOR_ARM_7TDMI 70001
261 #define PROCESSOR_OPTIL 18767 // 0x494f
262 */
263
264
265 /*
266 static const char * const k_PF[] =
267 {
268 "FP_ERRATA"
269 , "FP_EMU"
270 , "CMPXCHG"
271 , "MMX"
272 , "PPC_MOVEMEM_64BIT"
273 , "ALPHA_BYTE"
274 , "SSE"
275 , "3DNOW"
276 , "RDTSC"
277 , "PAE"
278 , "SSE2"
279 , "SSE_DAZ"
280 , "NX"
281 , "SSE3"
282 , "CMPXCHG16B"
283 , "CMP8XCHG16"
284 , "CHANNELS"
285 , "XSAVE"
286 , "ARM_VFP_32"
287 , "ARM_NEON"
288 , "L2AT"
289 , "VIRT_FIRMWARE"
290 , "RDWRFSGSBASE"
291 , "FASTFAIL"
292 , "ARM_DIVIDE"
293 , "ARM_64BIT_LOADSTORE_ATOMIC"
294 , "ARM_EXTERNAL_CACHE"
295 , "ARM_FMAC"
296 , "RDRAND"
297 , "ARM_V8"
298 , "ARM_V8_CRYPTO"
299 , "ARM_V8_CRC32"
300 , "RDTSCP"
301 , "RDPID"
302 , "ARM_V81_ATOMIC"
303 , "MONITORX"
304 };
305 */
306
307 #endif
308
309
PrintPage(AString &s, UInt64 v)310 static void PrintPage(AString &s, UInt64 v)
311 {
312 const char *t = "B";
313 if ((v & 0x3ff) == 0)
314 {
315 v >>= 10;
316 t = "KB";
317 }
318 s.Add_UInt64(v);
319 s += t;
320 }
321
322 #ifdef _WIN32
323
TypeToString2(const char * const table[], unsigned num, UInt32 value)324 static AString TypeToString2(const char * const table[], unsigned num, UInt32 value)
325 {
326 char sz[16];
327 const char *p = NULL;
328 if (value < num)
329 p = table[value];
330 if (!p)
331 {
332 ConvertUInt32ToString(value, sz);
333 p = sz;
334 }
335 return (AString)p;
336 }
337
338 // #if defined(Z7_LARGE_PAGES) || defined(_WIN32)
339 // #ifdef _WIN32
PrintSize_KMGT_Or_Hex(AString &s, UInt64 v)340 void PrintSize_KMGT_Or_Hex(AString &s, UInt64 v)
341 {
342 char c = 0;
343 if ((v & 0x3FF) == 0) { v >>= 10; c = 'K';
344 if ((v & 0x3FF) == 0) { v >>= 10; c = 'M';
345 if ((v & 0x3FF) == 0) { v >>= 10; c = 'G';
346 if ((v & 0x3FF) == 0) { v >>= 10; c = 'T';
347 }}}}
348 else
349 {
350 // s += "0x";
351 PrintHex(s, v);
352 return;
353 }
354 s.Add_UInt64(v);
355 if (c)
356 s += c;
357 s += 'B';
358 }
359 // #endif
360 // #endif
361
SysInfo_To_String(AString &s, const SYSTEM_INFO &si)362 static void SysInfo_To_String(AString &s, const SYSTEM_INFO &si)
363 {
364 s += TypeToString2(k_PROCESSOR_ARCHITECTURE, Z7_ARRAY_SIZE(k_PROCESSOR_ARCHITECTURE), si.wProcessorArchitecture);
365
366 if (!( (si.wProcessorArchitecture == Z7_WIN_PROCESSOR_ARCHITECTURE_INTEL && si.dwProcessorType == Z7_WIN_PROCESSOR_INTEL_PENTIUM)
367 || (si.wProcessorArchitecture == Z7_WIN_PROCESSOR_ARCHITECTURE_AMD64 && si.dwProcessorType == Z7_WIN_PROCESSOR_AMD_X8664)))
368 {
369 s.Add_Space();
370 // s += TypePairToString(k_PROCESSOR, Z7_ARRAY_SIZE(k_PROCESSOR), si.dwProcessorType);
371 s.Add_UInt32(si.dwProcessorType);
372 }
373 s.Add_Space();
374 PrintHex(s, si.wProcessorLevel);
375 s.Add_Dot();
376 PrintHex(s, si.wProcessorRevision);
377 if ((UInt64)si.dwActiveProcessorMask + 1 != ((UInt64)1 << si.dwNumberOfProcessors))
378 if ((UInt64)si.dwActiveProcessorMask + 1 != 0 || si.dwNumberOfProcessors != sizeof(UInt64) * 8)
379 {
380 s += " act:";
381 PrintHex(s, si.dwActiveProcessorMask);
382 }
383 s += " cpus:";
384 s.Add_UInt32(si.dwNumberOfProcessors);
385 if (si.dwPageSize != 1 << 12)
386 {
387 s += " page:";
388 PrintPage(s, si.dwPageSize);
389 }
390 if (si.dwAllocationGranularity != 1 << 16)
391 {
392 s += " gran:";
393 PrintPage(s, si.dwAllocationGranularity);
394 }
395 s.Add_Space();
396
397 const DWORD_PTR minAdd = (DWORD_PTR)si.lpMinimumApplicationAddress;
398 UInt64 maxSize = (UInt64)(DWORD_PTR)si.lpMaximumApplicationAddress + 1;
399 const UInt32 kReserveSize = ((UInt32)1 << 16);
400 if (minAdd != kReserveSize)
401 {
402 PrintSize_KMGT_Or_Hex(s, minAdd);
403 s += "-";
404 }
405 else
406 {
407 if ((maxSize & (kReserveSize - 1)) == 0)
408 maxSize += kReserveSize;
409 }
410 PrintSize_KMGT_Or_Hex(s, maxSize);
411 }
412
413 #ifndef _WIN64
414 EXTERN_C_BEGIN
415 typedef VOID (WINAPI *Func_GetNativeSystemInfo)(LPSYSTEM_INFO lpSystemInfo);
416 EXTERN_C_END
417 #endif
418
419 #endif
420
421 #ifdef __APPLE__
422 #ifndef MY_CPU_X86_OR_AMD64
Add_sysctlbyname_to_String(const char *name, AString &s)423 static void Add_sysctlbyname_to_String(const char *name, AString &s)
424 {
425 size_t bufSize = 256;
426 char buf[256];
427 if (z7_sysctlbyname_Get(name, &buf, &bufSize) == 0)
428 s += buf;
429 }
430 #endif
431 #endif
432
433 void GetSysInfo(AString &s1, AString &s2);
GetSysInfo(AString &s1, AString &s2)434 void GetSysInfo(AString &s1, AString &s2)
435 {
436 s1.Empty();
437 s2.Empty();
438
439 #ifdef _WIN32
440 SYSTEM_INFO si;
441 GetSystemInfo(&si);
442 {
443 SysInfo_To_String(s1, si);
444 // s += " : ";
445 }
446
447 #if !defined(_WIN64) && !defined(UNDER_CE)
448 const
449 Func_GetNativeSystemInfo fn = Z7_GET_PROC_ADDRESS(
450 Func_GetNativeSystemInfo, GetModuleHandleA("kernel32.dll"),
451 "GetNativeSystemInfo");
452 if (fn)
453 {
454 SYSTEM_INFO si2;
455 fn(&si2);
456 // if (memcmp(&si, &si2, sizeof(si)) != 0)
457 {
458 // s += " - ";
459 SysInfo_To_String(s2, si2);
460 }
461 }
462 #endif
463 #endif
464 }
465
466
467 void GetCpuName(AString &s);
468
AddBracedString(AString &dest, AString &src)469 static void AddBracedString(AString &dest, AString &src)
470 {
471 if (!src.IsEmpty())
472 {
473 AString s;
474 s += '(';
475 s += src;
476 s += ')';
477 dest.Add_OptSpaced(s);
478 }
479 }
480
481 struct CCpuName
482 {
483 AString CpuName;
484 AString Revision;
485 AString Microcode;
486 AString LargePages;
487
488 void Fill();
489
Get_Revision_Microcode_LargePagesCCpuName490 void Get_Revision_Microcode_LargePages(AString &s)
491 {
492 s.Empty();
493 AddBracedString(s, Revision);
494 AddBracedString(s, Microcode);
495 s.Add_OptSpaced(LargePages);
496 }
497 };
498
Fill()499 void CCpuName::Fill()
500 {
501 CpuName.Empty();
502 Revision.Empty();
503 Microcode.Empty();
504 LargePages.Empty();
505
506 AString &s = CpuName;
507
508 #ifdef MY_CPU_X86_OR_AMD64
509 {
510 #if !defined(MY_CPU_AMD64)
511 if (!z7_x86_cpuid_GetMaxFunc())
512 s += "x86";
513 else
514 #endif
515 {
516 x86cpuid_to_String(s);
517 {
518 UInt32 a[4];
519 z7_x86_cpuid(a, 1);
520 char temp[16];
521 ConvertUInt32ToHex(a[0], temp);
522 Revision += temp;
523 }
524 }
525 }
526 #elif defined(__APPLE__)
527 {
528 Add_sysctlbyname_to_String("machdep.cpu.brand_string", s);
529 }
530 #endif
531
532
533 if (s.IsEmpty())
534 {
535 #ifdef MY_CPU_LE
536 s += "LE";
537 #elif defined(MY_CPU_BE)
538 s += "BE";
539 #endif
540 }
541
542 #ifdef __APPLE__
543 {
544 AString s2;
545 UInt32 v = 0;
546 if (z7_sysctlbyname_Get_UInt32("machdep.cpu.core_count", &v) == 0)
547 {
548 s2.Add_UInt32(v);
549 s2 += 'C';
550 }
551 if (z7_sysctlbyname_Get_UInt32("machdep.cpu.thread_count", &v) == 0)
552 {
553 s2.Add_UInt32(v);
554 s2 += 'T';
555 }
556 if (!s2.IsEmpty())
557 {
558 s.Add_Space_if_NotEmpty();
559 s += s2;
560 }
561 }
562 #endif
563
564
565 #ifdef _WIN32
566 {
567 NRegistry::CKey key;
568 if (key.Open(HKEY_LOCAL_MACHINE, TEXT("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"), KEY_READ) == ERROR_SUCCESS)
569 {
570 LONG res[2];
571 CByteBuffer bufs[2];
572 {
573 for (unsigned i = 0; i < 2; i++)
574 {
575 UInt32 size = 0;
576 res[i] = key.QueryValue(i == 0 ?
577 TEXT("Previous Update Revision") :
578 TEXT("Update Revision"), bufs[i], size);
579 if (res[i] == ERROR_SUCCESS)
580 if (size != bufs[i].Size())
581 res[i] = ERROR_SUCCESS + 1;
582 }
583 }
584 if (res[0] == ERROR_SUCCESS || res[1] == ERROR_SUCCESS)
585 {
586 for (unsigned i = 0; i < 2; i++)
587 {
588 if (i == 1)
589 Microcode += "->";
590 if (res[i] != ERROR_SUCCESS)
591 continue;
592 const CByteBuffer &buf = bufs[i];
593 if (buf.Size() == 8)
594 {
595 UInt32 high = GetUi32(buf);
596 if (high != 0)
597 {
598 PrintHex(Microcode, high);
599 Microcode += ".";
600 }
601 PrintHex(Microcode, GetUi32(buf + 4));
602 }
603 }
604 }
605 }
606 }
607 #endif
608
609
610 #ifdef Z7_LARGE_PAGES
611 Add_LargePages_String(LargePages);
612 #endif
613 }
614
615 void AddCpuFeatures(AString &s);
AddCpuFeatures(AString &s)616 void AddCpuFeatures(AString &s)
617 {
618 #ifdef _WIN32
619 // const unsigned kNumFeatures_Extra = 32; // we check also for unknown features
620 // const unsigned kNumFeatures = Z7_ARRAY_SIZE(k_PF) + kNumFeatures_Extra;
621 const unsigned kNumFeatures = 64;
622 UInt64 flags = 0;
623 for (unsigned i = 0; i < kNumFeatures; i++)
624 {
625 if (IsProcessorFeaturePresent(i))
626 {
627 flags += (UInt64)1 << i;
628 // s.Add_Space_if_NotEmpty();
629 // s += TypeToString2(k_PF, Z7_ARRAY_SIZE(k_PF), i);
630 }
631 }
632 s.Add_OptSpaced("f:");
633 PrintHex(s, flags);
634
635 #elif defined(__APPLE__)
636 {
637 UInt32 v = 0;
638 if (z7_sysctlbyname_Get_UInt32("hw.pagesize", &v) == 0)
639 {
640 s.Add_OptSpaced("PageSize:");
641 PrintPage(s, v);
642 }
643 }
644
645 #else
646
647 const long v = sysconf(_SC_PAGESIZE);
648 if (v != -1)
649 {
650 s.Add_OptSpaced("PageSize:");
651 PrintPage(s, (unsigned long)v);
652 }
653
654 #if !defined(_AIX)
655
656 #ifdef __linux__
657
658 CByteBuffer buf;
659 if (ReadFile_to_Buffer("/sys/kernel/mm/transparent_hugepage/enabled", buf))
660 // if (ReadFile_to_Buffer("/proc/cpuinfo", buf))
661 {
662 s.Add_OptSpaced("THP:");
663 AString s2;
664 s2.SetFrom_CalcLen((const char *)(const void *)(const Byte *)buf, (unsigned)buf.Size());
665 const int pos = s2.Find('[');
666 if (pos >= 0)
667 {
668 const int pos2 = s2.Find(']', (unsigned)pos + 1);
669 if (pos2 >= 0)
670 {
671 s2.DeleteFrom((unsigned)pos2);
672 s2.DeleteFrontal((unsigned)pos + 1);
673 }
674 }
675 s += s2;
676 }
677 // else throw CSystemException(MY_SRes_HRESULT_FROM_WRes(errno));
678
679 #endif
680
681
682 #ifdef AT_HWCAP
683 s.Add_OptSpaced("hwcap:");
684 {
685 unsigned long h = getauxval(AT_HWCAP);
686 PrintHex(s, h);
687 #ifdef MY_CPU_ARM64
688 if (h & HWCAP_CRC32) s += ":CRC32";
689 if (h & HWCAP_SHA1) s += ":SHA1";
690 if (h & HWCAP_SHA2) s += ":SHA2";
691 if (h & HWCAP_AES) s += ":AES";
692 if (h & HWCAP_ASIMD) s += ":ASIMD";
693 #elif defined(MY_CPU_ARM)
694 if (h & HWCAP_NEON) s += ":NEON";
695 #endif
696 }
697 #endif // AT_HWCAP
698
699 #ifdef AT_HWCAP2
700 {
701 unsigned long h = getauxval(AT_HWCAP2);
702 #ifndef MY_CPU_ARM
703 if (h != 0)
704 #endif
705 {
706 s += " hwcap2:";
707 PrintHex(s, h);
708 #ifdef MY_CPU_ARM
709 if (h & HWCAP2_CRC32) s += ":CRC32";
710 if (h & HWCAP2_SHA1) s += ":SHA1";
711 if (h & HWCAP2_SHA2) s += ":SHA2";
712 if (h & HWCAP2_AES) s += ":AES";
713 #endif
714 }
715 }
716 #endif // AT_HWCAP2
717 #endif // _AIX
718 #endif // _WIN32
719 }
720
721
722 #ifdef _WIN32
723 #ifndef UNDER_CE
724
725 EXTERN_C_BEGIN
726 typedef void (WINAPI * Func_RtlGetVersion) (OSVERSIONINFOEXW *);
727 EXTERN_C_END
728
My_RtlGetVersion(OSVERSIONINFOEXW *vi)729 static BOOL My_RtlGetVersion(OSVERSIONINFOEXW *vi)
730 {
731 const HMODULE ntdll = ::GetModuleHandleW(L"ntdll.dll");
732 if (!ntdll)
733 return FALSE;
734 const
735 Func_RtlGetVersion func = Z7_GET_PROC_ADDRESS(
736 Func_RtlGetVersion, ntdll,
737 "RtlGetVersion");
738 if (!func)
739 return FALSE;
740 func(vi);
741 return TRUE;
742 }
743
744 #endif
745 #endif
746
747
GetOsInfoText(AString &sRes)748 void GetOsInfoText(AString &sRes)
749 {
750 sRes.Empty();
751 AString s;
752
753 #ifdef _WIN32
754 #ifndef UNDER_CE
755 // OSVERSIONINFO vi;
756 OSVERSIONINFOEXW vi;
757 vi.dwOSVersionInfoSize = sizeof(vi);
758 // if (::GetVersionEx(&vi))
759 if (My_RtlGetVersion(&vi))
760 {
761 s += "Windows";
762 if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT)
763 s.Add_UInt32(vi.dwPlatformId);
764 s.Add_Space(); s.Add_UInt32(vi.dwMajorVersion);
765 s.Add_Dot(); s.Add_UInt32(vi.dwMinorVersion);
766 s.Add_Space(); s.Add_UInt32(vi.dwBuildNumber);
767
768 if (vi.wServicePackMajor != 0 || vi.wServicePackMinor != 0)
769 {
770 s += " SP:"; s.Add_UInt32(vi.wServicePackMajor);
771 s.Add_Dot(); s.Add_UInt32(vi.wServicePackMinor);
772 }
773 // s += " Suite:"; PrintHex(s, vi.wSuiteMask);
774 // s += " Type:"; s.Add_UInt32(vi.wProductType);
775 // s.Add_Space(); s += GetOemString(vi.szCSDVersion);
776 }
777 /*
778 {
779 s += " OEMCP:"; s.Add_UInt32(GetOEMCP());
780 s += " ACP:"; s.Add_UInt32(GetACP());
781 }
782 */
783 #endif
784 #else // _WIN32
785
786 if (!s.IsEmpty())
787 s.Add_LF();
788 struct utsname un;
789 if (uname(&un) == 0)
790 {
791 s += un.sysname;
792 // s += " : "; s += un.nodename; // we don't want to show name of computer
793 s += " : "; s += un.release;
794 s += " : "; s += un.version;
795 s += " : "; s += un.machine;
796
797 #ifdef __APPLE__
798 // Add_sysctlbyname_to_String("kern.version", s);
799 // it's same as "utsname.version"
800 #endif
801 }
802 #endif // _WIN32
803
804 sRes += s;
805 #ifdef MY_CPU_X86_OR_AMD64
806 {
807 AString s2;
808 GetVirtCpuid(s2);
809 if (!s2.IsEmpty())
810 {
811 sRes += " : ";
812 sRes += s2;
813 }
814 }
815 #endif
816 }
817
818
819
GetSystemInfoText(AString &sRes)820 void GetSystemInfoText(AString &sRes)
821 {
822 GetOsInfoText(sRes);
823 sRes.Add_LF();
824
825 {
826 AString s, s1, s2;
827 GetSysInfo(s1, s2);
828 if (!s1.IsEmpty() || !s2.IsEmpty())
829 {
830 s = s1;
831 if (s1 != s2 && !s2.IsEmpty())
832 {
833 s += " - ";
834 s += s2;
835 }
836 }
837 {
838 AddCpuFeatures(s);
839 if (!s.IsEmpty())
840 {
841 sRes += s;
842 sRes.Add_LF();
843 }
844 }
845 }
846 {
847 AString s;
848 GetCpuName(s);
849 if (!s.IsEmpty())
850 {
851 sRes += s;
852 sRes.Add_LF();
853 }
854 }
855 /*
856 #ifdef MY_CPU_X86_OR_AMD64
857 {
858 AString s;
859 x86cpuid_all_to_String(s);
860 if (!s.IsEmpty())
861 {
862 printCallback->Print(s);
863 printCallback->NewLine();
864 }
865 }
866 #endif
867 */
868 }
869
870
871 void GetCpuName(AString &s);
GetCpuName(AString &s)872 void GetCpuName(AString &s)
873 {
874 CCpuName cpuName;
875 cpuName.Fill();
876 s = cpuName.CpuName;
877 AString s2;
878 cpuName.Get_Revision_Microcode_LargePages(s2);
879 s.Add_OptSpaced(s2);
880 }
881
882
883 void GetCpuName_MultiLine(AString &s);
GetCpuName_MultiLine(AString &s)884 void GetCpuName_MultiLine(AString &s)
885 {
886 CCpuName cpuName;
887 cpuName.Fill();
888 s = cpuName.CpuName;
889 AString s2;
890 cpuName.Get_Revision_Microcode_LargePages(s2);
891 if (!s2.IsEmpty())
892 {
893 s.Add_LF();
894 s += s2;
895 }
896 }
897
898
899 #ifdef MY_CPU_X86_OR_AMD64
900
GetVirtCpuid(AString &s)901 void GetVirtCpuid(AString &s)
902 {
903 const UInt32 kHv = 0x40000000;
904
905 Z7_IF_X86_CPUID_SUPPORTED
906 {
907 UInt32 a[4];
908 z7_x86_cpuid(a, kHv);
909
910 if (a[0] < kHv || a[0] >= kHv + (1 << 16))
911 return;
912 {
913 {
914 for (unsigned j = 1; j < 4; j++)
915 PrintCpuChars(s, a[j]);
916 }
917 }
918 if (a[0] >= kHv + 1)
919 {
920 UInt32 d[4];
921 z7_x86_cpuid(d, kHv + 1);
922 s += " : ";
923 PrintCpuChars(s, d[0]);
924 if (a[0] >= kHv + 2)
925 {
926 z7_x86_cpuid(d, kHv + 2);
927 s += " : ";
928 s.Add_UInt32(d[1] >> 16);
929 s.Add_Dot(); s.Add_UInt32(d[1] & 0xffff);
930 s.Add_Dot(); s.Add_UInt32(d[0]);
931 s.Add_Dot(); s.Add_UInt32(d[2]);
932 s.Add_Dot(); s.Add_UInt32(d[3] >> 24);
933 s.Add_Dot(); s.Add_UInt32(d[3] & 0xffffff);
934 }
935 /*
936 if (a[0] >= kHv + 5)
937 {
938 z7_x86_cpuid(d, kHv + 5);
939 s += " : ";
940 s.Add_UInt32(d[0]);
941 s += "p";
942 s.Add_UInt32(d[1]);
943 s += "t";
944 }
945 */
946 }
947 }
948 }
949
950 #endif
951
952
GetCompiler(AString &s)953 void GetCompiler(AString &s)
954 {
955 #ifdef __VERSION__
956 s += __VERSION__;
957 #endif
958
959 #ifdef __GNUC__
960 s += " GCC ";
961 s.Add_UInt32(__GNUC__);
962 s.Add_Dot();
963 s.Add_UInt32(__GNUC_MINOR__);
964 s.Add_Dot();
965 s.Add_UInt32(__GNUC_PATCHLEVEL__);
966 #endif
967
968 #ifdef __clang__
969 s += " CLANG ";
970 s.Add_UInt32(__clang_major__);
971 s.Add_Dot();
972 s.Add_UInt32(__clang_minor__);
973 #endif
974
975 #ifdef __xlC__
976 s += " XLC ";
977 s.Add_UInt32(__xlC__ >> 8);
978 s.Add_Dot();
979 s.Add_UInt32(__xlC__ & 0xFF);
980 #ifdef __xlC_ver__
981 s.Add_Dot();
982 s.Add_UInt32(__xlC_ver__ >> 8);
983 s.Add_Dot();
984 s.Add_UInt32(__xlC_ver__ & 0xFF);
985 #endif
986 #endif
987
988 #ifdef _MSC_VER
989 s += " MSC ";
990 s.Add_UInt32(_MSC_VER);
991 #endif
992
993 #if defined(__AVX2__)
994 #define MY_CPU_COMPILE_ISA "AVX2"
995 #elif defined(__AVX__)
996 #define MY_CPU_COMPILE_ISA "AVX"
997 #elif defined(__SSE2__)
998 #define MY_CPU_COMPILE_ISA "SSE2"
999 #elif defined(_M_IX86_FP) && (_M_IX86_FP >= 2)
1000 #define MY_CPU_COMPILE_ISA "SSE2"
1001 #elif defined(__SSE__)
1002 #define MY_CPU_COMPILE_ISA "SSE"
1003 #elif defined(_M_IX86_FP) && (_M_IX86_FP >= 1)
1004 #define MY_CPU_COMPILE_ISA "SSE"
1005 #elif defined(__i686__)
1006 #define MY_CPU_COMPILE_ISA "i686"
1007 #elif defined(__i586__)
1008 #define MY_CPU_COMPILE_ISA "i586"
1009 #elif defined(__i486__)
1010 #define MY_CPU_COMPILE_ISA "i486"
1011 #elif defined(__i386__)
1012 #define MY_CPU_COMPILE_ISA "i386"
1013 #elif defined(_M_IX86_FP)
1014 #define MY_CPU_COMPILE_ISA "IA32"
1015 #endif
1016
1017
1018 #ifdef MY_CPU_COMPILE_ISA
1019 s += ':';
1020 s.Add_OptSpaced(MY_CPU_COMPILE_ISA);
1021 #endif
1022 }
1023