Search

2012年12月25日 星期二

我現在才知道有CPUID這東西...

    最近想在Library中加入測試SSE指令集支援程度,然後看到這篇有cpuid這指令可用,功能選擇跟中斷很像根據eax決定。



msg.h


#ifndef __MSG__
#define __MSG__

char *ecx_msg[] = {
"SSE3 Extension: ",
"Carryless Multiplication: ",
"64-bit DS Area: ",
"MONITOR/MWAIT: ",
"CPL Qualified Debug Store: ",
"Virtual Machine Extensions: ",
"SaferMode Extensions: ",
"Enhanced Intel SpeedStep Technology: ",
"Thermal Monitor 2: ",
"Supplemental SSSE3 Extensions: ",
"L1 Context ID: ",
"",
"Fused Multiply Add: ",
"CMPXCHG16B: ",
"Update Control: ",
"Perf/Debug Capability MSR: ",
"",
"Process-context Identifiers: ",
"Direct Cache Access: ",
"SSE4.1: ",
"SSE4.2: ",
"x2APIC: ",
"MOVEBE: ",
"POPCNT: ",
"TSC-Deadline: ",
"AES: ",
"XSAVE: ",
"OSXSAVE: ",
"AVX: ",
"",
"",
""
};

char *edx_msg[] = {
"FPU: ",
"VME: ",
"DE:  ",
"PSE: ",
"TSC: ",
"MSR: ",
"PAE: ",
"MCE: ",
"CMPXCHG8B: ",
"APIC: ",
"",
"SYSENTER/SYSEXIT: ",
"MTRR: ",
"PGE: ",
"MCA: ",
"CMOV: ",
"PAT: ",
"PSE36: ",
"PNS: ",
"CLFSH: ",
"",
"Debug Store: ",
"ACPI: ",
"MMX: ",
"FXSR: ",
"SSE: ",
"SSE2: ",
"Self snoop: ",
"HTT: ",
"TM: ",
"",
"PBE: "
};

char *YES_NO[] = {"No","Yes"};

#endif


cpuid.h


#ifndef __CPUID__
#define __CPUID__

union Register
{
int dword[4]; //eax,ebx,ecx,edx
char byte[16];
};

class CPUID
{
public:
CPUID(){}
~CPUID(){}
void GetFeature(Register&); //eax = 0x00000001
void GetName(Register&); //eax = 0x80000002 ~ 0x80000004
};

#endif


cpuid.cpp


#include "cpuid.h"

void CPUID::GetFeature(Register &reg)
{
__asm{
mov esi,reg;
mov eax,1h;
cpuid;
mov dword ptr [esi],eax;
mov dword ptr [esi+4],ebx;
mov dword ptr [esi+8],ecx;
mov dword ptr [esi+12],edx;

}
}

void CPUID::GetName(Register &name)
{
__asm{;
mov esi,name;
mov eax,80000002h;

_loop:

push eax;
cpuid;
mov dword ptr [esi],eax;
mov dword ptr [esi+4],ebx;
mov dword ptr [esi+8],ecx;
mov dword ptr [esi+12],edx;
pop eax;
add eax,1h;
add esi,10h;
cmp eax,80000005h;

jnz _loop;

}
}


app.h


#ifndef __DRIVER_LOADER__
#define __DRIVER_LOADER__

#include <wx/wx.h>
#include <wx/listctrl.h>

#include "cpuid.h"
#include "msg.h"

enum{
COLUMN_0 = 0,
ENUM_FEATURE = 100
};

class App:public wxApp
{
public:

bool OnInit();
};

class MSGList:public wxListCtrl
{
public:

MSGList(wxWindow*);

void AddMessage(const wxString&);

private:

int item_num;
};

class Frame:public wxFrame
{
public:

Frame(const wxString&,const wxSize&);

void EnumFeature(wxCommandEvent&);
void OnExit(wxCommandEvent&);
private:

void CreateUI();

CPUID cpuid;

MSGList *msg;
Register reg[3];

DECLARE_EVENT_TABLE()
};

BEGIN_EVENT_TABLE(Frame,wxFrame)
EVT_MENU(ENUM_FEATURE,Frame::EnumFeature)
EVT_MENU(wxID_EXIT,Frame::OnExit)
END_EVENT_TABLE()

#endif


app.cpp


#include "app.h"

DECLARE_APP(App)
IMPLEMENT_APP(App)

bool App::OnInit()
{
Frame *frame = new Frame(wxT("wxCPUID"),wxSize(600,400));

frame->Show(true);

return true;
}

Frame::Frame(const wxString &title,const wxSize &size):wxFrame(NULL,wxID_ANY,title,wxDefaultPosition,size,wxMINIMIZE_BOX | wxCLOSE_BOX | wxCAPTION | wxSYSTEM_MENU)
{
CreateUI();
}

void Frame::CreateUI()
{
cpuid.GetName(reg[0]);
wxMenu *file = new wxMenu;
this->SetTitle(wxString(reg[0].byte,wxConvUTF8));

file->Append(ENUM_FEATURE,wxT("F&eature\tAlt-e"),wxT("Feature"));
file->Append(wxID_EXIT,wxT("E&xit\tAlt-q"),wxT("Exit"));

wxMenuBar *bar = new wxMenuBar;
bar->Append(file,wxT("file"));

msg = new MSGList(this);

SetMenuBar(bar);
CreateStatusBar(2);
}

void Frame::EnumFeature(wxCommandEvent &event)
{
cpuid.GetFeature(reg[0]);

for(int i = 0,j = 1;i < 32;++i){
wxString msg_str;
msg_str.Append(wxString(ecx_msg[i],wxConvUTF8));
if(msg_str.empty()){j <<= 1;continue;}
msg_str.Append(wxString(YES_NO[(bool)(reg[0].dword[2] & j)],wxConvUTF8));
j <<= 1;
msg->AddMessage(msg_str);
}

for(int i = 0,j = 1;i < 32;++i){
wxString msg_str;
msg_str.Append(wxString(edx_msg[i],wxConvUTF8));
if(msg_str.empty()){j <<= 1;continue;}
msg_str.Append(wxString(YES_NO[(bool)(reg[0].dword[3] & j)],wxConvUTF8));
j <<= 1;
msg->AddMessage(msg_str);
}
}

void Frame::OnExit(wxCommandEvent &event)
{
Close();
}

MSGList::MSGList(wxWindow *parent):wxListCtrl(parent,wxID_ANY,wxDefaultPosition,wxDefaultSize,wxLC_REPORT | wxLC_SINGLE_SEL)
{
item_num = 0;

wxListItem item;
item.SetText(wxT("Message"));
InsertColumn(COLUMN_0,item);
SetColumnWidth(COLUMN_0,600);
}

void MSGList::AddMessage(const wxString &msg)
{
InsertItem(item_num,msg,COLUMN_0);
++item_num;
}



沒有留言:

張貼留言