205 lines
6.5 KiB
C
205 lines
6.5 KiB
C
/// MentOS, The Mentoring Operating system project
|
|
/// @file ata.h
|
|
/// @brief ATA values and data structures.
|
|
/// @details
|
|
/// IDE is a keyword which refers to the electrical specification of the cables
|
|
/// which connect ATA drives (like hard drives) to another device. The drives
|
|
/// use the ATA (Advanced Technology Attachment) interface. An IDE cable also
|
|
/// can terminate at an IDE card connected to PCI.
|
|
/// ATAPI is an extension to ATA (recently renamed to PATA) which adds support
|
|
/// for the SCSI command set.
|
|
/// @copyright (c) 2014-2021 This file is distributed under the MIT License.
|
|
/// See LICENSE.md for details.
|
|
///! @cond Doxygen_Suppress
|
|
|
|
#pragma once
|
|
|
|
#include "stdint.h"
|
|
|
|
/// @defgroup ata_defines The ATA configuration registers.
|
|
/// @{
|
|
|
|
/// @defgroup status_register Status register bits.
|
|
/// @{
|
|
|
|
#define ATA_STAT_BUSY 0x80 /// Device Busy
|
|
#define ATA_STAT_READY 0x40 ///< Device Ready
|
|
#define ATA_STAT_FAULT 0x20 ///< Device Fault
|
|
#define ATA_STAT_SEEK 0x10 ///< Device Seek Complete
|
|
#define ATA_STAT_DRQ 0x08 ///< Data Request (ready)
|
|
#define ATA_STAT_CORR 0x04 ///< Corrected Data Error
|
|
#define ATA_STAT_INDEX 0x02 ///< Vendor specific
|
|
#define ATA_STAT_ERR 0x01 ///< Error
|
|
|
|
///< @}
|
|
|
|
/// @defgroup ata_commands ATA Commands
|
|
/// @{
|
|
|
|
#define ATA_CMD_READ 0x20 ///< Read Sectors (with retries)
|
|
#define ATA_CMD_READN 0x21 ///< Read Sectors (no retries)
|
|
#define ATA_CMD_WRITE 0x30 ///< Write Sectores (with retries)
|
|
#define ATA_CMD_WRITEN 0x31 ///< Write Sectors (no retries)
|
|
#define ATA_CMD_VRFY 0x40 ///< Read Verify (with retries)
|
|
#define ATA_CMD_VRFYN 0x41 ///< Read verify (no retries)
|
|
#define ATA_CMD_SEEK 0x70 ///< Seek
|
|
#define ATA_CMD_DIAG 0x90 ///< Execute Device Diagnostic
|
|
#define ATA_CMD_INIT 0x91 ///< Initialize Device Parameters
|
|
#define ATA_CMD_RD_MULT 0xC4 ///< Read Multiple
|
|
#define ATA_CMD_WR_MULT 0xC5 ///< Write Multiple
|
|
#define ATA_CMD_SETMULT 0xC6 ///< Set Multiple Mode
|
|
#define ATA_CMD_RD_DMA 0xC8 ///< Read DMA (with retries)
|
|
#define ATA_CMD_RD_DMAN 0xC9 ///< Read DMS (no retries)
|
|
#define ATA_CMD_WR_DMA 0xCA ///< Write DMA (with retries)
|
|
#define ATA_CMD_WR_DMAN 0xCB ///< Write DMA (no retires)
|
|
#define ATA_CMD_IDENT 0xEC ///< Identify Device
|
|
#define ATA_CMD_CH_FLSH 0xE7 ///< Cache flush.
|
|
#define ATA_CMD_SETF 0xEF ///< Set Features
|
|
#define ATA_CMD_CHK_PWR 0xE5 ///< Check Power Mode
|
|
|
|
///< @}
|
|
|
|
/// @defgroup atapi_commands ATAPI Commands
|
|
/// @{
|
|
|
|
#define ATAPI_CMD_PACKET 0xA0
|
|
#define ATAPI_CMD_ID_PCKT 0xA1
|
|
|
|
/// @}
|
|
|
|
/// @defgroup ata_ident_brits Identification Space Bits
|
|
/// @brief Definitions used to read information from the identification space.
|
|
/// @{
|
|
|
|
#define ATA_IDENT_DEVICETYPE 0
|
|
#define ATA_IDENT_CYLINDERS 2
|
|
#define ATA_IDENT_HEADS 6
|
|
#define ATA_IDENT_SECTORS 12
|
|
#define ATA_IDENT_SERIAL 20
|
|
#define ATA_IDENT_MODEL 54
|
|
#define ATA_IDENT_CAPABILITIES 98
|
|
#define ATA_IDENT_FIELDVALID 106
|
|
#define ATA_IDENT_MAX_LBA 120
|
|
#define ATA_IDENT_COMMANDSETS 164
|
|
#define ATA_IDENT_MAX_LBA_EXT 200
|
|
|
|
/// @}
|
|
|
|
/// @defgroup ata_interface Interface Type
|
|
/// @{
|
|
|
|
#define IDE_ATA 0x00 ///< ATA (Advanced Technology Attachment) interface.
|
|
#define IDE_ATAPI 0x01 ///< Extended ATA with support for SCSI command set.
|
|
|
|
/// @}
|
|
|
|
/// @defgroup ata_priority Interface Priority
|
|
/// @{
|
|
|
|
#define ATA_DEVICE_0 0x00
|
|
#define ATA_DEVICE_1 0x01
|
|
|
|
/// @}
|
|
|
|
/// @defgroup ata_command_block_registers Command block registers
|
|
/// @{
|
|
|
|
#define ATA_REG_DATA 0x00 ///< Read/Write PIO data bytes.
|
|
#define ATA_REG_ERROR 0x01 ///< Error generated by the last ATA command.
|
|
#define ATA_REG_FEATURES 0x01 ///< Control command specific interface features.
|
|
#define ATA_REG_SECCOUNT0 0x02 ///< Number of sectors to read/write (0 is a special value).
|
|
#define ATA_REG_LBA0 0x03 ///< Sector Number Register.
|
|
#define ATA_REG_LBA1 0x04 ///< Cylinder Low Register.
|
|
#define ATA_REG_LBA2 0x05 ///< Cylinder High Register.
|
|
#define ATA_REG_HDDEVSEL 0x06 ///< Used to select a drive and/or head.
|
|
#define ATA_REG_COMMAND 0x07 ///< Used to send ATA commands to the device.
|
|
#define ATA_REG_STATUS 0x07 ///< Used to read the current status.
|
|
#define ATA_REG_SECCOUNT1 0x08 ///<
|
|
#define ATA_REG_LBA3 0x09 ///<
|
|
#define ATA_REG_LBA4 0x0A ///<
|
|
#define ATA_REG_LBA5 0x0B ///<
|
|
#define ATA_REG_CONTROL 0x0C ///<
|
|
#define ATA_REG_ALTSTATUS 0x0C ///<
|
|
#define ATA_REG_DEVADDRESS 0x0D ///<
|
|
|
|
/// @}
|
|
|
|
/// @defgroup ata_channels Channels
|
|
/// @{
|
|
|
|
#define ATA_PRIMARY 0x00 ///< Primary channel.
|
|
#define ATA_SECONDARY 0x01 ///< Secondary channel.
|
|
/// @}
|
|
|
|
/// @defgroup ata_directions Directions
|
|
/// @{
|
|
|
|
#define ATA_READ 0x00 ///< Read direction.
|
|
#define ATA_WRITE 0x01 ///< Write direction.
|
|
|
|
/// @}
|
|
/// @}
|
|
|
|
/// @brief Stores information of a channel.
|
|
typedef struct ide_channel_regs_t{
|
|
uint16_t base; ///< I/O Base.
|
|
uint16_t ctrl; ///< Control Base
|
|
uint16_t bmide; ///< Bus Master IDE
|
|
uint16_t nien; ///< nIEN (No Interrupt);
|
|
} ide_channel_regs_t;
|
|
|
|
/// @brief Stores information of a device.
|
|
typedef struct ide_device_t{
|
|
uint8_t reserved; ///< 0 (Empty) or 1 (This Drive really exists).
|
|
uint8_t channel; ///< 0 (Primary Channel) or 1 (Secondary Channel).
|
|
uint8_t drive; ///< 0 (Drive 0) or 1 (Drive 1).
|
|
uint16_t type; ///< 0: ATA, 1:ATAPI.
|
|
uint16_t signature; ///< Drive Signature.
|
|
uint16_t capabilities; ///< Features.
|
|
uint32_t command_sets; ///< Command Sets Supported.
|
|
uint32_t size; ///< Size in Sectors.
|
|
uint8_t model[41]; ///< Model in string.
|
|
} ide_device_t;
|
|
|
|
/// @brief
|
|
typedef struct partition_t{
|
|
uint8_t status; ///<
|
|
uint8_t chs_first_sector[3]; ///<
|
|
uint8_t type; ///<
|
|
uint8_t chs_last_sector[3]; ///<
|
|
uint32_t lba_first_sector; ///<
|
|
uint32_t sector_count; ///<
|
|
} partition_t;
|
|
|
|
typedef struct ata_identify_t{
|
|
uint16_t flags;
|
|
uint16_t unused1[9];
|
|
char serial[20];
|
|
uint16_t unused2[3];
|
|
char firmware[8];
|
|
char model[40];
|
|
uint16_t sectors_per_int;
|
|
uint16_t unused3;
|
|
uint16_t capabilities[2];
|
|
uint16_t unused4[2];
|
|
uint16_t valid_ext_data;
|
|
uint16_t unused5[5];
|
|
uint16_t size_of_rw_mult;
|
|
uint32_t sectors_28;
|
|
uint16_t unused6[38];
|
|
uint64_t sectors_48;
|
|
uint16_t unused7[152];
|
|
} __attribute__((packed)) ata_identify_t;
|
|
|
|
/// @brief Master Boot Record.
|
|
typedef struct mbr_t{
|
|
uint8_t boostrap[446];
|
|
partition_t partitions[4];
|
|
uint8_t signature[2];
|
|
} __attribute__((packed)) mbr_t;
|
|
|
|
int ata_initialize();
|
|
|
|
int ata_finalize();
|
|
|
|
///! @endcond
|