// ide.h - shared IDE/ATA driver internals. #pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // --------------------------------------------------------------------------- // IDE register map (primary channel, base 0x1F0) // --------------------------------------------------------------------------- #define IDE_DATA 0x1F0 #define IDE_ERR 0x1F1 #define IDE_SECCNT 0x1F2 #define IDE_LBA0 0x1F3 #define IDE_LBA1 0x1F4 #define IDE_LBA2 0x1F5 #define IDE_DRIVE 0x1F6 #define IDE_STATUS 0x1F7 #define IDE_CMD 0x1F7 #define IDE_ALT 0x3F6 #define IDE_BUSY 0x80 #define IDE_READY 0x40 #define IDE_ERR_F 0x01 #define IDE_DRQ 0x08 // ATA commands #define CMD_READ_EXT 0x24 // PIO 48-bit read #define CMD_WRITE_EXT 0x34 // PIO 48-bit write #define CMD_READ_DMA_EXT 0x25 // DMA 48-bit read #define CMD_WRITE_DMA_EXT 0x35 // DMA 48-bit write #define CMD_READ_DMA 0xC8 // DMA 28-bit read #define CMD_WRITE_DMA 0xCA // DMA 28-bit write #define CMD_IDENT 0xEC // IDE primary IRQ #define IDE_IRQ_PRIMARY 14 // --------------------------------------------------------------------------- // Bus Master IDE register offsets (relative to gBmBase, primary channel) // --------------------------------------------------------------------------- #define BM_CMD_REG 0x00 // command #define BM_STATUS_REG 0x02 // status #define BM_PRDT_REG 0x04 // PRDT physical address (32-bit) // BM_CMD_REG bits #define BM_CMD_START 0x01 // start DMA transfer #define BM_CMD_READ 0x08 // 1 = disk→memory (read), 0 = memory→disk (write) // BM_STATUS_REG bits #define BM_STATUS_ACTIVE 0x01 // DMA active #define BM_STATUS_ERROR 0x02 // DMA error (write 1 to clear) #define BM_STATUS_IRQ 0x04 // interrupt pending (write 1 to clear) // --------------------------------------------------------------------------- // Physical Region Descriptor (PRDT entry, 8 bytes) // The PRDT itself must not cross a 64 KB boundary and must be 4-byte aligned. // We allocate a full page so both constraints are trivially satisfied. // --------------------------------------------------------------------------- #pragma pack(push, 1) typedef struct { uint32_t physAddr; // physical base of this memory region uint16_t byteCount; // byte count; 0 means 64 KB uint16_t flags; // bit 15: End Of Table } PRD; #pragma pack(pop) #define PRD_EOT 0x8000u // 512 entries × 8 bytes = 4096 bytes = exactly one page; supports 512×64 KB = 32 MB #define PRDT_MAX_ENTRIES 512 extern const HAL_API *gHal; extern DRIVER_OBJECT gDriver; extern DEVICE_OBJECT *gDevice; extern bool gDmaEnabled; extern uint64_t gSectorCount; extern bool gSupportsLba48; extern uint16_t gBmBase; extern PRD *gPrdtVirt; extern uint32_t gPrdtPhys; extern IRP_QUEUE gIrpQueue; extern SEMAPHORE *gIrpSemaphore; extern EVENT *gDmaEvent; extern KDPC gDmaDpc; void IdeDmaCompletionDpc(KDPC *dpc, void *context, void *systemArgument1, void *systemArgument2); void IdeIsr(void); void IdeWorker(uintptr_t arg); bool IdeDmaInit(void);