ata.h (5440B)
1 /* ATA PIO Driver for LuajitOS 2 * Provides basic ATA/IDE disk access using PIO mode 3 */ 4 5 #ifndef ATA_H 6 #define ATA_H 7 8 #include <stdint.h> 9 10 /* ATA I/O Ports - Primary Bus */ 11 #define ATA_PRIMARY_DATA 0x1F0 /* Data register (R/W) */ 12 #define ATA_PRIMARY_ERROR 0x1F1 /* Error register (R) / Features (W) */ 13 #define ATA_PRIMARY_SECCOUNT 0x1F2 /* Sector count */ 14 #define ATA_PRIMARY_LBA_LO 0x1F3 /* LBA low byte */ 15 #define ATA_PRIMARY_LBA_MID 0x1F4 /* LBA mid byte */ 16 #define ATA_PRIMARY_LBA_HI 0x1F5 /* LBA high byte */ 17 #define ATA_PRIMARY_DRIVE 0x1F6 /* Drive/Head register */ 18 #define ATA_PRIMARY_STATUS 0x1F7 /* Status register (R) / Command (W) */ 19 #define ATA_PRIMARY_CTRL 0x3F6 /* Device control register */ 20 21 /* ATA I/O Ports - Secondary Bus */ 22 #define ATA_SECONDARY_DATA 0x170 23 #define ATA_SECONDARY_ERROR 0x171 24 #define ATA_SECONDARY_SECCOUNT 0x172 25 #define ATA_SECONDARY_LBA_LO 0x173 26 #define ATA_SECONDARY_LBA_MID 0x174 27 #define ATA_SECONDARY_LBA_HI 0x175 28 #define ATA_SECONDARY_DRIVE 0x176 29 #define ATA_SECONDARY_STATUS 0x177 30 #define ATA_SECONDARY_CTRL 0x376 31 32 /* ATA Status Register Bits */ 33 #define ATA_SR_BSY 0x80 /* Busy */ 34 #define ATA_SR_DRDY 0x40 /* Drive ready */ 35 #define ATA_SR_DF 0x20 /* Drive write fault */ 36 #define ATA_SR_DSC 0x10 /* Drive seek complete */ 37 #define ATA_SR_DRQ 0x08 /* Data request ready */ 38 #define ATA_SR_CORR 0x04 /* Corrected data */ 39 #define ATA_SR_IDX 0x02 /* Index */ 40 #define ATA_SR_ERR 0x01 /* Error */ 41 42 /* ATA Error Register Bits */ 43 #define ATA_ER_BBK 0x80 /* Bad block */ 44 #define ATA_ER_UNC 0x40 /* Uncorrectable data */ 45 #define ATA_ER_MC 0x20 /* Media changed */ 46 #define ATA_ER_IDNF 0x10 /* ID mark not found */ 47 #define ATA_ER_MCR 0x08 /* Media change request */ 48 #define ATA_ER_ABRT 0x04 /* Command aborted */ 49 #define ATA_ER_TK0NF 0x02 /* Track 0 not found */ 50 #define ATA_ER_AMNF 0x01 /* Address mark not found */ 51 52 /* ATA Commands */ 53 #define ATA_CMD_READ_PIO 0x20 /* Read sectors (PIO) */ 54 #define ATA_CMD_READ_PIO_EXT 0x24 /* Read sectors ext (48-bit LBA) */ 55 #define ATA_CMD_WRITE_PIO 0x30 /* Write sectors (PIO) */ 56 #define ATA_CMD_WRITE_PIO_EXT 0x34 /* Write sectors ext (48-bit LBA) */ 57 #define ATA_CMD_CACHE_FLUSH 0xE7 /* Flush write cache */ 58 #define ATA_CMD_CACHE_FLUSH_EXT 0xEA /* Flush write cache ext */ 59 #define ATA_CMD_IDENTIFY 0xEC /* Identify drive */ 60 61 /* Drive selection */ 62 #define ATA_MASTER 0x00 63 #define ATA_SLAVE 0x01 64 65 /* Drive selection with LBA mode */ 66 #define ATA_DRIVE_LBA_MASTER 0xE0 /* 1110 0000: LBA mode, master */ 67 #define ATA_DRIVE_LBA_SLAVE 0xF0 /* 1111 0000: LBA mode, slave */ 68 69 /* Sector size */ 70 #define ATA_SECTOR_SIZE 512 71 72 /* Maximum timeout (in iterations) */ 73 #define ATA_TIMEOUT 100000 74 75 /* ATA Drive Information (from IDENTIFY command) */ 76 typedef struct { 77 uint8_t present; /* Drive detected */ 78 uint8_t is_ata; /* Is ATA device (not ATAPI) */ 79 uint8_t bus; /* 0 = primary, 1 = secondary */ 80 uint8_t drive; /* 0 = master, 1 = slave */ 81 uint32_t sectors; /* Total sectors (28-bit LBA) */ 82 uint64_t sectors_48; /* Total sectors (48-bit LBA) */ 83 uint8_t lba48_supported; /* 48-bit LBA supported */ 84 char model[41]; /* Model string */ 85 char serial[21]; /* Serial number */ 86 char firmware[9]; /* Firmware revision */ 87 } ata_drive_info_t; 88 89 /* Error codes */ 90 #define ATA_OK 0 91 #define ATA_ERR_NO_DRIVE -1 92 #define ATA_ERR_TIMEOUT -2 93 #define ATA_ERR_IO -3 94 #define ATA_ERR_INVALID -4 95 96 /* Function declarations */ 97 98 /** 99 * Initialize ATA driver and detect drives 100 * @return Number of drives detected 101 */ 102 int ata_init(void); 103 104 /** 105 * Get drive information 106 * @param bus 0 = primary, 1 = secondary 107 * @param drive 0 = master, 1 = slave 108 * @return Pointer to drive info, or NULL if not present 109 */ 110 ata_drive_info_t* ata_get_drive_info(uint8_t bus, uint8_t drive); 111 112 /** 113 * Read sectors from disk 114 * @param bus 0 = primary, 1 = secondary 115 * @param drive 0 = master, 1 = slave 116 * @param lba Starting sector (Logical Block Address) 117 * @param count Number of sectors to read (1-256, 0 means 256) 118 * @param buffer Output buffer (must be count * 512 bytes) 119 * @return ATA_OK on success, error code on failure 120 */ 121 int ata_read_sectors(uint8_t bus, uint8_t drive, uint32_t lba, uint8_t count, void* buffer); 122 123 /** 124 * Write sectors to disk 125 * @param bus 0 = primary, 1 = secondary 126 * @param drive 0 = master, 1 = slave 127 * @param lba Starting sector (Logical Block Address) 128 * @param count Number of sectors to write (1-256, 0 means 256) 129 * @param buffer Input buffer (must be count * 512 bytes) 130 * @return ATA_OK on success, error code on failure 131 */ 132 int ata_write_sectors(uint8_t bus, uint8_t drive, uint32_t lba, uint8_t count, const void* buffer); 133 134 /** 135 * Flush write cache 136 * @param bus 0 = primary, 1 = secondary 137 * @param drive 0 = master, 1 = slave 138 * @return ATA_OK on success, error code on failure 139 */ 140 int ata_flush(uint8_t bus, uint8_t drive); 141 142 /** 143 * Get last error string 144 * @return Human-readable error description 145 */ 146 const char* ata_get_error_string(int error); 147 148 /* Lua bindings */ 149 struct lua_State; 150 int luaopen_ata(struct lua_State* L); 151 152 #endif /* ATA_H */