blob: cbfded4e1b0e7d18bb7f09005b1b600dad4aeb46 (
plain)
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
27
28
29
30
31
32
33
34
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
|
/* -------------------------------------------
Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
------------------------------------------- */
#include <Mod/ACPI/ACPIFactoryInterface.h>
#include <NewKit/KString.h>
#include <ArchKit/ArchKit.h>
#include <KernelKit/Heap.h>
namespace Kernel
{
/// @brief Finds a descriptor table inside ACPI XSDT.
ErrorOr<voidPtr> ACPIFactoryInterface::Find(const Char* signature)
{
MUST_PASS(fRsdp);
if (!signature)
return ErrorOr<voidPtr>{-1};
if (*signature == 0)
return ErrorOr<voidPtr>{-1};
RSDP* rsp_ptr = reinterpret_cast<RSDP*>(this->fRsdp);
if (rsp_ptr->Revision <= 1)
return ErrorOr<voidPtr>{-1};
RSDT* xsdt = reinterpret_cast<RSDT*>(rsp_ptr->RsdtAddress);
Int64 num = (xsdt->Length - sizeof(SDT)) / sizeof(Int64);
/***
crucial to avoid underflows.
*/
if (num < 1)
{
/// stop here, we should have entries...
ke_panic(RUNTIME_CHECK_ACPI);
return ErrorOr<voidPtr>{-1};
}
this->fEntries = num;
kcout << "ACPI: Number of entries: " << number(this->fEntries) << endl;
kcout << "ACPI: Revision: " << number(xsdt->Revision) << endl;
kcout << "ACPI: Signature: " << xsdt->Signature << endl;
kcout << "ACPI: Address of XSDT: " << hex_number((UIntPtr)xsdt) << endl;
const short cAcpiSignatureLength = 4;
for (Size index = 0; index < this->fEntries; ++index)
{
SDT* sdt = reinterpret_cast<SDT*>(xsdt->AddressArr[index]);
kcout << "ACPI: Checksum: " << number(sdt->Checksum) << endl;
kcout << "ACPI: Revision: " << number(sdt->Revision) << endl;
for (short signature_index = 0; signature_index < cAcpiSignatureLength; ++signature_index)
{
if (sdt->Signature[signature_index] != signature[signature_index])
break;
if (signature_index == (cAcpiSignatureLength - 1))
{
kcout << "ACPI: SDT Signature: " << sdt->Signature << endl;
kcout << "ACPI: SDT OEM ID: " << sdt->OemId << endl;
return ErrorOr<voidPtr>(reinterpret_cast<voidPtr>(xsdt->AddressArr[index]));
}
}
}
return ErrorOr<voidPtr>{-1};
}
/***
@brief Checksum on SDT header.
@param checksum the header to checksum
@param len the length of it.
*/
bool ACPIFactoryInterface::Checksum(const Char* checksum, SSizeT len)
{
if (len == 0)
return 1;
char chr = 0;
for (int index = 0; index < len; ++index)
{
chr += checksum[index];
}
return chr == 0;
}
} // namespace Kernel
|