Files
2026-10-27 09:28:31 +01:00

129 lines
4.9 KiB
C

// Kernel HAL binding and generic platform-operation wrappers.
#include <stdbool.h>
#include <kernel/ke_hal.h>
static const HAL_API* gHal;
// Binds the bootstrap HAL table before kernel code begins using interrupt-state primitives.
KSTATUS KeBindBootstrapHal(void) {
const HAL_API* hal = HalGetApi();
if (!hal || hal->Size != sizeof(HAL_API) || hal->Version != HAL_API_VERSION ||
!hal->Processor.DisableInterrupts || !hal->Processor.RestoreInterrupts ||
!hal->Processor.EnableInterrupts || !hal->Processor.WaitForInterrupt ||
!hal->Processor.Halt || !hal->Processor.Stop) {
return NTLSTATUS_INVALID_PARAMETER;
}
gHal = hal;
return NTLSTATUS_SUCCESS;
}
// Returns whether the initialized table contains every mandatory kernel platform service.
static bool KiHalRuntimeTableValid(const HAL_API* hal) {
return hal && hal->Size == sizeof(HAL_API) && hal->Version == HAL_API_VERSION &&
hal->Processor.DisableInterrupts && hal->Processor.RestoreInterrupts &&
hal->Processor.EnableInterrupts && hal->Processor.WaitForInterrupt &&
hal->Processor.Halt && hal->Processor.Stop && hal->Processor.QueryTopology &&
hal->Processor.Start &&
hal->Screen.GetFramebuffer &&
hal->Output.RegisterEndpoint && hal->Output.Write && hal->Output.QueryStats &&
hal->Timer.QueryTicks && hal->Timer.QueryTickFrequency && hal->Timer.Stall &&
hal->Timer.HandleInterrupt && hal->Timer.ConfigureCurrentProcessor &&
hal->Rtc.QueryTime && hal->Pci.Read32 && hal->Pci.Write32 &&
hal->InterruptController.RouteGsi && hal->InterruptController.MaskGsi &&
hal->InterruptController.ResolveIsa && hal->InterruptController.SendEoi &&
hal->InterruptController.SetTaskPriority && hal->InterruptController.QueryTaskPriority &&
hal->InterruptController.VectorPending &&
hal->InterruptController.InitializeCurrentProcessor &&
hal->InterruptController.SendProcessorInterrupt &&
hal->InterruptController.SendProcessorNmi && hal->InterruptController.BroadcastNmi &&
hal->InterruptController.ComposeMsi && hal->Power.Shutdown;
}
// Initializes the HAL and validates every mandatory runtime service consumed by the kernel.
KSTATUS KeInitializeHal(const HAL_INIT_PARAMS* params) {
if (!gHal || !params)
return NTLSTATUS_INVALID_PARAMETER;
KSTATUS status = HalInitialize(params);
if (!KSUCCESS(status))
return status;
const HAL_API* hal = HalGetApi();
if (hal != gHal || !KiHalRuntimeTableValid(hal))
return NTLSTATUS_INVALID_PARAMETER;
return NTLSTATUS_SUCCESS;
}
// Returns the bound HAL table.
const HAL_API* KeGetHal(void) {
return gHal;
}
// Masks interrupts and returns the previous processor flags.
__declspec(dllexport) uintptr_t KeDisableInterrupts(void) {
return gHal->Processor.DisableInterrupts();
}
// Restores a previously saved processor interrupt state.
__declspec(dllexport) void KeRestoreInterrupts(uintptr_t flags) {
gHal->Processor.RestoreInterrupts(flags);
}
// Enables maskable interrupts on the current processor.
void KeEnableInterrupts(void) {
gHal->Processor.EnableInterrupts();
}
// Enables interrupts and waits for the next interrupt on the current processor.
void KeWaitForInterrupt(void) {
gHal->Processor.WaitForInterrupt();
}
// Halts the current processor once without changing interrupt state.
void KeHaltProcessor(void) {
gHal->Processor.Halt();
}
// Permanently stops the current processor.
_Noreturn void KeStopProcessor(void) {
gHal->Processor.Stop();
for (;;) {
}
}
// Queries platform processor topology without exposing interrupt-controller details.
KSTATUS KeQueryProcessorTopology(HAL_PROCESSOR_TOPOLOGY* topologyOut) {
return gHal->Processor.QueryTopology(topologyOut);
}
// Starts one processor at a physical bootstrap entry address.
KSTATUS KeStartProcessor(uint32_t hardwareId, uintptr_t startPhysical) {
return gHal->Processor.Start(hardwareId, startPhysical);
}
// Initializes the current processor's local interrupt-controller state.
void KeInitializeCurrentProcessorInterruptController(void) {
gHal->InterruptController.InitializeCurrentProcessor();
}
// Sends one fixed-vector interrupt to a processor hardware ID.
void KeSendProcessorInterrupt(uint32_t hardwareId, uint8_t vector) {
gHal->InterruptController.SendProcessorInterrupt(hardwareId, vector);
}
// Sends one non-maskable interrupt to a processor hardware ID.
void KeSendProcessorNmi(uint32_t hardwareId) {
gHal->InterruptController.SendProcessorNmi(hardwareId);
}
// Sends a non-maskable interrupt to every other processor.
void KeBroadcastProcessorNmi(void) {
gHal->InterruptController.BroadcastNmi();
}
// Arms the calibrated periodic timer on the current processor.
void KeConfigureCurrentProcessorTimer(void) {
gHal->Timer.ConfigureCurrentProcessor();
}