Files
MentOS/mentos/inc/drivers/ata.h
T
2021-10-04 11:44:02 +02:00

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