summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexey Gavrilov <rebovas@yahoo.com>2024-02-22 14:18:39 +0700
committerAlexey Gavrilov <rebovas@yahoo.com>2024-02-22 14:18:39 +0700
commitcbcbf6e7d614ecf94dd7e1b9033f8d599f48662e (patch)
tree59872849d347794cc58c8ad3aa201a14e0db526f
parentc18781e37e6bfe153e7c0f2bc8b04df0aecf151d (diff)
Implement support of cpuid instruction + include folder + some updates
-rw-r--r--arch/x86/cpuinfo/CpuInfo.s21
-rw-r--r--arch/x86/cpuinfo/Cpuinfo.cpp367
-rw-r--r--arch/x86/cpuinfo/Cpuinfo.h364
-rwxr-xr-xarch/x86/gdt/Gdt.cpp17
-rwxr-xr-xarch/x86/gdt/Gdt.h5
-rw-r--r--arch/x86/gdt/GlobalObj.cpp8
-rw-r--r--arch/x86/gdt/GlobalObj.h3
-rw-r--r--arch/x86/inc/TypeConverter.cpp41
-rw-r--r--arch/x86/inc/TypeConverter.h17
-rw-r--r--arch/x86/io/VGADisplay.cpp18
-rw-r--r--arch/x86/io/VGADisplay.h3
-rw-r--r--arch/x86/io/VGADisplayInfo.h2
-rw-r--r--include/TypeConverter.cpp52
-rw-r--r--include/TypeConverter.h22
-rw-r--r--include/types.h (renamed from arch/x86/inc/types.h)2
-rw-r--r--iso/boot/grub/grub.cfg3
-rwxr-xr-xkernel/GlobalConstruct.cpp3
-rw-r--r--kernel/kernel.c11
-rw-r--r--makefile11
19 files changed, 884 insertions, 86 deletions
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 &reg = 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 <types.h>
+
+
+#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 <types.h>
// 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 <types.h>
#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/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 <TypeConverter.h>
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 <types.h>
#define TOBG(attr) attr << 4
diff --git a/include/TypeConverter.cpp b/include/TypeConverter.cpp
new file mode 100644
index 0000000..5ab429d
--- /dev/null
+++ b/include/TypeConverter.cpp
@@ -0,0 +1,52 @@
+#include "TypeConverter.h"
+
+IntConverter::IntConverter()
+{
+ resetProps();
+};
+
+void IntConverter::resetProps()
+{
+ for(int i = 0; i < 21; i++) buffer[i] = '\0';
+ index = bufferSize - 2;
+};
+
+char *IntConverter::intToChar(int n)
+{
+ resetProps();
+
+ int number = n >> 31; // n < 0 - n = -1, else n = 0
+ number = (n ^ number) - number; // Clear sign bit
+
+ bool isNegative = n < 0;
+
+ writeNumberToBuffer(number);
+
+ if(isNegative) buffer[index] = '-';
+
+ return &buffer[index];
+};
+
+char *IntConverter::uintToChar(const uint32 n)
+{
+ resetProps();
+ writeNumberToBuffer(n);
+
+ return &buffer[++index];
+};
+
+char *IntConverter::uintToChar(const uint64 n)
+{
+ resetProps();
+ writeNumberToBuffer(n);
+
+ return &buffer[++index];
+};
+
+void IntConverter::writeNumberToBuffer(uint64 n)
+{
+ do {
+ buffer[index--] = '0' + (n % 10);
+ n /= 10;
+ }while(n != 0);
+};
diff --git a/include/TypeConverter.h b/include/TypeConverter.h
new file mode 100644
index 0000000..f9db95c
--- /dev/null
+++ b/include/TypeConverter.h
@@ -0,0 +1,22 @@
+#ifndef TYPECONVERTER_H
+#define TYPECONVERTER_H
+
+#include <types.h>
+
+class IntConverter
+{
+ private:
+ const static unsigned int bufferSize = 21;
+ char buffer[bufferSize];
+ uint8 index;
+ void resetProps();
+ void writeNumberToBuffer(uint64 n);
+
+ public:
+ IntConverter();
+ char *intToChar(int n);
+ char *uintToChar(const uint32 n);
+ char *uintToChar(const uint64 n);
+};
+
+#endif
diff --git a/arch/x86/inc/types.h b/include/types.h
index 1ec71f3..54dcc25 100644
--- a/arch/x86/inc/types.h
+++ b/include/types.h
@@ -2,6 +2,6 @@
typedef unsigned char uint8;
-typedef unsigned int uint16;
+typedef unsigned short int uint16;
typedef unsigned long uint32;
typedef unsigned long long uint64;
diff --git a/iso/boot/grub/grub.cfg b/iso/boot/grub/grub.cfg
index fd0f925..fbebf70 100644
--- a/iso/boot/grub/grub.cfg
+++ b/iso/boot/grub/grub.cfg
@@ -1,3 +1,4 @@
-menuentry "myos" {
+menuentry "ObjectOS" {
multiboot /os/kernel.bin
+ insmod all_video
}
diff --git a/kernel/GlobalConstruct.cpp b/kernel/GlobalConstruct.cpp
index dc0a83a..b16b6ae 100755
--- a/kernel/GlobalConstruct.cpp
+++ b/kernel/GlobalConstruct.cpp
@@ -7,7 +7,8 @@ void GlobalConstruct::terminalInit()
void GlobalConstruct::gdtInit()
{
- mngGdtInit();
+ mngGdt = MngGdt();
+
mngGdt.addDescriptor(DescSeg32::flatCodeKernel());
mngGdt.addDescriptor(DescSeg32::flatDataKernel());
mngGdt.loadGdt();
diff --git a/kernel/kernel.c b/kernel/kernel.c
index 59caf0a..3d9a3cc 100644
--- a/kernel/kernel.c
+++ b/kernel/kernel.c
@@ -1,13 +1,12 @@
#include "GlobalConstruct.h"
-#include "../arch/x86/io/GlobalObj.h"
-#include "../arch/x86/inc/TypeConverter.h"
+#include <TypeConverter.h>
+#include <types.h>
+
+#include "../arch/x86/cpuinfo/Cpuinfo.h"
void main()
{
GlobalConstruct::terminalInit();
GlobalConstruct::gdtInit();
-
- display << "Hello, World!";
-
+ Cpuinfo cpuinf;
};
-
diff --git a/makefile b/makefile
index ab744ff..c9e0857 100644
--- a/makefile
+++ b/makefile
@@ -2,9 +2,9 @@ CC = i686-elf-g++
LD = ld
ASM = nasm
# test -O2 flag
-CFLAGS = -c -m32 -Wall -ffreestanding -nostdinc -nostdlib -lgcc
+CFLAGS = -c -m32 -Wall -ffreestanding -nostdinc -nostdlib
AFLAGS = -f elf32
-LDFLAGS = -m elf_i386
+LDFLAGS = -m elf_i386 -L$(GCC_PATH) -lgcc
QEMUFLAGS =
CFILES = $(shell find ./ -type f \( -name \*.cpp -o -name \*.c \))
@@ -12,6 +12,7 @@ AFILES = $(shell find ./ -type f \( -iname \*.s -o -name \*.asm \))
LDFILE = $(shell find ./ -type f -name *.ld)
SOURCE_FILES = $(CFILES) $(AFILES)
OBJ_FILES = $(addprefix $(BDIR)/, $(addsuffix .o, $(basename $(SOURCE_FILES))))
+INCLUDE = ./include
ifeq ($(DEBUG), true)
CFLAGS := -g3 $(CFLAGS)
@@ -28,12 +29,12 @@ build: startbuild $(SOURCE_FILES)
echo $(AFLAGS)
echo $(CFLAGS)
@echo "Link object files..."
- $(LD) $(LDFLAGS) -o $(OS_BINARY) -T $(LDFILE) $(OBJ_FILES)
+ $(LD) -o $(OS_BINARY) -T $(LDFILE) $(OBJ_FILES) $(LDFLAGS)
@echo "Project was built"
$(CFILES):
mkdir -p $(BDIR)/$(@D)
- $(CC) $(CFLAGS) -o $(BDIR)/$(addsuffix .o, $(basename $@)) $@
+ $(CC) $(CFLAGS) -I $(INCLUDE) -o $(BDIR)/$(addsuffix .o, $(basename $@)) $@
$(AFILES):
mkdir -p $(BDIR)/$(@D)
@@ -54,6 +55,6 @@ clean:
rm -rf ./iso/os/kernel.bin
run:
- qemu-system-i386 $(QEMUFLAGS) -cdrom ./$(BDIR)/kernel.iso
+ qemu-system-x86_64 $(QEMUFLAGS) -cdrom ./$(BDIR)/kernel.iso
all: clean build install run