feat: Phase 1 网络端到端打通 + FirstInit/Login/DevMode 完善

- 用户态共享网络协议栈 CODE/tools/net_stack.h(eth/ARP/IPv4/ICMP/UDP-DNS/TCP static inline,轮询模型)
- shell 内建 ping/curl/run 命令;ping.elf/curl.elf 对齐 net_stack.h 真实协议栈
- shell dev_mode 串口镜像(g_serial_mirror)便于自动化验证
- DSK 启动流程:firstInit.txt 双行格式(firstInit + dev_mode),dev_mode=1 触发 shell 自动回归测试
- FirstInit 完成→持久化 USER.CONF + 翻转 firstInit 0->1(保留 dev_mode)
- firstInit=1 时 DSK 加载 login.elf 进行用户选择 + 密码校验后再进 desktop
- 新增 CODE/login/ 登录应用、CODE/DKM/dkm_shared.h、Logo.png
- ahci/e1000/virtio_net/fat32/console_fb 驱动更新;utsm serial/block/dsk_loader 调整
- build.ps1 打包 ping.elf/curl.elf 进 SATA FAT32 根目录
- 移除 CODE/tools/bash(与 shell.elf 重复)
This commit is contained in:
xyou
2026-07-26 21:07:36 +08:00
parent 48dcb5568e
commit efa626ed17
83 changed files with 4993 additions and 1785 deletions
+110 -138
View File
@@ -4,100 +4,7 @@
* and ports so later block I/O can be added safely.
*/
#include <stdint.h>
#define DKM_DRIVER_MAGIC 0x444B4D31u
#define DKM_ABI_VERSION 1u
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long long u64;
typedef long long i64;
#define NULL ((void *)0)
struct dkm_log_api {
void (*info)(const char *msg);
void (*warn)(const char *msg);
void (*error)(const char *msg);
void (*panic)(const char *msg);
};
struct dkm_dma_buffer {
void *virt;
u64 phys;
u64 size;
};
struct dkm_dma_api {
int (*alloc_pages)(u64 page_count, u64 alignment, u64 max_phys, struct dkm_dma_buffer *out);
};
struct dkm_block_device_desc {
const char *name;
u64 sector_size;
u64 sector_count;
void *ctx;
int (*read)(void *ctx, u64 lba, u32 count, void *buffer);
};
struct dkm_block_api {
int (*register_device)(const struct dkm_block_device_desc *desc);
u32 (*device_count)(void);
int (*read)(u32 index, u64 lba, u32 count, void *buffer);
u64 (*sector_size)(u32 index);
const char *(*device_name)(u32 index);
};
struct dkm_kernel_api {
u32 version;
u32 size;
u64 feature_bits;
const struct dkm_log_api *log;
const void *mem;
const void *utsm;
const void *irq;
const void *pci;
const struct dkm_dma_api *dma;
const void *vfs;
const void *net;
const void *timer;
const void *drr;
const void *rsdp_address;
const void *fb_address;
u64 fb_width;
u64 fb_height;
u64 fb_pitch;
u16 fb_bpp;
const void *boot_modules_response;
int (*irq_register)(u8 irq, void *handler);
u64 hhdm_offset;
const struct dkm_block_api *block;
};
struct dkm_driver_handle;
struct dkm_driver_desc {
u32 magic;
u16 abi_version;
u16 desc_size;
const char *name;
const char *version;
const char *vendor;
u32 driver_class;
u32 stage;
u32 flags;
u32 priority;
const char *const *depends;
u32 depends_count;
const char *const *provides;
u32 provides_count;
u64 min_kernel_abi;
u64 feature_bits;
u64 reserved0;
u64 reserved1;
};
#include "../dkm_shared.h"
static const char *const g_depends[] = { "pci", "irq" };
static const char *const g_provides[] = { "block" };
@@ -124,21 +31,6 @@ const struct dkm_driver_desc driver_desc = {
.reserved1 = 0
};
#define PCI_ADDR 0xCF8
#define PCI_DATA 0xCFC
#define PCI_VENDOR_ID 0x00
#define PCI_COMMAND 0x04
#define PCI_PROG_IF 0x09
#define PCI_SUBCLASS 0x0A
#define PCI_CLASS 0x0B
#define PCI_HEADER 0x0E
#define PCI_BAR5 0x24
#define PCI_IRQ_LINE 0x3C
#define PCI_CMD_IO (1u << 0)
#define PCI_CMD_MEM (1u << 1)
#define PCI_CMD_BUSM (1u << 2)
#define AHCI_CLASS_STORAGE 0x01
#define AHCI_SUBCLASS_SATA 0x06
#define AHCI_PROGIF_AHCI 0x01
@@ -170,12 +62,15 @@ const struct dkm_driver_desc driver_desc = {
#define AHCI_CMD_ST (1u << 0)
#define AHCI_CMD_FRE (1u << 4)
#define AHCI_CMD_W (1u << 6)
#define AHCI_CMD_FR (1u << 14)
#define AHCI_CMD_CR (1u << 15)
#define AHCI_CMD_ICC_ACTIVE (1u << 28)
#define ATA_CMD_IDENTIFY 0xEC
#define ATA_CMD_IDENTIFY_PACKET 0xA1
#define ATA_CMD_READ_DMA_EXT 0x25
#define ATA_CMD_WRITE_DMA_EXT 0x35
typedef struct __attribute__((packed)) ahci_cmd_header {
u16 flags;
@@ -207,34 +102,12 @@ static ahci_cmd_header *g_cmd_header;
static struct dkm_dma_buffer g_cmd_table;
static struct dkm_dma_buffer g_data;
static __inline__ void outl(u16 port, u32 value) {
__asm__ volatile ("outl %0, %1" :: "a"(value), "Nd"(port));
}
static __inline__ u32 inl(u16 port) {
u32 value;
__asm__ volatile ("inl %1, %0" : "=a"(value) : "Nd"(port));
return value;
}
static u32 pci_read(u8 bus, u8 dev, u8 func, u8 reg) {
u32 addr = (1u << 31)
| ((u32)bus << 16)
| ((u32)dev << 11)
| ((u32)func << 8)
| ((u32)reg & 0xFC);
outl(PCI_ADDR, addr);
return inl(PCI_DATA);
return dkm_pci_read(bus, dev, func, reg);
}
static void pci_write(u8 bus, u8 dev, u8 func, u8 reg, u32 value) {
u32 addr = (1u << 31)
| ((u32)bus << 16)
| ((u32)dev << 11)
| ((u32)func << 8)
| ((u32)reg & 0xFC);
outl(PCI_ADDR, addr);
outl(PCI_DATA, value);
dkm_pci_write(bus, dev, func, reg, value);
}
static void log_hex(const char *prefix, u64 value) {
@@ -333,15 +206,21 @@ static int ahci_stop_port(u32 port) {
u32 cmd = g_abar[(base + PxCMD) / 4];
cmd &= ~AHCI_CMD_ST;
g_abar[(base + PxCMD) / 4] = cmd;
for (u32 i = 0; i < 100000; i++) {
/* 实机: 500ms TSC 超时等待 CR 清除 */
u64 deadline = dkm_rdtsc() + dkm_tsc_per_ms * 500;
while (dkm_rdtsc() < deadline) {
cmd = g_abar[(base + PxCMD) / 4];
if (!(cmd & AHCI_CMD_CR)) break;
__asm__ volatile("pause");
}
cmd &= ~AHCI_CMD_FRE;
g_abar[(base + PxCMD) / 4] = cmd;
for (u32 i = 0; i < 100000; i++) {
/* 实机: 500ms TSC 超时等待 FR 清除 */
deadline = dkm_rdtsc() + dkm_tsc_per_ms * 500;
while (dkm_rdtsc() < deadline) {
cmd = g_abar[(base + PxCMD) / 4];
if (!(cmd & AHCI_CMD_FR)) return 0;
__asm__ volatile("pause");
}
return -1;
}
@@ -368,7 +247,23 @@ static void ahci_fill_read_fis(u8 *fis, u64 lba, u32 count) {
ahci_zero(fis, 64);
fis[0] = 0x27;
fis[1] = 1u << 7;
fis[2] = 0x25; /* READ DMA EXT */
fis[2] = ATA_CMD_READ_DMA_EXT;
fis[4] = (u8)(lba & 0xff);
fis[5] = (u8)((lba >> 8) & 0xff);
fis[6] = (u8)((lba >> 16) & 0xff);
fis[7] = (1u << 6) | (u8)((lba >> 24) & 0x0f);
fis[8] = (u8)((lba >> 24) & 0xff);
fis[9] = (u8)((lba >> 32) & 0xff);
fis[10] = (u8)((lba >> 40) & 0xff);
fis[12] = (u8)(count & 0xff);
fis[13] = (u8)((count >> 8) & 0xff);
}
static void ahci_fill_write_fis(u8 *fis, u64 lba, u32 count) {
ahci_zero(fis, 64);
fis[0] = 0x27;
fis[1] = 1u << 7;
fis[2] = ATA_CMD_WRITE_DMA_EXT;
fis[4] = (u8)(lba & 0xff);
fis[5] = (u8)((lba >> 8) & 0xff);
fis[6] = (u8)((lba >> 16) & 0xff);
@@ -420,7 +315,81 @@ static int ahci_read_blocks_internal(u32 port, ahci_cmd_header *hdr, struct dkm_
return -3;
}
static int ahci_write_blocks_internal(u32 port, ahci_cmd_header *hdr, struct dkm_dma_buffer *table, struct dkm_dma_buffer *data, u64 lba, u32 count, const void *buffer) {
if (!buffer || count == 0) return -1;
if (count > 8) return -2;
u32 base = HBA_PORT_BASE + port * HBA_PORT_SIZE;
ahci_cmd_table *tbl = (ahci_cmd_table *)table->virt;
u32 bytes = count * 512;
ahci_zero(tbl, sizeof(ahci_cmd_table));
/* copy data from user buffer into DMA buffer */
{
u8 *dst = (u8 *)data->virt;
const u8 *src = (const u8 *)buffer;
for (u32 j = 0; j < bytes; j++) dst[j] = src[j];
}
hdr[0].flags = 5 | (1u << 6); /* CFL=5, W=1 (write) */
hdr[0].prdtl = 1;
hdr[0].prdbc = 0;
hdr[0].ctba = (u32)(table->phys & 0xffffffffu);
hdr[0].ctbau = (u32)(table->phys >> 32);
tbl->prdt[0].dba = (u32)(data->phys & 0xffffffffu);
tbl->prdt[0].dbau = (u32)(data->phys >> 32);
tbl->prdt[0].dbc_i = (bytes - 1) | (1u << 31);
ahci_fill_write_fis(tbl->cfis, lba, count);
/* set PxCMD.W to indicate write direction */
u32 cmd = g_abar[(base + PxCMD) / 4];
cmd |= AHCI_CMD_W;
g_abar[(base + PxCMD) / 4] = cmd;
g_abar[(base + PxIS) / 4] = 0xffffffffu;
g_abar[HBA_IS / 4] = (1u << port);
g_abar[(base + PxCI) / 4] = 1;
for (u32 i = 0; i < 5000000; i++) {
if ((g_abar[(base + PxCI) / 4] & 1u) == 0) {
/* clear PxCMD.W after write completes */
cmd = g_abar[(base + PxCMD) / 4];
cmd &= ~AHCI_CMD_W;
g_abar[(base + PxCMD) / 4] = cmd;
return 0;
}
}
/* timeout: clear PxCMD.W */
cmd = g_abar[(base + PxCMD) / 4];
cmd &= ~AHCI_CMD_W;
g_abar[(base + PxCMD) / 4] = cmd;
g_log->warn("[ahci] WRITE timeout");
log_hex("[ahci] WRITE lba=", lba);
log_hex("[ahci] WRITE count=", count);
log_hex("[ahci] WRITE CI=", g_abar[(base + PxCI) / 4]);
log_hex("[ahci] WRITE IS=", g_abar[(base + PxIS) / 4]);
log_hex("[ahci] WRITE TFD=", g_abar[(base + PxTFD) / 4]);
return -3;
}
static int ahci_block_read(void *ctx, u64 lba, u32 count, void *buffer) {
(void)ctx;
if (g_ready_port == 0xffffffffu || !g_cmd_header) return -1;
log_hex("[ahci] block_read lba=", lba);
log_hex("[ahci] block_read count=", count);
while (count > 0) {
u32 chunk = count > 8 ? 8 : count;
int status = ahci_read_blocks_internal(g_ready_port, g_cmd_header, &g_cmd_table, &g_data, lba, chunk, buffer);
if (status != 0) return status;
lba += chunk;
count -= chunk;
buffer = (void *)((u8 *)buffer + (chunk * 512));
}
return 0;
}
static int ahci_block_write(void *ctx, u64 lba, u32 count, const void *buffer) {
(void)ctx;
if (g_ready_port == 0xffffffffu || !g_cmd_header) return -1;
/* ensure port is in ST+FRE state */
@@ -433,11 +402,11 @@ static int ahci_block_read(void *ctx, u64 lba, u32 count, void *buffer) {
}
while (count > 0) {
u32 chunk = count > 8 ? 8 : count;
int status = ahci_read_blocks_internal(g_ready_port, g_cmd_header, &g_cmd_table, &g_data, lba, chunk, buffer);
int status = ahci_write_blocks_internal(g_ready_port, g_cmd_header, &g_cmd_table, &g_data, lba, chunk, buffer);
if (status != 0) return status;
lba += chunk;
count -= chunk;
buffer = (void *)((u8 *)buffer + (chunk * 512));
buffer = (const void *)((const u8 *)buffer + (chunk * 512));
}
return 0;
}
@@ -536,6 +505,8 @@ __attribute__((visibility("default")))
int driver_init(const struct dkm_kernel_api *api,
struct dkm_driver_handle *handle) {
(void)handle;
/* 实机要求: 先校准 TSC, 再使用基于 CPU 频率的延迟 */
dkm_tsc_calibrate();
if (!api || !api->log) return -1;
g_log = api->log;
@@ -628,6 +599,7 @@ int driver_init(const struct dkm_kernel_api *api,
desc.sector_count = 0;
desc.ctx = 0;
desc.read = ahci_block_read;
desc.write = ahci_block_write;
int index = api->block->register_device(&desc);
log_hex("[ahci] block provider index=", (u64)(i64)index);
} else if (identified) {
+38 -151
View File
@@ -17,105 +17,7 @@
* 部分高级特性(ANI/MRR/AGC 调优)留待硬件验证后增量完善。
*/
#include <stdint.h>
#define DKM_DRIVER_MAGIC 0x444B4D31u
#define DKM_ABI_VERSION 1u
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long long u64;
typedef long long i64;
typedef signed char i8;
#define NULL ((void *)0)
/* ---- DKM ABI ---- */
struct dkm_log_api {
void (*info)(const char *msg);
void (*warn)(const char *msg);
void (*error)(const char *msg);
void (*panic)(const char *msg);
};
struct dkm_net_scan_result {
char ssid[33];
u8 bssid[6];
u8 channel;
i8 rssi;
u8 security;
};
struct dkm_net_device_desc {
const char *name;
u8 mac[6];
u32 flags;
void *ctx;
int (*tx)(void *ctx, const void *packet, u32 length);
int (*rx_poll)(void *ctx, void *buffer, u32 capacity, u32 *out_length);
int (*scan_start)(void *ctx);
int (*scan_count)(void *ctx);
int (*scan_result)(void *ctx, u32 n, struct dkm_net_scan_result *out);
int (*is_wireless)(void *ctx);
};
struct dkm_net_api {
int (*register_device)(const struct dkm_net_device_desc *desc);
u32 (*device_count)(void);
int (*device_info)(u32 index, void *out);
int (*tx)(u32 index, const void *packet, u32 length);
int (*rx_poll)(u32 index, void *buffer, u32 capacity, u32 *out_length);
int (*scan_start)(u32 index);
int (*scan_count)(u32 index);
int (*scan_result)(u32 index, u32 n, struct dkm_net_scan_result *out);
int (*is_wireless)(u32 index);
};
struct dkm_dma_buffer {
void *virt;
u64 phys;
u64 size;
};
struct dkm_dma_api {
int (*alloc_pages)(u64 page_count, u64 alignment, u64 max_phys, struct dkm_dma_buffer *out);
};
#define DKM_NET_F_LINK_UP (1u << 0)
#define DKM_NET_F_TX_READY (1u << 1)
#define DKM_NET_F_RX_READY (1u << 2)
#define DKM_NET_F_WIRELESS (1u << 3)
#define DKM_NET_SEC_OPEN 0u
#define DKM_NET_SEC_WEP 1u
#define DKM_NET_SEC_WPA 2u
#define DKM_NET_SEC_WPA2 3u
#define DKM_NET_SEC_WPA3 4u
struct dkm_kernel_api {
u32 version; u32 size; u64 feature_bits;
const struct dkm_log_api *log;
const void *mem,*utsm,*irq_api,*pci_api;
const struct dkm_dma_api *dma;
const void *vfs_api;
const struct dkm_net_api *net;
const void *timer,*drr;
const void *rsdp_address,*fb_address;
u64 fb_width,fb_height,fb_pitch; u16 fb_bpp;
const void *boot_modules_response;
int (*irq_register)(u8 irq, void *handler);
u64 hhdm_offset;
};
struct dkm_driver_handle;
struct dkm_driver_desc {
u32 magic; u16 abi_version; u16 desc_size;
const char *name,*version,*vendor;
u32 driver_class,stage,flags,priority;
const char *const *depends; u32 depends_count;
const char *const *provides; u32 provides_count;
u64 min_kernel_abi,feature_bits,reserved0,reserved1;
};
#include "../dkm_shared.h"
static const char *const g_depends[] = {"pci","irq"};
static const char *const g_provides[] = {"netdev"};
@@ -129,19 +31,6 @@ const struct dkm_driver_desc driver_desc = {
.provides=g_provides,.provides_count=1,.min_kernel_abi=1,
};
/* ---- PCI config ---- */
#define PCI_ADDR 0xCF8
#define PCI_DATA 0xCFC
#define PCI_VENDOR_ID 0x00
#define PCI_COMMAND 0x04
#define PCI_BAR0 0x10
#define PCI_BAR1 0x14
#define PCI_IRQ_LINE 0x3C
#define PCI_CMD_IO (1u << 0)
#define PCI_CMD_MEM (1u << 1)
#define PCI_CMD_BUSMST (1u << 2)
/* ---- ath9k 寄存器(AR9280/9285/9287 PCIe MAC,Linux ath9k reg.h 关键子集) ---- */
#define AR_RC 0x4000u
#define AR_RC_MAC 0x00000001u
@@ -285,20 +174,20 @@ static u32 g_scan_count;
static int g_scanning;
/* ---- 串口日志(参考 e1000 raw_log) ---- */
static __inline__ void outb(u16 p, u8 v) { __asm__ volatile("outb %0,%1"::"a"(v),"Nd"(p):"memory"); }
static __inline__ u8 inb(u16 p) { u8 v; __asm__ volatile("inb %1,%0":"=a"(v):"Nd"(p):"memory"); return v; }
static __inline__ void outl(u16 p, u32 v) { __asm__ volatile("outl %0,%1"::"a"(v),"Nd"(p):"memory"); }
static __inline__ u32 inl(u16 p) { u32 v; __asm__ volatile("inl %1,%0":"=a"(v):"Nd"(p):"memory"); return v; }
#define COM1 0x3F8
/* 串口发送等待 thin wrapper — 调用 dkm 共享实现 */
static void serial_wait_tx(void) { dkm_serial_wait_tx(COM1); }
static void raw_log(const char *s) {
while (*s) {
char c = *s++;
if (c == '\n') {
for (u32 i=0;i<100000;i++) if (inb(0x3F8+5)&0x20) break;
outb(0x3F8, '\r');
serial_wait_tx();
dkm_outb(COM1, '\r');
}
for (u32 i=0;i<100000;i++) if (inb(0x3F8+5)&0x20) break;
outb(0x3F8, (u8)c);
serial_wait_tx();
dkm_outb(COM1, (u8)c);
}
}
@@ -307,26 +196,19 @@ static void raw_hex(const char *prefix, u64 v) {
raw_log(prefix);
raw_log("0x");
for (int i=15; i>=0; i--) {
for (u32 wait=0; wait<100000; wait++) if (inb(0x3F8+5)&0x20) break;
outb(0x3F8, (u8)h[(v >> (i * 4)) & 0xf]);
serial_wait_tx();
dkm_outb(COM1, (u8)h[(v >> (i * 4)) & 0xf]);
}
raw_log("\n");
}
static void delay_us(u32 us) {
/* 粗略延时:每个 iteration ~1us on QEMU x86 */
for (u32 i = 0; i < us * 10; i++) __asm__ volatile("pause");
}
/* ---- PCI 配置空间 ---- */
static u32 pci_read(u8 bus, u8 dev, u8 func, u8 reg) {
u32 a = (1u<<31)|((u32)bus<<16)|((u32)dev<<11)|((u32)func<<8)|((u32)reg&0xFC);
outl(PCI_ADDR,a); return inl(PCI_DATA);
return dkm_pci_read(bus, dev, func, reg);
}
static void pci_write(u8 bus, u8 dev, u8 func, u8 reg, u32 v) {
u32 a = (1u<<31)|((u32)bus<<16)|((u32)dev<<11)|((u32)func<<8)|((u32)reg&0xFC);
outl(PCI_ADDR,a); outl(PCI_DATA,v);
dkm_pci_write(bus, dev, func, reg, v);
}
/* ath9k PCI 设备 ID 表(vendor 0x168c Atheros) */
@@ -403,11 +285,12 @@ static u16 ath9k_eeprom_read(u16 addr) {
/* AR5416_EEPROM_CMD: bit0=READ, bit1=BUSY, bit2=RESET */
/* 启动 read:写 cmd=READ | addr<<3 */
ath9k_reg_write(AR_EEPROM_CMD, AR_EEPROM_CMD_RESET);
delay_us(5);
dkm_delay_us(5);
u32 cmd = AR_EEPROM_CMD_READ | ((u32)(addr & 0x3FF) << 3);
ath9k_reg_write(AR_EEPROM_CMD, cmd);
/* 等待 RDBUSY 清除 */
for (u32 i = 0; i < 100000; i++) {
/* 等待 RDBUSY 清除 (实机: 100ms TSC 超时) */
u64 deadline = dkm_rdtsc() + dkm_tsc_per_ms * 100;
while (dkm_rdtsc() < deadline) {
u32 sts = ath9k_reg_read(AR_EEPROM_STS);
if (!(sts & AR_EEPROM_STS_RDBUSY)) {
if (sts & AR_EEPROM_STS_VALID) {
@@ -415,7 +298,7 @@ static u16 ath9k_eeprom_read(u16 addr) {
}
return 0xffff;
}
delay_us(1);
dkm_delay_us(1);
}
return 0xffff;
}
@@ -425,27 +308,29 @@ static int ath9k_reset(void) {
raw_log("[ath9k.raw] reset sequence\n");
/* 1. 强制唤醒(Power-On) */
ath9k_reg_write(AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_ON | AR_RTC_FORCE_WAKE_INT);
delay_us(50);
/* 2. 等待 RTC 进入 ON 状态 */
for (u32 i = 0; i < 100000; i++) {
dkm_delay_us(50);
/* 2. 等待 RTC 进入 ON 状态 (实机: 100ms TSC 超时) */
u64 deadline = dkm_rdtsc() + dkm_tsc_per_ms * 100;
while (dkm_rdtsc() < deadline) {
u32 s = ath9k_reg_read(AR_RTC_STATUS);
if ((s & 0x3) == AR_RTC_STATUS_ON) break;
delay_us(1);
dkm_delay_us(1);
}
/* 3. 全 chip 复位 */
ath9k_reg_write(AR_RC, AR_RC_MAC | AR_RC_BB | AR_RC_RPCU);
delay_us(100);
dkm_delay_us(100);
ath9k_reg_write(AR_RC, 0);
delay_us(100);
dkm_delay_us(100);
/* 4. 重新唤醒 */
ath9k_reg_write(AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_ON | AR_RTC_FORCE_WAKE_INT);
delay_us(50);
/* 5. 等待 RTC ON */
dkm_delay_us(50);
/* 5. 等待 RTC ON (实机: 100ms TSC 超时) */
u32 ok = 0;
for (u32 i = 0; i < 100000; i++) {
u64 deadline2 = dkm_rdtsc() + dkm_tsc_per_ms * 100;
while (dkm_rdtsc() < deadline2) {
u32 s = ath9k_reg_read(AR_RTC_STATUS);
if ((s & 0x3) == AR_RTC_STATUS_ON) { ok = 1; break; }
delay_us(1);
dkm_delay_us(1);
}
if (!ok) { raw_log("[ath9k.raw] reset: RTC not ON\n"); return -1; }
raw_log("[ath9k.raw] reset: RTC ON\n");
@@ -461,7 +346,7 @@ static int ath9k_hw_init(void) {
raw_log("[ath9k.raw] hw_init minimal\n");
/* 关闭 RX/DMA,清 STA_ID1 */
ath9k_reg_write(AR_CR, AR_CR_RXD);
delay_us(10);
dkm_delay_us(10);
ath9k_reg_write(AR_STA_ID1, 0);
/* 清中断 */
ath9k_reg_write(AR_ISR, 0xFFFFFFFFu);
@@ -650,13 +535,13 @@ static void ath9k_set_channel(u8 channel) {
/* TODO: 完整 ath9k 信道切换序列(参考 ar9002_hw_set_channel) */
/* 触发 RFBUS 请求,等待 grant */
ath9k_reg_write(AR_PHY_RFBUS_REQ, 0x1);
delay_us(5);
dkm_delay_us(5);
for (u32 i = 0; i < 1000; i++) {
if (ath9k_reg_read(AR_PHY_RFBUS_REQ) & 0x2) break;
delay_us(1);
dkm_delay_us(1);
}
ath9k_reg_write(AR_PHY_RFBUS_REQ, 0);
delay_us(50);
dkm_delay_us(50);
}
/* ---- 被动扫描状态机 ----
@@ -684,7 +569,7 @@ static int ath9k_scan_start_impl(void *ctx) {
/* 在该信道停留 ~400ms,期间轮询 RX 环 */
for (u32 tick = 0; tick < 400; tick++) {
ath9k_rx_drain();
delay_us(1000);
dkm_delay_us(1000);
}
}
g_scanning = 0;
@@ -752,6 +637,8 @@ __attribute__((visibility("default")))
int driver_init(const struct dkm_kernel_api *api,
struct dkm_driver_handle *handle) {
(void)handle;
/* 实机要求: 先校准 TSC, 再使用基于 CPU 频率的延迟 */
dkm_tsc_calibrate();
raw_log("[ath9k.raw] driver_init entered\n");
if (!api || !api->log) return -1;
g_log = api->log;
@@ -766,7 +653,7 @@ int driver_init(const struct dkm_kernel_api *api,
/* 2. 启用 PCI 命令(MEM + Bus Master) */
u32 cmd = pci_read(bus, dev, 0, PCI_COMMAND);
pci_write(bus, dev, 0, PCI_COMMAND, cmd | PCI_CMD_MEM | PCI_CMD_BUSMST);
pci_write(bus, dev, 0, PCI_COMMAND, cmd | PCI_CMD_MEM | PCI_CMD_BUSM);
/* 3. 读取 BAR0 */
u32 bar0 = pci_read(bus, dev, 0, PCI_BAR0);
+10 -162
View File
@@ -1,6 +1,8 @@
/* DKM Console Framebuffer Driver
* Stage 1, optional, provides "console".
* Light-blue background + centered circular loading animation (4-color arc ring).
* Clears the framebuffer to a solid light-blue background so the screen is
* clean before DSK takes over and draws the Logo. The former 4-color arc
* loading ring has been removed — DSK now shows a static Logo instead.
*/
#include <stdint.h>
@@ -51,7 +53,7 @@ __attribute__((visibility("default"), used))
const struct dkm_driver_desc driver_desc = {
.magic=DKM_DRIVER_MAGIC, .abi_version=DKM_ABI_VERSION,
.desc_size=sizeof(struct dkm_driver_desc),
.name="console_fb", .version="0.2.0", .vendor="Deshab",
.name="console_fb", .version="0.3.0", .vendor="Deshab",
.driver_class=5, .stage=1, .flags=0, .priority=0,
.depends=NULL, .depends_count=0,
.provides=g_provides, .provides_count=1,
@@ -61,18 +63,11 @@ const struct dkm_driver_desc driver_desc = {
/* ---------------------------------------------------------------
* Colors
* --------------------------------------------------------------- */
static const u32 BG = 0xFFC8E0F0; /* light blue background */
static const u32 ARC[4] = { 0xFF4488CC, 0xFF2266AA, 0xFF66AAEE, 0xFF88CCFF };
static const u32 BG = 0xFFC8E0F0; /* light blue background — cleared before DSK Logo */
/* ---------------------------------------------------------------
* Drawing helpers – all integer arithmetic, no soft-float
* --------------------------------------------------------------- */
static u64 fb_w, fb_h, fb_p;
/* double-buffer sprite for ring area (128×128 = no flicker) */
#define SPR_SIZE 128
static u32 g_sprite[SPR_SIZE * SPR_SIZE];
static void fb_fill(u32 *fb, u64 pitch, u64 w, u64 h, u32 color) {
for (u64 y = 0; y < h; y++) {
u32 *line = (u32 *)((u8 *)fb + y * pitch);
@@ -80,105 +75,6 @@ static void fb_fill(u32 *fb, u64 pitch, u64 w, u64 h, u32 color) {
}
}
/* alpha-blend c2 over c1, alpha 0-255 */
static u32 blend(u32 c1, u32 c2, u32 a) {
u32 na = 256 - a;
u32 r = ((c1 & 0xFF) * na + (c2 & 0xFF) * a) >> 8;
u32 g = (((c1 >> 8) & 0xFF) * na + ((c2 >> 8) & 0xFF) * a) >> 8;
u32 b = (((c1 >> 16) & 0xFF) * na + ((c2 >> 16) & 0xFF) * a) >> 8;
return 0xFF000000 | (b << 16) | (g << 8) | r;
}
/* integer sqrt – returns floor(sqrt(v)) */
static u64 isqrt(u64 v) {
u64 x = v, y = (x + 1) >> 1;
while (y < x) { x = y; y = (y + v / y) >> 1; }
return x;
}
/* approximate atan2 in degrees (0=right, CCW). dx,dy = pixel offset from center */
static i64 approx_angle(i64 dx, i64 dy) {
if (dx == 0) return dy < 0 ? 90 : 270;
i64 ax = dx < 0 ? -dx : dx;
i64 ay = dy < 0 ? -dy : dy;
i64 a;
if (ax > ay) {
a = ay * 45 / ax;
} else {
a = 90 - ax * 45 / (ay ? ay : 1);
}
/* quadrant correction */
if (dx >= 0 && dy <= 0) return a; /* Q1 */
else if (dx < 0 && dy <= 0) return 180 - a; /* Q2 */
else if (dx < 0 && dy > 0) return 180 + a; /* Q3 */
else return 360 - a; /* Q4 */
}
/* draw one arc segment: rounded caps (6° head/tail), bright mid, comet-tail fade */
static void arc_segment(u32 *fb, i64 cx, i64 cy, i64 r, i64 start, i64 sweep, u32 color, i64 thk) {
i64 ro = r + thk, ri = r - thk;
i64 ri2 = ri * ri, ro2 = (ro + 1) * (ro + 1);
i64 rnd = 6; /* rounding zone at each end, in degrees */
for (i64 dy = -ro - 1; dy <= ro + 1; dy++) {
i64 y = cy + dy;
if ((u64)y >= fb_h) continue;
u32 *line = (u32 *)((u8 *)fb + (u64)y * fb_p);
for (i64 dx = -ro - 1; dx <= ro + 1; dx++) {
i64 x = cx + dx;
if ((u64)x >= fb_w) continue;
i64 d2 = dx * dx + dy * dy;
if (d2 < ri2 - 2 || d2 > ro2 + 2) continue;
i64 ang = approx_angle(dx, dy);
i64 a = ang - start;
if (a < 0) a += 360;
if ((u64)a > (u64)sweep) continue;
/* rounded-cap fade: 0→255 over rnd°, then 255→0 over last rnd° */
u32 fade;
if ((u64)a < (u64)rnd) {
fade = (u32)(a * 255 / rnd);
} else if ((u64)a > (u64)(sweep - rnd)) {
fade = (u32)((sweep - a) * 255 / rnd);
} else {
fade = 255;
}
i64 dist = (i64)isqrt((u64)d2);
u32 effective = blend(BG, color, fade);
if (dist >= ri && dist <= ro) {
line[(u64)x] = effective;
} else if (dist >= ri - 2 && dist < ri) {
line[(u64)x] = blend(BG, effective, (u32)((dist - (ri - 2)) * 85));
} else if (dist > ro && dist <= ro + 2) {
line[(u64)x] = blend(effective, BG, (u32)((dist - ro) * 85));
}
}
}
}
/* filled disc with anti-aliased edge */
static void fill_disc(u32 *fb, i64 cx, i64 cy, i64 r, u32 color) {
i64 r2 = r * r, o2 = (r + 1) * (r + 1);
for (i64 dy = -r - 2; dy <= r + 2; dy++) {
i64 y = cy + dy;
if ((u64)y >= fb_h) continue;
u32 *line = (u32 *)((u8 *)fb + (u64)y * fb_p);
for (i64 dx = -r - 2; dx <= r + 2; dx++) {
i64 x = cx + dx;
if ((u64)x >= fb_w) continue;
i64 d2 = dx * dx + dy * dy;
if (d2 <= r2) {
line[(u64)x] = color;
} else if (d2 <= o2) {
u32 a = (u32)((o2 - d2) * 255 / (o2 - r2));
line[(u64)x] = blend(BG, color, a);
}
}
}
}
/* ---------------------------------------------------------------
* Driver entry
* --------------------------------------------------------------- */
@@ -192,61 +88,13 @@ int driver_init(const struct dkm_kernel_api *api,
return 0;
}
api->log->info("[console_fb] boot screen");
api->log->info("[console_fb] clearing boot screen");
fb_w = api->fb_width; fb_h = api->fb_height; fb_p = api->fb_pitch;
/* Solid background fill only — DSK draws the Logo next. Clearing here
* avoids firmware/UEFI leftover garbage being visible during the
* UTSM→DSK handoff. */
u32 *fb = (u32 *)api->fb_address;
i64 cx = (i64)fb_w / 2, cy = (i64)fb_h / 2, r = 48, thk = 4;
/* light-blue background */
fb_fill(fb, fb_p, fb_w, fb_h, BG);
/* animation: 2000 frames × 2° clockwise × ~1ms, no flicker */
i64 spr_p = SPR_SIZE * 4;
i64 scx = SPR_SIZE / 2;
i64 scy = SPR_SIZE / 2;
i64 frame = 0, base = 0;
i64 bx = cx - scx; /* screen position of sprite top-left */
i64 by = cy - scy;
while (frame < 2000) {
/* draw into sprite buffer — swap globals to sprite layout */
u64 save_w = fb_w, save_h = fb_h, save_p = fb_p;
fb_w = SPR_SIZE; fb_h = SPR_SIZE; fb_p = spr_p;
fb_fill(g_sprite, spr_p, SPR_SIZE, SPR_SIZE, BG);
arc_segment(g_sprite, scx, scy, r, base + 0, 82, ARC[0], thk);
arc_segment(g_sprite, scx, scy, r, base + 90, 82, ARC[1], thk);
arc_segment(g_sprite, scx, scy, r, base +180, 82, ARC[2], thk);
arc_segment(g_sprite, scx, scy, r, base +270, 82, ARC[3], thk);
fill_disc(g_sprite, scx, scy, r - 8, blend(BG, 0xFFD0F0FF, 80));
/* restore screen globals for blit */
fb_w = save_w; fb_h = save_h; fb_p = save_p;
/* blit sprite to screen */
for (i64 sr = 0; sr < SPR_SIZE; sr++) {
i64 sy = by + sr;
if ((u64)sy >= fb_h) continue;
u32 *dst = (u32 *)((u8 *)fb + (u64)sy * fb_p) + bx;
u32 *src = &g_sprite[sr * SPR_SIZE];
for (i64 sc = 0; sc < SPR_SIZE; sc++) {
i64 sx = bx + sc;
if ((u64)sx >= fb_w) continue;
dst[sc] = src[sc];
}
}
for (volatile u32 d = 0; d < 72000; d++) {
__asm__ volatile ("pause");
}
base -= 2;
if (base < 0) base += 360;
frame++;
}
fb_fill(fb, api->fb_pitch, api->fb_width, api->fb_height, BG);
api->log->info("[console_fb] ready");
return 0;
+331
View File
@@ -0,0 +1,331 @@
/* DKM 共享头文件 — 消除各驱动重复的结构体/宏/PCI/TSC 代码
*
* 设计要点:
* - 结构体定义与 UTSM/include/utsm/dkm.h 保持布局一致 (canonical)
* - PCI I/O 函数使用 static __inline__, 每个 .drv 文件获得独立副本, 避免链接冲突
* - TSC 校准函数使用 static __inline__, 每个 .drv 文件获得自己的 dkm_tsc_per_ms
* - 驱动源文件只需 #include "../dkm_shared.h", 保留各自的 driver_desc 和 driver_init
*
* 使用约定:
* 1. 在 driver_init 开头调用 dkm_tsc_calibrate() 完成校准
* 2. 时序等待使用 dkm_delay_ms() / dkm_delay_us()
* 3. 串口发送等待使用 dkm_serial_wait_tx(COM1)
* 4. MMIO 寄存器读取等待使用 dkm_rdtsc() + dkm_tsc_per_ms 直接计算 deadline
*/
#ifndef DKM_SHARED_H
#define DKM_SHARED_H
#include <stdint.h>
/* ---- 基本类型 (与 UTSM/types.h 一致) ---- */
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long long u64;
typedef signed char i8;
typedef short i16;
typedef int i32;
typedef long long i64;
#ifndef NULL
#define NULL ((void *)0)
#endif
/* ---- DKM magic / ABI 版本 ---- */
#define DKM_DRIVER_MAGIC 0x444B4D31u
#define DKM_ABI_VERSION 1u
/* ---- DKM 驱动类别 (driver_desc.driver_class) ---- */
#define DKM_CLASS_PLATFORM 1u
#define DKM_CLASS_BUS 2u
#define DKM_CLASS_INTERRUPT 3u
#define DKM_CLASS_TIMER 4u
#define DKM_CLASS_CONSOLE 5u
#define DKM_CLASS_STORAGE 6u
#define DKM_CLASS_FS 7u
#define DKM_CLASS_NET 8u
#define DKM_CLASS_INPUT 9u
#define DKM_CLASS_GPU 10u
#define DKM_CLASS_MISC 11u
/* ---- DKM 驱动标志 (driver_desc.flags) ---- */
#define DKM_F_REQUIRED (1u << 0)
#define DKM_F_BOOT_MODULE (1u << 1)
#define DKM_F_NO_UNLOAD (1u << 2)
#define DKM_F_STRONG_RECOVERY (1u << 3)
#define DKM_F_DMA_REQUIRED (1u << 4)
#define DKM_F_EARLY_LOG (1u << 5)
/* ---- 网卡链路/能力标志 ---- */
#define DKM_NET_F_LINK_UP (1u << 0)
#define DKM_NET_F_TX_READY (1u << 1)
#define DKM_NET_F_RX_READY (1u << 2)
#define DKM_NET_F_WIRELESS (1u << 3)
/* ---- WiFi 扫描加密类型 ---- */
#define DKM_NET_SEC_OPEN 0u
#define DKM_NET_SEC_WEP 1u
#define DKM_NET_SEC_WPA 2u
#define DKM_NET_SEC_WPA2 3u
#define DKM_NET_SEC_WPA3 4u
/* ---- DKM 结构体定义 (与 UTSM/include/utsm/dkm.h 布局一致) ---- */
struct dkm_log_api {
void (*info)(const char *msg);
void (*warn)(const char *msg);
void (*error)(const char *msg);
void (*panic)(const char *msg);
};
struct dkm_dma_buffer {
void *virt;
u64 phys;
u64 size;
};
struct dkm_dma_api {
int (*alloc_pages)(u64 page_count, u64 alignment, u64 max_phys, struct dkm_dma_buffer *out);
};
struct dkm_net_scan_result {
char ssid[33];
u8 bssid[6];
u8 channel;
i8 rssi;
u8 security;
};
struct dkm_net_device_desc {
const char *name;
u8 mac[6];
u32 flags;
void *ctx;
int (*tx)(void *ctx, const void *packet, u32 length);
int (*rx_poll)(void *ctx, void *buffer, u32 capacity, u32 *out_length);
/* 无线扩展回调(有线驱动置 NULL,向后兼容)。 */
int (*scan_start)(void *ctx);
int (*scan_count)(void *ctx);
int (*scan_result)(void *ctx, u32 n, struct dkm_net_scan_result *out);
int (*is_wireless)(void *ctx);
};
struct dkm_net_api {
int (*register_device)(const struct dkm_net_device_desc *desc);
u32 (*device_count)(void);
int (*device_info)(u32 index, void *out);
int (*tx)(u32 index, const void *packet, u32 length);
int (*rx_poll)(u32 index, void *buffer, u32 capacity, u32 *out_length);
int (*scan_start)(u32 index);
int (*scan_count)(u32 index);
int (*scan_result)(u32 index, u32 n, struct dkm_net_scan_result *out);
int (*is_wireless)(u32 index);
};
typedef int (*dkm_block_read_fn)(void *ctx, u64 lba, u32 count, void *buffer);
typedef int (*dkm_block_write_fn)(void *ctx, u64 lba, u32 count, const void *buffer);
struct dkm_block_device_desc {
const char *name;
u64 sector_size;
u64 sector_count;
void *ctx;
int (*read)(void *ctx, u64 lba, u32 count, void *buffer);
int (*write)(void *ctx, u64 lba, u32 count, const void *buffer);
};
struct dkm_block_api {
int (*register_device)(const struct dkm_block_device_desc *desc);
u32 (*device_count)(void);
int (*read)(u32 index, u64 lba, u32 count, void *buffer);
int (*write)(u32 index, u64 lba, u32 count, const void *buffer);
u64 (*sector_size)(u32 index);
const char *(*device_name)(u32 index);
int (*set_write_fn)(u32 index, dkm_block_write_fn fn);
};
/* 与 UTSM/include/utsm/dkm.h 中的 dkm_kernel_api 布局完全一致.
* 字段顺序/类型不可调整 — UTSM 端按此偏移填充. */
struct dkm_kernel_api {
u32 version;
u32 size;
u64 feature_bits;
const struct dkm_log_api *log;
const void *mem;
const void *utsm;
const void *irq;
const void *pci;
const struct dkm_dma_api *dma;
const void *vfs;
const struct dkm_net_api *net;
const void *timer;
const void *drr;
const void *rsdp_address;
const void *fb_address;
u64 fb_width;
u64 fb_height;
u64 fb_pitch;
u16 fb_bpp;
const void *boot_modules_response;
int (*irq_register)(u8 irq, void *handler);
u64 hhdm_offset;
const struct dkm_block_api *block; /* 末尾字段, 不使用 block 的驱动可不访问 */
};
struct dkm_driver_handle;
struct dkm_driver_desc {
u32 magic;
u16 abi_version;
u16 desc_size;
const char *name;
const char *version;
const char *vendor;
u32 driver_class;
u32 stage;
u32 flags;
u32 priority;
const char *const *depends;
u32 depends_count;
const char *const *provides;
u32 provides_count;
u64 min_kernel_abi;
u64 feature_bits;
u64 reserved0;
u64 reserved1;
};
/* ---- PCI 配置空间常量 ---- */
#define PCI_ADDR 0xCF8
#define PCI_DATA 0xCFC
#define PCI_VENDOR_ID 0x00
#define PCI_DEVICE_ID 0x02
#define PCI_COMMAND 0x04
#define PCI_PROG_IF 0x09
#define PCI_SUBCLASS 0x0A
#define PCI_CLASS 0x0B
#define PCI_HEADER 0x0E
#define PCI_CAP_PTR 0x34
#define PCI_IRQ_LINE 0x3C
#define PCI_BAR0 0x10
#define PCI_BAR1 0x14
#define PCI_BAR2 0x18
#define PCI_BAR3 0x1C
#define PCI_BAR4 0x20
#define PCI_BAR5 0x24
#define PCI_CMD_IO (1u << 0)
#define PCI_CMD_MEM (1u << 1)
#define PCI_CMD_BUSM (1u << 2)
/* ---- PCI I/O 端口内联函数 (每个 .drv 获得独立副本) ---- */
static __inline__ void dkm_outl(u16 port, u32 value) {
__asm__ volatile ("outl %0, %1" :: "a"(value), "Nd"(port));
}
static __inline__ u32 dkm_inl(u16 port) {
u32 value;
__asm__ volatile ("inl %1, %0" : "=a"(value) : "Nd"(port));
return value;
}
static __inline__ void dkm_outb(u16 port, u8 value) {
__asm__ volatile ("outb %0, %1" :: "a"(value), "Nd"(port));
}
static __inline__ u8 dkm_inb(u16 port) {
u8 value;
__asm__ volatile ("inb %1, %0" : "=a"(value) : "Nd"(port));
return value;
}
static __inline__ u32 dkm_pci_read(u8 bus, u8 dev, u8 func, u8 reg) {
u32 addr = (1u << 31)
| ((u32)bus << 16)
| ((u32)dev << 11)
| ((u32)func << 8)
| ((u32)reg & 0xFC);
dkm_outl(PCI_ADDR, addr);
return dkm_inl(PCI_DATA);
}
static __inline__ void dkm_pci_write(u8 bus, u8 dev, u8 func, u8 reg, u32 value) {
u32 addr = (1u << 31)
| ((u32)bus << 16)
| ((u32)dev << 11)
| ((u32)func << 8)
| ((u32)reg & 0xFC);
dkm_outl(PCI_ADDR, addr);
dkm_outl(PCI_DATA, value);
}
static __inline__ u8 dkm_pci_read8(u8 bus, u8 dev, u8 func, u8 reg) {
u32 v = dkm_pci_read(bus, dev, func, reg);
return (u8)((v >> ((reg & 3) * 8)) & 0xff);
}
/* ---- TSC 时序: 实机要求用 CPU 频率计算, 不用循环 ----
* 每个 .drv 包含此头文件后获得自己的 file-local dkm_tsc_per_ms 副本,
* 通过 dkm_tsc_calibrate() 在 driver_init 开头初始化.
*/
static u64 dkm_tsc_per_ms __attribute__((unused)) = 0;
static __inline__ u64 dkm_rdtsc(void) {
u32 lo, hi;
__asm__ volatile("rdtsc" : "=a"(lo), "=d"(hi));
return ((u64)hi << 32) | lo;
}
/* 通过 PIT ch0 + TSC 校准 ~10ms 区间, 推算每毫秒 TSC 周期数. */
static __inline__ void dkm_tsc_calibrate(void) {
dkm_outb(0x43, 0x30); /* ch0, lo+hi, mode 0, binary */
dkm_outb(0x40, 0x7c); /* 11932 low = ~10ms */
dkm_outb(0x40, 0x2e); /* 11932 high */
u64 tsc_start = dkm_rdtsc();
u16 prev = 0; u64 loops = 0;
for (;;) {
dkm_outb(0x43, 0x00);
u16 cur = (u16)dkm_inb(0x40) | ((u16)dkm_inb(0x40) << 8);
if (cur > prev && loops > 10) break;
prev = cur; loops++;
}
u64 tsc_end = dkm_rdtsc();
dkm_tsc_per_ms = (tsc_end - tsc_start) / 10;
}
static __inline__ void dkm_delay_ms(u32 ms) {
if (!dkm_tsc_per_ms) {
for (volatile u32 i = 0; i < 100000 * ms; i++) __asm__ volatile("pause");
return;
}
u64 target = dkm_tsc_per_ms * ms;
u64 start = dkm_rdtsc();
while (dkm_rdtsc() - start < target) __asm__ volatile("pause");
}
static __inline__ void dkm_delay_us(u32 us) {
if (!dkm_tsc_per_ms) {
for (volatile u32 i = 0; i < 100 * us; i++) __asm__ volatile("pause");
return;
}
u64 target = dkm_tsc_per_ms * us / 1000;
u64 start = dkm_rdtsc();
while (dkm_rdtsc() - start < target) __asm__ volatile("pause");
}
/* 实机: 基于 TSC 的串口发送等待 (100us 超时). com_port = 0x3F8 (COM1). */
static __inline__ void dkm_serial_wait_tx(u16 com_port) {
if (!dkm_tsc_per_ms) {
for (volatile u32 i = 0; i < 100000; i++) {
if (dkm_inb((u16)(com_port + 5)) & 0x20) break;
__asm__ volatile("pause");
}
return;
}
u64 deadline = dkm_rdtsc() + dkm_tsc_per_ms / 10;
while (dkm_rdtsc() < deadline) {
if (dkm_inb((u16)(com_port + 5)) & 0x20) break;
__asm__ volatile("pause");
}
}
#endif /* DKM_SHARED_H */
+26 -119
View File
@@ -3,98 +3,7 @@
* Finds e1000 via PCI, maps MMIO, reads MAC address.
*/
#include <stdint.h>
#define DKM_DRIVER_MAGIC 0x444B4D31u
#define DKM_ABI_VERSION 1u
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long long u64;
typedef signed char i8;
typedef long long i64;
#define NULL ((void *)0)
struct dkm_log_api {
void (*info)(const char *msg);
void (*warn)(const char *msg);
void (*error)(const char *msg);
void (*panic)(const char *msg);
};
struct dkm_net_scan_result {
char ssid[33];
u8 bssid[6];
u8 channel;
i8 rssi;
u8 security;
};
struct dkm_net_device_desc {
const char *name;
u8 mac[6];
u32 flags;
void *ctx;
int (*tx)(void *ctx, const void *packet, u32 length);
int (*rx_poll)(void *ctx, void *buffer, u32 capacity, u32 *out_length);
/* 无线扩展回调(有线驱动置 NULL,向后兼容)。 */
int (*scan_start)(void *ctx);
int (*scan_count)(void *ctx);
int (*scan_result)(void *ctx, u32 n, struct dkm_net_scan_result *out);
int (*is_wireless)(void *ctx);
};
struct dkm_net_api {
int (*register_device)(const struct dkm_net_device_desc *desc);
u32 (*device_count)(void);
int (*device_info)(u32 index, void *out);
int (*tx)(u32 index, const void *packet, u32 length);
int (*rx_poll)(u32 index, void *buffer, u32 capacity, u32 *out_length);
int (*scan_start)(u32 index);
int (*scan_count)(u32 index);
int (*scan_result)(u32 index, u32 n, struct dkm_net_scan_result *out);
int (*is_wireless)(u32 index);
};
struct dkm_dma_buffer {
void *virt;
u64 phys;
u64 size;
};
struct dkm_dma_api {
int (*alloc_pages)(u64 page_count, u64 alignment, u64 max_phys, struct dkm_dma_buffer *out);
};
#define DKM_NET_F_LINK_UP (1u << 0)
#define DKM_NET_F_TX_READY (1u << 1)
#define DKM_NET_F_RX_READY (1u << 2)
struct dkm_kernel_api {
u32 version; u32 size; u64 feature_bits;
const struct dkm_log_api *log;
const void *mem,*utsm,*irq_api,*pci_api;
const struct dkm_dma_api *dma;
const void *vfs_api;
const struct dkm_net_api *net;
const void *timer,*drr;
const void *rsdp_address,*fb_address;
u64 fb_width,fb_height,fb_pitch; u16 fb_bpp;
const void *boot_modules_response;
int (*irq_register)(u8 irq, void *handler);
u64 hhdm_offset;
};
struct dkm_driver_handle;
struct dkm_driver_desc {
u32 magic; u16 abi_version; u16 desc_size;
const char *name,*version,*vendor;
u32 driver_class,stage,flags,priority;
const char *const *depends; u32 depends_count;
const char *const *provides; u32 provides_count;
u64 min_kernel_abi,feature_bits,reserved0,reserved1;
};
#include "../dkm_shared.h"
static const char *const g_depends[] = {"pci","irq"};
static const char *const g_provides[] = {"netdev"};
@@ -108,16 +17,6 @@ const struct dkm_driver_desc driver_desc = {
.provides=g_provides,.provides_count=1,.min_kernel_abi=1,
};
/* PCI config ports */
#define PCI_ADDR 0xCF8
#define PCI_DATA 0xCFC
#define PCI_VENDOR_ID 0x00
#define PCI_DEVICE_ID 0x02
#define PCI_COMMAND 0x04
#define PCI_BAR0 0x10
#define PCI_BAR1 0x14
#define PCI_IRQ_LINE 0x3C
/* e1000 MMIO registers */
#define E1000_CTRL 0x0000
#define E1000_STATUS 0x0008
@@ -205,20 +104,20 @@ static u32 g_rx_tail;
static u32 g_tx_tail;
static int g_rings_ready;
static __inline__ void outl(u16 p, u32 v) { __asm__ volatile("outl %0,%1"::"a"(v),"Nd"(p):"memory"); }
static __inline__ u32 inl(u16 p) { u32 v; __asm__ volatile("inl %1,%0":"=a"(v):"Nd"(p):"memory"); return v; }
static u8 inb(u16 p) { u8 v; __asm__ volatile("inb %1,%0":"=a"(v):"Nd"(p):"memory"); return v; }
static void outb(u16 p, u8 v) { __asm__ volatile("outb %0,%1"::"a"(v),"Nd"(p):"memory"); }
#define COM1 0x3F8
/* 串口发送等待 thin wrapper — 调用 dkm 共享实现 */
static void serial_wait_tx(void) { dkm_serial_wait_tx(COM1); }
static void raw_log(const char *s) {
while (*s) {
char c = *s++;
if (c == '\n') {
for (u32 i=0;i<100000;i++) if (inb(0x3F8+5)&0x20) break;
outb(0x3F8, '\r');
serial_wait_tx();
dkm_outb(COM1, '\r');
}
for (u32 i=0;i<100000;i++) if (inb(0x3F8+5)&0x20) break;
outb(0x3F8, (u8)c);
serial_wait_tx();
dkm_outb(COM1, (u8)c);
}
}
@@ -227,20 +126,18 @@ static void raw_hex(const char *prefix, u64 v) {
raw_log(prefix);
raw_log("0x");
for (int i=15; i>=0; i--) {
for (u32 wait=0; wait<100000; wait++) if (inb(0x3F8+5)&0x20) break;
outb(0x3F8, (u8)h[(v >> (i * 4)) & 0xf]);
serial_wait_tx();
dkm_outb(COM1, (u8)h[(v >> (i * 4)) & 0xf]);
}
raw_log("\n");
}
static u32 pci_read(u8 bus, u8 dev, u8 func, u8 reg) {
u32 a = (1u<<31)|((u32)bus<<16)|((u32)dev<<11)|((u32)func<<8)|((u32)reg&0xFC);
outl(PCI_ADDR,a); return inl(PCI_DATA);
return dkm_pci_read(bus, dev, func, reg);
}
static void pci_write(u8 bus, u8 dev, u8 func, u8 reg, u32 v) {
u32 a = (1u<<31)|((u32)bus<<16)|((u32)dev<<11)|((u32)func<<8)|((u32)reg&0xFC);
outl(PCI_ADDR,a); outl(PCI_DATA,v);
dkm_pci_write(bus, dev, func, reg, v);
}
static int e1000_find(u8 *bus, u8 *dev) {
@@ -262,9 +159,12 @@ static int e1000_find(u8 *bus, u8 *dev) {
static u16 e1000_eeprom_read(u16 addr) {
/* EERD: bit0=START, addr<<8, 完成后 bit4=DONE, data 在高 16 位 */
g_mmio[E1000_EERD/4] = ((u32)addr << 8) | 1u;
for (u32 i=0;i<100000;i++) {
/* 实机: 100ms TSC 超时 */
u64 deadline = dkm_rdtsc() + dkm_tsc_per_ms * 100;
while (dkm_rdtsc() < deadline) {
u32 v = g_mmio[E1000_EERD/4];
if (v & (1u<<4)) return (u16)(v >> 16);
__asm__ volatile("pause");
}
return 0xffff;
}
@@ -382,7 +282,9 @@ static int e1000_tx(void *ctx, const void *packet, u32 length) {
g_tx_tail = (index + 1) % E1000_TX_DESC_COUNT;
g_mmio[E1000_TDT/4] = g_tx_tail;
mmio_flush();
for (u32 wait=0; wait<1000000; wait++) {
/* 实机: 1秒 TSC 超时等待 TX 完成 */
u64 deadline = dkm_rdtsc() + dkm_tsc_per_ms * 1000;
while (dkm_rdtsc() < deadline) {
dma_fence();
if (g_tx_desc[index].status & E1000_TX_STA_DD) {
raw_log("[e1000.raw] tx complete\n");
@@ -428,6 +330,8 @@ static int e1000_rx_poll(void *ctx, void *buffer, u32 capacity, u32 *out_length)
__attribute__((visibility("default")))
int driver_init(const struct dkm_kernel_api *api,
struct dkm_driver_handle *handle) {
/* 实机要求: 先校准 TSC, 再使用基于 CPU 频率的延迟 */
dkm_tsc_calibrate();
raw_log("[e1000.raw] driver_init entered\n");
(void)handle;
if (!api||!api->log) return -1;
@@ -472,8 +376,11 @@ int driver_init(const struct dkm_kernel_api *api,
/* 软件复位,确保 RX/TX/RAL/RAH 从已知状态开始配置。 */
g_mmio[E1000_CTRL/4] = g_mmio[E1000_CTRL/4] | (1u << 26);
for (u32 wait=0; wait<1000000; wait++) {
/* 实机: 1秒 TSC 超时等待复位完成 */
u64 deadline = dkm_rdtsc() + dkm_tsc_per_ms * 1000;
while (dkm_rdtsc() < deadline) {
if (!(g_mmio[E1000_CTRL/4] & (1u << 26))) break;
__asm__ volatile("pause");
}
raw_log("[e1000.raw] reset done\n");
+2
View File
@@ -31,8 +31,10 @@ struct dkm_block_api {
int (*register_device)(const void *desc);
u32 (*device_count)(void);
int (*read)(u32 index, u64 lba, u32 count, void *buffer);
int (*write)(u32 index, u64 lba, u32 count, const void *buffer);
u64 (*sector_size)(u32 index);
const char *(*device_name)(u32 index);
int (*set_write_fn)(u32 index, int (*fn)(void *ctx, u64 lba, u32 count, const void *buf));
};
struct dkm_kernel_api {
+44 -161
View File
@@ -4,110 +4,23 @@
* it does not negotiate features, create virtqueues, or transmit packets.
*/
#include <stdint.h>
#include "../dkm_shared.h"
#define DKM_DRIVER_MAGIC 0x444B4D31u
#define DKM_ABI_VERSION 1u
/* virtio-specific PCI IDs and capability types (driver-local) */
#define PCI_CLASS_REG 0x08 /* 32-bit class/subclass/prog_if/revision */
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long long u64;
typedef signed char i8;
typedef long long i64;
#define PCI_VENDOR_VIRTIO 0x1AF4u
#define VIRTIO_TRANS_DEVICE_MIN 0x1000u
#define VIRTIO_TRANS_DEVICE_MAX 0x103Fu
#define VIRTIO_MODERN_DEVICE_MIN 0x1040u
#define VIRTIO_MODERN_DEVICE_MAX 0x107Fu
#define VIRTIO_NET_DEVICE_ID 1u
#define NULL ((void *)0)
struct dkm_log_api {
void (*info)(const char *msg);
void (*warn)(const char *msg);
void (*error)(const char *msg);
void (*panic)(const char *msg);
};
struct dkm_net_scan_result {
char ssid[33];
u8 bssid[6];
u8 channel;
i8 rssi;
u8 security;
};
struct dkm_net_device_desc {
const char *name;
u8 mac[6];
u32 flags;
void *ctx;
int (*tx)(void *ctx, const void *packet, u32 length);
int (*rx_poll)(void *ctx, void *buffer, u32 capacity, u32 *out_length);
/* 无线扩展回调(有线驱动置 NULL,向后兼容)。 */
int (*scan_start)(void *ctx);
int (*scan_count)(void *ctx);
int (*scan_result)(void *ctx, u32 n, struct dkm_net_scan_result *out);
int (*is_wireless)(void *ctx);
};
struct dkm_net_api {
int (*register_device)(const struct dkm_net_device_desc *desc);
u32 (*device_count)(void);
int (*device_info)(u32 index, void *out);
int (*tx)(u32 index, const void *packet, u32 length);
int (*rx_poll)(u32 index, void *buffer, u32 capacity, u32 *out_length);
int (*scan_start)(u32 index);
int (*scan_count)(u32 index);
int (*scan_result)(u32 index, u32 n, struct dkm_net_scan_result *out);
int (*is_wireless)(u32 index);
};
#define DKM_NET_F_LINK_UP (1u << 0)
struct dkm_kernel_api {
u32 version;
u32 size;
u64 feature_bits;
const struct dkm_log_api *log;
const void *mem;
const void *utsm;
const void *irq;
const void *pci;
const void *dma;
const void *vfs;
const struct dkm_net_api *net;
const void *timer;
const void *drr;
const void *rsdp_address;
const void *fb_address;
u64 fb_width;
u64 fb_height;
u64 fb_pitch;
u16 fb_bpp;
const void *boot_modules_response;
int (*irq_register)(u8 irq, void *handler);
u64 hhdm_offset;
};
struct dkm_driver_handle;
struct dkm_driver_desc {
u32 magic;
u16 abi_version;
u16 desc_size;
const char *name;
const char *version;
const char *vendor;
u32 driver_class;
u32 stage;
u32 flags;
u32 priority;
const char *const *depends;
u32 depends_count;
const char *const *provides;
u32 provides_count;
u64 min_kernel_abi;
u64 feature_bits;
u64 reserved0;
u64 reserved1;
};
#define VIRTIO_PCI_CAP_COMMON_CFG 1u
#define VIRTIO_PCI_CAP_NOTIFY_CFG 2u
#define VIRTIO_PCI_CAP_ISR_CFG 3u
#define VIRTIO_PCI_CAP_DEVICE_CFG 4u
#define VIRTIO_PCI_CAP_PCI_CFG 5u
static const char *const g_depends[] = { "pci", "irq" };
static const char *const g_provides[] = { "netdev" };
@@ -134,73 +47,18 @@ const struct dkm_driver_desc driver_desc = {
.reserved1 = 0
};
#define PCI_ADDR 0xCF8
#define PCI_DATA 0xCFC
#define PCI_VENDOR_ID 0x00
#define PCI_COMMAND 0x04
#define PCI_CLASS_REG 0x08
#define PCI_HEADER 0x0E
#define PCI_CAP_PTR 0x34
#define PCI_IRQ_LINE 0x3C
#define PCI_BAR0 0x10
#define PCI_BAR1 0x14
#define PCI_BAR2 0x18
#define PCI_BAR3 0x1C
#define PCI_BAR4 0x20
#define PCI_BAR5 0x24
#define PCI_CMD_IO (1u << 0)
#define PCI_CMD_MEM (1u << 1)
#define PCI_CMD_BUSM (1u << 2)
#define PCI_VENDOR_VIRTIO 0x1AF4u
#define VIRTIO_TRANS_DEVICE_MIN 0x1000u
#define VIRTIO_TRANS_DEVICE_MAX 0x103Fu
#define VIRTIO_MODERN_DEVICE_MIN 0x1040u
#define VIRTIO_MODERN_DEVICE_MAX 0x107Fu
#define VIRTIO_NET_DEVICE_ID 1u
#define VIRTIO_PCI_CAP_COMMON_CFG 1u
#define VIRTIO_PCI_CAP_NOTIFY_CFG 2u
#define VIRTIO_PCI_CAP_ISR_CFG 3u
#define VIRTIO_PCI_CAP_DEVICE_CFG 4u
#define VIRTIO_PCI_CAP_PCI_CFG 5u
static const struct dkm_log_api *g_log;
static __inline__ void outl(u16 port, u32 value) {
__asm__ volatile ("outl %0, %1" :: "a"(value), "Nd"(port));
}
static __inline__ u32 inl(u16 port) {
u32 value;
__asm__ volatile ("inl %1, %0" : "=a"(value) : "Nd"(port));
return value;
}
static u32 pci_read(u8 bus, u8 dev, u8 func, u8 reg) {
u32 addr = (1u << 31)
| ((u32)bus << 16)
| ((u32)dev << 11)
| ((u32)func << 8)
| ((u32)reg & 0xFC);
outl(PCI_ADDR, addr);
return inl(PCI_DATA);
return dkm_pci_read(bus, dev, func, reg);
}
static void pci_write(u8 bus, u8 dev, u8 func, u8 reg, u32 value) {
u32 addr = (1u << 31)
| ((u32)bus << 16)
| ((u32)dev << 11)
| ((u32)func << 8)
| ((u32)reg & 0xFC);
outl(PCI_ADDR, addr);
outl(PCI_DATA, value);
dkm_pci_write(bus, dev, func, reg, value);
}
static u8 pci_read8(u8 bus, u8 dev, u8 func, u8 reg) {
u32 v = pci_read(bus, dev, func, reg);
return (u8)((v >> ((reg & 3) * 8)) & 0xff);
return dkm_pci_read8(bus, dev, func, reg);
}
static void log_hex(const char *prefix, u64 value) {
@@ -320,6 +178,28 @@ static void log_virtio_caps(u8 bus, u8 dev, u8 func) {
}
}
/* ---- tx/rx_poll stub: 安全占位, 不实际收发, 防止 netdev 调用 NULL ---- */
static int virtio_net_tx(void *ctx, const void *packet, u32 length) {
(void)ctx;
(void)packet;
/* 仅记录日志, 避免每次发包刷屏: 仅记录长度 */
static u32 s_tx_log_guard = 0;
if (s_tx_log_guard < 4) {
g_log->info("[virtio_net] tx stub: packet dropped (virtqueues not enabled)");
log_hex("[virtio_net] tx stub len=", length);
s_tx_log_guard++;
}
return 0;
}
static int virtio_net_rx_poll(void *ctx, void *buffer, u32 capacity, u32 *out_length) {
(void)ctx;
(void)buffer;
(void)capacity;
if (out_length) *out_length = 0;
return 0; /* 无数据, virtqueues 未启用 */
}
__attribute__((visibility("default")))
int driver_init(const struct dkm_kernel_api *api,
struct dkm_driver_handle *handle) {
@@ -328,6 +208,9 @@ int driver_init(const struct dkm_kernel_api *api,
if (!api || !api->log) return -1;
g_log = api->log;
/* 实机要求: 在驱动初始化开头校准 TSC, 为后续时序提供准确计时 */
dkm_tsc_calibrate();
g_log->info("[virtio_net] init begin");
u8 bus = 0;
@@ -379,8 +262,8 @@ int driver_init(const struct dkm_kernel_api *api,
for (int i = 0; i < 6; i++) netdev.mac[i] = 0;
netdev.flags = DKM_NET_F_LINK_UP;
netdev.ctx = 0;
netdev.tx = 0;
netdev.rx_poll = 0;
netdev.tx = virtio_net_tx; /* stub: 安全占位, 不 NULL */
netdev.rx_poll = virtio_net_rx_poll;
int net_index = api->net->register_device(&netdev);
log_hex("[virtio_net] netdev register rc=", (u64)(i64)net_index);
} else {