mirror of
https://github.com/subhobhai943/SUB-OS.git
synced 2026-10-25 16:52:29 +00:00
Add three real platform device drivers (x86 hardware, ARM-stubbed): - drivers/timer/hpet.c + include/drivers/hpet.h: High Precision Event Timer. Maps the HPET block at the standard 0xFED00000, reads the femtosecond period from the capability register, enables the main counter and exposes a monotonic nanosecond time source (hpet_get_ns) far finer than the 100 Hz PIT. - drivers/char/lpt.c + include/drivers/lpt.h: IBM PC parallel port (LPT1) with the Centronics data/strobe handshake over ports 0x378/0x379/0x37A. - drivers/char/nvram.c + include/drivers/nvram.h: MC146818 CMOS NVRAM read/write over 0x70/0x71, preserving the NMI-disable bit, with checksum and hex dump. Wired all three into the [5/14] device-enumeration boot step and added LazyBox applets `hpet`, `lpt`, and `nvram`. Verified live under QEMU (screenshotted): HPET reports 100 MHz / 3 comparators / 10 ns period and its counter advances ~1.4 s of real time between two `hpet` runs; NVRAM dumps 128 bytes with a computed checksum; LPT1 detected at 0x378. Clean build on x86_64/aarch64/armv8i; 0 panics / 0 OOM. Co-Authored-By: Claude Opus 4.8 <[email protected]> Claude-Session: https://claude.ai/code/session_01Fh5z6V7nGPbHvqVG5p4CXX
65 lines
2.0 KiB
C
65 lines
2.0 KiB
C
// CMOS / RTC NVRAM driver for SUB-OS.
|
|
//
|
|
// Reads and writes the MC146818 CMOS register file behind ports 0x70/0x71.
|
|
// The NMI-disable bit (0x80) of the index port is preserved on every access so
|
|
// this driver never inadvertently re-enables NMIs.
|
|
|
|
#include <drivers/nvram.h>
|
|
#include <kernel/printk.h>
|
|
|
|
#if defined(__x86_64__)
|
|
#include <arch/x86_64/io.h>
|
|
|
|
#define CMOS_INDEX 0x70
|
|
#define CMOS_DATA 0x71
|
|
#define CMOS_NMI_DISABLE 0x80
|
|
|
|
uint8_t nvram_read(uint8_t index) {
|
|
uint8_t prev = inb(CMOS_INDEX) & CMOS_NMI_DISABLE;
|
|
outb(CMOS_INDEX, prev | (index & 0x7F));
|
|
return inb(CMOS_DATA);
|
|
}
|
|
|
|
void nvram_write(uint8_t index, uint8_t value) {
|
|
uint8_t prev = inb(CMOS_INDEX) & CMOS_NMI_DISABLE;
|
|
outb(CMOS_INDEX, prev | (index & 0x7F));
|
|
outb(CMOS_DATA, value);
|
|
}
|
|
|
|
uint8_t nvram_checksum(void) {
|
|
uint16_t sum = 0;
|
|
for (int i = NVRAM_USER_START; i < NVRAM_SIZE; i++) {
|
|
sum += nvram_read((uint8_t)i);
|
|
}
|
|
return (uint8_t)(sum & 0xFF);
|
|
}
|
|
|
|
void nvram_dump(void) {
|
|
printk(ANSI_BRIGHT_CYAN "CMOS NVRAM (128 bytes):\n" ANSI_RESET);
|
|
for (int row = 0; row < NVRAM_SIZE; row += 16) {
|
|
printk(" %02X: ", row);
|
|
for (int col = 0; col < 16; col++) {
|
|
printk("%02X ", nvram_read((uint8_t)(row + col)));
|
|
}
|
|
printk("\n");
|
|
}
|
|
}
|
|
|
|
void nvram_init(void) {
|
|
// Byte 0x0F is the BIOS shutdown status; reading it proves the port works.
|
|
uint8_t shutdown_status = nvram_read(0x0F);
|
|
printk(ANSI_BRIGHT_GREEN "NVRAM: " ANSI_RESET
|
|
"CMOS scratch RAM ready (%d bytes, checksum 0x%02X, shutdown-status 0x%02X)\n",
|
|
NVRAM_SIZE, nvram_checksum(), shutdown_status);
|
|
}
|
|
|
|
#else // CMOS/RTC NVRAM is an x86 platform device.
|
|
|
|
uint8_t nvram_read(uint8_t index) { (void)index; return 0; }
|
|
void nvram_write(uint8_t index, uint8_t v){ (void)index; (void)v; }
|
|
uint8_t nvram_checksum(void) { return 0; }
|
|
void nvram_dump(void) { }
|
|
void nvram_init(void) { }
|
|
|
|
#endif
|