add system time, clean up pci into pci.sys, clean up syscall names, fix USERAPC1 typo

This commit is contained in:
maksw committed 2026-06-11 18:11:59 +02:00
1 parent c1a291c4c9
commit e41bf6e2c0
64 files changed
+4514 -2220

No files matched your search

+11 -2
View File
@@ -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
View File
@@ -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;
}
+163
View File
@@ -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");
}
}
+1 -1
View File
@@ -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;
+11
View File
@@ -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);
+94 -93
View File
@@ -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
View File
@@ -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
};
// ---------------------------------------------------------------------------
+500
View File
@@ -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;
}
+7
View File
@@ -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;