From 3678f5d1970feea92f787928ceb9f53ed0b4c1e2 Mon Sep 17 00:00:00 2001 From: Alexey Gavrilov Date: Tue, 19 Mar 2024 16:44:56 +0700 Subject: Implementation acpi tables through structs --- arch/x86/cpuinfo/Cpuinfo.cpp | 1 - drivers/acpi/acpi.cpp | 71 ++++++++++++++++++++++++++++++ drivers/acpi/acpi.h | 101 +++++++++++++++++++++++++++++++++++++++++++ drivers/acpi/acpi.h.gch | Bin 0 -> 1675700 bytes 4 files changed, 172 insertions(+), 1 deletion(-) create mode 100644 drivers/acpi/acpi.cpp create mode 100644 drivers/acpi/acpi.h create mode 100644 drivers/acpi/acpi.h.gch diff --git a/arch/x86/cpuinfo/Cpuinfo.cpp b/arch/x86/cpuinfo/Cpuinfo.cpp index 4db7c84..b246ef7 100644 --- a/arch/x86/cpuinfo/Cpuinfo.cpp +++ b/arch/x86/cpuinfo/Cpuinfo.cpp @@ -1,5 +1,4 @@ #include "Cpuinfo.h" -#include "MemoryOperations.h" inline Cpuinfo::cpuidFunctionIndex operator++(Cpuinfo::cpuidFunctionIndex& command) diff --git a/drivers/acpi/acpi.cpp b/drivers/acpi/acpi.cpp new file mode 100644 index 0000000..41a7aa7 --- /dev/null +++ b/drivers/acpi/acpi.cpp @@ -0,0 +1,71 @@ +#include "acpi.h" +#include "StringOperations.h" + + +Rsdp::Rsdp() : rsdpStruct(nullptr), rsdtObj(nullptr), xsdtObj(nullptr) +{ + rsdpStruct = (struct rsdp *)StringOperations::findInMemory(rsdpSign, rsdpRomMemArea); + + if(rsdpStruct == nullptr) + { + rsdpStruct = (struct rsdp *)StringOperations::findInMemory(rsdpSign, rsdpEbdaMemArea); + } + + if(rsdpStruct != nullptr) + { + rsdtObj = Rsdt(rsdpStruct->rsdtAddress); + if(rsdpStruct->revision >= validFieldRevision) + { + xsdtObj = Xsdt(rsdpStruct->xsdtAddress); + } + } +}; + +const Rsdt *Rsdp::getRsdt() const +{ + if(rsdpStruct != nullptr) return &rsdtObj; + else return nullptr; +}; + +Rsdt::Rsdt(const nulltype null) : entry(null) +{ + rsdtStruct = null; +}; + +Rsdt::Rsdt(const uint32 addrRsdt) : entry(nullptr) +{ + rsdtStruct = (const struct rsdt *)(addrRsdt); + if(rsdtStruct != nullptr) + { + entry = Entry(rsdtStruct->header.length, + (&rsdtStruct->firstEntryAddr)); + } +}; + +const Xsdt *Rsdp::getXsdt() const +{ + if(rsdpStruct != nullptr) return &xsdtObj; + else return nullptr; +}; + +Xsdt::Xsdt(const nulltype null) +{ + xsdtStruct = nullptr; +}; + +Xsdt::Xsdt(const uint32 xsdt) +{ + xsdtStruct = (const struct xsdt *)(xsdt); +}; + +Entry::Entry(const uint32 rsdtLength, const uint32 *entryAddress) +{ + sizeHeadersInBytes = rsdtLength - sizeof(descHeader); + headers = (const struct descHeader **)(entryAddress); +}; + +Entry::Entry(const nulltype null) +{ + sizeHeadersInBytes = 0; + headers = null; +}; diff --git a/drivers/acpi/acpi.h b/drivers/acpi/acpi.h new file mode 100644 index 0000000..28221d7 --- /dev/null +++ b/drivers/acpi/acpi.h @@ -0,0 +1,101 @@ +#include +#include + + +typedef decltype(nullptr) nulltype; + +struct descHeader +{ + char signature[4]; + uint32 length; + uint8 revision; + uint8 checksum; + char oemId[6]; + uint64 oemTableId; + uint32 oemRevision; + uint32 creatorId; + uint32 creatorRevision; +} __attribute__((packed)); + +struct rsdt +{ + descHeader header; + uint32 firstEntryAddr; +} __attribute__((packed, aligned(sizeof(uint32)))); + +struct xsdt +{ + descHeader header; + uint64 firstEntryAddr; +} __attribute__((packed, aligned(sizeof(uint32)))); + +struct rsdp +{ + char signature[8]; + uint8 checksum; + char oemId[6]; + uint8 revision; + uint32 rsdtAddress; + uint32 length; + uint32 xsdtAddress; + uint8 extendedChecksum; + char reserved[3]; +} __attribute__((packed)); + +class DescriptorTable +{ + +}; + +class Entry +{ + private: + uint32 sizeHeadersInBytes; + const struct descHeader **headers; + // DescriptorTable &tables; + public: + Entry() = delete; + Entry(const uint32 sizeEntriesBytes, const uint32 *entryAddress); + Entry(const nulltype null); +}; + +class Rsdt +{ + private: + const struct rsdt* rsdtStruct; + Entry entry; + public: + Rsdt() = delete; + Rsdt(const uint32 addr); + Rsdt(const nulltype null); + const Entry& getEntries(); +}; + +class Xsdt +{ + private: + const struct xsdt* xsdtStruct; + public: + Xsdt() = delete; + Xsdt(const uint32 addr); + Xsdt(const nulltype null); +}; + +class Rsdp +{ + private: + const uint8 validFieldRevision = 2; + // RSDP memory address areas in IA-PC systems + const char *rsdpSign = "RSD PTR "; + const MemArea rsdpRomMemArea = MemArea(0xe0000, 0xfffff); + const MemArea rsdpEbdaMemArea = MemArea(0x80000, 0x803ff); + + const struct rsdp *rsdpStruct; + Rsdt rsdtObj; + Xsdt xsdtObj; + public: + Rsdp(); + const Rsdt *getRsdt() const; + const Xsdt *getXsdt() const; + +}; diff --git a/drivers/acpi/acpi.h.gch b/drivers/acpi/acpi.h.gch new file mode 100644 index 0000000..8cbaac5 Binary files /dev/null and b/drivers/acpi/acpi.h.gch differ -- cgit v1.2.3 From d8a708d4a2c612c348cf7c108a7c1ad683b394d8 Mon Sep 17 00:00:00 2001 From: Alexey Gavrilov Date: Tue, 19 Mar 2024 16:47:59 +0700 Subject: Remove unnecessary file --- drivers/acpi/acpi.h.gch | Bin 1675700 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 drivers/acpi/acpi.h.gch diff --git a/drivers/acpi/acpi.h.gch b/drivers/acpi/acpi.h.gch deleted file mode 100644 index 8cbaac5..0000000 Binary files a/drivers/acpi/acpi.h.gch and /dev/null differ -- cgit v1.2.3 From bbac386769210a8ecccba5826cfaf75d431cc2af Mon Sep 17 00:00:00 2001 From: Alexey Gavrilov Date: Mon, 25 Mar 2024 11:24:38 +0700 Subject: Acpi classes + string operations --- drivers/acpi/acpi.cpp | 86 +++++++++---------- drivers/acpi/acpi.h | 194 ++++++++++++++++++++++++++++--------------- include/StringOperations.cpp | 67 +++++++++++++++ include/StringOperations.h | 31 +++++++ include/types.h | 6 ++ makefile | 2 +- 6 files changed, 271 insertions(+), 115 deletions(-) create mode 100644 include/StringOperations.cpp create mode 100644 include/StringOperations.h diff --git a/drivers/acpi/acpi.cpp b/drivers/acpi/acpi.cpp index 41a7aa7..25dad9d 100644 --- a/drivers/acpi/acpi.cpp +++ b/drivers/acpi/acpi.cpp @@ -1,71 +1,61 @@ #include "acpi.h" -#include "StringOperations.h" -Rsdp::Rsdp() : rsdpStruct(nullptr), rsdtObj(nullptr), xsdtObj(nullptr) -{ - rsdpStruct = (struct rsdp *)StringOperations::findInMemory(rsdpSign, rsdpRomMemArea); +const char *Rsdp::signatureString = "RSD PTR "; +const uint8 Rsdp::validFieldRevision = 2; +const memAddr Rsdp::romAreaStart = 0xe0000; +const memAddr Rsdp::romAreaEnd = 0xfffff; +const memAddr Rsdp::ebdaAreaStart = 0x80000; +const memAddr Rsdp::ebdaAreaEnd = 0x803ff; +const uint8 Rsdp::checksunFieldSize = 20; +// Entry **Rsdt::entries = nullptr; - if(rsdpStruct == nullptr) - { - rsdpStruct = (struct rsdp *)StringOperations::findInMemory(rsdpSign, rsdpEbdaMemArea); - } - - if(rsdpStruct != nullptr) - { - rsdtObj = Rsdt(rsdpStruct->rsdtAddress); - if(rsdpStruct->revision >= validFieldRevision) - { - xsdtObj = Xsdt(rsdpStruct->xsdtAddress); - } - } -}; - -const Rsdt *Rsdp::getRsdt() const +Rsdt *Rsdp::getRsdt() const { - if(rsdpStruct != nullptr) return &rsdtObj; - else return nullptr; + Rsdt *rsdtPtr = (Rsdt *)(rsdtAddress); + if(rsdtPtr == nullptr or checksumCheck()) return nullptr; + else return rsdtPtr; }; -Rsdt::Rsdt(const nulltype null) : entry(null) +Xsdt *Rsdp::getXsdt() const { - rsdtStruct = null; + Xsdt *xsdtPtr = (Xsdt *)(xsdtAddress); + if(xsdtPtr == nullptr or checksumCheck()) return nullptr; + else return xsdtPtr; }; -Rsdt::Rsdt(const uint32 addrRsdt) : entry(nullptr) -{ - rsdtStruct = (const struct rsdt *)(addrRsdt); - if(rsdtStruct != nullptr) - { - entry = Entry(rsdtStruct->header.length, - (&rsdtStruct->firstEntryAddr)); - } -}; -const Xsdt *Rsdp::getXsdt() const +const uint32 DescHeader::getLength() const { - if(rsdpStruct != nullptr) return &xsdtObj; - else return nullptr; + return length; }; -Xsdt::Xsdt(const nulltype null) +const Entry *Rsdt::getEntry(uint8 index) { - xsdtStruct = nullptr; -}; + uint32 entriesAmount = (header.getLength() - sizeof(DescHeader)) / Entry::size; -Xsdt::Xsdt(const uint32 xsdt) -{ - xsdtStruct = (const struct xsdt *)(xsdt); + if(index >= entriesAmount + or entries == nullptr + or header.checksumCheck()) return nullptr; + else return ((const Entry **)&entries)[index]; }; -Entry::Entry(const uint32 rsdtLength, const uint32 *entryAddress) +uint8 Rsdp::checksumCheck() const { - sizeHeadersInBytes = rsdtLength - sizeof(descHeader); - headers = (const struct descHeader **)(entryAddress); + uint8 check = 0; + for(uint32 offset = 0; offset < checksunFieldSize; offset++) + { + check += *(uint8 *)((memAddr)this + offset); + } + return check; }; -Entry::Entry(const nulltype null) +uint8 DescHeader::checksumCheck() const { - sizeHeadersInBytes = 0; - headers = null; + uint8 check = 0; + for(uint32 offset = 0; offset < length; offset++) + { + check += *(uint8 *)((memAddr)this + offset); + } + return check; }; diff --git a/drivers/acpi/acpi.h b/drivers/acpi/acpi.h index 28221d7..069c954 100644 --- a/drivers/acpi/acpi.h +++ b/drivers/acpi/acpi.h @@ -4,98 +4,160 @@ typedef decltype(nullptr) nulltype; -struct descHeader +class Gas { - char signature[4]; - uint32 length; - uint8 revision; - uint8 checksum; - char oemId[6]; - uint64 oemTableId; - uint32 oemRevision; - uint32 creatorId; - uint32 creatorRevision; -} __attribute__((packed)); + private: + const uint8 addressSpaceId; + const uint8 registerBitWidth; + const uint8 registerBitOffset; + const uint8 accessSize; + const uint64 address; + public: + Gas(); + Gas(const Gas &) = default; +}; -struct rsdt +class DescHeader { - descHeader header; - uint32 firstEntryAddr; -} __attribute__((packed, aligned(sizeof(uint32)))); + private: + const char signature[4]; + const uint32 length; + const uint8 revision; + const uint8 checksum; + const char oemId[6]; + const uint64 oemTableId; + const uint32 oemRevision; + const uint32 creatorId; + const uint32 creatorRevision; + public: + DescHeader() = delete; + DescHeader(const DescHeader &) = delete; + const uint32 getLength() const; + uint8 checksumCheck() const; +} __attribute__((packed)); -struct xsdt -{ - descHeader header; - uint64 firstEntryAddr; -} __attribute__((packed, aligned(sizeof(uint32)))); -struct rsdp +class Entry { - char signature[8]; - uint8 checksum; - char oemId[6]; - uint8 revision; - uint32 rsdtAddress; - uint32 length; - uint32 xsdtAddress; - uint8 extendedChecksum; - char reserved[3]; + public: + // In bytes + static const uint8 size = 4; + protected: + const DescHeader header; + public: + Entry() = delete; + Entry(const Entry &) = delete; } __attribute__((packed)); -class DescriptorTable -{ - -}; - -class Entry +class FadtEntry : public Entry { private: - uint32 sizeHeadersInBytes; - const struct descHeader **headers; - // DescriptorTable &tables; + const uint32 firmwareCtrl; + const uint32 dsdt; + const uint8 reserved; + const uint8 preferredPmProfile; + const uint16 sciInt; + const uint32 smiCmd; + const uint8 acpiEnable; + const uint8 acpiDisable; + const uint8 s4biosReq; + const uint8 pstateCnt; + const uint32 pm1AEvtBlk; + const uint32 pm1BEvtBlk; + const uint32 pm1ACntBlk; + const uint32 pm1BCntBlk; + const uint32 pm2CntBlk; + const uint32 pmTmrBlk; + const uint32 gpe0Blk; + const uint32 gpe1Blk; + const uint8 pm1EvtLen; + const uint8 pm1CntLen; + const uint8 pm2CntLen; + const uint8 pmTmrLen; + const uint8 gpe0BlkLen; + const uint8 gpe1BlkLen; + const uint8 gpe1Base; + const uint8 cstCnt; + const uint16 pLvl2Lat; + const uint16 pLvl3Lat; + const uint16 flushSize; + const uint16 flushStride; + const uint8 dutyOffset; + const uint8 dutyWidth; + const uint8 dayAlrm; + const uint8 monAlrm; + const uint8 century; + const uint16 iapcBootArch; + const uint8 reservedTwo; + const uint32 flags; + const Gas resetReg; + const uint8 resetValue; + const uint16 armBootArch; + const uint8 minorRevision; + const uint64 xFirmwareCtrl; + const uint64 xDsdt; + const Gas xPm1AEvtBlk; + const Gas xPm1BEvtBlk; + const Gas xPm1ACntBlk; + const Gas xPm1BCntBlk; + const Gas xPm2CntBlk; + const Gas xPmTmrBlk; + const Gas xGpe0Blk; + const Gas xGpe1Blk; + const Gas sleepControlReg; + const Gas sleepStatusReg; + const uint64 hypervisorVendorIdentity; public: - Entry() = delete; - Entry(const uint32 sizeEntriesBytes, const uint32 *entryAddress); - Entry(const nulltype null); -}; + FadtEntry() = delete; + FadtEntry(const FadtEntry &) = delete; +} __attribute__((packed)); class Rsdt { private: - const struct rsdt* rsdtStruct; - Entry entry; + const DescHeader header; + const Entry **entries; public: Rsdt() = delete; - Rsdt(const uint32 addr); - Rsdt(const nulltype null); - const Entry& getEntries(); -}; + Rsdt(const Rsdt &) = delete; + const Entry *getEntry(uint8 index); +} __attribute__((packed, aligned(sizeof(uint32)))); class Xsdt { private: - const struct xsdt* xsdtStruct; + const DescHeader header; + const uint64 firstEntryAddr; public: Xsdt() = delete; - Xsdt(const uint32 addr); - Xsdt(const nulltype null); -}; + Xsdt(const Xsdt &) = delete; +} __attribute__((packed)); class Rsdp { - private: - const uint8 validFieldRevision = 2; + public: + const static uint8 validFieldRevision; // RSDP memory address areas in IA-PC systems - const char *rsdpSign = "RSD PTR "; - const MemArea rsdpRomMemArea = MemArea(0xe0000, 0xfffff); - const MemArea rsdpEbdaMemArea = MemArea(0x80000, 0x803ff); - - const struct rsdp *rsdpStruct; - Rsdt rsdtObj; - Xsdt xsdtObj; + const static char *signatureString; + const static memAddr romAreaStart; + const static memAddr romAreaEnd; + const static memAddr ebdaAreaStart; + const static memAddr ebdaAreaEnd; + private: + const static uint8 checksunFieldSize; + const char signature[8]; + const uint8 checksum; + const char oemId[6]; + const uint8 revision; + const uint32 rsdtAddress; + const uint32 length; + const uint32 xsdtAddress; + const uint8 extendedChecksum; + const char reserved[3]; public: - Rsdp(); - const Rsdt *getRsdt() const; - const Xsdt *getXsdt() const; - + Rsdp() = delete; + Rsdp(const Rsdp &) = delete; + Rsdt *getRsdt() const; + Xsdt *getXsdt() const; + uint8 checksumCheck() const; }; diff --git a/include/StringOperations.cpp b/include/StringOperations.cpp new file mode 100644 index 0000000..01e7a76 --- /dev/null +++ b/include/StringOperations.cpp @@ -0,0 +1,67 @@ +#include "StringOperations.h" + + +MemArea::MemArea() +{ + start = final = NULL; +}; + +MemArea::MemArea(const memAddr start, const memAddr final) +{ + this->start = start; + this->final = final; + + if(!valid()) + { + *this = MemArea(); + } +}; + +memAddr MemArea::begin() +{ + return start; +} + +memAddr MemArea::end() +{ + if(start == final) return start; + else return final + 1; +}; + +bool MemArea::valid() +{ + if(start > final + or start == NULL + or final == NULL) return false; + else return true; +}; + +uint32 StringOperations::sequenceSize(const char *chars) +{ + uint32 indx = 0; + while(chars[indx++]){} + + return --indx; +}; + +void *StringOperations::findInMemory(const char *sequence, MemArea memory) +{ + if(sequence == nullptr or !memory.valid()) return NULL; + + uint32 seqIndx = 0; + for(MemArea::iterator it = memory.begin(); it != memory.end(); it++) + { + char ch = sequence[seqIndx], chMem = (*((char *)it)); + + if(ch == '\0') return (void *)(it - sequenceSize(sequence)); + else if(ch != chMem) + { + seqIndx = 0; + } + else if(ch == chMem) + { + seqIndx++; + } + } + return NULL; +}; diff --git a/include/StringOperations.h b/include/StringOperations.h new file mode 100644 index 0000000..81d7144 --- /dev/null +++ b/include/StringOperations.h @@ -0,0 +1,31 @@ +#ifndef STRINGOPERATIONS_H +#define STRINGOPERATIONS_H + +#include + + +class MemArea +{ + private: + memAddr start, final; + public: + MemArea(); + MemArea(const memAddr start, const memAddr final); + memAddr begin(); + memAddr end(); + bool valid(); + + typedef memAddr iterator; +}; + +class StringOperations +{ + public: + // Return the starting address where is sequence is allocated + // else NULL + static void *findInMemory(const char *sequence, MemArea memory); + // Return size of ASCIZ sequence without 0-symbol, NULL on failure + static uint32 sequenceSize(const char *chars); +}; + +#endif diff --git a/include/types.h b/include/types.h index 54dcc25..e578adb 100644 --- a/include/types.h +++ b/include/types.h @@ -5,3 +5,9 @@ typedef unsigned char uint8; typedef unsigned short int uint16; typedef unsigned long uint32; typedef unsigned long long uint64; + +#if defined(__x86_64) + typedef uint64 memAddr; +#else + typedef uint32 memAddr; +#endif diff --git a/makefile b/makefile index d7bdcb2..1b43240 100644 --- a/makefile +++ b/makefile @@ -56,6 +56,6 @@ clean: rm -rf ./iso/os/kernel.bin run: - qemu-system-x86_64 $(QEMUFLAGS) -cdrom ./$(BDIR)/kernel.iso + qemu-system-i386 $(QEMUFLAGS) -cdrom ./$(BDIR)/kernel.iso all: clean build install run -- cgit v1.2.3