├── version.h ├── MSVC_Round.h ├── doc └── readme.odt ├── MSVC_Round.cpp ├── sysdep.h ├── config.h ├── Signal.h ├── Signal.cpp ├── cpuPrimitives.h ├── PCIRegObject.h ├── MSRObject.h ├── scaler.h ├── sysdep-linux.cpp ├── Makefile ├── OlsDef.h ├── .project ├── PerformanceCounter.h ├── Brazos.h ├── Llano.h ├── Griffin.h ├── Interlagos.h ├── K10Processor.h ├── PCIRegObject.cpp ├── sysdep-win32.cpp ├── cpuPrimitives.cpp ├── MSRObject.cpp ├── config.cpp ├── Processor.h ├── scaler.cpp ├── PerformanceCounter.cpp ├── K10PerformanceCounters.cpp ├── Processor.cpp ├── OlsApi.h └── .cproject /version.h: -------------------------------------------------------------------------------- 1 | #define _VERSION "0.44-rc2+" 2 | -------------------------------------------------------------------------------- /MSVC_Round.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | int round (float); -------------------------------------------------------------------------------- /doc/readme.odt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/turionpowercontrol/tpc/HEAD/doc/readme.odt -------------------------------------------------------------------------------- /MSVC_Round.cpp: -------------------------------------------------------------------------------- 1 | #include "MSVC_Round.h" 2 | 3 | int round (float value) { 4 | return (int)(floor(value+0.5)); 5 | } -------------------------------------------------------------------------------- /sysdep.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __SYSDEP_H 3 | #define __SYSDEP_H 4 | 5 | #define CLEARSCREEN_FLAG_SMART 0x01 6 | 7 | bool initializeCore(void); 8 | bool deinitializeCore(void); 9 | void ClearScreen(unsigned int flags); 10 | BOOL SysReadPciConfigDwordEx(DWORD pciAddress, DWORD regAddress, PDWORD value); 11 | BOOL SysWritePciConfigDwordEx(DWORD pciAddress, DWORD regAddress, DWORD value); 12 | 13 | #endif /* __SYSDEP_H */ 14 | -------------------------------------------------------------------------------- /config.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "Processor.h" 4 | 5 | class CfgManager { 6 | private: 7 | FILE *cfgFile; 8 | class Processor *processor; 9 | class Scaler *scaler; 10 | int consumePStateSection (); 11 | int consumeGeneralSection (); 12 | int consumeScalerSection (); 13 | public: 14 | CfgManager (class Processor *, class Scaler *); 15 | ~CfgManager (); 16 | bool openCfgFile (char*); 17 | int parseCfgFile (); 18 | bool closeCfgFile (); 19 | }; 20 | -------------------------------------------------------------------------------- /Signal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Signal.h 3 | * 4 | * Created on: 04/lug/2011 5 | * Author: paolo 6 | */ 7 | 8 | #ifndef SIGNAL_H_ 9 | #define SIGNAL_H_ 10 | 11 | #include 12 | 13 | class Signal { 14 | 15 | public: 16 | 17 | static bool signaled; 18 | static void signalHandler (int signo); 19 | static void activateSignalHandler (int signo); 20 | static bool getSignalStatus (); 21 | static void activateUserSignalsHandler (); 22 | 23 | }; 24 | 25 | #endif /* SIGNAL_H_ */ 26 | -------------------------------------------------------------------------------- /Signal.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Signal.cpp 3 | * 4 | * Created on: 04/lug/2011 5 | * Author: paolo 6 | */ 7 | 8 | #include "Signal.h" 9 | 10 | bool Signal::signaled=false; 11 | 12 | void Signal::signalHandler (int signo) { 13 | 14 | signaled=true; 15 | 16 | } 17 | 18 | void Signal::activateSignalHandler (int signo) { 19 | 20 | signaled=false; 21 | signal (signo, signalHandler); 22 | 23 | } 24 | 25 | bool Signal::getSignalStatus () { 26 | 27 | return signaled; 28 | 29 | } 30 | 31 | void Signal::activateUserSignalsHandler () { 32 | 33 | activateSignalHandler(SIGINT); 34 | activateSignalHandler(SIGTERM); 35 | #ifdef SIGBREAK 36 | activateSignalHandler(SIGBREAK); 37 | #endif /* SIGBREAK */ 38 | #ifdef SIGQUIT 39 | activateSignalHandler(SIGQUIT); 40 | #endif /* SIGQUIT */ 41 | } 42 | -------------------------------------------------------------------------------- /cpuPrimitives.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define DWORD uint32_t 4 | #define PDWORD DWORD* 5 | 6 | #ifdef __LP64__ 7 | #define DWORD_PTR uint64_t 8 | #else 9 | #define DWORD_PTR uint32_t 10 | #endif 11 | 12 | #define TRUE true 13 | #define FALSE false 14 | #define BOOL bool 15 | 16 | BOOL Cpuid(DWORD index, PDWORD eax, PDWORD ebx, PDWORD ecx, PDWORD edx); 17 | 18 | BOOL ReadPciConfigDwordEx(DWORD pciAddress, DWORD regAddress, PDWORD value); 19 | BOOL WritePciConfigDwordEx(DWORD pciAddress, DWORD regAddress, DWORD value); 20 | 21 | BOOL RdmsrPx(DWORD index, PDWORD eax, PDWORD edx, DWORD_PTR processAffinityMask); 22 | BOOL Rdmsr(DWORD index, PDWORD eax, PDWORD edx); 23 | 24 | BOOL WrmsrPx(DWORD index, DWORD eax, DWORD edx, DWORD_PTR processorAffinityMask); 25 | BOOL Wrmsr(DWORD index, DWORD eax, DWORD edx); 26 | 27 | void Sleep (DWORD ms); 28 | 29 | int GetTickCount (); 30 | -------------------------------------------------------------------------------- /PCIRegObject.h: -------------------------------------------------------------------------------- 1 | /* 2 | * PCIRegObject.h 3 | * 4 | * Created on: 29/mar/2011 5 | * Author: paolo 6 | */ 7 | 8 | #ifndef PCIREGOBJECT_H_ 9 | #define PCIREGOBJECT_H_ 10 | 11 | #include 12 | #include 13 | #include 14 | #include "Processor.h" 15 | 16 | class PCIRegObject { 17 | private: 18 | DWORD *reg_ptr; 19 | unsigned int *absIndex; 20 | DWORD reg; 21 | DWORD function; 22 | DWORD device; 23 | DWORD nodeCount; 24 | DWORD nodeMask; 25 | 26 | DWORD getPath (); 27 | DWORD getPath (DWORD, DWORD); 28 | 29 | public: 30 | PCIRegObject(); 31 | 32 | void newPCIReg (DWORD, DWORD, DWORD, DWORD); 33 | 34 | bool readPCIReg (DWORD, DWORD, DWORD, DWORD); 35 | bool writePCIReg (); 36 | 37 | unsigned int indexToAbsolute (unsigned int); 38 | DWORD getCount (); 39 | 40 | bool setBits (unsigned int, unsigned int, DWORD); 41 | DWORD getBits (unsigned int, unsigned int, unsigned int); 42 | 43 | virtual ~PCIRegObject(); 44 | }; 45 | 46 | #endif /* PCIREGOBJECT_H_ */ 47 | -------------------------------------------------------------------------------- /MSRObject.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MSRObject.h 3 | * 4 | * Created on: 28/mar/2011 5 | * Author: paolo 6 | */ 7 | 8 | #ifndef MSROBJECT_H_ 9 | #define MSROBJECT_H_ 10 | 11 | #include 12 | #include 13 | #include 14 | #include "Processor.h" 15 | 16 | class MSRObject { 17 | private: 18 | DWORD cpuCount; 19 | PROCESSORMASK cpuMask; 20 | DWORD reg; 21 | DWORD *eax_ptr; 22 | DWORD *edx_ptr; 23 | unsigned int *absIndex; 24 | 25 | public: 26 | MSRObject(); 27 | bool readMSR (DWORD, PROCESSORMASK); 28 | bool writeMSR (); 29 | unsigned int indexToAbsolute (unsigned int); 30 | DWORD getCount (); 31 | uint64_t getBits (unsigned int, unsigned int, unsigned int); 32 | DWORD getBitsLow (unsigned int, unsigned int, unsigned int); 33 | DWORD getBitsHigh (unsigned int, unsigned int, unsigned int); 34 | bool setBits (unsigned int, unsigned int, uint64_t); 35 | bool setBitsLow (unsigned int, unsigned int, DWORD); 36 | bool setBitsHigh (unsigned int, unsigned int, DWORD); 37 | virtual ~MSRObject(); 38 | }; 39 | 40 | #endif /* MSROBJECT_H_ */ 41 | -------------------------------------------------------------------------------- /scaler.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "Processor.h" 4 | #include "MSRObject.h" 5 | #include "PerformanceCounter.h" 6 | #include "Signal.h" 7 | 8 | #define POLICY_ROCKET 0 9 | #define POLICY_STEP 1 10 | 11 | #define DEFAULT_SAMPLING_RATE 1000 //Default sampling rate in milliseconds 12 | 13 | class Scaler { 14 | private: 15 | int samplingRate; 16 | 17 | int policy; 18 | 19 | int upperThreshold; 20 | int lowerThreshold; 21 | 22 | int midUpperThreshold; 23 | int midLowerThreshold; 24 | 25 | Processor *processor; 26 | 27 | unsigned char slowestPowerState; 28 | 29 | PerformanceCounter *perfCounter; 30 | MSRObject *tscCounter; 31 | uint64_t *prevPerfCounters; 32 | uint64_t *prevTSCCounters; 33 | 34 | uint64_t *raiseTable; 35 | uint64_t *reduceTable; 36 | 37 | int initializeCounters (); 38 | void loopPolicyRocket (); 39 | void loopPolicyStep (); 40 | void createPerformanceTables (); 41 | 42 | public: 43 | void setSamplingFrequency (int); 44 | 45 | void setPolicy (int); 46 | 47 | void setUpperThreshold (int); 48 | void setLowerThreshold (int); 49 | 50 | Scaler (class Processor *); 51 | void beginScaling (); 52 | }; 53 | -------------------------------------------------------------------------------- /sysdep-linux.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | #include "cpuPrimitives.h" 13 | 14 | bool initializeCore() 15 | { 16 | int fd; 17 | 18 | fd = open("/dev/cpu/0/cpuid", O_RDONLY); 19 | if (fd == -1) { 20 | printf("ERROR: couldn't open /dev/cpu/0/cpuid (%s).", strerror(errno)); 21 | if (errno == ENXIO || errno == ENOENT) { 22 | printf(" Make sure that cpuid module is loaded.\n"); 23 | return false; 24 | } 25 | if (errno == EACCES) { 26 | printf(" Not root?.\n"); 27 | return false; 28 | } 29 | printf("\n"); 30 | return false; 31 | } 32 | close(fd); 33 | 34 | fd = open("/dev/cpu/0/msr", O_RDWR); 35 | if (fd == -1) { 36 | printf("ERROR: couldn't open /dev/cpu/0/msr (%s).", strerror(errno)); 37 | if (errno == ENXIO || errno == ENOENT) { 38 | printf(" Make sure that msr module is loaded.\n"); 39 | return false; 40 | } 41 | if (errno == EACCES) { 42 | printf(" Not root?.\n"); 43 | return false; 44 | } 45 | printf("\n"); 46 | return false; 47 | } 48 | close(fd); 49 | 50 | signal(SIGPIPE, SIG_IGN); 51 | 52 | return true; 53 | } 54 | 55 | 56 | bool deinitializeCore() 57 | { 58 | return true; 59 | } 60 | 61 | 62 | void ClearScreen(unsigned int flags) 63 | { 64 | static char *clearstr; 65 | 66 | if (!clearstr) { 67 | if (!cur_term) { 68 | int ret; 69 | 70 | if (setupterm(NULL, 1, &ret) == ERR) { 71 | return; 72 | } 73 | } 74 | clearstr = tigetstr("clear"); 75 | if (!clearstr) { 76 | return; 77 | } 78 | } 79 | putp(clearstr); 80 | } 81 | 82 | BOOL SysReadPciConfigDwordEx(DWORD pciAddress, DWORD regAddress, PDWORD value) 83 | { 84 | return ReadPciConfigDwordEx(pciAddress, regAddress, value); 85 | } 86 | 87 | BOOL SysWritePciConfigDwordEx(DWORD pciAddress, DWORD regAddress, DWORD value) 88 | { 89 | return WritePciConfigDwordEx(pciAddress, regAddress, value); 90 | } 91 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | PREFIX=/usr 3 | 4 | ARCH=$(shell uname -m) 5 | 6 | PROJECT=TurionPowerControl 7 | PROJ_CXXFLAGS=-O2 $(CXXFLAGS) $(shell getconf LFS_CFLAGS) 8 | PROJ_LDFLAGS=$(LDFLAGS) 9 | PROJ_LIBS=$(LIBS) -lrt -lncurses 10 | 11 | OBJROOT=obj 12 | OBJDIR=$(OBJROOT)/$(ARCH) 13 | 14 | SOURCES=TurionPowerControl.cpp \ 15 | config.cpp \ 16 | cpuPrimitives.cpp \ 17 | Griffin.cpp \ 18 | K10Processor.cpp \ 19 | Brazos.cpp \ 20 | Llano.cpp \ 21 | Interlagos.cpp \ 22 | MSRObject.cpp \ 23 | MSVC_Round.cpp \ 24 | PCIRegObject.cpp \ 25 | PerformanceCounter.cpp \ 26 | Processor.cpp \ 27 | K10PerformanceCounters.cpp \ 28 | scaler.cpp \ 29 | Signal.cpp \ 30 | sysdep-linux.cpp 31 | 32 | OBJECTS=$(SOURCES:%.cpp=$(OBJDIR)/%.o) 33 | DEPS=$(SOURCES:%.cpp=$(OBJDIR)/.%.d) 34 | 35 | GENERATED=source_version.h 36 | 37 | all: $(OBJDIR) source_version.h $(PROJECT) 38 | @echo Build completed. 39 | 40 | source_version.h: FORCE 41 | ${shell BRANCH=$$(svn info | sed -nr '/URL:/{s=(.*/)([^/]*$$)=\2=;p}') ; REV=$$(svnversion) ; [ "$$BRANCH" != "" -a "$$REV" != "" ] && A=\"$$BRANCH-r$$REV\" || A=\"export\" ; if [ "$$A" != "$$(cat source_version.h 2> /dev/null | cut -f 3 -d \ )" ]; then echo \#define _SOURCE_VERSION $$A > source_version.h ; fi} 42 | @true 43 | 44 | i386: 45 | $(MAKE) CXXFLAGS="-m32 -D_FILE_OFFSET_BITS=64" LDFLAGS="-m32" ARCH=i386 46 | 47 | install: 48 | install -ps $(PROJECT) $(DESTDIR)$(PREFIX)/bin 49 | ln -sf $(PROJECT) $(DESTDIR)$(PREFIX)/bin/tpc 50 | 51 | uninstall: 52 | $(RM) $(DESTDIR)$(PREFIX)/bin/$(PROJECT) 53 | $(RM) $(DESTDIR)$(PREFIX)/bin/tpc 54 | 55 | $(PROJECT): $(OBJDIR)/$(PROJECT) 56 | cp $< $@ 57 | 58 | $(OBJDIR)/$(PROJECT): $(OBJECTS) 59 | $(CXX) $(PROJ_LDFLAGS) -o $@ $(OBJECTS) $(PROJ_LIBS) 60 | 61 | $(OBJDIR)/%.o: %.cpp 62 | $(CXX) $(PROJ_CXXFLAGS) -MMD -MF $(<:%.cpp=$(OBJDIR)/.%.d) -MT $(<:%.cpp=$(OBJDIR)/%.o) -c -o $@ $< 63 | 64 | $(OBJDIR): 65 | mkdir -p $(OBJDIR) 66 | 67 | clean: 68 | $(RM) $(OBJECTS) $(OBJDIR)/$(PROJECT) $(PROJECT) 69 | 70 | distclean: clean 71 | $(RM) -r $(OBJROOT) 72 | $(RM) -r $(GENERATED) 73 | $(RM) core core.[0-9] 74 | $(RM) *~ DEADJOE *.orig *.rej *.i *.r[0-9]* *.mine 75 | 76 | .PHONY: clean distclean all install uninstall i386 FORCE 77 | 78 | -include $(DEPS) 79 | -------------------------------------------------------------------------------- /OlsDef.h: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Author : hiyohiyo 3 | // Mail : hiyohiyo@crystalmark.info 4 | // Web : http://openlibsys.org/ 5 | // License : The modified BSD license 6 | // 7 | // Copyright 2007 OpenLibSys.org. All rights reserved. 8 | //----------------------------------------------------------------------------- 9 | 10 | #pragma once 11 | 12 | //----------------------------------------------------------------------------- 13 | // 14 | // DLL Status Code 15 | // 16 | //----------------------------------------------------------------------------- 17 | 18 | #define OLS_DLL_NO_ERROR 0 19 | #define OLS_DLL_UNSUPPORTED_PLATFORM 1 20 | #define OLS_DLL_DRIVER_NOT_LOADED 2 21 | #define OLS_DLL_DRIVER_NOT_FOUND 3 22 | #define OLS_DLL_DRIVER_UNLOADED 4 23 | #define OLS_DLL_DRIVER_NOT_LOADED_ON_NETWORK 5 24 | #define OLS_DLL_UNKNOWN_ERROR 9 25 | 26 | //----------------------------------------------------------------------------- 27 | // 28 | // Driver Type 29 | // 30 | //----------------------------------------------------------------------------- 31 | 32 | #define OLS_DRIVER_TYPE_UNKNOWN 0 33 | #define OLS_DRIVER_TYPE_WIN_9X 1 34 | #define OLS_DRIVER_TYPE_WIN_NT 2 35 | #define OLS_DRIVER_TYPE_WIN_NT4 3 // Obsolete 36 | #define OLS_DRIVER_TYPE_WIN_NT_X64 4 37 | #define OLS_DRIVER_TYPE_WIN_NT_IA64 5 // Reseved 38 | 39 | //----------------------------------------------------------------------------- 40 | // 41 | // PCI Error Code 42 | // 43 | //----------------------------------------------------------------------------- 44 | 45 | #define OLS_ERROR_PCI_BUS_NOT_EXIST (0xE0000001L) 46 | #define OLS_ERROR_PCI_NO_DEVICE (0xE0000002L) 47 | #define OLS_ERROR_PCI_WRITE_CONFIG (0xE0000003L) 48 | #define OLS_ERROR_PCI_READ_CONFIG (0xE0000004L) 49 | 50 | //----------------------------------------------------------------------------- 51 | // 52 | // Support Macros 53 | // 54 | //----------------------------------------------------------------------------- 55 | 56 | // Bus Number, Device Number and Function Number to PCI Device Address 57 | #define PciBusDevFunc(Bus, Dev, Func) ((Bus&0xFF)<<8) | ((Dev&0x1F)<<3) | (Func&7) 58 | // PCI Device Address to Bus Number 59 | #define PciGetBus(address) ((address>>8) & 0xFF) 60 | // PCI Device Address to Device Number 61 | #define PciGetDev(address) ((address>>3) & 0x1F) 62 | // PCI Device Address to Function Number 63 | #define PciGetFunc(address) (address&7) 64 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | TurionPowerControl 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | clean,full,incremental, 11 | 12 | 13 | ?name? 14 | 15 | 16 | 17 | org.eclipse.cdt.make.core.append_environment 18 | true 19 | 20 | 21 | org.eclipse.cdt.make.core.autoBuildTarget 22 | all 23 | 24 | 25 | org.eclipse.cdt.make.core.buildArguments 26 | 27 | 28 | 29 | org.eclipse.cdt.make.core.buildCommand 30 | make 31 | 32 | 33 | org.eclipse.cdt.make.core.buildLocation 34 | ${workspace_loc:/TurionPowerControl/Debug} 35 | 36 | 37 | org.eclipse.cdt.make.core.cleanBuildTarget 38 | clean 39 | 40 | 41 | org.eclipse.cdt.make.core.contents 42 | org.eclipse.cdt.make.core.activeConfigSettings 43 | 44 | 45 | org.eclipse.cdt.make.core.enableAutoBuild 46 | false 47 | 48 | 49 | org.eclipse.cdt.make.core.enableCleanBuild 50 | true 51 | 52 | 53 | org.eclipse.cdt.make.core.enableFullBuild 54 | true 55 | 56 | 57 | org.eclipse.cdt.make.core.fullBuildTarget 58 | all 59 | 60 | 61 | org.eclipse.cdt.make.core.stopOnError 62 | true 63 | 64 | 65 | org.eclipse.cdt.make.core.useDefaultBuildCmd 66 | true 67 | 68 | 69 | 70 | 71 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 72 | full,incremental, 73 | 74 | 75 | 76 | 77 | 78 | org.eclipse.cdt.core.cnature 79 | org.eclipse.cdt.core.ccnature 80 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 81 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 82 | 83 | 84 | -------------------------------------------------------------------------------- /PerformanceCounter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * PerformanceCounter.h 3 | * 4 | * Created on: 25/mag/2011 5 | * Author: paolo 6 | */ 7 | 8 | #ifndef PERFORMANCECOUNTER_H_ 9 | #define PERFORMANCECOUNTER_H_ 10 | 11 | #include "Processor.h" 12 | #include "MSRObject.h" 13 | 14 | class PerformanceCounter { 15 | protected: 16 | 17 | //On Family 11h BKDG Manual (doc. 41256 Rev. 3.00) see chapter 3.12, page 224 for reference 18 | 19 | PROCESSORMASK cpuMask; 20 | 21 | char perfCounterSlot[MAX_CORES]; 22 | 23 | unsigned char slot; 24 | unsigned char maxslots; 25 | 26 | unsigned short int eventSelect; //Event selection 27 | unsigned char counterMask; //Counter Mask 28 | unsigned char unitMask; //Usually set to 0, can be used to select a sub-event 29 | bool invertCntMask; //Invert counter mask, check reference for explanation 30 | bool enableAPICInterrupt; //Enables an APIC Interrupt when a counter overflows 31 | bool edgeDetect; //0 means Level Detect, 1 means Edge Detect 32 | bool countOsMode; //Counts events happening in OS Mode 33 | bool countUserMode; //Counts events happening in User Mode 34 | unsigned int pesrReg; //Base PESR Register for the CPU 35 | unsigned int percReg; //Base PERC Register for the CPU 36 | unsigned char offset; //Register offset from the base register 37 | 38 | bool enabled; //Only used in case of fetch() method. Do not use it elsewhere 39 | 40 | unsigned int getPESRReg(unsigned char slot); 41 | unsigned int getPERCReg(unsigned char slot); 42 | 43 | MSRObject *snapshotRegister; 44 | 45 | public: 46 | PerformanceCounter(PROCESSORMASK cpuMask, DWORD slot, DWORD maxslots); 47 | 48 | bool program (); 49 | bool fetch(DWORD cpuIndex); 50 | bool enable (); 51 | bool disable (); 52 | bool takeSnapshot (); 53 | uint64_t getCounter (DWORD cpuIndex); 54 | unsigned int findAvailableSlot (); 55 | unsigned int findFreeSlot (); 56 | 57 | virtual ~PerformanceCounter(); 58 | 59 | bool getEnabled () const; 60 | bool getCountUserMode() const; 61 | unsigned char getCounterMask() const; 62 | PROCESSORMASK getCpuMask() const; 63 | bool getEdgeDetect() const; 64 | bool getEnableAPICInterrupt() const; 65 | unsigned short int getEventSelect() const; 66 | bool getInvertCntMask() const; 67 | unsigned char getSlot() const; 68 | unsigned char getUnitMask() const; 69 | void setCountUserMode(bool countUserMode); 70 | void setCounterMask(unsigned char counterMask); 71 | void setCpuMask(PROCESSORMASK cpuMask); 72 | void setEdgeDetect(bool edgeDetect); 73 | void setEnableAPICInterrupt(bool enableAPICInterrupt); 74 | void setEventSelect(unsigned short int eventSelect); 75 | void setInvertCntMask(bool invertCntMask); 76 | void setSlot(unsigned char slot); 77 | void setUnitMask(unsigned char unitMask); 78 | bool getCountOsMode() const; 79 | void setCountOsMode(bool countOsMode); 80 | void setMaxSlots(unsigned char maxslots); 81 | }; 82 | 83 | #endif /* PERFORMANCECOUNTER_H_ */ 84 | -------------------------------------------------------------------------------- /Brazos.h: -------------------------------------------------------------------------------- 1 | class Brazos: protected Processor { 2 | private: 3 | 4 | bool getDramValid(DWORD device); 5 | int getDramFrequency (DWORD device); 6 | void getDramTimingHigh(DWORD device, DWORD *TrwtWB, DWORD *TrwtTO, 7 | DWORD *Twrrd, DWORD *Twrwr, DWORD *Trdrd, DWORD *Tref, DWORD *Trfc0, 8 | DWORD *Trfc1, DWORD *MaxRdLatency); 9 | void getDramTimingLow( 10 | DWORD device, // 0 or 1 DCT0 or DCT1 11 | DWORD *Tcl, DWORD *Trcd, DWORD *Trp, DWORD *Trtp, DWORD *Tras, 12 | DWORD *Trc, DWORD *Twr, DWORD *Trrd, DWORD *Tcwl, DWORD *T_mode, 13 | DWORD *Twtr, DWORD *Tfaw); 14 | 15 | 16 | public: 17 | 18 | Brazos (); 19 | 20 | static bool isProcessorSupported (); 21 | 22 | void showFamilySpecs (); 23 | void showHTC(); 24 | void showHTLink(); 25 | void showDramTimings (); 26 | 27 | float convertVIDtoVcore (DWORD); 28 | DWORD convertVcoretoVID (float); 29 | DWORD convertFDtoFreq (float); 30 | void convertFreqtoFD(DWORD, float *); 31 | 32 | void setVID (PState , DWORD); 33 | void setDID (PState , float); 34 | 35 | DWORD getVID (PState); 36 | float getDID (PState); 37 | 38 | void setFrequency (PState , DWORD); 39 | void setVCore (PState, float); 40 | 41 | DWORD getFrequency (PState); 42 | float getVCore (PState); 43 | 44 | void pStateEnable (PState) ; 45 | void pStateDisable (PState); 46 | bool pStateEnabled (PState); 47 | 48 | void setMaximumPState (PState); 49 | PState getMaximumPState (); 50 | 51 | void forcePState (PState); 52 | 53 | DWORD minVID (); 54 | DWORD maxVID (); 55 | 56 | DWORD startupPState (); 57 | DWORD maxCPUFrequency (); 58 | 59 | DWORD getTctlRegister (void); 60 | DWORD getTctlMaxDiff (void); 61 | 62 | DWORD getRampTime (void); 63 | void setRampTime (DWORD); 64 | 65 | //HTC Section - Read status 66 | bool HTCisCapable (); 67 | bool HTCisEnabled (); 68 | bool HTCisActive (); 69 | bool HTChasBeenActive (); 70 | DWORD HTCTempLimit (); 71 | bool HTCSlewControl (); 72 | DWORD HTCHystTemp (); 73 | DWORD HTCPStateLimit (); 74 | bool HTCLocked (); 75 | 76 | DWORD getAltVID (); 77 | 78 | //HTC Section - Change status 79 | void HTCEnable (); 80 | 81 | void HTCDisable (); 82 | void HTCsetTempLimit (DWORD); 83 | void HTCsetHystLimit (DWORD); 84 | void setAltVid (DWORD); 85 | 86 | //PSI_L bit 87 | bool getPsiEnabled (); 88 | DWORD getPsiThreshold (); 89 | void setPsiEnabled (bool); 90 | void setPsiThreshold (DWORD); 91 | 92 | //HyperTransport Section 93 | 94 | //Various settings 95 | bool getC1EStatus (); 96 | void setC1EStatus (bool); 97 | 98 | // Autocheck mode 99 | void checkMode (); 100 | 101 | //Performance counters 102 | void perfCounterGetInfo (); 103 | void perfCounterGetValue (unsigned int); 104 | void perfMonitorCPUUsage (); 105 | void perfMonitorFPUUsage (); 106 | void perfMonitorDCMA (); 107 | 108 | //Scaler helper methods 109 | void getCurrentStatus (struct procStatus *pStatus, DWORD core); 110 | 111 | }; 112 | 113 | -------------------------------------------------------------------------------- /Llano.h: -------------------------------------------------------------------------------- 1 | class Llano: protected Processor { 2 | private: 3 | 4 | bool getDramValid(DWORD device); 5 | int getDramFrequency (DWORD device); 6 | void getDramTimingHigh(DWORD device, DWORD *TrwtWB, DWORD *TrwtTO, 7 | DWORD *Twrrd, DWORD *Twrwr, DWORD *Trdrd, DWORD *Tref, DWORD *Trfc0, 8 | DWORD *Trfc1, DWORD *MaxRdLatency); 9 | void getDramTimingLow( 10 | DWORD device, // 0 or 1 DCT0 or DCT1 11 | DWORD *Tcl, DWORD *Trcd, DWORD *Trp, DWORD *Trtp, DWORD *Tras, 12 | DWORD *Trc, DWORD *Twr, DWORD *Trrd, DWORD *Tcwl, DWORD *T_mode, 13 | DWORD *Twtr, DWORD *Tfaw); 14 | 15 | float roundDivisor (float divisor); 16 | int roundDivisorToDid (float divisor); 17 | float didDivisors[9]; 18 | 19 | public: 20 | 21 | Llano (); 22 | 23 | static bool isProcessorSupported (); 24 | 25 | void showFamilySpecs (); 26 | void showHTC(); 27 | void showHTLink(); 28 | void showDramTimings (); 29 | 30 | float convertVIDtoVcore (DWORD); 31 | DWORD convertVcoretoVID (float); 32 | DWORD convertFDtoFreq (float, float); 33 | void convertFreqtoFD(DWORD, float *, float *); 34 | 35 | void setVID (PState , DWORD); 36 | void setFID (PState , float); 37 | void setDID (PState , float); 38 | 39 | DWORD getVID (PState); 40 | float getFID (PState); 41 | float getDID (PState); 42 | 43 | void setFrequency (PState , DWORD); 44 | void setVCore (PState, float); 45 | 46 | DWORD getFrequency (PState); 47 | float getVCore (PState); 48 | 49 | void pStateEnable (PState) ; 50 | void pStateDisable (PState); 51 | bool pStateEnabled (PState); 52 | 53 | void setMaximumPState (PState); 54 | PState getMaximumPState (); 55 | 56 | void forcePState (PState); 57 | 58 | DWORD minVID (); 59 | DWORD maxVID (); 60 | 61 | DWORD startupPState (); 62 | DWORD maxCPUFrequency (); 63 | 64 | DWORD getTctlRegister (void); 65 | DWORD getTctlMaxDiff (void); 66 | 67 | DWORD getRampTime(void); 68 | void setRampTime(DWORD slmTime); 69 | 70 | //HTC Section - Read status 71 | bool HTCisCapable (); 72 | bool HTCisEnabled (); 73 | bool HTCisActive (); 74 | bool HTChasBeenActive (); 75 | DWORD HTCTempLimit (); 76 | bool HTCSlewControl (); 77 | DWORD HTCHystTemp (); 78 | DWORD HTCPStateLimit (); 79 | bool HTCLocked (); 80 | 81 | DWORD getAltVID (); 82 | 83 | //HTC Section - Change status 84 | void HTCEnable (); 85 | 86 | void HTCDisable (); 87 | void HTCsetTempLimit (DWORD); 88 | void HTCsetHystLimit (DWORD); 89 | void setAltVid (DWORD); 90 | 91 | //PSI_L bit 92 | bool getPsiEnabled (); 93 | DWORD getPsiThreshold (); 94 | void setPsiEnabled (bool); 95 | void setPsiThreshold (DWORD); 96 | 97 | //Various settings 98 | bool getC1EStatus (); 99 | void setC1EStatus (bool); 100 | 101 | // Autocheck mode 102 | void checkMode (); 103 | 104 | //Performance counters 105 | void perfCounterGetInfo (); 106 | void perfCounterGetValue (unsigned int); 107 | void perfMonitorCPUUsage (); 108 | void perfMonitorFPUUsage (); 109 | void perfMonitorDCMA (); 110 | 111 | //Scaler helper methods 112 | void getCurrentStatus (struct procStatus *pStatus, DWORD core); 113 | 114 | }; 115 | 116 | -------------------------------------------------------------------------------- /Griffin.h: -------------------------------------------------------------------------------- 1 | class Griffin: protected Processor { 2 | private: 3 | 4 | //Private methods for HT Link support 5 | DWORD getHTLinkSpeed(DWORD link, DWORD Sublink); 6 | DWORD getHTLinkWidth(DWORD link, DWORD Sublink, DWORD *WidthIn, 7 | DWORD *WidthOut, bool *pfCoherent, bool *pfUnganged); 8 | DWORD getHTLinkDistributionTarget(DWORD link, DWORD *DstLnk, 9 | DWORD *DstNode); 10 | 11 | void printRoute(DWORD); 12 | 13 | int getDramFrequency (DWORD device); 14 | bool getDramValid (DWORD device); 15 | 16 | void getDramTimingLow( 17 | DWORD device, // 0 or 1 DCT0 or DCT1 18 | DWORD *Tcl, DWORD *Trcd, DWORD *Trp, DWORD *Trtp, DWORD *Tras, 19 | DWORD *Trc, DWORD *Twr, DWORD *Trrd, DWORD *T_mode, DWORD *Tfaw); 20 | 21 | void getDramTimingHigh(DWORD device, DWORD *TrwtWB, DWORD *TrwtTO, 22 | DWORD *Twtr, DWORD *Twrrd, DWORD *Twrwr, DWORD *Trdrd, DWORD *Tref, 23 | DWORD *Trfc0, DWORD *Trfc1); 24 | 25 | protected: 26 | 27 | public: 28 | 29 | Griffin (); 30 | 31 | void testMSR(); 32 | 33 | static bool isProcessorSupported (); 34 | 35 | void showFamilySpecs (); 36 | void showHTC(); 37 | void showHTLink(); 38 | void showDramTimings(); 39 | 40 | float convertVIDtoVcore (DWORD); 41 | DWORD convertVcoretoVID (float); 42 | DWORD convertFDtoFreq (DWORD, DWORD); 43 | void convertFreqtoFD(DWORD, int *, int *); 44 | 45 | void setVID (PState , DWORD); 46 | void setFID (PState , float); 47 | void setDID (PState , float); 48 | 49 | DWORD getVID (PState); 50 | float getFID (PState); 51 | float getDID (PState); 52 | 53 | void setFrequency (PState , DWORD); 54 | void setVCore (PState, float); 55 | 56 | DWORD getFrequency (PState); 57 | float getVCore (PState); 58 | 59 | void pStateEnable (PState) ; 60 | void pStateDisable (PState); 61 | bool pStateEnabled (PState); 62 | 63 | void setMaximumPState (PState); 64 | PState getMaximumPState (); 65 | 66 | void forcePState (PState); 67 | 68 | void setNBVid (DWORD); 69 | DWORD getNBVid (); 70 | // DWORD getNBVid (PState); 71 | // DWORD getNBDid (PState); 72 | bool getSMAF7Enabled (); 73 | DWORD c1eDID (); 74 | DWORD minVID (); 75 | DWORD maxVID (); 76 | DWORD startupPState (); 77 | DWORD maxCPUFrequency (); 78 | 79 | DWORD getTctlRegister (void); 80 | DWORD getTctlMaxDiff (void); 81 | 82 | DWORD getSlamTime (void); 83 | void setSlamTime (DWORD); 84 | 85 | DWORD getAltVidSlamTime (void); 86 | void setAltVidSlamTime (DWORD); 87 | 88 | 89 | /*DWORD getStepUpRampTime (void); 90 | DWORD getStepDownRampTime (void); 91 | void setStepUpRampTime (DWORD); 92 | void setStepDownRampTime (DWORD);*/ 93 | 94 | //HTC Section - Read status 95 | bool HTCisCapable (); 96 | bool HTCisEnabled (); 97 | bool HTCisActive (); 98 | bool HTChasBeenActive (); 99 | DWORD HTCTempLimit (); 100 | bool HTCSlewControl (); 101 | DWORD HTCHystTemp (); 102 | DWORD HTCPStateLimit (); 103 | bool HTCLocked (); 104 | DWORD getAltVID (); 105 | 106 | //HTC Section - Change status 107 | void HTCEnable (); 108 | void HTCDisable (); 109 | void HTCsetTempLimit (DWORD); 110 | void HTCsetHystLimit (DWORD); 111 | void setAltVid (DWORD); 112 | 113 | //PSI_L bit 114 | bool getPsiEnabled (); 115 | DWORD getPsiThreshold (); 116 | void setPsiEnabled (bool); 117 | void setPsiThreshold (DWORD); 118 | 119 | //HyperTransport Section 120 | void setHTLinkSpeed (DWORD, DWORD); 121 | 122 | //Various settings 123 | bool getC1EStatus (); 124 | void setC1EStatus (bool); 125 | 126 | //Performance counters 127 | void perfCounterGetInfo (); 128 | void perfCounterGetValue (unsigned int); 129 | void perfMonitorCPUUsage (); 130 | void perfMonitorFPUUsage (); 131 | void perfMonitorDCMA (); 132 | 133 | 134 | // Autocheck mode 135 | void checkMode (); 136 | 137 | //Scaler helper methods 138 | void getCurrentStatus (struct procStatus *pStatus); 139 | 140 | }; 141 | 142 | -------------------------------------------------------------------------------- /Interlagos.h: -------------------------------------------------------------------------------- 1 | class Interlagos: protected Processor 2 | { 3 | private: 4 | 5 | //Private methods for HT Link support 6 | DWORD getHTLinkSpeed(DWORD link, DWORD Sublink); 7 | DWORD getHTLinkWidth(DWORD link, DWORD Sublink, DWORD *WidthIn, DWORD *WidthOut, bool *pfCoherent, bool *pfUnganged); 8 | DWORD getHTLinkDistributionTarget(DWORD link, DWORD *DstLnk, DWORD *DstNode); 9 | 10 | void printRoute(DWORD); 11 | 12 | bool setDramController(DWORD device); 13 | int getDramFrequency(DWORD device, DWORD *T_mode); 14 | bool getDramValid(DWORD device); 15 | 16 | //DRAM timing registers 17 | void getDramTiming(DWORD device, /* 0 or 1 */ DWORD *Tcl, DWORD *Trcd, DWORD *Trp, DWORD *Trtp, DWORD *Tras, 18 | DWORD *Trc, DWORD *Twr, DWORD *Trrd, DWORD *Tcwl, DWORD *T_faw, DWORD *TrwtWB, 19 | DWORD *TrwtTO, DWORD *Twtr, DWORD *Twrrd, DWORD *Twrwrsdsc, DWORD *Trdrdsdsc, DWORD *Tref, 20 | DWORD *Trfc0, DWORD *Trfc1, DWORD *Trfc2, DWORD *Trfc3, DWORD *MaxRdLatency); 21 | 22 | bool isSvi2(); 23 | bool isPsiThresholdValid(DWORD); 24 | 25 | public: 26 | 27 | Interlagos(); 28 | 29 | static bool isProcessorSupported(); 30 | 31 | void showFamilySpecs(); 32 | void showHTC(); 33 | void showHTLink(); 34 | void showDramTimings (); 35 | 36 | float convertVIDtoVcore(DWORD); 37 | DWORD convertVcoretoVID(float); 38 | void convertFreqtoFDEx(DWORD, int *, int *, int, int, int); 39 | void convertFreqtoFD(DWORD, int *, int *); 40 | DWORD convertFDtoFreq(DWORD, DWORD); 41 | void convertNBFreqtoFD(DWORD, int *, int *); 42 | DWORD convertNBFDtoFreq(DWORD, DWORD); 43 | 44 | void setVID(PState, DWORD); 45 | void setFID(PState, float); 46 | void setDID(PState, float); 47 | 48 | DWORD getVID(PState); 49 | float getFID(PState); 50 | float getDID(PState); 51 | 52 | void setFrequency(PState , DWORD); 53 | void setVCore(PState, float); 54 | 55 | DWORD getFrequency(PState); 56 | float getVCore(PState); 57 | 58 | bool getPVIMode(); 59 | 60 | void pStateEnable(PState) ; 61 | void pStateDisable(PState); 62 | bool pStateEnabled(PState); 63 | 64 | void setMaximumPState(PState); 65 | PState getMaximumPState(); 66 | 67 | void forcePState(PState); 68 | 69 | void setNBVid(DWORD); 70 | void setNBDid(DWORD); 71 | DWORD getNBVid(); 72 | 73 | DWORD getNBDid(); 74 | DWORD getNBFid(); 75 | DWORD getNBCOF(); 76 | void setNBFid(DWORD); 77 | 78 | bool setNBFrequency(DWORD); 79 | DWORD getNBFrequency(); 80 | 81 | DWORD getMaxNBFrequency(); 82 | 83 | DWORD minVID(); 84 | DWORD maxVID(); 85 | 86 | DWORD maxVIDByCore(DWORD core); 87 | DWORD minVIDByCore(DWORD core); 88 | 89 | DWORD startupPState(); 90 | DWORD maxCPUFrequency(); 91 | DWORD getNumBoostStates(void); 92 | void setNumBoostStates(DWORD); 93 | DWORD getBoost(void); 94 | void setBoost(bool); 95 | DWORD getTDP(void); 96 | 97 | //Virtual method to modify DRAM timings -- Needs testing, only for DDR3 at the moment 98 | DWORD setDramTiming(DWORD device, /* 0 or 1 */ DWORD Tcl, DWORD Trcd, DWORD Trp, DWORD Trtp, DWORD Tras, 99 | DWORD Trc, DWORD Twr, DWORD Trrd, DWORD Tcwl, DWORD T_mode); 100 | 101 | DWORD getTctlRegister(void); 102 | DWORD getTctlMaxDiff(void); 103 | 104 | DWORD getSlamTime(void); 105 | void setSlamTime(DWORD); 106 | 107 | DWORD getStepUpRampTime(void); 108 | DWORD getStepDownRampTime(void); 109 | void setStepUpRampTime(DWORD); 110 | void setStepDownRampTime(DWORD); 111 | 112 | //HTC Section - Read status 113 | bool HTCisCapable(); 114 | bool HTCisEnabled(); 115 | bool HTCisActive(); 116 | bool HTChasBeenActive(); 117 | DWORD HTCTempLimit(); 118 | bool HTCSlewControl(); 119 | DWORD HTCHystTemp(); 120 | DWORD HTCPStateLimit(); 121 | bool HTCLocked(); 122 | 123 | //HTC Section - Change status 124 | void HTCEnable(); 125 | 126 | void HTCDisable(); 127 | void HTCsetTempLimit(DWORD); 128 | void HTCsetHystLimit(DWORD); 129 | 130 | //PSI_L bit 131 | bool getPsiEnabled(); 132 | DWORD getPsiThreshold(); 133 | void setPsiEnabled(bool); 134 | void setPsiThreshold(DWORD); 135 | 136 | //HyperTransport Section 137 | void setHTLinkSpeed(DWORD, DWORD); 138 | 139 | //Various settings 140 | bool getC1EStatus(); 141 | void setC1EStatus(bool); 142 | 143 | // Autocheck mode 144 | void checkMode(); 145 | 146 | //Performance counters 147 | void perfCounterGetInfo(); 148 | void perfCounterGetValue(unsigned int); 149 | void perfMonitorCPUUsage(); 150 | void perfMonitorFPUUsage(); 151 | void perfMonitorDCMA(); 152 | 153 | //Scaler helper methods 154 | void getCurrentStatus(struct procStatus *pStatus, DWORD core); 155 | }; -------------------------------------------------------------------------------- /K10Processor.h: -------------------------------------------------------------------------------- 1 | class K10Processor: protected Processor { 2 | private: 3 | 4 | //Private methods for HT Link support 5 | DWORD getHTLinkSpeed(DWORD link, DWORD Sublink); 6 | DWORD getHTLinkWidth(DWORD link, DWORD Sublink, DWORD *WidthIn, 7 | DWORD *WidthOut, bool *pfCoherent, bool *pfUnganged); 8 | DWORD getHTLinkDistributionTarget(DWORD link, DWORD *DstLnk, 9 | DWORD *DstNode); 10 | 11 | void printRoute(DWORD); 12 | 13 | int getDramFrequency (DWORD device); 14 | bool getDDR3Mode (DWORD device); 15 | bool getDramValid (DWORD device); 16 | 17 | 18 | //DRAM timing register Low 19 | void getDramTimingLow( 20 | DWORD device, // 0 or 1 21 | DWORD *Tcl, DWORD *Trcd, DWORD *Trp, DWORD *Trtp, DWORD *Tras, 22 | DWORD *Trc, DWORD *Twr, DWORD *Trrd, DWORD *Tcwl, DWORD *T_mode, DWORD *T_faw); 23 | 24 | //DRAM timing register High 25 | void getDramTimingHigh(DWORD device, DWORD *TrwtWB, 26 | DWORD *TrwtTO, DWORD *Twtr, DWORD *Twrrd, DWORD *Twrwr, 27 | DWORD *Trdrd, DWORD *Tref, DWORD *Trfc0, DWORD *Trfc1, 28 | DWORD *Trfc2, DWORD *Trfc3, DWORD *MaxRdLatency); 29 | 30 | int boostSupported; 31 | bool isPsiThresholdValid(DWORD); 32 | 33 | public: 34 | 35 | K10Processor (); 36 | 37 | static bool isProcessorSupported (); 38 | 39 | void showFamilySpecs (); 40 | void showHTC(); 41 | void showHTLink(); 42 | void showDramTimings (); 43 | 44 | float convertVIDtoVcore (DWORD); 45 | DWORD convertVcoretoVID (float); 46 | void convertFreqtoFDEx(DWORD, int *, int *, int, int, int); 47 | void convertFreqtoFD(DWORD, int *, int *); 48 | DWORD convertFDtoFreq (DWORD, DWORD); 49 | void convertNBFreqtoFD(DWORD, int *, int *); 50 | DWORD convertNBFDtoFreq(DWORD, DWORD); 51 | 52 | void setVID (PState , DWORD); 53 | void setFID (PState , float); 54 | void setDID (PState , float); 55 | 56 | DWORD getVID (PState); 57 | float getFID (PState); 58 | float getDID (PState); 59 | 60 | void setFrequency (PState , DWORD); 61 | void setVCore (PState, float); 62 | 63 | DWORD getFrequency (PState); 64 | float getVCore (PState); 65 | 66 | bool getPVIMode (); 67 | 68 | void pStateEnable (PState) ; 69 | void pStateDisable (PState); 70 | bool pStateEnabled (PState); 71 | 72 | void setMaximumPState (PState); 73 | PState getMaximumPState (); 74 | 75 | void forcePState (PState); 76 | 77 | void setNBVid (PState, DWORD); 78 | void setNBDid (PState, DWORD); 79 | // DWORD getNBVid (); 80 | DWORD getNBVid (PState); 81 | 82 | DWORD getNBDid (PState); 83 | DWORD getNBFid (); 84 | void setNBFid (DWORD); 85 | 86 | bool setNBFrequency(PState, DWORD); 87 | DWORD getNBFrequency(PState); 88 | 89 | DWORD getMaxNBFrequency (); 90 | 91 | DWORD minVID (); 92 | DWORD maxVID (); 93 | 94 | DWORD maxVIDByCore( DWORD core ); 95 | DWORD minVIDByCore( DWORD core ); 96 | 97 | DWORD startupPState (); 98 | DWORD maxCPUFrequency (); 99 | DWORD getNumBoostStates(void); 100 | void setNumBoostStates(DWORD); 101 | DWORD getBoost(void); 102 | void setBoost(bool); 103 | 104 | //Virtual method to modify DRAM timings -- Needs testing, only for DDR3 at the moment 105 | DWORD setDramTiming( 106 | DWORD device, // 0 or 1 107 | DWORD Tcl, DWORD Trcd, DWORD Trp, DWORD Trtp, DWORD Tras, 108 | DWORD Trc, DWORD Twr, DWORD Trrd, DWORD Tcwl, DWORD T_mode); 109 | 110 | DWORD getTctlRegister (void); 111 | DWORD getTctlMaxDiff (void); 112 | 113 | DWORD getSlamTime (void); 114 | void setSlamTime (DWORD); 115 | 116 | /*DWORD getAltVidSlamTime (void); 117 | void setAltVidSlamTime (DWORD);*/ 118 | 119 | DWORD getStepUpRampTime (void); 120 | DWORD getStepDownRampTime (void); 121 | void setStepUpRampTime (DWORD); 122 | void setStepDownRampTime (DWORD); 123 | 124 | //HTC Section - Read status 125 | bool HTCisCapable (); 126 | bool HTCisEnabled (); 127 | bool HTCisActive (); 128 | bool HTChasBeenActive (); 129 | DWORD HTCTempLimit (); 130 | bool HTCSlewControl (); 131 | DWORD HTCHystTemp (); 132 | DWORD HTCPStateLimit (); 133 | bool HTCLocked (); 134 | 135 | DWORD getAltVID (); 136 | 137 | //HTC Section - Change status 138 | void HTCEnable (); 139 | 140 | void HTCDisable (); 141 | void HTCsetTempLimit (DWORD); 142 | void HTCsetHystLimit (DWORD); 143 | void setAltVid (DWORD); 144 | 145 | //PSI_L bit 146 | bool getPsiEnabled (); 147 | DWORD getPsiThreshold (); 148 | void setPsiEnabled (bool); 149 | void setPsiThreshold (DWORD); 150 | 151 | //HyperTransport Section 152 | void setHTLinkSpeed (DWORD, DWORD); 153 | 154 | //Various settings 155 | bool getC1EStatus (); 156 | void setC1EStatus (bool); 157 | 158 | // Autocheck mode 159 | void checkMode (); 160 | 161 | //Performance counters 162 | void perfCounterGetInfo (); 163 | void perfCounterGetValue (unsigned int); 164 | void perfMonitorCPUUsage (); 165 | void perfMonitorFPUUsage (); 166 | void perfMonitorDCMA (); 167 | 168 | //Scaler helper methods 169 | void getCurrentStatus (struct procStatus *pStatus, DWORD core); 170 | 171 | }; 172 | 173 | -------------------------------------------------------------------------------- /PCIRegObject.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * PCIRegObject.cpp 3 | * 4 | * Created on: 29/mar/2011 5 | * Author: paolo 6 | */ 7 | 8 | #include "PCIRegObject.h" 9 | #include "sysdep.h" 10 | 11 | DWORD PCIRegObject::getPath() 12 | { 13 | return getPath(this->device, this->function); 14 | } 15 | 16 | DWORD PCIRegObject::getPath(DWORD device, DWORD function) 17 | { 18 | return (device << 3) + (function); 19 | } 20 | 21 | //Constructor 22 | PCIRegObject::PCIRegObject() 23 | { 24 | this->reg_ptr=NULL; 25 | this->absIndex=NULL; 26 | this->nodeMask=0x0; 27 | this->reg=0x0; 28 | this->function=0x0; 29 | this->device=0x0; 30 | this->nodeCount=0x0; 31 | } 32 | 33 | /* 34 | * newPCIReg initializes a new object with default values (zeros). 35 | * Use this function if you are going to override register values 36 | */ 37 | void PCIRegObject::newPCIReg(DWORD device, DWORD function, DWORD reg, DWORD nodeMask) 38 | { 39 | DWORD mask; 40 | unsigned int count; 41 | 42 | this->nodeMask = nodeMask; 43 | this->reg = reg; 44 | this->function = function; 45 | this->device = device; 46 | 47 | //count as many nodes are accounted in nodeMask 48 | mask = this->nodeMask; 49 | count = 0; 50 | while (mask) { 51 | if (mask & 1) { 52 | count++; 53 | } 54 | mask >>= 1; 55 | } 56 | 57 | this->nodeCount = count; 58 | 59 | if (this->reg_ptr) free(this->reg_ptr); 60 | if (this->absIndex) free(this->absIndex); 61 | 62 | this->reg_ptr = (DWORD *) calloc(this->nodeCount, sizeof(DWORD)); 63 | this->absIndex = (unsigned int *) calloc (this->nodeCount, sizeof(unsigned int)); 64 | 65 | return; 66 | } 67 | 68 | /* 69 | * readPCIReg reads a PCI Configuration Register 70 | * Parameters are: 71 | * - device 72 | * - function 73 | * - register 74 | * - nodeMask 75 | * 76 | * device and function parameters are constructed togheter using the private function 77 | * getPath. In multiprocessor machines, each function is increased for each processor/node 78 | * in the system. 79 | * nodeMask is a bitmask of nodes. Bit 0 will let the function read the PCI register from 80 | * node 0, bit 1 for node 1 and so on. 81 | */ 82 | bool PCIRegObject::readPCIReg(DWORD device, DWORD function, DWORD reg, DWORD nodeMask) 83 | { 84 | DWORD mask; 85 | unsigned int count; 86 | DWORD nid; 87 | 88 | this->nodeMask = nodeMask; 89 | this->reg = reg; 90 | this->function = function; 91 | this->device = device; 92 | 93 | //count as many nodes are accounted in nodeMask 94 | mask = this->nodeMask; 95 | count = 0; 96 | while (mask) { 97 | if (mask & 1) { 98 | count++; 99 | } 100 | mask >>= 1; 101 | } 102 | 103 | this->nodeCount = count; 104 | 105 | if (this->reg_ptr) free(this->reg_ptr); 106 | if (this->absIndex) free (this->absIndex); 107 | 108 | this->reg_ptr = (DWORD *) calloc(this->nodeCount, sizeof(DWORD)); 109 | this->absIndex = (unsigned int *) calloc (this->nodeCount, sizeof(unsigned int)); 110 | 111 | mask = this->nodeMask; 112 | count = 0; 113 | nid = 0; 114 | 115 | while (mask) 116 | { 117 | if (mask & 1) 118 | { 119 | if (!SysReadPciConfigDwordEx(getPath(this->device+nid, this->function), this->reg, &this->reg_ptr[count])) 120 | { 121 | /*This is not needed since memory will be freed by destructor 122 | free(this->reg_ptr); 123 | free(this->absIndex);*/ 124 | this->nodeCount = 0; 125 | return false; 126 | } 127 | absIndex[count] = nid; 128 | count++; 129 | } 130 | 131 | nid++; 132 | mask >>= 1; 133 | 134 | } 135 | 136 | return true; 137 | } 138 | 139 | /* 140 | * writePCIReg writes the PCI registers to the processors using nodeMask and parameters 141 | * set when using readPCIReg. 142 | */ 143 | 144 | bool PCIRegObject::writePCIReg () 145 | { 146 | DWORD mask; 147 | unsigned int count; 148 | DWORD nid; 149 | 150 | if (this->nodeCount==0) return true; 151 | 152 | mask = this->nodeMask; 153 | count=0; 154 | nid=0; 155 | 156 | while (mask) 157 | { 158 | if (mask & 1) 159 | { 160 | if (!SysWritePciConfigDwordEx (getPath(this->device+nid, this->function),this->reg,this->reg_ptr[count])) return false; 161 | count++; 162 | } 163 | 164 | nid++; 165 | mask >>= 1; 166 | 167 | } 168 | 169 | return true; 170 | 171 | } 172 | 173 | unsigned int PCIRegObject::indexToAbsolute (unsigned int index) 174 | { 175 | 176 | return this->absIndex[index]; 177 | 178 | } 179 | 180 | /* Returns the number of nodes currently in memory of an object */ 181 | DWORD PCIRegObject::getCount () 182 | { 183 | return this->nodeCount; 184 | } 185 | 186 | /* 187 | * getBits returns an integer for a specific node. Base and length parameters are used to isolate 188 | * the sector of the whole register that is interesting. 189 | */ 190 | DWORD PCIRegObject::getBits (unsigned int nodeNumber, unsigned int base, unsigned int length) 191 | { 192 | 193 | DWORD xReg; 194 | 195 | if (this->nodeCount==0) return 0; 196 | if (nodeNumber>=this->nodeCount) return 0; 197 | 198 | xReg=this->reg_ptr[nodeNumber]; 199 | 200 | xReg=xReg<<(32-base-length); 201 | xReg=xReg>>(32-length); 202 | 203 | return xReg; 204 | } 205 | 206 | /* 207 | * setBits set the bits for all the processors specified in nodeMask. 208 | * Base and length specify the offset and the width of the sector of the register 209 | * we're interested in. 210 | */ 211 | bool PCIRegObject::setBits (unsigned int base, unsigned int length, DWORD value) 212 | { 213 | 214 | DWORD mask; 215 | DWORD count; 216 | 217 | if (this->nodeCount==0) return false; 218 | 219 | mask = -1; 220 | mask >>= (32 - length); 221 | mask <<= base; 222 | 223 | value=value<nodeCount;count++) 229 | this->reg_ptr[count]=(this->reg_ptr[count] & mask) | value; 230 | 231 | return true; 232 | 233 | } 234 | 235 | PCIRegObject::~PCIRegObject() 236 | { 237 | 238 | if (this->reg_ptr) free (this->reg_ptr); 239 | if (this->absIndex) free (this->absIndex); 240 | 241 | } 242 | -------------------------------------------------------------------------------- /sysdep-win32.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include "OlsApi.h" 5 | #include "OlsDef.h" 6 | #include "sysdep.h" 7 | 8 | bool initializeCore(void) 9 | { 10 | int dllStatus; 11 | BYTE verMajor,verMinor,verRevision,verRelease; 12 | 13 | InitializeOls (); 14 | 15 | dllStatus=GetDllStatus (); 16 | 17 | if (dllStatus!=0) { 18 | printf ("Unable to initialize WinRing0 library\n"); 19 | 20 | switch (dllStatus) { 21 | case OLS_DLL_UNSUPPORTED_PLATFORM: 22 | printf ("Error: unsupported platform\n"); 23 | break; 24 | case OLS_DLL_DRIVER_NOT_LOADED: 25 | printf ("Error: driver not loaded\n"); 26 | break; 27 | case OLS_DLL_DRIVER_NOT_FOUND: 28 | printf ("Error: driver not found\n"); 29 | break; 30 | case OLS_DLL_DRIVER_UNLOADED: 31 | printf ("Error: driver unloaded by other process\n"); 32 | break; 33 | case OLS_DLL_DRIVER_NOT_LOADED_ON_NETWORK: 34 | printf ("Error: driver not loaded from network\n"); 35 | break; 36 | case OLS_DLL_UNKNOWN_ERROR: 37 | printf ("Error: unknown error\n"); 38 | break; 39 | default: 40 | printf ("Error: unknown error\n"); 41 | } 42 | 43 | return false; 44 | } 45 | 46 | GetDriverVersion (&verMajor,&verMinor,&verRevision,&verRelease); 47 | 48 | if ((verMajor>=1) && (verMinor>=2)) return true; 49 | 50 | return false; 51 | } 52 | 53 | 54 | bool deinitializeCore(void) 55 | { 56 | DeinitializeOls(); 57 | return true; 58 | } 59 | 60 | 61 | void ClearScreen(unsigned int flags) 62 | { 63 | HANDLE h; 64 | CONSOLE_SCREEN_BUFFER_INFO csbi; 65 | DWORD len; 66 | DWORD dummy; 67 | COORD corner = { 0, 0 }; 68 | COORD now; 69 | 70 | h = GetStdHandle(STD_OUTPUT_HANDLE); 71 | if (h == INVALID_HANDLE_VALUE) { 72 | return; 73 | } 74 | 75 | if (!GetConsoleScreenBufferInfo(h, &csbi)) { 76 | return; 77 | } 78 | if (flags & CLEARSCREEN_FLAG_SMART) { 79 | len = csbi.dwSize.X * csbi.dwCursorPosition.Y + csbi.dwCursorPosition.X; 80 | } else { 81 | len = csbi.dwSize.X * csbi.dwSize.Y; 82 | } 83 | 84 | if (!FillConsoleOutputCharacter(h, (TCHAR) ' ', len, corner, &dummy)) { 85 | return; 86 | } 87 | 88 | if (!FillConsoleOutputAttribute(h, csbi.wAttributes, len, corner, &dummy)) { 89 | return; 90 | } 91 | SetConsoleCursorPosition(h, corner); 92 | } 93 | 94 | // 95 | // Tests if special PCI Extended Configuration Space access is required. 96 | // 97 | // This is true on Windows XP/2003 and configuration space offsets >= 0x100 98 | // as these operating systems do not provide appropriate API. 99 | // 100 | // More info: 101 | // http://www.osronline.com/showThread.cfm?link=87866 102 | // https://code.google.com/p/turionpowercontrol/issues/detail?id=28 103 | // 104 | bool SpecialEcsAccessRequired(DWORD reg) 105 | { 106 | OSVERSIONINFO versioninfo; 107 | if (reg < 0x100) 108 | return false; 109 | versioninfo.dwOSVersionInfoSize = sizeof(versioninfo); 110 | if (!GetVersionEx(&versioninfo)) { 111 | return false; 112 | } 113 | if (versioninfo.dwMajorVersion >= 6) { 114 | return false; 115 | } 116 | return true; 117 | } 118 | 119 | // 120 | // Performs special Extended Configuration Space access. 121 | // 122 | // It takes advantage of AMD-specific IO CF8h/CFCh extension that enables 123 | // accesses to PCI Extended Configuration Space. Access is realized by 124 | // enabling ECS access via IOCF8/IOCFC using EnableCf8ExtCfg from NB_CFG 125 | // MSR (MSRC001_001F) and performing CF8h/CFCh access per specifciation. 126 | // State of NB_CFG and IOCF8 is saved before the operation and gets 127 | // restored afterwards. Calling process is also bound to first CPU 128 | // in the system for the duration of the operation to accommodate 129 | // environments with multiple northbridges. 130 | // 131 | // EnableCf8ExtCfg is supported by all currently supported CPU families, 132 | // that is, 10h, 11h, 12h, 14h, 15h and 16h. 133 | // 134 | // IO CF8h/CFCh method, while racy, is the only feasible method to access 135 | // PCI ECS on Windows XP/2003 (accessing memory mapped configuration space 136 | // is off the table due to lack of physical memory access support 137 | // in WinRing0). 138 | // 139 | // Best effort is put to detect simultaneous users of CF8h/CFCh. 140 | // 141 | bool SpecialEcsAccess(bool write, DWORD devfunc, DWORD reg, DWORD *res) 142 | { 143 | DWORD_PTR mask_save; 144 | DWORD_PTR dummy; 145 | DWORD eax_save; 146 | DWORD edx_save; 147 | DWORD edx; 148 | DWORD addr; 149 | DWORD addr_save; 150 | DWORD addr_check; 151 | DWORD data; 152 | bool result = false; 153 | 154 | if (!GetProcessAffinityMask((HANDLE)-1, &mask_save, &dummy)) { 155 | fprintf(stderr, "ERROR getting affinity mask\n"); 156 | goto out; 157 | } 158 | if (!SetProcessAffinityMask((HANDLE)-1, 1)) { 159 | fprintf(stderr, "ERROR setting affinity mask\n"); 160 | goto out; 161 | } 162 | if (!RdmsrPx(0xC001001F, &eax_save, &edx_save, 1)) { 163 | fprintf(stderr, "ERROR reading NB_CFG\n"); 164 | goto out_affinity; 165 | } 166 | edx = edx_save; 167 | edx |= 0x4000; 168 | if (!WrmsrPx(0xC001001F, eax_save, edx, (DWORD_PTR)1)) { 169 | fprintf(stderr, "ERROR writing NB_CFG\n"); 170 | goto out_affinity; 171 | } 172 | addr_save = ReadIoPortDword(0xcf8); 173 | addr = 1; 174 | addr <<= 7; 175 | addr |= (reg >> 8) & 0x0F; 176 | addr <<= 16; 177 | addr |= devfunc & 0xFFFF; 178 | addr <<= 8; 179 | addr |= reg & 0xFF; 180 | WriteIoPortDword(0xcf8, addr); 181 | if (write == false) { 182 | data = ReadIoPortDword(0xcfc); 183 | } else { 184 | WriteIoPortDword(0xcfc, *res); 185 | } 186 | addr_check = ReadIoPortDword(0xcf8); 187 | if (addr_check != addr) { 188 | fprintf(stderr, "ERROR: IO CF8h hijacked!\n"); 189 | goto out_nbcfg; 190 | } 191 | WriteIoPortDword(0xcf8, addr_save); 192 | if (write == false) { 193 | *res = data; 194 | } 195 | result = true; 196 | out_nbcfg: 197 | WrmsrPx(0xC001001F, eax_save, edx_save, (DWORD_PTR)1); 198 | out_affinity: 199 | SetProcessAffinityMask((HANDLE)-1, mask_save); 200 | out: 201 | return result; 202 | } 203 | 204 | BOOL SysReadPciConfigDwordEx(DWORD pciAddress, DWORD regAddress, PDWORD value) 205 | { 206 | if (SpecialEcsAccessRequired(regAddress)) { 207 | return SpecialEcsAccess(false, pciAddress, regAddress, value); 208 | } 209 | return ReadPciConfigDwordEx(pciAddress, regAddress, value); 210 | } 211 | 212 | BOOL SysWritePciConfigDwordEx(DWORD pciAddress, DWORD regAddress, DWORD value) 213 | { 214 | if (SpecialEcsAccessRequired(regAddress)) { 215 | return SpecialEcsAccess(true, pciAddress, regAddress, &value); 216 | } 217 | return WritePciConfigDwordEx(pciAddress, regAddress, value); 218 | } 219 | -------------------------------------------------------------------------------- /cpuPrimitives.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "cpuPrimitives.h" 9 | #include 10 | 11 | BOOL Cpuid(DWORD index, PDWORD eax, PDWORD ebx, PDWORD ecx, PDWORD edx) 12 | { 13 | char cpuid_filename[128]; 14 | DWORD data[4]; 15 | int fd; 16 | 17 | sprintf(cpuid_filename, "/dev/cpu/0/cpuid"); 18 | 19 | fd = open(cpuid_filename, O_RDONLY); 20 | 21 | if ( fd < 0 ) 22 | { 23 | if ( errno == ENXIO ) 24 | { 25 | fprintf(stderr, "cpuid: No CPUID on processor 0\n"); 26 | return false; 27 | } 28 | else if (errno == EIO ) 29 | { 30 | fprintf(stderr, "cpuid: CPU 0 doesn't support CPUID\n"); 31 | return false; 32 | } 33 | else 34 | { 35 | perror("cpuid:open"); 36 | return false; 37 | } 38 | } 39 | 40 | if ( pread(fd, &data, sizeof data, index) != sizeof data ) 41 | { 42 | perror("cpuid:pread"); 43 | return false; 44 | } 45 | 46 | *eax=data[0]; 47 | *ebx=data[1]; 48 | *ecx=data[2]; 49 | *edx=data[3]; 50 | 51 | close(fd); 52 | 53 | return true; 54 | } 55 | 56 | BOOL ReadPciConfigDwordEx(DWORD pciAddress, DWORD regAddress, PDWORD value) 57 | { 58 | char pcidev_filename[128]; 59 | int fd; 60 | DWORD data; 61 | DWORD bus, device, function; 62 | 63 | bus=(pciAddress >> 8) & 0xff; 64 | device=(pciAddress >> 3) & 0x1f; 65 | function=pciAddress & 0x7; 66 | 67 | sprintf(pcidev_filename, "/proc/bus/pci/%02x/%02x.%x",bus,device,function); 68 | 69 | fd = open(pcidev_filename, O_RDONLY); 70 | 71 | if ( fd < 0 ) 72 | { 73 | if ( errno == ENXIO ) 74 | { 75 | fprintf(stderr, "ReadPciConfigDwordEx: ENXIO error\n"); 76 | return false; 77 | } 78 | else if (errno == EIO ) 79 | { 80 | fprintf(stderr, "ReadPciConfigDwordEx: EIO error\n"); 81 | return false; 82 | } 83 | else 84 | { 85 | perror("ReadPciConfigDwordEx: open"); 86 | return false; 87 | } 88 | } 89 | 90 | if ( pread(fd, &data, sizeof data, regAddress) != sizeof data ) 91 | { 92 | perror("ReadPciConfigDwordEx: pread"); 93 | return false; 94 | } 95 | 96 | *value = data; 97 | 98 | close(fd); 99 | 100 | return true; 101 | } 102 | 103 | BOOL WritePciConfigDwordEx(DWORD pciAddress, DWORD regAddress, DWORD value) 104 | { 105 | char pcidev_filename[128]; 106 | int fd; 107 | DWORD data; 108 | DWORD bus, device, function; 109 | 110 | bus=(pciAddress >> 8) & 0xff; 111 | device=(pciAddress >> 3) & 0x1f; 112 | function=pciAddress & 0x7; 113 | 114 | sprintf(pcidev_filename, "/proc/bus/pci/%02x/%02x.%x",bus,device,function); 115 | 116 | fd = open(pcidev_filename, O_WRONLY); 117 | 118 | if ( fd < 0 ) 119 | { 120 | if ( errno == ENXIO ) 121 | { 122 | fprintf(stderr, "WritePciConfigDwordEx: ENXIO error\n"); 123 | return false; 124 | } 125 | else if (errno == EIO ) 126 | { 127 | fprintf(stderr, "WritePciConfigDwordEx: EIO error\n"); 128 | return false; 129 | } 130 | else 131 | { 132 | perror("WritePciConfigDwordEx: open"); 133 | return false; 134 | } 135 | } 136 | 137 | data=value; 138 | 139 | if ( pwrite(fd, &data, sizeof data, regAddress) != sizeof data ) 140 | { 141 | perror("WritePciConfigDwordEx: pwrite"); 142 | return false; 143 | } 144 | 145 | close(fd); 146 | 147 | return true; 148 | } 149 | 150 | BOOL RdmsrPx(DWORD index, PDWORD eax, PDWORD edx, DWORD_PTR processAffinityMask) 151 | { 152 | char msr_filename[128]; 153 | DWORD data[2]; 154 | int fd; 155 | DWORD processor=0; 156 | 157 | while (processAffinityMask) 158 | { 159 | if (processAffinityMask & 1) 160 | { 161 | sprintf(msr_filename, "/dev/cpu/%d/msr",processor); 162 | 163 | fd = open(msr_filename, O_RDONLY); 164 | 165 | if ( fd < 0 ) { 166 | if ( errno == ENXIO ) { 167 | fprintf(stderr, "RdmsrPx: Invalid %u processor\n",processor); 168 | return false; 169 | } else if (errno == EIO ) { 170 | fprintf(stderr, "RdmsrPx: CPU %u doesn't support MSR\n",processor); 171 | return false; 172 | } else { 173 | perror("RdmsrPx: open"); 174 | return false; 175 | } 176 | } 177 | 178 | 179 | if ( pread(fd, &data, sizeof data, index) != sizeof data ) 180 | { 181 | perror("rdmsr: pread"); 182 | return false; 183 | } 184 | 185 | *eax=data[0]; 186 | *edx=data[1]; 187 | 188 | close(fd); 189 | 190 | //This is intended because this procedure can't report more than 191 | //one CPU MSR, so we will report the first processor in the mask 192 | //discarding the others. 193 | //In the write flavour of this procedure, it is useful to try 194 | //for all processors in the mask. 195 | return true; 196 | } 197 | processor++; 198 | processAffinityMask >>= 1; 199 | } 200 | return true; 201 | } 202 | 203 | BOOL Rdmsr(DWORD index, PDWORD eax, PDWORD edx) 204 | { 205 | return RdmsrPx(index, eax, edx, 0x1); 206 | } 207 | 208 | BOOL WrmsrPx(DWORD index, DWORD eax, DWORD edx, DWORD_PTR processAffinityMask) 209 | { 210 | char msr_filename[128]; 211 | DWORD data[2]; 212 | int fd; 213 | DWORD processor=0; 214 | 215 | // printf ("Mask: %x\n", processAffinityMask); 216 | 217 | while (processAffinityMask) { 218 | 219 | if (processAffinityMask & 1) { 220 | 221 | // printf ("processor %d is valid\n", processor); 222 | 223 | data[0]=eax; 224 | data[1]=edx; 225 | 226 | sprintf(msr_filename, "/dev/cpu/%u/msr",processor); 227 | 228 | fd = open(msr_filename, O_WRONLY); 229 | 230 | if ( fd < 0 ) 231 | { 232 | if ( errno == ENXIO ) 233 | { 234 | fprintf(stderr, "WrmsrPx: Invalid %u processor\n",processor); 235 | return false; 236 | } 237 | else if (errno == EIO ) 238 | { 239 | fprintf(stderr, "WrmsrPx: CPU %u doesn't support MSR\n",processor); 240 | return false; 241 | } 242 | else 243 | { 244 | fprintf(stderr, "WrmsrPx: open"); 245 | return false; 246 | } 247 | } 248 | 249 | if ( pwrite(fd, &data, sizeof data, index) != sizeof data) 250 | { 251 | if (errno == EIO) 252 | fprintf(stderr, "wrmsr: CPU %d cannot set MSR %X to %X %X\n", processor, index, data[0], data[1]); 253 | else 254 | fprintf(stderr, "WrmsrPx pread Errno %x\n",errno); 255 | close(fd); 256 | return false; 257 | } 258 | 259 | close(fd); 260 | 261 | } 262 | processor++; 263 | processAffinityMask >>= 1; 264 | } 265 | 266 | return true; 267 | } 268 | 269 | BOOL Wrmsr(DWORD index, DWORD eax, DWORD edx) 270 | { 271 | return WrmsrPx(index, eax, edx, 0x1); 272 | } 273 | 274 | void Sleep (DWORD ms) { 275 | usleep (ms*1000); 276 | return; 277 | } 278 | 279 | int GetTickCount () 280 | { 281 | #ifndef CLOCK_MONOTONIC_HR 282 | #define CLOCK_MONOTONIC_HR CLOCK_MONOTONIC 283 | #endif 284 | struct timespec tp; 285 | 286 | if (clock_gettime(CLOCK_MONOTONIC_HR, &tp)) 287 | return -1; 288 | 289 | tp.tv_sec *= 1000; 290 | tp.tv_nsec /= 1000000; 291 | tp.tv_sec += tp.tv_nsec; 292 | return tp.tv_sec; 293 | } 294 | -------------------------------------------------------------------------------- /MSRObject.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * MSRObject.cpp 3 | * 4 | * Created on: 28/mar/2011 5 | * Author: paolo 6 | */ 7 | 8 | #include "MSRObject.h" 9 | 10 | //Constructor: inizializes the object 11 | MSRObject::MSRObject() 12 | { 13 | this->eax_ptr=NULL; 14 | this->edx_ptr=NULL; 15 | this->absIndex=NULL; 16 | this->cpuMask=0x0; 17 | this->reg=0x0; 18 | this->cpuCount=0x0; 19 | } 20 | 21 | /* 22 | * readMSR: reads the MSR defined in reg parameter with the mask described in cpuMask 23 | * cpuMask is defined as a bitmask where bit 0 is cpu 0, bit 1 is cpu 1 and so on 24 | */ 25 | bool MSRObject::readMSR (DWORD reg, PROCESSORMASK cpuMask) 26 | { 27 | unsigned int count=0; 28 | unsigned int pId=0; 29 | PROCESSORMASK mask; 30 | 31 | this->reg = reg; 32 | this->cpuMask = cpuMask; 33 | 34 | //count as many processors are accounted in cpuMask 35 | for (pId = 0; pId < MAX_CORES; pId++) 36 | { 37 | mask=(PROCESSORMASK)1<cpuCount=count; 42 | 43 | if (this->eax_ptr) free (this->eax_ptr); 44 | if (this->edx_ptr) free (this->edx_ptr); 45 | if (this->absIndex) free (this->absIndex); 46 | 47 | this->eax_ptr=(DWORD *)calloc (this->cpuCount, sizeof(DWORD)); 48 | this->edx_ptr=(DWORD *)calloc (this->cpuCount, sizeof(DWORD)); 49 | this->absIndex=(unsigned int *)calloc (this->cpuCount, sizeof(unsigned int)); 50 | 51 | count=0; 52 | pId=0; 53 | 54 | while (pId < MAX_CORES) 55 | { 56 | mask = (PROCESSORMASK) 1 << pId; 57 | 58 | if (cpuMask & mask) 59 | { 60 | if (!RdmsrPx (this->reg, &eax_ptr[count], &edx_ptr[count], mask)) 61 | { 62 | /* This is not needed, memory will be freed by destructor 63 | free(this->eax_ptr); 64 | free(this->edx_ptr); 65 | free(this->absIndex);*/ 66 | this->cpuCount=0; 67 | return false; 68 | } 69 | this->absIndex[count]=pId; 70 | count++; 71 | } 72 | pId++; 73 | } 74 | return true; 75 | } 76 | 77 | /* 78 | * writeMSR writes the msr to the processor. Requires no parameters, since the register is 79 | * defined when readMSR is called and the mask is the same 80 | * 81 | */ 82 | bool MSRObject::writeMSR () 83 | { 84 | PROCESSORMASK mask; 85 | PROCESSORMASK cCpuMask; 86 | DWORD pId; 87 | unsigned int count; 88 | 89 | if (this->cpuCount==0) 90 | return true; 91 | 92 | cCpuMask=this->cpuMask; 93 | pId=0; 94 | count=0; 95 | 96 | while (pIdreg, this->eax_ptr[count], this->edx_ptr[count], mask)) return false; 103 | cCpuMask^=mask; //Inverts the bit of current cpu in the mask. 104 | if (cCpuMask==0) return true; //No more cpu's in the mask, stops the loop 105 | count++; 106 | } 107 | 108 | pId++; 109 | } 110 | 111 | return true; 112 | } 113 | 114 | /* 115 | * Uses the absIndex private array to return the absolute CPU/core associated to an index. 116 | * getbits method uses indexes, indexToAbsolute method is useful to discover the absolute 117 | * cpu/core. 118 | */ 119 | unsigned int MSRObject::indexToAbsolute (unsigned int index) { 120 | 121 | return this->absIndex[index]; 122 | 123 | } 124 | 125 | /* 126 | * Returns the count of the cpus currently taken in memory by this object 127 | */ 128 | DWORD MSRObject::getCount () { 129 | return this->cpuCount; 130 | } 131 | 132 | /* 133 | * getBits return a 64-bit integer containing the part of the MSR with offset defined in base parameter 134 | * and with length bits. cpuNumber parameter defines the specific cpu. cpuNumber=0 means that you are going 135 | * to read bits from first cpu in cpuMask, cpuNumber=1 means reading from second cpu in cpuMask and so on. 136 | */ 137 | uint64_t MSRObject::getBits (unsigned int cpuNumber, unsigned int base, unsigned int length) { 138 | 139 | uint64_t xReg; 140 | 141 | if (this->cpuCount==0) return 0; 142 | if (cpuNumber>=this->cpuCount) return 0; 143 | 144 | xReg=this->eax_ptr[cpuNumber]+((uint64_t)this->edx_ptr[cpuNumber]<<32); 145 | 146 | xReg=xReg<<(64-base-length); 147 | xReg=xReg>>(64-length); 148 | 149 | return xReg; 150 | 151 | } 152 | 153 | /* 154 | * getBitsLow is as getBits, but just on the lower part (eax) of the MSR register. 155 | * It is preferable to use this on 32 bit systems since it is faster in such environment 156 | * 157 | */ 158 | DWORD MSRObject::getBitsLow (unsigned int cpuNumber, unsigned int base, unsigned int length) { 159 | 160 | DWORD xReg; 161 | 162 | if (this->cpuCount==0) return 0; 163 | if (cpuNumber>=this->cpuCount) return 0; 164 | 165 | xReg=this->eax_ptr[cpuNumber]; 166 | 167 | xReg=xReg<<(32-base-length); 168 | xReg=xReg>>(32-length); 169 | 170 | return xReg; 171 | } 172 | 173 | /* 174 | * getBitsLow is as getBits, but just on the lower part (eax) of the MSR register. 175 | * It is preferable to use this on 32 bit systems since it is faster in such environment 176 | * 177 | */ 178 | DWORD MSRObject::getBitsHigh (unsigned int cpuNumber, unsigned int base, unsigned int length) 179 | { 180 | 181 | DWORD xReg; 182 | 183 | if (this->cpuCount==0) return 0; 184 | if (cpuNumber>=this->cpuCount) return 0; 185 | 186 | xReg=this->edx_ptr[cpuNumber]; 187 | 188 | xReg=xReg<<(32-base-length); 189 | xReg=xReg>>(32-length); 190 | 191 | return xReg; 192 | } 193 | 194 | 195 | /* 196 | * setBits set the bits for all cpu in cpuMask. As usual, base parameter is the offset from least 197 | * significant bit and length parameter is the length of the supposed part of register you are 198 | * going to write. value parameter is a 64 bit integer that is the value to be set in the MSR. 199 | * Note that value parameter is automatically cut to length bits to prevent overlapping in case 200 | * of overflow to adiacent registers. 201 | */ 202 | bool MSRObject::setBits (unsigned int base, unsigned int length, uint64_t value) { 203 | 204 | uint64_t xReg; 205 | uint64_t mask; 206 | DWORD count; 207 | 208 | if (this->cpuCount==0) return false; 209 | 210 | //Does some bitshifting to create a bitmask to isolate 211 | //the part of the register that is afftected by the change 212 | mask = -1; 213 | mask >>= (64 - length); 214 | mask <<= base; 215 | 216 | 217 | //Bitshifts the value parameter to the right position 218 | //and then cut it to prevent overlapping on other bits 219 | value=value<cpuCount;count++) { 229 | 230 | xReg=this->eax_ptr[count]+((uint64_t)this->edx_ptr[count]<<32); 231 | 232 | xReg=(xReg & mask) | value; 233 | 234 | this->edx_ptr[count]=(DWORD)(xReg>>32); 235 | this->eax_ptr[count]=(DWORD)*(&xReg); 236 | 237 | } 238 | 239 | return true; 240 | 241 | } 242 | 243 | /* 244 | * setBitsLow is as setBits, but does the job only on lower part (eax) of the MSR register. 245 | * It uses less resources than setBits and is preferable for use in 32 bit systems. 246 | * 247 | */ 248 | bool MSRObject::setBitsLow (unsigned int base, unsigned int length, DWORD value) { 249 | 250 | DWORD mask; 251 | DWORD count; 252 | 253 | if (this->cpuCount==0) return false; 254 | 255 | mask = -1; 256 | mask >>= (32 - length); 257 | mask <<= base; 258 | 259 | value=value<cpuCount;count++) 265 | this->eax_ptr[count]=(this->eax_ptr[count] & mask) | value; 266 | 267 | return true; 268 | 269 | } 270 | 271 | /* 272 | * setBitsHigh is as setBits, but does the job only on higher part (edx) of the MSR register. 273 | * It uses less resources than setBits and is preferable for use in 32 bit systems. 274 | * 275 | */ 276 | bool MSRObject::setBitsHigh (unsigned int base, unsigned int length, DWORD value) { 277 | 278 | DWORD mask; 279 | DWORD count; 280 | 281 | if (this->cpuCount==0) return false; 282 | 283 | mask = -1; 284 | mask >>= (32 - length); 285 | mask <<= base; 286 | 287 | value=value<cpuCount;count++) 293 | this->edx_ptr[count]=(this->eax_ptr[count] & mask) | value; 294 | 295 | return true; 296 | 297 | } 298 | 299 | //Releases dynamic memory and destroys the object 300 | MSRObject::~MSRObject() { 301 | if (this->eax_ptr) free (this->eax_ptr); 302 | if (this->edx_ptr) free (this->edx_ptr); 303 | if (this->absIndex) free (this->absIndex); 304 | } 305 | -------------------------------------------------------------------------------- /config.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include "config.h" 4 | #include "scaler.h" 5 | 6 | 7 | //Takes care of a configuration file 8 | 9 | CfgManager::CfgManager (class Processor *prc, class Scaler *sclr) { 10 | 11 | cfgFile=NULL; 12 | processor=prc; 13 | scaler=sclr; 14 | } 15 | 16 | //Open the file. Returns false if file is opened correctly, else returns true 17 | bool CfgManager::openCfgFile (char *txtFile) { 18 | 19 | cfgFile=fopen (txtFile,"r"); 20 | 21 | printf ("Configuration file: %s\n",txtFile); 22 | 23 | if (cfgFile==NULL) { 24 | cfgFile=NULL; 25 | return true; 26 | } 27 | 28 | return false; 29 | 30 | } 31 | 32 | //Reads and parses a PState section in the configuration file. 33 | //Only some commands are available for a pstate section, for example 34 | //vid, fid and did commands... topLine is the row containing PState 35 | //and core identifiers. 36 | int CfgManager::consumePStateSection () { 37 | 38 | unsigned int pstateId=-1; 39 | unsigned int coreId=-1; 40 | unsigned int nodeId=-1; 41 | char line[256]; 42 | 43 | //-1 means "do not touch". 44 | int vid=-1, enable=-1, frequency=-1, nbvid=-1; 45 | float voltage=-1,nbvoltage=-1, fid=-1, did=-1; 46 | 47 | char *token; 48 | 49 | fgets (line,256,cfgFile); 50 | 51 | token=strtok (line," "); 52 | 53 | while (token!=NULL) { 54 | 55 | if (strcmp(token,"pstate")==0) { 56 | //found pstate identifier. Throws an error if there are multiple pstate identifiers in a single statement 57 | token=strtok (NULL," "); 58 | if (pstateId!=-1) return true; 59 | sscanf (token,"%u",&pstateId); 60 | } else if (strcmp(token,"core")==0) { 61 | //found core identifier. Throws and error if there are multiple core identifiers in a single statement 62 | token=strtok (NULL," "); 63 | if (coreId!=-1) return true; 64 | sscanf (token,"%u",&coreId); 65 | } else if (strcmp(token,"node")==0) { 66 | //found node identifier. Throws and error if there are multiple nodes identifiers in a single statement 67 | token=strtok (NULL," "); 68 | if (nodeId!=-1) return true; 69 | sscanf (token,"%d",&nodeId); 70 | } else { 71 | //Found an unknown identifier, throws error. 72 | return true; 73 | } 74 | 75 | token=strtok (NULL," "); 76 | 77 | } 78 | 79 | //Let's scan for internal identifiers, like vid, fid, did, etc... 80 | 81 | while (true) { 82 | 83 | if (fscanf (cfgFile, "%s", line)==-1) break; 84 | 85 | if (strcmp (line,"#")==0) { 86 | //This is a comment, then read the whole line and go ahead 87 | fgets (line,256,cfgFile); 88 | } else if (strcmp (line,"vid")==0) { 89 | fscanf (cfgFile, "%d", &vid); 90 | } else if (strcmp (line,"fid")==0) { 91 | fscanf (cfgFile, "%f", &fid); 92 | } else if (strcmp (line,"did")==0) { 93 | fscanf (cfgFile, "%f", &did); 94 | } else if (strcmp (line,"enable")==0) { 95 | enable=1; 96 | } else if (strcmp (line,"disable")==0) { 97 | enable=0; 98 | } else if (strcmp (line,"frequency")==0) { 99 | fscanf (cfgFile, "%d", &frequency); 100 | } else if (strcmp (line,"voltage")==0) { 101 | fscanf (cfgFile, "%f", &voltage); 102 | } else if (strcmp (line,"nbvoltage")==0) { 103 | fscanf (cfgFile, "%f", &nbvoltage); 104 | } else if (strcmp (line,"nbvid")==0) { 105 | fscanf (cfgFile, "%d", &nbvid); 106 | } else if (strcmp (line,":")==0) { 107 | //Found new statement, let's reposition the reading pointer and return 108 | fseek (cfgFile, -1, SEEK_CUR); 109 | break; 110 | } else { 111 | printf ("Unknown identifier: %s\n", line); 112 | return true; 113 | } 114 | 115 | } 116 | 117 | if (pstateId==-1) return true; 118 | 119 | PState pstate (pstateId); 120 | 121 | //Select nodes to operate on 122 | if (nodeId==-1) 123 | processor->setNode(processor->ALL_NODES); 124 | else 125 | processor->setNode(nodeId); 126 | 127 | //Select cores to operate on 128 | if (coreId==-1) 129 | processor->setCore(processor->ALL_CORES); 130 | else 131 | processor->setCore(coreId); 132 | 133 | //Applies FID and DID commands, but only if frequency command is not present, else applies frequency command 134 | if (frequency==-1) { 135 | if (did!=-1) processor->setDID (pstate, did); 136 | if (fid!=-1) processor->setFID (pstate, fid); 137 | } else { 138 | processor->setFrequency (pstate, frequency); 139 | } 140 | 141 | //Applies VID commands, but only if voltage command is not present, else applies voltage command 142 | if (voltage==-1) { 143 | if (vid!=-1) processor->setVID (pstate, vid); 144 | } else { 145 | processor->setVCore (pstate, voltage); 146 | } 147 | 148 | //Enables or disables a pstate 149 | if (enable==0) processor->pStateDisable (pstate); 150 | if (enable==1) processor->pStateEnable (pstate); 151 | 152 | //Applies nbvoltage and nbvid commands 153 | if (nbvoltage!=-1) processor->setNBVid (pstate, processor->convertVcoretoVID(nbvoltage)); 154 | if (nbvid!=-1) processor->setNBVid (pstate, nbvid); 155 | 156 | return false; 157 | 158 | } 159 | 160 | int CfgManager::consumeGeneralSection () { 161 | 162 | PState ps(0); 163 | char line [256]; 164 | 165 | int temp; 166 | float ftemp; 167 | 168 | //Let's scan for internal identifiers, like psmax, etc... 169 | 170 | processor->setCore(processor->ALL_CORES); 171 | processor->setNode(processor->ALL_NODES); 172 | 173 | while (true) { 174 | 175 | if (fscanf (cfgFile, "%s", line)==-1) break; 176 | 177 | //This are generic items for comments or ending sections, don't change them 178 | 179 | if (strcmp (line,"#")==0) { 180 | //This is a comment, then read the whole line and go ahead 181 | fgets (line,256,cfgFile); 182 | } else if (strcmp (line,":")==0) { 183 | //Found new statement, let's reposition the reading pointer and return 184 | fseek (cfgFile, -1, SEEK_CUR); 185 | break; 186 | 187 | // ********** These items controls general power management behaviour 188 | 189 | } else if (strcmp (line,"set node")==0) { 190 | fscanf (cfgFile, "%u", &temp); 191 | processor->setNode(temp); 192 | } else if (strcmp (line,"psmax")==0) { 193 | fscanf (cfgFile, "%d", &temp); 194 | ps.setPState (temp); 195 | processor->setMaximumPState (ps); 196 | } else if (strcmp (line,"nbvid")==0) { 197 | fscanf (cfgFile, "%d", &temp); 198 | processor->setNBVid (temp); 199 | } else if (strcmp (line,"altvid")==0) { 200 | fscanf (cfgFile, "%d", &temp); 201 | processor->setAltVid (temp); 202 | } else if (strcmp (line,"slamtime")==0) { 203 | fscanf (cfgFile, "%d", &temp); 204 | processor->setSlamTime (temp); 205 | } else if (strcmp (line,"altvidslamtime")==0) { 206 | fscanf (cfgFile, "%d", &temp); 207 | processor->setAltVidSlamTime (temp); 208 | } else if (strcmp (line,"psienable")==0) { 209 | processor->setPsiEnabled (true); 210 | } else if (strcmp (line,"psidisable")==0) { 211 | processor->setPsiEnabled (false); 212 | } else if (strcmp (line,"psithreshold")==0) { 213 | fscanf (cfgFile, "%d", &temp); 214 | processor->setPsiThreshold (temp); 215 | } else if (strcmp (line,"C1Eenable")==0) { 216 | fscanf (cfgFile,"%d", &temp); 217 | processor->setCore(temp); 218 | processor->setC1EStatus (true); 219 | } else if (strcmp (line,"C1Edisable")==0) { 220 | fscanf (cfgFile,"%d", &temp); 221 | processor->setCore(temp); 222 | processor->setC1EStatus (false); 223 | } else if (strcmp (line,"nbvoltage")==0) { 224 | fscanf (cfgFile,"%f", &ftemp); 225 | processor->setNBVid (processor->convertVcoretoVID(ftemp)); 226 | } 227 | 228 | 229 | // ************** Bad unknown items 230 | else { 231 | printf ("Unknown identifier: %s\n", line); 232 | return true; 233 | } 234 | 235 | } 236 | 237 | return false; 238 | 239 | } 240 | 241 | int CfgManager::consumeScalerSection () { 242 | 243 | char line [256]; 244 | char strTemp[256]; 245 | 246 | int temp; 247 | 248 | //Let's scan for internal identifiers, like uppolicy, downpolicy, samplingrate 249 | 250 | while (true) { 251 | 252 | if (fscanf (cfgFile, "%s", line)==-1) break; 253 | 254 | //These are generic items for comments or ending sections, don't change them 255 | 256 | if (strcmp (line,"#")==0) { 257 | //This is a comment, then read the whole line and go ahead 258 | fgets (line,256,cfgFile); 259 | } else if (strcmp (line,":")==0) { 260 | //Found new statement, let's reposition the reading pointer and return 261 | fseek (cfgFile, -1, SEEK_CUR); 262 | break; 263 | 264 | // ********** These items controls general power management behaviour 265 | 266 | } else if (strcmp (line,"samplingrate")==0) { 267 | fscanf (cfgFile, "%d", &temp); 268 | scaler->setSamplingFrequency (temp); 269 | } else if (strcmp (line,"policy")==0) { 270 | fscanf (cfgFile, "%s", strTemp); 271 | if (strcmp(strTemp,"rocket")==0) 272 | scaler->setPolicy (POLICY_ROCKET); 273 | else if (strcmp(strTemp,"step")==0) 274 | scaler->setPolicy (POLICY_STEP); 275 | else return true; 276 | 277 | } else if (strcmp (line,"upperthreshold")==0) { 278 | fscanf (cfgFile, "%d", &temp); 279 | if ((temp<0) || (temp>100)) return true; 280 | scaler->setUpperThreshold (temp); 281 | } else if (strcmp (line,"lowerthreshold")==0) { 282 | fscanf (cfgFile, "%d", &temp); 283 | if ((temp<0) || (temp>100)) return true; 284 | scaler->setLowerThreshold (temp); 285 | } 286 | 287 | 288 | // ************** Bad unknown items 289 | else { 290 | printf ("Unknown identifier: %s\n", line); 291 | return true; 292 | } 293 | 294 | } 295 | 296 | return false; 297 | 298 | } 299 | 300 | 301 | //Parse configuration file. Returns 0 (false) if parsed correctly, else returns 302 | //the row of the error in the cfg file. 303 | int CfgManager::parseCfgFile () { 304 | 305 | printf ("Parsing configuration...\n"); 306 | 307 | char line[256]; 308 | 309 | if (cfgFile==NULL) return 0; 310 | 311 | while (!feof (cfgFile)) { 312 | 313 | //reads a string, returns -1 if there are no more string (so file is finished) 314 | if (fscanf (cfgFile,"%s",line)==-1) break; 315 | 316 | //Ignores all the comments beginning with # character 317 | if (strcmp (line,"#")==0) { 318 | fgets (line,256,cfgFile); 319 | } else if (strcmp (line,":")==0) { 320 | 321 | //The colon (:) determines a statement, next there's an uppercase word that 322 | //indicates the statement referring to. 323 | 324 | //Actually there are two statements, PSTATESET to allow configuring a pstate 325 | //configuration and GENERAL to allow configuring general settings 326 | 327 | fscanf (cfgFile,"%s",line); 328 | 329 | if (strcmp (line,"PSTATESET")==0) { 330 | if (consumePStateSection ()) return ftell (cfgFile); 331 | } else if (strcmp (line,"GENERAL")==0) { 332 | if (consumeGeneralSection ()) return ftell (cfgFile); 333 | } else if (strcmp (line,"SCALER")==0) { 334 | if (consumeScalerSection ()) return ftell (cfgFile); 335 | } else { 336 | return ftell (cfgFile); 337 | } 338 | 339 | } else { 340 | //Else there is other garbage we don't care about 341 | fgets (line,256,cfgFile); 342 | printf ("Invalid data: %s\n", line); 343 | } 344 | 345 | } 346 | 347 | printf ("Configuration file has been parsed!\n"); 348 | 349 | return 0; 350 | 351 | } 352 | 353 | bool CfgManager::closeCfgFile () { 354 | 355 | if (cfgFile==NULL) return false; 356 | 357 | fclose (cfgFile); 358 | 359 | return false; 360 | } 361 | 362 | CfgManager::~CfgManager () { 363 | 364 | closeCfgFile (); 365 | 366 | } 367 | -------------------------------------------------------------------------------- /Processor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define MAX_CORES (sizeof(unsigned int *)<<3) //MAX_CORES depends on system architecture 4 | #define MAX_NODES (sizeof(DWORD)<<3) //MAX_NODES is fixed to 32 5 | #define PROCESSORMASK DWORD_PTR 6 | 7 | #ifdef _WIN32 8 | 9 | #ifndef uint64_t 10 | #define uint64_t long long unsigned int 11 | #endif 12 | 13 | #include 14 | #include "OlsApi.h" 15 | #include "OlsDef.h" 16 | #include "MSVC_Round.h" 17 | #include 18 | #endif 19 | 20 | #ifdef __linux 21 | #include "cpuPrimitives.h" 22 | #endif 23 | 24 | #include 25 | #include 26 | 27 | //MSRs defines 28 | //Base (pstate 0) MSR register for Family 10h processors: 29 | #define BASE_K10_PSTATEMSR 0xC0010064 30 | 31 | //Base (pstate 0) MSR register for Family 11h processors: 32 | #define BASE_ZM_PSTATEMSR 0xC0010064 33 | 34 | //Base (pstate 0) MSR register for Family 12h processors: 35 | #define BASE_12H_PSTATEMSR 0xC0010064 36 | 37 | //Base (pstate 0) MSR register for Family 14h processors: 38 | #define BASE_14H_PSTATEMSR 0xC0010064 39 | 40 | //Base (pstate 0) MSR register for Family 15h processors: 41 | #define BASE_15H_PSTATEMSR 0xC0010064 42 | 43 | 44 | //Shared (both Family 10h and Family 11h use the same registers) 45 | //regarding PSTATE Control, COFVID Status and CMPHALT registers. 46 | #define BASE_PSTATE_CTRL_REG 0xC0010062 47 | #define COFVID_STATUS_REG 0xC0010071 48 | #define CMPHALT_REG 0xc0010055 49 | 50 | //Shared (both Family 10h and Family 11h use the same registers) 51 | //regarding Performance Registers and Time stamp counter 52 | #define BASE_PESR_REG 0xc0010000 53 | #define BASE_PERC_REG 0xc0010004 54 | #define TIME_STAMP_COUNTER_REG 0x00000010 55 | 56 | //Family 15h Performance Registers 57 | #define BASE_PESR_REG_15 0xC0010200 58 | #define BASE_PERC_REG_15 0xC0010201 59 | #define APML_TDP_LIMIT_REG_15 0xC0010075 60 | 61 | //Performance Event constants (used for IDLE counting for CPU Usage 62 | //counter) 63 | #define IDLE_COUNTER_EAX 0x430076 64 | #define IDLE_COUNTER_EDX 0x0 65 | 66 | //PCI Registers defines for northbridge 67 | #define PCI_FUNC_LINK_CONTROL 0x4 68 | #define PCI_FUNC_MISC_CONTROL_3 0x3 69 | #define PCI_FUNC_MISC_CONTROL_5 0x5 70 | #define PCI_FUNC_DRAM_CONTROLLER 0x2 71 | #define PCI_FUNC_ADDRESS_MAP 0x1 72 | #define PCI_FUNC_HT_CONFIG 0x0 73 | #define PCI_DEV_NORTHBRIDGE 0x18 74 | 75 | //Processor Identifier defines 76 | #define ERROR_CLASS_PROCESSOR 0 77 | #define UNKNOWN_PROCESSOR 1 78 | #define TURION_ULTRA_ZM_FAMILY 2 79 | #define TURION_X2_RM_FAMILY 3 80 | #define ATHLON_X2_QL_FAMILY 4 81 | #define SEMPRON_SI_FAMILY 5 82 | 83 | #define PROCESSOR_10H_FAMILY 6 84 | 85 | #define PROCESSOR_12H_FAMILY 8 86 | 87 | #define PROCESSOR_14H_FAMILY 7 88 | 89 | #define PROCESSOR_15H_FAMILY 9 90 | 91 | //Scaler helper structures: 92 | struct procStatus { 93 | DWORD pstate;DWORD vid;DWORD fid;DWORD did; 94 | }; 95 | 96 | 97 | 98 | class PState { 99 | DWORD pstate; 100 | public: 101 | PState(DWORD);DWORD getPState(); 102 | void setPState(DWORD); 103 | }; 104 | 105 | class Processor { 106 | protected: 107 | 108 | //Nested class that defines the behaviour of K10-style performance counters 109 | 110 | friend class K10PerfomanceCounters; 111 | class K10PerformanceCounters { 112 | 113 | public: 114 | static void perfMonitorCPUUsage (class Processor *p); 115 | static void perfMonitorFPUUsage (class Processor *p); 116 | static void perfMonitorDCMA (class Processor *p); //Data Cache Misaligned Accesses 117 | static void perfCounterGetInfo (class Processor *p); 118 | }; 119 | 120 | 121 | /* 122 | * Attributes 123 | */ 124 | 125 | DWORD powerStates;DWORD processorCores; 126 | char processorStrId[64];DWORD processorIdentifier;DWORD processorNodes; // count of physical processor nodes (eg: 8 on a quad 6100 opteron box). 127 | 128 | //Processor Specs 129 | int familyBase; 130 | int familyExtended; 131 | int model; 132 | 133 | int stepping; 134 | int modelExtended; 135 | int brandId; 136 | int processorModel; 137 | int string1; 138 | int string2; 139 | int pkgType; 140 | int numBoostStates; 141 | int TDP; 142 | int maxslots; 143 | 144 | DWORD selectedCore; 145 | DWORD selectedNode; 146 | 147 | /* 148 | * Methods 149 | */ 150 | 151 | void setProcessorStrId(const char *); 152 | void setPowerStates(DWORD); 153 | void setProcessorCores (DWORD); 154 | void setProcessorIdentifier(DWORD); 155 | void setProcessorNodes(DWORD); 156 | 157 | DWORD getNodeMask (DWORD); 158 | DWORD getNodeMask (); 159 | bool isValidNode (DWORD); 160 | bool isValidCore (DWORD); 161 | 162 | //Set method for processor specifications 163 | void setSpecFamilyBase(int); 164 | void setSpecModel(int); 165 | void setSpecStepping(int); 166 | void setSpecFamilyExtended(int); 167 | void setSpecModelExtended(int); 168 | void setSpecBrandId(int); 169 | void setSpecProcessorModel(int); 170 | void setSpecString1(int); 171 | void setSpecString2(int); 172 | void setSpecPkgType(int); 173 | void setBoostStates(int); 174 | void setTDP(int); 175 | void setMaxSlots(int); 176 | 177 | virtual void setPCtoIdleCounter(int, int) { 178 | return; 179 | } 180 | 181 | public: 182 | const static DWORD ALL_NODES=-1; 183 | const static DWORD ALL_CORES=-1; 184 | 185 | PROCESSORMASK getMask (DWORD, DWORD); 186 | PROCESSORMASK getMask (); 187 | 188 | 189 | //Sets the current node to operate on 190 | void setNode (DWORD); 191 | //Returns the current node that is operating on 192 | DWORD getNode (); 193 | 194 | //Sets the current core to operate on 195 | void setCore (DWORD); 196 | //Returns the current core that is operating on 197 | DWORD getCore (); 198 | 199 | //This method is used to know if a module supports the currently installed 200 | //processor. Main can ask each module if it detects a supported processor 201 | //in turn and then, if it get a positive answer, it can retrieve processor 202 | //family and details 203 | static bool isProcessorSupported(); 204 | 205 | //Public method to show on the console some processor family specific information. This is 206 | //per-family setting because different processor families have some different 207 | //specifications. 208 | virtual void showFamilySpecs(void); 209 | 210 | //Public method to show on the console some DRAM Timings 211 | virtual void showDramTimings(void); 212 | 213 | //Public method to show some detailed information about Hypertransport Link 214 | virtual void showHTLink (void); 215 | 216 | //Public method to show some detailed information about Hardware Thermal Control 217 | virtual void showHTC (void); 218 | 219 | //Get methods to obtain general processor specifications 220 | int getSpecFamilyBase(); 221 | int getSpecModel(); 222 | int getSpecStepping(); 223 | int getSpecFamilyExtended(); 224 | int getSpecModelExtended(); 225 | int getSpecBrandId(); 226 | int getSpecProcessorModel(); 227 | int getSpecString1(); 228 | int getSpecString2(); 229 | int getSpecPkgType(); 230 | int getBoostStates(); 231 | int getMaxSlots(); 232 | 233 | virtual float convertVIDtoVcore(DWORD); 234 | virtual DWORD convertVcoretoVID(float); 235 | virtual DWORD convertFDtoFreq(DWORD, DWORD); 236 | virtual void convertFreqtoFD(DWORD, int *, int *); 237 | 238 | DWORD HTLinkToFreq(DWORD); 239 | 240 | DWORD getProcessorCores() { 241 | return processorCores; 242 | } 243 | DWORD getPowerStates() { 244 | return powerStates; 245 | } 246 | DWORD getProcessorIdentifier() { 247 | return processorIdentifier; 248 | } 249 | char *getProcessorStrId() { 250 | return processorStrId; 251 | } 252 | DWORD getProcessorNodes() { 253 | return processorNodes; 254 | } 255 | 256 | //Low level functions to set specific processor primitives 257 | virtual void setVID (PState , DWORD); 258 | virtual void setFID (PState , float); 259 | virtual void setDID (PState , float); 260 | 261 | virtual DWORD getVID(PState); 262 | virtual float getFID(PState); 263 | virtual float getDID(PState); 264 | 265 | //Higher level functions that do conversions into lower level primitives 266 | virtual void setFrequency(PState, DWORD); 267 | virtual void setVCore(PState, float); 268 | 269 | virtual DWORD getFrequency(PState); 270 | virtual float getVCore(PState); 271 | 272 | virtual void pStateEnable(PState); 273 | virtual void pStateDisable(PState); 274 | virtual bool pStateEnabled(PState); 275 | 276 | //Primitives to set maximum p-state 277 | virtual void setMaximumPState(PState); 278 | 279 | virtual PState getMaximumPState(); 280 | 281 | //Family 11h have a shared northbridge vid for all cores 282 | virtual DWORD getNBVid(); 283 | virtual void setNBVid(DWORD); 284 | 285 | //Family 10h require northbridge vid per each pstate 286 | virtual DWORD getNBVid(PState); 287 | virtual void setNBVid(PState, DWORD); 288 | 289 | //Northbridge DID and FID are available only on family 10h processors 290 | virtual DWORD getNBDid(PState); 291 | virtual void setNBDid(PState, DWORD); 292 | virtual DWORD getNBFid(); 293 | virtual void setNBFid(DWORD); 294 | 295 | virtual bool setNBFrequency(PState, DWORD); 296 | virtual DWORD getNBFrequency(PState); 297 | virtual bool setNBFrequency(DWORD); 298 | virtual DWORD getNBFrequency(); 299 | 300 | virtual DWORD getMaxNBFrequency(); 301 | 302 | //Family 11h should not implement this 303 | //Family 10h may report 0-PVI mode or 1-SVI mode 304 | virtual bool getPVIMode(); 305 | 306 | virtual void forcePState(PState); 307 | virtual bool getSMAF7Enabled(); 308 | virtual DWORD c1eDID(); 309 | virtual DWORD minVID(); 310 | virtual DWORD maxVID(); 311 | virtual DWORD startupPState(); 312 | virtual DWORD maxCPUFrequency(); // 0 means that there 313 | //is no maximum CPU frequency, i.e. unlocked multiplier 314 | virtual void setBoost(bool); 315 | virtual DWORD getBoost(void); 316 | virtual void setNumBoostStates(DWORD); 317 | virtual DWORD getTDP(void); 318 | 319 | //Temperature registers 320 | virtual DWORD getTctlRegister(void); 321 | 322 | virtual DWORD getTctlMaxDiff(void); 323 | 324 | //Voltage slamming time registers 325 | virtual DWORD getSlamTime(void); 326 | virtual void setSlamTime(DWORD); 327 | 328 | virtual DWORD getAltVidSlamTime(void); 329 | virtual void setAltVidSlamTime(DWORD); 330 | 331 | //Voltage ramping time registers - Taken from Phenom Datasheets, not official on turions 332 | virtual DWORD getStepUpRampTime(void); 333 | virtual DWORD getStepDownRampTime(void); 334 | 335 | virtual void setStepUpRampTime(DWORD); 336 | virtual void setStepDownRampTime(DWORD); 337 | 338 | //HTC Section 339 | virtual bool HTCisCapable(); 340 | virtual bool HTCisEnabled(); 341 | virtual bool HTCisActive(); 342 | virtual bool HTChasBeenActive(); 343 | virtual DWORD HTCTempLimit(); 344 | virtual bool HTCSlewControl(); 345 | virtual DWORD HTCHystTemp(); 346 | virtual DWORD HTCPStateLimit(); 347 | virtual bool HTCLocked(); 348 | virtual DWORD getAltVID(); 349 | 350 | //HTC Section - Change status 351 | 352 | virtual void HTCEnable(); 353 | virtual void HTCDisable(); 354 | virtual void HTCsetTempLimit(DWORD); 355 | virtual void HTCsetHystLimit(DWORD); 356 | virtual void setAltVid(DWORD); 357 | 358 | //PSI_L bit 359 | virtual bool getPsiEnabled(); 360 | virtual DWORD getPsiThreshold(); 361 | virtual void setPsiEnabled(bool); 362 | virtual void setPsiThreshold(DWORD); 363 | 364 | //Hypertransport Section 365 | 366 | virtual void setHTLinkSpeed(DWORD, DWORD); 367 | 368 | virtual void checkMode(); 369 | 370 | //Various settings 371 | 372 | virtual bool getC1EStatus(); 373 | virtual void setC1EStatus(bool toggle); 374 | 375 | //performance counters section 376 | 377 | virtual void perfCounterGetInfo(); 378 | virtual void perfCounterGetValue(unsigned int); 379 | virtual void perfMonitorCPUUsage(); 380 | virtual void perfMonitorFPUUsage(); 381 | virtual void perfMonitorDCMA(); //Data Cache Misaligned Accesses 382 | 383 | 384 | //Scaler helper methods 385 | virtual void getCurrentStatus (struct procStatus *, DWORD); 386 | 387 | 388 | }; 389 | 390 | -------------------------------------------------------------------------------- /scaler.cpp: -------------------------------------------------------------------------------- 1 | #include "scaler.h" 2 | 3 | //TODO: IMPORTANT ********* Scaler must be completely revised 4 | 5 | Scaler::Scaler(class Processor *prc) { 6 | 7 | processor = prc; 8 | 9 | processor->setNode(0); 10 | processor->setCore(0); 11 | 12 | samplingRate = DEFAULT_SAMPLING_RATE; 13 | 14 | policy = POLICY_STEP; 15 | 16 | upperThreshold = 70; 17 | lowerThreshold = 20; 18 | 19 | midUpperThreshold = (100 + upperThreshold) >> 1; 20 | midLowerThreshold = (100 - lowerThreshold) >> 1; 21 | 22 | PState ps(0); 23 | ps = processor->getMaximumPState(); 24 | 25 | slowestPowerState = ps.getPState(); 26 | 27 | } 28 | 29 | void Scaler::setSamplingFrequency(int msSmpFreq) { 30 | samplingRate = msSmpFreq; 31 | } 32 | 33 | void Scaler::setPolicy(int policy) { 34 | this->policy = policy; 35 | } 36 | 37 | void Scaler::setUpperThreshold(int thres) { 38 | 39 | if (thres > 100) 40 | upperThreshold = 100; 41 | else 42 | upperThreshold = thres; 43 | 44 | midUpperThreshold = (100 + upperThreshold) >> 1; 45 | } 46 | 47 | void Scaler::setLowerThreshold(int thres) { 48 | 49 | if (thres < 0) 50 | lowerThreshold = 0; 51 | else 52 | lowerThreshold = thres; 53 | 54 | midLowerThreshold = (100 - lowerThreshold) >> 1; 55 | } 56 | 57 | /* Scaling methods: 58 | 59 | STEP - Stepped scaling, means that when CPU usage goes over 70% for a core, 60 | the scaler brings the core at the immediate faster pstate. 61 | When processor usage goes below 20% for a core, the scaler brings the core 62 | at the immediate slower pstate. 63 | 64 | ROCKET - If CPU core usage goes above 70%, core is set to full frequency. If 65 | cpu core usage goes below 20%, core is immediately set to slower pstate. 66 | 67 | DYNAMIC - If CPU core usage is 100%, core is set to full frequency. If CPU 68 | core usage is above 85%, core is set a faster pstate to two step ahead. 69 | If CPU core usage is above 70%, core is set to the immediate next faster 70 | pstate. 71 | 72 | If cpu core usage is 0%, core is set to slowest frequency. If CPU core 73 | usage is below 10%, core is set to a slower pstate two step backward. 74 | If CPU usage is below 20%, core is set to one step backward. 75 | */ 76 | 77 | int Scaler::initializeCounters() { 78 | DWORD cpuIndex, nodeId, coreId; 79 | PROCESSORMASK cpuMask; 80 | unsigned int perfCounterSlot; 81 | 82 | try { 83 | 84 | this->processor->setNode(this->processor->ALL_NODES); 85 | this->processor->setCore(this->processor->ALL_CORES); 86 | 87 | cpuMask = this->processor->getMask(); 88 | /* We do this to do some "caching" of the mask, instead of calculating each time 89 | we need to retrieve the time stamp counter */ 90 | 91 | // Allocating space for previous values of counters. 92 | this->prevPerfCounters = (uint64_t *) calloc( 93 | this->processor->getProcessorCores() * this->processor->getProcessorNodes(), 94 | sizeof(uint64_t)); 95 | this->prevTSCCounters = (uint64_t *) calloc( 96 | this->processor->getProcessorCores() * this->processor->getProcessorNodes(), 97 | sizeof(uint64_t)); 98 | 99 | // MSR Object to retrieve the time stamp counter for all the nodes and all the processors 100 | this->tscCounter = new MSRObject(); 101 | 102 | //Creates a new performance counter, for now we set slot 0, but we will 103 | //use the findAvailable slot method to find an available method to be used 104 | this->perfCounter = new PerformanceCounter(cpuMask, 0, this->processor->getMaxSlots()); 105 | 106 | //Event 0x76 is Idle Counter 107 | perfCounter->setEventSelect(0x76); 108 | perfCounter->setCountOsMode(true); 109 | perfCounter->setCountUserMode(true); 110 | perfCounter->setCounterMask(0); 111 | perfCounter->setEdgeDetect(false); 112 | perfCounter->setEnableAPICInterrupt(false); 113 | perfCounter->setInvertCntMask(false); 114 | perfCounter->setUnitMask(0); 115 | 116 | //Finds an available slot for our purpose 117 | perfCounterSlot = this->perfCounter->findAvailableSlot(); 118 | 119 | //findAvailableSlot() returns -2 in case of error 120 | if (perfCounterSlot == 0xfffffffe) 121 | throw "unable to access performance counter slots"; 122 | 123 | //findAvailableSlot() returns -1 in case there aren't available slots 124 | if (perfCounterSlot == 0xffffffff) 125 | throw "unable to find an available performance counter slot"; 126 | 127 | printf("Performance counter will use slot #%d\n", perfCounterSlot); 128 | 129 | //In case there are no errors, we program the object with the slot itself has found 130 | this->perfCounter->setSlot(perfCounterSlot); 131 | 132 | // Program the counter slot 133 | if (!this->perfCounter->program()) 134 | throw "unable to program performance counter parameters"; 135 | 136 | // Enable the counter slot 137 | if (!this->perfCounter->enable()) 138 | throw "unable to enable performance counters"; 139 | 140 | /* Here we take a snapshot of the performance counter and a snapshot of the time 141 | * stamp counter to initialize the arrays to let them not show erratic huge numbers 142 | * on first step 143 | */ 144 | 145 | if (!this->perfCounter->takeSnapshot()) 146 | throw "unable to retrieve performance counter data"; 147 | 148 | if (!this->tscCounter->readMSR(TIME_STAMP_COUNTER_REG, cpuMask)) 149 | throw "unable to retrieve time stamp counter"; 150 | 151 | cpuIndex = 0; 152 | for (nodeId = 0; nodeId < this->processor->getProcessorNodes(); nodeId++) { 153 | for (coreId = 0x0; coreId < this->processor->getProcessorCores(); coreId++) { 154 | this->prevPerfCounters[cpuIndex] = this->perfCounter->getCounter(cpuIndex); 155 | this->prevTSCCounters[cpuIndex] 156 | = this->tscCounter->getBits(cpuIndex, 0, 64); 157 | cpuIndex++; 158 | } 159 | } 160 | 161 | this->perfCounter->disable(); 162 | 163 | } catch (char const *str) { 164 | 165 | if (this->perfCounter->getEnabled()) 166 | this->perfCounter->disable(); 167 | 168 | free(this->perfCounter); 169 | free(this->tscCounter); 170 | free(this->prevPerfCounters); 171 | free(this->prevTSCCounters); 172 | 173 | printf("Scaler.cpp::initializeCounters - %s\n", str); 174 | 175 | return -1; //In case of error, we return -1 176 | 177 | } 178 | 179 | return 0; //In case of success, we return 0 180 | 181 | } 182 | 183 | void Scaler::loopPolicyRocket() { 184 | 185 | unsigned char reqPState; 186 | unsigned int enabledPowerStates; 187 | DWORD units, cpuIndex, targetUnit, nodeIndex, coreIndex; 188 | uint64_t deltaUsage; 189 | unsigned int divisor; 190 | 191 | PState **ps; 192 | 193 | units=this->processor->getProcessorCores()*this->processor->getProcessorNodes(); 194 | 195 | ps=(PState **)calloc (units, sizeof (PState *)); 196 | 197 | for (cpuIndex=0;cpuIndexsamplingRate; 201 | 202 | enabledPowerStates=this->processor->getMaximumPState().getPState(); 203 | 204 | Signal::activateSignalHandler( SIGINT); 205 | 206 | while (!Signal::getSignalStatus()) { 207 | 208 | if (!this->perfCounter->takeSnapshot()) 209 | throw "unable to retrieve performance counter data"; 210 | 211 | cpuIndex=0; 212 | 213 | for (nodeIndex=0;nodeIndexprocessor->getProcessorNodes();nodeIndex++) { 214 | 215 | this->processor->setNode(nodeIndex); 216 | 217 | for (coreIndex=0;coreIndexprocessor->getProcessorCores();coreIndex++) { 218 | 219 | this->processor->setCore(coreIndex); 220 | 221 | reqPState=ps[cpuIndex]->getPState(); 222 | 223 | deltaUsage = ((this->perfCounter->getCounter(cpuIndex)) 224 | - this->prevPerfCounters[cpuIndex])/divisor; 225 | 226 | targetUnit=(reqPState*enabledPowerStates)+cpuIndex; 227 | 228 | /*printf ("CPU %d Usage: %d Current pstate: %d - Raise Freq: %d Reduce Freq: %d \n ", 229 | cpuIndex, deltaUsage, reqPState, raiseTable[targetUnit], reduceTable[targetUnit]);*/ 230 | 231 | if (deltaUsage>raiseTable[targetUnit]){ reqPState=0; } 232 | else if (deltaUsagesetPState(reqPState); 235 | 236 | this->processor->forcePState(ps[cpuIndex]->getPState()); 237 | 238 | this->prevPerfCounters[cpuIndex] = this->perfCounter->getCounter(cpuIndex); 239 | 240 | cpuIndex++; 241 | 242 | } 243 | 244 | } 245 | 246 | //printf("\n"); 247 | 248 | Sleep(this->samplingRate); 249 | 250 | } 251 | 252 | for (cpuIndex=0;cpuIndexprocessor->getProcessorCores()*this->processor->getProcessorNodes(); 269 | 270 | ps=(PState **)calloc (units, sizeof (PState *)); 271 | 272 | for (cpuIndex=0;cpuIndexsamplingRate; 276 | 277 | enabledPowerStates=this->processor->getMaximumPState().getPState(); 278 | 279 | Signal::activateSignalHandler( SIGINT); 280 | 281 | while (!Signal::getSignalStatus()) { 282 | 283 | if (!this->perfCounter->takeSnapshot()) 284 | throw "unable to retrieve performance counter data"; 285 | 286 | cpuIndex=0; 287 | 288 | for (nodeIndex=0;nodeIndexprocessor->getProcessorNodes();nodeIndex++) { 289 | 290 | this->processor->setNode(nodeIndex); 291 | 292 | for (coreIndex=0;coreIndexprocessor->getProcessorCores();coreIndex++) { 293 | 294 | this->processor->setCore(coreIndex); 295 | 296 | reqPState=ps[cpuIndex]->getPState(); 297 | 298 | deltaUsage = ((this->perfCounter->getCounter(cpuIndex)) 299 | - this->prevPerfCounters[cpuIndex])/divisor; 300 | 301 | targetUnit=(reqPState*enabledPowerStates)+cpuIndex; 302 | 303 | /*printf ("CPU %d Usage: %d Current pstate: %d - Raise Freq: %d Reduce Freq: %d \n ", 304 | cpuIndex, deltaUsage, reqPState, raiseTable[targetUnit], reduceTable[targetUnit]);*/ 305 | 306 | if (deltaUsage>raiseTable[targetUnit]){ if (reqPState!=0) reqPState--; } 307 | else if (deltaUsagesetPState(reqPState); 310 | 311 | this->processor->forcePState(ps[cpuIndex]->getPState()); 312 | 313 | this->prevPerfCounters[cpuIndex] = this->perfCounter->getCounter(cpuIndex); 314 | 315 | cpuIndex++; 316 | 317 | } 318 | 319 | } 320 | 321 | //printf("\n"); 322 | 323 | Sleep(this->samplingRate); 324 | 325 | } 326 | 327 | for (cpuIndex=0;cpuIndexprocessor->getProcessorCores()*this->processor->getProcessorNodes(); 346 | enabledPowerStates=this->processor->getMaximumPState().getPState(); 347 | 348 | raiseTable=(uint64_t *)calloc (units*(enabledPowerStates+1), sizeof(uint64_t)); 349 | reduceTable=(uint64_t *)calloc (units*(enabledPowerStates+1), sizeof(uint64_t)); 350 | 351 | for (i=0;i<=enabledPowerStates;i++) { 352 | 353 | printf ("Power State %d:" , i); 354 | 355 | ps.setPState(i); 356 | unitIndex=0; 357 | 358 | for (nodeIndex=0;nodeIndexprocessor->getProcessorNodes();nodeIndex++) { 359 | 360 | this->processor->setNode(nodeIndex); 361 | 362 | for (coreIndex=0;coreIndexprocessor->getProcessorCores();coreIndex++) { 363 | 364 | this->processor->setCore (coreIndex); 365 | 366 | targetUnit=(i*enabledPowerStates) + unitIndex; 367 | 368 | if (i==this->processor->getMaximumPState().getPState()) { 369 | reduceTable[targetUnit]=0; 370 | raiseTable[targetUnit]=this->processor->getFrequency(ps)*this->upperThreshold/100; 371 | } 372 | else 373 | { 374 | ps_back.setPState(i+1); 375 | diff_frequency=this->processor->getFrequency(ps)-this->processor->getFrequency(ps_back); 376 | 377 | raiseTable[targetUnit]=(diff_frequency*this->upperThreshold/100)+this->processor->getFrequency(ps_back); 378 | reduceTable[targetUnit]=(diff_frequency*this->lowerThreshold/100)+this->processor->getFrequency(ps_back); 379 | 380 | } 381 | 382 | //printf ("Ra:%ld Re:%ld ",raiseTable[targetUnit], reduceTable[targetUnit]); 383 | 384 | unitIndex++; 385 | 386 | } 387 | } 388 | 389 | printf ("\n"); 390 | 391 | } 392 | 393 | return; 394 | 395 | } 396 | 397 | void Scaler::beginScaling() { 398 | 399 | if (initializeCounters()) { 400 | perror( 401 | "Scaler::beginScaling - performance counters initialization failed\n"); 402 | return; 403 | } 404 | 405 | createPerformanceTables(); 406 | 407 | this->perfCounter->enable(); 408 | 409 | switch (this->policy) { 410 | case POLICY_STEP: 411 | loopPolicyStep(); //loop will be terminated with a CTRL-C command 412 | break; 413 | case POLICY_ROCKET: 414 | loopPolicyRocket(); 415 | break; 416 | } 417 | 418 | printf ("CTRL-C pressed. Terminating scaler and freeing resources... "); 419 | 420 | this->perfCounter->disable(); 421 | 422 | if (this->perfCounter->getEnabled()) 423 | this->perfCounter->disable(); 424 | 425 | free(this->perfCounter); 426 | free(this->tscCounter); 427 | free(this->prevPerfCounters); 428 | free(this->prevTSCCounters); 429 | 430 | free(this->raiseTable); 431 | free(this->reduceTable); 432 | 433 | printf ("done.\n"); 434 | 435 | } 436 | -------------------------------------------------------------------------------- /PerformanceCounter.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * PerformanceCounter.cpp 3 | * 4 | * This class allows a faster use of performance counter. 5 | * Instructions on how to use: 6 | * 7 | * 1 - Instantiate the object giving a cpuMask and a slot to count. Look that the slot 8 | * will be the same for all the cpus in cpuMask 9 | * 2 - Use setters to setup optional parameters of the performance register 10 | * 3 - Use program() method to program the performance counter. Program method will program the hardware registers 11 | * but will not enable the performance counters 12 | * 4 - Use the enable() method to enable the performance counters 13 | * 5 - Take a snapshot of the current performance counters condition with takeSnapshot() method. This is useful to avoid 14 | * time stretched data retrieving 15 | * 6 - Obtain freezed counters using getCounter() method for all the cpus you need. 16 | * 7 - Repeat from step 5 as long as you need the performance counter data 17 | * 8 - When finished, just issue the disable() method to disable the performance counters. It won't actually deallocate 18 | * but since they are disabled, they can be reused. 19 | * 20 | * If you wish to know the actual hardware condition, you can use the fetch () method that reads the hardware registers 21 | * and changes the protected parameters of this class. Then you can access the parameters via setters/getters. 22 | * 23 | * Created on: 25/mag/2011 24 | * Author: paolo 25 | */ 26 | 27 | #include "PerformanceCounter.h" 28 | 29 | PerformanceCounter::PerformanceCounter(PROCESSORMASK cpuMask, DWORD slot, DWORD maxslots) 30 | { 31 | if (slot > maxslots) 32 | this->slot = maxslots; 33 | else 34 | this->slot = slot; 35 | 36 | this->maxslots = maxslots; 37 | this->cpuMask = cpuMask; 38 | this->eventSelect = 0x00; //Default event 39 | this->countOsMode = true; 40 | this->countUserMode = true; 41 | this->counterMask = 0; 42 | this->edgeDetect = false; 43 | this->enableAPICInterrupt = false; 44 | this->invertCntMask = false; 45 | this->unitMask = 0; 46 | 47 | //Note that the number of slots determines the register to be used 48 | //Based on BKDG for 15h (pg 547), the legacy slots do exist, however if they are used 49 | // you are only receiving the performance info for the lower 4 of 6 slots 50 | //Therefore the max number of slots can be used to determine the appropriate register 51 | //If a newer CPU is misdetected/mishandled, the performance info will be correct, 52 | // However it will not give you all available info 53 | if (maxslots == 6) 54 | { 55 | this->pesrReg = BASE_PESR_REG_15; 56 | this->percReg = BASE_PERC_REG_15; 57 | this->offset = 2; 58 | } 59 | else 60 | { 61 | this->pesrReg = BASE_PESR_REG; 62 | this->percReg = BASE_PERC_REG; 63 | this->offset = 1; 64 | } 65 | 66 | snapshotRegister = new MSRObject(); 67 | } 68 | 69 | /* 70 | * MSR Register is different based on the Extended CPU Family 71 | * This method will return the register required to get/set the PESR bits 72 | * 73 | */ 74 | 75 | unsigned int PerformanceCounter::getPESRReg(unsigned char slot) 76 | { 77 | return (this->pesrReg + (this->offset * slot)); 78 | } 79 | 80 | unsigned int PerformanceCounter::getPERCReg(unsigned char slot) 81 | { 82 | return (this->percReg + (this->offset * slot)); 83 | } 84 | 85 | /* 86 | * program method will program the MS registers according to settings required by the user. This 87 | * method will not enable the performance counter, will just write the parameters. 88 | * 89 | * Returns true if successful, false if not successful. 90 | * 91 | */ 92 | 93 | bool PerformanceCounter::program() 94 | { 95 | MSRObject *pCounterMSRObject = new MSRObject(); 96 | 97 | //Loads the current status of the MS registers for all the cpus in the mask 98 | if (!pCounterMSRObject->readMSR(getPESRReg(this->slot), this->cpuMask)) 99 | { 100 | free(pCounterMSRObject); 101 | return false; 102 | } 103 | 104 | //Programs the bits of the performance counter register according with specifications 105 | pCounterMSRObject->setBits(8, 8, this->unitMask); 106 | pCounterMSRObject->setBits(16, 1, this->countUserMode); 107 | pCounterMSRObject->setBits(17, 1, this->countOsMode); 108 | pCounterMSRObject->setBits(18, 1, this->edgeDetect); 109 | pCounterMSRObject->setBits(20, 1, this->enableAPICInterrupt); 110 | pCounterMSRObject->setBits(23, 1, this->invertCntMask); 111 | pCounterMSRObject->setBits(24, 8, this->counterMask); 112 | pCounterMSRObject->setBits(0, 8, this->eventSelect & 0xff); //Lower 8 bits of eventSelect 113 | pCounterMSRObject->setBits(32, 4, this->eventSelect & 0xf00); //Higher 4 bits of eventSelect 114 | pCounterMSRObject->setBits(22, 1, 0); //Disables the counter, it must be enabled with another method 115 | 116 | //Writes the data in the MS registers; 117 | if (!pCounterMSRObject->writeMSR()) 118 | { 119 | free(pCounterMSRObject); 120 | return false; 121 | } 122 | 123 | free(pCounterMSRObject); 124 | return true; 125 | 126 | } 127 | 128 | /* 129 | * fetch method will do the inverse of program method. Program method will program the hardware registers 130 | * with parameters sets in an object of this class, instead fetch will read the hardware registers and will 131 | * modify the parameters of the object. Then the parameters can be read by the main program using the 132 | * getters to obtain actual hardware status. 133 | * 134 | * The only limitation with this method is the fact that you can fetch hardware registers of only one cpu 135 | * in the cpu mask. 136 | * 137 | */ 138 | bool PerformanceCounter::fetch(DWORD cpuIndex) 139 | { 140 | MSRObject *pCounterMSRObject = new MSRObject(); 141 | 142 | //Loads the current status of the MS registers for all the cpus in the mask. 143 | //Actually it could be optimized reading data for one cpu only. 144 | if (!pCounterMSRObject->readMSR(getPESRReg(this->slot), this->cpuMask)) 145 | { 146 | free(pCounterMSRObject); 147 | return false; 148 | } 149 | 150 | this->unitMask=pCounterMSRObject->getBits(cpuIndex, 8, 8); 151 | this->countUserMode=pCounterMSRObject->getBits(cpuIndex, 16, 1); 152 | this->countOsMode=pCounterMSRObject->getBits(cpuIndex, 17, 1); 153 | this->edgeDetect=pCounterMSRObject->getBits(cpuIndex, 18, 1); 154 | this->enableAPICInterrupt=pCounterMSRObject->getBits(cpuIndex, 20, 1); 155 | this->invertCntMask=pCounterMSRObject->getBits(cpuIndex, 23, 1); 156 | this->counterMask=pCounterMSRObject->getBits(cpuIndex, 24, 8); 157 | this->enabled=pCounterMSRObject->getBits(cpuIndex, 22,1); 158 | this->eventSelect=pCounterMSRObject->getBits(cpuIndex, 0, 8); //Lower 8 bits of eventSelect 159 | this->eventSelect+=pCounterMSRObject->getBits(cpuIndex, 32, 4) << 4; //Higher 4 bits of eventSelect 160 | 161 | return true; 162 | 163 | } 164 | 165 | /* 166 | * findAvailableSlot() will find a "row" of available slots. It means that it will cycle through the 167 | * performance counter slots and will search for a slot that is, for all processors in the mask, 168 | * not enabled at all or has exactly the same parameters that is going to be programmed. 169 | * 170 | * Returns the performance counter slot if the class finds an available slot for all the processors. 171 | * Returns -1 (0xffffffff) if no available slot is found 172 | * Returns -2 (0xfffffffe) in case of errors 173 | * 174 | */ 175 | 176 | unsigned int PerformanceCounter::findAvailableSlot () 177 | { 178 | MSRObject *pCounterMSRObject = new MSRObject(); 179 | unsigned int slot; 180 | unsigned int cpuIndex; 181 | bool valid; 182 | 183 | for (slot = 0; slot < this->maxslots; slot++) 184 | { 185 | //Loads the current status of the MS registers for all the cpus in the mask. 186 | if (!pCounterMSRObject->readMSR(getPESRReg(slot), this->cpuMask)) 187 | { 188 | free(pCounterMSRObject); 189 | return -2; 190 | } 191 | 192 | valid = true; 193 | 194 | for (cpuIndex = 0; cpuIndex < pCounterMSRObject->getCount(); cpuIndex++) 195 | { 196 | //If the counter slot is disabled, we proceed to the next cpu in the mask 197 | //If the counter slot is enabled, we check the parameters. If we find that parameters are 198 | //exactly the same as those programmed in the class object, we proceed to the next 199 | //cpu in the mask. If parameters are not the same, we break the cycle and proceed to the next slot 200 | if (pCounterMSRObject->getBits(cpuIndex, 22, 1) != 0) 201 | { 202 | if ((pCounterMSRObject->getBits(cpuIndex, 8, 8) != this->unitMask) || 203 | (pCounterMSRObject->getBits(cpuIndex, 16, 1) != this->countUserMode) || 204 | (pCounterMSRObject->getBits(cpuIndex, 17, 1) != this->countOsMode) || 205 | (pCounterMSRObject->getBits(cpuIndex, 18, 1) != this->edgeDetect) || 206 | (pCounterMSRObject->getBits(cpuIndex, 20, 1) != this->enableAPICInterrupt) || 207 | (pCounterMSRObject->getBits(cpuIndex, 23, 1) != this->invertCntMask) || 208 | (pCounterMSRObject->getBits(cpuIndex, 24, 8) != this->counterMask) || 209 | (pCounterMSRObject->getBits(cpuIndex, 0, 8) != (this->eventSelect & 0xff)) || 210 | (pCounterMSRObject->getBits(cpuIndex, 32, 4) != (this->eventSelect & 0xf00))) 211 | { 212 | valid=false; 213 | break; 214 | } 215 | } 216 | 217 | } 218 | 219 | if (valid == true) 220 | return slot; 221 | } 222 | 223 | //We found no valid slot, returns -1 as expected 224 | return -1; 225 | 226 | } 227 | 228 | /* 229 | * findFreeSlot() will find a "row" of available slots. It means that it will cycle through the 230 | * performance counter slots and will search for a slot that is, for all processors in the mask, 231 | * not enabled at all. 232 | * 233 | * Returns the performance counter slot if the class finds free slots for all the processors. 234 | * Returns -1 (0xffffffff) if no free slot is found 235 | * Returns -2 (0xfffffffe) in case of errors 236 | * 237 | */ 238 | 239 | unsigned int PerformanceCounter::findFreeSlot () 240 | { 241 | MSRObject *pCounterMSRObject = new MSRObject(); 242 | unsigned int slot; 243 | unsigned int cpuIndex; 244 | bool valid; 245 | 246 | for (slot = 0; slot < this->maxslots; slot++) 247 | { 248 | //Loads the current status of the MS registers for all the cpus in the mask. 249 | if (!pCounterMSRObject->readMSR(getPESRReg(slot), this->cpuMask)) 250 | { 251 | free(pCounterMSRObject); 252 | return -2; 253 | } 254 | 255 | valid=true; 256 | 257 | for (cpuIndex=0;cpuIndexgetCount();cpuIndex++) 258 | { 259 | //If the counter slot is disabled, we proceed to the next cpu in the mask 260 | //If the counter slos is enabled, we stop the cycle and declare the slot unfree 261 | if (pCounterMSRObject->getBits(cpuIndex, 22, 1) != 0) 262 | { 263 | valid=false; 264 | break; 265 | } 266 | 267 | } 268 | 269 | if (valid==true) return slot; 270 | 271 | } 272 | 273 | //We found no valid slot, returns -1 as expected 274 | return -1; 275 | 276 | } 277 | 278 | 279 | /* 280 | * Enables the performance counter slot for all the processors in cpuMask 281 | * Be sure to program them first with program method! 282 | * 283 | * Returns true is successful, false in the other case. 284 | * 285 | */ 286 | 287 | bool PerformanceCounter::enable() 288 | { 289 | 290 | MSRObject *pCounterMSRObject = new MSRObject(); 291 | 292 | //Loads the current status of the MS registers for all the cpus in the mask. 293 | if (!pCounterMSRObject->readMSR(getPESRReg(this->slot), this->cpuMask)) 294 | { 295 | free(pCounterMSRObject); 296 | return -2; 297 | } 298 | 299 | pCounterMSRObject->setBitsLow(22, 1, 0x1); //Sets the bit 22, enables the performance counter 300 | 301 | if (!pCounterMSRObject->writeMSR()) 302 | { 303 | free(pCounterMSRObject); 304 | return false; 305 | } 306 | 307 | this->enabled = true; 308 | 309 | free(pCounterMSRObject); 310 | return true; 311 | 312 | } 313 | 314 | /* 315 | * Disables the performance counter slot for all the processors in cpuMask 316 | * 317 | * 318 | * Returns true is successful, false in the other case. 319 | * 320 | */ 321 | 322 | bool PerformanceCounter::disable() 323 | { 324 | 325 | MSRObject *pCounterMSRObject = new MSRObject(); 326 | 327 | //Loads the current status of the MS registers for all the cpus in the mask. 328 | if (!pCounterMSRObject->readMSR(getPESRReg(this->slot), this->cpuMask)) 329 | { 330 | free(pCounterMSRObject); 331 | return -2; 332 | } 333 | 334 | pCounterMSRObject->setBitsLow(22, 1, 0x0); //Sets the bit 22, disables the performance counter 335 | 336 | if (!pCounterMSRObject->writeMSR()) 337 | { 338 | 339 | free(pCounterMSRObject); 340 | return false; 341 | 342 | } 343 | 344 | this->enabled=false; 345 | 346 | free(pCounterMSRObject); 347 | return true; 348 | 349 | } 350 | 351 | /* 352 | * takeSnapshot method will read the counter associated with the performance counter and will store it 353 | * inside the object. Then the main program can access each single counter for each processor/core without 354 | * the problem of retrieving time-stretched uncoherent data. 355 | * 356 | * Returns true if the snapshot has been taken correctly, else will return false 357 | */ 358 | bool PerformanceCounter::takeSnapshot() 359 | { 360 | if (!snapshotRegister->readMSR(getPERCReg(this->slot), this->cpuMask)) 361 | return false; 362 | 363 | return true; 364 | 365 | } 366 | 367 | /* 368 | * Returns the counter associated with cpuIndex. Remember that cpuIndex is not the absolute number of the cpu 369 | * you want to read the counter, but it is an index as explained in the getBits method in the MSRObject class 370 | * 371 | * Remember also to issue a call to takeSnapshot before calling getCounter, else you will get invalid data 372 | * 373 | */ 374 | uint64_t PerformanceCounter::getCounter(DWORD cpuIndex) 375 | { 376 | return snapshotRegister->getBits(cpuIndex, 0, 64); 377 | } 378 | 379 | /* 380 | * Getters and setters, not much interesting 381 | * 382 | */ 383 | 384 | bool PerformanceCounter::getEnabled() const { 385 | return enabled; 386 | } 387 | 388 | bool PerformanceCounter::getCountUserMode() const { 389 | return countUserMode; 390 | } 391 | 392 | unsigned char PerformanceCounter::getCounterMask() const { 393 | return counterMask; 394 | } 395 | 396 | PROCESSORMASK PerformanceCounter::getCpuMask() const { 397 | return cpuMask; 398 | } 399 | 400 | bool PerformanceCounter::getEdgeDetect() const { 401 | return edgeDetect; 402 | } 403 | 404 | bool PerformanceCounter::getEnableAPICInterrupt() const { 405 | return enableAPICInterrupt; 406 | } 407 | 408 | unsigned short int PerformanceCounter::getEventSelect() const { 409 | return eventSelect; 410 | } 411 | 412 | bool PerformanceCounter::getInvertCntMask() const { 413 | return invertCntMask; 414 | } 415 | 416 | unsigned char PerformanceCounter::getSlot() const { 417 | return slot; 418 | } 419 | 420 | unsigned char PerformanceCounter::getUnitMask() const { 421 | return unitMask; 422 | } 423 | 424 | void PerformanceCounter::setCountUserMode(bool countUserMode) { 425 | this->countUserMode = countUserMode; 426 | } 427 | 428 | void PerformanceCounter::setCounterMask(unsigned char counterMask) { 429 | this->counterMask = counterMask; 430 | } 431 | 432 | void PerformanceCounter::setCpuMask(PROCESSORMASK cpuMask) { 433 | this->cpuMask = cpuMask; 434 | } 435 | 436 | void PerformanceCounter::setEdgeDetect(bool edgeDetect) { 437 | this->edgeDetect = edgeDetect; 438 | } 439 | 440 | void PerformanceCounter::setEnableAPICInterrupt(bool enableAPICInterrupt) { 441 | this->enableAPICInterrupt = enableAPICInterrupt; 442 | } 443 | 444 | void PerformanceCounter::setEventSelect(unsigned short int eventSelect) { 445 | this->eventSelect = eventSelect; 446 | } 447 | 448 | void PerformanceCounter::setInvertCntMask(bool invertCntMask) { 449 | this->invertCntMask = invertCntMask; 450 | } 451 | 452 | void PerformanceCounter::setSlot(unsigned char slot) { 453 | this->slot = slot; 454 | } 455 | 456 | bool PerformanceCounter::getCountOsMode() const 457 | { 458 | return countOsMode; 459 | } 460 | 461 | void PerformanceCounter::setCountOsMode(bool countOsMode) 462 | { 463 | this->countOsMode = countOsMode; 464 | } 465 | 466 | void PerformanceCounter::setUnitMask(unsigned char unitMask) { 467 | this->unitMask = unitMask; 468 | } 469 | 470 | void PerformanceCounter::setMaxSlots(unsigned char maxslots) 471 | { 472 | this->maxslots = maxslots; 473 | } 474 | 475 | /* 476 | * Destructor. Frees resources. 477 | * 478 | */ 479 | 480 | PerformanceCounter::~PerformanceCounter() { 481 | 482 | free(snapshotRegister); 483 | 484 | } 485 | -------------------------------------------------------------------------------- /K10PerformanceCounters.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * K10PerformanceCounters.cpp 3 | * 4 | * Collection of static method to exploit performance counters. Since many architectures shares the same 5 | * performance counter structure, counting and registers, we use this technique to not repeat a lot of times 6 | * the same common code 7 | * 8 | * Created on: 31/lug/2011 9 | * Author: paolo 10 | */ 11 | 12 | #include "Processor.h" 13 | #include "PerformanceCounter.h" 14 | #include "PCIRegObject.h" 15 | #include "MSRObject.h" 16 | #include "Signal.h" 17 | 18 | void Processor::K10PerformanceCounters::perfMonitorCPUUsage(class Processor *p) 19 | { 20 | PerformanceCounter *perfCounter; 21 | MSRObject *tscCounter; //We need the timestamp counter too to determine the cpu usage in percentage 22 | 23 | DWORD cpuIndex, nodeId, coreId; 24 | PROCESSORMASK cpuMask; 25 | unsigned int perfCounterSlot; 26 | 27 | uint64_t usage; 28 | 29 | // These two pointers will refer to two arrays containing previous performance counter values 30 | // and previous Time Stamp counters. We need these to obtain instantaneous CPU usage information 31 | uint64_t *prevPerfCounters; 32 | uint64_t *prevTSCCounters; 33 | 34 | try 35 | { 36 | p->setNode(p->ALL_NODES); 37 | p->setCore(p->ALL_CORES); 38 | 39 | cpuMask = p->getMask(); 40 | /* We do this to do some "caching" of the mask, instead of calculating each time 41 | we need to retrieve the time stamp counter */ 42 | 43 | // Allocating space for previous values of counters. 44 | prevPerfCounters = (uint64_t *) calloc(p->getProcessorCores() * p->getProcessorNodes(), sizeof(uint64_t)); 45 | prevTSCCounters = (uint64_t *) calloc(p->getProcessorCores() * p->getProcessorNodes(), sizeof(uint64_t)); 46 | 47 | // MSR Object to retrieve the time stamp counter for all the nodes and all the processors 48 | tscCounter = new MSRObject(); 49 | 50 | //Creates a new performance counter, for now we set slot 0, but we will 51 | //use the findAvailable slot method to find an available method to be used 52 | perfCounter = new PerformanceCounter(cpuMask, 0, p->getMaxSlots()); 53 | 54 | //Event 0x76 is Idle Counter 55 | perfCounter->setEventSelect(0x76); 56 | perfCounter->setCountOsMode(true); 57 | perfCounter->setCountUserMode(true); 58 | perfCounter->setCounterMask(0); 59 | perfCounter->setEdgeDetect(false); 60 | perfCounter->setEnableAPICInterrupt(false); 61 | perfCounter->setInvertCntMask(false); 62 | perfCounter->setUnitMask(0); 63 | perfCounter->setMaxSlots(p->getMaxSlots()); 64 | 65 | //Finds an available slot for our purpose 66 | perfCounterSlot = perfCounter->findAvailableSlot(); 67 | 68 | //findAvailableSlot() returns -2 in case of error 69 | if (perfCounterSlot == 0xfffffffe) 70 | throw "unable to access performance counter slots"; 71 | 72 | //findAvailableSlot() returns -1 in case there aren't available slots 73 | if (perfCounterSlot == 0xffffffff) 74 | throw "unable to find an available performance counter slot"; 75 | 76 | printf("Performance counter will use slot #%d\n", perfCounterSlot); 77 | 78 | //In case there are no errors, we program the object with the slot itself has found 79 | perfCounter->setSlot(perfCounterSlot); 80 | 81 | // Program the counter slot 82 | if (!perfCounter->program()) 83 | throw "unable to program performance counter parameters"; 84 | 85 | // Enable the counter slot 86 | if (!perfCounter->enable()) 87 | throw "unable to enable performance counters"; 88 | 89 | /* Here we take a snapshot of the performance counter and a snapshot of the time 90 | * stamp counter to initialize the arrays to let them not show erratic huge numbers 91 | * on first step 92 | */ 93 | 94 | if (!perfCounter->takeSnapshot()) 95 | { 96 | throw "unable to retrieve performance counter data"; 97 | return; 98 | } 99 | 100 | if (!tscCounter->readMSR(TIME_STAMP_COUNTER_REG, cpuMask)) 101 | { 102 | throw "unable to retrieve time stamp counter"; 103 | return; 104 | } 105 | 106 | cpuIndex = 0; 107 | for (nodeId = 0; nodeId < p->getProcessorNodes(); nodeId++) 108 | { 109 | for (coreId = 0; coreId < p->getProcessorCores(); coreId++) 110 | { 111 | prevPerfCounters[cpuIndex] = perfCounter->getCounter(cpuIndex); 112 | prevTSCCounters[cpuIndex] = tscCounter->getBits(cpuIndex, 0, 64); 113 | cpuIndex++; 114 | } 115 | } 116 | 117 | Signal::activateUserSignalsHandler(); 118 | printf("Values >100%% can be expected if the CPU is in a Boosted State\n"); 119 | 120 | while (!Signal::getSignalStatus()) 121 | { 122 | if (!perfCounter->takeSnapshot()) 123 | { 124 | throw "unable to retrieve performance counter data"; 125 | return; 126 | } 127 | 128 | if (!tscCounter->readMSR(TIME_STAMP_COUNTER_REG, cpuMask)) 129 | { 130 | throw "unable to retrieve time stamp counter"; 131 | return; 132 | } 133 | 134 | cpuIndex = 0; 135 | 136 | for (nodeId = 0; nodeId < p->getProcessorNodes(); nodeId++) 137 | { 138 | printf("\nNode %d -", nodeId); 139 | 140 | for (coreId = 0x0; coreId < p->getProcessorCores(); coreId++) 141 | { 142 | usage = ((perfCounter->getCounter(cpuIndex)) - prevPerfCounters[cpuIndex]) * 100; 143 | usage /= tscCounter->getBits(cpuIndex, 0, 64) - prevTSCCounters[cpuIndex]; 144 | 145 | printf(" c%d:%d%%", coreId, (unsigned int) usage); 146 | 147 | prevPerfCounters[cpuIndex] = perfCounter->getCounter(cpuIndex); 148 | prevTSCCounters[cpuIndex] = tscCounter->getBits(cpuIndex, 0, 64); 149 | 150 | cpuIndex++; 151 | } 152 | } 153 | fflush(stdout); 154 | Sleep(1000); 155 | } 156 | 157 | perfCounter->disable(); 158 | 159 | } catch (char const *str) { 160 | 161 | if (perfCounter->getEnabled()) perfCounter->disable(); 162 | 163 | printf("K10PerformanceCounters.cpp::perfMonitorCPUUsage - %s\n", str); 164 | 165 | } 166 | 167 | free(perfCounter); 168 | free(tscCounter); 169 | free(prevPerfCounters); 170 | free(prevTSCCounters); 171 | 172 | return; 173 | 174 | } 175 | 176 | void Processor::K10PerformanceCounters::perfMonitorFPUUsage(class Processor *p) 177 | { 178 | PerformanceCounter *perfCounter; 179 | MSRObject *tscCounter; //We need the timestamp counter too to determine the cpu usage in percentage 180 | 181 | DWORD cpuIndex, nodeId, coreId; 182 | PROCESSORMASK cpuMask; 183 | unsigned int perfCounterSlot; 184 | 185 | uint64_t usage; 186 | 187 | // These two pointers will refer to two arrays containing previous performance counter values 188 | // and previous Time Stamp counters. We need these to obtain instantaneous CPU usage information 189 | uint64_t *prevPerfCounters; 190 | uint64_t *prevTSCCounters; 191 | 192 | try { 193 | 194 | p->setNode(p->ALL_NODES); 195 | p->setCore(p->ALL_CORES); 196 | 197 | cpuMask = p->getMask(); 198 | /* We do this to do some "caching" of the mask, instead of calculating each time 199 | we need to retrieve the time stamp counter */ 200 | 201 | // Allocating space for previous values of counters. 202 | prevPerfCounters = (uint64_t *) calloc(p->getProcessorCores() * p->getProcessorNodes(), sizeof(uint64_t)); 203 | prevTSCCounters = (uint64_t *) calloc(p->getProcessorCores() * p->getProcessorNodes(), sizeof(uint64_t)); 204 | 205 | // MSR Object to retrieve the time stamp counter for all the nodes and all the processors 206 | tscCounter = new MSRObject(); 207 | 208 | //Creates a new performance counter, for now we set slot 0, but we will 209 | //use the findAvailable slot method to find an available method to be used 210 | perfCounter = new PerformanceCounter(cpuMask, 0, p->getMaxSlots()); 211 | 212 | //Event 0x76 is Idle Counter 213 | perfCounter->setEventSelect(0x1); 214 | perfCounter->setCountOsMode(true); 215 | perfCounter->setCountUserMode(true); 216 | perfCounter->setCounterMask(0); 217 | perfCounter->setEdgeDetect(false); 218 | perfCounter->setEnableAPICInterrupt(false); 219 | perfCounter->setInvertCntMask(false); 220 | perfCounter->setUnitMask(0); 221 | 222 | //Finds an available slot for our purpose 223 | perfCounterSlot = perfCounter->findAvailableSlot(); 224 | 225 | //findAvailableSlot() returns -2 in case of error 226 | if (perfCounterSlot == 0xfffffffe) 227 | throw "unable to access performance counter slots"; 228 | 229 | //findAvailableSlot() returns -1 in case there aren't available slots 230 | if (perfCounterSlot == 0xffffffff) 231 | throw "unable to find an available performance counter slot"; 232 | 233 | printf("Performance counter will use slot #%d\n", perfCounterSlot); 234 | 235 | //In case there are no errors, we program the object with the slot itself has found 236 | perfCounter->setSlot(perfCounterSlot); 237 | 238 | // Program the counter slot 239 | if (!perfCounter->program()) 240 | throw "unable to program performance counter parameters"; 241 | 242 | // Enable the counter slot 243 | if (!perfCounter->enable()) 244 | throw "unable to enable performance counters"; 245 | 246 | /* Here we take a snapshot of the performance counter and a snapshot of the time 247 | * stamp counter to initialize the arrays to let them not show erratic huge numbers 248 | * on first step 249 | */ 250 | 251 | if (!perfCounter->takeSnapshot()) 252 | throw "unable to retrieve performance counter data"; 253 | 254 | if (!tscCounter->readMSR(TIME_STAMP_COUNTER_REG, cpuMask)) 255 | throw "unable to retrieve time stamp counter"; 256 | 257 | cpuIndex = 0; 258 | for (nodeId = 0; nodeId < p->getProcessorNodes(); nodeId++) 259 | { 260 | for (coreId = 0x0; coreId < p->getProcessorCores(); coreId++) 261 | { 262 | prevPerfCounters[cpuIndex] = perfCounter->getCounter(cpuIndex); 263 | prevTSCCounters[cpuIndex] = tscCounter->getBits(cpuIndex, 0, 64); 264 | cpuIndex++; 265 | } 266 | } 267 | 268 | Signal::activateUserSignalsHandler(); 269 | 270 | while (!Signal::getSignalStatus()) 271 | { 272 | if (!perfCounter->takeSnapshot()) 273 | throw "unable to retrieve performance counter data"; 274 | 275 | if (!tscCounter->readMSR(TIME_STAMP_COUNTER_REG, cpuMask)) 276 | throw "unable to retrieve time stamp counter"; 277 | 278 | cpuIndex = 0; 279 | 280 | for (nodeId = 0; nodeId < p->getProcessorNodes(); nodeId++) 281 | { 282 | printf("Node %d -", nodeId); 283 | 284 | for (coreId = 0x0; coreId < p->getProcessorCores(); coreId++) 285 | { 286 | 287 | usage = ((perfCounter->getCounter(cpuIndex)) - prevPerfCounters[cpuIndex]) * 100; 288 | usage /= tscCounter->getBits(cpuIndex, 0, 64) - prevTSCCounters[cpuIndex]; 289 | 290 | printf(" c%u:%u%%", coreId, (unsigned int) usage); 291 | 292 | prevPerfCounters[cpuIndex] = perfCounter->getCounter(cpuIndex); 293 | prevTSCCounters[cpuIndex] = tscCounter->getBits(cpuIndex, 0, 64); 294 | 295 | cpuIndex++; 296 | } 297 | printf("\n"); 298 | } 299 | if (fflush(stdout) == EOF) { 300 | break; 301 | } 302 | Sleep(1000); 303 | } 304 | 305 | perfCounter->disable(); 306 | 307 | } catch (char const *str) { 308 | 309 | if (perfCounter->getEnabled()) perfCounter->disable(); 310 | 311 | printf("K10PerformanceCounters.cpp::perfMonitorCPUUsage - %s\n", str); 312 | } 313 | 314 | free(perfCounter); 315 | free(tscCounter); 316 | free(prevPerfCounters); 317 | free(prevTSCCounters); 318 | 319 | return; 320 | 321 | } 322 | 323 | void Processor::K10PerformanceCounters::perfMonitorDCMA(class Processor *p) 324 | { 325 | PerformanceCounter *perfCounter; 326 | 327 | DWORD cpuIndex, nodeId, coreId; 328 | PROCESSORMASK cpuMask; 329 | unsigned int perfCounterSlot; 330 | 331 | uint64_t misses; 332 | 333 | // This pointers will refer an array containing previous performance counter values 334 | uint64_t *prevPerfCounters; 335 | 336 | try { 337 | 338 | p->setNode(p->ALL_NODES); 339 | p->setCore(p->ALL_CORES); 340 | 341 | cpuMask = p->getMask(); 342 | /* We do this to do some "caching" of the mask, instead of calculating each time 343 | we need to retrieve the time stamp counter */ 344 | 345 | // Allocating space for previous values of counters. 346 | prevPerfCounters = (uint64_t *) calloc( 347 | p->getProcessorCores() * p->getProcessorNodes(), 348 | sizeof(uint64_t)); 349 | 350 | //Creates a new performance counter, for now we set slot 0, but we will 351 | //use the findAvailable slot method to find an available method to be used 352 | perfCounter = new PerformanceCounter(cpuMask, 0, p->getMaxSlots()); 353 | 354 | //Event 0x76 is Idle Counter 355 | perfCounter->setEventSelect(0x47); 356 | perfCounter->setCountOsMode(true); 357 | perfCounter->setCountUserMode(true); 358 | perfCounter->setCounterMask(0); 359 | perfCounter->setEdgeDetect(false); 360 | perfCounter->setEnableAPICInterrupt(false); 361 | perfCounter->setInvertCntMask(false); 362 | perfCounter->setUnitMask(0); 363 | 364 | //Finds an available slot for our purpose 365 | perfCounterSlot = perfCounter->findAvailableSlot(); 366 | 367 | //findAvailableSlot() returns -2 in case of error 368 | if (perfCounterSlot == 0xfffffffe) 369 | throw "unable to access performance counter slots"; 370 | 371 | //findAvailableSlot() returns -1 in case there aren't available slots 372 | if (perfCounterSlot == 0xffffffff) 373 | throw "unable to find an available performance counter slot"; 374 | 375 | printf("Performance counter will use slot #%d\n", perfCounterSlot); 376 | 377 | //In case there are no errors, we program the object with the slot itself has found 378 | perfCounter->setSlot(perfCounterSlot); 379 | 380 | // Program the counter slot 381 | if (!perfCounter->program()) 382 | throw "unable to program performance counter parameters"; 383 | 384 | // Enable the counter slot 385 | if (!perfCounter->enable()) 386 | throw "unable to enable performance counters"; 387 | 388 | /* Here we take a snapshot of the performance counter and a snapshot of the time 389 | * stamp counter to initialize the arrays to let them not show erratic huge numbers 390 | * on first step 391 | */ 392 | 393 | if (!perfCounter->takeSnapshot()) 394 | throw "unable to retrieve performance counter data"; 395 | 396 | cpuIndex = 0; 397 | for (nodeId = 0; nodeId < p->getProcessorNodes(); nodeId++) 398 | { 399 | for (coreId = 0x0; coreId < p->getProcessorCores(); coreId++) 400 | { 401 | prevPerfCounters[cpuIndex] = perfCounter->getCounter(cpuIndex); 402 | cpuIndex++; 403 | } 404 | } 405 | 406 | Signal::activateUserSignalsHandler(); 407 | 408 | while (!Signal::getSignalStatus()) 409 | { 410 | if (!perfCounter->takeSnapshot()) 411 | throw "unable to retrieve performance counter data"; 412 | 413 | cpuIndex = 0; 414 | 415 | for (nodeId = 0; nodeId < p->getProcessorNodes(); nodeId++) 416 | { 417 | printf("Node %d -", nodeId); 418 | 419 | for (coreId = 0x0; coreId < p->getProcessorCores(); coreId++) 420 | { 421 | misses = perfCounter->getCounter(cpuIndex) - prevPerfCounters[cpuIndex]; 422 | 423 | printf(" c%u:%0.3fk", coreId, (float) (misses/1000.0f)); 424 | 425 | prevPerfCounters[cpuIndex] = perfCounter->getCounter(cpuIndex); 426 | 427 | cpuIndex++; 428 | } 429 | printf("\n"); 430 | } 431 | if (fflush(stdout) == EOF) { 432 | break; 433 | } 434 | Sleep(1000); 435 | } 436 | 437 | perfCounter->disable(); 438 | 439 | } catch (char const *str) { 440 | 441 | if (perfCounter->getEnabled()) perfCounter->disable(); 442 | 443 | printf("K10PerformanceCounters.cpp::perfMonitorCPUUsage - %s\n", str); 444 | 445 | } 446 | 447 | free(perfCounter); 448 | free(prevPerfCounters); 449 | 450 | return; 451 | 452 | } 453 | 454 | 455 | 456 | void Processor::K10PerformanceCounters::perfCounterGetInfo (class Processor *p) { 457 | 458 | PerformanceCounter *performanceCounter; 459 | DWORD node, core, slot; 460 | 461 | printf ("Caption:\n"); 462 | printf ("Evt:\tperformance counter event\n"); 463 | printf ("En:\tperformance counter is enabled\n"); 464 | printf ("U:\tperformance counter will count usermode instructions\n"); 465 | printf ("OS:\tperformance counter will counter Os/kernel instructions\n"); 466 | printf ("cMsk:\tperformance counter mask (see processor manual reference)\n"); 467 | printf ("ED:\tcounting on edge detect, else counting on level detect\n"); 468 | printf ("APIC:\tif set, an APIC interrupt will be issued on counter overflow\n"); 469 | printf ("icMsk:\tif set, mask is inversed (see processor manual reference)\n"); 470 | printf ("uMsk:\tunit mask (see processor manual reference)\n\n"); 471 | 472 | for (node = 0; node < p->getProcessorNodes(); node++) 473 | { 474 | printf ("--- Node %d\n", node); 475 | 476 | p->setNode(node); 477 | p->setCore(ALL_CORES); 478 | 479 | for (slot = 0; slot < p->getMaxSlots(); slot++) 480 | { 481 | performanceCounter = new PerformanceCounter(p->getMask(), slot, p->getMaxSlots()); 482 | 483 | for (core = 0; core < p->getProcessorCores(); core++) 484 | { 485 | if (!performanceCounter->fetch (core)) 486 | { 487 | printf ("K10PerformanceCounters.cpp::perfCounterGetInfo - unable to read performance counter register\n"); 488 | free (performanceCounter); 489 | return; 490 | } 491 | 492 | printf ("Slot %d core %d - evt:0x%x En:%d U:%d OS:%d cMsk:%x ED:%d APIC:%d icMsk:%x uMsk:%x\n", 493 | slot, 494 | core, 495 | performanceCounter->getEventSelect(), 496 | performanceCounter->getEnabled(), 497 | performanceCounter->getCountUserMode(), 498 | performanceCounter->getCountOsMode(), 499 | performanceCounter->getCounterMask(), 500 | performanceCounter->getEdgeDetect(), 501 | performanceCounter->getEnableAPICInterrupt(), 502 | performanceCounter->getInvertCntMask(), 503 | performanceCounter->getUnitMask() 504 | ); 505 | } 506 | free (performanceCounter); 507 | } 508 | } 509 | } 510 | -------------------------------------------------------------------------------- /Processor.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #ifdef _WIN32 5 | #define uint64_t unsigned long long int 6 | #include 7 | #include "OlsApi.h" 8 | #endif 9 | 10 | #ifdef __linux 11 | #include "cpuPrimitives.h" 12 | #include 13 | #endif 14 | 15 | #include "Processor.h" 16 | 17 | 18 | PState::PState (DWORD ps) { 19 | pstate=ps; 20 | } 21 | 22 | DWORD PState::getPState () { 23 | return pstate; 24 | } 25 | 26 | void PState::setPState (DWORD ps) { 27 | pstate=ps; 28 | } 29 | 30 | void Processor::setCore (DWORD core) { 31 | 32 | if (!isValidCore(core)) return; 33 | 34 | selectedCore=core; 35 | 36 | } 37 | 38 | void Processor::setNode (DWORD node) { 39 | 40 | if (!isValidNode(node)) return; 41 | 42 | selectedNode=node; 43 | 44 | } 45 | 46 | DWORD Processor::getCore () { 47 | 48 | return selectedCore; 49 | 50 | } 51 | 52 | DWORD Processor::getNode () { 53 | 54 | return selectedNode; 55 | 56 | } 57 | 58 | /* 59 | * getMask - Gets a processor bitmask based on selectedCore and selectedNode 60 | * This is useful to use MSRObject class, since it involves 61 | * per-core bits. This bitmask is 64-bit wide on 64-bit systems 62 | * and 32-bit wide on 32-bit systems 63 | * If selectedCore is equal to static constant ALL_CORES and selectedNode 64 | * is a single node, the returned mask will have all the bits for those 65 | * cores of that precise node set. 66 | * If selectedCore is ALL_CORES and selectedNode is ALL_NODES, all bits are 67 | * set for all cores of all cpus present in the system 68 | * If selectedNode is ALL_NODES and selectedCore is a single value, then 69 | * the mask returned will set the selected core bit for each node in the system. 70 | */ 71 | PROCESSORMASK Processor::getMask (DWORD core, DWORD node) 72 | { 73 | PROCESSORMASK mask; 74 | 75 | //In the case we are pointing to a specific core on a specific node, this is 76 | //the right formula to get the mask for a single cpu. 77 | if ((core!=ALL_CORES) && (node!=ALL_NODES)) 78 | return (PROCESSORMASK)1<<((node*processorCores)+core); 79 | 80 | 81 | //If core is set to ALL_CORES and node is free we set the mask 82 | //to specify all the cores of one specific node 83 | if ((core==ALL_CORES) && (node!=ALL_NODES)) 84 | { 85 | mask = 1; 86 | mask <<= processorCores; 87 | mask -= 1; 88 | mask <<= processorCores * node; 89 | 90 | return mask; 91 | } 92 | 93 | //If core is free and node is set to ALL_NODES, we set 94 | //the mask to cover that specific core of all the nodes 95 | if ((core!=ALL_CORES) && (node==ALL_NODES)) 96 | { 97 | unsigned int offset; 98 | 99 | mask=0; 100 | for (offset=core;offset<(processorCores*processorNodes);offset+=processorCores) 101 | mask|=(PROCESSORMASK)1<>= (64 - processorCores * processorNodes); 113 | 114 | return mask; 115 | } 116 | 117 | return 0; 118 | 119 | } 120 | 121 | PROCESSORMASK Processor::getMask () { 122 | 123 | return getMask (selectedCore, selectedNode); 124 | 125 | } 126 | 127 | /* 128 | * getNodeMask - Gets a bitmask based on selectedNode nodes. 129 | * This bitmask is useful for PCIRegObject class and is 130 | * always 32-bit wide. 131 | * If selectedNode is equal to ALL_NODES static constant, 132 | * the bitmask returned by this function will set bits for only 133 | * active and present nodes. 134 | */ 135 | DWORD Processor::getNodeMask(DWORD node) 136 | { 137 | DWORD mask; 138 | 139 | if (node == ALL_NODES) 140 | { 141 | mask = 1; 142 | mask <<= processorNodes; 143 | mask -= 1; 144 | 145 | return mask; 146 | } 147 | 148 | mask = (DWORD) 1 << (node); 149 | return mask; 150 | 151 | } 152 | 153 | DWORD Processor::getNodeMask () 154 | { 155 | return getNodeMask (selectedNode); 156 | } 157 | 158 | //Return true if core is in the range, else shows an error message and return false 159 | bool Processor::isValidCore (DWORD core) { 160 | 161 | if (core==ALL_CORES) return true; 162 | 163 | if (core>=0 && core=0 && node sizeof(processorStrId) - 1) 226 | printf ("Warning: processor string Id Exceeds %d bytes!\n", sizeof(processorStrId) - 1); 227 | strncpy(processorStrId, strId, sizeof(processorStrId)); 228 | processorStrId[sizeof(processorStrId) - 1] = '\0'; 229 | } 230 | 231 | void Processor::setPowerStates (DWORD pstates) { 232 | powerStates=pstates; 233 | } 234 | 235 | void Processor::setProcessorCores (DWORD pcores) { 236 | processorCores=pcores; 237 | } 238 | 239 | void Processor::setProcessorIdentifier (DWORD pId) { 240 | processorIdentifier=pId; 241 | } 242 | 243 | void Processor::setProcessorNodes (DWORD nodes) { 244 | processorNodes=nodes; 245 | } 246 | 247 | DWORD Processor::HTLinkToFreq (DWORD reg) { 248 | 249 | switch (reg) { 250 | case 0x00: 251 | return 200; 252 | case 0x02: 253 | return 400; 254 | case 0x04: 255 | return 600; 256 | case 0x05: 257 | return 800; 258 | case 0x06: 259 | return 1000; 260 | case 0x07: 261 | return 1200; 262 | case 0x08: 263 | return 1400; 264 | case 0x09: 265 | return 1600; 266 | case 0x0A: 267 | return 1800; 268 | case 0x0B: 269 | return 2000; 270 | case 0x0C: 271 | return 2200; 272 | case 0x0D: 273 | return 2400; 274 | case 0x0E: 275 | return 2600; 276 | case 0x11: 277 | return 2800; 278 | case 0x12: 279 | return 3000; 280 | case 0x13: 281 | return 3200; 282 | default: 283 | return 0; 284 | } 285 | } 286 | 287 | void Processor::setSpecFamilyBase (int familyBase) { 288 | this->familyBase=familyBase; 289 | } 290 | 291 | void Processor::setSpecModel (int model) { 292 | this->model=model; 293 | } 294 | 295 | void Processor::setSpecStepping (int stepping) { 296 | this->stepping=stepping; 297 | } 298 | 299 | void Processor::setSpecFamilyExtended (int familyExtended) { 300 | this->familyExtended=familyExtended; 301 | } 302 | 303 | void Processor::setSpecModelExtended (int modelExtended) { 304 | this->modelExtended=modelExtended; 305 | } 306 | 307 | void Processor::setSpecBrandId (int brandId) { 308 | this->brandId=brandId; 309 | } 310 | 311 | void Processor::setSpecProcessorModel (int processorModel) { 312 | this->processorModel=processorModel; 313 | } 314 | 315 | void Processor::setSpecString1 (int string1) { 316 | this->string1=string1; 317 | } 318 | 319 | void Processor::setSpecString2 (int string2) { 320 | this->string2=string2; 321 | } 322 | 323 | void Processor::setSpecPkgType (int pkgType) { 324 | this->pkgType=pkgType; 325 | } 326 | 327 | void Processor::setBoostStates(int numBoostStates) 328 | { 329 | this->numBoostStates = numBoostStates; 330 | } 331 | 332 | DWORD Processor::getBoost(void) 333 | { 334 | return -1; 335 | } 336 | 337 | void Processor::setBoost(bool boost) 338 | { 339 | printf ("Unsupported processor feature\n"); 340 | return; 341 | } 342 | 343 | void Processor::setNumBoostStates(DWORD numBoostStates) 344 | { 345 | printf ("Unsupported processor feature\n"); 346 | return; 347 | } 348 | 349 | void Processor::setTDP(int TDP) 350 | { 351 | this->TDP = TDP; 352 | } 353 | 354 | void Processor::setMaxSlots(int maxslots) 355 | { 356 | this->maxslots = maxslots; 357 | } 358 | 359 | int Processor::getSpecFamilyBase () { 360 | return this->familyBase; 361 | } 362 | 363 | int Processor::getSpecModel () { 364 | return this->model; 365 | } 366 | 367 | int Processor::getSpecStepping () { 368 | return this->stepping; 369 | } 370 | 371 | int Processor::getSpecFamilyExtended () { 372 | return this->familyExtended; 373 | } 374 | 375 | int Processor::getSpecModelExtended () { 376 | return this->modelExtended; 377 | } 378 | 379 | int Processor::getSpecBrandId () { 380 | return this->brandId; 381 | } 382 | 383 | int Processor::getSpecProcessorModel () { 384 | return this->processorModel; 385 | } 386 | 387 | int Processor::getSpecString1 () { 388 | return this->string1; 389 | } 390 | 391 | int Processor::getSpecString2 () { 392 | return this->string2; 393 | } 394 | 395 | int Processor::getSpecPkgType () { 396 | return this->pkgType; 397 | } 398 | 399 | int Processor::getBoostStates () 400 | { 401 | return this->numBoostStates; 402 | } 403 | 404 | DWORD Processor::getTDP () 405 | { 406 | return this->TDP; 407 | } 408 | 409 | 410 | int Processor::getMaxSlots () 411 | { 412 | return this->maxslots; 413 | } 414 | 415 | /*** Following methods are likely to be overloaded/overridden inside each module ***/ 416 | 417 | /* setVID */ 418 | void Processor::setVID(PState ps, DWORD vid) { 419 | printf ("Processor::setVID()\n"); 420 | return; 421 | } 422 | 423 | /* setFID */ 424 | 425 | void Processor::setFID(PState ps, float fid) { 426 | return; 427 | } 428 | 429 | /* setDID */ 430 | 431 | void Processor::setDID(PState ps, float did) { 432 | return; 433 | } 434 | 435 | /* 436 | * get* methods allows to gather specific vid/fid/did parameter. 437 | * Here we have just one complete variant (instead of three different 438 | * variant as set* methods have) with four parameters because 439 | * these methods return a single value. To avoid overlapping 440 | * and useless contradictions, and to make code more compact, 441 | * I prefer to make definitions of these methods as precise 442 | * as possible 443 | */ 444 | 445 | /* getVID */ 446 | 447 | DWORD Processor::getVID(PState ps) { 448 | return -1; 449 | } 450 | 451 | /* getFID */ 452 | 453 | float Processor::getFID(PState ps) { 454 | return -1; 455 | } 456 | 457 | /* getDID */ 458 | 459 | float Processor::getDID(PState ps) { 460 | return -1; 461 | } 462 | 463 | 464 | /* setFrequency */ 465 | 466 | void Processor::setFrequency(PState ps, DWORD frequency) { 467 | return; 468 | } 469 | 470 | /* setVCore */ 471 | 472 | void Processor::setVCore(PState ps, float vcore) { 473 | return; 474 | } 475 | 476 | /* getFrequency */ 477 | 478 | DWORD Processor::getFrequency(PState ps) { 479 | return -1; 480 | } 481 | 482 | /* getVCore */ 483 | 484 | float Processor::getVCore(PState ps) { 485 | return -1; 486 | } 487 | 488 | /* pStateEnable */ 489 | void Processor::pStateEnable(PState ps) { 490 | return; 491 | } 492 | 493 | /* pStateDisable */ 494 | void Processor::pStateDisable(PState ps) { 495 | return; 496 | } 497 | 498 | /* pStateEnabled (peeking) */ 499 | bool Processor::pStateEnabled(PState ps) { 500 | return false; 501 | } 502 | 503 | //Primitives to set maximum p-state 504 | void Processor::setMaximumPState(PState ps) { 505 | printf("Unsupported processor feature\n"); 506 | return; 507 | } 508 | 509 | PState Processor::getMaximumPState() { 510 | printf("Unsupported processor feature\n"); 511 | return 0; 512 | } 513 | 514 | /* setNBVid */ 515 | void Processor::setNBVid(DWORD vid) { 516 | printf("Unsupported processor feature\n"); 517 | return; 518 | } 519 | 520 | void Processor::setNBVid(PState ps, DWORD vid) { 521 | printf("Unsupported processor feature\n"); 522 | return; 523 | } 524 | 525 | /* setNBDid */ 526 | void Processor::setNBDid(PState ps, DWORD did) { 527 | printf("Unsupported processor feature\n"); 528 | return; 529 | } 530 | 531 | 532 | /* getNBVid */ 533 | DWORD Processor::getNBVid() { 534 | printf("Unsupported processor feature\n"); 535 | return -1; 536 | } 537 | 538 | DWORD Processor::getNBVid(PState ps) { 539 | printf("Unsupported processor feature\n"); 540 | return -1; 541 | } 542 | 543 | /* getNBDid */ 544 | DWORD Processor::getNBDid(PState ps) { 545 | printf("Unsupported processor feature\n"); 546 | return -1; 547 | } 548 | 549 | /* setNBFid */ 550 | void Processor::setNBFid(DWORD fid) { 551 | printf("Unsupported processor feature\n"); 552 | return; 553 | } 554 | 555 | /* getNBFid */ 556 | DWORD Processor::getNBFid() { 557 | printf ("Unsupported processor feature\n"); 558 | return -1; 559 | } 560 | 561 | bool Processor::setNBFrequency(PState ps, DWORD frequency) { 562 | printf ("Unsupported processor feature\n"); 563 | return false; 564 | } 565 | 566 | DWORD Processor::getNBFrequency(PState ps) { 567 | printf ("Unsupported processor feature\n"); 568 | return -1; 569 | } 570 | 571 | bool Processor::setNBFrequency(DWORD frequency) { 572 | printf ("Unsupported processor feature\n"); 573 | return false; 574 | } 575 | 576 | DWORD Processor::getNBFrequency() { 577 | printf ("Unsupported processor feature\n"); 578 | return -1; 579 | } 580 | 581 | /* getMaxNBFrequency */ 582 | DWORD Processor::getMaxNBFrequency() { 583 | printf("Unsupported processor feature\n"); 584 | return -1; 585 | } 586 | 587 | bool Processor::getPVIMode() { 588 | return false; 589 | } 590 | 591 | void Processor::forcePState(PState ps) { 592 | return; 593 | } 594 | bool Processor::getSMAF7Enabled() { 595 | return false; 596 | } 597 | DWORD Processor::c1eDID() { 598 | return -1; 599 | } 600 | DWORD Processor::minVID() { 601 | return -1; 602 | } 603 | DWORD Processor::maxVID() { 604 | return -1; 605 | } 606 | DWORD Processor::startupPState() { 607 | return -1; 608 | } 609 | DWORD Processor::maxCPUFrequency() { 610 | return 0; 611 | } // 0 means that there 612 | 613 | //Temperature registers 614 | DWORD Processor::getTctlRegister(void) { 615 | return -1; 616 | } 617 | 618 | DWORD Processor::getTctlMaxDiff(void) { 619 | return -1; 620 | } 621 | 622 | //Voltage slamming time registers 623 | DWORD Processor::getSlamTime(void) { 624 | return -1; 625 | } 626 | void Processor::setSlamTime(DWORD slamTime) { 627 | return; 628 | } 629 | 630 | DWORD Processor::getAltVidSlamTime(void) { 631 | return -1; 632 | } 633 | void Processor::setAltVidSlamTime(DWORD slamTime) { 634 | return; 635 | } 636 | 637 | //Voltage ramping time registers - Taken from Phenom Datasheets, not official on turions 638 | DWORD Processor::getStepUpRampTime(void) { 639 | return -1; 640 | } 641 | DWORD Processor::getStepDownRampTime(void) { 642 | return -1; 643 | } 644 | 645 | void Processor::setStepUpRampTime(DWORD) { 646 | return; 647 | } 648 | 649 | void Processor::setStepDownRampTime(DWORD) { 650 | return; 651 | } 652 | 653 | //HTC Section 654 | bool Processor::HTCisCapable() { 655 | return false; 656 | } 657 | 658 | bool Processor::HTCisEnabled() { 659 | return false; 660 | } 661 | 662 | bool Processor::HTCisActive() { 663 | return false; 664 | } 665 | 666 | bool Processor::HTChasBeenActive() { 667 | return false; 668 | } 669 | 670 | DWORD Processor::HTCTempLimit() { 671 | return -1; 672 | } 673 | 674 | bool Processor::HTCSlewControl() { 675 | return false; 676 | } 677 | 678 | DWORD Processor::HTCHystTemp() { 679 | return -1; 680 | } 681 | 682 | DWORD Processor::HTCPStateLimit() { 683 | return -1; 684 | } 685 | 686 | bool Processor::HTCLocked() { 687 | return false; 688 | } 689 | 690 | DWORD Processor::getAltVID() { 691 | return -1; 692 | } 693 | 694 | //HTC Section - Change status 695 | 696 | void Processor::HTCEnable() { 697 | return; 698 | } 699 | 700 | void Processor::HTCDisable() { 701 | return; 702 | } 703 | void Processor::HTCsetTempLimit(DWORD tempLimit) { 704 | return; 705 | } 706 | void Processor::HTCsetHystLimit(DWORD hystLimit) { 707 | return; 708 | } 709 | void Processor::setAltVid(DWORD altvid) { 710 | return; 711 | } 712 | 713 | //PSI_L bit 714 | 715 | bool Processor::getPsiEnabled() { 716 | return false; 717 | } 718 | DWORD Processor::getPsiThreshold() { 719 | return -1; 720 | } 721 | void Processor::setPsiEnabled(bool toggle) { 722 | return; 723 | } 724 | void Processor::setPsiThreshold(DWORD threshold) { 725 | return; 726 | } 727 | 728 | //Hypertransport Section 729 | void Processor::setHTLinkSpeed(DWORD, DWORD) { 730 | return; 731 | } 732 | 733 | //Various settings 734 | 735 | bool Processor::getC1EStatus() { 736 | return false; 737 | } 738 | void Processor::setC1EStatus(bool toggle) { 739 | return; 740 | } 741 | 742 | //performance counters section 743 | 744 | void Processor::perfCounterGetInfo() { 745 | return; 746 | } 747 | 748 | void Processor::perfCounterGetValue(unsigned int perfCounter) { 749 | return; 750 | } 751 | 752 | void Processor::perfMonitorCPUUsage() { 753 | return; 754 | } 755 | 756 | void Processor::perfMonitorFPUUsage() { 757 | return; 758 | } 759 | 760 | void Processor::perfMonitorDCMA() { 761 | return; 762 | } 763 | 764 | void Processor::checkMode() { 765 | return; 766 | } 767 | 768 | //Scaler helper methods and structes 769 | void Processor::getCurrentStatus(struct procStatus *, DWORD) { 770 | return; 771 | } 772 | -------------------------------------------------------------------------------- /OlsApi.h: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Author : hiyohiyo 3 | // Mail : hiyohiyo@crystalmark.info 4 | // Web : http://openlibsys.org/ 5 | // License : The modified BSD license 6 | // 7 | // Copyright 2007-2009 OpenLibSys.org. All rights reserved. 8 | //----------------------------------------------------------------------------- 9 | // for WinRing0 1.3.x 10 | 11 | #pragma once 12 | 13 | #ifdef __cplusplus 14 | extern "C" { 15 | #endif /* __cplusplus */ 16 | 17 | /****************************************************************************** 18 | ** 19 | ** DLL Information 20 | ** 21 | ******************************************************************************/ 22 | 23 | //----------------------------------------------------------------------------- 24 | // GetDllStatus 25 | //----------------------------------------------------------------------------- 26 | DWORD // DLL Status, defined OLS_DLL_**** 27 | WINAPI GetDllStatus(); 28 | 29 | //----------------------------------------------------------------------------- 30 | // GetDllVersion 31 | //----------------------------------------------------------------------------- 32 | DWORD // DLL Version, defined OLS_VERSION 33 | WINAPI GetDllVersion( 34 | PBYTE major, // major version 35 | PBYTE minor, // minor version 36 | PBYTE revision, // revision 37 | PBYTE release // release/build 38 | ); 39 | 40 | //----------------------------------------------------------------------------- 41 | // GetDriverVersion 42 | //----------------------------------------------------------------------------- 43 | DWORD // Device Driver Version, defined OLS_DRIVER_VERSION 44 | WINAPI GetDriverVersion( 45 | PBYTE major, // major version 46 | PBYTE minor, // minor version 47 | PBYTE revision, // revision 48 | PBYTE release // release/build 49 | ); 50 | 51 | //----------------------------------------------------------------------------- 52 | // GetDriverType 53 | //----------------------------------------------------------------------------- 54 | DWORD // Device Driver Type, defined OLS_DRIVER_TYPE_**** 55 | WINAPI GetDriverType(); 56 | 57 | //----------------------------------------------------------------------------- 58 | // InitializeOls 59 | //----------------------------------------------------------------------------- 60 | BOOL // TRUE: success, FALSE: failure 61 | WINAPI InitializeOls(); 62 | 63 | //----------------------------------------------------------------------------- 64 | // DeinitializeOls 65 | //----------------------------------------------------------------------------- 66 | VOID WINAPI DeinitializeOls(); 67 | 68 | /****************************************************************************** 69 | ** 70 | ** CPU 71 | ** 72 | ******************************************************************************/ 73 | 74 | //----------------------------------------------------------------------------- 75 | // IsCpuid 76 | //----------------------------------------------------------------------------- 77 | BOOL // TRUE: support CPUID instruction, FALSE: not support CPUID instruction 78 | WINAPI IsCpuid(); 79 | 80 | //----------------------------------------------------------------------------- 81 | // IsMsr 82 | //----------------------------------------------------------------------------- 83 | BOOL // TRUE: support MSR(Model-Specific Register), FALSE: not support MSR 84 | WINAPI IsMsr(); 85 | 86 | //----------------------------------------------------------------------------- 87 | // IsTsc 88 | //----------------------------------------------------------------------------- 89 | BOOL // TRUE: support TSC(Time Stamp Counter), FALSE: not support TSC 90 | WINAPI IsTsc(); 91 | 92 | //----------------------------------------------------------------------------- 93 | // Rdmsr 94 | //----------------------------------------------------------------------------- 95 | BOOL // TRUE: success, FALSE: failure 96 | WINAPI Rdmsr( 97 | DWORD index, // MSR index 98 | PDWORD eax, // bit 0-31 99 | PDWORD edx // bit 32-63 100 | ); 101 | 102 | //----------------------------------------------------------------------------- 103 | // RdmsrTx 104 | //----------------------------------------------------------------------------- 105 | BOOL // TRUE: success, FALSE: failure 106 | WINAPI RdmsrTx( 107 | DWORD index, // MSR index 108 | PDWORD eax, // bit 0-31 109 | PDWORD edx, // bit 32-63 110 | DWORD_PTR threadAffinityMask 111 | ); 112 | 113 | //----------------------------------------------------------------------------- 114 | // RdmsrPx 115 | //----------------------------------------------------------------------------- 116 | BOOL // TRUE: success, FALSE: failure 117 | WINAPI RdmsrPx( 118 | DWORD index, // MSR index 119 | PDWORD eax, // bit 0-31 120 | PDWORD edx, // bit 32-63 121 | DWORD_PTR processAffinityMask 122 | ); 123 | 124 | //----------------------------------------------------------------------------- 125 | // Wrmsr 126 | //----------------------------------------------------------------------------- 127 | BOOL // TRUE: success, FALSE: failure 128 | WINAPI Wrmsr( 129 | DWORD index, // MSR index 130 | DWORD eax, // bit 0-31 131 | DWORD edx // bit 32-63 132 | ); 133 | 134 | //----------------------------------------------------------------------------- 135 | // WrmsrTx 136 | //----------------------------------------------------------------------------- 137 | BOOL // TRUE: success, FALSE: failure 138 | WINAPI WrmsrTx( 139 | DWORD index, // MSR index 140 | DWORD eax, // bit 0-31 141 | DWORD edx, // bit 32-63 142 | DWORD_PTR threadAffinityMask 143 | ); 144 | 145 | //----------------------------------------------------------------------------- 146 | // WrmsrPx 147 | //----------------------------------------------------------------------------- 148 | BOOL // TRUE: success, FALSE: failure 149 | WINAPI WrmsrPx( 150 | DWORD index, // MSR index 151 | DWORD eax, // bit 0-31 152 | DWORD edx, // bit 32-63 153 | DWORD_PTR processAffinityMask 154 | ); 155 | 156 | //----------------------------------------------------------------------------- 157 | // Rdpmc 158 | //----------------------------------------------------------------------------- 159 | BOOL // TRUE: success, FALSE: failure 160 | WINAPI Rdpmc( 161 | DWORD index, // PMC index 162 | PDWORD eax, // bit 0-31 163 | PDWORD edx // bit 32-63 164 | ); 165 | 166 | //----------------------------------------------------------------------------- 167 | // RdmsrTx 168 | //----------------------------------------------------------------------------- 169 | BOOL // TRUE: success, FALSE: failure 170 | WINAPI RdpmcTx( 171 | DWORD index, // PMC index 172 | PDWORD eax, // bit 0-31 173 | PDWORD edx, // bit 32-63 174 | DWORD_PTR threadAffinityMask 175 | ); 176 | 177 | //----------------------------------------------------------------------------- 178 | // RdmsrPx 179 | //----------------------------------------------------------------------------- 180 | BOOL // TRUE: success, FALSE: failure 181 | WINAPI RdpmcPx( 182 | DWORD index, // PMC index 183 | PDWORD eax, // bit 0-31 184 | PDWORD edx, // bit 32-63 185 | DWORD_PTR processAffinityMask 186 | ); 187 | 188 | //----------------------------------------------------------------------------- 189 | // Cpuid 190 | //----------------------------------------------------------------------------- 191 | BOOL // TRUE: success, FALSE: failure 192 | WINAPI Cpuid( 193 | DWORD index, // CPUID index 194 | PDWORD eax, 195 | PDWORD ebx, 196 | PDWORD ecx, 197 | PDWORD edx 198 | ); 199 | 200 | //----------------------------------------------------------------------------- 201 | // CpuidTx 202 | //----------------------------------------------------------------------------- 203 | BOOL // TRUE: success, FALSE: failure 204 | WINAPI CpuidTx( 205 | DWORD index, // CPUID index 206 | PDWORD eax, 207 | PDWORD ebx, 208 | PDWORD ecx, 209 | PDWORD edx, 210 | DWORD_PTR threadAffinityMask 211 | ); 212 | 213 | //----------------------------------------------------------------------------- 214 | // CpuidPx 215 | //----------------------------------------------------------------------------- 216 | BOOL // TRUE: success, FALSE: failure 217 | WINAPI CpuidPx( 218 | DWORD index, // CPUID index 219 | PDWORD eax, 220 | PDWORD ebx, 221 | PDWORD ecx, 222 | PDWORD edx, 223 | DWORD_PTR processAffinityMask 224 | ); 225 | 226 | //----------------------------------------------------------------------------- 227 | // Rdtsc 228 | //----------------------------------------------------------------------------- 229 | BOOL // TRUE: success, FALSE: failure 230 | WINAPI Rdtsc( 231 | PDWORD eax, // bit 0-31 232 | PDWORD edx // bit 32-63 233 | ); 234 | 235 | //----------------------------------------------------------------------------- 236 | // RdmsrTx 237 | //----------------------------------------------------------------------------- 238 | BOOL // TRUE: success, FALSE: failure 239 | WINAPI RdtscTx( 240 | PDWORD eax, // bit 0-31 241 | PDWORD edx, // bit 32-63 242 | DWORD_PTR threadAffinityMask 243 | ); 244 | 245 | //----------------------------------------------------------------------------- 246 | // RdmsrPx 247 | //----------------------------------------------------------------------------- 248 | BOOL // TRUE: success, FALSE: failure 249 | WINAPI RdtscPx( 250 | PDWORD eax, // bit 0-31 251 | PDWORD edx, // bit 32-63 252 | DWORD_PTR processAffinityMask 253 | ); 254 | 255 | //----------------------------------------------------------------------------- 256 | // Hlt 257 | //----------------------------------------------------------------------------- 258 | BOOL // TRUE: success, FALSE: failure 259 | WINAPI Hlt(); 260 | 261 | //----------------------------------------------------------------------------- 262 | // HltTx 263 | //----------------------------------------------------------------------------- 264 | BOOL // TRUE: success, FALSE: failure 265 | WINAPI HltTx( 266 | DWORD_PTR threadAffinityMask 267 | ); 268 | 269 | //----------------------------------------------------------------------------- 270 | // HltPx 271 | //----------------------------------------------------------------------------- 272 | BOOL // TRUE: success, FALSE: failure 273 | WINAPI HltPx( 274 | DWORD_PTR processAffinityMask 275 | ); 276 | 277 | /****************************************************************************** 278 | ** 279 | ** I/O 280 | ** 281 | ******************************************************************************/ 282 | 283 | //----------------------------------------------------------------------------- 284 | // ReadIoPortByte 285 | //----------------------------------------------------------------------------- 286 | BYTE // Read Value 287 | WINAPI ReadIoPortByte( 288 | WORD port // I/O port address 289 | ); 290 | 291 | //----------------------------------------------------------------------------- 292 | // ReadIoPortWord 293 | //----------------------------------------------------------------------------- 294 | WORD // Read Value 295 | WINAPI ReadIoPortWord( 296 | WORD port // I/O port address 297 | ); 298 | 299 | //----------------------------------------------------------------------------- 300 | // ReadIoPortDword 301 | //----------------------------------------------------------------------------- 302 | DWORD // Read Value 303 | WINAPI ReadIoPortDword( 304 | WORD port // I/O port address 305 | ); 306 | 307 | //----------------------------------------------------------------------------- 308 | // ReadIoPortByteEx 309 | //----------------------------------------------------------------------------- 310 | BOOL // TRUE: success, FALSE: failure 311 | WINAPI ReadIoPortByteEx( 312 | WORD port, // I/O port address 313 | PBYTE value // Read Value 314 | ); 315 | //----------------------------------------------------------------------------- 316 | // ReadIoPortWordEx 317 | //----------------------------------------------------------------------------- 318 | BOOL // TRUE: success, FALSE: failure 319 | WINAPI ReadIoPortWordEx( 320 | WORD port, // I/O port address 321 | PWORD value // Read Value 322 | ); 323 | //----------------------------------------------------------------------------- 324 | // ReadIoPortDwordEx 325 | //----------------------------------------------------------------------------- 326 | BOOL // TRUE: success, FALSE: failure 327 | WINAPI ReadIoPortDwordEx( 328 | WORD port, // I/O port address 329 | PDWORD value // Read Value 330 | ); 331 | 332 | //----------------------------------------------------------------------------- 333 | // WriteIoPortByte 334 | //----------------------------------------------------------------------------- 335 | VOID 336 | WINAPI WriteIoPortByte( 337 | WORD port, // I/O port address 338 | BYTE value // Write Value 339 | ); 340 | 341 | //----------------------------------------------------------------------------- 342 | // WriteIoPortDword 343 | //----------------------------------------------------------------------------- 344 | VOID 345 | WINAPI WriteIoPortDword( 346 | WORD port, // I/O port address 347 | DWORD value // Write Value 348 | ); 349 | 350 | 351 | //----------------------------------------------------------------------------- 352 | // WriteIoPortWord 353 | //----------------------------------------------------------------------------- 354 | VOID 355 | WINAPI WriteIoPortWord( 356 | WORD port, // I/O port address 357 | WORD value // Write Value 358 | ); 359 | 360 | //----------------------------------------------------------------------------- 361 | // WriteIoPortByteEx 362 | //----------------------------------------------------------------------------- 363 | BOOL // TRUE: success, FALSE: failure 364 | WINAPI WriteIoPortByteEx( 365 | WORD port, // I/O port address 366 | BYTE value // Write Value 367 | ); 368 | 369 | //----------------------------------------------------------------------------- 370 | // WriteIoPortWordEx 371 | //----------------------------------------------------------------------------- 372 | BOOL // TRUE: success, FALSE: failure 373 | WINAPI WriteIoPortWordEx( 374 | WORD port, // I/O port address 375 | WORD value // Write Value 376 | ); 377 | 378 | 379 | //----------------------------------------------------------------------------- 380 | // WriteIoPortDwordEx 381 | //----------------------------------------------------------------------------- 382 | BOOL // TRUE: success, FALSE: failure 383 | WINAPI WriteIoPortDwordEx( 384 | WORD port, // I/O port address 385 | DWORD value // Write Value 386 | ); 387 | 388 | /****************************************************************************** 389 | ** 390 | ** PCI 391 | ** 392 | ******************************************************************************/ 393 | // pciAddress 394 | // 0- 2: Function Number 395 | // 3- 7: Device Number 396 | // 8-15: PCI Bus Number 397 | // 16-31: Reserved 398 | // 0xFFFFFFFF : Error 399 | 400 | //----------------------------------------------------------------------------- 401 | // SetPciMaxBusNo 402 | //----------------------------------------------------------------------------- 403 | VOID 404 | WINAPI SetPciMaxBusIndex( 405 | BYTE max // Max PCI Bus to Scan 406 | ); 407 | 408 | //----------------------------------------------------------------------------- 409 | // ReadPciConfigByte 410 | //----------------------------------------------------------------------------- 411 | BYTE // Read Value 412 | WINAPI ReadPciConfigByte( 413 | DWORD pciAddress, // PCI Device Address 414 | BYTE regAddress // Configuration Address 0-255 415 | ); 416 | 417 | //----------------------------------------------------------------------------- 418 | // ReadPciConfigWord 419 | //----------------------------------------------------------------------------- 420 | WORD // Read Value 421 | WINAPI ReadPciConfigWord( 422 | DWORD pciAddress, // PCI Device Address 423 | BYTE regAddress // Configuration Address 0-255 424 | ); 425 | 426 | //----------------------------------------------------------------------------- 427 | // ReadPciConfigDword 428 | //----------------------------------------------------------------------------- 429 | DWORD // Read Value 430 | WINAPI ReadPciConfigDword( 431 | DWORD pciAddress, // PCI Device Address 432 | BYTE regAddress // Configuration Address 0-255 433 | ); 434 | 435 | //----------------------------------------------------------------------------- 436 | // ReadPciConfigByteEx 437 | //----------------------------------------------------------------------------- 438 | BOOL // TRUE: success, FALSE: failure 439 | WINAPI ReadPciConfigByteEx( 440 | DWORD pciAddress, // PCI Device Address 441 | DWORD regAddress, // Configuration Address 0-whatever 442 | PBYTE value // Read Value 443 | ); 444 | 445 | //----------------------------------------------------------------------------- 446 | // ReadPciConfigWordEx 447 | //----------------------------------------------------------------------------- 448 | BOOL // TRUE: success, FALSE: failure 449 | WINAPI ReadPciConfigWordEx( 450 | DWORD pciAddress, // PCI Device Address 451 | DWORD regAddress, // Configuration Address 0-whatever 452 | PWORD value // Read Value 453 | ); 454 | 455 | //----------------------------------------------------------------------------- 456 | // ReadPciConfigDwordEx 457 | //----------------------------------------------------------------------------- 458 | BOOL // TRUE: success, FALSE: failure 459 | WINAPI ReadPciConfigDwordEx( 460 | DWORD pciAddress, // PCI Device Address 461 | DWORD regAddress, // Configuration Address 0-whatever 462 | PDWORD value // Read Value 463 | ); 464 | 465 | //----------------------------------------------------------------------------- 466 | // WritePciConfigByte 467 | //----------------------------------------------------------------------------- 468 | VOID 469 | WINAPI WritePciConfigByte( 470 | DWORD pciAddress, // PCI Device Address 471 | BYTE regAddress, // Configuration Address 0-255 472 | BYTE value // Write Value 473 | ); 474 | 475 | //----------------------------------------------------------------------------- 476 | // WritePciConfigWord 477 | //----------------------------------------------------------------------------- 478 | VOID 479 | WINAPI WritePciConfigWord( 480 | DWORD pciAddress, // PCI Device Address 481 | BYTE regAddress, // Configuration Address 0-255 482 | WORD value // Write Value 483 | ); 484 | 485 | //----------------------------------------------------------------------------- 486 | // WritePciConfigDword 487 | //----------------------------------------------------------------------------- 488 | VOID 489 | WINAPI WritePciConfigDword( 490 | DWORD pciAddress, // PCI Device Address 491 | BYTE regAddress, // Configuration Address 0-255 492 | DWORD value // Write Value 493 | ); 494 | 495 | //----------------------------------------------------------------------------- 496 | // WritePciConfigByteEx 497 | //----------------------------------------------------------------------------- 498 | BOOL // TRUE: success, FALSE: failure 499 | WINAPI WritePciConfigByteEx( 500 | DWORD pciAddress, // PCI Device Address 501 | DWORD regAddress, // Configuration Address 0-whatever 502 | BYTE value // Write Value 503 | ); 504 | 505 | //----------------------------------------------------------------------------- 506 | // WritePciConfigWordEx 507 | //----------------------------------------------------------------------------- 508 | BOOL // TRUE: success, FALSE: failure 509 | WINAPI WritePciConfigWordEx( 510 | DWORD pciAddress, // PCI Device Address 511 | DWORD regAddress, // Configuration Address 0-whatever 512 | WORD value // Write Value 513 | ); 514 | 515 | //----------------------------------------------------------------------------- 516 | // WritePciConfigDwordEx 517 | //----------------------------------------------------------------------------- 518 | BOOL // TRUE: success, FALSE: failure 519 | WINAPI WritePciConfigDwordEx( 520 | DWORD pciAddress, // PCI Device Address 521 | DWORD regAddress, // Configuration Address 0-whatever 522 | DWORD value // Write Value 523 | ); 524 | 525 | //----------------------------------------------------------------------------- 526 | // FindPciDeviceById 527 | //----------------------------------------------------------------------------- 528 | DWORD // pciAddress, 0xFFFFFFFF: failure 529 | WINAPI FindPciDeviceById( 530 | WORD vendorId, // Vendor ID 531 | WORD deviceId, // Device ID 532 | BYTE index // Index 533 | ); 534 | 535 | //----------------------------------------------------------------------------- 536 | // FindPciDeviceByClass 537 | //----------------------------------------------------------------------------- 538 | DWORD // pciAddress, 0xFFFFFFFF: failure 539 | WINAPI FindPciDeviceByClass( 540 | BYTE baseClass, // Base Class 541 | BYTE subClass, // Sub Class 542 | BYTE programIf, // Program Interface 543 | BYTE index // Index 544 | ); 545 | 546 | /****************************************************************************** 547 | ** 548 | ** Memory (Special API) 549 | ** 550 | ******************************************************************************/ 551 | 552 | #ifdef _PHYSICAL_MEMORY_SUPPORT 553 | //----------------------------------------------------------------------------- 554 | // ReadDmiMemory 555 | //----------------------------------------------------------------------------- 556 | DWORD // Read size(byte), 0: failure 557 | WINAPI ReadDmiMemory( 558 | PBYTE buffer, // Buffer 559 | DWORD count, // Count 560 | DWORD unitSize // Unit Size (BYTE, WORD, DWORD) 561 | ); 562 | 563 | //----------------------------------------------------------------------------- 564 | // ReadPhysicalMemory 565 | //----------------------------------------------------------------------------- 566 | DWORD // Read size(byte), 0: failure 567 | WINAPI ReadPhysicalMemory( 568 | DWORD_PTR address, // Physical Memory Address 569 | PBYTE buffer, // Buffer 570 | DWORD count, // Count 571 | DWORD unitSize // Unit Size (BYTE, WORD, DWORD) 572 | ); 573 | 574 | //----------------------------------------------------------------------------- 575 | // WritePhysicalMemory 576 | //----------------------------------------------------------------------------- 577 | DWORD // Write size(byte), 0: failure 578 | WINAPI WritePhysicalMemory( 579 | DWORD_PTR address, // Physical Memory Address 580 | PBYTE buffer, // Buffer 581 | DWORD count, // Count 582 | DWORD unitSize // Unit Size (BYTE, WORD, DWORD) 583 | ); 584 | #endif 585 | #ifdef __cplusplus 586 | } 587 | #endif /* __cplusplus */ 588 | -------------------------------------------------------------------------------- /.cproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 30 | 31 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 492 | 493 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | 730 | 731 | 732 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 757 | 758 | 759 | 760 | 761 | 762 | 763 | 764 | 765 | 766 | 767 | 768 | 769 | 770 | 771 | 772 | 773 | 774 | 775 | 776 | 777 | 778 | 779 | 780 | 781 | 782 | 783 | 784 | 785 | 786 | 787 | 788 | 789 | 790 | 791 | 792 | 793 | 794 | 795 | 796 | 797 | 798 | 799 | 800 | 801 | 802 | 803 | 804 | 805 | 806 | 807 | 808 | 809 | 810 | 811 | 812 | 813 | 814 | 815 | 816 | 817 | 818 | 819 | 820 | 821 | 822 | 823 | 824 | 825 | 826 | 827 | 828 | 829 | 830 | 831 | 832 | 833 | 834 | 835 | 836 | 837 | 838 | 839 | 840 | 841 | 842 | 843 | 844 | 845 | 846 | 847 | 848 | 849 | 850 | 851 | 852 | 853 | 854 | 855 | 856 | 857 | 858 | 859 | 860 | 861 | 862 | 863 | 864 | 865 | 866 | 867 | 868 | 869 | 870 | 871 | 872 | 873 | 874 | 875 | 876 | 877 | 878 | 879 | 880 | 881 | 882 | 883 | 884 | 885 | 886 | 887 | 888 | 889 | 890 | 891 | 892 | 893 | 894 | 895 | 896 | 897 | 898 | 899 | 900 | 901 | 902 | 903 | 904 | 905 | 906 | 907 | 908 | 909 | 910 | 911 | 912 | 913 | 914 | 915 | 916 | 917 | 918 | 919 | 920 | 921 | 922 | 923 | 924 | 925 | 926 | 927 | 928 | 929 | 930 | 931 | 932 | 933 | 934 | 935 | --------------------------------------------------------------------------------