add system time, clean up pci into pci.sys, clean up syscall names, fix USERAPC1 typo
This commit is contained in:
1 parent
c1a291c4c9
commit
e41bf6e2c0
64 files changed
+4514
-2220
No files matched your search
@@ -12,6 +12,8 @@ void HalScreenInitialize(void* (*AllocatePool)(size_t size), uintptr_t fb, int w
|
||||
HAL_SCREEN* out);
|
||||
KSTATUS HalTimerInitialize(uintptr_t lapicPhys, uintptr_t hpetPhys, HAL_TIMER *out);
|
||||
void HalPciInitialize(HAL_PCI* out);
|
||||
void HalRtcInitialize(HAL_RTC* out);
|
||||
void HalRtcSetCenturyRegister(uint8_t centuryRegister);
|
||||
extern void HalSetDebugEnabled(int v);
|
||||
|
||||
// Defined in mm_virt.c - HAL needs it for MMIO window access.
|
||||
@@ -117,6 +119,7 @@ static void *HalPhysToVirt(uint64_t phys) {
|
||||
#define FADT_X_DSDT_OFFSET 140u
|
||||
#define FADT_X_PM1A_CNT_BLK_OFFSET 172u
|
||||
#define FADT_X_PM1B_CNT_BLK_OFFSET 184u
|
||||
#define FADT_CENTURY_OFFSET 108u
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct {
|
||||
@@ -312,8 +315,13 @@ static void ParseFadt(const ACPISDTHeader* header) {
|
||||
if (!dsdtPhys)
|
||||
dsdtPhys = AcpiReadU32(fadt, len, FADT_DSDT_OFFSET);
|
||||
|
||||
HalDbgPrint("HAL: FADT PM1a_CNT=0x%04x PM1b_CNT=0x%04x DSDT=0x%016llx\n",
|
||||
gPm1aCntBlk, gPm1bCntBlk, dsdtPhys);
|
||||
uint8_t centuryRegister = 0;
|
||||
if (FADT_CENTURY_OFFSET < len)
|
||||
centuryRegister = *((const uint8_t*)fadt + FADT_CENTURY_OFFSET);
|
||||
HalRtcSetCenturyRegister(centuryRegister);
|
||||
|
||||
HalDbgPrint("HAL: FADT PM1a_CNT=0x%04x PM1b_CNT=0x%04x DSDT=0x%016llx RTC_CENTURY=0x%02x\n",
|
||||
gPm1aCntBlk, gPm1bCntBlk, dsdtPhys, centuryRegister);
|
||||
|
||||
if (dsdtPhys) {
|
||||
const ACPISDTHeader* dsdt = (const ACPISDTHeader*)(dsdtPhys + gPhysBase);
|
||||
@@ -550,6 +558,7 @@ __declspec(dllexport) KSTATUS HalInitialize(const HAL_INIT_PARAMS* initParams) {
|
||||
KSTATUS ts = HalTimerInitialize(gLapicPhys, gHpetPhys, &gApi.Timer);
|
||||
if (!KSUCCESS(ts)) HalDbgPrint("HAL: HPET unavailable, using fallback\n");
|
||||
|
||||
HalRtcInitialize(&gApi.Rtc);
|
||||
HalPciInitialize(&gApi.Pci);
|
||||
gApi.Intc.RouteIrq = HalApicRouteIrq;
|
||||
gApi.Intc.MaskIrq = HalApicMaskIrq;
|
||||
|
||||
+22
-156
@@ -1,178 +1,44 @@
|
||||
// hal_pci.c - PCI configuration space via Mechanism 1 port I/O
|
||||
// hal_pci.c - raw PCI configuration access via legacy Mechanism 1 port I/O
|
||||
#include <stdint.h>
|
||||
#include <ntlite/ddi/hal_api.h>
|
||||
#include <kernel/hal/hal_apic.h>
|
||||
#include <kernel/hal/hal_debug.h>
|
||||
|
||||
#define PCI_CONFIG_ADDR 0xCF8
|
||||
#define PCI_CONFIG_DATA 0xCFC
|
||||
|
||||
#define PCI_REG_COMMAND_STATUS 0x04u
|
||||
#define PCI_REG_CAP_PTR 0x34u
|
||||
#define PCI_STATUS_CAP_LIST (1u << 20)
|
||||
#define PCI_COMMAND_INTX_DISABLE (1u << 10)
|
||||
|
||||
#define PCI_CAP_ID_MSI 0x05u
|
||||
#define PCI_CAP_ID_MSIX 0x11u
|
||||
#define PCI_MSI_CTRL_ENABLE (1u << 0)
|
||||
#define PCI_MSI_CTRL_MME_MASK (7u << 4)
|
||||
#define PCI_MSI_CTRL_64BIT (1u << 7)
|
||||
#define PCI_MSI_CTRL_PVM (1u << 8)
|
||||
|
||||
#define PCI_MSI_ADDRESS_BASE 0xFEE00000u
|
||||
#define PCI_IRQ_VECTOR_BASE 0x20u
|
||||
|
||||
static uint32_t MakeAddr(uint8_t bus, uint8_t dev, uint8_t fn, uint8_t reg) {
|
||||
static uint32_t MakeAddr(uint8_t bus, uint8_t dev, uint8_t fn, uint16_t offset) {
|
||||
return 0x80000000UL
|
||||
| ((uint32_t)bus << 16)
|
||||
| ((uint32_t)(dev & 0x1F) << 11)
|
||||
| ((uint32_t)(fn & 0x07) << 8)
|
||||
| (reg & 0xFC);
|
||||
| ((uint32_t)offset & 0xFCu);
|
||||
}
|
||||
|
||||
static uint32_t PciRead32(uint8_t bus, uint8_t dev, uint8_t fn, uint8_t reg) {
|
||||
__outdword(PCI_CONFIG_ADDR, MakeAddr(bus, dev, fn, reg));
|
||||
static uint32_t PciRead32(uint16_t segment,
|
||||
uint8_t bus,
|
||||
uint8_t dev,
|
||||
uint8_t fn,
|
||||
uint16_t offset) {
|
||||
if (segment != 0 || offset > 0xFCu)
|
||||
return 0xFFFFFFFFu;
|
||||
|
||||
__outdword(PCI_CONFIG_ADDR, MakeAddr(bus, dev, fn, offset));
|
||||
return __indword(PCI_CONFIG_DATA);
|
||||
}
|
||||
|
||||
static void PciWrite32(uint8_t bus, uint8_t dev, uint8_t fn,
|
||||
uint8_t reg, uint32_t val) {
|
||||
__outdword(PCI_CONFIG_ADDR, MakeAddr(bus, dev, fn, reg));
|
||||
__outdword(PCI_CONFIG_DATA, val);
|
||||
}
|
||||
static void PciWrite32(uint16_t segment,
|
||||
uint8_t bus,
|
||||
uint8_t dev,
|
||||
uint8_t fn,
|
||||
uint16_t offset,
|
||||
uint32_t value) {
|
||||
if (segment != 0 || offset > 0xFCu)
|
||||
return;
|
||||
|
||||
static uint8_t PciRead8(uint8_t bus, uint8_t dev, uint8_t fn, uint8_t reg) {
|
||||
uint32_t v = PciRead32(bus, dev, fn, reg);
|
||||
return (uint8_t)(v >> ((reg & 3u) * 8u));
|
||||
}
|
||||
|
||||
static uint16_t PciRead16(uint8_t bus, uint8_t dev, uint8_t fn, uint8_t reg) {
|
||||
uint32_t v = PciRead32(bus, dev, fn, reg);
|
||||
return (uint16_t)(v >> ((reg & 2u) * 8u));
|
||||
}
|
||||
|
||||
static void PciWrite16(uint8_t bus, uint8_t dev, uint8_t fn, uint8_t reg, uint16_t value) {
|
||||
uint8_t aligned = reg & ~3u;
|
||||
uint32_t shift = (reg & 2u) * 8u;
|
||||
uint32_t old = PciRead32(bus, dev, fn, aligned);
|
||||
old &= ~(0xFFFFu << shift);
|
||||
old |= ((uint32_t)value << shift);
|
||||
PciWrite32(bus, dev, fn, aligned, old);
|
||||
}
|
||||
|
||||
static bool PciFindDevice(uint16_t vendor, uint16_t device,
|
||||
uint8_t* outBus, uint8_t* outDev, uint8_t* outFn) {
|
||||
for (int bus = 0; bus < 256; bus++)
|
||||
for (int dev = 0; dev < 32; dev++)
|
||||
for (int fn = 0; fn < 8; fn++) {
|
||||
uint32_t id = PciRead32((uint8_t)bus, (uint8_t)dev, (uint8_t)fn, 0);
|
||||
if ((id & 0xFFFF) == vendor && (id >> 16) == device) {
|
||||
*outBus = (uint8_t)bus; *outDev = (uint8_t)dev; *outFn = (uint8_t)fn;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool PciFindClass(uint8_t classCode, uint8_t subclass,
|
||||
uint8_t* outBus, uint8_t* outDev, uint8_t* outFn) {
|
||||
for (int bus = 0; bus < 256; bus++)
|
||||
for (int dev = 0; dev < 32; dev++)
|
||||
for (int fn = 0; fn < 8; fn++) {
|
||||
uint32_t id = PciRead32((uint8_t)bus,(uint8_t)dev,(uint8_t)fn,0);
|
||||
if ((id & 0xFFFF) == 0xFFFF) continue; // no device
|
||||
uint32_t cc = PciRead32((uint8_t)bus,(uint8_t)dev,(uint8_t)fn,8);
|
||||
if (((cc >> 24) & 0xFF) == classCode &&
|
||||
((cc >> 16) & 0xFF) == subclass) {
|
||||
*outBus = (uint8_t)bus; *outDev = (uint8_t)dev; *outFn = (uint8_t)fn;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static uint8_t PciGetIrqLine(uint8_t bus, uint8_t dev, uint8_t fn) {
|
||||
// PCI config register 0x3C: byte 0 = IRQ line, byte 1 = IRQ pin
|
||||
uint32_t val = PciRead32(bus, dev, fn, 0x3C);
|
||||
return (uint8_t)(val & 0xFF); // 0xFF = not connected
|
||||
}
|
||||
|
||||
static uint8_t PciFindCapability(uint8_t bus, uint8_t dev, uint8_t fn, uint8_t capId) {
|
||||
uint32_t status = PciRead32(bus, dev, fn, PCI_REG_COMMAND_STATUS);
|
||||
if ((status & PCI_STATUS_CAP_LIST) == 0)
|
||||
return 0;
|
||||
|
||||
uint8_t cap = PciRead8(bus, dev, fn, PCI_REG_CAP_PTR) & 0xFCu;
|
||||
for (uint32_t guard = 0; cap && guard < 48u; guard++) {
|
||||
uint32_t hdr = PciRead32(bus, dev, fn, cap);
|
||||
uint8_t id = (uint8_t)(hdr & 0xFFu);
|
||||
uint8_t next = (uint8_t)((hdr >> 8) & 0xFCu);
|
||||
if (id == capId)
|
||||
return cap;
|
||||
cap = next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static KSTATUS PciEnableMsi(uint8_t bus, uint8_t dev, uint8_t fn, uint8_t irqSlot) {
|
||||
if (irqSlot >= 24u)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
uint8_t cap = PciFindCapability(bus, dev, fn, PCI_CAP_ID_MSI);
|
||||
if (!cap) {
|
||||
HalDbgPrint("PCI %u:%u.%u: MSI capability not present\n", bus, dev, fn);
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
uint32_t bspLapic = HalGetBspLapicId();
|
||||
if (!HalApicUsingX2Apic() && bspLapic >= 256u)
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
if (HalApicUsingX2Apic() && bspLapic >= 256u) {
|
||||
// Extended x2APIC MSI destinations need interrupt-remapping awareness.
|
||||
// Keep the first MSI implementation xAPIC-compatible and explicit.
|
||||
HalDbgPrint("PCI %u:%u.%u: MSI x2APIC destination %u not supported yet\n",
|
||||
bus, dev, fn, bspLapic);
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
uint16_t control = PciRead16(bus, dev, fn, (uint8_t)(cap + 2u));
|
||||
bool is64 = (control & PCI_MSI_CTRL_64BIT) != 0;
|
||||
bool pvm = (control & PCI_MSI_CTRL_PVM) != 0;
|
||||
uint8_t vector = (uint8_t)(PCI_IRQ_VECTOR_BASE + irqSlot);
|
||||
uint32_t address = PCI_MSI_ADDRESS_BASE | ((bspLapic & 0xFFu) << 12);
|
||||
uint16_t data = vector;
|
||||
|
||||
PciWrite32(bus, dev, fn, (uint8_t)(cap + 4u), address);
|
||||
if (is64) {
|
||||
PciWrite32(bus, dev, fn, (uint8_t)(cap + 8u), 0);
|
||||
PciWrite16(bus, dev, fn, (uint8_t)(cap + 12u), data);
|
||||
if (pvm)
|
||||
PciWrite32(bus, dev, fn, (uint8_t)(cap + 16u), 0);
|
||||
} else {
|
||||
PciWrite16(bus, dev, fn, (uint8_t)(cap + 8u), data);
|
||||
if (pvm)
|
||||
PciWrite32(bus, dev, fn, (uint8_t)(cap + 12u), 0);
|
||||
}
|
||||
|
||||
control &= (uint16_t)~PCI_MSI_CTRL_MME_MASK; // enable exactly one message
|
||||
control |= PCI_MSI_CTRL_ENABLE;
|
||||
PciWrite16(bus, dev, fn, (uint8_t)(cap + 2u), control);
|
||||
|
||||
uint32_t cmd = PciRead32(bus, dev, fn, PCI_REG_COMMAND_STATUS);
|
||||
cmd |= PCI_COMMAND_INTX_DISABLE;
|
||||
PciWrite32(bus, dev, fn, PCI_REG_COMMAND_STATUS, cmd);
|
||||
|
||||
HalDbgPrint("PCI %u:%u.%u: MSI enabled cap=0x%02x vector=0x%02x irqslot=%u dest=%u %s\n",
|
||||
bus, dev, fn, cap, vector, irqSlot, bspLapic, is64 ? "64-bit" : "32-bit");
|
||||
return STATUS_SUCCESS;
|
||||
__outdword(PCI_CONFIG_ADDR, MakeAddr(bus, dev, fn, offset));
|
||||
__outdword(PCI_CONFIG_DATA, value);
|
||||
}
|
||||
|
||||
void HalPciInitialize(HAL_PCI* out) {
|
||||
out->Read32 = PciRead32;
|
||||
out->Write32 = PciWrite32;
|
||||
out->FindDevice = PciFindDevice;
|
||||
out->FindClass = PciFindClass;
|
||||
out->GetIrqLine = PciGetIrqLine;
|
||||
out->EnableMsi = PciEnableMsi;
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
// hal_rtc.c - legacy CMOS RTC fallback clock
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <intrin.h>
|
||||
#include <ntlite/status.h>
|
||||
#include <ntlite/ddi/hal_api.h>
|
||||
#include <kernel/hal/hal_debug.h>
|
||||
|
||||
#define CMOS_INDEX_PORT 0x70
|
||||
#define CMOS_DATA_PORT 0x71
|
||||
|
||||
#define RTC_REG_SECONDS 0x00
|
||||
#define RTC_REG_MINUTES 0x02
|
||||
#define RTC_REG_HOURS 0x04
|
||||
#define RTC_REG_WEEKDAY 0x06
|
||||
#define RTC_REG_DAY 0x07
|
||||
#define RTC_REG_MONTH 0x08
|
||||
#define RTC_REG_YEAR 0x09
|
||||
#define RTC_REG_STATUS_A 0x0A
|
||||
#define RTC_REG_STATUS_B 0x0B
|
||||
|
||||
static uint8_t gCenturyRegister;
|
||||
|
||||
static uint8_t RtcRead(uint8_t reg) {
|
||||
__outbyte(CMOS_INDEX_PORT, (uint8_t)(reg | 0x80u)); // keep NMI masked while selecting.
|
||||
return __inbyte(CMOS_DATA_PORT);
|
||||
}
|
||||
|
||||
static bool RtcUpdateInProgress(void) {
|
||||
return (RtcRead(RTC_REG_STATUS_A) & 0x80u) != 0;
|
||||
}
|
||||
|
||||
static uint8_t RtcBcdToBinary(uint8_t value) {
|
||||
return (uint8_t)(((value >> 4) * 10u) + (value & 0x0Fu));
|
||||
}
|
||||
|
||||
static bool RtcReadStable(HAL_RTC_TIME* out) {
|
||||
if (!out) return false;
|
||||
|
||||
uint8_t sec1 = 0, min1 = 0, hour1 = 0, day1 = 0, month1 = 0, year1 = 0, century1 = 0;
|
||||
uint8_t sec2 = 0, min2 = 0, hour2 = 0, day2 = 0, month2 = 0, year2 = 0, century2 = 0;
|
||||
bool stable = false;
|
||||
|
||||
for (uint32_t tries = 0; tries < 100000u; tries++) {
|
||||
while (RtcUpdateInProgress()) _mm_pause();
|
||||
|
||||
sec1 = RtcRead(RTC_REG_SECONDS);
|
||||
min1 = RtcRead(RTC_REG_MINUTES);
|
||||
hour1 = RtcRead(RTC_REG_HOURS);
|
||||
day1 = RtcRead(RTC_REG_DAY);
|
||||
month1 = RtcRead(RTC_REG_MONTH);
|
||||
year1 = RtcRead(RTC_REG_YEAR);
|
||||
century1 = gCenturyRegister ? RtcRead(gCenturyRegister) : 0;
|
||||
|
||||
while (RtcUpdateInProgress()) _mm_pause();
|
||||
|
||||
sec2 = RtcRead(RTC_REG_SECONDS);
|
||||
min2 = RtcRead(RTC_REG_MINUTES);
|
||||
hour2 = RtcRead(RTC_REG_HOURS);
|
||||
day2 = RtcRead(RTC_REG_DAY);
|
||||
month2 = RtcRead(RTC_REG_MONTH);
|
||||
year2 = RtcRead(RTC_REG_YEAR);
|
||||
century2 = gCenturyRegister ? RtcRead(gCenturyRegister) : 0;
|
||||
|
||||
if (sec1 == sec2 && min1 == min2 && hour1 == hour2 && day1 == day2 &&
|
||||
month1 == month2 && year1 == year2 && century1 == century2) {
|
||||
stable = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!stable) return false;
|
||||
|
||||
uint8_t statusB = RtcRead(RTC_REG_STATUS_B);
|
||||
bool binary = (statusB & 0x04u) != 0;
|
||||
bool hour24 = (statusB & 0x02u) != 0;
|
||||
bool pm = (!hour24 && (hour1 & 0x80u) != 0);
|
||||
|
||||
if (!binary) {
|
||||
sec1 = RtcBcdToBinary(sec1);
|
||||
min1 = RtcBcdToBinary(min1);
|
||||
hour1 = (uint8_t)((hour1 & 0x80u) | RtcBcdToBinary((uint8_t)(hour1 & 0x7Fu)));
|
||||
day1 = RtcBcdToBinary(day1);
|
||||
month1 = RtcBcdToBinary(month1);
|
||||
year1 = RtcBcdToBinary(year1);
|
||||
if (gCenturyRegister) century1 = RtcBcdToBinary(century1);
|
||||
}
|
||||
|
||||
if (!hour24) {
|
||||
hour1 = (uint8_t)(hour1 & 0x7Fu);
|
||||
if (pm && hour1 < 12u) hour1 = (uint8_t)(hour1 + 12u);
|
||||
if (!pm && hour1 == 12u) hour1 = 0;
|
||||
}
|
||||
|
||||
uint16_t year;
|
||||
if (gCenturyRegister && century1) {
|
||||
year = (uint16_t)((uint16_t)century1 * 100u + year1);
|
||||
} else {
|
||||
year = (uint16_t)((year1 < 70u) ? (2000u + year1) : (1900u + year1));
|
||||
}
|
||||
|
||||
out->Year = year;
|
||||
out->Month = month1;
|
||||
out->Day = day1;
|
||||
out->Hour = hour1;
|
||||
out->Minute = min1;
|
||||
out->Second = sec1;
|
||||
out->Nanosecond = 0;
|
||||
out->Flags = HAL_RTC_TIME_FLAG_VALID | HAL_RTC_TIME_FLAG_RTC;
|
||||
out->Reserved = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool RtcLeapYear(uint16_t year) {
|
||||
return ((year % 4u) == 0u && (year % 100u) != 0u) || ((year % 400u) == 0u);
|
||||
}
|
||||
|
||||
static uint8_t RtcDaysInMonth(uint16_t year, uint8_t month) {
|
||||
static const uint8_t days[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
|
||||
if (month < 1u || month > 12u) return 0;
|
||||
if (month == 2u && RtcLeapYear(year)) return 29;
|
||||
return days[month - 1u];
|
||||
}
|
||||
|
||||
static bool RtcValid(const HAL_RTC_TIME* t) {
|
||||
if (!t) return false;
|
||||
if (t->Year < 1970u || t->Year > 9999u) return false;
|
||||
if (t->Month < 1u || t->Month > 12u) return false;
|
||||
uint8_t dim = RtcDaysInMonth(t->Year, t->Month);
|
||||
if (t->Day < 1u || t->Day > dim) return false;
|
||||
if (t->Hour > 23u || t->Minute > 59u || t->Second > 59u) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static KSTATUS HalRtcQueryTime(HAL_RTC_TIME* outTime) {
|
||||
if (!outTime) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
HAL_RTC_TIME t;
|
||||
memset(&t, 0, sizeof(t));
|
||||
if (!RtcReadStable(&t) || !RtcValid(&t))
|
||||
return STATUS_DEVICE_ERROR;
|
||||
|
||||
*outTime = t;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void HalRtcSetCenturyRegister(uint8_t centuryRegister) {
|
||||
gCenturyRegister = centuryRegister;
|
||||
}
|
||||
|
||||
void HalRtcInitialize(HAL_RTC* out) {
|
||||
if (!out) return;
|
||||
out->QueryTime = HalRtcQueryTime;
|
||||
|
||||
HAL_RTC_TIME t;
|
||||
if (HalRtcQueryTime(&t) == STATUS_SUCCESS) {
|
||||
HalDbgPrint("HAL: RTC %04u-%02u-%02u %02u:%02u:%02u century-reg=0x%02x\n",
|
||||
t.Year, t.Month, t.Day, t.Hour, t.Minute, t.Second,
|
||||
gCenturyRegister);
|
||||
} else {
|
||||
HalDbgPrint("HAL: RTC unavailable or invalid\n");
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,7 @@ typedef struct SYS_USER_APC_FRAME_K {
|
||||
uint64_t SystemArgument2;
|
||||
} SYS_USER_APC_FRAME_K;
|
||||
|
||||
#define SYS_USER_APC_FRAME_MAGIC 0x3143504152555355ULL /* "USURAPC1" little-ish */
|
||||
#define SYS_USER_APC_FRAME_MAGIC 0x3143504152455355ULL /* "USERAPC1" little-ish */
|
||||
|
||||
struct KUSER_APC {
|
||||
LIST_ENTRY Link;
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
#include <ntlite/status.h>
|
||||
#include <ntlite/time.h>
|
||||
|
||||
typedef struct BOOT_INFO BOOT_INFO;
|
||||
typedef struct HAL_API HAL_API;
|
||||
|
||||
void KeTimeInitialize(const BOOT_INFO* bootInfo, const HAL_API* hal);
|
||||
KSTATUS KeTimeReloadSettings(void);
|
||||
__declspec(dllexport) KSTATUS KeQuerySystemTime(SYS_SYSTEM_TIME* outTime);
|
||||
__declspec(dllexport) uint64_t KeQueryUnixTimeSeconds(void);
|
||||
@@ -6,97 +6,98 @@
|
||||
// R10, R11 = args 4-5 (loaded by SYSCALL_STUB6)
|
||||
// RAX = return value
|
||||
|
||||
#define SYS_EXIT_PROCESS 0
|
||||
#define SYS_EXIT_THREAD 1
|
||||
#define SYS_CREATE_PROCESS 2
|
||||
#define SYS_WAIT_FOR_PROCESS 3
|
||||
#define SYS_GET_PROCESS_EXIT_CODE 4
|
||||
#define SYS_KILL_PROCESS 5
|
||||
#define SYS_GET_PROCESS_LIST 6
|
||||
#define SYS_GET_PROCESS_PID 7
|
||||
#define SYS_CREATE_THREAD 8
|
||||
#define SYS_WAIT_THREAD 9
|
||||
#define SYS_GET_CURRENT_TID 10
|
||||
#define SYS_GET_CURRENT_PID 11
|
||||
#define SYS_SET_THREAD_PRIORITY 12
|
||||
#define SYS_YIELD 13
|
||||
#define SYS_SLEEP 14
|
||||
#define SYS_SET_USER_APC_DISPATCHER 15
|
||||
#define SYS_APC_RETURN 16
|
||||
#define SYS_VM_ALLOC 17
|
||||
#define SYS_VM_FREE 18
|
||||
#define SYS_VM_PROTECT 19
|
||||
#define SYS_VM_QUERY 20
|
||||
#define SYS_CLOSE_HANDLE 21
|
||||
#define SYS_MUTEX_CREATE 22
|
||||
#define SYS_MUTEX_ACQUIRE 23
|
||||
#define SYS_MUTEX_TRY_ACQUIRE 24
|
||||
#define SYS_MUTEX_RELEASE 25
|
||||
#define SYS_SEM_CREATE 26
|
||||
#define SYS_SEM_WAIT 27
|
||||
#define SYS_SEM_TRY_WAIT 28
|
||||
#define SYS_SEM_SIGNAL 29
|
||||
#define SYS_EVENT_CREATE 30
|
||||
#define SYS_EVENT_SIGNAL 31
|
||||
#define SYS_EVENT_CLEAR 32
|
||||
#define SYS_EVENT_WAIT 33
|
||||
#define SYS_QUEUE_CREATE 34
|
||||
#define SYS_QUEUE_SEND 35
|
||||
#define SYS_QUEUE_RECV 36
|
||||
#define SYS_PUBLISH_QUEUE 37
|
||||
#define SYS_OPEN_NAMED_QUEUE 38
|
||||
#define SYS_QUEUE_DUPLICATE 39
|
||||
#define SYS_NAMED_QUEUE_OWNER_PID 40
|
||||
#define SYS_OPEN_FILE 41
|
||||
#define SYS_CREATE_FILE 42
|
||||
#define SYS_READ_FILE 43
|
||||
#define SYS_WRITE_FILE 44
|
||||
#define SYS_READ_FILE_ASYNC 45
|
||||
#define SYS_WRITE_FILE_ASYNC 46
|
||||
#define SYS_CANCEL_IO 47
|
||||
#define SYS_SEEK_FILE 48
|
||||
#define SYS_GET_FILE_POS 49
|
||||
#define SYS_GET_FILE_SIZE 50
|
||||
#define SYS_TRUNCATE_FILE 51
|
||||
#define SYS_DELETE_FILE 52
|
||||
#define SYS_RENAME_FILE 53
|
||||
#define SYS_OPEN_DIR 54
|
||||
#define SYS_READ_DIR 55
|
||||
#define SYS_CREATE_DIR 56
|
||||
#define SYS_REMOVE_DIR 57
|
||||
#define SYS_SET_CWD 58
|
||||
#define SYS_GET_CWD 59
|
||||
#define SYS_WRITE_CONSOLE 60
|
||||
#define SYS_SCREEN_BLIT 61
|
||||
#define SYS_SCREEN_CLEAR 62
|
||||
#define SYS_SCREEN_GET_SIZE 63
|
||||
#define SYS_SCREEN_PUT_CHAR 64
|
||||
#define SYS_KB_POLL 65
|
||||
#define SYS_KB_IS_KEY_DOWN 66
|
||||
#define SYS_KB_READ_CHAR 67
|
||||
#define SYS_KB_READ_KEY 68
|
||||
#define SYS_KB_GET_MODIFIERS 69
|
||||
#define SYS_MOUSE_POLL 70
|
||||
#define SYS_MOUSE_READ 71
|
||||
#define SYS_MOUSE_GET_POS 72
|
||||
#define SYS_GET_TICK 73
|
||||
#define SYS_DEBUG_PRINT 74
|
||||
#define SYS_QUERY_TRAP_FRAME 75
|
||||
#define SYS_SOCKET 76
|
||||
#define SYS_BIND 77
|
||||
#define SYS_LISTEN 78
|
||||
#define SYS_ACCEPT 79
|
||||
#define SYS_CONNECT 80
|
||||
#define SYS_SEND 81
|
||||
#define SYS_RECV 82
|
||||
#define SYS_SHUTDOWN 83
|
||||
#define SYS_SEND_TO 84
|
||||
#define SYS_RECV_FROM 85
|
||||
#define SYS_RESOLVE_HOST 86
|
||||
#define SYS_SET_SOCKET_OPTION 87
|
||||
#define SYS_GET_SOCKET_OPTION 88
|
||||
#define SYS_POLL 89
|
||||
#define SYS_GET_MEMORY_STATUS 90
|
||||
#define SYS_QUERY_KERNEL_STATS 91
|
||||
#define SYS_EXIT_PROCESS 0
|
||||
#define SYS_EXIT_THREAD 1
|
||||
#define SYS_CREATE_PROCESS 2
|
||||
#define SYS_WAIT_FOR_PROCESS 3
|
||||
#define SYS_GET_PROCESS_EXIT_CODE 4
|
||||
#define SYS_KILL_PROCESS 5
|
||||
#define SYS_GET_PROCESS_LIST 6
|
||||
#define SYS_GET_PROCESS_PID 7
|
||||
#define SYS_CREATE_THREAD 8
|
||||
#define SYS_WAIT_THREAD 9
|
||||
#define SYS_GET_CURRENT_TID 10
|
||||
#define SYS_GET_CURRENT_PID 11
|
||||
#define SYS_SET_THREAD_PRIORITY 12
|
||||
#define SYS_YIELD 13
|
||||
#define SYS_SLEEP 14
|
||||
#define SYS_SET_USER_APC_DISPATCHER 15
|
||||
#define SYS_APC_RETURN 16
|
||||
#define SYS_ALLOC_VM 17
|
||||
#define SYS_FREE_VM 18
|
||||
#define SYS_PROTECT_VM 19
|
||||
#define SYS_QUERY_VM 20
|
||||
#define SYS_CLOSE_HANDLE 21
|
||||
#define SYS_CREATE_MUTEX 22
|
||||
#define SYS_ACQUIRE_MUTEX 23
|
||||
#define SYS_TRY_ACQUIRE_MUTEX 24
|
||||
#define SYS_RELEASE_MUTEX 25
|
||||
#define SYS_CREATE_SEM 26
|
||||
#define SYS_WAIT_SEM 27
|
||||
#define SYS_TRY_WAIT_SEM 28
|
||||
#define SYS_SIGNAL_SEM 29
|
||||
#define SYS_CREATE_EVENT 30
|
||||
#define SYS_SIGNAL_EVENT 31
|
||||
#define SYS_CLEAR_EVENT 32
|
||||
#define SYS_WAIT_EVENT 33
|
||||
#define SYS_CREATE_QUEUE 34
|
||||
#define SYS_SEND_QUEUE 35
|
||||
#define SYS_RECV_QUEUE 36
|
||||
#define SYS_PUBLISH_QUEUE 37
|
||||
#define SYS_OPEN_NAMED_QUEUE 38
|
||||
#define SYS_DUPLICATE_QUEUE 39
|
||||
#define SYS_GET_NAMED_QUEUE_OWNER_PID 40
|
||||
#define SYS_OPEN_FILE 41
|
||||
#define SYS_CREATE_FILE 42
|
||||
#define SYS_READ_FILE 43
|
||||
#define SYS_WRITE_FILE 44
|
||||
#define SYS_READ_FILE_ASYNC 45
|
||||
#define SYS_WRITE_FILE_ASYNC 46
|
||||
#define SYS_CANCEL_IO 47
|
||||
#define SYS_SEEK_FILE 48
|
||||
#define SYS_GET_FILE_POS 49
|
||||
#define SYS_GET_FILE_SIZE 50
|
||||
#define SYS_TRUNCATE_FILE 51
|
||||
#define SYS_DELETE_FILE 52
|
||||
#define SYS_RENAME_FILE 53
|
||||
#define SYS_OPEN_DIR 54
|
||||
#define SYS_READ_DIR 55
|
||||
#define SYS_CREATE_DIR 56
|
||||
#define SYS_REMOVE_DIR 57
|
||||
#define SYS_SET_CWD 58
|
||||
#define SYS_GET_CWD 59
|
||||
#define SYS_WRITE_CONSOLE 60
|
||||
#define SYS_BLIT_SCREEN 61
|
||||
#define SYS_CLEAR_SCREEN 62
|
||||
#define SYS_GET_SCREEN_SIZE 63
|
||||
#define SYS_PUT_SCREEN_CHAR 64
|
||||
#define SYS_POLL_KEYBOARD 65
|
||||
#define SYS_IS_KEY_DOWN 66
|
||||
#define SYS_READ_KEYBOARD_CHAR 67
|
||||
#define SYS_READ_KEY 68
|
||||
#define SYS_GET_KEY_MODIFIERS 69
|
||||
#define SYS_POLL_MOUSE 70
|
||||
#define SYS_READ_MOUSE 71
|
||||
#define SYS_GET_MOUSE_POS 72
|
||||
#define SYS_GET_TICK 73
|
||||
#define SYS_PRINT_DEBUG 74
|
||||
#define SYS_QUERY_TRAP_FRAME 75
|
||||
#define SYS_CREATE_SOCKET 76
|
||||
#define SYS_BIND_SOCKET 77
|
||||
#define SYS_LISTEN_SOCKET 78
|
||||
#define SYS_ACCEPT_SOCKET 79
|
||||
#define SYS_CONNECT_SOCKET 80
|
||||
#define SYS_SEND_SOCKET 81
|
||||
#define SYS_RECV_SOCKET 82
|
||||
#define SYS_SHUTDOWN_SOCKET 83
|
||||
#define SYS_SEND_TO_SOCKET 84
|
||||
#define SYS_RECV_FROM_SOCKET 85
|
||||
#define SYS_RESOLVE_HOST 86
|
||||
#define SYS_SET_SOCKET_OPTION 87
|
||||
#define SYS_GET_SOCKET_OPTION 88
|
||||
#define SYS_POLL 89
|
||||
#define SYS_GET_MEMORY_STATUS 90
|
||||
#define SYS_QUERY_KERNEL_STATS 91
|
||||
#define SYS_GET_SYSTEM_TIME 92
|
||||
|
||||
#define SYS_MAX 92
|
||||
#define SYS_MAX 93
|
||||
+104
-88
@@ -61,6 +61,7 @@
|
||||
#include <kernel/net_socket.h>
|
||||
#include <kernel/ke_trap.h>
|
||||
#include <kernel/ke_input.h>
|
||||
#include <kernel/ke_time.h>
|
||||
#include <ntlite/syscall.h>
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -499,7 +500,7 @@ static uint64_t SyscallVmQuery(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_MUTEX_CREATE (11) a0 = *handleOut
|
||||
// SYS_CREATE_MUTEX (11) a0 = *handleOut
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallMutexCreate(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -520,7 +521,7 @@ static uint64_t SyscallMutexCreate(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_MUTEX_ACQUIRE (12) a0 = handle
|
||||
// SYS_ACQUIRE_MUTEX (12) a0 = handle
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallMutexAcquire(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -533,7 +534,7 @@ static uint64_t SyscallMutexAcquire(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_MUTEX_TRY_ACQUIRE (13) a0 = handle
|
||||
// SYS_TRY_ACQUIRE_MUTEX (13) a0 = handle
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallMutexTryAcquire(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -546,7 +547,7 @@ static uint64_t SyscallMutexTryAcquire(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_MUTEX_RELEASE (14) a0 = handle
|
||||
// SYS_RELEASE_MUTEX (14) a0 = handle
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallMutexRelease(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -559,7 +560,7 @@ static uint64_t SyscallMutexRelease(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_SEM_CREATE (15) a0=initial a1=max a2=*handleOut
|
||||
// SYS_CREATE_SEM (15) a0=initial a1=max a2=*handleOut
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallSemCreate(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -580,7 +581,7 @@ static uint64_t SyscallSemCreate(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_SEM_WAIT (16) a0 = handle
|
||||
// SYS_WAIT_SEM (16) a0 = handle
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallSemWait(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -593,7 +594,7 @@ static uint64_t SyscallSemWait(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_SEM_TRY_WAIT (17) a0 = handle
|
||||
// SYS_TRY_WAIT_SEM (17) a0 = handle
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallSemTryWait(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -606,7 +607,7 @@ static uint64_t SyscallSemTryWait(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_SEM_SIGNAL (18) a0 = handle
|
||||
// SYS_SIGNAL_SEM (18) a0 = handle
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallSemSignal(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -619,7 +620,7 @@ static uint64_t SyscallSemSignal(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_EVENT_CREATE (19) a0=type a1=initialState a2=*handleOut
|
||||
// SYS_CREATE_EVENT (19) a0=type a1=initialState a2=*handleOut
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallEventCreate(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -640,7 +641,7 @@ static uint64_t SyscallEventCreate(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_EVENT_SIGNAL (20) a0 = handle
|
||||
// SYS_SIGNAL_EVENT (20) a0 = handle
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallEventSignal(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -653,7 +654,7 @@ static uint64_t SyscallEventSignal(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_EVENT_CLEAR (21) a0 = handle
|
||||
// SYS_CLEAR_EVENT (21) a0 = handle
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallEventClear(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -666,7 +667,7 @@ static uint64_t SyscallEventClear(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_EVENT_WAIT a0 = handle, a1 = alertable
|
||||
// SYS_WAIT_EVENT a0 = handle, a1 = alertable
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallEventWait(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -685,7 +686,7 @@ static uint64_t SyscallEventWait(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_QUEUE_CREATE (23) a0 = *handleOut
|
||||
// SYS_CREATE_QUEUE (23) a0 = *handleOut
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallQueueCreate(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -706,7 +707,7 @@ static uint64_t SyscallQueueCreate(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_QUEUE_SEND (24) a0=handle a1=*msg a2=blocking
|
||||
// SYS_SEND_QUEUE (24) a0=handle a1=*msg a2=blocking
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallQueueSend(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -725,7 +726,7 @@ static uint64_t SyscallQueueSend(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_QUEUE_RECV (25) a0=handle a1=*msg a2=blocking
|
||||
// SYS_RECV_QUEUE (25) a0=handle a1=*msg a2=blocking
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallQueueRecv(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -1203,7 +1204,7 @@ static uint64_t SyscallGetFileSize(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_SCREEN_BLIT (36) a0=x a1=y a2=w a3=h a4=*pixels
|
||||
// SYS_BLIT_SCREEN (36) a0=x a1=y a2=w a3=h a4=*pixels
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallScreenBlit(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -1233,7 +1234,7 @@ static uint64_t SyscallScreenBlit(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_SCREEN_CLEAR (37) a0=color
|
||||
// SYS_CLEAR_SCREEN (37) a0=color
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallScreenClear(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -1244,7 +1245,7 @@ static uint64_t SyscallScreenClear(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_SCREEN_GET_SIZE (38) a0=*widthOut a1=*heightOut
|
||||
// SYS_GET_SCREEN_SIZE (38) a0=*widthOut a1=*heightOut
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallScreenGetSize(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -1264,7 +1265,7 @@ static uint64_t SyscallScreenGetSize(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_SCREEN_PUT_CHAR (39) a0=c a1=x a2=y a3=fg a4=bg
|
||||
// SYS_PUT_SCREEN_CHAR (39) a0=c a1=x a2=y a3=fg a4=bg
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallScreenPutChar(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -1276,7 +1277,7 @@ static uint64_t SyscallScreenPutChar(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_KB_POLL (64) -> next INPUT_KEY or INPUT_KEY_NONE
|
||||
// SYS_POLL_KEYBOARD (64) -> next INPUT_KEY or INPUT_KEY_NONE
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallKbPoll(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -1285,7 +1286,7 @@ static uint64_t SyscallKbPoll(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_KB_IS_KEY_DOWN (65) a0=INPUT_KEY -> 1 or 0
|
||||
// SYS_IS_KEY_DOWN (65) a0=INPUT_KEY -> 1 or 0
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallKbIsKeyDown(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -1294,7 +1295,7 @@ static uint64_t SyscallKbIsKeyDown(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_KB_READ_CHAR (66) -> char (blocks, yields while waiting)
|
||||
// SYS_READ_KEYBOARD_CHAR (66) -> char (blocks, yields while waiting)
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallKbReadChar(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -1304,7 +1305,7 @@ static uint64_t SyscallKbReadChar(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_KB_READ_KEY (67) -> INPUT_KEY (blocks, yields while waiting)
|
||||
// SYS_READ_KEY (67) -> INPUT_KEY (blocks, yields while waiting)
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallKbReadKey(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -1314,7 +1315,7 @@ static uint64_t SyscallKbReadKey(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_KB_GET_MODIFIERS (68) -> uint32_t INPUT_MOD_* flags
|
||||
// SYS_GET_KEY_MODIFIERS (68) -> uint32_t INPUT_MOD_* flags
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallKbGetModifiers(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -1323,7 +1324,7 @@ static uint64_t SyscallKbGetModifiers(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_MOUSE_POLL (69) -> 1 or 0
|
||||
// SYS_POLL_MOUSE (69) -> 1 or 0
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallMousePoll(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -1332,7 +1333,7 @@ static uint64_t SyscallMousePoll(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_MOUSE_READ (70) a0=*dx a1=*dy a2=*buttons -> 1 or 0
|
||||
// SYS_READ_MOUSE (70) a0=*dx a1=*dy a2=*buttons -> 1 or 0
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallMouseRead(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -1350,7 +1351,7 @@ static uint64_t SyscallMouseRead(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_MOUSE_GET_POS (71) a0=*x a1=*y
|
||||
// SYS_GET_MOUSE_POS (71) a0=*x a1=*y
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallMouseGetPos(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -1374,13 +1375,27 @@ static uint64_t SyscallGetTick(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_DEBUG_PRINT (49) a0=*str
|
||||
// SYS_GET_SYSTEM_TIME a0=*SYS_SYSTEM_TIME
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallGetSystemTime(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
(void)a1; (void)a2; (void)a3; (void)a4; (void)a5;
|
||||
if (!a0) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
SYS_SYSTEM_TIME t;
|
||||
KSTATUS s = KeQuerySystemTime(&t);
|
||||
if (!KSUCCESS(s)) return s;
|
||||
return CopyToUser((void*)(uintptr_t)a0, &t, sizeof(t));
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_PRINT_DEBUG (49) a0=*str
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallDebugPrint(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
(void)a1; (void)a2; (void)a3; (void)a4; (void)a5;
|
||||
|
||||
SYS_DEBUG_PRINT_REQUEST req;
|
||||
SYS_PRINT_DEBUG_REQUEST req;
|
||||
KSTATUS s = KiCopyUserRequest(a0, &req, sizeof(req));
|
||||
if (!KSUCCESS(s)) return s;
|
||||
if (req.Text.Length == 0) return STATUS_SUCCESS;
|
||||
@@ -1593,7 +1608,7 @@ static uint64_t SyscallGetProcessExitCode(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_WRITE_CONSOLE (53) a0=*buf a1=len
|
||||
// Writes user console text in white; distinct from green SYS_DEBUG_PRINT.
|
||||
// Writes user console text in white; distinct from green SYS_PRINT_DEBUG.
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallWriteConsole(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -1922,7 +1937,7 @@ static uint64_t SyscallOpenNamedQueue(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_QUEUE_DUPLICATE (62) a0=handle a1=targetPid a2=*handleOut
|
||||
// SYS_DUPLICATE_QUEUE (62) a0=handle a1=targetPid a2=*handleOut
|
||||
//
|
||||
// Looks up the QUEUE behind 'handle' in the CALLER's table, then allocates
|
||||
// a new handle for the same object in the TARGET process's table.
|
||||
@@ -1959,11 +1974,11 @@ static uint64_t SyscallQueueDuplicate(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_NAMED_QUEUE_OWNER_PID (63) a0=*name a1=*pidOut
|
||||
// SYS_GET_NAMED_QUEUE_OWNER_PID (63) a0=*name a1=*pidOut
|
||||
//
|
||||
// Returns the ProcessId of whoever published the named queue.
|
||||
// Lets a client get the publisher's PID so it can duplicate one of its
|
||||
// own handles into that process via SYS_QUEUE_DUPLICATE.
|
||||
// own handles into that process via SYS_DUPLICATE_QUEUE.
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallNamedQueueOwnerPid(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -2151,7 +2166,7 @@ typedef struct SYS_MEMORY_STATUS_K {
|
||||
#define SYS_POLL_MAX_FDS 64u
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_SOCKET a0=domain a1=type a2=protocol a3=*handleOut
|
||||
// SYS_CREATE_SOCKET a0=domain a1=type a2=protocol a3=*handleOut
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallSocket(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -2178,7 +2193,7 @@ static uint64_t SyscallSocket(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_BIND a0=socketHandle a1=*SYS_SOCKET_ADDRESS_IPV4 a2=addressSize
|
||||
// SYS_BIND_SOCKET a0=socketHandle a1=*SYS_SOCKET_ADDRESS_IPV4 a2=addressSize
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallBind(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -2199,7 +2214,7 @@ static uint64_t SyscallBind(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_LISTEN a0=socketHandle a1=backlog
|
||||
// SYS_LISTEN_SOCKET a0=socketHandle a1=backlog
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallListen(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -2214,7 +2229,7 @@ static uint64_t SyscallListen(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_ACCEPT a0=listenSocket a1=*remoteAddressOut(optional)
|
||||
// SYS_ACCEPT_SOCKET a0=listenSocket a1=*remoteAddressOut(optional)
|
||||
// a2=*remoteAddressSizeInOut(optional) a3=*acceptedHandleOut
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallAccept(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
@@ -2271,7 +2286,7 @@ static uint64_t SyscallAccept(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_CONNECT a0=socketHandle a1=*SYS_SOCKET_ADDRESS_IPV4 a2=addressSize
|
||||
// SYS_CONNECT_SOCKET a0=socketHandle a1=*SYS_SOCKET_ADDRESS_IPV4 a2=addressSize
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallConnect(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -2292,7 +2307,7 @@ static uint64_t SyscallConnect(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_SEND a0=socketHandle a1=*buffer a2=length a3=flags a4=*sentOut(optional)
|
||||
// SYS_SEND_SOCKET a0=socketHandle a1=*buffer a2=length a3=flags a4=*sentOut(optional)
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallSend(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -2328,7 +2343,7 @@ static uint64_t SyscallSend(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_RECV a0=socketHandle a1=*buffer a2=length a3=flags a4=*receivedOut(optional)
|
||||
// SYS_RECV_SOCKET a0=socketHandle a1=*buffer a2=length a3=flags a4=*receivedOut(optional)
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallRecv(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -2365,7 +2380,7 @@ static uint64_t SyscallRecv(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_SHUTDOWN a0=socketHandle a1=SYS_SHUTDOWN_*
|
||||
// SYS_SHUTDOWN_SOCKET a0=socketHandle a1=SYS_SHUTDOWN_SOCKET_*
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallShutdown(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -2380,7 +2395,7 @@ static uint64_t SyscallShutdown(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_SEND_TO a0=socketHandle a1=*SYS_SOCKET_SEND_TO_REQUEST
|
||||
// SYS_SEND_TO_SOCKET a0=socketHandle a1=*SYS_SOCKET_SEND_TO_REQUEST
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallSendTo(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -2423,7 +2438,7 @@ static uint64_t SyscallSendTo(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SYS_RECV_FROM a0=socketHandle a1=*SYS_SOCKET_RECV_FROM_REQUEST
|
||||
// SYS_RECV_FROM_SOCKET a0=socketHandle a1=*SYS_SOCKET_RECV_FROM_REQUEST
|
||||
// ---------------------------------------------------------------------------
|
||||
static uint64_t SyscallRecvFrom(uint64_t a0, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5) {
|
||||
@@ -2797,30 +2812,30 @@ static const SYSCALL_HANDLER gSyscallTable[SYS_MAX] = {
|
||||
/* 14 SYS_SLEEP */ SyscallSleep,
|
||||
/* 15 SYS_SET_USER_APC_DISPATCHER */ SyscallSetUserApcDispatcher,
|
||||
/* 16 SYS_APC_RETURN */ SyscallApcReturn,
|
||||
/* 17 SYS_VM_ALLOC */ SyscallVmAlloc,
|
||||
/* 18 SYS_VM_FREE */ SyscallVmFree,
|
||||
/* 19 SYS_VM_PROTECT */ SyscallVmProtect,
|
||||
/* 20 SYS_VM_QUERY */ SyscallVmQuery,
|
||||
/* 17 SYS_ALLOC_VM */ SyscallVmAlloc,
|
||||
/* 18 SYS_FREE_VM */ SyscallVmFree,
|
||||
/* 19 SYS_PROTECT_VM */ SyscallVmProtect,
|
||||
/* 20 SYS_QUERY_VM */ SyscallVmQuery,
|
||||
/* 21 SYS_CLOSE_HANDLE */ SyscallCloseHandle,
|
||||
/* 22 SYS_MUTEX_CREATE */ SyscallMutexCreate,
|
||||
/* 23 SYS_MUTEX_ACQUIRE */ SyscallMutexAcquire,
|
||||
/* 24 SYS_MUTEX_TRY_ACQUIRE */ SyscallMutexTryAcquire,
|
||||
/* 25 SYS_MUTEX_RELEASE */ SyscallMutexRelease,
|
||||
/* 26 SYS_SEM_CREATE */ SyscallSemCreate,
|
||||
/* 27 SYS_SEM_WAIT */ SyscallSemWait,
|
||||
/* 28 SYS_SEM_TRY_WAIT */ SyscallSemTryWait,
|
||||
/* 29 SYS_SEM_SIGNAL */ SyscallSemSignal,
|
||||
/* 30 SYS_EVENT_CREATE */ SyscallEventCreate,
|
||||
/* 31 SYS_EVENT_SIGNAL */ SyscallEventSignal,
|
||||
/* 32 SYS_EVENT_CLEAR */ SyscallEventClear,
|
||||
/* 33 SYS_EVENT_WAIT */ SyscallEventWait,
|
||||
/* 34 SYS_QUEUE_CREATE */ SyscallQueueCreate,
|
||||
/* 35 SYS_QUEUE_SEND */ SyscallQueueSend,
|
||||
/* 36 SYS_QUEUE_RECV */ SyscallQueueRecv,
|
||||
/* 22 SYS_CREATE_MUTEX */ SyscallMutexCreate,
|
||||
/* 23 SYS_ACQUIRE_MUTEX */ SyscallMutexAcquire,
|
||||
/* 24 SYS_TRY_ACQUIRE_MUTEX */ SyscallMutexTryAcquire,
|
||||
/* 25 SYS_RELEASE_MUTEX */ SyscallMutexRelease,
|
||||
/* 26 SYS_CREATE_SEM */ SyscallSemCreate,
|
||||
/* 27 SYS_WAIT_SEM */ SyscallSemWait,
|
||||
/* 28 SYS_TRY_WAIT_SEM */ SyscallSemTryWait,
|
||||
/* 29 SYS_SIGNAL_SEM */ SyscallSemSignal,
|
||||
/* 30 SYS_CREATE_EVENT */ SyscallEventCreate,
|
||||
/* 31 SYS_SIGNAL_EVENT */ SyscallEventSignal,
|
||||
/* 32 SYS_CLEAR_EVENT */ SyscallEventClear,
|
||||
/* 33 SYS_WAIT_EVENT */ SyscallEventWait,
|
||||
/* 34 SYS_CREATE_QUEUE */ SyscallQueueCreate,
|
||||
/* 35 SYS_SEND_QUEUE */ SyscallQueueSend,
|
||||
/* 36 SYS_RECV_QUEUE */ SyscallQueueRecv,
|
||||
/* 37 SYS_PUBLISH_QUEUE */ SyscallPublishQueue,
|
||||
/* 38 SYS_OPEN_NAMED_QUEUE */ SyscallOpenNamedQueue,
|
||||
/* 39 SYS_QUEUE_DUPLICATE */ SyscallQueueDuplicate,
|
||||
/* 40 SYS_NAMED_QUEUE_OWNER_PID */ SyscallNamedQueueOwnerPid,
|
||||
/* 39 SYS_DUPLICATE_QUEUE */ SyscallQueueDuplicate,
|
||||
/* 40 SYS_GET_NAMED_QUEUE_OWNER_PID */ SyscallNamedQueueOwnerPid,
|
||||
/* 41 SYS_OPEN_FILE */ SyscallOpenFile,
|
||||
/* 42 SYS_CREATE_FILE */ SyscallCreateFile,
|
||||
/* 43 SYS_READ_FILE */ SyscallReadFile,
|
||||
@@ -2841,37 +2856,38 @@ static const SYSCALL_HANDLER gSyscallTable[SYS_MAX] = {
|
||||
/* 58 SYS_SET_CWD */ SyscallSetCwd,
|
||||
/* 59 SYS_GET_CWD */ SyscallGetCwd,
|
||||
/* 60 SYS_WRITE_CONSOLE */ SyscallWriteConsole,
|
||||
/* 61 SYS_SCREEN_BLIT */ SyscallScreenBlit,
|
||||
/* 62 SYS_SCREEN_CLEAR */ SyscallScreenClear,
|
||||
/* 63 SYS_SCREEN_GET_SIZE */ SyscallScreenGetSize,
|
||||
/* 64 SYS_SCREEN_PUT_CHAR */ SyscallScreenPutChar,
|
||||
/* 65 SYS_KB_POLL */ SyscallKbPoll,
|
||||
/* 66 SYS_KB_IS_KEY_DOWN */ SyscallKbIsKeyDown,
|
||||
/* 67 SYS_KB_READ_CHAR */ SyscallKbReadChar,
|
||||
/* 68 SYS_KB_READ_KEY */ SyscallKbReadKey,
|
||||
/* 69 SYS_KB_GET_MODIFIERS */ SyscallKbGetModifiers,
|
||||
/* 70 SYS_MOUSE_POLL */ SyscallMousePoll,
|
||||
/* 71 SYS_MOUSE_READ */ SyscallMouseRead,
|
||||
/* 72 SYS_MOUSE_GET_POS */ SyscallMouseGetPos,
|
||||
/* 61 SYS_BLIT_SCREEN */ SyscallScreenBlit,
|
||||
/* 62 SYS_CLEAR_SCREEN */ SyscallScreenClear,
|
||||
/* 63 SYS_GET_SCREEN_SIZE */ SyscallScreenGetSize,
|
||||
/* 64 SYS_PUT_SCREEN_CHAR */ SyscallScreenPutChar,
|
||||
/* 65 SYS_POLL_KEYBOARD */ SyscallKbPoll,
|
||||
/* 66 SYS_IS_KEY_DOWN */ SyscallKbIsKeyDown,
|
||||
/* 67 SYS_READ_KEYBOARD_CHAR */ SyscallKbReadChar,
|
||||
/* 68 SYS_READ_KEY */ SyscallKbReadKey,
|
||||
/* 69 SYS_GET_KEY_MODIFIERS */ SyscallKbGetModifiers,
|
||||
/* 70 SYS_POLL_MOUSE */ SyscallMousePoll,
|
||||
/* 71 SYS_READ_MOUSE */ SyscallMouseRead,
|
||||
/* 72 SYS_GET_MOUSE_POS */ SyscallMouseGetPos,
|
||||
/* 73 SYS_GET_TICK */ SyscallGetTick,
|
||||
/* 74 SYS_DEBUG_PRINT */ SyscallDebugPrint,
|
||||
/* 74 SYS_PRINT_DEBUG */ SyscallDebugPrint,
|
||||
/* 75 SYS_QUERY_TRAP_FRAME */ SyscallQueryTrapFrame,
|
||||
/* 76 SYS_SOCKET */ SyscallSocket,
|
||||
/* 77 SYS_BIND */ SyscallBind,
|
||||
/* 78 SYS_LISTEN */ SyscallListen,
|
||||
/* 79 SYS_ACCEPT */ SyscallAccept,
|
||||
/* 80 SYS_CONNECT */ SyscallConnect,
|
||||
/* 81 SYS_SEND */ SyscallSend,
|
||||
/* 82 SYS_RECV */ SyscallRecv,
|
||||
/* 83 SYS_SHUTDOWN */ SyscallShutdown,
|
||||
/* 84 SYS_SEND_TO */ SyscallSendTo,
|
||||
/* 85 SYS_RECV_FROM */ SyscallRecvFrom,
|
||||
/* 76 SYS_CREATE_SOCKET */ SyscallSocket,
|
||||
/* 77 SYS_BIND_SOCKET */ SyscallBind,
|
||||
/* 78 SYS_LISTEN_SOCKET */ SyscallListen,
|
||||
/* 79 SYS_ACCEPT_SOCKET */ SyscallAccept,
|
||||
/* 80 SYS_CONNECT_SOCKET */ SyscallConnect,
|
||||
/* 81 SYS_SEND_SOCKET */ SyscallSend,
|
||||
/* 82 SYS_RECV_SOCKET */ SyscallRecv,
|
||||
/* 83 SYS_SHUTDOWN_SOCKET */ SyscallShutdown,
|
||||
/* 84 SYS_SEND_TO_SOCKET */ SyscallSendTo,
|
||||
/* 85 SYS_RECV_FROM_SOCKET */ SyscallRecvFrom,
|
||||
/* 86 SYS_RESOLVE_HOST */ SyscallResolveHost,
|
||||
/* 87 SYS_SET_SOCKET_OPTION */ SyscallSetSocketOption,
|
||||
/* 88 SYS_GET_SOCKET_OPTION */ SyscallGetSocketOption,
|
||||
/* 89 SYS_POLL */ SyscallPoll,
|
||||
/* 90 SYS_GET_MEMORY_STATUS */ SyscallGetMemoryStatus,
|
||||
/* 91 SYS_QUERY_KERNEL_STATS */ SyscallQueryKernelStats
|
||||
/* 91 SYS_QUERY_KERNEL_STATS */ SyscallQueryKernelStats,
|
||||
/* 92 SYS_GET_SYSTEM_TIME */ SyscallGetSystemTime
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,500 @@
|
||||
// ke_time.c - kernel wall-clock time service
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <ntlite/status.h>
|
||||
#include <ntlite/boot_info.h>
|
||||
#include <ntlite/ddi/hal_api.h>
|
||||
#include <kernel/ke_time.h>
|
||||
#include <kernel/ke_debug.h>
|
||||
#include <kernel/ke_settings.h>
|
||||
|
||||
#define KE_TIME_FALLBACK_YEAR 2024u
|
||||
#define KE_TIME_FALLBACK_MONTH 1u
|
||||
#define KE_TIME_FALLBACK_DAY 1u
|
||||
|
||||
#define KE_TZ_UNSPECIFIED SYS_TIME_UNSPECIFIED_TZ
|
||||
#define KE_CE_STANDARD_OFFSET 60
|
||||
#define KE_DST_OFFSET_DELTA 60
|
||||
|
||||
typedef enum KE_DST_RULE {
|
||||
KeDstRuleNone = 0,
|
||||
KeDstRuleAlways,
|
||||
KeDstRuleCentralEurope,
|
||||
} KE_DST_RULE;
|
||||
|
||||
typedef struct KE_TIME_ZONE_POLICY {
|
||||
int16_t StandardOffsetMinutes; // minutes east of UTC.
|
||||
KE_DST_RULE DstRule;
|
||||
bool TimeZoneKnown;
|
||||
} KE_TIME_ZONE_POLICY;
|
||||
|
||||
typedef enum KE_HARDWARE_CLOCK_MODE {
|
||||
KeHardwareClockUtc = 0,
|
||||
KeHardwareClockLocal,
|
||||
} KE_HARDWARE_CLOCK_MODE;
|
||||
|
||||
static const HAL_API* gTimeHal;
|
||||
static uint64_t gSourceRawEpochSeconds;
|
||||
static int16_t gSourceTimeZoneMinutes;
|
||||
static bool gSourceTimeZoneKnown;
|
||||
static uint32_t gSourceNanosecond;
|
||||
static uint64_t gSourceTickMicroseconds;
|
||||
static uint64_t gBaseUtcEpochSeconds;
|
||||
static uint64_t gBaseTickMicroseconds;
|
||||
static uint16_t gSourceFlags;
|
||||
static KE_TIME_ZONE_POLICY gTimeZonePolicy = {
|
||||
KE_CE_STANDARD_OFFSET,
|
||||
KeDstRuleCentralEurope,
|
||||
true,
|
||||
};
|
||||
static KE_HARDWARE_CLOCK_MODE gHardwareClockMode = KeHardwareClockUtc;
|
||||
|
||||
static bool KiIsLeapYear(uint32_t year) {
|
||||
return ((year % 4u) == 0u && (year % 100u) != 0u) || ((year % 400u) == 0u);
|
||||
}
|
||||
|
||||
static uint32_t KiDaysInMonth(uint32_t year, uint32_t month) {
|
||||
static const uint8_t days[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
|
||||
if (month == 2u && KiIsLeapYear(year)) return 29u;
|
||||
if (month < 1u || month > 12u) return 0u;
|
||||
return days[month - 1u];
|
||||
}
|
||||
|
||||
static bool KiValidCalendar(uint32_t year, uint32_t month, uint32_t day,
|
||||
uint32_t hour, uint32_t minute, uint32_t second,
|
||||
uint32_t nanosecond) {
|
||||
if (year < 1970u || year > 9999u) return false;
|
||||
if (month < 1u || month > 12u) return false;
|
||||
uint32_t dim = KiDaysInMonth(year, month);
|
||||
if (day < 1u || day > dim) return false;
|
||||
if (hour > 23u || minute > 59u || second > 59u) return false;
|
||||
if (nanosecond >= 1000000000u) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint64_t KiDaysBeforeYear(uint32_t year) {
|
||||
uint64_t days = 0;
|
||||
for (uint32_t y = 1970u; y < year; y++)
|
||||
days += KiIsLeapYear(y) ? 366u : 365u;
|
||||
return days;
|
||||
}
|
||||
|
||||
static uint64_t KiCalendarToEpochSeconds(uint32_t year, uint32_t month, uint32_t day,
|
||||
uint32_t hour, uint32_t minute, uint32_t second) {
|
||||
uint64_t days = KiDaysBeforeYear(year);
|
||||
for (uint32_t m = 1u; m < month; m++)
|
||||
days += KiDaysInMonth(year, m);
|
||||
days += (uint64_t)(day - 1u);
|
||||
return (((days * 24u) + hour) * 60u + minute) * 60u + second;
|
||||
}
|
||||
|
||||
static void KiEpochSecondsToCalendar(uint64_t epochSeconds, SYS_SYSTEM_TIME* out) {
|
||||
uint64_t days = epochSeconds / 86400u;
|
||||
uint32_t sod = (uint32_t)(epochSeconds % 86400u);
|
||||
|
||||
uint32_t year = 1970u;
|
||||
for (;;) {
|
||||
uint32_t diy = KiIsLeapYear(year) ? 366u : 365u;
|
||||
if (days < diy) break;
|
||||
days -= diy;
|
||||
year++;
|
||||
}
|
||||
|
||||
uint32_t month = 1u;
|
||||
for (;;) {
|
||||
uint32_t dim = KiDaysInMonth(year, month);
|
||||
if (days < dim) break;
|
||||
days -= dim;
|
||||
month++;
|
||||
}
|
||||
|
||||
uint64_t totalDays = epochSeconds / 86400u;
|
||||
out->Year = (uint16_t)year;
|
||||
out->Month = (uint8_t)month;
|
||||
out->Day = (uint8_t)(days + 1u);
|
||||
out->Hour = (uint8_t)(sod / 3600u);
|
||||
out->Minute = (uint8_t)((sod / 60u) % 60u);
|
||||
out->Second = (uint8_t)(sod % 60u);
|
||||
out->DayOfWeek = (uint8_t)((totalDays + 4u) % 7u); // 1970-01-01 was Thursday.
|
||||
}
|
||||
|
||||
static uint32_t KiDayOfWeek(uint32_t year, uint32_t month, uint32_t day) {
|
||||
uint64_t epoch = KiCalendarToEpochSeconds(year, month, day, 0, 0, 0);
|
||||
return (uint32_t)(((epoch / 86400u) + 4u) % 7u);
|
||||
}
|
||||
|
||||
static uint32_t KiLastSundayOfMonth(uint32_t year, uint32_t month) {
|
||||
uint32_t last = KiDaysInMonth(year, month);
|
||||
uint32_t dow = KiDayOfWeek(year, month, last); // Sunday == 0.
|
||||
return last - dow;
|
||||
}
|
||||
|
||||
static bool KiCentralEuropeDstActiveUtc(uint64_t utcEpochSeconds) {
|
||||
SYS_SYSTEM_TIME utc;
|
||||
memset(&utc, 0, sizeof(utc));
|
||||
KiEpochSecondsToCalendar(utcEpochSeconds, &utc);
|
||||
|
||||
uint32_t startDay = KiLastSundayOfMonth(utc.Year, 3u);
|
||||
uint32_t endDay = KiLastSundayOfMonth(utc.Year, 10u);
|
||||
uint64_t startUtc = KiCalendarToEpochSeconds(utc.Year, 3u, startDay, 1u, 0u, 0u);
|
||||
uint64_t endUtc = KiCalendarToEpochSeconds(utc.Year, 10u, endDay, 1u, 0u, 0u);
|
||||
return utcEpochSeconds >= startUtc && utcEpochSeconds < endUtc;
|
||||
}
|
||||
|
||||
static int16_t KiOffsetForUtcEpoch(uint64_t utcEpochSeconds, bool* daylight) {
|
||||
int32_t offset = gTimeZonePolicy.StandardOffsetMinutes;
|
||||
bool dst = false;
|
||||
|
||||
if (gTimeZonePolicy.DstRule == KeDstRuleAlways) {
|
||||
dst = true;
|
||||
} else if (gTimeZonePolicy.DstRule == KeDstRuleCentralEurope) {
|
||||
dst = KiCentralEuropeDstActiveUtc(utcEpochSeconds);
|
||||
}
|
||||
|
||||
if (dst) offset += KE_DST_OFFSET_DELTA;
|
||||
if (daylight) *daylight = dst;
|
||||
return (int16_t)offset;
|
||||
}
|
||||
|
||||
static uint64_t KiLocalEpochToUtc(uint64_t localEpochSeconds, int16_t offsetMinutes) {
|
||||
uint64_t offsetSeconds = (uint64_t)((offsetMinutes < 0) ? -offsetMinutes : offsetMinutes) * 60u;
|
||||
if (offsetMinutes >= 0)
|
||||
return (localEpochSeconds > offsetSeconds) ? (localEpochSeconds - offsetSeconds) : 0;
|
||||
return localEpochSeconds + offsetSeconds;
|
||||
}
|
||||
|
||||
static void KiRebaseUtcFromSource(void) {
|
||||
if (gSourceTimeZoneKnown) {
|
||||
gBaseUtcEpochSeconds = KiLocalEpochToUtc(gSourceRawEpochSeconds, gSourceTimeZoneMinutes);
|
||||
} else if (gHardwareClockMode == KeHardwareClockLocal) {
|
||||
bool daylight = false;
|
||||
int16_t offset = KiOffsetForUtcEpoch(gSourceRawEpochSeconds, &daylight);
|
||||
|
||||
// The first pass treated the local clock as UTC only so we can choose
|
||||
// the correct rule-year. Run one refinement against the candidate UTC
|
||||
// instant to handle daylight-saving transitions cleanly.
|
||||
uint64_t candidateUtc = KiLocalEpochToUtc(gSourceRawEpochSeconds, offset);
|
||||
offset = KiOffsetForUtcEpoch(candidateUtc, &daylight);
|
||||
gBaseUtcEpochSeconds = KiLocalEpochToUtc(gSourceRawEpochSeconds, offset);
|
||||
} else {
|
||||
gBaseUtcEpochSeconds = gSourceRawEpochSeconds;
|
||||
}
|
||||
gBaseTickMicroseconds = gSourceTickMicroseconds;
|
||||
}
|
||||
|
||||
static int KiAsciiLower(int c) {
|
||||
if (c >= 'A' && c <= 'Z') return c + ('a' - 'A');
|
||||
return c;
|
||||
}
|
||||
|
||||
static bool KiStringEqualsNoCase(const char* a, const char* b) {
|
||||
if (!a || !b) return false;
|
||||
while (*a && *b) {
|
||||
if (KiAsciiLower((unsigned char)*a) != KiAsciiLower((unsigned char)*b))
|
||||
return false;
|
||||
a++;
|
||||
b++;
|
||||
}
|
||||
return *a == '\0' && *b == '\0';
|
||||
}
|
||||
|
||||
static bool KiParseInt32(const char* s, int32_t* out) {
|
||||
if (!s || !*s || !out) return false;
|
||||
|
||||
int sign = 1;
|
||||
if (*s == '-') {
|
||||
sign = -1;
|
||||
s++;
|
||||
} else if (*s == '+') {
|
||||
s++;
|
||||
}
|
||||
|
||||
if (*s < '0' || *s > '9') return false;
|
||||
|
||||
int32_t value = 0;
|
||||
while (*s >= '0' && *s <= '9') {
|
||||
value = (value * 10) + (*s - '0');
|
||||
s++;
|
||||
}
|
||||
if (*s != '\0') return false;
|
||||
|
||||
*out = value * sign;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool KiStartsWithNoCase(const char* s, const char* prefix) {
|
||||
if (!s || !prefix) return false;
|
||||
while (*prefix) {
|
||||
if (KiAsciiLower((unsigned char)*s) != KiAsciiLower((unsigned char)*prefix))
|
||||
return false;
|
||||
s++;
|
||||
prefix++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool KiParseUtcOffset(const char* s, int16_t* out) {
|
||||
if (!s || !out) return false;
|
||||
|
||||
if (KiStringEqualsNoCase(s, "utc") || KiStringEqualsNoCase(s, "gmt") ||
|
||||
KiStringEqualsNoCase(s, "z") || KiStringEqualsNoCase(s, "utcz")) {
|
||||
*out = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (KiStartsWithNoCase(s, "utc")) {
|
||||
s += 3;
|
||||
} else if (KiStartsWithNoCase(s, "gmt")) {
|
||||
s += 3;
|
||||
}
|
||||
|
||||
int sign = 1;
|
||||
if (*s == '+') {
|
||||
sign = 1;
|
||||
s++;
|
||||
} else if (*s == '-') {
|
||||
sign = -1;
|
||||
s++;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (*s < '0' || *s > '9') return false;
|
||||
|
||||
int hours = 0;
|
||||
int digits = 0;
|
||||
while (*s >= '0' && *s <= '9' && digits < 2) {
|
||||
hours = hours * 10 + (*s - '0');
|
||||
s++;
|
||||
digits++;
|
||||
}
|
||||
|
||||
int minutes = 0;
|
||||
if (*s == ':') {
|
||||
s++;
|
||||
if (s[0] < '0' || s[0] > '9' || s[1] < '0' || s[1] > '9') return false;
|
||||
minutes = (s[0] - '0') * 10 + (s[1] - '0');
|
||||
s += 2;
|
||||
} else if (*s >= '0' && *s <= '9') {
|
||||
// Compact form, e.g. UTC+0200. Exactly two minute digits must remain.
|
||||
if (s[1] < '0' || s[1] > '9' || s[2] != '\0') return false;
|
||||
minutes = (s[0] - '0') * 10 + (s[1] - '0');
|
||||
s += 2;
|
||||
}
|
||||
|
||||
if (*s != '\0') return false;
|
||||
if (hours > 14 || minutes > 59) return false;
|
||||
|
||||
*out = (int16_t)(sign * (hours * 60 + minutes));
|
||||
return true;
|
||||
}
|
||||
|
||||
static void KiApplyDefaultTimeZonePolicy(void) {
|
||||
gTimeZonePolicy.StandardOffsetMinutes = KE_CE_STANDARD_OFFSET;
|
||||
gTimeZonePolicy.DstRule = KeDstRuleCentralEurope;
|
||||
gTimeZonePolicy.TimeZoneKnown = true;
|
||||
gHardwareClockMode = KeHardwareClockUtc;
|
||||
}
|
||||
|
||||
void KeTimeInitialize(const BOOT_INFO* bootInfo, const HAL_API* hal) {
|
||||
gTimeHal = hal;
|
||||
KiApplyDefaultTimeZonePolicy();
|
||||
gSourceTickMicroseconds = (hal && hal->Timer.QueryTicks) ? hal->Timer.QueryTicks() : 0;
|
||||
|
||||
const BOOT_TIME* bt = bootInfo ? &bootInfo->BootTime : 0;
|
||||
if (bt && (bt->Flags & BOOT_TIME_FLAG_VALID) &&
|
||||
KiValidCalendar(bt->Year, bt->Month, bt->Day, bt->Hour, bt->Minute,
|
||||
bt->Second, bt->Nanosecond)) {
|
||||
gSourceRawEpochSeconds = KiCalendarToEpochSeconds(bt->Year, bt->Month, bt->Day,
|
||||
bt->Hour, bt->Minute, bt->Second);
|
||||
gSourceTimeZoneKnown = (bt->Flags & BOOT_TIME_FLAG_TZ_KNOWN) &&
|
||||
bt->TimeZoneMinutes != BOOT_TIME_UNSPECIFIED_TZ;
|
||||
gSourceTimeZoneMinutes = gSourceTimeZoneKnown ? bt->TimeZoneMinutes : 0;
|
||||
gSourceNanosecond = bt->Nanosecond;
|
||||
gSourceFlags = SYS_TIME_FLAG_VALID | SYS_TIME_FLAG_UEFI;
|
||||
} else {
|
||||
HAL_RTC_TIME rtc;
|
||||
memset(&rtc, 0, sizeof(rtc));
|
||||
if (hal && hal->Rtc.QueryTime && hal->Rtc.QueryTime(&rtc) == STATUS_SUCCESS &&
|
||||
(rtc.Flags & HAL_RTC_TIME_FLAG_VALID) &&
|
||||
KiValidCalendar(rtc.Year, rtc.Month, rtc.Day, rtc.Hour, rtc.Minute,
|
||||
rtc.Second, rtc.Nanosecond)) {
|
||||
gSourceRawEpochSeconds = KiCalendarToEpochSeconds(rtc.Year, rtc.Month, rtc.Day,
|
||||
rtc.Hour, rtc.Minute, rtc.Second);
|
||||
gSourceTimeZoneKnown = false;
|
||||
gSourceTimeZoneMinutes = 0;
|
||||
gSourceNanosecond = rtc.Nanosecond;
|
||||
gSourceFlags = SYS_TIME_FLAG_VALID | SYS_TIME_FLAG_RTC;
|
||||
} else {
|
||||
gSourceRawEpochSeconds = KiCalendarToEpochSeconds(KE_TIME_FALLBACK_YEAR,
|
||||
KE_TIME_FALLBACK_MONTH,
|
||||
KE_TIME_FALLBACK_DAY,
|
||||
0, 0, 0);
|
||||
gSourceTimeZoneKnown = false;
|
||||
gSourceTimeZoneMinutes = 0;
|
||||
gSourceNanosecond = 0;
|
||||
gSourceFlags = SYS_TIME_FLAG_VALID | SYS_TIME_FLAG_FALLBACK;
|
||||
}
|
||||
}
|
||||
|
||||
KiRebaseUtcFromSource();
|
||||
|
||||
SYS_SYSTEM_TIME now;
|
||||
if (KeQuerySystemTime(&now) == STATUS_SUCCESS) {
|
||||
DbgPrint("time: initialized %04u-%02u-%02u %02u:%02u:%02u.%03u flags=0x%x tz=%d hw=%s epoch=%llu\n",
|
||||
now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second,
|
||||
now.Millisecond, now.Flags, now.TimeZoneMinutes,
|
||||
gHardwareClockMode == KeHardwareClockLocal ? "local" : "utc",
|
||||
now.EpochSeconds);
|
||||
}
|
||||
}
|
||||
|
||||
KSTATUS KeTimeReloadSettings(void) {
|
||||
KE_TIME_ZONE_POLICY policy = gTimeZonePolicy;
|
||||
char value[64];
|
||||
bool fixedTimezone = false;
|
||||
bool allowStandardOffsetSetting = false;
|
||||
|
||||
KSTATUS st = KeGetSettingString("time", "timezone", value, sizeof(value));
|
||||
if (KSUCCESS(st)) {
|
||||
if (KiStringEqualsNoCase(value, "central-europe") ||
|
||||
KiStringEqualsNoCase(value, "europe/warsaw")) {
|
||||
policy.StandardOffsetMinutes = KE_CE_STANDARD_OFFSET;
|
||||
policy.DstRule = KeDstRuleCentralEurope;
|
||||
policy.TimeZoneKnown = true;
|
||||
} else if (KiStringEqualsNoCase(value, "cet")) {
|
||||
policy.StandardOffsetMinutes = KE_CE_STANDARD_OFFSET;
|
||||
policy.DstRule = KeDstRuleNone;
|
||||
policy.TimeZoneKnown = true;
|
||||
fixedTimezone = true;
|
||||
} else if (KiStringEqualsNoCase(value, "cest")) {
|
||||
policy.StandardOffsetMinutes = KE_CE_STANDARD_OFFSET + KE_DST_OFFSET_DELTA;
|
||||
policy.DstRule = KeDstRuleNone;
|
||||
policy.TimeZoneKnown = true;
|
||||
fixedTimezone = true;
|
||||
} else if (KiStringEqualsNoCase(value, "custom") ||
|
||||
KiStringEqualsNoCase(value, "manual")) {
|
||||
policy.DstRule = KeDstRuleNone;
|
||||
policy.TimeZoneKnown = true;
|
||||
fixedTimezone = true;
|
||||
allowStandardOffsetSetting = true;
|
||||
} else if (KiStringEqualsNoCase(value, "utc") ||
|
||||
KiStringEqualsNoCase(value, "gmt") ||
|
||||
KiStringEqualsNoCase(value, "z")) {
|
||||
policy.StandardOffsetMinutes = 0;
|
||||
policy.DstRule = KeDstRuleNone;
|
||||
policy.TimeZoneKnown = true;
|
||||
fixedTimezone = true;
|
||||
} else {
|
||||
int16_t parsedOffset = 0;
|
||||
if (KiParseUtcOffset(value, &parsedOffset)) {
|
||||
policy.StandardOffsetMinutes = parsedOffset;
|
||||
policy.DstRule = KeDstRuleNone;
|
||||
policy.TimeZoneKnown = true;
|
||||
fixedTimezone = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
st = KeGetSettingString("time", "standard_offset_minutes", value, sizeof(value));
|
||||
if (KSUCCESS(st) && allowStandardOffsetSetting) {
|
||||
int32_t minutes;
|
||||
if (KiParseInt32(value, &minutes) && minutes >= -14 * 60 && minutes <= 14 * 60) {
|
||||
policy.StandardOffsetMinutes = (int16_t)minutes;
|
||||
policy.TimeZoneKnown = true;
|
||||
fixedTimezone = true;
|
||||
}
|
||||
}
|
||||
|
||||
st = KeGetSettingString("time", "daylight_saving", value, sizeof(value));
|
||||
if (KSUCCESS(st)) {
|
||||
if (KiStringEqualsNoCase(value, "auto")) {
|
||||
if (!fixedTimezone)
|
||||
policy.DstRule = KeDstRuleCentralEurope;
|
||||
} else if (KiStringEqualsNoCase(value, "central-europe")) {
|
||||
policy.DstRule = KeDstRuleCentralEurope;
|
||||
} else if (KiStringEqualsNoCase(value, "on") || KiStringEqualsNoCase(value, "yes") ||
|
||||
KiStringEqualsNoCase(value, "true") || KiStringEqualsNoCase(value, "1")) {
|
||||
policy.DstRule = KeDstRuleAlways;
|
||||
} else if (KiStringEqualsNoCase(value, "off") || KiStringEqualsNoCase(value, "no") ||
|
||||
KiStringEqualsNoCase(value, "false") || KiStringEqualsNoCase(value, "0")) {
|
||||
policy.DstRule = KeDstRuleNone;
|
||||
}
|
||||
}
|
||||
|
||||
KE_HARDWARE_CLOCK_MODE hardwareClockMode = gHardwareClockMode;
|
||||
st = KeGetSettingString("time", "hardware_clock", value, sizeof(value));
|
||||
if (KSUCCESS(st)) {
|
||||
if (KiStringEqualsNoCase(value, "utc") || KiStringEqualsNoCase(value, "z")) {
|
||||
hardwareClockMode = KeHardwareClockUtc;
|
||||
} else if (KiStringEqualsNoCase(value, "local") ||
|
||||
KiStringEqualsNoCase(value, "localtime") ||
|
||||
KiStringEqualsNoCase(value, "wall-clock")) {
|
||||
hardwareClockMode = KeHardwareClockLocal;
|
||||
}
|
||||
}
|
||||
|
||||
gTimeZonePolicy = policy;
|
||||
gHardwareClockMode = hardwareClockMode;
|
||||
KiRebaseUtcFromSource();
|
||||
|
||||
SYS_SYSTEM_TIME now;
|
||||
if (KeQuerySystemTime(&now) == STATUS_SUCCESS) {
|
||||
DbgPrint("time: settings timezone=%d dst=%s hw=%s now=%04u-%02u-%02u %02u:%02u:%02u flags=0x%x epoch=%llu\n",
|
||||
now.TimeZoneMinutes,
|
||||
(now.Flags & SYS_TIME_FLAG_DAYLIGHT) ? "on" : "off",
|
||||
gHardwareClockMode == KeHardwareClockLocal ? "local" : "utc",
|
||||
now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second,
|
||||
now.Flags, now.EpochSeconds);
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
__declspec(dllexport) KSTATUS KeQuerySystemTime(SYS_SYSTEM_TIME* outTime) {
|
||||
if (!outTime) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
uint64_t nowTick = (gTimeHal && gTimeHal->Timer.QueryTicks)
|
||||
? gTimeHal->Timer.QueryTicks()
|
||||
: gBaseTickMicroseconds;
|
||||
uint64_t elapsedUs = nowTick - gBaseTickMicroseconds;
|
||||
|
||||
uint64_t utcEpochSeconds = gBaseUtcEpochSeconds + (elapsedUs / 1000000u);
|
||||
uint64_t ns = (uint64_t)gSourceNanosecond + (elapsedUs % 1000000u) * 1000u;
|
||||
if (ns >= 1000000000u) {
|
||||
utcEpochSeconds += ns / 1000000000u;
|
||||
ns %= 1000000000u;
|
||||
}
|
||||
|
||||
bool daylight = false;
|
||||
int16_t offset = KiOffsetForUtcEpoch(utcEpochSeconds, &daylight);
|
||||
uint64_t offsetSeconds = (uint64_t)((offset < 0) ? -offset : offset) * 60u;
|
||||
uint64_t localEpochSeconds;
|
||||
if (offset >= 0) {
|
||||
localEpochSeconds = utcEpochSeconds + offsetSeconds;
|
||||
} else {
|
||||
localEpochSeconds = (utcEpochSeconds > offsetSeconds) ? (utcEpochSeconds - offsetSeconds) : 0;
|
||||
}
|
||||
|
||||
SYS_SYSTEM_TIME t;
|
||||
memset(&t, 0, sizeof(t));
|
||||
KiEpochSecondsToCalendar(localEpochSeconds, &t);
|
||||
t.Nanosecond = (uint32_t)ns;
|
||||
t.Millisecond = (uint16_t)(ns / 1000000u);
|
||||
t.Flags = gSourceFlags;
|
||||
if (gTimeZonePolicy.TimeZoneKnown) t.Flags |= SYS_TIME_FLAG_TZ_KNOWN;
|
||||
if (daylight) t.Flags |= SYS_TIME_FLAG_DAYLIGHT;
|
||||
t.TimeZoneMinutes = gTimeZonePolicy.TimeZoneKnown ? offset : KE_TZ_UNSPECIFIED;
|
||||
t.EpochSeconds = utcEpochSeconds;
|
||||
t.TickMicroseconds = nowTick;
|
||||
|
||||
*outTime = t;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
__declspec(dllexport) uint64_t KeQueryUnixTimeSeconds(void) {
|
||||
SYS_SYSTEM_TIME t;
|
||||
if (KeQuerySystemTime(&t) != STATUS_SUCCESS)
|
||||
return 0;
|
||||
return t.EpochSeconds;
|
||||
}
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <kernel/ke_selftest.h>
|
||||
#include <kernel/ke_smp.h>
|
||||
#include <kernel/ke_input.h>
|
||||
#include <kernel/ke_time.h>
|
||||
#include <common/ini_parser.h>
|
||||
|
||||
typedef struct {
|
||||
@@ -214,6 +215,10 @@ static void KiInitializeDrivers(BOOT_INFO* bootInfo, const HAL_API* hal) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Runtime modules may also export DDIs to drivers loaded later. Boot
|
||||
// drivers were already registered above; keep the module model uniform.
|
||||
LdrRegisterModule(runtimeKeys[i], mappedBase);
|
||||
|
||||
DRIVER_ENTRY_FN entry = (DRIVER_ENTRY_FN)(LdrGetEntryPoint(mappedBase));
|
||||
|
||||
KSTATUS ds = entry(hal);
|
||||
@@ -337,6 +342,7 @@ void SystemInitThread(void* arg) {
|
||||
KiRunEarlyKernelSelfTests();
|
||||
|
||||
KiInitializeDrivers(args->bootInfo, args->hal);
|
||||
KeTimeReloadSettings();
|
||||
|
||||
KiResolveSystemImports(args->bootInfo);
|
||||
KiReclaimBootloaderMemory(args->bootInfo);
|
||||
@@ -422,6 +428,7 @@ extern void KernelMain(BOOT_INFO* bootInfo) {
|
||||
gKmainHal = hal;
|
||||
|
||||
KeInitDebug(hal->Screen.PrintChar, bootInfo->Debug);
|
||||
KeTimeInitialize(bootInfo, hal);
|
||||
|
||||
// CPU startup intentionally lives after HAL initialization but before IRQs
|
||||
// and scheduler startup. HAL owns ACPI/MADT discovery and LAPIC INIT/SIPI;
|
||||
|
||||
Reference in new issue
Block a user