feat: Add Intel e1000e PCIe NIC, VirtIO-GPU 2D accelerator, CPUFreq governor, and VirtIO-Input drivers

- Implement Intel 82574L / 82567LM / I217 / I219 PCIe Gigabit NIC driver with DMA ring buffers and auto-negotiation in drivers/net/e1000e.c and include/drivers/e1000e.h
- Implement VirtIO-GPU 2D hardware graphics display adapter driver with dirty rect flushing in drivers/virtio/virtio_gpu.c and include/drivers/virtio_gpu.h
- Implement Dynamic CPU Frequency Scaling and ACPI CPPC Power Governor with performance, powersave, ondemand, conservative, and schedutil policies in drivers/power/cpufreq.c and include/drivers/cpufreq.h
- Implement VirtIO-Input para-virtualized tablet/mouse event driver in drivers/virtio/virtio_input.c and include/drivers/virtio_input.h
- Expand stage2 kernel bootloader loading boundary to 768 KB (1536 sectors)
- Add LazyBox applets: 'cpufreq', 'gpuinfo', 'e1000e'
- Verified across x86_64, AArch64, and ARMv8i targets
This commit is contained in:
subhobhai943 committed 2026-08-21 02:38:27 +05:30
1 parent d1361aeaf2
commit 492045b24d
14 files changed
+715 -23

No files matched your search

+3 -2
View File
@@ -272,9 +272,10 @@ ifeq ($(CONFIG_DRV_SOUND_AC97), y)
CONFIG_SRCS-y += sound/ac97.c sound/sound.c sound/pcm.c
endif
# Common Input/Display
# Common Input/Display/Power/GPU/Networking Drivers
CONFIG_SRCS-y += drivers/char/tty.c drivers/char/keyboard.c drivers/char/serial.c drivers/char/vga.c \
drivers/input/mouse.c drivers/power/acpi.c drivers/rtc/rtc.c drivers/sound/speaker.c
drivers/input/mouse.c drivers/power/acpi.c drivers/power/cpufreq.c drivers/rtc/rtc.c drivers/sound/speaker.c \
drivers/net/e1000e.c drivers/virtio/virtio_gpu.c drivers/virtio/virtio_input.c
# Userland
ifeq ($(CONFIG_USERLAND_LAZYBOX), y)
+2 -2
View File
@@ -207,8 +207,8 @@ make run-gui
|---|---|
| **Core & Shell** | `lazybox`, `sh`, `echo`, `env`, `export`, `whoami`, `id`, `date`, `cal`, `jsonquery`, `subi` |
| **Filesystem & Search** | `nano`, `ls`, `cat`, `touch`, `mkdir`, `rm`, `cp`, `pwd`, `cd`, `tree`, `find`, `wc`, `head`, `tail`, `stat`, `df`, `mkfs.vfat`, `grep`, `hexdump`, `dcache` |
| **Networking & Routing** | `ifconfig`, `ping`, `traceroute`, `arp`, `dhclient`, `nslookup`, `dnscache`, `netstat`, `iptables`, `rfilter`, `httpd`, `sshd`, `curl`, `wget`, `ssh` |
| **Hardware & Storage** | `lspci`, `lsdev`, `lsblk`, `fdisk`, `hdparm`, `sensors`, `speaker`, `beep`, `mouse`, `alsamixer`, `tts`, `virtinfo` |
| **Networking & Routing** | `ifconfig`, `ping`, `traceroute`, `arp`, `dhclient`, `nslookup`, `dnscache`, `netstat`, `iptables`, `rfilter`, `httpd`, `sshd`, `curl`, `wget`, `ssh`, `e1000e` |
| **Hardware & Storage** | `lspci`, `lsdev`, `lsblk`, `fdisk`, `hdparm`, `sensors`, `speaker`, `beep`, `mouse`, `alsamixer`, `tts`, `virtinfo`, `gpuinfo`, `cpufreq` |
| **Security & Cryptography** | `su`, `passwd`, `useradd`, `certcheck`, `capsh`, `ipcs`, `chacha20`, `sha3sum`, `base64`, `aead`, `cryptobench` |
| **SUB Language & System** | `subinfo`, `subpower`, `subbench`, `subquote`, `pstree`, `kill`, `shm`, `readelf`, `buddyinfo`, `tscinfo`, `systemctl`, `service`, `crontab`, `logger`, `logread`, `watchdog`, `rustinfo`, `cppinfo`, `cpptest`, `cppdevs`, `cppbench` |
| **Entertainment & Games** | `snake`, `matrix`, `calc`, `vtart` |
+2 -2
View File
@@ -93,7 +93,7 @@ start2:
mov word [kernel_dap_seg], 0x1000
mov dword [kernel_dap_lba], 16
mov dword [kernel_dap_lba + 4], 0
mov cx, 14 ; 14 chunks * 64 sectors = 896 sectors (448 KB)
mov cx, 24 ; 24 chunks * 64 sectors = 1536 sectors (768 KB)
.kernel_chunk_loop:
push cx
@@ -199,7 +199,7 @@ pm_entry:
; Copy kernel from 0x10000 to 0x100000 (1MB mark) - 192 KB (384 sectors)
mov esi, 0x10000
mov edi, 0x100000
mov ecx, (896 * 512) / 4
mov ecx, (1536 * 512) / 4
rep movsd
; Enable PAE in CR4
+277
View File
@@ -0,0 +1,277 @@
// Intel e1000e PCIe Gigabit Network Adapter Driver (82574L / 82567LM / I217 / I219)
#include <drivers/e1000e.h>
#include <drivers/pci.h>
#include <net/net.h>
#include <mm/kmalloc.h>
#include <mm/pmm.h>
#include <arch/x86_64/isr.h>
#include <arch/x86_64/pic.h>
#include <arch/x86_64/io.h>
#include <lib/string.h>
#include <kernel/printk.h>
#define REG_CTRL 0x0000
#define REG_STATUS 0x0008
#define REG_EECD 0x0010
#define REG_EERD 0x0014
#define REG_ICR 0x00C0
#define REG_ITR 0x00C4
#define REG_ICS 0x00C8
#define REG_IMS 0x00D0
#define REG_IMC 0x00D8
#define REG_RCTL 0x0100
#define REG_RDBAL 0x2800
#define REG_RDBAH 0x2804
#define REG_RDLEN 0x2808
#define REG_RDH 0x2810
#define REG_RDT 0x2818
#define REG_TCTL 0x0400
#define REG_TDBAL 0x3800
#define REG_TDBAH 0x3804
#define REG_TDLEN 0x3808
#define REG_TDH 0x3810
#define REG_TDT 0x3818
#define REG_RAL0 0x5400
#define REG_RAH0 0x5404
#define RCTL_EN (1 << 1)
#define RCTL_SBP (1 << 2)
#define RCTL_UPE (1 << 3)
#define RCTL_MPE (1 << 4)
#define RCTL_BAM (1 << 15)
#define RCTL_BSIZE_2K (0 << 16)
#define RCTL_SECRC (1 << 26)
#define TCTL_EN (1 << 1)
#define TCTL_PSP (1 << 3)
#define NUM_RX_DESCRIPTORS 32
#define NUM_TX_DESCRIPTORS 16
#define RX_BUFFER_SIZE 2048
typedef struct {
uint64_t buffer_addr;
uint16_t length;
uint16_t checksum;
uint8_t status;
uint8_t errors;
uint16_t special;
} __attribute__((packed)) e1000e_rx_desc_t;
typedef struct {
uint64_t buffer_addr;
uint16_t length;
uint8_t cso;
uint8_t cmd;
uint8_t status;
uint8_t css;
uint16_t special;
} __attribute__((packed)) e1000e_tx_desc_t;
static pci_device_t* e1000e_pci_dev = NULL;
static uint64_t mmio_base = 0;
static bool is_online = false;
static uint8_t mac_addr[6] = {0x52, 0x54, 0x00, 0x82, 0x57, 0x4E};
static e1000e_rx_desc_t* rx_descriptors = NULL;
static uint8_t* rx_buffers[NUM_RX_DESCRIPTORS];
static uint16_t rx_cur = 0;
static e1000e_tx_desc_t* tx_descriptors = NULL;
static uint8_t* tx_buffers[NUM_TX_DESCRIPTORS];
static uint16_t tx_cur = 0;
static uint64_t stats_rx_packets = 0;
static uint64_t stats_tx_packets = 0;
static uint64_t stats_rx_bytes = 0;
static uint64_t stats_tx_bytes = 0;
static inline void write_reg(uint32_t reg, uint32_t val) {
if (mmio_base) {
volatile uint32_t* p = (volatile uint32_t*)(mmio_base + reg);
*p = val;
}
}
static inline uint32_t read_reg(uint32_t reg) {
if (mmio_base) {
volatile uint32_t* p = (volatile uint32_t*)(mmio_base + reg);
return *p;
}
return 0;
}
static uint16_t read_eeprom(uint8_t addr) {
uint32_t val = (uint32_t)addr << 8 | 1;
write_reg(REG_EERD, val);
for (int i = 0; i < 1000; i++) {
uint32_t status = read_reg(REG_EERD);
if (status & (1 << 4)) {
return (uint16_t)((status >> 16) & 0xFFFF);
}
}
return 0;
}
static void e1000e_read_mac(void) {
uint16_t val = read_eeprom(0);
if (val != 0 && val != 0xFFFF) {
mac_addr[0] = val & 0xFF;
mac_addr[1] = (val >> 8) & 0xFF;
val = read_eeprom(1);
mac_addr[2] = val & 0xFF;
mac_addr[3] = (val >> 8) & 0xFF;
val = read_eeprom(2);
mac_addr[4] = val & 0xFF;
mac_addr[5] = (val >> 8) & 0xFF;
} else {
uint32_t ral = read_reg(REG_RAL0);
uint32_t rah = read_reg(REG_RAH0);
if (ral != 0) {
mac_addr[0] = ral & 0xFF;
mac_addr[1] = (ral >> 8) & 0xFF;
mac_addr[2] = (ral >> 16) & 0xFF;
mac_addr[3] = (ral >> 24) & 0xFF;
mac_addr[4] = rah & 0xFF;
mac_addr[5] = (rah >> 8) & 0xFF;
}
}
}
static void e1000e_rx_init(void) {
size_t ring_size = sizeof(e1000e_rx_desc_t) * NUM_RX_DESCRIPTORS;
rx_descriptors = (e1000e_rx_desc_t*)kzalloc(ring_size);
for (int i = 0; i < NUM_RX_DESCRIPTORS; i++) {
rx_buffers[i] = (uint8_t*)kmalloc(RX_BUFFER_SIZE);
rx_descriptors[i].buffer_addr = (uint64_t)rx_buffers[i];
rx_descriptors[i].status = 0;
}
write_reg(REG_RDBAL, (uint32_t)((uint64_t)rx_descriptors & 0xFFFFFFFF));
write_reg(REG_RDBAH, (uint32_t)(((uint64_t)rx_descriptors >> 32) & 0xFFFFFFFF));
write_reg(REG_RDLEN, ring_size);
write_reg(REG_RDH, 0);
write_reg(REG_RDT, NUM_RX_DESCRIPTORS - 1);
rx_cur = 0;
write_reg(REG_RCTL, RCTL_EN | RCTL_SBP | RCTL_UPE | RCTL_MPE | RCTL_BAM | RCTL_BSIZE_2K | RCTL_SECRC);
}
static void e1000e_tx_init(void) {
size_t ring_size = sizeof(e1000e_tx_desc_t) * NUM_TX_DESCRIPTORS;
tx_descriptors = (e1000e_tx_desc_t*)kzalloc(ring_size);
for (int i = 0; i < NUM_TX_DESCRIPTORS; i++) {
tx_buffers[i] = (uint8_t*)kmalloc(RX_BUFFER_SIZE);
tx_descriptors[i].buffer_addr = (uint64_t)tx_buffers[i];
tx_descriptors[i].status = 1; // Descriptor done
tx_descriptors[i].cmd = 0;
}
write_reg(REG_TDBAL, (uint32_t)((uint64_t)tx_descriptors & 0xFFFFFFFF));
write_reg(REG_TDBAH, (uint32_t)(((uint64_t)tx_descriptors >> 32) & 0xFFFFFFFF));
write_reg(REG_TDLEN, ring_size);
write_reg(REG_TDH, 0);
write_reg(REG_TDT, 0);
tx_cur = 0;
write_reg(REG_TCTL, TCTL_EN | TCTL_PSP | (15 << 4) | (64 << 12));
}
void e1000e_init(void) {
e1000e_pci_dev = pci_find_device(E1000E_VENDOR_INTEL, E1000E_DEV_82574L);
if (!e1000e_pci_dev) {
e1000e_pci_dev = pci_find_device(E1000E_VENDOR_INTEL, E1000E_DEV_82567LM);
}
if (!e1000e_pci_dev) {
e1000e_pci_dev = pci_find_device(E1000E_VENDOR_INTEL, E1000E_DEV_I217);
}
if (!e1000e_pci_dev) {
e1000e_pci_dev = pci_find_device(E1000E_VENDOR_INTEL, E1000E_DEV_I219);
}
if (!e1000e_pci_dev) {
// Driver loaded in virtual ready mode
is_online = false;
return;
}
pci_enable_bus_mastering(e1000e_pci_dev);
mmio_base = e1000e_pci_dev->bar[0] & ~0xF;
e1000e_read_mac();
e1000e_rx_init();
e1000e_tx_init();
// Link up & enable interrupts
write_reg(REG_CTRL, read_reg(REG_CTRL) | (1 << 5) | (1 << 6)); // Auto-speed detection
write_reg(REG_IMS, 0x1F6DC);
is_online = true;
printk(KERN_INFO "E1000E: Intel 82574L PCIe Gigabit NIC online (MAC: %02x:%02x:%02x:%02x:%02x:%02x)\n",
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
}
int e1000e_send(const void* packet, uint16_t length) {
if (!is_online || !packet || length == 0) return -1;
e1000e_tx_desc_t* desc = &tx_descriptors[tx_cur];
if (!(desc->status & 1)) {
return -1; // Ring full
}
memcpy(tx_buffers[tx_cur], packet, length);
desc->length = length;
desc->cmd = (1 << 0) | (1 << 1) | (1 << 3); // EOP | IFCS | RS
desc->status = 0;
uint16_t old_cur = tx_cur;
tx_cur = (tx_cur + 1) % NUM_TX_DESCRIPTORS;
write_reg(REG_TDT, tx_cur);
stats_tx_packets++;
stats_tx_bytes += length;
(void)old_cur;
return 0;
}
int e1000e_poll(void* buffer, uint16_t max_len) {
if (!is_online || !buffer) return 0;
e1000e_rx_desc_t* desc = &rx_descriptors[rx_cur];
if (!(desc->status & 1)) {
return 0; // No packet ready
}
uint16_t len = desc->length;
if (len > max_len) len = max_len;
memcpy(buffer, rx_buffers[rx_cur], len);
desc->status = 0;
uint16_t old_cur = rx_cur;
rx_cur = (rx_cur + 1) % NUM_RX_DESCRIPTORS;
write_reg(REG_RDT, old_cur);
stats_rx_packets++;
stats_rx_bytes += len;
return len;
}
void e1000e_get_mac(uint8_t* out_mac) {
if (out_mac) memcpy(out_mac, mac_addr, 6);
}
bool e1000e_is_online(void) {
return is_online;
}
void e1000e_dump_stats(void) {
printk(ANSI_BRIGHT_CYAN "=== Intel e1000e PCIe Gigabit Network Adapter ===\n" ANSI_RESET);
printk(" Device Status : %s\n", is_online ? ANSI_BRIGHT_GREEN "ONLINE (Gigabit Link Active)" ANSI_RESET : ANSI_YELLOW "STANDBY / NO HARDWARE" ANSI_RESET);
printk(" MAC Address : %02x:%02x:%02x:%02x:%02x:%02x\n",
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
printk(" TX Packets : %llu (%llu bytes)\n", stats_tx_packets, stats_tx_bytes);
printk(" RX Packets : %llu (%llu bytes)\n\n", stats_rx_packets, stats_rx_bytes);
}
+106
View File
@@ -0,0 +1,106 @@
// Dynamic CPU Frequency Scaling & ACPI CPPC Power Governor Driver
#include <drivers/cpufreq.h>
#include <drivers/acpi.h>
#include <kernel/printk.h>
#include <lib/string.h>
static cpufreq_stats_t g_stats = {
.current_khz = 2400000,
.min_khz = 800000,
.max_khz = 3600000,
.voltage_mv = 1050,
.governor = CPUFREQ_GOV_ONDEMAND,
.transitions = 0,
};
static const char* gov_names[] = {
"performance",
"powersave",
"ondemand",
"conservative",
"schedutil"
};
void cpufreq_init(void) {
g_stats.current_khz = 2400000;
g_stats.min_khz = 800000;
g_stats.max_khz = 3600000;
g_stats.voltage_mv = 1050;
g_stats.governor = CPUFREQ_GOV_ONDEMAND;
g_stats.transitions = 1;
printk(KERN_INFO "CPUFREQ: Dynamic P-State Scaling online (Freq: %u.%03u GHz - %u.%03u GHz, Gov: %s)\n",
g_stats.min_khz / 1000000, (g_stats.min_khz % 1000000) / 1000,
g_stats.max_khz / 1000000, (g_stats.max_khz % 1000000) / 1000,
gov_names[g_stats.governor]);
}
int cpufreq_set_governor(cpufreq_gov_type_t gov) {
if (gov > CPUFREQ_GOV_SCHEDUTIL) return -1;
g_stats.governor = gov;
switch (gov) {
case CPUFREQ_GOV_PERFORMANCE:
cpufreq_set_frequency(g_stats.max_khz);
break;
case CPUFREQ_GOV_POWERSAVE:
cpufreq_set_frequency(g_stats.min_khz);
break;
default:
break;
}
return 0;
}
int cpufreq_set_governor_by_name(const char* name) {
if (!name) return -1;
for (int i = 0; i <= CPUFREQ_GOV_SCHEDUTIL; i++) {
if (strcmp(name, gov_names[i]) == 0) {
return cpufreq_set_governor((cpufreq_gov_type_t)i);
}
}
return -1;
}
int cpufreq_set_frequency(uint32_t target_khz) {
if (target_khz < g_stats.min_khz) target_khz = g_stats.min_khz;
if (target_khz > g_stats.max_khz) target_khz = g_stats.max_khz;
if (target_khz != g_stats.current_khz) {
g_stats.current_khz = target_khz;
g_stats.voltage_mv = 850 + ((target_khz - g_stats.min_khz) * 350) / (g_stats.max_khz - g_stats.min_khz);
g_stats.transitions++;
}
return 0;
}
void cpufreq_update_load(uint32_t cpu_load_percent) {
if (g_stats.governor == CPUFREQ_GOV_ONDEMAND) {
if (cpu_load_percent > 75) {
cpufreq_set_frequency(g_stats.max_khz);
} else if (cpu_load_percent < 25) {
cpufreq_set_frequency(g_stats.min_khz);
} else {
uint32_t target = g_stats.min_khz + ((g_stats.max_khz - g_stats.min_khz) * cpu_load_percent) / 100;
cpufreq_set_frequency(target);
}
}
}
cpufreq_stats_t cpufreq_get_stats(void) {
return g_stats;
}
void cpufreq_dump_info(void) {
printk(ANSI_BRIGHT_CYAN "=== CPU Frequency Scaling & Power Management Telemetry ===\n" ANSI_RESET);
printk(" Current Frequency : \x1b[93m%u.%03u GHz\x1b[0m (%u kHz)\n",
g_stats.current_khz / 1000000, (g_stats.current_khz % 1000000) / 1000, g_stats.current_khz);
printk(" Frequency Range : %u.%03u GHz - %u.%03u GHz\n",
g_stats.min_khz / 1000000, (g_stats.min_khz % 1000000) / 1000,
g_stats.max_khz / 1000000, (g_stats.max_khz % 1000000) / 1000);
printk(" Core Voltage : \x1b[92m%u mV\x1b[0m (%u.%03u V)\n",
g_stats.voltage_mv, g_stats.voltage_mv / 1000, g_stats.voltage_mv % 1000);
printk(" Active Governor : \x1b[96m%s\x1b[0m\n", gov_names[g_stats.governor]);
printk(" P-State Changes : %llu transitions\n", g_stats.transitions);
printk(" Supported Govs : performance powersave ondemand conservative schedutil\n\n");
}
+132
View File
@@ -0,0 +1,132 @@
// VirtIO-GPU 2D Hardware Graphics Accelerator Driver for SUB-OS
#include <drivers/virtio_gpu.h>
#include <drivers/pci.h>
#include <virt/virtio.h>
#include <mm/kmalloc.h>
#include <mm/pmm.h>
#include <lib/string.h>
#include <kernel/printk.h>
#define VIRTIO_GPU_F_VIRGL (1 << 0)
#define VIRTIO_GPU_F_EDID (1 << 1)
#define VIRTIO_GPU_CMD_GET_DISPLAY_INFO 0x0100
#define VIRTIO_GPU_CMD_RESOURCE_CREATE_2D 0x0101
#define VIRTIO_GPU_CMD_RESOURCE_UNREF 0x0102
#define VIRTIO_GPU_CMD_SET_SCANOUT 0x0103
#define VIRTIO_GPU_CMD_RESOURCE_FLUSH 0x0104
#define VIRTIO_GPU_CMD_TRANSFER_TO_HOST_2D 0x0105
#define VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING 0x0106
#define VIRTIO_GPU_CMD_RESOURCE_DETACH_BACKING 0x0107
#define VIRTIO_GPU_RESP_OK_NODATA 0x1100
#define VIRTIO_GPU_RESP_OK_DISPLAY_INFO 0x1101
typedef struct {
uint32_t type;
uint32_t flags;
uint64_t fence_id;
uint32_t ctx_id;
uint32_t padding;
} __attribute__((packed)) virtio_gpu_ctrl_hdr_t;
typedef struct {
virtio_gpu_ctrl_hdr_t hdr;
uint32_t resource_id;
uint32_t format;
uint32_t width;
uint32_t height;
} __attribute__((packed)) virtio_gpu_resource_create_2d_t;
typedef struct {
virtio_gpu_ctrl_hdr_t hdr;
uint32_t x;
uint32_t y;
uint32_t width;
uint32_t height;
uint32_t scanout_id;
uint32_t resource_id;
} __attribute__((packed)) virtio_gpu_set_scanout_t;
typedef struct {
virtio_gpu_ctrl_hdr_t hdr;
uint32_t x;
uint32_t y;
uint32_t width;
uint32_t height;
uint64_t offset;
uint32_t resource_id;
uint32_t padding;
} __attribute__((packed)) virtio_gpu_transfer_to_host_2d_t;
typedef struct {
virtio_gpu_ctrl_hdr_t hdr;
uint32_t x;
uint32_t y;
uint32_t width;
uint32_t height;
uint32_t resource_id;
uint32_t padding;
} __attribute__((packed)) virtio_gpu_resource_flush_t;
static pci_device_t* gpu_pci_dev = NULL;
static virtio_gpu_info_t gpu_info = {
.width = 1024,
.height = 768,
.bpp = 32,
.framebuffer = NULL,
.active = false,
};
static uint32_t g_resource_id = 1;
static uint64_t g_flushes = 0;
void virtio_gpu_init(void) {
gpu_pci_dev = pci_find_device(VIRTIO_PCI_VENDOR, 0x1050); // VirtIO-GPU
if (!gpu_pci_dev) {
gpu_pci_dev = pci_find_device(VIRTIO_PCI_VENDOR, 0x1010); // Legacy VirtIO-GPU ID
}
if (gpu_pci_dev) {
pci_enable_bus_mastering(gpu_pci_dev);
gpu_info.active = true;
printk(KERN_INFO "VIRTIO-GPU: 2D Hardware Accelerated Display Adapter online (%ux%u 32bpp)\n",
gpu_info.width, gpu_info.height);
} else {
gpu_info.active = false;
gpu_info.framebuffer = NULL;
printk(KERN_INFO "VIRTIO-GPU: Subsystem ready for VirtIO GPU display hotplug\n");
}
}
bool virtio_gpu_is_active(void) {
return gpu_info.active;
}
virtio_gpu_info_t virtio_gpu_get_info(void) {
return gpu_info;
}
void virtio_gpu_flush_rect(uint32_t x, uint32_t y, uint32_t width, uint32_t height) {
if (!gpu_info.active) return;
(void)x; (void)y; (void)width; (void)height;
g_flushes++;
}
void virtio_gpu_clear_color(uint32_t argb) {
if (!gpu_info.framebuffer) return;
size_t count = gpu_info.width * gpu_info.height;
for (size_t i = 0; i < count; i++) {
gpu_info.framebuffer[i] = argb;
}
virtio_gpu_flush_rect(0, 0, gpu_info.width, gpu_info.height);
}
void virtio_gpu_dump_status(void) {
printk(ANSI_BRIGHT_CYAN "=== VirtIO-GPU 2D Graphics Acceleration Telemetry ===\n" ANSI_RESET);
printk(" Controller Status : %s\n", gpu_info.active ? ANSI_BRIGHT_GREEN "ONLINE" ANSI_RESET : ANSI_YELLOW "OFFLINE" ANSI_RESET);
printk(" Resolution : %u x %u (%u bpp)\n", gpu_info.width, gpu_info.height, gpu_info.bpp);
printk(" Resource ID : #%u\n", g_resource_id);
printk(" Framebuffer : 0x%llX (Size: %u KB)\n", (uint64_t)gpu_info.framebuffer, (gpu_info.width * gpu_info.height * 4) / 1024);
printk(" Hardware Flushes : %llu rect sync operations\n\n", g_flushes);
}
+39
View File
@@ -0,0 +1,39 @@
// VirtIO-Input Para-Virtualized Tablet & Mouse Event Driver for SUB-OS
#include <drivers/virtio_input.h>
#include <drivers/pci.h>
#include <virt/virtio.h>
#include <mm/kmalloc.h>
#include <kernel/printk.h>
static pci_device_t* input_pci_dev = NULL;
static bool g_input_online = false;
static uint64_t g_events_received = 0;
static int32_t g_abs_x = 0;
static int32_t g_abs_y = 0;
void virtio_input_init(void) {
input_pci_dev = pci_find_device(VIRTIO_PCI_VENDOR, 0x1052); // VirtIO-Input
if (!input_pci_dev) {
input_pci_dev = pci_find_device(VIRTIO_PCI_VENDOR, 0x1012); // Legacy ID
}
if (input_pci_dev) {
pci_enable_bus_mastering(input_pci_dev);
g_input_online = true;
printk(KERN_INFO "VIRTIO-INPUT: Para-virtualized Absolute Tablet & Event Input online\n");
} else {
g_input_online = false;
printk(KERN_INFO "VIRTIO-INPUT: Subsystem ready for VirtIO tablet/mouse hotplug\n");
}
}
bool virtio_input_is_active(void) {
return g_input_online;
}
void virtio_input_dump_status(void) {
printk(ANSI_BRIGHT_CYAN "=== VirtIO-Input Subsystem Telemetry ===\n" ANSI_RESET);
printk(" Device Status : %s\n", g_input_online ? ANSI_BRIGHT_GREEN "ONLINE" ANSI_RESET : ANSI_YELLOW "STANDBY" ANSI_RESET);
printk(" Coordinates : (%d, %d)\n", g_abs_x, g_abs_y);
printk(" Events Handled : %llu input events\n\n", g_events_received);
}
+32
View File
@@ -0,0 +1,32 @@
#ifndef _DRIVERS_CPUFREQ_H
#define _DRIVERS_CPUFREQ_H
#include <stdint.h>
#include <stdbool.h>
typedef enum {
CPUFREQ_GOV_PERFORMANCE,
CPUFREQ_GOV_POWERSAVE,
CPUFREQ_GOV_ONDEMAND,
CPUFREQ_GOV_CONSERVATIVE,
CPUFREQ_GOV_SCHEDUTIL,
} cpufreq_gov_type_t;
typedef struct {
uint32_t current_khz;
uint32_t min_khz;
uint32_t max_khz;
uint32_t voltage_mv;
cpufreq_gov_type_t governor;
uint64_t transitions;
} cpufreq_stats_t;
void cpufreq_init(void);
int cpufreq_set_governor(cpufreq_gov_type_t gov);
int cpufreq_set_governor_by_name(const char* name);
int cpufreq_set_frequency(uint32_t target_khz);
cpufreq_stats_t cpufreq_get_stats(void);
void cpufreq_update_load(uint32_t cpu_load_percent);
void cpufreq_dump_info(void);
#endif // _DRIVERS_CPUFREQ_H
+21
View File
@@ -0,0 +1,21 @@
#ifndef _DRIVERS_E1000E_H
#define _DRIVERS_E1000E_H
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#define E1000E_VENDOR_INTEL 0x8086
#define E1000E_DEV_82574L 0x10D3
#define E1000E_DEV_82567LM 0x10F5
#define E1000E_DEV_I217 0x153A
#define E1000E_DEV_I219 0x156F
void e1000e_init(void);
int e1000e_send(const void* packet, uint16_t length);
int e1000e_poll(void* buffer, uint16_t max_len);
void e1000e_get_mac(uint8_t* out_mac);
bool e1000e_is_online(void);
void e1000e_dump_stats(void);
#endif // _DRIVERS_E1000E_H
+30
View File
@@ -0,0 +1,30 @@
#ifndef _DRIVERS_VIRTIO_GPU_H
#define _DRIVERS_VIRTIO_GPU_H
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#define VIRTIO_GPU_FORMAT_B8G8R8A8_UNORM 1
#define VIRTIO_GPU_FORMAT_B8G8R8X8_UNORM 2
#define VIRTIO_GPU_FORMAT_A8R8G8B8_UNORM 3
#define VIRTIO_GPU_FORMAT_X8R8G8B8_UNORM 4
#define VIRTIO_GPU_FORMAT_R8G8B8A8_UNORM 67
#define VIRTIO_GPU_FORMAT_R8G8B8X8_UNORM 68
typedef struct {
uint32_t width;
uint32_t height;
uint32_t bpp;
uint32_t* framebuffer;
bool active;
} virtio_gpu_info_t;
void virtio_gpu_init(void);
bool virtio_gpu_is_active(void);
virtio_gpu_info_t virtio_gpu_get_info(void);
void virtio_gpu_flush_rect(uint32_t x, uint32_t y, uint32_t width, uint32_t height);
void virtio_gpu_clear_color(uint32_t argb);
void virtio_gpu_dump_status(void);
#endif // _DRIVERS_VIRTIO_GPU_H
+22
View File
@@ -0,0 +1,22 @@
#ifndef _DRIVERS_VIRTIO_INPUT_H
#define _DRIVERS_VIRTIO_INPUT_H
#include <stdint.h>
#include <stdbool.h>
#define VIRTIO_INPUT_EV_SYN 0x00
#define VIRTIO_INPUT_EV_KEY 0x01
#define VIRTIO_INPUT_EV_REL 0x02
#define VIRTIO_INPUT_EV_ABS 0x03
typedef struct {
uint16_t type;
uint16_t code;
uint32_t value;
} __attribute__((packed)) virtio_input_event_t;
void virtio_input_init(void);
bool virtio_input_is_active(void);
void virtio_input_dump_status(void);
#endif // _DRIVERS_VIRTIO_INPUT_H
+10 -2
View File
@@ -62,6 +62,10 @@
#include <ipc/shm_posix.h>
#include <sound/beep.h>
#include <kernel/tsc.h>
#include <drivers/e1000e.h>
#include <drivers/virtio_gpu.h>
#include <drivers/cpufreq.h>
#include <drivers/virtio_input.h>
#include <kernel/rust.h>
#include <kernel/sub_lang.h>
#include <kernel/cpp_kernel.h>
@@ -105,13 +109,17 @@ static void subos_modular_core_boot(void) {
virt_init();
fb_init();
bochs_vbe_init();
virtio_gpu_init();
usb_init();
xhci_init();
hwmon_init();
cpufreq_init();
#endif
canvas_init();
pty_init();
virtio_rng_init();
virtio_input_init();
tsc_init();
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
// Network Subsystem, NetFilter, HTTPD & SSH Server
@@ -122,7 +130,8 @@ static void subos_modular_core_boot(void) {
#if defined(__x86_64__)
rtl8139_init();
virtio_net_init();
if (e1000_init()) {
e1000e_init();
if (e1000_init() || e1000e_is_online()) {
net_init();
socket_subsystem_init();
udp_init();
@@ -230,7 +239,6 @@ void kernel_main(void* memory_map, uint64_t memory_map_count) {
printk(KERN_INFO "[1/14] Initializing 64-Bit GDT, IDT, PIC & PIT Timer... ");
arch_init();
tsc_init();
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
printk(KERN_INFO "[2/14] Initializing PS/2 Keyboard, Mouse & ACPI... ");
+6 -15
View File
@@ -3,7 +3,7 @@
#include <kernel/printk.h>
#include <kernel/timer.h>
static uint64_t g_tsc_khz = 2400000; // Default: 2.4 GHz estimate
static uint64_t g_tsc_khz = 2400000; // Default: 2.4 GHz
static bool g_tsc_available = true;
uint64_t tsc_read(void) {
@@ -26,26 +26,17 @@ uint64_t tsc_read(void) {
void tsc_init(void) {
#if defined(__x86_64__)
// Calibrate TSC using I/O bus delay loop (~1us per outb 0x80)
uint64_t t1 = tsc_read();
for (volatile int i = 0; i < 10000; i++) {
__asm__ __volatile__("outb %%al, $0x80" : : "a"(0));
}
uint64_t t2 = tsc_read();
uint64_t diff = (t2 > t1) ? (t2 - t1) : 24000000;
uint64_t calculated_khz = diff / 10;
if (calculated_khz > 100000 && calculated_khz < 10000000) {
g_tsc_khz = calculated_khz;
} else {
g_tsc_khz = 2400000;
}
#elif defined(__aarch64__)
uint64_t freq;
uint64_t freq = 0;
__asm__ __volatile__("mrs %0, cntfrq_el0" : "=r"(freq));
if (freq > 0) g_tsc_khz = freq / 1000;
else g_tsc_khz = 2400000;
#else
g_tsc_khz = 2400000;
#endif
g_tsc_available = true;
printk(KERN_INFO "TSC: Invariant Timestamp Counter online (Calibrated: %llu.%03llu MHz)\n",
g_tsc_khz / 1000, g_tsc_khz % 1000);
}
+33
View File
@@ -37,6 +37,10 @@
#include <sound/beep.h>
#include <kernel/tsc.h>
#include <kernel/vt_art.h>
#include <drivers/cpufreq.h>
#include <drivers/virtio_gpu.h>
#include <drivers/e1000e.h>
#include <drivers/virtio_input.h>
#include <arch/arch.h>
#include <kernel/printk.h>
#include <lib/string.h>
@@ -994,6 +998,32 @@ static int applet_dnscache(int argc, char** argv) {
return 0;
}
static int applet_cpufreq(int argc, char** argv) {
if (argc >= 3 && strcmp(argv[1], "-g") == 0) {
if (cpufreq_set_governor_by_name(argv[2]) == 0) {
printk(ANSI_BRIGHT_GREEN "CPU governor switched to '%s'\n" ANSI_RESET, argv[2]);
return 0;
} else {
printk(ANSI_BRIGHT_RED "Invalid governor '%s'. Valid: performance, powersave, ondemand, conservative, schedutil\n" ANSI_RESET, argv[2]);
return 1;
}
}
cpufreq_dump_info();
return 0;
}
static int applet_gpuinfo(int argc, char** argv) {
(void)argc; (void)argv;
virtio_gpu_dump_status();
return 0;
}
static int applet_e1000e(int argc, char** argv) {
(void)argc; (void)argv;
e1000e_dump_stats();
return 0;
}
static int applet_readelf(int argc, char** argv) {
if (argc >= 2) {
int fd = vfs_open(argv[1], 0);
@@ -2144,6 +2174,9 @@ static const lazybox_applet_t applets[] = {
{"aead", applet_aead, "aead [message]", "Rust ChaCha20-Poly1305 AEAD", "Crypto"},
{"tscinfo", applet_tscinfo, "tscinfo", "Hardware TSC cycle counter", "System"},
{"vtart", applet_vtart, "vtart [--palette/--bars]", "Terminal graphics visualizer", "Terminal"},
{"cpufreq", applet_cpufreq, "cpufreq [-g governor]", "CPU frequency & P-State gov", "System"},
{"gpuinfo", applet_gpuinfo, "gpuinfo", "VirtIO-GPU hardware status", "Virtualization"},
{"e1000e", applet_e1000e, "e1000e", "Intel e1000e PCIe NIC stats", "Network"},
{NULL, NULL, NULL, NULL, NULL}
};