redo boot around an explicit system volume and fixed kernel/HAL images, redo volumes and filesystem paths around capabilities instead of drive numbers and kernel CWD state, add a capability/security model with derived and revocable handles and security contexts, add port IPC and rssrv to manage the userspace resource namespace and publish the system volume, move process, dll and path loading to userspace and add process builder syscalls, init now supervises rssrv and the session process, redo the syscall ABI around request structs and four arguments, add a volume manager and proper partition arrival/removal handling so FAT and NTFS mount dynamically, clean up the HAL/DDK boundary so drivers don't depend on HAL internals, save fpu state properly now, the serial driver doesn't hang on a missing port, fix AHCI startup races, fix timeout accounting, fix shared mmap writeback, more smoke tests
This commit is contained in:
1 parent
4add6789ba
commit
f882d339fb
232 files changed
+20934
-8898
No files matched your search
@@ -1,26 +1,51 @@
|
||||
// HAL serial output endpoint. This file owns polling COM1 writes and subscribes serial to HAL text streams.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <intrin.h>
|
||||
#include <ntlite/ddi/hal_api.h>
|
||||
#include <kernel/hal/hal_api.h>
|
||||
#include <kernel/hal/hal_output.h>
|
||||
#include <kernel/hal/hal_processor.h>
|
||||
|
||||
#define HAL_COM1_DATA_PORT 0x03F8u
|
||||
#define HAL_COM1_STATUS_PORT 0x03FDu
|
||||
#define HAL_COM1_TX_READY 0x20u
|
||||
#define HAL_COM1_BASE 0x03F8u
|
||||
#define HAL_COM1_DATA_PORT (HAL_COM1_BASE + 0u)
|
||||
#define HAL_COM1_STATUS_PORT (HAL_COM1_BASE + 5u)
|
||||
#define HAL_COM1_SCRATCH_PORT (HAL_COM1_BASE + 7u)
|
||||
#define HAL_COM1_TX_READY 0x20u
|
||||
#define HAL_SERIAL_TX_SPIN_LIMIT 1000000u
|
||||
|
||||
static volatile long gSerialWriteLock;
|
||||
static volatile long gSerialPresent;
|
||||
|
||||
// Waits until COM1 can accept one byte.
|
||||
static void HalSerialWaitForTransmit(void) {
|
||||
while ((__inbyte(HAL_COM1_STATUS_PORT) & HAL_COM1_TX_READY) == 0)
|
||||
_mm_pause();
|
||||
// Probes the 16550 scratch register without relying on line-status values from an absent port.
|
||||
static bool HalSerialProbeCom1(void) {
|
||||
uint8_t original = __inbyte(HAL_COM1_SCRATCH_PORT);
|
||||
|
||||
__outbyte(HAL_COM1_SCRATCH_PORT, 0x5Au);
|
||||
uint8_t first = __inbyte(HAL_COM1_SCRATCH_PORT);
|
||||
__outbyte(HAL_COM1_SCRATCH_PORT, 0xA5u);
|
||||
uint8_t second = __inbyte(HAL_COM1_SCRATCH_PORT);
|
||||
__outbyte(HAL_COM1_SCRATCH_PORT, original);
|
||||
|
||||
return first == 0x5Au && second == 0xA5u;
|
||||
}
|
||||
|
||||
// Writes one byte to COM1.
|
||||
static void HalSerialWriteByte(uint8_t value) {
|
||||
HalSerialWaitForTransmit();
|
||||
// Waits for COM1 transmit readiness without allowing broken or removed hardware to stall the machine forever.
|
||||
static bool HalSerialWaitForTransmit(void) {
|
||||
for (uint32_t spin = 0; spin < HAL_SERIAL_TX_SPIN_LIMIT; spin++) {
|
||||
if ((__inbyte(HAL_COM1_STATUS_PORT) & HAL_COM1_TX_READY) != 0)
|
||||
return true;
|
||||
_mm_pause();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Writes one byte to COM1 when the device remains responsive.
|
||||
static bool HalSerialWriteByte(uint8_t value) {
|
||||
if (!HalSerialWaitForTransmit())
|
||||
return false;
|
||||
__outbyte(HAL_COM1_DATA_PORT, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Acquires the normal serial writer lock.
|
||||
@@ -37,7 +62,8 @@ static void HalSerialReleaseWriteLock(void) {
|
||||
// Writes one output record through polling COM1.
|
||||
static void HalSerialWriteRecord(void* context, const HAL_OUTPUT_RECORD* record) {
|
||||
(void)context;
|
||||
if (!record || !record->Buffer)
|
||||
if (!record || !record->Buffer ||
|
||||
_InterlockedCompareExchange(&gSerialPresent, 0, 0) == 0)
|
||||
return;
|
||||
|
||||
bool emergency = (record->Flags & HAL_OUTPUT_WRITE_EMERGENCY) != 0;
|
||||
@@ -47,24 +73,36 @@ static void HalSerialWriteRecord(void* context, const HAL_OUTPUT_RECORD* record)
|
||||
HalSerialAcquireWriteLock();
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < record->Length; i++) {
|
||||
bool responsive = true;
|
||||
for (size_t i = 0; i < record->Length && responsive; i++) {
|
||||
char c = record->Buffer[i];
|
||||
if (c == '\n')
|
||||
HalSerialWriteByte('\r');
|
||||
HalSerialWriteByte((uint8_t)c);
|
||||
responsive = HalSerialWriteByte('\r');
|
||||
if (responsive)
|
||||
responsive = HalSerialWriteByte((uint8_t)c);
|
||||
}
|
||||
|
||||
if (!responsive)
|
||||
_InterlockedExchange(&gSerialPresent, 0);
|
||||
|
||||
if (!emergency) {
|
||||
HalSerialReleaseWriteLock();
|
||||
HalRestoreInterrupts(interruptFlags);
|
||||
}
|
||||
}
|
||||
|
||||
// Registers the polling serial endpoint.
|
||||
// Registers the polling serial endpoint only when a 16550-compatible COM1 device is present.
|
||||
void HalSerialInitialize(HAL_OUTPUT_ROUTER* output) {
|
||||
if (!output || !output->RegisterEndpoint)
|
||||
return;
|
||||
|
||||
gSerialWriteLock = 0;
|
||||
gSerialPresent = 0;
|
||||
if (!HalSerialProbeCom1())
|
||||
return;
|
||||
|
||||
gSerialPresent = 1;
|
||||
|
||||
HAL_OUTPUT_ENDPOINT endpoint;
|
||||
endpoint.Name = "serial0";
|
||||
endpoint.StreamMask = HAL_OUTPUT_STREAM_ALL;
|
||||
@@ -75,4 +113,6 @@ void HalSerialInitialize(HAL_OUTPUT_ROUTER* output) {
|
||||
uint32_t endpointId = HAL_OUTPUT_ENDPOINT_INVALID;
|
||||
if (KSUCCESS(output->RegisterEndpoint(&endpoint, &endpointId)))
|
||||
output->SerialEndpointId = endpointId;
|
||||
else
|
||||
gSerialPresent = 0;
|
||||
}
|
||||
Reference in new issue
Block a user