Add IDE/ATA disk driver with devicefs integration

Implement PIO-mode IDE driver that scans primary and secondary channels
for ATA hard drives and ATAPI CD/DVD drives using IDENTIFY commands.

Features:
- Scans 4 possible devices (2 channels x 2 drives each)
- ATA IDENTIFY DEVICE for hard drives
- ATAPI IDENTIFY PACKET DEVICE for CD/DVD drives
- PIO-mode 28-bit LBA sector read/write for ATA drives
- Model string extraction and sector count parsing
- Registers as kernel driver via REGISTER_DRIVER macro
- Registers devices with devicefs: ATA → hdd class, ATAPI → cd class
- Added inw/outw to port_io.h for 16-bit I/O

Tested: QEMU detects hdd1 (QEMU HARDDISK) and cd1 (QEMU DVD-ROM).
This commit is contained in:
AI
2026-02-23 13:57:00 +00:00
parent c12d49dea0
commit c07ec030a7
4 changed files with 491 additions and 0 deletions

88
src/ide.h Normal file
View File

@@ -0,0 +1,88 @@
/**
* @file ide.h
* @brief IDE/ATA disk driver.
*
* Enumerates IDE devices on the primary and secondary channels, identifies
* ATA hard drives and ATAPI CD-ROMs, and registers them with the devicefs
* subsystem as block devices (hddN / cdN).
*/
#ifndef IDE_H
#define IDE_H
#include <stdint.h>
/** Maximum number of IDE devices (2 channels × 2 drives). */
#define IDE_MAX_DEVICES 4
/** IDE channel I/O port bases. */
#define IDE_PRIMARY_IO 0x1F0
#define IDE_PRIMARY_CTRL 0x3F6
#define IDE_SECONDARY_IO 0x170
#define IDE_SECONDARY_CTRL 0x376
/** IDE register offsets from I/O base. */
#define IDE_REG_DATA 0x00
#define IDE_REG_ERROR 0x01
#define IDE_REG_FEATURES 0x01
#define IDE_REG_SECCOUNT 0x02
#define IDE_REG_LBA_LO 0x03
#define IDE_REG_LBA_MID 0x04
#define IDE_REG_LBA_HI 0x05
#define IDE_REG_DRIVE_HEAD 0x06
#define IDE_REG_STATUS 0x07
#define IDE_REG_COMMAND 0x07
/** IDE status register bits. */
#define IDE_STATUS_ERR 0x01 /**< Error occurred. */
#define IDE_STATUS_DRQ 0x08 /**< Data request ready. */
#define IDE_STATUS_SRV 0x10 /**< Overlapped mode service request. */
#define IDE_STATUS_DF 0x20 /**< Drive fault. */
#define IDE_STATUS_DRDY 0x40 /**< Drive ready. */
#define IDE_STATUS_BSY 0x80 /**< Drive busy. */
/** IDE commands. */
#define IDE_CMD_IDENTIFY 0xEC /**< ATA IDENTIFY DEVICE. */
#define IDE_CMD_IDENTIFY_PKT 0xA1 /**< ATAPI IDENTIFY PACKET DEVICE. */
#define IDE_CMD_READ_PIO 0x20 /**< Read sectors (PIO, 28-bit LBA). */
#define IDE_CMD_WRITE_PIO 0x30 /**< Write sectors (PIO, 28-bit LBA). */
/** IDE device types. */
#define IDE_TYPE_NONE 0 /**< No device present. */
#define IDE_TYPE_ATA 1 /**< ATA hard disk. */
#define IDE_TYPE_ATAPI 2 /**< ATAPI CD/DVD drive. */
/**
* IDE device descriptor.
*/
typedef struct ide_device {
uint8_t present; /**< 1 if device is present. */
uint8_t type; /**< IDE_TYPE_ATA or IDE_TYPE_ATAPI. */
uint8_t channel; /**< 0 = primary, 1 = secondary. */
uint8_t drive; /**< 0 = master, 1 = slave. */
uint16_t io_base; /**< I/O base port for this channel. */
uint16_t ctrl_base; /**< Control port for this channel. */
uint32_t sector_count; /**< Total sectors (28-bit LBA max). */
uint32_t sector_size; /**< Sector size in bytes (usually 512). */
char model[41]; /**< Model string from IDENTIFY. */
} ide_device_t;
/**
* Initialize the IDE driver.
*
* Scans primary and secondary channels for ATA/ATAPI devices,
* reads their IDENTIFY data, and registers them with devicefs.
*
* @return Number of devices found.
*/
int ide_init(void);
/**
* Get an IDE device by index (03).
*
* @param index Device index.
* @return Pointer to the device descriptor, or NULL if invalid/not present.
*/
ide_device_t *ide_get_device(int index);
#endif /* IDE_H */