651 lines
25 KiB
Plaintext
651 lines
25 KiB
Plaintext
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Microsoft Research Singularity
|
||
|
//
|
||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
//
|
||
|
// File: ProcMemInfo.cs
|
||
|
//
|
||
|
//
|
||
|
// Note: Simple Windows XP-like ProcMemInfo program.
|
||
|
//
|
||
|
using System;
|
||
|
using System.Collections;
|
||
|
using System.Runtime.CompilerServices;
|
||
|
using System.Threading;
|
||
|
|
||
|
using Microsoft.Singularity;
|
||
|
using Microsoft.Singularity.Channels;
|
||
|
using Microsoft.Singularity.Diagnostics.Contracts;
|
||
|
using Microsoft.Singularity.Configuration;
|
||
|
using Microsoft.Singularity.Io;
|
||
|
using Microsoft.Singularity.Directory;
|
||
|
using Microsoft.Singularity.V1.Services;
|
||
|
using Microsoft.SingSharp;
|
||
|
|
||
|
using Microsoft.Contracts;
|
||
|
using Microsoft.SingSharp.Reflection;
|
||
|
using Microsoft.Singularity.Applications;
|
||
|
[assembly: Transform(typeof(ApplicationResourceTransform))]
|
||
|
|
||
|
|
||
|
namespace Microsoft.Singularity.Applications
|
||
|
{
|
||
|
[ConsoleCategory(HelpMessage=
|
||
|
"ProcMemInfo [options] Display Processor Cache info",
|
||
|
DefaultAction=true)]
|
||
|
internal sealed class Parameters
|
||
|
{
|
||
|
[Endpoint]
|
||
|
public readonly TRef<UnicodePipeContract.Exp:READY> Stdin;
|
||
|
|
||
|
[Endpoint]
|
||
|
public readonly TRef<UnicodePipeContract.Imp:READY> Stdout;
|
||
|
|
||
|
[Endpoint]
|
||
|
public readonly TRef<ProcMemInfoContract.Imp:Start> pmInfoRef;
|
||
|
|
||
|
[BoolParameter( "d", Default=true , HelpMessage=
|
||
|
"Dumps output and PageTable to Debugger.")]
|
||
|
internal bool dumpTable;
|
||
|
|
||
|
reflective internal Parameters();
|
||
|
|
||
|
internal int AppMain() {
|
||
|
return ProcMemInfo.AppMain(this);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public class ProcMemInfo
|
||
|
{
|
||
|
// Check if processor is Intel/AMD
|
||
|
internal static bool isIntel(uint ebx, uint ecx, uint edx)
|
||
|
{
|
||
|
if (ebx == 0x756e6547 && ecx == 0x6c65746e && edx == 0x49656e69) {
|
||
|
return true;
|
||
|
}
|
||
|
else {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Check if processor is Intel/AMD
|
||
|
internal static bool isAMD(uint ebx, uint ecx, uint edx)
|
||
|
{
|
||
|
if (ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65) {
|
||
|
return true;
|
||
|
}
|
||
|
else {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Call CPUID with all possible inputs (EAX=1-5,8000_0001-8000_000A)
|
||
|
internal static void DoTestAllCpuId(Parameters! config)
|
||
|
{
|
||
|
bool dumpTable = config.dumpTable;
|
||
|
uint v0, v1, v2, v3;
|
||
|
|
||
|
WriteLine(dumpTable, "\n");
|
||
|
WriteLine(dumpTable, "----------------------------------------");
|
||
|
WriteLine(dumpTable, "TESTING ALL CPUID ");
|
||
|
WriteLine(dumpTable, "----------------------------------------\n");
|
||
|
|
||
|
for (uint i = 0; i < 6; i++) {
|
||
|
Processor.ReadCpuid(i, out v0, out v1, out v2, out v3);
|
||
|
WriteLine(dumpTable, "{0:x8} : {1:x8}.{2:x8}.{3:x8}.{4:x8}",
|
||
|
i, v0, v1, v2, v3);
|
||
|
}
|
||
|
for (uint i = 0x80000000; i < 0x80000010; i++) {
|
||
|
Processor.ReadCpuid(i, out v0, out v1, out v2, out v3);
|
||
|
WriteLine(dumpTable, "{0:x8} : {1:x8}.{2:x8}.{3:x8}.{4:x8}",
|
||
|
i, v0, v1, v2, v3);
|
||
|
}
|
||
|
WriteLine(dumpTable, "\n");
|
||
|
}
|
||
|
|
||
|
// Get AMD Processor Cache Information
|
||
|
internal static void GetAmdInfo(Parameters! config)
|
||
|
{
|
||
|
bool dumpTable = config.dumpTable;
|
||
|
uint v0, v1, v2, v3;
|
||
|
|
||
|
WriteLine(dumpTable, "\n");
|
||
|
WriteLine(dumpTable, "----------------------------------------");
|
||
|
WriteLine(dumpTable, "PROCESSOR CACHE INFORMATION (from CPUID)");
|
||
|
WriteLine(dumpTable, "----------------------------------------\n");
|
||
|
|
||
|
// Call CPUID with Input EAX=1, 8000_0005H and 8000_0006H
|
||
|
GetAmdInput1(config);
|
||
|
GetAmdInput85(config);
|
||
|
GetAmdInput86(config);
|
||
|
}
|
||
|
|
||
|
// EAX = 1
|
||
|
// a : Processor Signature
|
||
|
// b : Initial APIC ID, CLFLUSH Size, Brand ID
|
||
|
// c : Reserved
|
||
|
// d : Standard Feature support
|
||
|
internal static void GetAmdInput1(Parameters! config)
|
||
|
{
|
||
|
uint a, b, c, d;
|
||
|
uint eax = 1;
|
||
|
bool dumpTable = config.dumpTable;
|
||
|
|
||
|
Processor.ReadCpuid(eax, out a, out b, out c, out d);
|
||
|
|
||
|
// -------------------------------------- output EAX
|
||
|
uint stepping = (a & 0x0000000f);
|
||
|
uint model = (a & 0x000000f0) >> 4;
|
||
|
uint family = (a & 0x00000f00) >> 8;
|
||
|
uint xModel = (a & 0x000f0000) >> 16;
|
||
|
uint xFamily = (a & 0x0ff00000) >> 20;
|
||
|
|
||
|
// from AMD, CPUID manual:
|
||
|
// computing effective family/model computation
|
||
|
uint effFamily = family;
|
||
|
if (family == 0x0f) {
|
||
|
effFamily = (xFamily + family);
|
||
|
}
|
||
|
uint effModel = model;
|
||
|
if (family == 0x0f) {
|
||
|
effModel = (xModel << 4) + model;
|
||
|
}
|
||
|
|
||
|
/// -------------------------------------- output EBX
|
||
|
uint brandId = (b & 0x000000ff);
|
||
|
uint clflush = (b & 0x0000ff00) >> 8;
|
||
|
uint apicId = (b & 0xff000000) >> 24;
|
||
|
|
||
|
Write(dumpTable, "\nInput EAX={0:x8} ", eax);
|
||
|
Write(dumpTable,"output:{1:x8}.{2:x8}.{3:x8}.{4:x8}\n\n",
|
||
|
eax, a, b, c, d);
|
||
|
|
||
|
if (a == 0 && b == 0 && c == 0 && d == 0) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
WriteLine(dumpTable, " Output EAX:");
|
||
|
WriteLine(dumpTable, " Stepping {0}", stepping);
|
||
|
WriteLine(dumpTable, " Model {0}", model);
|
||
|
WriteLine(dumpTable, " Family {0}", family);
|
||
|
WriteLine(dumpTable, " xModel {0}", xModel);
|
||
|
WriteLine(dumpTable, " xFamily {0}", xFamily);
|
||
|
WriteLine(dumpTable, " effFamily {0}", effFamily);
|
||
|
WriteLine(dumpTable, " effModel {0}", effModel);
|
||
|
WriteLine(dumpTable, " Output EBX:");
|
||
|
WriteLine(dumpTable, " Brand Id {0}", brandId);
|
||
|
WriteLine(dumpTable, " CLFLUSH Size {0}", clflush);
|
||
|
WriteLine(dumpTable, " APIC ID {0}", apicId);
|
||
|
|
||
|
// -------------------------------------- output EDX
|
||
|
WriteLine(dumpTable, " Output EDX:");
|
||
|
Write(dumpTable, " ");
|
||
|
if ((d & 0x1) > 0) { Write(dumpTable, "x87 "); }
|
||
|
if ((d & 0x2) > 0) { Write(dumpTable, "VME "); }
|
||
|
if ((d & 0x4) > 0) { Write(dumpTable, "DBG "); }
|
||
|
if ((d & 0x8) > 0) { Write(dumpTable, "PSE "); }
|
||
|
if ((d & 0x10) > 0) { Write(dumpTable, "TSC "); }
|
||
|
if ((d & 0x20) > 0) { Write(dumpTable, "MSR "); }
|
||
|
if ((d & 0x40) > 0) { Write(dumpTable, "PAE "); }
|
||
|
if ((d & 0x80) > 0) { Write(dumpTable, "MCE "); }
|
||
|
Write(dumpTable, "\n ");
|
||
|
if ((d & 0x100) > 0) { Write(dumpTable, "CX8 "); }
|
||
|
if ((d & 0x200) > 0) { Write(dumpTable, "APIC "); }
|
||
|
if ((d & 0x200) > 0) { Write(dumpTable, "R0 "); }
|
||
|
if ((d & 0x800) > 0) { Write(dumpTable, "SEP "); }
|
||
|
if ((d & 0x1000) > 0) { Write(dumpTable, "MTRR "); }
|
||
|
if ((d & 0x2000) > 0) { Write(dumpTable, "PGE "); }
|
||
|
if ((d & 0x4000) > 0) { Write(dumpTable, "MCA "); }
|
||
|
if ((d & 0x8000) > 0) { Write(dumpTable, "CMOV "); }
|
||
|
Write(dumpTable, "\n ");
|
||
|
if ((d & 0x10000) > 0) { Write(dumpTable, "PAT "); }
|
||
|
if ((d & 0x20000) > 0) { Write(dumpTable, "P36 "); }
|
||
|
if ((d & 0x40000) > 0) { Write(dumpTable, "R1 "); }
|
||
|
if ((d & 0x80000) > 0) { Write(dumpTable, "CFL "); }
|
||
|
if ((d & 0x100000) > 0) { Write(dumpTable, "R2 "); }
|
||
|
if ((d & 0x200000) > 0) { Write(dumpTable, "R3 "); }
|
||
|
if ((d & 0x400000) > 0) { Write(dumpTable, "R4 "); }
|
||
|
if ((d & 0x800000) > 0) { Write(dumpTable, "MMX "); }
|
||
|
Write(dumpTable, "\n ");
|
||
|
if ((d & 0x1000000) > 0) { Write(dumpTable, "FXSR "); }
|
||
|
if ((d & 0x2000000) > 0) { Write(dumpTable, "SSE "); }
|
||
|
if ((d & 0x4000000) > 0) { Write(dumpTable, "SSE2 "); }
|
||
|
if ((d & 0x8000000) > 0) { Write(dumpTable, "R5 "); }
|
||
|
if ((d & 0x10000000) > 0){ Write(dumpTable, "R6 "); }
|
||
|
if ((d & 0x20000000) > 0){ Write(dumpTable, "R7 "); }
|
||
|
if ((d & 0x40000000) > 0){ Write(dumpTable, "R8 "); }
|
||
|
if ((d & 0x80000000) > 0){ Write(dumpTable, "R9 "); }
|
||
|
Write(dumpTable, "\n");
|
||
|
}
|
||
|
|
||
|
// EAX = 8000_0005
|
||
|
// a : TLB Bits for 2 MB and 4MB
|
||
|
// b : TLB Bits for 4 KB
|
||
|
// c : L1 Data Cache Bits
|
||
|
// d : L1 Instruction Cache Bits
|
||
|
internal static void GetAmdInput85(Parameters! config)
|
||
|
{
|
||
|
uint a, b, c, d;
|
||
|
uint eax = 0x80000005;
|
||
|
bool dumpTable = config.dumpTable;
|
||
|
|
||
|
Processor.ReadCpuid(eax, out a, out b, out c, out d);
|
||
|
|
||
|
Write(dumpTable, "\nInput EAX={0:x8} ", eax);
|
||
|
Write(dumpTable,"output:{1:x8}.{2:x8}.{3:x8}.{4:x8}\n\n",
|
||
|
eax, a, b, c, d);
|
||
|
|
||
|
if (a == 0 && b == 0 && c == 0 && d == 0) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
uint a1 = (a & 0x000000ff) >> 0;
|
||
|
uint a2 = (a & 0x0000ff00) >> 8;
|
||
|
uint a3 = (a & 0x00ff0000) >> 16;
|
||
|
uint a4 = (a & 0xff000000) >> 24;
|
||
|
|
||
|
uint b1 = (b & 0x000000ff) >> 0;
|
||
|
uint b2 = (b & 0x0000ff00) >> 8;
|
||
|
uint b3 = (b & 0x00ff0000) >> 16;
|
||
|
uint b4 = (b & 0xff000000) >> 24;
|
||
|
|
||
|
uint c1 = (c & 0x000000ff) >> 0;
|
||
|
uint c2 = (c & 0x0000ff00) >> 8;
|
||
|
uint c3 = (c & 0x00ff0000) >> 16;
|
||
|
uint c4 = (c & 0xff000000) >> 24;
|
||
|
|
||
|
uint d1 = (d & 0x000000ff) >> 0;
|
||
|
uint d2 = (d & 0x0000ff00) >> 8;
|
||
|
uint d3 = (d & 0x00ff0000) >> 16;
|
||
|
uint d4 = (d & 0xff000000) >> 24;
|
||
|
|
||
|
|
||
|
// -------------------------------------- output EAX
|
||
|
WriteLine(dumpTable, " Output EAX:");
|
||
|
WriteLine(dumpTable, " 2MB Inst TLB, Entries {0}", a1);
|
||
|
WriteLine(dumpTable, " 2MB Inst TLB, Assctvy {0}", Assoc(a2));
|
||
|
WriteLine(dumpTable, " 2MB Data TLB, Entries {0}", a3);
|
||
|
WriteLine(dumpTable, " 2MB Data TLB, Assctvy {0}", Assoc(a4));
|
||
|
|
||
|
// -------------------------------------- output EBX
|
||
|
WriteLine(dumpTable, " Output EBX:");
|
||
|
WriteLine(dumpTable, " 4KB Inst TLB, Entries {0}", b1);
|
||
|
WriteLine(dumpTable, " 4KB Inst TLB, Assctvy {0}", Assoc(b2));
|
||
|
WriteLine(dumpTable, " 4KB Data TLB, Entries {0}", b3);
|
||
|
WriteLine(dumpTable, " 4KB Data TLB, Assctvy {0}", Assoc(b4));
|
||
|
|
||
|
// -------------------------------------- output ECX
|
||
|
WriteLine(dumpTable, " Output ECX:");
|
||
|
WriteLine(dumpTable, " L1 Data, Line Size {0}", c1);
|
||
|
WriteLine(dumpTable, " L1 Data, Lines/Tag {0}", c2);
|
||
|
WriteLine(dumpTable, " L1 Data, Assctvy {0}", Assoc(c3));
|
||
|
WriteLine(dumpTable, " L1 Data, Size (KB) {0}", c4);
|
||
|
|
||
|
// -------------------------------------- output EDX
|
||
|
WriteLine(dumpTable, " Output EDX:");
|
||
|
WriteLine(dumpTable, " L1 Inst , Line Size {0}", d1);
|
||
|
WriteLine(dumpTable, " L1 Inst , Lines/Tag {0}", d2);
|
||
|
WriteLine(dumpTable, " L1 Inst , Assctvy {0}", Assoc(d3));
|
||
|
WriteLine(dumpTable, " L1 Inst , Size (KB) {0}", d4);
|
||
|
}
|
||
|
|
||
|
// Convert associativity code to associativity in string
|
||
|
internal static string Assoc(uint associativity)
|
||
|
{
|
||
|
switch (associativity) {
|
||
|
case 0: return "Reserved"; break;
|
||
|
case 1: return "Direct Mapped"; break;
|
||
|
case 0xff: return "Fully Assoc"; break;
|
||
|
default :
|
||
|
return string.Format("{0}-way", associativity);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Similar to Assoc() but specific for L2 cache
|
||
|
internal static string AssocL2(uint associativity)
|
||
|
{
|
||
|
switch (associativity) {
|
||
|
case 0: return "Off/Disabled"; break;
|
||
|
case 1: return "Direct Mapped"; break;
|
||
|
case 0x02: return "2-way"; break;
|
||
|
case 0x04: return "4-way"; break;
|
||
|
case 0x06: return "8-way"; break;
|
||
|
case 0x08: return "16-way"; break;
|
||
|
case 0x0f: return "Fully Assoc"; break;
|
||
|
default :
|
||
|
return "Reserved (disabled?)";
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Check if L2 is reserved according to the associativity code
|
||
|
internal static bool IsL2Reserved(uint associativity)
|
||
|
{
|
||
|
switch (associativity)
|
||
|
{
|
||
|
case 0:
|
||
|
case 1:
|
||
|
case 0x02:
|
||
|
case 0x04:
|
||
|
case 0x06:
|
||
|
case 0x08:
|
||
|
case 0x0f:
|
||
|
return false;
|
||
|
break;
|
||
|
default :
|
||
|
return true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// EAX = 8000_0006
|
||
|
// a : L2 TLB Bits for 2 MB / 4 MB pages
|
||
|
// b : L2 TLB Bits for 4 KB
|
||
|
// c : L2 Cache Bits
|
||
|
// d : reserved
|
||
|
internal static void GetAmdInput86(Parameters! config)
|
||
|
{
|
||
|
uint a, b, c, d;
|
||
|
uint eax = 0x80000006;
|
||
|
|
||
|
bool dumpTable = config.dumpTable;
|
||
|
|
||
|
Processor.ReadCpuid(eax, out a, out b, out c, out d);
|
||
|
|
||
|
uint a1 = (a & 0x000000ff) >> 0;
|
||
|
uint a2 = (a & 0x0000ff00) >> 8;
|
||
|
uint a3 = (a & 0x00ff0000) >> 16;
|
||
|
uint a4 = (a & 0xff000000) >> 24;
|
||
|
|
||
|
uint b1 = (b & 0x000000ff) >> 0;
|
||
|
uint b2 = (b & 0x0000ff00) >> 8;
|
||
|
uint b3 = (b & 0x00ff0000) >> 16;
|
||
|
uint b4 = (b & 0xff000000) >> 24;
|
||
|
|
||
|
uint c1 = (c & 0x000000ff) >> 0;
|
||
|
uint c2 = (c & 0x0000ff00) >> 8;
|
||
|
uint c3 = (c & 0x00ff0000) >> 16;
|
||
|
uint c4 = (c & 0xff000000) >> 24;
|
||
|
|
||
|
Write(dumpTable, "\nInput EAX={0:x8} ", eax);
|
||
|
Write(dumpTable,"output:{1:x8}.{2:x8}.{3:x8}.{4:x8}\n\n",
|
||
|
eax, a, b, c, d);
|
||
|
|
||
|
if (a == 0 && b == 0 && c == 0 && d == 0) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// -------------------------------------- output EAX
|
||
|
WriteLine(dumpTable, " Output EAX:");
|
||
|
if (a2 == 0) {
|
||
|
WriteLine(dumpTable, " 2MB L2 Inst TLB is disabled");
|
||
|
}
|
||
|
else if (IsL2Reserved(a2)) {
|
||
|
WriteLine(dumpTable, " 2MB L2 Inst TLB is reserved");
|
||
|
}
|
||
|
else {
|
||
|
WriteLine(dumpTable, " 2MB L2 Inst TLB, Entries {0}", a1);
|
||
|
WriteLine(dumpTable, " 2MB L2 Inst TLB, Assctvy {0}",
|
||
|
AssocL2(a2));
|
||
|
}
|
||
|
if (a4 == 0) {
|
||
|
WriteLine(dumpTable, " 2MB L2 Data TLB is disabled");
|
||
|
}
|
||
|
else if (IsL2Reserved(a4)) {
|
||
|
WriteLine(dumpTable, " 2MB L2 Inst TLB is reserved");
|
||
|
}
|
||
|
else {
|
||
|
WriteLine(dumpTable, " 2MB L2 Data TLB, Entries {0}", a3);
|
||
|
WriteLine(dumpTable, " 2MB L2 Data TLB, Assctvy {0}",
|
||
|
AssocL2(a4));
|
||
|
}
|
||
|
|
||
|
// -------------------------------------- output EBX
|
||
|
WriteLine(dumpTable, " Output EBX:");
|
||
|
if (b2 == 0) {
|
||
|
WriteLine(dumpTable, " 4KB L2 Inst TLB is disabled");
|
||
|
}
|
||
|
else if (IsL2Reserved(b2)) {
|
||
|
WriteLine(dumpTable, " 4KB L2 Inst TLB is reserved");
|
||
|
}
|
||
|
else {
|
||
|
WriteLine(dumpTable, " 4KB L2 Inst TLB, Entries {0}", b1);
|
||
|
WriteLine(dumpTable, " 4KB L2 Inst TLB, Assctvy {0}",
|
||
|
AssocL2(b2));
|
||
|
}
|
||
|
if (b4 == 0) {
|
||
|
WriteLine(dumpTable, " 4KB L2 Data TLB is disabled");
|
||
|
}
|
||
|
else if (IsL2Reserved(b4))
|
||
|
{
|
||
|
WriteLine(dumpTable, " 4KB L2 Data TLB is reserved");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
WriteLine(dumpTable, " 4KB L2 Data TLB, Entries {0}", b3);
|
||
|
WriteLine(dumpTable, " 4KB L2 Data TLB, Assctvy {0}",
|
||
|
AssocL2(b4));
|
||
|
}
|
||
|
|
||
|
// -------------------------------------- output ECX
|
||
|
WriteLine(dumpTable, " Output ECX:");
|
||
|
if (c3 == 0)
|
||
|
{
|
||
|
WriteLine(dumpTable, " L2 Cache is disabled");
|
||
|
}
|
||
|
else if (IsL2Reserved(c3))
|
||
|
{
|
||
|
WriteLine(dumpTable, " L2 Cache is reserved");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
WriteLine(dumpTable, " L2, Line Size {0}", c1);
|
||
|
WriteLine(dumpTable, " L2, Lines Per Tag {0}", c2);
|
||
|
WriteLine(dumpTable, " L2, Associativity {0}", c3);
|
||
|
WriteLine(dumpTable, " L2, Size (KB) {0}", c4);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Call GetCPUID
|
||
|
internal static void DoTestGetCpuId(Parameters! config)
|
||
|
{
|
||
|
bool intel = false, amd = false;
|
||
|
uint a, b, c, d;
|
||
|
|
||
|
Processor.ReadCpuid(0, out a, out b, out c, out d);
|
||
|
intel = isIntel(b, c, d);
|
||
|
amd = isAMD(b, c, d);
|
||
|
|
||
|
if (intel) {
|
||
|
// haryadi: I haven't implemented Intel config yet
|
||
|
// GetIntelInfo(config);
|
||
|
}
|
||
|
else if (amd) {
|
||
|
GetAmdInfo(config);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Get Processor and Memory Affinity
|
||
|
internal static void DoTestGetAffinity(Parameters! config)
|
||
|
{
|
||
|
bool dumpTable = config.dumpTable;
|
||
|
ProcMemInfoContract.ProcessorAffinity[] in ExHeap processors;
|
||
|
ProcMemInfoContract.MemoryAffinity[] in ExHeap memories;
|
||
|
|
||
|
ProcMemInfoContract.Imp imp = config.pmInfoRef.Acquire();
|
||
|
if (imp == null) {
|
||
|
throw new ApplicationException("Error: Unable to bind to " +
|
||
|
ProcMemInfoContract.ModuleName);
|
||
|
}
|
||
|
|
||
|
imp.SendGetProcessorAffinity();
|
||
|
imp.RecvResultProcessorAffinity(out processors);
|
||
|
|
||
|
imp.SendGetMemoryAffinity();
|
||
|
imp.RecvResultMemoryAffinity(out memories);
|
||
|
|
||
|
WriteLine(dumpTable, "\n");
|
||
|
WriteLine(dumpTable, "----------------------------------------");
|
||
|
WriteLine(dumpTable, "PROCESSOR AFFINITY INFORMATION");
|
||
|
WriteLine(dumpTable, "----------------------------------------\n");
|
||
|
|
||
|
if (processors == null) {
|
||
|
WriteLine(dumpTable, "There is no Processor Affinity info!");
|
||
|
}
|
||
|
else {
|
||
|
WriteLine(dumpTable, "Found {0} processors\n",
|
||
|
processors.Length);
|
||
|
|
||
|
for (int i = 0; i < processors.Length; i++) {
|
||
|
WriteLine(dumpTable, "Processor #{0}", i);
|
||
|
WriteLine(dumpTable, " domain : {0}",
|
||
|
processors[i].domain);
|
||
|
WriteLine(dumpTable, " apicId : {0}",
|
||
|
processors[i].apicId);
|
||
|
WriteLine(dumpTable, " flagIgnore : {0}\n",
|
||
|
processors[i].flagIgnore);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
WriteLine(dumpTable, "\n");
|
||
|
WriteLine(dumpTable, "----------------------------------------");
|
||
|
WriteLine(dumpTable, "MEMORY AFFINITY INFORMATION");
|
||
|
WriteLine(dumpTable, "----------------------------------------\n");
|
||
|
|
||
|
if (memories == null) {
|
||
|
WriteLine(dumpTable, "There is no Memory Affinity info!");
|
||
|
}
|
||
|
else {
|
||
|
WriteLine(dumpTable, "Found {0} memory\n", memories.Length);
|
||
|
|
||
|
for (int i = 0; i < memories.Length; i++) {
|
||
|
WriteLine(dumpTable, "Memory #{0}", i);
|
||
|
WriteLine(dumpTable, " domain : {0}",
|
||
|
memories[i].domain);
|
||
|
WriteLine(dumpTable, " baseAddress : {0} {1}",
|
||
|
GetBigAddr(memories[i].baseAddress),
|
||
|
GetBigAddrStr(memories[i].baseAddress));
|
||
|
WriteLine(dumpTable, " endAddress : {0} {1}",
|
||
|
GetBigAddr(memories[i].endAddress),
|
||
|
GetBigAddrStr(memories[i].endAddress));
|
||
|
WriteLine(dumpTable, " memorySize : {0} {1}",
|
||
|
GetBigAddr(memories[i].memorySize),
|
||
|
GetBigAddrStr(memories[i].memorySize));
|
||
|
WriteLine(dumpTable, " flagIgnore : {0}",
|
||
|
memories[i].flagIgnore);
|
||
|
WriteLine(dumpTable, " flagHotPlug : {0}",
|
||
|
memories[i].flagHotPluggable);
|
||
|
WriteLine(dumpTable, " flagNonVoltl: {0}\n",
|
||
|
memories[i].flagNonVolatile);
|
||
|
}
|
||
|
}
|
||
|
delete processors;
|
||
|
delete memories;
|
||
|
config.pmInfoRef.Release(imp);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
internal static ulong GetBigAddr(ulong address)
|
||
|
{
|
||
|
ulong KB = 1024;
|
||
|
ulong MB = KB * KB;
|
||
|
ulong GB = KB * KB * KB;
|
||
|
|
||
|
if (address > GB) {
|
||
|
return address / GB;
|
||
|
}
|
||
|
else if (address > MB) {
|
||
|
return address / MB;
|
||
|
}
|
||
|
else if (address > KB) {
|
||
|
return address / KB;
|
||
|
}
|
||
|
else {
|
||
|
return address;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal static string GetBigAddrStr(ulong address)
|
||
|
{
|
||
|
ulong KB = 1024;
|
||
|
ulong MB = KB * KB;
|
||
|
ulong GB = KB * KB * KB;
|
||
|
|
||
|
if (address > GB) {
|
||
|
return "GB";
|
||
|
}
|
||
|
else if (address > MB) {
|
||
|
return "MB";
|
||
|
}
|
||
|
else if (address > KB) {
|
||
|
return "KB";
|
||
|
}
|
||
|
else {
|
||
|
return "B";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Main
|
||
|
internal static int AppMain(Parameters! config)
|
||
|
{
|
||
|
// Set the default options
|
||
|
bool dumpTable = config.dumpTable;
|
||
|
|
||
|
WriteLine(dumpTable, "\nWelcome to ProcMemInfo ... \n\n");
|
||
|
|
||
|
// Test if ProcMemInfoContract is okay
|
||
|
ProcMemInfoContract.Imp imp3 = config.pmInfoRef.Acquire();
|
||
|
imp3.RecvReady();
|
||
|
config.pmInfoRef.Release(imp3);
|
||
|
|
||
|
try {
|
||
|
DoTestGetAffinity(config);
|
||
|
DoTestGetCpuId (config);
|
||
|
DoTestAllCpuId (config);
|
||
|
} catch (Exception ex) {
|
||
|
Console.WriteLine("Error .");
|
||
|
Console.WriteLine(ex.ToString());
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
/// <summary>
|
||
|
/// Use this method to write output to both the screen and the
|
||
|
/// debugger if toDebugger is true.
|
||
|
/// </summary>
|
||
|
public static void WriteLine(bool toDebugger, string format,
|
||
|
params object[] args) {
|
||
|
string s = String.Format(format, args);
|
||
|
Console.WriteLine(s);
|
||
|
if (toDebugger) {
|
||
|
DebugStub.WriteLine(s);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static void Write(bool toDebugger, string format,
|
||
|
params object[] args) {
|
||
|
string s = String.Format(format, args);
|
||
|
Console.Write(s);
|
||
|
if (toDebugger) {
|
||
|
DebugStub.Write(s);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static void WriteLine(bool toDebugger) {
|
||
|
Console.WriteLine();
|
||
|
if (toDebugger) {
|
||
|
DebugStub.WriteLine();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
} // end of ProcMemInfo class
|
||
|
} // end of Singularity.Applications
|
||
|
|
||
|
|
||
|
|