replace nob with ms' build, move disk creation to build.bat, major comment cleanup, remove old and stupid tests, overhaul interrupt management with per-CPU vector allocation, affinity migration and safe teardown, add proper IOAPIC routing and PCI MSI/MSI-X/INTx support, migrate drivers to the new interrupt API, integrate ACPICA with a proper OS services layer, move ACPI firmware events, power button handling and S5 shutdown into acpi.sys, add parallel driver startup and atomic publication, replace PnP arrays with dynamic lists, redesign service startup again to be asynchronous, add delayed startup mode for services, allow omitting keys in services.ini, fix acpi ec deferred work handling, fix kernel threads having garbage exit code.

This commit is contained in:
maksw committed 2026-10-28 15:18:43 +01:00
1 parent d36f19509c
commit 36eef8f58d
696 files changed
+147281 -7530

No files matched your search

+1
View File
@@ -20,6 +20,7 @@
#include <ntlite/ddk/mutex.h>
#include <ntlite/ddk/object.h>
#include <ntlite/ddk/platform.h>
#include <ntlite/ddk/power.h>
#include <ntlite/ddk/scheduler.h>
#include <ntlite/ddk/semaphore.h>
#include <ntlite/ddk/settings.h>
+2 -1
View File
@@ -15,11 +15,12 @@
#define KE_DEBUG_POOL_CALLERS 0x00000040u // Track pool allocation/free callers.
#define KE_DEBUG_DISPLAY_ASSERTS 0x00000080u // Enable display-path consistency assertions.
#define KE_DEBUG_LIST_CHECKS 0x00000100u // Validate intrusive-list links on mutation.
#define KE_DEBUG_ACPI_INFO 0x00000200u // Include ACPICA informational output.
#define KE_DEBUG_VALID_MASK (KE_DEBUG_CONSOLE | KE_DEBUG_SELFTEST | KE_DEBUG_FILE_LOG | \
KE_DEBUG_POOL_CANARY | KE_DEBUG_POOL_POISON | \
KE_DEBUG_POOL_QUARANTINE | KE_DEBUG_POOL_CALLERS | \
KE_DEBUG_DISPLAY_ASSERTS | KE_DEBUG_LIST_CHECKS)
KE_DEBUG_DISPLAY_ASSERTS | KE_DEBUG_LIST_CHECKS | KE_DEBUG_ACPI_INFO)
+44 -9
View File
@@ -1,22 +1,57 @@
// Public nt-lite DDK interrupt declarations.
// Kernel interrupt objects and platform source registration.
#pragma once
#include <stdint.h>
#include <ntlite/status.h>
typedef struct KE_INTERRUPT KE_INTERRUPT;
typedef void (*KE_INTERRUPT_ROUTINE)(void* context);
typedef struct KE_INTERRUPT_INFO {
uint32_t CpuIndex;
uint32_t HardwareId;
uint32_t Gsi;
uint16_t Flags;
uint8_t Vector;
uint8_t IsMessage;
uint64_t Delivered;
} KE_INTERRUPT_INFO;
typedef enum KE_INTERRUPT_MESSAGE_OPERATION {
KeInterruptMessageQuiesce = 1,
KeInterruptMessageProgram,
KeInterruptMessageResume
} KE_INTERRUPT_MESSAGE_OPERATION;
typedef struct NTL_DDK_MSI_MESSAGE {
uint64_t Address;
uint32_t Data;
uint32_t Reserved;
} NTL_DDK_MSI_MESSAGE;
// Only the bus owner programs a device's message source. The interrupt manager
// selects CPUs/vectors and coordinates quiescence with this device callback.
typedef KSTATUS (*KE_INTERRUPT_MESSAGE_PROGRAM)(void* context,
KE_INTERRUPT_MESSAGE_OPERATION operation, const NTL_DDK_MSI_MESSAGE* message);
// The platform owns GSI routing and ISA overrides; drivers own only their handler.
__declspec(dllexport) KSTATUS KeInterruptConnectGsi(uint32_t gsi, uint16_t flags,
uint64_t affinity, KE_INTERRUPT_ROUTINE routine, void* context, KE_INTERRUPT** out);
__declspec(dllexport) KSTATUS KeInterruptConnectIsa(uint8_t isaIrq, uint16_t sourceFlags, uint64_t affinity,
KE_INTERRUPT_ROUTINE routine, void* context, KE_INTERRUPT** out);
// Allocates one kernel IRQ slot for MSI delivery.
__declspec(dllexport) KSTATUS KeIrqAllocateMsiVector(uint8_t* outIrq);
// Registers a legacy interrupt handler for an IRQ slot.
__declspec(dllexport) void KeIrqRegister(uint8_t irq, void (*handler)(void));
__declspec(dllexport) KSTATUS KeIrqComposeMsiMessage(uint8_t irq, NTL_DDK_MSI_MESSAGE* messageOut);
// PCI enables the device's MSI/MSI-X source after reserving the CPU/vector route.
__declspec(dllexport) KSTATUS KeInterruptReserveMessage(uint64_t affinity,
KE_INTERRUPT_ROUTINE routine, void* context, KE_INTERRUPT** out);
__declspec(dllexport) KSTATUS KeInterruptComposeMessage(const KE_INTERRUPT* interrupt,
NTL_DDK_MSI_MESSAGE* out);
__declspec(dllexport) KSTATUS KeInterruptQuery(const KE_INTERRUPT* interrupt, KE_INTERRUPT_INFO* out);
__declspec(dllexport) KSTATUS KeInterruptBindMessageSource(KE_INTERRUPT* interrupt,
KE_INTERRUPT_MESSAGE_PROGRAM program, void* context);
__declspec(dllexport) KSTATUS KeInterruptActivateMessage(KE_INTERRUPT* interrupt);
__declspec(dllexport) KSTATUS KeInterruptSetAffinity(KE_INTERRUPT* interrupt,
uint64_t permittedCpuMask);
// Bus drivers close a route before disabling its source, serializing migration.
__declspec(dllexport) void KeInterruptBeginDisconnect(KE_INTERRUPT* interrupt);
// Disconnect waits for active handlers and requires PASSIVE_LEVEL.
__declspec(dllexport) void KeInterruptDisconnect(KE_INTERRUPT* interrupt);
+5
View File
@@ -83,3 +83,8 @@ __declspec(dllexport) void* MmReallocatePool(void* ptr, size_t newSize);
__declspec(dllexport) void* MmDdkPhysToVirt(uint64_t physicalAddress);
__declspec(dllexport) KSTATUS MmDdkMapPage(uintptr_t virtualAddress, uint64_t physicalAddress, uint64_t flags, NTL_DDK_MAP_MODE mode);
// UC device mapping with a private kernel VA and an exact matching unmap.
// Use in thread context. Returned mappings must be released with their length.
__declspec(dllexport) KSTATUS MmDdkMapIoMemory(uint64_t physicalAddress, size_t length, void** outVirtual);
__declspec(dllexport) KSTATUS MmDdkUnmapIoMemory(void* virtualAddress, size_t length);
+37 -17
View File
@@ -6,10 +6,12 @@
#define NTL_DDK_MODULE_EXPORT_NAME "NtlDriverModule"
#define NTL_DDK_MODULE_SIGNATURE 0x324D444Eu // "NDM2" in little-endian memory.
#define NTL_DDK_MODULE_ABI_VERSION 5u
#define NTL_DDK_MODULE_ABI_VERSION 6u
typedef struct NTL_MODULE NTL_MODULE;
typedef KSTATUS (*NTL_MODULE_INITIALIZE)(NTL_MODULE* module);
typedef KSTATUS (*NTL_MODULE_PREPARE_START)(NTL_MODULE* module);
typedef void (*NTL_MODULE_COMMIT_START)(NTL_MODULE* module);
typedef void (*NTL_MODULE_ABORT_START)(NTL_MODULE* module);
typedef KSTATUS (*NTL_MODULE_PREPARE_SHUTDOWN)(NTL_MODULE* module);
typedef void (*NTL_MODULE_COMMIT_SHUTDOWN)(NTL_MODULE* module);
@@ -20,7 +22,7 @@ typedef struct NTL_MODULE_EXPORT {
uint32_t Version;
uint32_t Size;
uint32_t Flags;
NTL_MODULE_INITIALIZE Initialize;
NTL_MODULE_PREPARE_START PrepareStart;
const NTL_DEVICE_DESC* Devices;
uint32_t DeviceCount;
uint32_t Reserved;
@@ -29,49 +31,67 @@ typedef struct NTL_MODULE_EXPORT {
uint32_t Reserved2;
NTL_MODULE_PREPARE_SHUTDOWN PrepareShutdown;
NTL_MODULE_COMMIT_SHUTDOWN CommitShutdown;
NTL_MODULE_COMMIT_START CommitStart;
NTL_MODULE_ABORT_START AbortStart;
} NTL_MODULE_EXPORT;
#ifdef __cplusplus
static_assert(sizeof(NTL_MODULE_EXPORT) == 72u, "DDK module export ABI changed");
static_assert(sizeof(NTL_MODULE_EXPORT) == 88u, "DDK module export ABI changed");
#define NTL_DDK_C_EXPORT extern "C"
#else
_Static_assert(sizeof(NTL_MODULE_EXPORT) == 72u, "DDK module export ABI changed");
_Static_assert(sizeof(NTL_MODULE_EXPORT) == 88u, "DDK module export ABI changed");
#define NTL_DDK_C_EXPORT
#endif
#define NTL_DECLARE_MODULE(initialize_fn) \
#define NTL_DECLARE_MODULE(prepareFn) \
NTL_DDK_C_EXPORT __declspec(dllexport) const NTL_MODULE_EXPORT NtlDriverModule = { \
NTL_DDK_MODULE_SIGNATURE, NTL_DDK_MODULE_ABI_VERSION, \
(uint32_t)sizeof(NTL_MODULE_EXPORT), 0u, (initialize_fn), 0, 0u, 0u, 0, 0u, 0u, 0, 0 \
(uint32_t)sizeof(NTL_MODULE_EXPORT), 0u, (prepareFn), 0, 0u, 0u, 0, 0u, 0u, 0, 0, 0, 0 \
}
#define NTL_DECLARE_DEVICE_MODULE(deviceArray) \
NTL_DDK_C_EXPORT __declspec(dllexport) const NTL_MODULE_EXPORT NtlDriverModule = { \
NTL_DDK_MODULE_SIGNATURE, NTL_DDK_MODULE_ABI_VERSION, \
(uint32_t)sizeof(NTL_MODULE_EXPORT), 0u, 0, (deviceArray), \
(uint32_t)(sizeof(deviceArray) / sizeof((deviceArray)[0])), 0u, 0, 0u, 0u, 0, 0 \
(uint32_t)(sizeof(deviceArray) / sizeof((deviceArray)[0])), 0u, 0, 0u, 0u, 0, 0, 0, 0 \
}
#define NTL_DECLARE_IO_MODULE(initialize_fn, driverArray) \
#define NTL_DECLARE_IO_MODULE(prepareFn, driverArray) \
NTL_DDK_C_EXPORT __declspec(dllexport) const NTL_MODULE_EXPORT NtlDriverModule = { \
NTL_DDK_MODULE_SIGNATURE, NTL_DDK_MODULE_ABI_VERSION, \
(uint32_t)sizeof(NTL_MODULE_EXPORT), 0u, (initialize_fn), 0, 0u, 0u, \
(driverArray), (uint32_t)(sizeof(driverArray) / sizeof((driverArray)[0])), 0u, 0, 0 \
(uint32_t)sizeof(NTL_MODULE_EXPORT), 0u, (prepareFn), 0, 0u, 0u, \
(driverArray), (uint32_t)(sizeof(driverArray) / sizeof((driverArray)[0])), 0u, 0, 0, 0, 0 \
}
#define NTL_DECLARE_MODULE_WITH_SHUTDOWN(initialize_fn, prepareFn, commitFn) \
#define NTL_DECLARE_MODULE_WITH_SHUTDOWN(startPrepareFn, shutdownPrepareFn, commitFn) \
NTL_DDK_C_EXPORT __declspec(dllexport) const NTL_MODULE_EXPORT NtlDriverModule = { \
NTL_DDK_MODULE_SIGNATURE, NTL_DDK_MODULE_ABI_VERSION, \
(uint32_t)sizeof(NTL_MODULE_EXPORT), 0u, (initialize_fn), 0, 0u, 0u, \
0, 0u, 0u, (prepareFn), (commitFn) \
(uint32_t)sizeof(NTL_MODULE_EXPORT), 0u, (startPrepareFn), 0, 0u, 0u, \
0, 0u, 0u, (shutdownPrepareFn), (commitFn), 0, 0 \
}
#define NTL_DECLARE_IO_MODULE_WITH_SHUTDOWN(initialize_fn, driverArray, prepareFn, commitFn) \
#define NTL_DECLARE_IO_MODULE_WITH_SHUTDOWN(startPrepareFn, driverArray, shutdownPrepareFn, commitFn) \
NTL_DDK_C_EXPORT __declspec(dllexport) const NTL_MODULE_EXPORT NtlDriverModule = { \
NTL_DDK_MODULE_SIGNATURE, NTL_DDK_MODULE_ABI_VERSION, \
(uint32_t)sizeof(NTL_MODULE_EXPORT), 0u, (initialize_fn), 0, 0u, 0u, \
(uint32_t)sizeof(NTL_MODULE_EXPORT), 0u, (startPrepareFn), 0, 0u, 0u, \
(driverArray), (uint32_t)(sizeof(driverArray) / sizeof((driverArray)[0])), 0u, \
(prepareFn), (commitFn) \
(shutdownPrepareFn), (commitFn), 0, 0 \
}
// Prepare may fail. Commit publishes fully prepared state and returns void.
#define NTL_DECLARE_STAGED_MODULE(prepareFn, commitFn, abortFn) \
NTL_DDK_C_EXPORT __declspec(dllexport) const NTL_MODULE_EXPORT NtlDriverModule = { \
NTL_DDK_MODULE_SIGNATURE, NTL_DDK_MODULE_ABI_VERSION, \
(uint32_t)sizeof(NTL_MODULE_EXPORT), 0u, (prepareFn), 0, 0u, 0u, \
0, 0u, 0u, 0, 0, (commitFn), (abortFn) \
}
#define NTL_DECLARE_STAGED_IO_MODULE(prepareFn, driverArray, commitFn, abortFn) \
NTL_DDK_C_EXPORT __declspec(dllexport) const NTL_MODULE_EXPORT NtlDriverModule = { \
NTL_DDK_MODULE_SIGNATURE, NTL_DDK_MODULE_ABI_VERSION, \
(uint32_t)sizeof(NTL_MODULE_EXPORT), 0u, (prepareFn), 0, 0u, 0u, \
(driverArray), (uint32_t)(sizeof(driverArray) / sizeof((driverArray)[0])), \
0u, 0, 0, (commitFn), (abortFn) \
}
// Query the configured module identity; the returned string is borrowed.
+5
View File
@@ -3,6 +3,11 @@
#pragma once
#include <stdint.h>
#include <ntlite/status.h>
__declspec(dllexport) uint32_t KePciReadConfig32(uint16_t segment, uint8_t bus, uint8_t device, uint8_t function, uint16_t offset);
__declspec(dllexport) void KePciWriteConfig32(uint16_t segment, uint8_t bus, uint8_t device, uint8_t function, uint16_t offset, uint32_t value);
// Returns a checksum-validated ACPI RSDP root, independent of its consumer.
// A firmware driver maps the physical tables using the DDK memory interface.
__declspec(dllexport) KSTATUS KeFirmwareQueryAcpiRsdp(uint64_t* physicalAddressOut);
+36
View File
@@ -0,0 +1,36 @@
// Firmware power provider interface for resident platform drivers.
#pragma once
#include <stdint.h>
#include <ntlite/status.h>
// A registered provider remains resident through the final hardware transition.
// Callbacks run in thread context; Enter returns an error if the transition fails.
typedef struct NTL_FIRMWARE_POWER_PROVIDER {
uint32_t Size;
void* Context;
KSTATUS (*Prepare)(void* context, uint32_t action);
KSTATUS (*Enter)(void* context, uint32_t action);
} NTL_FIRMWARE_POWER_PROVIDER;
#ifdef NTL_KERNEL_BUILD
#define NTL_DDK_POWER_API __declspec(dllexport)
#else
#define NTL_DDK_POWER_API __declspec(dllimport)
#endif
#ifdef __cplusplus
extern "C" {
#endif
// Installs one firmware power provider for the lifetime of the boot.
NTL_DDK_POWER_API KSTATUS KeRegisterFirmwarePowerProvider(
const NTL_FIRMWARE_POWER_PROVIDER* provider);
// Reports a physical button press from a firmware driver's worker context.
NTL_DDK_POWER_API KSTATUS KeNotifyPowerButton(void);
#ifdef __cplusplus
}
#endif
+3
View File
@@ -72,3 +72,6 @@ __declspec(dllexport) KSTATUS KeResumeThread(THREAD* thread,
// Yields the current processor to another runnable thread.
__declspec(dllexport) void KeYield(void);
// Returns the stable opaque identity of the calling kernel thread.
__declspec(dllexport) uintptr_t KeCurrentThreadIdentity(void);