summaryrefslogtreecommitdiffhomepage
path: root/dev/ZKA/HALKit
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal.elmahrouss@icloud.com>2024-08-27 19:37:29 +0200
committerAmlal El Mahrouss <amlal.elmahrouss@icloud.com>2024-08-27 19:37:29 +0200
commitc9e0e4b6058f833f39c2193e217dc38f4edd8b82 (patch)
tree7eadd57a88b51fc70ffd2668c7adc29386650e91 /dev/ZKA/HALKit
parentfdbcbba07cac3dbf9ef377f2f5248dd662f6babd (diff)
[WIP] Finishing SMP support, and then working on system driver and
loader. Signed-off-by: Amlal El Mahrouss <amlal.elmahrouss@icloud.com>
Diffstat (limited to 'dev/ZKA/HALKit')
-rw-r--r--dev/ZKA/HALKit/AMD64/HalACPIFactoryInterface.cxx116
-rw-r--r--dev/ZKA/HALKit/AMD64/HalCoreMultiProcessingAMD64.cxx25
-rw-r--r--dev/ZKA/HALKit/AMD64/HalDescriptorLoader.cxx4
-rw-r--r--dev/ZKA/HALKit/AMD64/HalInterruptAPI.asm16
-rw-r--r--dev/ZKA/HALKit/AMD64/HalKernelMouse.cxx190
-rw-r--r--dev/ZKA/HALKit/AMD64/HalTimer.cxx55
6 files changed, 143 insertions, 263 deletions
diff --git a/dev/ZKA/HALKit/AMD64/HalACPIFactoryInterface.cxx b/dev/ZKA/HALKit/AMD64/HalACPIFactoryInterface.cxx
index 28b26223..37b1375f 100644
--- a/dev/ZKA/HALKit/AMD64/HalACPIFactoryInterface.cxx
+++ b/dev/ZKA/HALKit/AMD64/HalACPIFactoryInterface.cxx
@@ -12,53 +12,101 @@
namespace Kernel
{
- /// Custom to the virtual machine, you'll need to parse the MADT instead.
-
- void rt_shutdown_acpi_qemu_20(void)
+ namespace Detail
{
- HAL::Out16(0xb004, 0x2000);
- }
-
- void rt_shutdown_acpi_qemu_30_plus(void)
- {
- HAL::Out16(0x604, 0x2000);
- }
-
- void rt_shutdown_acpi_virtualbox(void)
- {
- HAL::Out16(0x4004, 0x3400);
- }
-
- /// You have to parse the MADT!
+ struct FADT final : public SDT
+ {
+ UInt32 FirmwareCtrl;
+ UInt32 Dsdt;
+
+ // field used in ACPI 1.0; no longer in use, for compatibility only
+ UInt8 Reserved;
+
+ UInt8 PreferredPowerManagementProfile;
+ UInt16 SCI_Interrupt;
+ UInt32 SMI_CommandPort;
+ UInt8 AcpiEnable;
+ UInt8 AcpiDisable;
+ UInt8 S4BIOS_REQ;
+ UInt8 PSTATE_Control;
+ UInt32 PM1aEventBlock;
+ UInt32 PM1bEventBlock;
+ UInt32 PM1aControlBlock;
+ UInt32 PM1bControlBlock;
+ UInt32 PM2ControlBlock;
+ UInt32 PMTimerBlock;
+ UInt32 GPE0Block;
+ UInt32 GPE1Block;
+ UInt8 PM1EventLength;
+ UInt8 PM1ControlLength;
+ UInt8 PM2ControlLength;
+ UInt8 PMTimerLength;
+ UInt8 GPE0Length;
+ UInt8 GPE1Length;
+ UInt8 GPE1Base;
+ UInt8 CStateControl;
+ UInt16 WorstC2Latency;
+ UInt16 WorstC3Latency;
+ UInt16 FlushSize;
+ UInt16 FlushStride;
+ UInt8 DutyOffset;
+ UInt8 DutyWidth;
+ UInt8 DayAlarm;
+ UInt8 MonthAlarm;
+ UInt8 Century;
+
+ // reserved in ACPI 1.0; used since ACPI 2.0+
+ UInt16 BootArchitectureFlags;
+
+ UInt8 Reserved2;
+ UInt32 Flags;
+
+ // 12 byte structure; see below for details
+ ACPI_ADDRESS ResetReg;
+
+ UInt8 ResetValue;
+ UInt8 Reserved3[3];
+
+ // 64bit pointers - Available on ACPI 2.0+
+ UInt64 X_FirmwareControl;
+ UInt64 X_Dsdt;
+
+ ACPI_ADDRESS X_PM1aEventBlock;
+ ACPI_ADDRESS X_PM1bEventBlock;
+ ACPI_ADDRESS X_PM1aControlBlock;
+ ACPI_ADDRESS X_PM1bControlBlock;
+ ACPI_ADDRESS X_PM2ControlBlock;
+ ACPI_ADDRESS X_PMTimerBlock;
+ ACPI_ADDRESS X_GPE0Block;
+ ACPI_ADDRESS X_GPE1Block;
+ };
+ } // namespace Detail
ACPIFactoryInterface::ACPIFactoryInterface(VoidPtr rsdPtr)
: fRsdp(rsdPtr), fEntries(0)
{
-#ifdef __DEBUG__
- kcout << "newoskrnl: ACPI: init interface.\r";
-#else
-
-#endif
}
Void ACPIFactoryInterface::Shutdown()
{
-#ifdef __DEBUG__
- rt_shutdown_acpi_qemu_30_plus();
-#else
-
-#endif
+ failed_to_shutdown:
+ // in case no acpi mode, or it's not available.
+ while (Yes)
+ {
+ asm volatile("cli; hlt");
+ }
}
- /// @brief Reboot (shutdowns on qemu.)
- /// @return
+ /// @brief Reboot machine in either ACPI or by triple faulting.
+ /// @return nothing it's a reboot.
Void ACPIFactoryInterface::Reboot()
{
-#ifdef __DEBUG__
- rt_shutdown_acpi_qemu_30_plus();
-#else
-
-#endif
+ failed_to_reboot:
+ // in case no acpi mode, or it's not available.
+ while (Yes)
+ {
+ asm volatile("cli; hlt");
+ }
}
/// @brief Finds a descriptor table inside ACPI XSDT.
diff --git a/dev/ZKA/HALKit/AMD64/HalCoreMultiProcessingAMD64.cxx b/dev/ZKA/HALKit/AMD64/HalCoreMultiProcessingAMD64.cxx
index d11d1c8c..512ee483 100644
--- a/dev/ZKA/HALKit/AMD64/HalCoreMultiProcessingAMD64.cxx
+++ b/dev/ZKA/HALKit/AMD64/HalCoreMultiProcessingAMD64.cxx
@@ -12,6 +12,8 @@
#include <KernelKit/ProcessScheduler.hxx>
#include <KernelKit/Timer.hxx>
+#include <Modules/CoreCG/TextRenderer.hxx>
+
// Needed for SMP. //
#include <KernelKit/MP.hxx>
@@ -45,7 +47,7 @@ namespace Kernel::HAL
STATIC Void hal_switch_context(HAL::StackFramePtr stack_frame);
- STATIC MADT_TABLE* kMADTBlock = nullptr;
+ STATIC struct MADT_TABLE* kMADTBlock = nullptr;
STATIC Bool kSMPAware = false;
STATIC Int64 kSMPCount = 0;
@@ -114,7 +116,7 @@ namespace Kernel::HAL
/// @param targetAddress
/// @return
/***********************************************************************************/
-
+
Void hal_send_start_ipi(UInt32 apicId, UInt8 vector, UInt32 targetAddress)
{
Kernel::ke_dma_write(targetAddress, kAPIC_ICR_High, (apicId << 24));
@@ -130,13 +132,14 @@ namespace Kernel::HAL
/***********************************************************************************/
Void hal_send_end_ipi(UInt32 apicId, UInt8 vector, UInt32 targetAddress)
{
- Kernel::ke_dma_write(targetAddress, kAPIC_ICR_High, apicId << 24);
+ Kernel::ke_dma_write(targetAddress, kAPIC_ICR_High, (apicId << 24));
Kernel::ke_dma_write(targetAddress, kAPIC_ICR_Low, kAPIC_EIPI_Vector | vector);
}
/// @internal
EXTERN_C Void hal_ap_startup(Void)
{
+ CGDrawString("100", 10, 50, RGB(0x00, 0x00, 0x00));
ke_stop(RUNTIME_CHECK_BOOTSTRAP);
}
@@ -200,6 +203,8 @@ namespace Kernel::HAL
kcout << "newoskrnl: Probing MADT cores...\r";
+ UIntPtr madt_address = kMADTBlock->Address;
+
while (Yes)
{
if (kMADTBlock->List[index].Type == 0 ||
@@ -210,14 +215,21 @@ namespace Kernel::HAL
{
case 0x01: {
cSMPCores[index] = kMADTBlock->List[index].IOAPIC.IoID;
+ kcout << "newoskrnl: Core ID: " << number(cSMPCores[index]) << endl;
++kSMPCount;
break;
}
case 0x02: {
cSMPCores[index] = kMADTBlock->List[index].LAPIC.ProcessorID;
+ kcout << "newoskrnl: Core ID: " << number(cSMPCores[index]) << endl;
++kSMPCount;
break;
}
+ case 0x05: {
+ madt_address = kMADTBlock->List[index].LAPIC_ADDRESS_OVERRIDE.Address;
+ kcout << "newoskrnl: Address: " << number(madt_address) << endl;
+ break;
+ }
}
++index;
@@ -226,7 +238,14 @@ namespace Kernel::HAL
kcout << "newoskrnl: # of cores: " << number(kSMPCount) << endl;
kcout << "newoskrnl: First core ID: " << number(cSMPCores[0]) << endl;
+ // Kernel is now SMP aware.
+ // That means that the scheduler is now available (on MP kernels)
+
kSMPAware = true;
+
+ // This is used to start the
+ hal_send_end_ipi(cSMPCores[0], 0x34, madt_address);
+ hal_send_start_ipi(cSMPCores[0], 0x34, madt_address);
}
}
} // namespace Kernel::HAL
diff --git a/dev/ZKA/HALKit/AMD64/HalDescriptorLoader.cxx b/dev/ZKA/HALKit/AMD64/HalDescriptorLoader.cxx
index 678b0896..11f9f249 100644
--- a/dev/ZKA/HALKit/AMD64/HalDescriptorLoader.cxx
+++ b/dev/ZKA/HALKit/AMD64/HalDescriptorLoader.cxx
@@ -55,8 +55,6 @@ namespace Kernel::HAL
MUST_PASS(baseIdt);
- Detail::hal_remap_intel_pic_ctrl();
-
for (UInt16 i = 0; i < kKernelIdtSize; ++i)
{
MUST_PASS(baseIdt[i]);
@@ -77,6 +75,8 @@ namespace Kernel::HAL
(kKernelIdtSize - 1);
hal_load_idt(Detail::kRegIdt);
+
+ Detail::hal_remap_intel_pic_ctrl();
}
void GDTLoader::Load(Ref<RegisterGDT>& gdt)
diff --git a/dev/ZKA/HALKit/AMD64/HalInterruptAPI.asm b/dev/ZKA/HALKit/AMD64/HalInterruptAPI.asm
index 0c79be81..9a637b8a 100644
--- a/dev/ZKA/HALKit/AMD64/HalInterruptAPI.asm
+++ b/dev/ZKA/HALKit/AMD64/HalInterruptAPI.asm
@@ -35,7 +35,6 @@ __NEW_INT_%1:
global ke_handle_irq
global kInterruptVectorTable
-extern hal_handle_mouse
extern idt_handle_gpf
extern idt_handle_pf
extern ke_io_write
@@ -107,7 +106,9 @@ IntNormal 18
IntNormal 19
IntNormal 20
IntNormal 21
+
IntNormal 22
+
IntNormal 23
IntNormal 24
IntNormal 25
@@ -115,7 +116,8 @@ IntNormal 26
IntNormal 27
IntNormal 28
IntNormal 29
-IntExp 30
+
+IntExp 30
IntNormal 31
@@ -132,15 +134,7 @@ IntNormal 40
IntNormal 41
IntNormal 42
IntNormal 43
-
-__NEW_INT_44:
- cli
-
- call hal_handle_mouse
-
- sti
- iretq
-
+IntNormal 44
IntNormal 45
IntNormal 46
IntNormal 47
diff --git a/dev/ZKA/HALKit/AMD64/HalKernelMouse.cxx b/dev/ZKA/HALKit/AMD64/HalKernelMouse.cxx
deleted file mode 100644
index 06cdc81b..00000000
--- a/dev/ZKA/HALKit/AMD64/HalKernelMouse.cxx
+++ /dev/null
@@ -1,190 +0,0 @@
-/* -------------------------------------------
-
- Copyright ZKA Technologies.
-
-------------------------------------------- */
-
-#include <Modules/PS2/PS2MouseInterface.hxx>
-#include <Modules/CoreCG/FbRenderer.hxx>
-#include <Modules/CoreCG/Rsrc/Cursor.rsrc>
-#include <KernelKit/Framebuffer.hxx>
-#include <NewKit/Defines.hxx>
-
-/// @note forward decl.
-EXTERN_C Kernel::Boolean _hal_draw_mouse();
-EXTERN_C Kernel::Void _hal_init_mouse();
-
-STATIC Kernel::Int32 kPrevX = 10;
-STATIC Kernel::Int32 kPrevY = 10;
-STATIC Kernel::Int32 kX = 10;
-STATIC Kernel::Int32 kY = 10;
-STATIC Kernel::Int32 kMouseCycle = 0;
-STATIC Kernel::Char kMousePacket[4] = {};
-STATIC Kernel::Boolean kMousePacketReady = false;
-
-STATIC CGInit();
-
-#define kPS2Leftbutton 0b00000001
-#define kPS2Middlebutton 0b00000010
-#define kPS2Rightbutton 0b00000100
-#define kPS2XSign 0b00010000
-#define kPS2YSign 0b00100000
-#define kPS2XOverflow 0b01000000
-#define kPS2YOverflow 0b10000000
-
-using namespace Kernel;
-
-EXTERN_C Void hal_handle_mouse()
-{
- Kernel::UInt8 data = HAL::In8(0x60);
-
- switch (kMouseCycle)
- {
- case 0:
- if (kMousePacketReady)
- break;
- if ((data & 0b00001000) == 0)
- break;
- kMousePacket[0] = data;
- kMouseCycle++;
- break;
- case 1:
- if (kMousePacketReady)
- break;
- kMousePacket[1] = data;
- kMouseCycle++;
- break;
- case 2:
- if (kMousePacketReady)
- break;
- kMousePacket[2] = data;
- kMousePacketReady = true;
- kMouseCycle = 0;
- break;
- }
-
- // Notify PIC controller that we're done with it's interrupt.
-
- Kernel::HAL::Out8(0x20, 0x20);
- Kernel::HAL::Out8(0xA0, 0x20);
-}
-
-EXTERN_C Boolean _hal_left_button_pressed()
-{
- return kMousePacket[0] & kPS2Leftbutton;
-}
-EXTERN_C Boolean _hal_right_button_pressed()
-{
- return kMousePacket[0] & kPS2Rightbutton;
-}
-EXTERN_C Boolean _hal_middle_button_pressed()
-{
- return kMousePacket[0] & kPS2Middlebutton;
-}
-
-/// @brief Draws the kernel's mouse.
-EXTERN_C Boolean _hal_draw_mouse()
-{
- if (!kMousePacketReady)
- return false;
-
- bool xNegative, yNegative, xOverflow, yOverflow;
-
- if (kMousePacket[0] & kPS2XSign)
- {
- xNegative = true;
- }
- else
- xNegative = false;
-
- if (kMousePacket[0] & kPS2YSign)
- {
- yNegative = true;
- }
- else
- yNegative = false;
-
- if (kMousePacket[0] & kPS2XOverflow)
- {
- xOverflow = true;
- }
- else
- xOverflow = false;
-
- if (kMousePacket[0] & kPS2YOverflow)
- {
- yOverflow = true;
- }
- else
- yOverflow = false;
-
- if (!xNegative)
- {
- kX += kMousePacket[1];
- if (xOverflow)
- {
- kX += 255;
- }
- }
- else
- {
- kMousePacket[1] = 256 - kMousePacket[1];
- kX -= kMousePacket[1];
- if (xOverflow)
- {
- kX -= 255;
- }
- }
-
- if (!yNegative)
- {
- kY -= kMousePacket[2];
- if (yOverflow)
- {
- kY -= 255;
- }
- }
- else
- {
- kMousePacket[2] = 256 - kMousePacket[2];
- kY += kMousePacket[2];
- if (yOverflow)
- {
- kY += 255;
- }
- }
-
- if (kX < 0)
- kX = 0;
- if (kX > kHandoverHeader->f_GOP.f_Width - 8)
- kX = kHandoverHeader->f_GOP.f_Width - 8;
-
- if (kY < 0)
- kY = 0;
- if (kY > kHandoverHeader->f_GOP.f_Height - 16)
- kY = kHandoverHeader->f_GOP.f_Height - 16;
-
- /// Draw mouse here.
-
- kPrevX = kX;
- kPrevY = kY;
-
- CGDrawBitMapInRegionA(Cursor, cCurHeight, cCurWidth, kY, kX);
-
- kMousePacketReady = false;
- return true;
-}
-
-/// @brief Init kernel mouse.
-EXTERN_C Void _hal_init_mouse()
-{
- kPrevX = 10;
- kPrevY = 10;
- kX = 10;
- kY = 10;
- kMouseCycle = 0;
- kMousePacketReady = false;
-
- Kernel::PS2MouseInterface ps2_mouse;
- ps2_mouse.Init();
-}
diff --git a/dev/ZKA/HALKit/AMD64/HalTimer.cxx b/dev/ZKA/HALKit/AMD64/HalTimer.cxx
index e6e21a67..33b0e00f 100644
--- a/dev/ZKA/HALKit/AMD64/HalTimer.cxx
+++ b/dev/ZKA/HALKit/AMD64/HalTimer.cxx
@@ -15,25 +15,31 @@
#include <ArchKit/ArchKit.hxx>
#include <KernelKit/Timer.hxx>
+// timer slot 0
+
+#define cHPETCounterValue (0x0f0 * 0x20)
+#define cHPETConfigValue (0x010 * 0x20)
+#define cHPETCompValue (0x108 * 0x20)
+
///! BUGS: 0
///! @file HalTimer.cxx
-///! @brief Hardware Timer.
+///! @brief Hardware Timer (HPET)
namespace Kernel::Detail
{
struct HPET_BLOCK : public Kernel::SDT
{
- Kernel::UInt8 hardware_rev_id;
- Kernel::UInt8 comparator_count : 5;
- Kernel::UInt8 counter_size : 1;
- Kernel::UInt8 reserved : 1;
- Kernel::UInt8 legacy_replacement : 1;
- Kernel::UInt16 pci_vendor_id;
- Kernel::ACPI_ADDRESS address;
- Kernel::UInt8 hpet_number;
- Kernel::UInt16 minimum_tick;
- Kernel::UInt8 page_protection;
- } __attribute__((packed));
+ Kernel::UInt8 hardware_rev_id;
+ Kernel::UInt8 comparator_count : 5;
+ Kernel::UInt8 counter_size : 1;
+ Kernel::UInt8 reserved : 1;
+ Kernel::UInt8 legacy_replacement : 1;
+ Kernel::UInt16 pci_vendor_id;
+ ACPI_ADDRESS address;
+ Kernel::UInt8 hpet_number;
+ Kernel::UInt16 minimum_tick;
+ Kernel::UInt8 page_protection;
+ } PACKED;
} // namespace Kernel::Detail
using namespace Kernel;
@@ -43,9 +49,10 @@ HardwareTimer::HardwareTimer(Int64 ms)
{
auto power = PowerFactoryInterface(kHandoverHeader->f_HardwareTables.f_VendorPtr);
- auto hpet = (Detail::HPET_BLOCK*)power.Find("HPET").Leak().Leak();
+ auto hpet = (Detail::HPET_BLOCK*)power.Find("HPET").Leak().Leak();
+ MUST_PASS(hpet);
+
fDigitalTimer = (IntPtr*)hpet->address.Address;
- MUST_PASS(fDigitalTimer);
}
HardwareTimer::~HardwareTimer()
@@ -59,19 +66,21 @@ Int32 HardwareTimer::Wait() noexcept
if (fWaitFor < 1)
return -1;
- UInt32 minimum_tick = *(fDigitalTimer) >> 32;
-
- const UInt64 cLimitVal = 0x10000000000000;
+ // if not enabled yet.
+ if (!(*(fDigitalTimer + cHPETConfigValue) & (1 << 0)))
+ {
+ *(fDigitalTimer + cHPETConfigValue) |= (1 << 0); // enable it
+ *(fDigitalTimer + cHPETConfigValue) |= (1 << 3); // one shot conf
+ }
- UInt64 microsecond = fWaitFor / minimum_tick;
+ UInt64 ticks = fWaitFor / ((*(fDigitalTimer) >> 32) & __UINT32_MAX__);
- *(fDigitalTimer + 0x0f0) = cLimitVal - microsecond;
- *(fDigitalTimer + 0x010) = 0x1;
+ auto prev = *(fDigitalTimer + cHPETCounterValue);
- kcout << "MS: " << number(microsecond) << endl;
+ *(fDigitalTimer + cHPETCompValue) = prev + ticks;
- while (*(fDigitalTimer + 0x0f0) <= cLimitVal)
- ;
+ while (*(fDigitalTimer + cHPETCounterValue) < (ticks))
+ kcout << "MS: " << number(*(fDigitalTimer + cHPETCounterValue)) << endl;
return 0;
}