CPUID.Mod 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198
  1. MODULE CPUID; (** AUTHOR "staubesv"; PURPOSE "Intel/AMD CPUID Information"; *)
  2. (**
  3. * The purpose of this module is to dump processor information provided by the CPUID instruction in a human readable format.
  4. * It is not part (and not intended to be part) of the kernel.
  5. *
  6. * Usage:
  7. *
  8. * CPUID.Show ~ displays the processor name and the most relevant features
  9. * CPUID.ShowDetailed ~ displays all information provided by CPUID
  10. *
  11. * System.Free CPUID ~
  12. *
  13. * Notes:
  14. * - The CPUID instruction is supported by CPUs >= 80486
  15. *
  16. * References:
  17. *
  18. * [1] Intel Processor Identification and the CPUID Instruction, Application Note 485, December 2007
  19. * [2] AMD CPUID Specification, Revision 2.18, January 2006
  20. *)
  21. IMPORT
  22. SYSTEM, Streams, Commands, Options;
  23. CONST
  24. (** CpuInformation.type encoding *)
  25. Intel* = 0;
  26. Amd* = 1;
  27. Other* = 2;
  28. (* CpuInformation.features encoding *)
  29. PBE* = 31; (** INTEL: Pending Break Enable *)
  30. IA64* = 30; (** INTEL: IA64 Capabilities *)
  31. TM* = 29; (** INTEL: Thermal Monitor supported *)
  32. HTT* = 28; (** Hyper-Threading Technology *)
  33. SS* = 27; (** INTEL: Self-Snoop *)
  34. SSE2* = 26; (** SSE2 extensions *)
  35. SSE* = 25; (** SSE extensions *)
  36. FXSR* = 24; (** FXSAVE and FXRSTOR instructions *)
  37. MMX* = 23; (** MMX instructions *)
  38. ACPI* = 22; (** INTEL: Thermal Monitor and Software Controlled Clock Facilities supported *)
  39. DS* = 21; (** INTEL: Debug Store *)
  40. CLFLUSH* = 19; (** CLFLUSH instruction *)
  41. PSN* = 18; (** INTEL: Processor serial number is present and enabled *)
  42. PSE36* = 17; (** Page-size extension *)
  43. PAT* = 16; (** Page attribute table *)
  44. CMOV* = 15; (** CMOV & FCMOV conditional move instructions *)
  45. MCA* = 14; (** Machine check architecture *)
  46. PGE* = 13; (** Page global extension *)
  47. MTRR* = 12; (** Memory-type range registers *)
  48. SysEnterSysExit* = 11; (** SYSENTER & SYSEXIT instructions *)
  49. APIC* = 9; (** APIC exists and is enabled *)
  50. CMPXCH8B* = 8; (** CMPXCHGB8 instruction *)
  51. MCE* = 7; (** Machine check exception *)
  52. PAE* = 6; (** Physical-address extendions (support for physical addresss > 32b) *)
  53. MSR* = 5; (** Model-specific registers with RDMSR & WRMSR instructions *)
  54. TSC* = 4; (** Time stamp counter with RDTSC and RDTSCP instruction support *)
  55. PSE* = 3; (** Page-size extensions (4MB pages) *)
  56. DE* = 2; (** Debugging extensions, I/O breakpoints *)
  57. VME* = 1; (** Virtual-mode enhancements *)
  58. FPU* = 0; (** Floating point unit on chip *)
  59. (** CpuIformation.features2 encoding *)
  60. SSE4_2* = 20; (** INTEL: Streaming SIMD Extensions 4.2*)
  61. SSE4_1* = 19; (** INTEL: Streaming SIMD Extensions 4.1*)
  62. DCA* = 18; (** INTEL: Direct Access Cache *)
  63. PDCM* =15; (** INTEL: Performance Capabilities MSR*)
  64. XTPR* = 14; (** INTEL: Send Task Priority Messages *)
  65. CMPXCHG16B* = 13; (** CMPXCHG16B instruction *)
  66. CID* = 10; (** INTEL: Context ID *)
  67. SSSE3* = 9; (** INTEL: Supplemental Streaming SIMD Extensions 3 *)
  68. TM2* = 8; (** INTEL: Thermal Monitor 2 *)
  69. EST* = 7; (** INTEL: Enhanced Intel SpeedStep Technology *)
  70. SMX* = 6; (** INTEL: Safer Mode Extensions *)
  71. VMX* = 5; (** INTEL: Virtual Machine Extensions *)
  72. DS_CPL* = 4; (** INTEL: CPL Qualified Debug Store *)
  73. MONITOR* = 3; (** INTEL: Monitor/MWAIT *)
  74. DTES64* = 2; (** INTEL: 64-Bit Debug Store *)
  75. SSE3* = 0; (** SSE3 extensions *)
  76. (** CpuInformation.extFeatures encoding (AMD) *)
  77. Amd3DNow* = 31; (** AMD: 3DNow! instructions *)
  78. Amd3DNowExt* = 32; (** AMD: AMD extensions to 3DNow! *)
  79. LM* = 29; (** Long Mode supported (64bit support), IA-32e*)
  80. RDTSCP* = 27; (** AMD: RDTSCP instruction *)
  81. FFXSR* = 25; (** AMD: FXSAVE & FXRSTOR instruction optimizations *)
  82. MmxExt* = 22; (** AMD: AMD extensions to MMX instructins *)
  83. NX* = 20; (** No-execute page protection *)
  84. SysCallSysRet* = 11; (** SYSCALL & SYSRET instructions *)
  85. (** Bits 24..23, 17..12, 9..0 contain the same information as cpuInfo.features *)
  86. (** CpuInformation.extFeatures2 encoding (AMD) *)
  87. AltMovCr8* = 4; (** AMD: LOCK MOV CR0 means MOV CR8 *)
  88. SVM* = 2; (** AMD: Secure virtual machine feature *)
  89. CmpLegacy* = 1; (** AMD: Core multi-processing legacy mode *)
  90. LahfSahf* = 0; (** LAHF & SAHF instruction support in 64-bit mode *)
  91. (** CpuInformation.powerManagement encoding (AMD) *)
  92. AMD7_TscInvariant* = 8; (** TSC rate is ensured to be invariant across all P-States, C-States and stop-grant transitions *)
  93. AMD7_STC* = 5; (** Software Thermal Control is supported *)
  94. AMD7_TM* = 4; (** Hardware Thermal Control is supported *)
  95. AMD7_TTP* = 3; (** THERMTRIP is supported *)
  96. AMD7_VID* = 2; (** Voltage ID control is supported *)
  97. AMD7_FID* = 1; (** Frequency ID control is supported *)
  98. AMD7_TS* = 0; (** Temperature sensor *)
  99. TYPE
  100. CpuInformation* = RECORD
  101. cputype- : LONGINT; (* Intel, Amd or Other *)
  102. (** Standard Function 0: Processor Vendor and Largest Standard Function *)
  103. largestStandardFunction- : LONGINT;
  104. vendor- : ARRAY 13 OF CHAR;
  105. (** Standard Function 1: Family, Model, Stepping Identifiers *)
  106. family-, model-, stepping- : LONGINT;
  107. type- : LONGINT; (* INTEL *)
  108. features-, features2- : SET;
  109. localApicId-, logicalProcessorCount- : LONGINT;
  110. clflushSize- : LONGINT; (* specifies the size of a cache line flushed by the CLFLUSH instruction [in bytes] *)
  111. brandId- : LONGINT;
  112. (** Extended Function 0: Largest Extended Function *)
  113. largestExtendedFunction- : LONGINT;
  114. (** Extended Function 1: Features *)
  115. extFeatures-, extFeatures2- : SET;
  116. (** Extended Function 2-4: Processor name *)
  117. processorName- : ARRAY 48 OF CHAR;
  118. (** AMD-Specific *)
  119. (** Level 1 Cache and TLB *)
  120. (** L1 2M/4M pages TLB associativity & size *)
  121. l1DataTlbAssociativity2M4M- : LONGINT;
  122. l1DataTlbSize2M4M- : LONGINT;
  123. l1InstrTlbAssociativity2M4M- : LONGINT;
  124. l1InstrTlbSize2M4M- : LONGINT;
  125. (** L1 4K pages TLB associativity & size *)
  126. l1DataTlbAssociativity4K- : LONGINT;
  127. l1DataTlbSize4K- : LONGINT;
  128. l1InstrTlbAssociativity4K- : LONGINT;
  129. l1InstrTlbSize4K- : LONGINT;
  130. (** L1 data cache characteristics *)
  131. l1DcSize- : LONGINT; (* KB *)
  132. l1DcAssociativity- : LONGINT;
  133. l1DcLinesPerTag- : LONGINT; (* AMD *)
  134. l1DcLineSize- : LONGINT;
  135. (** L1 instruction cache characteristics *)
  136. l1IcSize- : LONGINT; (* KB *)
  137. l1IcAssociativity- : LONGINT;
  138. l1IcLinesPerTag- : LONGINT; (* AMD *)
  139. l1IcLineSize- : LONGINT;
  140. (** Level 2 Cache and TLB *)
  141. unifiedTlb- : BOOLEAN; (* if TRUE, one TLB for all 4K/2M/4M pages *)
  142. (** L2 2M/4M pages TLB associativity & size *)
  143. l2DataTlbAssociativity2M4M- : LONGINT;
  144. l2DataTlbSize2M4M- : LONGINT;
  145. l2InstrTlbAssociativity2M4M- : LONGINT;
  146. l2InstrTlbSize2M4M- : LONGINT;
  147. (** L2 4K pages TLB associativity & size *)
  148. l2DataTlbAssociativity4K- : LONGINT;
  149. l2DataTlbSize4K- : LONGINT;
  150. l2InstrTlbAssociativity4K- : LONGINT;
  151. l2InstrTlbSize4K- : LONGINT;
  152. l2CacheSize- : LONGINT; (* KB *)
  153. l2Associativity- : LONGINT; (* encoded *)
  154. l2LinesPerTag- : LONGINT; (* AMD *)
  155. l2LineSize- : LONGINT;
  156. (** Extended function 7: Advanced Power Management Information *)
  157. powerManagement- : SET; (* AMD *)
  158. (** Extended function 8: Long Mode Address Size Identifiers *)
  159. linAddrSize- : LONGINT; (* maximum linear byte address size in bits *)
  160. physAddrSize- : LONGINT; (* maximum physical byte address size in bits *)
  161. apicIdCoreIdSize- : LONGINT; (* AMD *)
  162. numberOfCores- : LONGINT; (* AMD *)
  163. (** Extended function A: SVM Revision and Feature Identification *)
  164. svmRev- : LONGINT; (* AMD *)
  165. nasid- : LONGINT; (** AMD: Number of address space identifiers *)
  166. END;
  167. (** CPU identification *)
  168. PROCEDURE CPUID(function : LONGINT; VAR eax, ebx, ecx, edx : SET);
  169. CODE
  170. #IF I386 THEN
  171. MOV EAX, [EBP+function] ; CPUID function parameter
  172. MOV ESI, [EBP+ecx] ; required for INTEL standard function4.
  173. MOV ECX, [ESI]
  174. CPUID ; execute CPUID
  175. MOV ESI, [EBP+eax] ; copy EAX into eax
  176. MOV [ESI], EAX
  177. MOV ESI, [EBP+ebx] ; copy EBX into ebx
  178. MOV [ESI], EBX
  179. MOV ESI, [EBP+ecx] ; copy ECX into ecx
  180. MOV [ESI], ECX
  181. MOV ESI, [EBP+edx] ; copy EDX into edx
  182. MOV [ESI], EDX
  183. #ELSIF AMD64 THEN
  184. MOV EAX, [RBP + function] ; CPUID function parameter
  185. MOV RSI, [RBP + ecx] ; required for INTEL standard function4.
  186. MOV ECX, [RSI]
  187. CPUID ; execute CPUID
  188. MOV RSI, [RBP + eax] ; copy EAX into eax
  189. MOV [RSI], EAX
  190. MOV RSI, [RBP + ebx] ; copy EBX into ebx
  191. MOV [RSI], EBX
  192. MOV RSI, [RBP + ecx] ; copy ECX into ecx
  193. MOV [RSI], ECX
  194. MOV RSI, [RBP + edx] ; copy EDX into edx
  195. MOV [RSI], EDX
  196. #ELSE
  197. unimplemented
  198. #END
  199. END CPUID;
  200. (* If the CPUID instruction is supported, the ID flag (bit 21) of the EFLAGS register is r/w *)
  201. PROCEDURE CpuIdSupported() : BOOLEAN;
  202. CODE
  203. #IF I386 THEN
  204. PUSHFD ; save EFLAGS
  205. POP EAX ; store EFLAGS in EAX
  206. MOV EBX, EAX ; save EBX for later testing
  207. XOR EAX, 00200000H ; toggle bit 21
  208. PUSH EAX ; push to stack
  209. POPFD ; save changed EAX to EFLAGS
  210. PUSHFD ; push EFLAGS to TOS
  211. POP EAX ; store EFLAGS in EAX
  212. CMP EAX, EBX ; see if bit 21 has changed
  213. SETNE AL; ; return TRUE if bit 21 has changed, FALSE otherwise
  214. #ELSIF AMD64 THEN
  215. PUSHFQ ; save RFLAGS
  216. POP RAX ; store RFLAGS in RAX
  217. MOV RBX, RAX ; save RBX for later testing
  218. XOR RAX, 00200000H ; toggle bit 21
  219. PUSH RAX ; push to stack
  220. POPFQ ; save changed RAX to RFLAGS
  221. PUSHFQ ; push RFLAGS to TOS
  222. POP RAX ; store RFLAGS in RAX
  223. CMP RAX, RBX ; see if bit 21 has changed
  224. SETNE AL; ; return TRUE if bit 21 has changed, FALSE otherwise
  225. #ELSE
  226. unimplemented
  227. #END
  228. END CpuIdSupported;
  229. (* Standard Function 0: Processor Vendor and Largest Standard Function Number *)
  230. PROCEDURE StandardFunction0(VAR cpuInfo: CpuInformation);
  231. VAR eax, ebx, ecx, edx : SET;
  232. BEGIN
  233. CPUID(0H, eax, ebx, ecx, edx);
  234. cpuInfo.largestStandardFunction := SYSTEM.VAL(LONGINT, eax);
  235. GetString(cpuInfo.vendor, 0, ebx);
  236. GetString(cpuInfo.vendor, 4, edx);
  237. GetString(cpuInfo.vendor, 8, ecx);
  238. cpuInfo.vendor[12] := 0X;
  239. IF cpuInfo.vendor = "GenuineIntel" THEN cpuInfo.cputype := Intel;
  240. ELSIF cpuInfo.vendor = "AuthenticAMD" THEN cpuInfo.cputype := Amd;
  241. ELSE cpuInfo.cputype := Other;
  242. END;
  243. END StandardFunction0;
  244. (* Standard Function 1: Family, Model, Stepping Identifiers *)
  245. PROCEDURE StandardFunction1(VAR cpuInfo : CpuInformation);
  246. CONST
  247. ExtendedFamily = {20..27}; ExtendedModel = {16..19};
  248. BaseFamily = {8..11}; BaseModel = {4..7}; BaseStepping = {0..3};
  249. LocalApicId = {24..31}; LogicalProcessorCount = {16..23}; CLFlush = {8..15}; BrandId = {0..7};
  250. VAR
  251. eax, ebx, ecx, edx : SET;
  252. BEGIN
  253. CPUID(1H, eax, ebx, ecx, edx);
  254. (* EAX *)
  255. cpuInfo.stepping := SYSTEM.VAL(LONGINT, eax * BaseStepping);
  256. cpuInfo.model := SYSTEM.VAL(LONGINT, LSH(eax * BaseModel, -4));
  257. cpuInfo.family := SYSTEM.VAL(LONGINT, LSH(eax * BaseFamily, -8));
  258. IF cpuInfo.family < 0FH THEN
  259. cpuInfo.family := cpuInfo.family + SYSTEM.VAL(LONGINT, LSH(eax * ExtendedFamily, -20));
  260. cpuInfo.model := cpuInfo.model + SYSTEM.VAL(LONGINT, LSH(eax * ExtendedModel, -12));
  261. END;
  262. (* EBX *)
  263. cpuInfo.localApicId := SYSTEM.VAL(LONGINT, LSH(ebx * LocalApicId, -24));
  264. cpuInfo.logicalProcessorCount := SYSTEM.VAL(LONGINT, LSH(ebx * LogicalProcessorCount, - 16));
  265. cpuInfo.clflushSize := SYSTEM.VAL(LONGINT, LSH(ebx * CLFlush, -8)) * 8;
  266. cpuInfo.brandId := SYSTEM.VAL(LONGINT, ebx * BrandId);
  267. (* ECX *)
  268. cpuInfo.features2 := ecx;
  269. (* EDX *)
  270. cpuInfo.features := edx;
  271. IF cpuInfo.cputype = Intel THEN
  272. cpuInfo.type := SYSTEM.VAL(LONGINT, LSH(edx * {12..13}, -12));
  273. END;
  274. END StandardFunction1;
  275. (** INTEL: Standard Function 4: deterministic cache parameters
  276. Cache Type: eax*{0..4}
  277. 0 = Null, no more caches
  278. 1 = Data Cache
  279. 2 = Instruction Cache
  280. 3 = Unified Cache
  281. 4-31 = Reserved
  282. *)
  283. PROCEDURE IntelStandardFunction4(wr: Streams.Writer );
  284. VAR
  285. eax, ebx, ecx, edx : SET;
  286. cores, threads, cachelevel, cachetype: LONGINT;
  287. selfinit, fullassoc, waysofassoc, physlinepart, syscoherline, numofsets, prefetchstride: LONGINT;
  288. cachesize: LONGINT;
  289. k: LONGINT;
  290. BEGIN
  291. k := 0;
  292. LOOP (* iterate over ecx = 0,1,2,3.. until eax*{0..4}=0 *)
  293. ecx := SYSTEM.VAL(SET,k) ;
  294. CPUID(4H, eax, ebx,ecx, edx);
  295. cachetype := SYSTEM.VAL(LONGINT, eax *{0..4});
  296. IF cachetype=0 THEN EXIT; END;
  297. wr.String("CacheType: "); wr.Int(cachetype,0);
  298. IF cachetype=1 THEN wr.String(" [Data Cache]");
  299. ELSIF cachetype=2 THEN wr.String(" [Instruction Cache]");
  300. ELSIF cachetype=3 THEN wr.String(" [Unified Cache]");
  301. ELSIF cachetype=4 THEN wr.String(" [Reserved]");
  302. END;
  303. wr.Ln;
  304. cachelevel := SYSTEM.VAL(LONGINT, LSH(eax *{5..7} , -5));
  305. wr.String("Cache Level: "); wr.Int(cachelevel,0); wr.Ln;
  306. cores := SYSTEM.VAL(LONGINT, LSH(eax *{26..31}, -26)) + 1;
  307. threads := SYSTEM.VAL(LONGINT, LSH(eax *{14..25} , -14)) +1;
  308. fullassoc := SYSTEM.VAL(LONGINT, LSH(eax *{9},-9));
  309. selfinit := SYSTEM.VAL(LONGINT, LSH(eax *{8},-8));
  310. waysofassoc := SYSTEM.VAL(LONGINT, LSH(ebx *{22..31},-22)) +1;
  311. physlinepart := SYSTEM.VAL(LONGINT, LSH(ebx *{12..21},-12)) +1;
  312. syscoherline := SYSTEM.VAL(LONGINT, ebx *{0..11}) +1 ;
  313. numofsets := SYSTEM.VAL(LONGINT, ecx ) +1;
  314. prefetchstride := SYSTEM.VAL(LONGINT, edx*{0..9} );
  315. wr.String("Maximum number of processor cores per package: "); wr.Int(cores,0); wr.Ln;
  316. wr.String("Maximum number of threads sharing this cache: "); wr.Int(threads,0); wr.Ln;
  317. wr.String("Full Associative cache: "); wr.Int(fullassoc,0); wr.Ln;
  318. wr.String("Self initializing cache: "); wr.Int(selfinit,0); wr.Ln;
  319. wr.String("Ways of associativity: "); wr.Int(waysofassoc,0); wr.Ln;
  320. wr.String("Physical line partitions: "); wr.Int(physlinepart,0); wr.Ln;
  321. wr.String("System coherency line: "); wr.Int(syscoherline,0); wr.Ln;
  322. wr.String("Number of sets: "); wr.Int(numofsets,0); wr.Ln;
  323. wr.String("Prefetch stride: "); wr.Int(prefetchstride,0); wr.Ln;
  324. cachesize:= waysofassoc * physlinepart * syscoherline * numofsets;
  325. wr.String("This Cache Size (Bytes) : "); wr.Int(cachesize,0); wr.Ln;
  326. wr.String("****************************"); wr.Ln;
  327. wr.Update;
  328. INC(k);
  329. END;
  330. END IntelStandardFunction4;
  331. (** INTEL: MONITOR/ MWAIT Parameters *)
  332. PROCEDURE IntelStandardFunction5(w: Streams.Writer);
  333. VAR
  334. eax, ebx, ecx, edx : SET;
  335. smallestMon, largestMon : LONGINT;
  336. supporttreatingInterrup, supportMonMwait: BOOLEAN;
  337. numofC0, numofC1, numofC2, numofC3, numofC4: LONGINT;
  338. BEGIN
  339. CPUID(5H, eax, ebx,ecx, edx);
  340. smallestMon := SYSTEM.VAL(LONGINT, eax*{0..15});
  341. largestMon := SYSTEM.VAL(LONGINT, ebx*{0..15} );
  342. supporttreatingInterrup := SYSTEM.VAL(BOOLEAN,LSH(ecx*{1},-1));
  343. supportMonMwait := SYSTEM.VAL(BOOLEAN,ecx*{0});
  344. numofC4 := SYSTEM.VAL(LONGINT,LSH(edx*{16..19},-16));
  345. numofC3 := SYSTEM.VAL(LONGINT,LSH(edx*{12..15},-12));
  346. numofC2 := SYSTEM.VAL(LONGINT,LSH(edx*{8..11},-8));
  347. numofC1 := SYSTEM.VAL(LONGINT,LSH(edx*{4..7},-4));
  348. numofC0 := SYSTEM.VAL(LONGINT, edx*{0..3});
  349. w.String("Smallest Monitor size (bytes) = "); w.Int(smallestMon, 0 ); w.Ln;
  350. w.String("Largest Monitor size (bytes) = "); w.Int(largestMon, 0 ); w.Ln;
  351. w.String("Support treating Interrupt as break-events for MOITOR/MWAIT : ");
  352. IF supporttreatingInterrup THEN w.String("TRUE") ELSE w.String("FALSE") END;
  353. w.Ln;
  354. w.String(" MOITOR/MWAIT extensions supported : ");
  355. IF supportMonMwait THEN w.String("TRUE") ELSE w.String("FALSE") END;
  356. w.Ln;
  357. w.String(" Number of C4 sub states supported : "); w.Int(numofC4, 0); w.Ln;
  358. w.String(" Number of C3 sub states supported : "); w.Int(numofC3, 0); w.Ln;
  359. w.String(" Number of C2 sub states supported : "); w.Int(numofC2, 0); w.Ln;
  360. w.String(" Number of C1 sub states supported : "); w.Int(numofC1, 0); w.Ln;
  361. w.String(" Number of C0 sub states supported : "); w.Int(numofC0, 0); w.Ln;
  362. w.Update;
  363. END IntelStandardFunction5;
  364. (** INTEL: Digital Termal Sensor and Power Management Parameters *)
  365. PROCEDURE IntelStandardFunction6(w: Streams.Writer);
  366. VAR
  367. eax, ebx, ecx, edx : SET;
  368. digitalTermalSensorCapabilitiy: LONGINT;
  369. numberofInterruptThreshold: LONGINT;
  370. hardwareCoordFeedbackCap: LONGINT;
  371. BEGIN
  372. CPUID(6H, eax, ebx,ecx, edx);
  373. digitalTermalSensorCapabilitiy := SYSTEM.VAL(LONGINT, eax*{0});
  374. numberofInterruptThreshold := SYSTEM.VAL(LONGINT, ebx*{0..3} );
  375. hardwareCoordFeedbackCap := SYSTEM.VAL(LONGINT, ecx*{0});
  376. w.String("Digital termal Sensor Capabilitiy = "); w.Int(digitalTermalSensorCapabilitiy,0 ); w.Ln;
  377. w.String("Number of Interrupt Thresholds = "); w.Int(numberofInterruptThreshold,0 ); w.Ln;
  378. w.String("Hardware Coordination Feedback Capablity = "); w.Int(hardwareCoordFeedbackCap,0 ); w.Ln;
  379. w.Update;
  380. END IntelStandardFunction6;
  381. (** INTEL: Direct Cache Access (DCA) Parameters *)
  382. PROCEDURE IntelStandardFunction9(w: Streams.Writer);
  383. VAR
  384. eax, ebx, ecx, edx : SET;
  385. BEGIN
  386. CPUID(9H, eax, ebx,ecx, edx);
  387. w.String("Value of PLATFORM_DCA_CAP MSR Bits : "); w.Set(eax); w.Ln;
  388. (* w.String("ebx: RESERVED: "); w.Set(ebx); w.Ln;
  389. w.String("ecx: RESERVED: "); w.Set(ecx); w.Ln;
  390. w.String("edx: RESERVED: "); w.Set(edx); w.Ln;
  391. *)
  392. w.Update;
  393. END IntelStandardFunction9;
  394. (** INTEL: Architectural Performance Monitor Features *)
  395. PROCEDURE IntelStandardFunction0A(w: Streams.Writer);
  396. VAR
  397. eax, ebx, ecx, edx : SET;
  398. lenEBX: LONGINT;
  399. bitwidthCounter: LONGINT;
  400. numberofCountCore: LONGINT;
  401. verID: LONGINT;
  402. brachMispredict: LONGINT;
  403. branchInstruct: LONGINT;
  404. cacheMisses: LONGINT;
  405. cacheReference: LONGINT;
  406. referenceCycle: LONGINT;
  407. instructionRetired: LONGINT;
  408. CoreCycle: LONGINT;
  409. bitwidthFunction: LONGINT;
  410. numberofFunction: LONGINT;
  411. BEGIN
  412. CPUID(0AH, eax, ebx,ecx, edx);
  413. lenEBX := SYSTEM.VAL(LONGINT, LSH(eax * {24..31}, -24));
  414. bitwidthCounter:=SYSTEM.VAL(LONGINT, LSH(eax * {16..23}, -16));
  415. numberofCountCore:=SYSTEM.VAL(LONGINT, LSH(eax * {8..15}, -8));
  416. verID := SYSTEM.VAL(LONGINT,eax*{0..7});
  417. brachMispredict:=SYSTEM.VAL(LONGINT,LSH(ebx*{6},-6) );
  418. branchInstruct:=SYSTEM.VAL(LONGINT,LSH(ebx*{5},-5) );
  419. cacheMisses:=SYSTEM.VAL(LONGINT,LSH(ebx*{4},-4) );
  420. cacheReference := SYSTEM.VAL(LONGINT,LSH(ebx*{3},-3) );
  421. referenceCycle := SYSTEM.VAL(LONGINT,LSH(ebx*{2},-2) );
  422. instructionRetired := SYSTEM.VAL(LONGINT,LSH(ebx*{1},-1) );
  423. CoreCycle := SYSTEM.VAL(LONGINT,ebx*{0} );
  424. bitwidthFunction := SYSTEM.VAL(LONGINT,LSH(ecx*{5..12},-5) );
  425. numberofFunction :=SYSTEM.VAL(LONGINT,ecx*{0..4} );
  426. w.String("Length of EBX bit vector = "); w.Int(lenEBX ,0 ); w.Ln;
  427. w.String("Bit width of counter = "); w.Int(bitwidthCounter,0 ); w.Ln;
  428. w.String("Number of counter per logical processor = "); w.Int(numberofCountCore,0 );w.Ln;
  429. w.String("Version ID = "); w.Int(verID ,0 );w.Ln;
  430. w.String("Branch mispredict retired event = "); w.Int(brachMispredict,0 );w.Ln;
  431. w.String("Branch Instruction retired event = "); w.Int(branchInstruct,0 );w.Ln;
  432. w.String("Last-level cache misses event = "); w.Int(cacheMisses,0 );w.Ln;
  433. w.String("Last-level cache reference event = "); w.Int(cacheReference ,0 );w.Ln;
  434. w.String("Reference cycles event = "); w.Int(referenceCycle ,0 );w.Ln;
  435. w.String("Instruction retired event = "); w.Int(instructionRetired ,0 );w.Ln;
  436. w.String("Core cycle event = "); w.Int(CoreCycle ,0 );w.Ln;
  437. w.String("Bit width of fixed-function performance counters = "); w.Int(bitwidthFunction ,0 );w.Ln;
  438. w.String("Number of fixed-function performance counters ="); w.Int(numberofFunction ,0 );w.Ln;
  439. w.Update;
  440. END IntelStandardFunction0A;
  441. PROCEDURE ExtendedFunction0(VAR cpuInfo : CpuInformation);
  442. VAR eax, ebx, ecx, edx : SET;
  443. BEGIN
  444. eax := {};
  445. CPUID(LONGINT(80000000H), eax, ebx, ecx, edx);
  446. (* The largest extended function as value from offset 8000000H. Since we don't have unsigned integers, ignore the MSB *)
  447. cpuInfo.largestExtendedFunction := SYSTEM.VAL(LONGINT, eax - {31});
  448. (* ebx, ecx & edx contain the same information as in standard function 0 *)
  449. END ExtendedFunction0;
  450. PROCEDURE ExtendedFunction1(VAR cpuInfo : CpuInformation);
  451. VAR eax, ebx, ecx, edx : SET;
  452. BEGIN
  453. CPUID(LONGINT(80000001H), eax, ebx, ecx, edx);
  454. (* eax contains the same information as in standard function 1 *)
  455. (* ebx: brandid, ignore so far*)
  456. cpuInfo.extFeatures2 := ecx;
  457. cpuInfo.extFeatures := edx;
  458. END ExtendedFunction1;
  459. PROCEDURE ExtendedFunction2to4(VAR cpuInfo : CpuInformation);
  460. VAR eax, ebx, ecx, edx : SET;
  461. BEGIN
  462. CPUID(LONGINT(80000002H), eax, ebx, ecx, edx);
  463. GetString(cpuInfo.processorName, 0, eax);
  464. GetString(cpuInfo.processorName, 4, ebx);
  465. GetString(cpuInfo.processorName, 8, ecx);
  466. GetString(cpuInfo.processorName, 12, edx);
  467. IF cpuInfo.largestExtendedFunction < 3 THEN RETURN END;
  468. CPUID(LONGINT(80000003H), eax, ebx, ecx, edx);
  469. GetString(cpuInfo.processorName, 16, eax);
  470. GetString(cpuInfo.processorName, 20, ebx);
  471. GetString(cpuInfo.processorName, 24, ecx);
  472. GetString(cpuInfo.processorName, 28, edx);
  473. IF cpuInfo.largestExtendedFunction < 4 THEN RETURN END;
  474. CPUID(LONGINT(80000004H), eax, ebx, ecx, edx);
  475. GetString(cpuInfo.processorName, 32, eax);
  476. GetString(cpuInfo.processorName, 36, ebx);
  477. GetString(cpuInfo.processorName, 40, ecx);
  478. GetString(cpuInfo.processorName, 44, edx);
  479. END ExtendedFunction2to4;
  480. PROCEDURE AmdExtendedFunction5(VAR cpuInfo : CpuInformation);
  481. VAR eax, ebx, ecx, edx : SET;
  482. BEGIN
  483. CPUID(LONGINT(80000005H), eax, ebx, ecx, edx);
  484. (* EAX *)
  485. cpuInfo.l1DataTlbAssociativity2M4M := SYSTEM.VAL(LONGINT, LSH(eax * {24..31}, -24));
  486. cpuInfo.l1DataTlbSize2M4M := SYSTEM.VAL(LONGINT, LSH(eax * {16..23}, -16));
  487. cpuInfo. l1InstrTlbAssociativity2M4M := SYSTEM.VAL(LONGINT, LSH(eax * {8..15}, -8));
  488. cpuInfo. l1InstrTlbSize2M4M := SYSTEM.VAL(LONGINT, eax * {0..7});
  489. (* EBX *)
  490. cpuInfo.l1DataTlbAssociativity4K := SYSTEM.VAL(LONGINT, LSH(ebx * {24..31}, -24));
  491. cpuInfo.l1DataTlbSize4K := SYSTEM.VAL(LONGINT, LSH(ebx * {16..23}, -16));
  492. cpuInfo.l1InstrTlbAssociativity4K := SYSTEM.VAL(LONGINT, LSH(ebx * {8..15}, -8));
  493. cpuInfo.l1InstrTlbSize4K := SYSTEM.VAL(LONGINT, ebx * {0..7});
  494. (* ECX *)
  495. cpuInfo.l1DcSize := SYSTEM.VAL(LONGINT, LSH(ecx * {24..31}, -24));
  496. cpuInfo.l1DcAssociativity := SYSTEM.VAL(LONGINT, LSH(ecx * {16..23}, -16));
  497. cpuInfo.l1DcLinesPerTag := SYSTEM.VAL(LONGINT, LSH(ecx * {8..15}, -8));
  498. cpuInfo.l1DcLineSize := SYSTEM.VAL(LONGINT, ecx * {0..7});
  499. (* EDX *)
  500. cpuInfo.l1IcSize := SYSTEM.VAL(LONGINT, LSH(edx * {24..31}, -24));
  501. cpuInfo.l1IcAssociativity := SYSTEM.VAL(LONGINT, LSH(edx * {16..23}, -16));
  502. cpuInfo.l1IcLinesPerTag := SYSTEM.VAL(LONGINT, LSH(edx * {8..15}, -8));
  503. cpuInfo.l1IcLineSize := SYSTEM.VAL(LONGINT, edx * {0..7});
  504. END AmdExtendedFunction5;
  505. (** AMD: L2 Cache and TLB Identifiers *)
  506. PROCEDURE AmdExtendedFunction6(VAR cpuInfo : CpuInformation);
  507. VAR eax, ebx, ecx, edx : SET;
  508. BEGIN
  509. CPUID(LONGINT(80000006H), eax, ebx, ecx, edx);
  510. cpuInfo.unifiedTlb := (eax * {16..31} = {}) & (ebx * {16..31} = {});
  511. IF ~cpuInfo.unifiedTlb THEN
  512. cpuInfo.l2DataTlbAssociativity2M4M := SYSTEM.VAL(LONGINT, LSH(eax * {28..31}, -28));
  513. cpuInfo.l2DataTlbSize2M4M := SYSTEM.VAL(LONGINT, LSH(eax * {16..27}, -16));
  514. cpuInfo.l2InstrTlbAssociativity2M4M := SYSTEM.VAL(LONGINT, LSH(eax * {12..15}, -12));
  515. cpuInfo.l2InstrTlbSize2M4M := SYSTEM.VAL(LONGINT, eax * {0..11});
  516. END;
  517. cpuInfo.l2DataTlbAssociativity4K := SYSTEM.VAL(LONGINT, LSH(ebx * {28..31}, -28));
  518. cpuInfo.l2DataTlbSize4K := SYSTEM.VAL(LONGINT, LSH(ebx * {16..27}, -16));
  519. cpuInfo.l2InstrTlbAssociativity4K := SYSTEM.VAL(LONGINT, LSH(ebx * {12..15}, -12));
  520. cpuInfo.l2InstrTlbSize4K := SYSTEM.VAL(LONGINT, ebx * {0..11});
  521. cpuInfo.l2CacheSize := SYSTEM.VAL(LONGINT, LSH(ecx * {16..31}, -16));
  522. cpuInfo.l2Associativity := SYSTEM.VAL(LONGINT, LSH(ecx * {12..15}, -12));
  523. cpuInfo.l2LinesPerTag := SYSTEM.VAL(LONGINT, LSH(ecx * {8..11}, -8));
  524. cpuInfo.l2LineSize := SYSTEM.VAL(LONGINT, ecx * {0..7});
  525. END AmdExtendedFunction6;
  526. (* INTEL: Extended L2 Cache Features *)
  527. PROCEDURE IntelExtendedFunction6(VAR cpuInfo : CpuInformation);
  528. VAR eax, ebx, ecx, edx : SET;
  529. BEGIN
  530. CPUID(LONGINT(80000006H), eax, ebx, ecx, edx);
  531. cpuInfo.l2CacheSize := SYSTEM.VAL(LONGINT, LSH(ecx * {16..31}, -16));
  532. cpuInfo.l2Associativity := SYSTEM.VAL(LONGINT, LSH(ecx * {12..15}, -12));
  533. cpuInfo.l2LineSize := SYSTEM.VAL(LONGINT, ecx * {0..7});
  534. END IntelExtendedFunction6;
  535. (* AMD: Advanced Power Management Information *)
  536. PROCEDURE AmdExtendedFunction7(VAR cpuInfo : CpuInformation);
  537. VAR eax, ebx, ecx, edx : SET;
  538. BEGIN
  539. CPUID(LONGINT(80000007H), eax, ebx, ecx, edx);
  540. cpuInfo.powerManagement := edx;
  541. END AmdExtendedFunction7;
  542. (* Long Mode Address Size Identifiers *)
  543. PROCEDURE ExtendedFunction8(VAR cpuInfo : CpuInformation);
  544. VAR eax, ebx, ecx, edx : SET;
  545. BEGIN
  546. CPUID(LONGINT(80000008H), eax, ebx, ecx, edx);
  547. cpuInfo.linAddrSize := SYSTEM.VAL(LONGINT, LSH(eax * {8..15}, -8));
  548. cpuInfo.physAddrSize := SYSTEM.VAL(LONGINT, eax * {0..7});
  549. IF cpuInfo.cputype = Amd THEN
  550. cpuInfo.apicIdCoreIdSize := SYSTEM.VAL(LONGINT, LSH(ecx * {12..15}, -12));
  551. cpuInfo.numberOfCores := SYSTEM.VAL(LONGINT, ecx * {0..7}) + 1;
  552. END;
  553. END ExtendedFunction8;
  554. (* AMD: SVM Revision and Feature Identification *)
  555. PROCEDURE AmdExtendedFunctionA(VAR cpuInfo : CpuInformation);
  556. VAR eax, ebx, ecx, edx : SET;
  557. BEGIN
  558. CPUID(LONGINT(8000000AH), eax, ebx, ecx, edx);
  559. cpuInfo.svmRev := SYSTEM.VAL(LONGINT, eax * {0..7});
  560. cpuInfo.nasid := SYSTEM.VAL(LONGINT, ebx);
  561. END AmdExtendedFunctionA;
  562. PROCEDURE GetString(VAR string : ARRAY OF CHAR; offset : LONGINT; register : SET);
  563. BEGIN
  564. string[offset] :=CHR(SYSTEM.VAL(LONGINT, register * {0..7}));
  565. string[offset+1] := CHR(SYSTEM.VAL(LONGINT, LSH(register * {8..15}, -8)));
  566. string[offset+2] := CHR(SYSTEM.VAL(LONGINT, LSH(register * {16..23}, -16)));
  567. string[offset+3] := CHR(SYSTEM.VAL(LONGINT, LSH(register * {24..31}, -24)));
  568. END GetString;
  569. PROCEDURE GetCpuInformation(VAR cpuInfo : CpuInformation);
  570. BEGIN
  571. StandardFunction0(cpuInfo);
  572. IF cpuInfo.largestStandardFunction >= 1 THEN StandardFunction1(cpuInfo); END;
  573. ExtendedFunction0(cpuInfo);
  574. IF cpuInfo.largestExtendedFunction >= 1 THEN
  575. ExtendedFunction1(cpuInfo);
  576. IF cpuInfo.largestExtendedFunction >= 2 THEN
  577. ExtendedFunction2to4(cpuInfo);
  578. IF cpuInfo.largestExtendedFunction >= 5 THEN
  579. IF cpuInfo.cputype = Amd THEN AmdExtendedFunction5(cpuInfo); END;
  580. IF cpuInfo.largestExtendedFunction >= 6 THEN
  581. IF cpuInfo.cputype = Amd THEN
  582. AmdExtendedFunction6(cpuInfo);
  583. ELSE
  584. IntelExtendedFunction6(cpuInfo);
  585. END;
  586. IF cpuInfo.largestExtendedFunction >= 7 THEN
  587. IF cpuInfo.cputype = Amd THEN AmdExtendedFunction7(cpuInfo); END;
  588. IF cpuInfo.largestExtendedFunction >= 8 THEN
  589. ExtendedFunction8(cpuInfo);
  590. IF cpuInfo.largestExtendedFunction >= 0AH THEN
  591. IF cpuInfo.cputype = Amd THEN AmdExtendedFunctionA(cpuInfo); END;
  592. END;
  593. END;
  594. END;
  595. END;
  596. END;
  597. END;
  598. END;
  599. END GetCpuInformation;
  600. PROCEDURE ShowExtFeatures2Amd(w : Streams.Writer; register : SET);
  601. BEGIN
  602. IF AltMovCr8 IN register THEN w.String("[AltMovCR8]"); END;
  603. IF SVM IN register THEN w.String("[SVM]"); END;
  604. IF CmpLegacy IN register THEN w.String("[CMP legacy]"); END;
  605. IF LahfSahf IN register THEN w.String("[LahfSahf]"); END;
  606. END ShowExtFeatures2Amd;
  607. PROCEDURE ShowExtFeaturesAmd(w : Streams.Writer; register : SET);
  608. BEGIN
  609. IF Amd3DNow IN register THEN w.String("[3DNow!]"); END;
  610. IF Amd3DNowExt IN register THEN w.String("[3DNow!Ext]"); END;
  611. IF LM IN register THEN w.String("[LongMode]"); END;
  612. IF RDTSCP IN register THEN w.String("[RDTSCP]"); END;
  613. IF FFXSR IN register THEN w.String("[FFXSR]"); END;
  614. IF MmxExt IN register THEN w.String("[MMXExt]"); END;
  615. IF NX IN register THEN w.String("[NX]"); END;
  616. IF SysCallSysRet IN register THEN w.String("[SysCallSysRet]"); END;
  617. END ShowExtFeaturesAmd;
  618. PROCEDURE ShowPowerManagementAmd(w : Streams.Writer; register : SET);
  619. BEGIN
  620. IF AMD7_TscInvariant IN register THEN w.String("[TSCInvariant]"); END;
  621. IF AMD7_STC IN register THEN w.String("[STC]"); END;
  622. IF AMD7_TM IN register THEN w.String("[TM]"); END;
  623. IF AMD7_TTP IN register THEN w.String("[TTP]"); END;
  624. IF AMD7_VID IN register THEN w.String("[VID]"); END;
  625. IF AMD7_FID IN register THEN w.String("[FID]"); END;
  626. IF AMD7_TS IN register THEN w.String("[TS]"); END;
  627. END ShowPowerManagementAmd;
  628. PROCEDURE ShowLongModeAS(w : Streams.Writer; cpuInfo : CpuInformation);
  629. BEGIN
  630. w.String(" Maximum linear byte address size: "); w.Int(cpuInfo.linAddrSize, 0); w.String(" bits"); w.Ln;
  631. w.String(" Maximum physical byte address size: "); w.Int(cpuInfo.physAddrSize, 0); w.String(" bits"); w.Ln;
  632. IF cpuInfo.cputype = Amd THEN
  633. w.String(" APIC ID Core ID Size: "); w.Int(cpuInfo.apicIdCoreIdSize, 0); w.String(" bits"); w.Ln;
  634. w.String(" Number of CPU cores: "); w.Int(cpuInfo.numberOfCores, 0);
  635. END;
  636. END ShowLongModeAS;
  637. PROCEDURE ShowFeatures2(w : Streams.Writer; register : SET);
  638. BEGIN
  639. IF DCA IN register THEN w.String("[DCA]"); END; (* INTEL *)
  640. IF XTPR IN register THEN w.String("[xTPR]"); END; (* INTEL *)
  641. IF CMPXCHG16B IN register THEN w.String("[CMPXCHG16B]"); END;
  642. IF CID IN register THEN w.String("[CID]"); END; (* INTEL *)
  643. IF SSSE3 IN register THEN w.String("[SSSE3]"); END; (* INTEL *)
  644. IF TM2 IN register THEN w.String("[TM2]"); END; (* INTEL *)
  645. IF EST IN register THEN w.String("[EST]"); END; (* INTEL *)
  646. IF VMX IN register THEN w.String("[VMX]"); END; (* INTEL *)
  647. IF DS_CPL IN register THEN w.String("[DS_CPL]"); END; (* INTEL *)
  648. IF MONITOR IN register THEN w.String("[MONITOR]"); END; (* INTEL *)
  649. IF SSE3 IN register THEN w.String("[SSE3]"); END;
  650. IF DTES64 IN register THEN w.String("[DTES64]"); END; (* INTEL *)
  651. IF SSE4_2 IN register THEN w.String("[SSE4_2]"); END; (* INTEL *)
  652. IF SSE4_1 IN register THEN w.String("[SSE4_1]"); END; (* INTEL *)
  653. IF PDCM IN register THEN w.String("[PDCM]"); END; (* INTEL *)
  654. IF SMX IN register THEN w.String("[SMX]"); END; (* INTEL *)
  655. END ShowFeatures2;
  656. PROCEDURE ShowFeatures(w : Streams.Writer; register : SET);
  657. BEGIN
  658. IF PBE IN register THEN w.String("[PBE]"); END; (* INTEL *)
  659. IF IA64 IN register THEN w.String("[IA64]"); END; (* INTEL *)
  660. IF TM IN register THEN w.String("[TM]"); END; (* INTEL *)
  661. IF HTT IN register THEN w.String("[HTT]"); END;
  662. IF SS IN register THEN w.String("[SelfSnoop]"); END; (* INTEL *)
  663. IF SSE2 IN register THEN w.String("[SSE2]"); END;
  664. IF SSE IN register THEN w.String("[SSE]"); END;
  665. IF FXSR IN register THEN w.String("[FXSR]"); END;
  666. IF MMX IN register THEN w.String("[MMX]"); END;
  667. IF ACPI IN register THEN w.String("[ACPI]"); END; (* INTEL *)
  668. IF DS IN register THEN w.String("[DebugStore]"); END; (* INTEL *)
  669. IF CLFLUSH IN register THEN w.String("[CLFLUSH]"); END;
  670. IF PSN IN register THEN w.String("[ProcessorSerialNumber]"); END; (* INTEL *)
  671. IF PSE36 IN register THEN w.String("[PSE36]"); END;
  672. IF PAT IN register THEN w.String("[PAT]"); END;
  673. IF CMOV IN register THEN w.String("[CMOV]"); END;
  674. IF MCA IN register THEN w.String("[MCA]"); END;
  675. IF PGE IN register THEN w.String("[PGE]"); END;
  676. IF MTRR IN register THEN w.String("[MTRR]"); END;
  677. IF SysEnterSysExit IN register THEN w.String("[SysEnterSysExit]"); END;
  678. IF APIC IN register THEN w.String("[APIC]"); END;
  679. IF CMPXCH8B IN register THEN w.String("[CMPXCH8B]"); END;
  680. IF MCE IN register THEN w.String("[MCE]"); END;
  681. IF PAE IN register THEN w.String("[PAE]"); END;
  682. IF MSR IN register THEN w.String("[MSR]"); END;
  683. IF TSC IN register THEN w.String("[TSC]"); END;
  684. IF PSE IN register THEN w.String("[PSE]"); END;
  685. IF DE IN register THEN w.String("[DE]"); END;
  686. IF VME IN register THEN w.String("[VME]"); END;
  687. IF FPU IN register THEN w.String("[FPU]"); END;
  688. END ShowFeatures;
  689. PROCEDURE ShowL1Associativity(w : Streams.Writer; value : LONGINT);
  690. BEGIN
  691. IF value = 0 THEN w.String("Reserved");
  692. ELSIF value = 1 THEN w.String("Direct mapped");
  693. ELSIF value = 0FFH THEN w.String("Fully associative");
  694. ELSE
  695. w.Int(value, 0); w.String("-way associative");
  696. END;
  697. END ShowL1Associativity;
  698. PROCEDURE ShowL2Associativity(w : Streams.Writer; value : LONGINT);
  699. BEGIN
  700. IF value = 0 THEN w.String("disabled");
  701. ELSIF value = 1 THEN w.String("Direct mapped");
  702. ELSIF value = 2 THEN w.String("2-way associative");
  703. ELSIF value = 4 THEN w.String("4-way associative");
  704. ELSIF value = 6 THEN w.String("8-way associative");
  705. ELSIF value = 8 THEN w.String("16-way associative");
  706. ELSIF value = 0FH THEN w.String("Fully associative");
  707. ELSE w.String("unknown");
  708. END;
  709. END ShowL2Associativity;
  710. PROCEDURE AmdShowL1TlbAndCache(w : Streams.Writer; cpuInfo : CpuInformation);
  711. BEGIN
  712. w.String(" TLB: "); w.Ln;
  713. w.String(" 2M/4M Data TLB: "); w.Int(cpuInfo.l1DataTlbSize2M4M, 0); w.String(" entries, ");
  714. ShowL1Associativity(w, cpuInfo.l1DataTlbAssociativity2M4M);
  715. w.Ln;
  716. w.String(" 2M/4M Instr TLB: "); w.Int(cpuInfo.l1InstrTlbSize2M4M, 0); w.String(" entries, ");
  717. ShowL1Associativity(w, cpuInfo.l1InstrTlbAssociativity2M4M);
  718. w.Ln;
  719. w.String(" 4K Data TLB: "); w.Int(cpuInfo.l1DataTlbSize4K, 0); w.String(" entries, ");
  720. ShowL1Associativity(w, cpuInfo.l1DataTlbAssociativity4K);
  721. w.Ln;
  722. w.String(" 4K Instr TLB: "); w.Int(cpuInfo.l1InstrTlbSize4K, 0); w.String(" entries, ");
  723. ShowL1Associativity(w, cpuInfo.l1InstrTlbAssociativity4K);
  724. w.Ln;
  725. w.String(" Level 1 cache: "); w.Ln;
  726. w.String(" Data: "); w.Int(cpuInfo.l1DcSize, 0); w.String("KB, "); ShowL1Associativity(w, cpuInfo.l1DcAssociativity);
  727. w.String(", Lines per Tag: "); w.Int(cpuInfo.l1DcLinesPerTag, 0); w.String(", Line size: "); w.Int(cpuInfo.l1DcLineSize, 0);
  728. w.String(" Bytes");
  729. w.Ln;
  730. w.String(" Instr: "); w.Int(cpuInfo.l1IcSize, 0); w.String("KB, "); ShowL1Associativity(w, cpuInfo.l1IcAssociativity);
  731. w.String(", Lines per Tag: "); w.Int(cpuInfo.l1IcLinesPerTag, 0);
  732. w.String(", Line size: "); w.Int(cpuInfo.l1IcLineSize, 0); w.String(" Bytes");
  733. END AmdShowL1TlbAndCache;
  734. PROCEDURE AmdShowL2TlbAndCache(w : Streams.Writer; cpuInfo : CpuInformation);
  735. BEGIN
  736. w.String(" TLB: "); w.Ln;
  737. IF ~cpuInfo.unifiedTlb THEN
  738. w.String(" 2M/4M Data TLB: "); w.Int(cpuInfo.l2DataTlbSize2M4M, 0); w.String(" entries, ");
  739. ShowL2Associativity(w, cpuInfo.l2DataTlbAssociativity2M4M);
  740. w.Ln;
  741. w.String(" 2M/4M Instr TLB: "); w.Int(cpuInfo.l2InstrTlbSize2M4M, 0); w.String(" entries, ");
  742. ShowL2Associativity(w, cpuInfo.l2InstrTlbAssociativity2M4M);
  743. w.Ln;
  744. ELSE
  745. w.String("Unified TLB for 4K/2M/4M: "); w.Ln;
  746. END;
  747. w.String(" 4K Data TLB: "); w.Int(cpuInfo.l2DataTlbSize4K, 0); w.String(" entries, ");
  748. ShowL2Associativity(w, cpuInfo.l2DataTlbAssociativity4K);
  749. w.Ln;
  750. w.String(" 4K Instr TLB: "); w.Int(cpuInfo.l2InstrTlbSize4K, 0); w.String(" entries, ");
  751. ShowL2Associativity(w, cpuInfo.l2InstrTlbAssociativity4K);
  752. w.Ln;
  753. w.String(" Level 2 cache: "); w.Ln;
  754. w.String(" Size: "); w.Int(cpuInfo.l2CacheSize, 0); w.String("KB, ");
  755. ShowL2Associativity(w, cpuInfo.l2Associativity);
  756. IF cpuInfo.cputype = Amd THEN
  757. w.String(", Lines per Tag: "); w.Int(cpuInfo.l2LinesPerTag, 0);
  758. END;
  759. w.String(", Line size: "); w.Int(cpuInfo.l2LineSize, 0); w.String(" Bytes");
  760. END AmdShowL2TlbAndCache;
  761. PROCEDURE AmdShowSVM(w : Streams.Writer; cpuInfo : CpuInformation);
  762. BEGIN
  763. w.String(" SVM Revision: "); w.Hex(cpuInfo.svmRev, -2); w.String("H"); w.Ln;
  764. w.String(" Number of address space identifiers (ASID): "); w.Int(cpuInfo.nasid, 0); w.Ln;
  765. END AmdShowSVM;
  766. PROCEDURE IntelShowCacheDescriptors(w : Streams.Writer);
  767. VAR eax, ebx, ecx, edx : SET; i : LONGINT;
  768. PROCEDURE ShowReg(reg : SET; isEax : BOOLEAN);
  769. VAR s: ARRAY 128 OF CHAR;
  770. BEGIN
  771. IF ~(31 IN reg )THEN
  772. IF ~isEax THEN
  773. IF reg * {0..7} # {} THEN GetCacheIntel(w, SYSTEM.VAL(LONGINT, reg * {0..7}), s); w.String(s); w.Ln; END;
  774. END;
  775. IF reg * {8..15} # {} THEN GetCacheIntel(w, SYSTEM.VAL(LONGINT, LSH(reg * {8..15},-8)), s); w.String(s); w.Ln; END;
  776. IF reg * {16..23} # {} THEN GetCacheIntel(w, SYSTEM.VAL(LONGINT,LSH( reg * {16..23},-16)), s); w.String(s); w.Ln; END;
  777. IF reg * {24..31} # {} THEN GetCacheIntel(w, SYSTEM.VAL(LONGINT, LSH(reg * {24..31},-24)), s); w.String(s); w.Ln; END;
  778. END;
  779. END ShowReg;
  780. BEGIN
  781. CPUID(2H, eax, ebx, ecx, edx);
  782. ShowReg(eax, TRUE);
  783. ShowReg(ebx, FALSE);
  784. ShowReg(ecx, FALSE);
  785. ShowReg(edx, FALSE);
  786. i := SYSTEM.VAL(LONGINT, eax * {0..7}) - 1;
  787. WHILE (i > 0) DO
  788. CPUID(2H, eax, ebx, ecx, edx);
  789. ShowReg(eax, TRUE);
  790. ShowReg(ebx, FALSE);
  791. ShowReg(ecx, FALSE);
  792. ShowReg(edx, FALSE);
  793. DEC(i);
  794. END;
  795. END IntelShowCacheDescriptors;
  796. PROCEDURE GetCacheIntel*(w : Streams.Writer; value : LONGINT; VAR s: ARRAY OF CHAR);
  797. BEGIN
  798. CASE value OF
  799. |00H: s := "Null";
  800. |01H: s := "Instruction TLB: 4KB Pages, 4-way set associative, 32 entries";
  801. |02H: s := "Instruction TLB: 4MB Pages, fully associative, 2 entries";
  802. |03H: s := "Data TLB: 4KB Pages, 4-way set associative, 64 entries";
  803. |04H: s := "Data TLB: 4MB Pages, 4-way set associative, 8 entries";
  804. |05H: s := "DataTLB: 4MB Pages, 4-way set associative, 32 entries";
  805. |06H: s := "L1 instruction cache, 8KB, 4-way set associative, 32 byte line size";
  806. |08H: s := "L1 instruction cache, 16KB, 4-way set associative, 32-byte line size";
  807. |0AH: s := "L1 data cache, 8KB, 2-way set associative, 32-byte line size";
  808. |0CH: s := "L1 data cache, 16KB, 4-way set associative, 32-byte line size";
  809. |22H: s := "L3 cache, 512KB, 4-way set associative, sectored cache, 64-byte line size";
  810. |23H: s := "L3 cache, 1MB, 8-way set associative, sectored cache, 64-byte line size";
  811. |25H: s := "L3 cache, 2MB, 8-way set associative, sectored cache, 64-byte line size";
  812. |29H: s := "L3 cache, 4MB, 8-way set associative, sectored cache, 64-byte line size";
  813. |2CH: s := "L1 data cache, 32KB, 8-way set associative, 64-byte line size";
  814. |30H: s := "L1 instruction cache, 32KB, 8-way set associative, 64-byte line size";
  815. |39H: s := "L2 cache, 128KB, 4-way set associative, sectored cache, 64-byte line size";
  816. |3AH: s := "L2 cache, 192KB, 6-way set associative, sectored cache, 64-byte line size";
  817. |3BH: s := "L2 cache, 128KB, 2-way set associative, sectored cache, 64-byte line size";
  818. |3CH: s := "L2 cache, 256KB, 4-way set associative, sectored cache, 64-byte line size";
  819. |3DH: s := "L2 cache, 384KB, 6-way set associative, sectored cache, 64-byte line size";
  820. |3EH: s := "L2 cache, 512KB, 4-way set associative, sectored cache, 64-byte line size";
  821. |40H: s := "No L2 cache or, if processor contains valid L2 cache, no L2 cache";
  822. |41H: s := "L2 cache, 128KB, 4-way set associative, 32-byte line size";
  823. |42H: s := "L2 cache, 256KB, 4-way set associative, 32-byte line size";
  824. |43H: s := "L2 cache, 512KB, 4-way set associative, 32-byte line size";
  825. |44H: s := "L2 cache, 1MB, 4-way set associative, 32-byte line size";
  826. |45H: s := "L2 cache, 2MB, 4-way set associative, 32-byte line size";
  827. |46H: s := "L3 cache, 4MB, 4-way set associative, 64-byte line size";
  828. |47H: s := "L3 cache, 8MB, 8-way set associative, 64-byte line size";
  829. |49H: s := "L2 cache, 4MB, 16-way set associative, 64-byte line size";
  830. |4AH: s := "L3 cache, 6MB, 12-way set associative, 64-byte line size";
  831. |4BH: s := "L3 cache, 8MB, 16-way set associative, 64-byte line size";
  832. |4CH: s := "L3 cache, 12MB, 12-way set associative, 64-byte line size";
  833. |4DH: s := "L3 cache, 16MB, 16-way set associative, 64-byte line size";
  834. |4EH: s:="2nd-level cache: 6MB, 24-way set associative, 64-byte line size";
  835. |50H: s := "Instruction TLB: 4KB, 2MB or 4MB pages, fully associative, 64 entries";
  836. |51H: s := "Instruction TLB: 4KB, 2MB or 4MB pages, fully associative, 128 entries";
  837. |52H: s := "Instruction TLB: 4KB, 2MB or 4MB pages, fully associative, 256 entries";
  838. |56H: s := "L0 Data TLB: 4MB pages, 4-way set associative, 16 entries";
  839. |57H: s := "L0 Data TLB: 4KB pages, 4-way set associative, 16 entries";
  840. |5BH: s := "Data TLB: 4KB or 4MB pages, fully associative, 64 entries";
  841. |5CH: s := "Data TLB: 4KB or 4MB pages, fully associative, 128 entries";
  842. |5DH: s := "Data TLB: 4KB or 4MB pages, fully associative, 256 entries";
  843. |60H: s := "L1 data cache, 16KB, 8-way set associative, sectored cache, 64-byte line size";
  844. |66H: s := "L1 data cache, 8KB, 4-way set associative, sectored cache, 64-byte line size";
  845. |67H: s := "L1 data cache, 16KB, 4-way set associative, sectored cache, 64-byte line size";
  846. |68H: s := "L1 data cache, 32KB, 4-way set associative, sectored cache, 64-byte line size";
  847. |70H: s := "Trace cache: 12 Kuops, 8-way set associative";
  848. |71H: s := "Trace cache: 16 Kuops, 8-way set associative";
  849. |72H: s := "Trace cache: 32 Kuops, 8-way set associative";
  850. |73H: s := "Trace cache: 64 Kuops, 8-way set associative";
  851. |78H: s := "L2 cache, 1MB, 4-way set associative, 64-byte line size";
  852. |79H: s := "L2 cache, 128KB, 8-way set associative, sectored cache, 64-byte line size";
  853. |7AH: s := "L2 cache, 256KB, 8-way set associative, sectored cache, 64-byte line size";
  854. |7BH: s := "L2 cache, 512KB, 8-way set associative, sectored cache, 64-byte line size";
  855. |7CH: s := "L2 cache, 1MB, 8-way set associative, sectored cache, 64-byte line size";
  856. |7DH: s := "L2 cache, 2MB, 8-way set associative, 64-byte line size";
  857. |7FH: s := "L2 cache, 512KB, 2-way set associative, 64-byte line size";
  858. |82H: s := "L2 cache, 256KB, 8-way set associative, 32-byte line size";
  859. |83H: s := "L2 cache, 512KB, 8-way set associative, 32-byte line size";
  860. |84H: s := "L2 cache, 1MB, 8-way set associative, 32-byte line size";
  861. |85H: s := "L2 cache, 2MB, 8-way set associative, 32-byte line size";
  862. |86H: s := "L2 cache, 512KB, 4-way set associative, 64-byte line size";
  863. |87H: s := "L2 cache, 1MB, 8-way set associative, 64-byte line size";
  864. |0B0H: s := "Instruction TLB: 4KB Pages, 4-way set associative, 128 entries";
  865. |0B1H: s := "Instruction TLB: 2M/4M pages, 4-way set associative, 2M: 4 entries, 4M: 8 entries";
  866. |0B3H: s := "Data TLB: 4KB pages, 4-way set associative, 128 entries";
  867. |0B4H: s := "Data TLB: 4KB pages, 4-way set associative, 256 entries";
  868. |0F0H: s := "64-byte Prefetching";
  869. |0F1H: s := "128-byte Prefetching";
  870. ELSE
  871. s := "Entry not defined";
  872. END;
  873. END GetCacheIntel;
  874. PROCEDURE IntelShowL2TlbAndCache(w : Streams.Writer; cpuInfo : CpuInformation);
  875. BEGIN
  876. w.String(" Level 2 cache: "); w.Ln;
  877. w.String(" Size: "); w.Int(cpuInfo.l2CacheSize, 0); w.String("KB, ");
  878. ShowL2Associativity(w, cpuInfo.l2Associativity);
  879. w.String(", Line size: "); w.Int(cpuInfo.l2LineSize, 0); w.String(" Bytes"); w.Ln;
  880. END IntelShowL2TlbAndCache;
  881. PROCEDURE ShowDetailedCpuInformation(w : Streams.Writer; cpuInfo : CpuInformation);
  882. BEGIN
  883. w.String("Standard Function 0: Processor Vendor and Largest Standard Function: "); w.Ln;
  884. w.String(" Vendor: "); w.String(cpuInfo.vendor); w.Ln;
  885. w.String(" Largest Standard Function: "); w.Int(cpuInfo.largestStandardFunction, 0); w.Ln;
  886. w.Ln;
  887. IF cpuInfo.largestStandardFunction >= 1 THEN
  888. w.String("Standard Function 1: Family, Model, Stepping Identifiers: "); w.Ln;
  889. w.String(" Family: "); w.Hex(cpuInfo.family, -2); w.String("H, Model: "); w.Hex(cpuInfo.model, -2);
  890. w.String("H, Stepping: "); w.Hex(cpuInfo.stepping, -2); w.Char("H");
  891. IF cpuInfo.cputype = Intel THEN
  892. w.String(", type: "); w.Int(cpuInfo.type, 0);
  893. CASE cpuInfo.type OF
  894. |0: w.String(" (Original OEM processor)");
  895. |1: w.String(" (OverDrive processor)");
  896. |2: w.String(" (Dual processor)");
  897. |3: w.String(" (Intel reserved)");
  898. ELSE
  899. w.String(" (Out of range)");
  900. END;
  901. END;
  902. w.Ln;
  903. w.String(" Local APIC Initial ID: "); w.Int(cpuInfo.localApicId, 0);
  904. w.String(", Logical processor count: "); w.Int(cpuInfo.logicalProcessorCount, 0);
  905. w.Ln;
  906. w.String(" CLFLUSH line size: "); w.Int(cpuInfo.clflushSize, 0); w.String(" Bytes");
  907. w.String(", BrandId: "); w.Int(cpuInfo.brandId, 0);
  908. w.Ln;
  909. w.String(" Features: "); ShowFeatures2(w, cpuInfo.features2); ShowFeatures(w, cpuInfo.features); w.Ln;
  910. w.Ln;
  911. END;
  912. IF (cpuInfo.largestStandardFunction >= 2) & (cpuInfo.cputype = Intel) THEN
  913. w.String("Standard Function 2: Cache Descriptors: "); w.Ln;
  914. IntelShowCacheDescriptors(w);
  915. w.Ln;
  916. END;
  917. IF (cpuInfo.largestStandardFunction >=4) THEN
  918. IF cpuInfo.cputype=Intel THEN
  919. w.String("INTEL Standard Function 4: Deterministic Cache Parameters : "); w.Ln;
  920. IntelStandardFunction4(w);
  921. w.Ln;
  922. END;
  923. END;
  924. IF (cpuInfo.largestStandardFunction >=5) THEN
  925. IF cpuInfo.cputype=Intel THEN
  926. w.String("INTEL Standard Function 5: MONITOR/ MWAIT Parameters : "); w.Ln;
  927. IntelStandardFunction5(w);
  928. w.Ln;
  929. END;
  930. END;
  931. IF (cpuInfo.largestStandardFunction >=6) THEN
  932. IF cpuInfo.cputype=Intel THEN
  933. w.String("INTEL Standard Function 6: Digital Termal Sensor and Power Management Parameters : "); w.Ln;
  934. IntelStandardFunction6(w);
  935. w.Ln;
  936. END;
  937. END;
  938. IF (cpuInfo.largestStandardFunction >=9) THEN
  939. IF cpuInfo.cputype=Intel THEN
  940. w.String("INTEL: Direct Cache Access (DCA) Parameters : "); w.Ln;
  941. IntelStandardFunction9(w);
  942. w.Ln;
  943. END;
  944. END;
  945. IF (cpuInfo.largestStandardFunction >9) THEN
  946. IF cpuInfo.cputype=Intel THEN
  947. w.String("INTEL Standard Function 0A: Architectural Performance Monitor Features: "); w.Ln;
  948. IntelStandardFunction0A(w);
  949. w.Ln;
  950. END;
  951. END;
  952. w.String("Extended Function 0: Largest Extended Function: "); w.Ln;
  953. w.String(" Largest Extended Function: "); w.Int(cpuInfo.largestExtendedFunction, 0); w.Ln;
  954. w.Ln;
  955. IF cpuInfo.largestExtendedFunction >= 1 THEN
  956. w.String("Extended Function 1: Features: "); w.Ln;
  957. w.String(" Extended features: "); ShowExtFeatures2Amd(w, cpuInfo.extFeatures2); ShowExtFeaturesAmd(w, cpuInfo.extFeatures); w.Ln;
  958. w.Ln;
  959. END;
  960. IF cpuInfo.largestExtendedFunction >= 2 THEN
  961. w.String("Extended Function 2-4: Processor Name: "); w.Ln;
  962. w.String(" Processor Name: "); w.String(cpuInfo.processorName); w.Ln;
  963. w.Ln;
  964. END;
  965. IF cpuInfo.largestExtendedFunction < 5 THEN RETURN; END;
  966. IF cpuInfo.cputype = Amd THEN
  967. w.String("AMD Extended Function 5: L1 Cache and TLB Identifiers: "); w.Ln;
  968. AmdShowL1TlbAndCache(w, cpuInfo); w.Ln;
  969. w.Ln;
  970. END;
  971. IF cpuInfo.largestExtendedFunction < 6 THEN RETURN; END;
  972. IF cpuInfo.cputype = Amd THEN
  973. w.String("AMD Extended Function 6: L2 Cache and TLB Identifiers: "); w.Ln;
  974. AmdShowL2TlbAndCache(w, cpuInfo); w.Ln;
  975. w.Ln;
  976. ELSIF cpuInfo.cputype=Intel THEN
  977. w.String("INTEL Extended Function 6: L2 Cache Features: "); w.Ln;
  978. IntelShowL2TlbAndCache(w, cpuInfo);
  979. w.Ln;
  980. END;
  981. IF cpuInfo.largestExtendedFunction < 7 THEN RETURN END;
  982. IF cpuInfo.cputype = Amd THEN
  983. w.String("AMD Extended Function 7: Advanced Power Management Information: "); w.Ln;
  984. w.String(" Features: "); ShowPowerManagementAmd(w, cpuInfo.powerManagement); w.Ln;
  985. w.Ln;
  986. END;
  987. IF cpuInfo.largestExtendedFunction < 8 THEN RETURN; END;
  988. IF (cpuInfo.cputype = Amd) OR (cpuInfo.cputype=Intel) THEN
  989. w.String("Extended Function 8: Long Mode Address Size Identifiers: "); w.Ln;
  990. ShowLongModeAS(w, cpuInfo); w.Ln;
  991. w.Ln;
  992. END;
  993. IF cpuInfo.largestExtendedFunction < 0AH THEN RETURN END;
  994. IF cpuInfo.cputype = Amd THEN
  995. w.String("AMD Extended Function A: SVM Revision and Feature Identification: "); w.Ln;
  996. AmdShowSVM(w, cpuInfo); w.Ln;
  997. w.Ln;
  998. END;
  999. END ShowDetailedCpuInformation;
  1000. PROCEDURE ShowCpuInformation(w : Streams.Writer; cpuInfo : CpuInformation);
  1001. PROCEDURE ShowFlag(flag : LONGINT; register : SET);
  1002. BEGIN
  1003. IF flag IN register THEN w.String("Yes"); ELSE w.String("No"); END;
  1004. END ShowFlag;
  1005. BEGIN
  1006. IF cpuInfo.largestExtendedFunction >= 2 THEN
  1007. w.String("Prozessor: "); w.String(cpuInfo.processorName); w.Ln;
  1008. END;
  1009. w.String(" Vendor: "); w.String(cpuInfo.vendor);
  1010. IF cpuInfo.largestStandardFunction >= 1 THEN
  1011. w.String(", Family: "); w.Hex(cpuInfo.family, -2); w.Char("H");
  1012. w.String(", Model: "); w.Hex(cpuInfo.model, -2); w.Char("H");
  1013. w.String(", Stepping: "); w.Hex(cpuInfo.stepping, -2); w.Char("H");
  1014. w.Ln;
  1015. IF HTT IN cpuInfo.features THEN
  1016. w.String("Logical processor count: "); w.Int(cpuInfo.logicalProcessorCount, 0); w.Ln;
  1017. END;
  1018. w.String("Features: "); w.Ln;
  1019. w.String(" MMX: "); ShowFlag(MMX, cpuInfo.features);
  1020. w.String(", SSE: "); ShowFlag(SSE, cpuInfo.features);
  1021. w.String(", SSE2: "); ShowFlag(SSE2, cpuInfo.features);
  1022. w.String(", SSE3: "); ShowFlag(SSE3, cpuInfo.features2);
  1023. w.String(", Supplemental SSE3: "); ShowFlag(SSSE3, cpuInfo.features2);
  1024. END;
  1025. w.Ln;
  1026. IF cpuInfo.largestExtendedFunction >= 1 THEN
  1027. w.String(" Extended 3DNow!: "); ShowFlag(Amd3DNowExt, cpuInfo.extFeatures);
  1028. w.String(", 3DNow!: "); ShowFlag(Amd3DNow, cpuInfo.extFeatures);
  1029. w.String(", AMD MMX Extensions: "); ShowFlag(MmxExt, cpuInfo.extFeatures);
  1030. w.Ln;
  1031. w.String(" 64bit instructions: "); ShowFlag(LM, cpuInfo.extFeatures);
  1032. w.Ln;
  1033. END;
  1034. IF (cpuInfo.cputype = Amd) & (cpuInfo.largestExtendedFunction >= 8) THEN
  1035. w.String(" Number of CPU cores: "); w.Int(cpuInfo.numberOfCores, 0); w.Ln;
  1036. END;
  1037. END ShowCpuInformation;
  1038. PROCEDURE Show*(context : Commands.Context); (** ["-d"|"--details"] ~ *)
  1039. VAR cpuInfo : CpuInformation; options : Options.Options;
  1040. BEGIN
  1041. NEW(options);
  1042. options.Add("d", "details", Options.Flag);
  1043. IF options.Parse(context.arg, context.error) THEN
  1044. IF CpuIdSupported() THEN
  1045. GetCpuInformation(cpuInfo);
  1046. IF options.GetFlag("details") THEN
  1047. ShowDetailedCpuInformation(context.out, cpuInfo);
  1048. ELSE
  1049. ShowCpuInformation(context.out, cpuInfo);
  1050. END;
  1051. ELSE
  1052. context.out.String("CPUID instruction is not supported."); context.out.Ln;
  1053. END;
  1054. END;
  1055. END Show;
  1056. END CPUID.
  1057. System.Free CPUID ~
  1058. CPUID.Show ~