summaryrefslogtreecommitdiffhomepage
path: root/Kernel/HALKit/AMD64
diff options
context:
space:
mode:
Diffstat (limited to 'Kernel/HALKit/AMD64')
-rw-r--r--Kernel/HALKit/AMD64/HalACPIFactoryInterface.cxx37
-rw-r--r--Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cpp52
-rw-r--r--Kernel/HALKit/AMD64/HalCoreMultiProcessingAMD64.cpp50
-rw-r--r--Kernel/HALKit/AMD64/HalDebugOutput.cxx2
-rw-r--r--Kernel/HALKit/AMD64/HalKernelMain.cxx2
-rw-r--r--Kernel/HALKit/AMD64/HalSMPCore.cxx2
-rw-r--r--Kernel/HALKit/AMD64/Processor.hpp65
-rw-r--r--Kernel/HALKit/AMD64/Storage/AHCI.cxx2
8 files changed, 163 insertions, 49 deletions
diff --git a/Kernel/HALKit/AMD64/HalACPIFactoryInterface.cxx b/Kernel/HALKit/AMD64/HalACPIFactoryInterface.cxx
index ff5372f4..14241f60 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
{
@@ -61,44 +63,53 @@ namespace NewOS
MUST_PASS(fRsdp);
if (!signature)
- return ErrorOr<voidPtr>{-2};
+ return ErrorOr<voidPtr>{-1};
if (*signature == 0)
- return ErrorOr<voidPtr>{-3};
+ return ErrorOr<voidPtr>{-1};
RSDP* rsdPtr = reinterpret_cast<RSDP*>(this->fRsdp);
if (rsdPtr->Revision <= 1)
- {
- return ErrorOr<voidPtr>{-4};
- }
+ return ErrorOr<voidPtr>{-1};
+
+ RSDT* xsdt = (RSDT*)(rsdPtr->RsdtAddress);
- SDT* xsdt = (SDT*)(rsdPtr->XsdtAddress >> (rsdPtr->XsdtAddress & 0xFFF));
+ Int64 num = (xsdt->Length - sizeof(SDT)) / sizeof(UInt32);
- SizeT num = -(xsdt->Length - sizeof(SDT)) / 8;
+ if (num < 1)
+ {
+ /// stop here, we should have entries...
+ ke_stop(RUNTIME_CHECK_ACPI);
+ return ErrorOr<voidPtr>{-1};
+ }
this->fEntries = num;
- kcout << "ACPI: Number of entries: " << number(num) << endl;
+ 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;
- 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];
+
+ kcout << "ACPI: Revision: " << number(sdt.CreatorID) << endl;
- 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])
break;
- if (signature_index == 4)
+ if (signature_index == (cAcpiSignatureLength - 1))
return ErrorOr<voidPtr>(reinterpret_cast<voidPtr>(&sdt));
}
}
- return ErrorOr<voidPtr>{nullptr};
+ return ErrorOr<voidPtr>{-1};
}
/***
diff --git a/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cpp b/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cpp
index 9477ecb7..6d831d3b 100644
--- a/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cpp
+++ b/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cpp
@@ -5,23 +5,23 @@
------------------------------------------- */
#include <ArchKit/ArchKit.hpp>
-#include <KernelKit/ProcessScheduler.hpp>
+#include <KernelKit/ProcessScheduler.hxx>
#include <NewKit/String.hpp>
/// @brief Handle GPF fault.
/// @param rsp
EXTERN_C void idt_handle_gpf(NewOS::UIntPtr rsp)
{
- MUST_PASS(NewOS::ProcessScheduler::Shared().Leak().GetCurrent());
+ MUST_PASS(NewOS::ProcessScheduler::The().Leak().GetCurrent());
- NewOS::kcout << "New OS: Stack Pointer: "
+ NewOS::kcout << "newoskrnl: Stack Pointer: "
<< NewOS::StringBuilder::FromInt("rsp{%}", rsp);
NewOS::kcout
- << "New OS: General Protection Fault, caused by "
- << NewOS::ProcessScheduler::Shared().Leak().GetCurrent().Leak().GetName();
+ << "newoskrnl: General Protection Fault, caused by "
+ << NewOS::ProcessScheduler::The().Leak().GetCurrent().Leak().GetName();
- NewOS::ProcessScheduler::Shared().Leak().GetCurrent().Leak().Crash();
+ NewOS::ProcessScheduler::The().Leak().GetCurrent().Leak().Crash();
}
/// @brief Handle the scheduler interrupt, raised from the HPET timer.
@@ -31,14 +31,14 @@ EXTERN_C void idt_handle_scheduler(NewOS::UIntPtr rsp)
NewOS::kcout << NewOS::StringBuilder::FromInt("rsp{%}", rsp);
NewOS::kcout
- << "New OS: Will be scheduled back later "
- << NewOS::ProcessScheduler::Shared().Leak().GetCurrent().Leak().GetName()
+ << "newoskrnl: Will be scheduled back later "
+ << NewOS::ProcessScheduler::The().Leak().GetCurrent().Leak().GetName()
<< NewOS::end_line();
/// schedule another process.
if (!NewOS::ProcessHelper::StartScheduling())
{
- NewOS::kcout << "New OS: Continue schedule this process...\r";
+ NewOS::kcout << "newoskrnl: Continue schedule this process...\r";
}
}
@@ -46,56 +46,56 @@ EXTERN_C void idt_handle_scheduler(NewOS::UIntPtr rsp)
/// @param rsp
EXTERN_C void idt_handle_pf(NewOS::UIntPtr rsp)
{
- MUST_PASS(NewOS::ProcessScheduler::Shared().Leak().GetCurrent());
+ MUST_PASS(NewOS::ProcessScheduler::The().Leak().GetCurrent());
NewOS::kcout << NewOS::StringBuilder::FromInt("rsp{%}", rsp);
NewOS::kcout
- << "New OS: Segmentation Fault, caused by "
- << NewOS::ProcessScheduler::Shared().Leak().GetCurrent().Leak().GetName();
+ << "newoskrnl: Segmentation Fault, caused by "
+ << NewOS::ProcessScheduler::The().Leak().GetCurrent().Leak().GetName();
- NewOS::ProcessScheduler::Shared().Leak().GetCurrent().Leak().Crash();
+ NewOS::ProcessScheduler::The().Leak().GetCurrent().Leak().Crash();
}
/// @brief Handle math fault.
/// @param rsp
EXTERN_C void idt_handle_math(NewOS::UIntPtr rsp)
{
- MUST_PASS(NewOS::ProcessScheduler::Shared().Leak().GetCurrent());
+ MUST_PASS(NewOS::ProcessScheduler::The().Leak().GetCurrent());
NewOS::kcout << NewOS::StringBuilder::FromInt("rsp{%}", rsp);
NewOS::kcout
- << "New OS: Math error, caused by "
- << NewOS::ProcessScheduler::Shared().Leak().GetCurrent().Leak().GetName();
+ << "newoskrnl: Math error, caused by "
+ << NewOS::ProcessScheduler::The().Leak().GetCurrent().Leak().GetName();
- NewOS::ProcessScheduler::Shared().Leak().GetCurrent().Leak().Crash();
+ NewOS::ProcessScheduler::The().Leak().GetCurrent().Leak().Crash();
}
/// @brief Handle any generic fault.
/// @param rsp
EXTERN_C void idt_handle_generic(NewOS::UIntPtr rsp)
{
- MUST_PASS(NewOS::ProcessScheduler::Shared().Leak().GetCurrent());
+ MUST_PASS(NewOS::ProcessScheduler::The().Leak().GetCurrent());
NewOS::kcout << NewOS::StringBuilder::FromInt("sp{%}", rsp);
NewOS::kcout
- << "New OS: Execution error, caused by "
- << NewOS::ProcessScheduler::Shared().Leak().GetCurrent().Leak().GetName();
+ << "newoskrnl: Execution error, caused by "
+ << NewOS::ProcessScheduler::The().Leak().GetCurrent().Leak().GetName();
- NewOS::ProcessScheduler::Shared().Leak().GetCurrent().Leak().Crash();
+ NewOS::ProcessScheduler::The().Leak().GetCurrent().Leak().Crash();
}
/// @brief Handle #UD fault.
/// @param rsp
EXTERN_C void idt_handle_ud(NewOS::UIntPtr rsp)
{
- MUST_PASS(NewOS::ProcessScheduler::Shared().Leak().GetCurrent());
+ MUST_PASS(NewOS::ProcessScheduler::The().Leak().GetCurrent());
- NewOS::kcout << "New OS: Stack Pointer: "
+ NewOS::kcout << "newoskrnl: Stack Pointer: "
<< NewOS::StringBuilder::FromInt("rsp{%}", rsp);
NewOS::kcout
- << "New OS: Invalid interrupt, caused by "
- << NewOS::ProcessScheduler::Shared().Leak().GetCurrent().Leak().GetName();
+ << "newoskrnl: Invalid interrupt, caused by "
+ << NewOS::ProcessScheduler::The().Leak().GetCurrent().Leak().GetName();
- NewOS::ProcessScheduler::Shared().Leak().GetCurrent().Leak().Crash();
+ NewOS::ProcessScheduler::The().Leak().GetCurrent().Leak().Crash();
}
diff --git a/Kernel/HALKit/AMD64/HalCoreMultiProcessingAMD64.cpp b/Kernel/HALKit/AMD64/HalCoreMultiProcessingAMD64.cpp
index abd19586..a184efc2 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,19 +108,51 @@ 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;
+ MadtType* madt = (MadtType*)kApicMadt;
+
+ constexpr auto cMaxProbableCores = 4;
+
+ for (SizeT i = 0; i < cMaxProbableCores; ++i)
+ {
+ if (madt->MadtRecords[i].Flags == 0x01) // if local apic.
+ {
+ // then register as a core for scheduler.
+ kcout << "newoskrnl: register core as scheduler thread.\r";
+ }
+ }
}
else
{
- kcout << "New OS: APIC is not present! it is a vital component.\r";
+ kcout << "newoskrnl: APIC is not present! it is a vital component.\r";
ke_stop(RUNTIME_CHECK_FAILED);
}
}
diff --git a/Kernel/HALKit/AMD64/HalDebugOutput.cxx b/Kernel/HALKit/AMD64/HalDebugOutput.cxx
index 3cec26df..22d5c072 100644
--- a/Kernel/HALKit/AMD64/HalDebugOutput.cxx
+++ b/Kernel/HALKit/AMD64/HalDebugOutput.cxx
@@ -132,7 +132,7 @@ namespace NewOS
#endif // __DEBUG__
}
- TerminalDevice& TerminalDevice::Shared() noexcept
+ TerminalDevice& TerminalDevice::The() noexcept
{
static TerminalDevice* out = nullptr;
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..4916d845 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 is present now.\r";
+
+ 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;
+ }
+ else
+ {
+ kcout << "PM is already present.\r";
+
+ kcout << "PhysicalAddress: " << 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;
+ }
+
+ 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;
+
+ 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
diff --git a/Kernel/HALKit/AMD64/Storage/AHCI.cxx b/Kernel/HALKit/AMD64/Storage/AHCI.cxx
index 93cef10c..a8045617 100644
--- a/Kernel/HALKit/AMD64/Storage/AHCI.cxx
+++ b/Kernel/HALKit/AMD64/Storage/AHCI.cxx
@@ -43,7 +43,7 @@ NewOS::Boolean drv_std_init(NewOS::UInt16& PortsImplemented)
iterator[devIndex].Leak().EnableMmio(); /// enable the memory i/o for this ahci device.
kAhciDevice = iterator[devIndex].Leak(); /// and then leak the reference.
- kcout << "New Kernel: [PCI] Found AHCI controller.\r";
+ kcout << "newoskrnl: [PCI] Found AHCI controller.\r";
return true;
}