summaryrefslogtreecommitdiffhomepage
path: root/Kernel/HALKit
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal.elmahrouss@icloud.com>2024-06-01 09:29:31 +0200
committerAmlal El Mahrouss <amlal.elmahrouss@icloud.com>2024-06-01 09:29:31 +0200
commitfc0d38259fd6670966b916b1f28a11f3cb2a4c45 (patch)
tree2a54c64137eae7ffacfcb1842a92335b0e41b39b /Kernel/HALKit
parentc8b9625efaeae241d57cc8a40c3234807206e386 (diff)
MHR-23: SMP: Add hal_send_start_ipi and hal_send_end_ipi, as well as
DMA utilities. Signed-off-by: Amlal El Mahrouss <amlal.elmahrouss@icloud.com>
Diffstat (limited to 'Kernel/HALKit')
-rw-r--r--Kernel/HALKit/AMD64/HalACPIFactoryInterface.cxx29
-rw-r--r--Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cpp2
-rw-r--r--Kernel/HALKit/AMD64/HalCoreMultiProcessingAMD64.cpp67
-rw-r--r--Kernel/HALKit/AMD64/HalKernelMain.cxx2
-rw-r--r--Kernel/HALKit/AMD64/HalSMPCore.cxx2
-rw-r--r--Kernel/HALKit/AMD64/Processor.hpp65
6 files changed, 150 insertions, 17 deletions
diff --git a/Kernel/HALKit/AMD64/HalACPIFactoryInterface.cxx b/Kernel/HALKit/AMD64/HalACPIFactoryInterface.cxx
index ff5372f4..f92554f8 100644
--- a/Kernel/HALKit/AMD64/HalACPIFactoryInterface.cxx
+++ b/Kernel/HALKit/AMD64/HalACPIFactoryInterface.cxx
@@ -7,6 +7,8 @@
#include <Builtins/ACPI/ACPIFactoryInterface.hxx>
#include <HALKit/AMD64/Processor.hpp>
#include <NewKit/String.hpp>
+#include <ArchKit/ArchKit.hpp>
+#include <KernelKit/KernelHeap.hpp>
namespace NewOS
{
@@ -73,28 +75,37 @@ namespace NewOS
return ErrorOr<voidPtr>{-4};
}
- SDT* xsdt = (SDT*)(rsdPtr->XsdtAddress >> (rsdPtr->XsdtAddress & 0xFFF));
+ /// FIXME
+ RSDT* xsdt = (RSDT*)rsdPtr->XsdtAddress;
- SizeT num = -(xsdt->Length - sizeof(SDT)) / 8;
+ if (NewOS::HAL::ke_map_address((PDE*)hal_read_cr3(), rsdPtr->XsdtAddress, (UIntPtr)xsdt, NewOS::HAL::eFlagsRw))
+ return ErrorOr<voidPtr>{-5};
+
+ Int64 num = (xsdt->Length - sizeof(SDT)) / sizeof(UInt64);
+
+ if (num < 1)
+ {
+ return ErrorOr<voidPtr>{-6};
+ }
this->fEntries = num;
- kcout << "ACPI: Number of entries: " << number(num) << endl;
+ kcout << "ACPI: Number of entries: " << number(this->fEntries) << endl;
kcout << "ACPI: Address of XSDT: " << hex_number((UIntPtr)xsdt) << endl;
- constexpr short ACPI_SIGNATURE_LENGTH = 4;
+ const short cAcpiSignatureLength = 4;
for (Size index = 0; index < this->fEntries; ++index)
{
- SDT& sdt = xsdt[index];
+ SDT* sdt = (SDT*)(xsdt->AddressArr[index]);
- for (short signature_index = 0; signature_index < ACPI_SIGNATURE_LENGTH; ++signature_index)
+ for (short signature_index = 0; signature_index < cAcpiSignatureLength; ++signature_index)
{
- if (sdt.Signature[signature_index] != signature[signature_index])
+ if (sdt->Signature[signature_index] != signature[signature_index])
break;
- if (signature_index == 4)
- return ErrorOr<voidPtr>(reinterpret_cast<voidPtr>(&sdt));
+ if (signature_index == (cAcpiSignatureLength - 1))
+ return ErrorOr<voidPtr>(reinterpret_cast<voidPtr>(sdt));
}
}
diff --git a/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cpp b/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cpp
index 0ac7a50e..d06dc6a6 100644
--- a/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cpp
+++ b/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cpp
@@ -5,7 +5,7 @@
------------------------------------------- */
#include <ArchKit/ArchKit.hpp>
-#include <KernelKit/ProcessScheduler.hpp>
+#include <KernelKit/ProcessScheduler.hxx>
#include <NewKit/String.hpp>
/// @brief Handle GPF fault.
diff --git a/Kernel/HALKit/AMD64/HalCoreMultiProcessingAMD64.cpp b/Kernel/HALKit/AMD64/HalCoreMultiProcessingAMD64.cpp
index abd19586..287b1882 100644
--- a/Kernel/HALKit/AMD64/HalCoreMultiProcessingAMD64.cpp
+++ b/Kernel/HALKit/AMD64/HalCoreMultiProcessingAMD64.cpp
@@ -7,6 +7,12 @@
#include <Builtins/ACPI/ACPIFactoryInterface.hxx>
#include <HALKit/AMD64/Processor.hpp>
#include <NewKit/KernelCheck.hpp>
+#include <ArchKit/ArchKit.hpp>
+
+#define kAPIC_ICR_Low 0x300
+#define kAPIC_ICR_High 0x310
+#define kAPIC_SIPI_Vector 0x00500
+#define kAPIC_EIPI_Vector 0x00400
///////////////////////////////////////////////////////////////////////////////////////
@@ -62,7 +68,7 @@ namespace NewOS::HAL
struct MadtProcessorLocalApic final
{
Char AcpiProcessorId;
- Char Reserved;
+ Char ApicId;
UInt32 Flags;
};
@@ -102,15 +108,66 @@ namespace NewOS::HAL
///////////////////////////////////////////////////////////////////////////////////////
- void hal_system_get_cores(voidPtr rsdPtr)
+ /// @brief Send start IPI for CPU.
+ /// @param apicId
+ /// @param vector
+ /// @param targetAddress
+ /// @return
+ Void hal_send_start_ipi(UInt32 apicId, UInt8 vector, UInt32 targetAddress)
+ {
+ NewOS::ke_dma_write(targetAddress, kAPIC_ICR_High, apicId << 24);
+ NewOS::ke_dma_write(targetAddress, kAPIC_ICR_Low, kAPIC_SIPI_Vector | vector);
+ }
+
+ /// @brief Send end IPI for CPU.
+ /// @param apicId
+ /// @param vector
+ /// @param targetAddress
+ /// @return
+ Void hal_send_end_ipi(UInt32 apicId, UInt8 vector, UInt32 targetAddress)
+ {
+ NewOS::ke_dma_write(targetAddress, kAPIC_ICR_High, apicId << 24);
+ NewOS::ke_dma_write(targetAddress, kAPIC_ICR_Low, kAPIC_EIPI_Vector | vector);
+ }
+
+ Void hal_system_get_cores(voidPtr rsdPtr)
{
auto acpi = ACPIFactoryInterface(rsdPtr);
kApicMadt = acpi.Find(kApicSignature).Leak().Leak();
- if (kApicMadt)
+ if (kApicMadt != nullptr)
{
- kcout << "New OS: APIC is present...\r";
- kApicInfoBlock = (MadtType*)kApicMadt;
+ auto madt = (SDT*)kApicMadt;
+
+ const UInt8* madt_end = (const UInt8*)madt + madt->Length;
+ const UInt8* entry_ptr = (const UInt8*)(madt + 1);
+
+ while (entry_ptr < madt_end)
+ {
+ const MadtType::MadtAddress* entry_header = (const MadtType::MadtAddress*)entry_ptr;
+
+ switch (entry_header->Flags)
+ {
+ case 0: {
+ const MadtProcessorLocalApic* local_apic = (const MadtProcessorLocalApic*)entry_ptr;
+ if (local_apic->Flags & 1)
+ {
+ // Processor is enabled
+ kcout << "Processor ID: %d, APIC ID: %d\n"
+ << number(local_apic->AcpiProcessorId) << number(local_apic->ApicId);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ entry_ptr += entry_header->RecordLen;
+ }
+
+ while (true)
+ {
+ }
}
else
{
diff --git a/Kernel/HALKit/AMD64/HalKernelMain.cxx b/Kernel/HALKit/AMD64/HalKernelMain.cxx
index 07656060..3136bf76 100644
--- a/Kernel/HALKit/AMD64/HalKernelMain.cxx
+++ b/Kernel/HALKit/AMD64/HalKernelMain.cxx
@@ -11,7 +11,7 @@
#include <KernelKit/Framebuffer.hpp>
#include <KernelKit/KernelHeap.hpp>
#include <KernelKit/PEFCodeManager.hxx>
-#include <KernelKit/ProcessScheduler.hpp>
+#include <KernelKit/ProcessScheduler.hxx>
#include <KernelKit/UserHeap.hpp>
#include <NewKit/Json.hpp>
diff --git a/Kernel/HALKit/AMD64/HalSMPCore.cxx b/Kernel/HALKit/AMD64/HalSMPCore.cxx
index 90703e13..7aa13068 100644
--- a/Kernel/HALKit/AMD64/HalSMPCore.cxx
+++ b/Kernel/HALKit/AMD64/HalSMPCore.cxx
@@ -4,7 +4,7 @@
------------------------------------------- */
-#include <KernelKit/ProcessScheduler.hpp>
+#include <KernelKit/ProcessScheduler.hxx>
using namespace NewOS;
Void ProcessHeader::SetEntrypoint(UIntPtr& imageStart) noexcept
diff --git a/Kernel/HALKit/AMD64/Processor.hpp b/Kernel/HALKit/AMD64/Processor.hpp
index 235e425d..608a502f 100644
--- a/Kernel/HALKit/AMD64/Processor.hpp
+++ b/Kernel/HALKit/AMD64/Processor.hpp
@@ -17,6 +17,7 @@
#include <NewKit/Defines.hpp>
#include <NewKit/Utils.hpp>
#include <FirmwareKit/Handover.hxx>
+#include <HALKit/AMD64/HalPageAlloc.hpp>
#ifdef kCPUBackendName
#undef kCPUBackendName
@@ -53,6 +54,68 @@ namespace NewOS
namespace NewOS::HAL
{
+
+ enum
+ {
+ eFlagsUser,
+ eFlagsRw,
+ eFlagsExecDisable
+ };
+
+ /// @brief Map address to PDE.
+ /// @param pde a valid page directory.
+ /// @param phys_addr a valid phyiscal address.
+ /// @param virt_addr a valid virtual address.
+ /// @param flags the flags to put on the page.
+ inline Int32 ke_map_address(PDE* pde, UIntPtr phys_addr, UIntPtr virt_addr, UInt32 flags)
+ {
+ UInt16 pml4_index = (virt_addr >> 39) & 0x1FF;
+
+ if (!pde->Pte[pml4_index].Present)
+ {
+ pde->Pte[pml4_index].Present = true;
+ kcout << "PM: It is present now.\r";
+ }
+ else
+ {
+ kcout << "PM: It is already present.\r";
+ kcout << "Address? " << hex_number(pde->Pte[pml4_index].PhysicalAddress) << endl;
+ kcout << "User? " << (pde->Pte[pml4_index].User ? "yes" : "no") << "\r";
+ kcout << "RW? " << (pde->Pte[pml4_index].Rw ? "yes" : "no") << "\r";
+
+ return 1;
+ }
+
+ pde->Pte[pml4_index].PhysicalAddress = phys_addr;
+ pde->Pte[pml4_index].Rw = flags & eFlagsRw;
+ pde->Pte[pml4_index].User = flags & eFlagsUser;
+ pde->Pte[pml4_index].ExecDisable = flags & eFlagsExecDisable;
+
+ return 0;
+ }
+
+ /// @brief Map address to PDE.
+ /// @param pde
+ /// @param phys_addr
+ /// @param virt_addr
+ /// @param flags
+ inline void ke_unmap_address(PDE* pde, UIntPtr phys_addr, UIntPtr virt_addr, UInt32 flags)
+ {
+ UInt16 pml4_index = (virt_addr >> 39) & 0x1FF;
+ UInt16 pdpt_index = (virt_addr >> 30) & 0x1FF;
+ UInt16 pd_index = (virt_addr >> 21) & 0x1FF;
+ UInt16 pt_index = (virt_addr >> 12) & 0x1FF;
+
+ if (pde->Pte[pml4_index].Present)
+ {
+ pde->Pte[pml4_index].Present = false;
+ pde->Pte[pml4_index].PhysicalAddress = 0;
+ pde->Pte[pml4_index].Rw = 0;
+ pde->Pte[pml4_index].User = 0;
+ pde->Pte[pml4_index].ExecDisable = 0;
+ }
+ }
+
EXTERN_C UChar In8(UInt16 port);
EXTERN_C UShort In16(UInt16 port);
EXTERN_C UInt In32(UInt16 port);
@@ -162,6 +225,8 @@ namespace NewOS::HAL
};
Void hal_system_get_cores(VoidPtr rsdPtr);
+ Void hal_send_start_ipi(UInt32 apicId, UInt8 vector, UInt32 targetAddress);
+ Void hal_send_end_ipi(UInt32 apicId, UInt8 vector, UInt32 targetAddress);
/// @brief Processor specific structures.
namespace Detail