diff options
Diffstat (limited to 'dev/ZKA/HALKit')
| -rw-r--r-- | dev/ZKA/HALKit/AMD64/HalACPIFactoryInterface.cxx | 116 | ||||
| -rw-r--r-- | dev/ZKA/HALKit/AMD64/HalCoreMultiProcessingAMD64.cxx | 25 | ||||
| -rw-r--r-- | dev/ZKA/HALKit/AMD64/HalDescriptorLoader.cxx | 4 | ||||
| -rw-r--r-- | dev/ZKA/HALKit/AMD64/HalInterruptAPI.asm | 16 | ||||
| -rw-r--r-- | dev/ZKA/HALKit/AMD64/HalKernelMouse.cxx | 190 | ||||
| -rw-r--r-- | dev/ZKA/HALKit/AMD64/HalTimer.cxx | 55 |
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;
}
|
