From cbcbf6e7d614ecf94dd7e1b9033f8d599f48662e Mon Sep 17 00:00:00 2001 From: Alexey Gavrilov Date: Thu, 22 Feb 2024 14:18:39 +0700 Subject: Implement support of cpuid instruction + include folder + some updates --- arch/x86/cpuinfo/CpuInfo.s | 21 +++ arch/x86/cpuinfo/Cpuinfo.cpp | 367 +++++++++++++++++++++++++++++++++++++++++ arch/x86/cpuinfo/Cpuinfo.h | 364 ++++++++++++++++++++++++++++++++++++++++ arch/x86/gdt/Gdt.cpp | 17 +- arch/x86/gdt/Gdt.h | 5 +- arch/x86/gdt/GlobalObj.cpp | 8 - arch/x86/gdt/GlobalObj.h | 3 +- arch/x86/inc/TypeConverter.cpp | 41 ----- arch/x86/inc/TypeConverter.h | 17 -- arch/x86/inc/types.h | 7 - arch/x86/io/VGADisplay.cpp | 18 ++ arch/x86/io/VGADisplay.h | 3 + arch/x86/io/VGADisplayInfo.h | 2 +- 13 files changed, 794 insertions(+), 79 deletions(-) create mode 100644 arch/x86/cpuinfo/CpuInfo.s create mode 100644 arch/x86/cpuinfo/Cpuinfo.cpp create mode 100644 arch/x86/cpuinfo/Cpuinfo.h delete mode 100644 arch/x86/inc/TypeConverter.cpp delete mode 100644 arch/x86/inc/TypeConverter.h delete mode 100644 arch/x86/inc/types.h (limited to 'arch') diff --git a/arch/x86/cpuinfo/CpuInfo.s b/arch/x86/cpuinfo/CpuInfo.s new file mode 100644 index 0000000..67bc9eb --- /dev/null +++ b/arch/x86/cpuinfo/CpuInfo.s @@ -0,0 +1,21 @@ +global CPUIDCHK:function +CPUIDCHK: + push ebx + pushfd + pop eax + mov ebx, eax + xor eax, 0x200000 + push eax + popfd + pushfd + pop eax + xor eax, ebx + je nocpuid + mov eax, 1 + jmp restore +nocpuid: + mov eax, 0 +restore: + pop ebx + ret +.endchk: diff --git a/arch/x86/cpuinfo/Cpuinfo.cpp b/arch/x86/cpuinfo/Cpuinfo.cpp new file mode 100644 index 0000000..682f68b --- /dev/null +++ b/arch/x86/cpuinfo/Cpuinfo.cpp @@ -0,0 +1,367 @@ +#include "Cpuinfo.h" +#include "../../../kernel/GlobalConstruct.h" + + +inline Cpuinfo::cpuidFunctionIndex operator++(Cpuinfo::cpuidFunctionIndex& command) +{ + command = Cpuinfo::cpuidFunctionIndex(int(command) + 1); + switch(int(command)) + { + case 0x8: command = Cpuinfo::DirectCacheAccessInfo; break; + case 0xC: command = Cpuinfo::ExtendedStateInfo; break; + case 0xE: command = Cpuinfo::RDTMonitoring; break; + case 0x11: command = Cpuinfo::SGXInfo; break; + case 0x13: command = Cpuinfo::TraceInfo; break; + default: + { + uint32 commandInt(command); + if(commandInt > Cpuinfo::SOCInfo + and commandInt < Cpuinfo::UnimplementedStart) + { + command = Cpuinfo::UnimplementedStart; + } + else if(commandInt > Cpuinfo::UnimplementedStart + and commandInt < Cpuinfo::UnimplementedEnd) + { + command = Cpuinfo::UnimplementedEnd; + } + else if(commandInt > Cpuinfo::UnimplementedEnd + and commandInt < Cpuinfo::ExtendedCpuidStart) + { + command = Cpuinfo::ExtendedCpuidStart; + } + else if(commandInt > Cpuinfo::ExtendedCpuidEnd) + { + command = Cpuinfo::BasicInfo; + } + break; + } + }; + + return command; +}; + +Cpuinfo::Cpuinfo() +{ + eax = ebx = ecx = edx = 0; + cpuidAvailable = CPUIDCHK(); + isBrandStringSupported = false; + maximumInputValue = maximumInputValueExtended = 0; + displayModel = displayFamily = stepping = 0; + brandIndex = clflushLineSize = maxNumberApicsIds = initialApicId = 0; + maxNumberProcessorsIds = 0; + currentCpuType = processorType::NotRead; + serialNumber = 0; + + // Write memset!!! + // memset(internalInfoDescriptors, 0, sizeof(uint8) * amountDescriptors) + + // Rewrite it! Create method memset() + for(uint8 i = 0; i < vendorStringSize; i++) vendorString[i] = '\0'; + for(uint8 i = 0; i < brandStringSize; i++) brandString[i] = '\0'; + + dataFilling(Cpuinfo::BasicInfo, Cpuinfo::ExtendedCpuidEnd); +}; + +bool Cpuinfo::isEaxValueCorrect(const cpuidFunctionIndex eaxInitValue) +{ + if(!cpuidAvailable) return false; + + else if(eaxInitValue > maximumInputValue + and eaxInitValue < ExtendedCpuidStart) return false; + + else if(eaxInitValue > maximumInputValueExtended + and eaxInitValue > ExtendedCpuidStart) return false; + + else if(eaxInitValue == 0x8 + or eaxInitValue == 0xC + or eaxInitValue == 0xE + or eaxInitValue == 0x11 + or eaxInitValue == 0x13) return false; + + else return true; +}; + +void Cpuinfo::setBasicData() +{ + maximumInputValue = eax; + + uint32 vendorStringInt[3] = {ebx, edx, ecx}; + + // Rewrite it! Create method memcpy() + for(int i = 0; i < 3; i++) + { + uint8 upperCharIndex = i * 4 + 3; + vendorString[upperCharIndex--] = vendorStringInt[i] >> 24; + vendorString[upperCharIndex--] = vendorStringInt[i] >> 16; + vendorString[upperCharIndex--] = vendorStringInt[i] >> 8; + vendorString[upperCharIndex--] = vendorStringInt[i]; + } +}; + +void Cpuinfo::setVersionData() +{ + uint8 steppingId, modelId, familyId, modelIdExt, familyIdExt; + + steppingId = eax & 0xf; + modelId = (eax >> 4) & 0xf; + familyId = (eax >> 8) & 0xf; + modelIdExt = (eax >> 16) & 0xf; + familyIdExt = (eax >> 20) & 0xf; + + stepping = steppingId; + currentCpuType = (processorType)((eax >> 12) & 0x3); + + if(familyId != 0xf) + { + displayFamily = familyId; + } + else displayFamily = familyIdExt + familyId; + + if(familyId == 0x6 or familyId == 0xf) + { + displayModel = (modelIdExt << 4) + modelId; + } + else displayModel = modelId; + + brandIndex = (uint8)ebx; + clflushLineSize = ((uint8)(ebx >> 8)) << 3; + maxNumberProcessorsIds = (ebx >> 16) & 0x0F; + initialApicId = ebx >> 24; + + if(edx & Cpuinfo::HTT) + { + uint8 powerOfTwo = 1; + for(; powerOfTwo < maxNumberProcessorsIds; powerOfTwo *= 2); + if(maxNumberProcessorsIds == NULL) maxNumberApicsIds = NULL; + else maxNumberApicsIds = powerOfTwo; + } +}; + +void Cpuinfo::setInternalData() +{ + uint32 regs[4] = {eax, ebx, ecx, edx}; + uint8 idxDesc = 0; + + for(uint8 idx = 0; idx < 4; idx++) + { + uint32 ® = regs[idx]; + for(uint8 bytes = 0; bytes < 4; bytes++) + { + internalInfoDescriptors[idxDesc++] = reg & 0xff; + reg >>= 8; + } + } +}; + +void Cpuinfo::setSerialData() +{ + if(cpuid(VersionInfo) + || !(edx & Cpuinfo::PSN) + || cpuid(SerialNumberInfo)) return; + + serialNumber = ((uint64)ecx) | (((uint64)edx) << 32); +}; + +void Cpuinfo::setExtendedBasicData() +{ + if(eax & Cpuinfo::ExtendedBasicInfo) + { + maximumInputValueExtended = eax; + isBrandStringSupported = true; + } + else isBrandStringSupported = false; +}; + +void Cpuinfo::setBrandString(brandStringPart part) +{ + if((part == Cpuinfo::brandString_low or + part == Cpuinfo::brandString_middle or + part == Cpuinfo::brandString_hight) + and isBrandStringSupported) + { + uint8 partUint = uint8(part); + uint32 regs[4] = {eax, ebx, ecx, edx}; + + // memCpy()!!! + for(uint8 regIndex = 0; regIndex < 4; regIndex++) + { + uint32 reg = regs[regIndex]; + for(uint8 bytesInRegister = 0; bytesInRegister < 4; bytesInRegister++) + { + brandString[partUint++] = reg; + reg >>= 8; + } + } + } +}; + +bool Cpuinfo::decodeCpuidResult(const cpuidFunctionIndex eaxValue) +{ + switch(eaxValue) + { + case Cpuinfo::BasicInfo: setBasicData(); break; + case Cpuinfo::VersionInfo: setVersionData(); break; + case Cpuinfo::InternalInfo: setInternalData(); break; + case Cpuinfo::SerialNumberInfo: setSerialData(); break; + case Cpuinfo::MonitorMwaitInfo: break; + case Cpuinfo::ThermalPowerInfo: break; + case Cpuinfo::DirectCacheAccessInfo: break; + case Cpuinfo::PerformanceMonitoring: break; + case Cpuinfo::ClockInfo: break; + case Cpuinfo::FrequencyInfo: break; + case Cpuinfo::ExtendedBasicInfo: setExtendedBasicData(); break; + case Cpuinfo::MoreFeatureInfo: break; + case Cpuinfo::BrandStringLow: setBrandString(brandString_low); break; + case Cpuinfo::BrandStringMiddle: setBrandString(brandString_middle); break; + case Cpuinfo::BrandStringHight: setBrandString(brandString_hight); break; + case Cpuinfo::CacheInfo: break; + case Cpuinfo::MiscFeatureInfo: break; + case Cpuinfo::AddressSize: break; + default: return true; break; + }; + + return false; +}; + +bool Cpuinfo::decodeCpuidCommand(const cpuidFunctionIndex eaxValue) +{ + if(cpuid(eaxValue)) + { + return true; + } + else + { + return decodeCpuidResult(eaxValue); + } +}; + +bool Cpuinfo::cpuid(const cpuidFunctionIndex eaxValue) +{ + // Clear registers + eax = ebx = ecx = edx = 0; + + if(!isEaxValueCorrect(eaxValue) + or isCommandSupportSubLeaf(eaxValue)) return true; + + asm("movl %[eaxValue], %%eax\n\t" + "movl %0, %%eax\n\t" + "cpuid\n\t" + "movl %%eax, %0\n\t" + "movl %%ebx, %1\n\t" + "movl %%ecx, %2\n\t" + "movl %%edx, %3\n\t" + : "=r" (eax), "=r" (ebx), "=r" (ecx), "=r" (edx) + : [eaxValue] "r" (eaxValue)); + + return false; +}; + +bool Cpuinfo::cpuid(const cpuidFunctionIndex eaxValue, uint32 ecxValue) +{ + // Clear registers + eax = ebx = ecx = edx = 0; + + if(!isEaxValueCorrect(eaxValue) + or !isCommandSupportSubLeaf(eaxValue)) return true; + + asm("movl %[eaxValue], %%eax\n\t" + "movl %[ecxValue], %%ecx\n\t" + "cpuid\n\t" + "movl %%eax, %0\n\t" + "movl %%ebx, %1\n\t" + "movl %%ecx, %2\n\t" + "movl %%edx, %3\n\t" + : "=r" (eax), "=r" (ebx), "=r" (ecx), "=r" (edx) + : [eaxValue] "r" (eaxValue), [ecxValue] "r" (ecxValue)); + + return false; +}; + +bool Cpuinfo::isCommandSupportSubLeaf(const cpuidFunctionIndex eaxValue) +{ + switch(eaxValue) + { + case DeterministicCacheInfo: return true; break; + case FeatureInfo: return true; break; + case ExtendedTopologyInfo: return true; break; + case ExtendedStateInfo: return true; break; + case RDTMonitoring: return true; break; + case AllocationInfo: return true; break; + case SGXInfo: return true; break; + case TraceInfo: return true; break; + case SOCInfo: return true; break; + default: return false; break; + }; +}; + +const char* Cpuinfo::getVendorString() +{ + const char* vendorStringInvalid = "VendorStringInvalid"; + + if(maximumInputValue != NULL) return (const char *)vendorString; + else return vendorStringInvalid; +}; + +void Cpuinfo::dataFilling(cpuidFunctionIndex startValue, + cpuidFunctionIndex endValue) +{ + cpuidFunctionIndex command = startValue; + uint32 ecx = 0; + + do{ + if(isEaxValueCorrect(command)) + { + if(isCommandSupportSubLeaf(command)) + { + cpuid(command, ecx); + } + else decodeCpuidCommand(command); + } + }while(++command <= endValue and command != Cpuinfo::BasicInfo); +}; + +cpuidOutputRegisters Cpuinfo::getRegs() +{ + return {eax, ebx, ecx, edx}; +}; + +uint8 Cpuinfo::getDisplayFamily() +{ + return displayFamily; +}; + +uint8 Cpuinfo::getDisplayModel() +{ + return displayModel; +}; + +uint8 Cpuinfo::getStepping() +{ + return stepping; +}; + +Cpuinfo::processorType Cpuinfo::getProcessorType() +{ + return currentCpuType; +}; + +uint8 Cpuinfo::getMaxFunctionIndex() +{ + return maximumInputValue; +}; + +uint32 Cpuinfo::getMaxFunctionIndexExtended() +{ + return maximumInputValueExtended; +}; + +uint8* Cpuinfo::getBrandString() +{ + return brandString; +}; + +uint8* Cpuinfo::getInternalDescriptors() +{ + return internalInfoDescriptors; +}; diff --git a/arch/x86/cpuinfo/Cpuinfo.h b/arch/x86/cpuinfo/Cpuinfo.h new file mode 100644 index 0000000..4baa76f --- /dev/null +++ b/arch/x86/cpuinfo/Cpuinfo.h @@ -0,0 +1,364 @@ +#ifndef CPUID_H +#define CPUID_H +#include + + +#ifdef __cplusplus +extern "C" { +#endif +extern bool CPUIDCHK(); +#ifdef __cplusplus +}; +#endif + +struct cpuidOutputRegisters +{ + uint32 eax; + uint32 ebx; + uint32 ecx; + uint32 edx; +}; + +/* Some updates: +// 1. Add ability to initialize all variables +// who depend on initial eax value in construction +*/ + +class Cpuinfo +{ + public: + // Initial value passed to eax register + enum cpuidFunctionIndex + { + BasicInfo = 0, + VersionInfo = 0x1, + InternalInfo = 0x2, + SerialNumberInfo = 0x3, + DeterministicCacheInfo = 0x4, + MonitorMwaitInfo = 0x5, + ThermalPowerInfo = 0x6, + FeatureInfo = 0x7, + DirectCacheAccessInfo = 0x9, + PerformanceMonitoring = 0xA, + ExtendedTopologyInfo = 0xB, + ExtendedStateInfo = 0xD, + RDTMonitoring = 0xF, + AllocationInfo = 0x10, + SGXInfo = 0x12, + TraceInfo = 0x14, + ClockInfo = 0x15, + FrequencyInfo = 0x16, + SOCInfo = 0x17, + UnimplementedStart = 0x40000000, + UnimplementedEnd = 0x4FFFFFFF, + ExtendedCpuidStart = 0x80000000, + ExtendedBasicInfo = 0x80000000, + MoreFeatureInfo = 0x80000001, + BrandStringLow = 0x80000002, + BrandStringMiddle = 0x80000003, + BrandStringHight = 0x80000004, + NotInfo = 0x80000005, + CacheInfo = 0x80000006, + MiscFeatureInfo = 0x80000007, + AddressSize = 0x80000008, + ExtendedCpuidEnd = 0x80000008, + }; + + enum processorType + { + OriginalOEM = 0, + IntelOneDrive = 1, + Dual = 2, + Reserved = 3, + NotRead = 0xf + }; + + enum featureInformationEcx + { + SSE3 = 1, + PCLMULDQDQ = 1 << 1, + DTES64 = 1 << 2, + MONITOR = 1 << 3, + DS_CPL = 1 << 4, + VMX = 1 << 5, + SMX = 1 << 6, + EIST = 1 << 7, + TM2 = 1 << 8, + SSSE3 = 1 << 9, + CNXT_ID = 1 << 10, + SDBG = 1 << 11, + FMA = 1 << 12, + CMPXCHG16B = 1 << 13, + xTPRUpdateControl = 1 << 14, + PDCM = 1 << 15, + PCID = 1 << 17, + DCA = 1 << 18, + SSE4_1 = 1 << 19, + SSE4_2 = 1 << 20, + x2APIC = 1 << 21, + MOVBE = 1 << 22, + POPCNT = 1 << 23, + TSC_Deadline = 1 << 24, + AESNI = 1 << 25, + XSAVE = 1 << 26, + OSXSAVE = 1 << 27, + AVX = 1 << 28, + F16C = 1 << 29, + RDRAND = 1 << 30 + }; + + enum featureInformationEdx + { + FPU = 1, + VME = 1 << 1, + DE = 1 << 2, + PSE = 1 << 3, + TSC = 1 << 4, + MSR = 1 << 5, + PAE = 1 << 6, + MCE = 1 << 7, + CX8 = 1 << 8, + APIC = 1 << 9, + SEP = 1 << 11, + MTRR = 1 << 12, + PGE = 1 << 13, + MCA = 1 << 14, + CMOV = 1 << 15, + PAT = 1 << 16, + PSE_36 = 1 << 17, + PSN = 1 << 18, + CLFSH = 1 << 19, + DS = 1 << 21, + ACPI = 1 << 22, + MMX = 1 << 23, + FXSR = 1 << 24, + SSE = 1 << 25, + SSE2 = 1 << 26, + SS = 1 << 27, + HTT = 1 << 28, + TM = 1 << 29, + PBE = 1 << 31 + }; + + enum generalDescriptors + { + NullDescriptor = 0, + NotreportInformation = 0xFF + }; + + enum TlbDescriptors + { + // TLB + type _ page size _ associative _ amount entries _ array (not necessary) + TLBI_4Kb_4WSA_32E = 0x1, + TLBI_4Mb_fullyA_32E = 0x2, + TLBD_4Kb_4WSA_64E = 0x3, + TLBD_4Mb_4WSA_8E = 0x4, + TLBD_4Mb_4WSA_32E = 0x5, + TLBI_4Mb_4WSA_4E = 0xB, + TLBI_4Kb_32E = 0x4F, + TLBI_4Kb2Mb_64E = 0x50, + TLBI_4Mb_64E = 0x50, + TLBI_4Kb2Mb_128E = 0x51, + TLBI_4Mb_128E = 0x51, + TLBI_4Kb2Mb_256E = 0x52, + TLBI_4Mb_256E = 0x52, + TLBI_2Mb_fully_7E = 0x55, + TLBI_4Mb_fully_7E = 0x55, + TLB0D_4Mb_4WSA_16E = 0x56, + TLB0D_4Kb_4WA_16E = 0x57, + TLB0D_4Kb_fully_16E = 0x59, + TLB0D_2Mb_4WSA_32E = 0x5A, + TLB0D_4Mb_4WSA_32E = 0x5A, + TLBD_4Kb4Mb_64E = 0x5B, + TLBD_4Kb4Mb_128E = 0x5C, + TLBD_4Kb4Mb_256E = 0x5D, + TLBI_4Kb_fully_48E = 0x61, + TLBD_2Mb_4WSA_32E_1GbArray4E = 0x63, + TLBD_4Mb_4WSA_32E_1GbArray4E = 0x63, + TLBD_4Kb_4WSA_512E = 0x64, + TLBI_2Mb_fully_8E = 0x76, + TLBI_4Mb_fully_8E = 0x76, + DTLB_4Kb_fully_32E = 0xA0, + TLBI_4Kb_4WSA_128E = 0xB0, + TLBI_2Mb_4WA_8E = 0xB1, + TLBI_4Mb_4WA_4E = 0xB1, + TLBI_4Kb_4WSA_64E = 0xB2, + TLBD_4Kb_4WSA_128E = 0xB3, + TLB1D_4Kb_4WSA_256E = 0xB4, + TLBI_4Kb_8WSA_64E = 0xB5, + TLBI_4Kb_8WSA_128E = 0xB6, + TLBD_4Kb_4WA_64E = 0xBA, + TLBD_4Kb4Mb_4WA_8E = 0xC0, + STLB_4Kb_8WA_1024 = 0xC1, + STLB_2Mb_8WA_1024 = 0xC1, + DTLB_4Kb_4WA_16E = 0xC2, + DTLB_2Mb_4WA_16E = 0xC2, + STLB_4Kb_6WA_1536E = 0xC3, + STLB_2Mb_6WA_1536E = 0xC3, + STLB_1Gb_4WA_16E = 0xC3, + DTLB_2Mb_4WA_32E = 0xC4, + DTLB_4Mb_4WA_32E = 0xC4, + STLB_4Kb_4WA_512E = 0xCA + }; + + enum CacheDescriptors + { + // CACHE _ lvl + type (if 1 lvl) _ size _ associative ways _ line size in bytes + CACHE_1lvlI_8Kb_4w_32b = 0x06, + CACHE_1lvlI_16Kb_4w_32b = 0x08, + CACHE_1lvlI_32Kb_4w_64b = 0x09, + CACHE_1lvlD_8Kb_2w_32b = 0x0A, + CACHE_1lvlD_16Kb_4w_32b = 0x0C, + CACHE_1lvlD_16Kb_4w_64b = 0x0D, + CACHE_1lvlD_24Kb_6w_64b = 0x0E, + CACHE_2lvl_128Kb_2w_64b = 0x1D, + CACHE_2lvl_256Kb_8w_64b = 0x21, + CACHE_3lvl_512_4w_64b_2lines = 0x22, + CACHE_3lvl_1Mb_8w_64b_2lines = 0x23, + CACHE_2lvl_1Mb_16w_64b = 0x24, + CACHE_3lvl_2Mb_8w_64b_2lines = 0x25, + CACHE_3lvl_4Mb_8w_64b_2lines = 0x29, + CACHE_1lvlD_32Kb_8w_64b = 0x2C, + CACHE_1lvlI_32Kb_8w_64b = 0x30, + CACHE_No2lvl_or_No3lvl = 0x40, + CACHE_2lvl_128Kb_4w_32b = 0x41, + CACHE_2lvl_256Kb_4w_32b = 0x42, + CACHE_2lvl_512Kb_4w_32b = 0x43, + CACHE_2lvl_1Mb_4w_32b = 0x44, + CACHE_2lvl_2Mb_4w_32b = 0x45, + CACHE_3lvl_4Mb_4w_64b = 0x46, + CACHE_3lvl_8Mb_8w_64b = 0x47, + CACHE_2lvl_3Mb_12w_64b = 0x48, + CACHE_3lvl_4Mb_16w_64b = 0x49, + CACHE_2lvl_4Mb_16w_64b = 0x49, + CACHE_3lvl_6Mb_12w_64b = 0x4A, + CACHE_3lvl_8Mb_16w_64b = 0x4B, + CACHE_3lvl_12Mb_12w_64b = 0x4C, + CACHE_3lvl_16Mb_16w_64b = 0x4D, + CACHE_2lvl_6Mb_24w_64b = 0x4E, + CACHE_1lvlD_16Kb_8w_64b = 0x60, + CACHE_1lvlD_8Kb_4w_64b = 0x66, + CACHE_1lvlD_16Kb_4w_64b_Repeat = 0x67, + CACHE_1lvlD_32Kb_4w_64b = 0x68, + CACHE_uTLB_4Kb_8w_64E = 0x6A, + CACHE_DTLB_4Kb_8w_256E = 0x6B, + CACHE_DTLB_2Mb_8w_128E = 0x6C, + CACHE_DTLB_4Mb_8w_128E = 0x6C, + CACHE_DTLB_1Gb_fully_16E = 0x6D, + CACHE_Trace_12K_8w = 0x70, + CACHE_Trace_16K_8w = 0x71, + CACHE_Trace_32K_8w = 0x72, + CACHE_2lvl_1Mb_4w_64b = 0x78, + CACHE_2lvl_128Kb_8w_64b_2lines = 0x79, + CACHE_2lvl_256Kb_8w_64b_2lines = 0x7A, + CACHE_2lvl_512Kb_8w_64b_2lines = 0x7B, + CACHE_2lvl_1Mb_8w_64b_2lines = 0x7C, + CACHE_2lvl_2Mb_8w_64b = 0x7D, + CACHE_2lvl_512Kb_2w_64b = 0x7F, + CACHE_2lvl_512Kb_8w_64b = 0x80, + CACHE_2lvl_256Kb_8w_32b = 0x82, + CACHE_2lvl_512Kb_8w_32b = 0x83, + CACHE_2lvl_1Mb_8w_32b = 0x84, + CACHE_2lvl_2Mb_8w_32b = 0x85, + CACHE_2lvl_512Kb_4w_64b = 0x86, + CACHE_2lvl_1Mb_8w_64b = 0x87, + CACHE_3lvl_512Kb_4w_64b = 0xD0, + CACHE_3lvl_1Mb_4w_64b = 0xD1, + CACHE_3lvl_2Mb_4w_64b = 0xD2, + CACHE_3lvl_1Mb_8w_64b = 0xD6, + CACHE_3lvl_2Mb_8w_64b = 0xD7, + CACHE_3lvl_4Mb_8w_64b = 0xD8, + CACHE_3lvl_1536Kb_12w_64b = 0xDC, + CACHE_3lvl_3Mb_12w_64b = 0xDD, + CACHE_3lvl_6Mb_12w_64b_Repeat = 0xDE, + CACHE_3lvl_2Mb_16w_64b = 0xE2, + CACHE_3lvl_4Mb_16w_64b_Repeat = 0xE3, + CACHE_3lvl_8Mb_16w_64b_Repeat = 0xE4, + CACHE_3lvl_12Mb_24w_64b = 0xEA, + CACHE_3lvl_18Mb_24w_64b = 0xEB, + CACHE_3lvl_24Mb_24w_64b = 0xEC + }; + + enum PrefetchDescriptors + { + PREFETCH_64 = 0xF0, + PREFETCH_128 = 0xF1 + }; + + enum brandStringPart + { + brandString_low = 0, + brandString_middle = 16, + brandString_hight = 32 + }; + + public: + const static uint8 amountBytesRegisters = 16; + const static uint8 amountDescriptors = 16; + // 12 ASCII-symbols + null symbol + const constexpr static uint8 vendorStringSize = 12 + 1; + const constexpr static uint8 brandStringSize = (3 * 4 * 4) + 1; + // Optional + const static uint8 amountRegisters = 4; + const static uint8 amountBytesInRegister = 4; + + private: + + bool cpuidAvailable; + // Saved data of cpuid for eax = 0 + char vendorString[vendorStringSize]; + uint8 maximumInputValue; + // The result of using the method cpuid last time + uint32 eax, ebx, ecx, edx; + // Saved data of cpuid for eax = 1 + uint8 displayFamily, displayModel, stepping, brandIndex; + // clflushLineSize - cache line size in bytes, max number variables for logical processors + uint8 maxNumberProcessorsIds, maxNumberApicsIds, initialApicId; + uint16 clflushLineSize; + processorType currentCpuType; + // Saved data of cpuid eax = 2 + uint8 internalInfoDescriptors[amountBytesRegisters]; + // Saved data of cpuid eax = 3 + uint64 serialNumber; + // Saved data for processor brand string function + uint8 brandString[brandStringSize]; + // Saved daata for extended basic data function + bool isBrandStringSupported; + uint32 maximumInputValueExtended; + + // If eax value correct - true, else false + bool isEaxValueCorrect(const cpuidFunctionIndex eaxValue); + // Decode and set local properties after cpuid command + // False result if cpuid result successfully decode, otherwise true + bool decodeCpuidResult(const cpuidFunctionIndex eaxValue); + // Cpuid command with decode result + bool decodeCpuidCommand(const cpuidFunctionIndex eaxValue); + // Below methods read data from registers and set some properties + void setBasicData(); + void setVersionData(); + void setSerialData(); + void setInternalData(); + void setExtendedBasicData(); + void setBrandString(brandStringPart part); + + void dataFilling(cpuidFunctionIndex startValue, + cpuidFunctionIndex endValue); + + public: + Cpuinfo(); + // false - if value in eax correct, else true + bool cpuid(const cpuidFunctionIndex eaxValue); + bool cpuid(const cpuidFunctionIndex eaxValue, uint32 ecxValue); + bool isCommandSupportSubLeaf(const cpuidFunctionIndex eaxValue); + cpuidOutputRegisters getRegs(); + const char* getVendorString(); + processorType getProcessorType(); + uint8 getDisplayFamily(); + uint8 getDisplayModel(); + uint8 getStepping(); + uint8 getMaxFunctionIndex(); + uint32 getMaxFunctionIndexExtended(); + uint8* getBrandString(); + uint8* getInternalDescriptors(); +}; +#endif diff --git a/arch/x86/gdt/Gdt.cpp b/arch/x86/gdt/Gdt.cpp index 63c70ef..88c7bbd 100755 --- a/arch/x86/gdt/Gdt.cpp +++ b/arch/x86/gdt/Gdt.cpp @@ -57,7 +57,7 @@ uint64 DescSeg32::flatDataUser() MngGdt::MngGdt() { - this->gdt[0] = 0; + gdt[0] = 0; currIdx = 1; isGdtLoaded = 0; }; @@ -82,7 +82,7 @@ bool MngGdt::loadGdt() uint64 pointer = 0; uint16 size = sizeof(uint64) * this->size - 1; - uint16 offset = (uint32)((void *)(&gdt)); + uint32 offset = (uint32)((void *)(&gdt)); pointer |= offset; pointer <<= 16; @@ -98,3 +98,16 @@ bool MngGdt::getIsGdtLoaded() { return isGdtLoaded; }; + +void MngGdt::operator=(const MngGdt& src) +{ + if(this->isGdtLoaded == 1 || src.isGdtLoaded == 1) + { + return; + } + + // Fix it. Write method to copy from ... to ... + for(int i = 0; i < this->size; i++) this->gdt[i] = src.gdt[i]; + this->isGdtLoaded = src.isGdtLoaded; + this->currIdx = src.currIdx; +}; diff --git a/arch/x86/gdt/Gdt.h b/arch/x86/gdt/Gdt.h index e3d48a3..a8d7dc2 100755 --- a/arch/x86/gdt/Gdt.h +++ b/arch/x86/gdt/Gdt.h @@ -1,7 +1,7 @@ #ifndef GDT_H #define GDT_H -#include "../inc/types.h" +#include // Define access options @@ -54,7 +54,7 @@ class DescSeg32 // Segment descriptor static uint64 flatDataKernel(); static uint64 flatCodeUser(); static uint64 flatDataUser(); -} __attribute__((packed)); +}; #ifdef __cplusplus extern "C" { @@ -74,6 +74,7 @@ class MngGdt public: MngGdt(); + void operator=(const MngGdt& src); bool addDescriptor(uint64 desc); // 0 - not set descriptor, 1 - set bool loadGdt(); // 0 - if GDT is not loaded, 1 - loaded bool getIsGdtLoaded(); diff --git a/arch/x86/gdt/GlobalObj.cpp b/arch/x86/gdt/GlobalObj.cpp index 5832c11..fbceeef 100644 --- a/arch/x86/gdt/GlobalObj.cpp +++ b/arch/x86/gdt/GlobalObj.cpp @@ -4,11 +4,3 @@ uint64 MngGdt::gdt[MngGdt::size]; MngGdt mngGdt; - -void mngGdtInit() -{ - if(!mngGdt.getIsGdtLoaded()) - { - mngGdt = MngGdt(); - } -}; diff --git a/arch/x86/gdt/GlobalObj.h b/arch/x86/gdt/GlobalObj.h index 563a2a9..3c62847 100644 --- a/arch/x86/gdt/GlobalObj.h +++ b/arch/x86/gdt/GlobalObj.h @@ -1,6 +1,7 @@ #ifndef GDTGLOBALOBJ_H #define GDTGLOBALOBJ_H -#include "../inc/types.h" + +#include #include "Gdt.h" extern MngGdt mngGdt; diff --git a/arch/x86/inc/TypeConverter.cpp b/arch/x86/inc/TypeConverter.cpp deleted file mode 100644 index 23119a2..0000000 --- a/arch/x86/inc/TypeConverter.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include "TypeConverter.h" - -void IntConverter::clearBuff() -{ - for(int i = 0; i < 21; i++) buffer[i] = '\0'; -}; - -char *IntConverter::intToChar(int n) -{ - clearBuff(); - - int number = n >> 31; // n < 0 - n = -1, else n = 0 - number = (n ^ number) - number; // Clear sign bit - - bool isNegative = n < 0; - unsigned int indx = 19; - - do { - buffer[indx--] = 48 + (number % 10); - number /= 10; - }while(number != 0); - - if(isNegative) buffer[indx--] = '-'; - - return &buffer[++indx]; -}; - -char *IntConverter::uintToChar(unsigned int n) -{ - clearBuff(); - - unsigned int number = n; - unsigned int indx = 19; - - do { - buffer[indx--] = 48 + (number % 10); - number /= 10; - }while(number != 0); - - return &buffer[++indx]; -}; diff --git a/arch/x86/inc/TypeConverter.h b/arch/x86/inc/TypeConverter.h deleted file mode 100644 index 93d2c8c..0000000 --- a/arch/x86/inc/TypeConverter.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef TYPECONVERTER_H -#define TYPECONVERTER_H - -#include "../io/VGADisplay.h" - -class IntConverter -{ - private: - char buffer[21]; - void clearBuff(); - - public: - char *intToChar(int n); - char *uintToChar(unsigned int n); -}; - -#endif diff --git a/arch/x86/inc/types.h b/arch/x86/inc/types.h deleted file mode 100644 index 1ec71f3..0000000 --- a/arch/x86/inc/types.h +++ /dev/null @@ -1,7 +0,0 @@ -#define NULL 0 - - -typedef unsigned char uint8; -typedef unsigned int uint16; -typedef unsigned long uint32; -typedef unsigned long long uint64; diff --git a/arch/x86/io/VGADisplay.cpp b/arch/x86/io/VGADisplay.cpp index b74858b..0cd0bed 100644 --- a/arch/x86/io/VGADisplay.cpp +++ b/arch/x86/io/VGADisplay.cpp @@ -23,6 +23,24 @@ VGADisplay& VGADisplay::operator<<(const char &c) return *this; }; +VGADisplay& VGADisplay::operator<<(const uint32 number) +{ + IntConverter conv; + + (*this) << conv.uintToChar(number); + + return *this; +}; + +VGADisplay& VGADisplay::operator<<(const uint64 number) +{ + IntConverter conv; + + (*this) << conv.uintToChar(number); + + return *this; +}; + VGADisplay& VGADisplay::operator++(int) { if(++xCurr == VGADisplayInfo::width) diff --git a/arch/x86/io/VGADisplay.h b/arch/x86/io/VGADisplay.h index 67f28b3..db4c4df 100644 --- a/arch/x86/io/VGADisplay.h +++ b/arch/x86/io/VGADisplay.h @@ -2,6 +2,7 @@ #define VGAGRAPHICS_H #include "VGADisplayInfo.h" +#include typedef unsigned short dchar; @@ -27,6 +28,8 @@ class VGADisplay VGADisplay(uint16 x, uint16 y); VGADisplay& operator<<(const char &c); VGADisplay& operator<<(const char *c); + VGADisplay& operator<<(const uint32 number); + VGADisplay& operator<<(const uint64 number); VGADisplay& operator++(int); void setShift(bool status); void setColor(char colorAttr); diff --git a/arch/x86/io/VGADisplayInfo.h b/arch/x86/io/VGADisplayInfo.h index 33235cc..875e7e5 100644 --- a/arch/x86/io/VGADisplayInfo.h +++ b/arch/x86/io/VGADisplayInfo.h @@ -1,7 +1,7 @@ #ifndef VGAINFOCLASS_H #define VGAINFOCLASS_H -#include "../inc/types.h" +#include #define TOBG(attr) attr << 4 -- cgit v1.2.3