Still learning the D(ll)

This commit is contained in:
Hane 2023-07-23 22:00:02 +02:00
commit dcf3cd2ac2
2 changed files with 88 additions and 64 deletions

1
buildlib.bat Normal file
View file

@ -0,0 +1 @@
clang++ -D DEBUG src\tmrtsc.hpp -Wall -Wextra -Wpedantic -std=c++11 -g -gcodeview -Wl,-pdb= -L C:\capybara\libclang\x86_64-w64-mingw32\bin -l c++ -l unwind --verbose

View file

@ -1,10 +1,7 @@
//TODO It's threadin' time
#ifdef _WIN64
//TODO mirame esta
#ifndef DEBUG
#define DEBUG
#endif
#define LIB_EXPORT __declspec(dllexport)
#define UNICODE
#define WIN32_LEAN_AND_MEAN
#define _WIN32_WINNT _WIN32_WINNT_WIN10 //0x0A00
@ -14,47 +11,105 @@
#include <winreg.h>
#include <stringapiset.h>
#include <synchapi.h>
#else
#define LIB_EXPORT
#endif
#include <iostream>
#include <cstring>
#include "debug.h"
/*
* #if _WIN64
* extern "C" {)
* #endif
*/
namespace tmr {
#ifdef _WIN64
enum winReturnValues{
enum LIB_EXPORT winReturnValues{
CANT_OPEN_KEY = -1,
CANT_RETRIEVE_KEY_INFO = -2,
CANT_READ_DATA_FROM_VALUE = -3,
CANT_RETRIEVE_FREQUENCY = -4
};
#endif
enum ReturnValues {
enum LIB_EXPORT ReturnValues {
OPERATION_SUCCESSFUL = 0,
INVARIANT_TSC_NOT_AVAILABLE = -1,
INVARIANT_TSC_NOT_SUPPORTED = -1,
UNSUPPORTED_CPU = -2,
CANT_READ_FREQUENCY_FROM_SYSTEM = -3,
ART_NOT_REPORTED = -4
};
class TSCTimer {
class LIB_EXPORT TSCTimer {
private:
static TSCTimer timer;
static char* vendorName;
static int64_t baseFreq = ART_NOT_REPORTED;
char* vendorName;
int64_t baseFreq = ART_NOT_REPORTED;
bool availableRDTSCP;
int64_t art; //reserved
TSCtimer () {
TSCTimer (char* vendorName, int64_t baseFreq) {
this->vendorName = vendorName;
this->baseFreq = baseFreq;
availableRDTSCP = (checkRDTSCP()) ? true : false;
}
~TSCTimer () {
free(vendorName);
}
static bool checkInvariantTSC() {
uint64_t rdx;
asm volatile (".intel_syntax noprefix\t\n" \
"mov eax, 0x80000007\t\n" \
"cpuid\t\n" : "=d" (rdx) );
bool iTSC = rdx & (1<<8);
return iTSC;
}
static char* readVendorName () {
char* palabritas = (char*)malloc(sizeof(char) * 13);
uint8_t siguienteLetra = 0;
uint64_t regs[3];
asm volatile ( ".intel_syntax noprefix\t\n" \
"mov eax, 0x0\t\n" \
"cpuid\t\n" : "=b" (regs[0]), "=c" (regs[2]), "=d" (regs[1]) );
int byte = 0;
for (int reg = 0; reg < 3; reg++, byte = 0){
char* charifiedReg = (char*)&regs[reg];
for(; byte < 4; byte++, siguienteLetra++ ){
palabritas[siguienteLetra] = charifiedReg[byte];
}
}
palabritas[siguienteLetra] = '\0';
return palabritas;
}
static int64_t intelRetrieveART(){
//TODO: Find a valid Intel CPU to debug ART route
//if (freq == nullptr) return -
uint64_t raxde, rbxnum, rcxhz;
asm volatile ( ".intel_syntax noprefix\t\n" \
"mov eax, 0x15\t\n" \
"cpuid\t\n" : "=a" (raxde), "=b" (rbxnum), "=c" (rcxhz) );
log_debugcpp("hmm " << raxde << " " << rbxnum << " " << rcxhz);
if (rbxnum == 0 || rcxhz == 0) return ART_NOT_REPORTED;
int64_t TSCFreq = (rcxhz * rbxnum)/raxde;
//*freq = TSCFreq;
log_debugcpp("raxo " << TSCFreq << " " << TSCFreq);
return TSCFreq;
}
#ifdef _WIN64
int64_t getFreqFromSystem(){
static int64_t getFreqFromSystem(){
//TODO: close opened key
const WORD STRING_SIZE = 4;
const WCHAR COMPARE_TARGET[STRING_SIZE + 1] = L"~MHz";
@ -129,15 +184,6 @@ namespace tmr {
#endif
bool checkInvariantTSC() {
uint64_t rdx;
asm volatile (".intel_syntax noprefix\t\n" \
"mov eax, 0x80000007\t\n" \
"cpuid\t\n" : "=d" (rdx) );
bool iTSC = rdx & (1<<8);
return iTSC;
}
bool checkRDTSCP(){ //Generic
uint64_t rdx;
asm volatile (".intel_syntax noprefix\t\n" \
@ -149,40 +195,6 @@ namespace tmr {
return RDTSCP;
}
char* readVendorName () {
char* palabritas = (char*)malloc(sizeof(char) * 13);
uint8_t siguienteLetra = 0;
uint64_t regs[3];
asm volatile ( ".intel_syntax noprefix\t\n" \
"mov eax, 0x0\t\n" \
"cpuid\t\n" : "=b" (regs[0]), "=c" (regs[2]), "=d" (regs[1]) );
int byte = 0;
for (int reg = 0; reg < 3; reg++, byte = 0){
char* charifiedReg = (char*)&regs[reg];
for(; byte < 4; byte++, siguienteLetra++ ){
palabritas[siguienteLetra] = charifiedReg[byte];
}
}
palabritas[siguienteLetra] = '\0';
return palabritas;
}
int64_t intelCheckART(){
//TODO: Find a valid Intel CPU to debug ART route
//if (freq == nullptr) return -
uint64_t rbxnum, rcxhz;
asm volatile ( ".intel_syntax noprefix\t\n" \
"mov eax, 0x15\t\n" \
"cpuid\t\n" : "=a" (raxde), "=b" (rbxnum), "=c" (rcxhz) );
log_debugcpp("hmm " << raxde << " " << rbxnum << " " << rcxhz);
if (rbxnum == 0 || rcxhz == 0) return ART_NOT_REPORTED;
int64_t TSCFreq = (rcxhz * rbxnum)/raxde;
//*freq = TSCFreq;
log_debugcpp("raxo " << TSCFreq << " " << *freq);
return TSCFreq;
}
uint64_t readRDTSC() {
uint64_t raxlo,rdxho;
asm volatile ( ".intel_syntax noprefix\t\n"
@ -203,13 +215,14 @@ namespace tmr {
public:
static int getTimer(TSCTimer* timer = nullptr) {
if (!checkInvariantTSC) return INVARIANT_TSC_NOT_SUPPORTED;
if (!checkInvariantTSC()) return INVARIANT_TSC_NOT_SUPPORTED;
//TODO debug dis
const char vendorNames[2][13] = {
{"AuthenticAMD\0"},
{"GenuineIntel\0"}
{"AuthenticAMD"},
{"GenuineIntel"}
};
vendorName = readVendorName();
char* vendorName = readVendorName();
int64_t baseFreq;
if (strcmp(vendorName, vendorNames[1]))
baseFreq = intelRetrieveART();
@ -218,7 +231,7 @@ namespace tmr {
if (baseFreq < OPERATION_SUCCESSFUL)
return CANT_READ_FREQUENCY_FROM_SYSTEM;
timer = new TSCTimer();
timer = new TSCTimer(vendorName, baseFreq);
return OPERATION_SUCCESSFUL;
}
@ -229,5 +242,15 @@ namespace tmr {
return readRDTSC();
}
}
uint64_t getBaseFrequency(){
return baseFreq;
}
};
}
/*
* #ifdef _WIN64
* }
* #endif
*/