/* * Copyright (c) 2012 Petr Jerman * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @file * Header for AHCI driver (AHCI 1.3 specification). */ #ifndef __AHCI_HW_H__ #define __AHCI_HW_H__ #include <stdint.h> /* * AHCI standard constants */ /** AHCI standard 1.3 - maximum ports. */ #define AHCI_MAX_PORTS 32 /* * AHCI PCI Registers */ /** AHCI PCI register Identifiers offset. */ #define AHCI_PCI_ID 0x00 /** AHCI PCI register Command offset. */ #define AHCI_PCI_CMD 0x04 /** AHCI PCI register Device Status offset. */ #define AHCI_PCI_STS 0x06 /** AHCI PCI register Revision ID offset. */ #define AHCI_PCI_RID 0x08 /** AHCI PCI register Class Codes offset. */ #define AHCI_PCI_CC 0x09 /** AHCI PCI register Cache Line Size offset. */ #define AHCI_PCI_CLS 0x0C /** AHCI PCI register Master Latency Timer offset. */ #define AHCI_PCI_MLT 0x0D /** AHCI PCI register Header Type offset. */ #define AHCI_PCI_HTYPE 0x0E /** AHCI PCI register Built In Self Test (Optional) offset. */ #define AHCI_PCI_BIST 0x0F /** AHCI PCI register Other Base Address Registres (Optional). */ #define AHCI_PCI_BAR0 0x10 /** AHCI PCI register Other Base Address Registres (Optional). */ #define AHCI_PCI_BAR1 0x14 /** AHCI PCI register Other Base Address Registres (Optional). */ #define AHCI_PCI_BAR2 0x18 /** AHCI PCI register Other Base Address Registres (Optional). */ #define AHCI_PCI_BAR3 0x1C /** AHCI PCI register Other Base Address Registres (Optional). */ #define AHCI_PCI_BAR4 0x20 /** AHCI PCI register AHCI Base Address offset. */ #define AHCI_PCI_ABAR 0x24 /** AHCI PCI register Subsystem Identifiers offset. */ #define AHCI_PCI_SS 0x2C /** AHCI PCI register Expansion ROM Base Address (Optional) offset. */ #define AHCI_PCI_EROM 0x30 /** AHCI PCI register Capabilities Pointer offset. */ #define AHCI_PCI_CAP 0x34 /** AHCI PCI register Interrupt Information offset. */ #define AHCI_PCI_INTR 0x3C /** AHCI PCI register Min Grant (Optional) offset. */ #define AHCI_PCI_MGNT 0x3E /** AHCI PCI register Max Latency (Optional) offset. */ #define AHCI_PCI_MLAT 0x3F /** AHCI PCI register Identifiers. */ typedef struct { /** Indicates the company vendor assigned by the PCI SIG. */ uint16_t vendorid; /** Indicates what device number assigned by the vendor */ uint16_t deviceid; } ahci_pcireg_id_t; /** AHCI PCI register Command. */ typedef union { struct { /** I/O Space Enable. */ unsigned int iose : 1; /** Memory Space Enable. */ unsigned int mse : 1; /** Bus Master Enable. */ unsigned int bme : 1; /** Special Cycle Enable. */ unsigned int sce : 1; /** Memory Write and Invalidate Enable. */ unsigned int mwie : 1; /** VGA Palette Snooping Enable. */ unsigned int vga : 1; /** Parity Error Response Enable. */ unsigned int pee : 1; /** Wait Cycle Enable. */ unsigned int wcc : 1; /** SERR# Enable. */ unsigned int see : 1; /** Fast Back-to-Back Enable. */ unsigned int fbe : 1; /** Interrupt Disable - disables the HBA from generating interrupts. * This bit does not have any effect on MSI operation. */ unsigned int id : 1; /** Reserved. */ unsigned int reserved : 5; }; uint16_t u16; } ahci_pcireg_cmd_t; /** AHCI PCI register Command - Interrupt Disable bit. */ #define AHCI_PCIREG_CMD_ID 0x0400 /** AHCI PCI register Command - Bus Master Enable bit. */ #define AHCI_PCIREG_CMD_BME 0x0004 /** AHCI PCI register Device status. */ typedef union { struct { /** Reserved. */ unsigned int reserved1 : 3; /** Indicate the interrupt status of the device (1 = asserted). */ unsigned int is : 1; /** Indicates presence of capatibility list. */ unsigned int cl : 1; /** 66 Mhz capable. */ unsigned int c66 : 1; /** Reserved. */ unsigned int reserved2 : 1; /** Fast back to back capable. */ unsigned int fbc : 1; /** Master data parity error detected. */ unsigned int dpd : 1; /** Device select timing. */ unsigned int devt : 2; /** Signaled target abort. */ unsigned int sta : 1; /** Received target abort. */ unsigned int rta : 1; /** Received master abort. */ unsigned int rma : 1; /** Signaled system error. */ unsigned int sse : 1; /** Detected parity error. */ unsigned int dpe : 1; }; uint16_t u16; } ahci_pcireg_sts_t; /** AHCI PCI register Revision ID. */ typedef struct { /** Indicates stepping of the HBA hardware. */ uint8_t u8; } ahci_pcireg_rid_t; /** AHCI PCI register Class Codes. */ typedef struct { /** Programing interface, when set to 01h and the scc is set to 06h, * indicates that this an AHCI HBA major revision 1. */ uint8_t pi; /** When set to 06h, indicates that is a SATA device. */ uint8_t scc; /** Value 01 indicates that is a mass storage device. */ uint8_t bcc; } ahci_pcireg_cc_t_t; /** AHCI PCI register Cache Line Size. */ typedef struct { /** Cache line size for use with the memory write and invalidate command. */ uint8_t u8; } ahci_pcireg_cls_t; /** AHCI PCI register Master Latency Timer. */ typedef struct { /** Master latency timer,indicates the number of clocks the HBA is allowed * to acts as master on PCI. */ uint8_t u8; } ahci_pcireg_mlt_t; /** AHCI PCI register Header Type. */ typedef union { struct { /** Header layout. */ unsigned int hl : 7; /** Multi function device flag. */ unsigned int mfd : 1; }; uint8_t u8; } ahci_pciregs_htype_t; /** AHCI PCI register Built in self test. */ typedef union { struct { /** Indicates the completion status of BIST * non-zero value indicates a failure. */ unsigned int cc : 4; /** Reserved. */ unsigned int reserved : 2; /** Software sets this bit to 1 to invoke BIST, * the HBA clears this bit to 0 when BIST is complete. */ unsigned int sb : 1; /** BIST capable. */ unsigned int bc : 1; }; uint8_t u8; } ahci_pciregs_bist_t; /** AHCI PCI register AHCI Base Address <BAR 5>. */ typedef union { struct { /** Indicates a request for register memory space. */ unsigned int rte : 1; /** Indicates the this range can be mapped anywhere in 32-bit address * space. */ unsigned int tp : 2; /** Indicate that this range is not prefetchable. */ unsigned int pf : 1; /** Reserved. */ unsigned int reserved : 9; /** Base address of registry memory space. */ unsigned int ba : 19; }; uint32_t u32; } ahci_pciregs_abar_t; /** AHCI PCI register Subsystem Identifiers. */ typedef struct { /** Sub system vendor identifier. */ uint8_t ssvid; /** Sub system identifier. */ uint8_t ssid; } ahci_pcireg_ss_t; /** AHCI PCI registers Expansion ROM Base Address. */ typedef struct { /** Indicates the base address of the HBA expansion ROM. */ uint32_t u32; } ahci_pcireg_erom_t; /** AHCI PCI register Capabilities Pointer. */ typedef struct { /** Indicates the first capability pointer offset. */ uint8_t u8; } ahci_pcireg_cap_t; /** AHCI PCI register Interrupt Information. */ typedef struct { /* * Software written value to indicate which interrupt vector * the interrupt is connected to. */ uint8_t iline; /** This indicates the interrupt pin the HBA uses. */ uint8_t ipin; } ahci_pcireg_intr; /** AHCI PCI register Min Grant (Optional). */ typedef struct { /** Indicates the minimum grant time that the device * wishes grant asserted. */ uint8_t u8; } ahci_pcireg_mgnt_t; /** AHCI PCI register Max Latency (Optional). */ typedef struct { /** Indicates the maximum latency that the device can withstand. */ uint8_t u8; } ahci_pcireg_mlat_t; /* * AHCI Memory Registers */ /** Number of pages for ahci memory registers. */ #define AHCI_MEMREGS_PAGES_COUNT 8 /** AHCI Memory register Generic Host Control - HBA Capabilities. */ typedef union { struct { /** Number of Ports. */ unsigned int np : 5; /** Supports External SATA. */ unsigned int sxs : 1; /** Enclosure Management Supported. */ unsigned int ems : 1; /** Command Completion Coalescing Supported. */ unsigned int cccs : 1; /** Number of Command Slots. */ unsigned int ncs : 5; /** Partial State Capable. */ unsigned int psc : 1; /** Slumber State Capable. */ unsigned int ssc : 1; /** PIO Multiple DRQ Block. */ unsigned int pmd : 1; /** FIS-based Switching Supported. */ unsigned int fbss : 1; /** Supports Port Multiplier. */ unsigned int spm : 1; /** Supports AHCI mode only. */ unsigned int sam : 1; /** Reserved. */ unsigned int reserved : 1; /** Interface Speed Support. */ unsigned int iss : 4; /** Supports Command List Override. */ unsigned int sclo : 1; /** Supports Activity LED. */ unsigned int sal : 1; /** Supports Aggressive Link Power Management. */ unsigned int salp : 1; /** Supports Staggered Spin-up. */ unsigned int sss : 1; /** Supports Mechanical Presence Switch. */ unsigned int smps : 1; /** Supports SNotification Register. */ unsigned int ssntf : 1; /** Supports Native Command Queuing. */ unsigned int sncq : 1; /** Supports 64-bit Addressing. */ unsigned int s64a : 1; }; uint32_t u32; } ahci_ghc_cap_t; /** AHCI Memory register Generic Host Control Global Host Control. */ typedef union { struct { /** HBA Reset. */ unsigned int hr : 1; /** Interrupt Enable. */ unsigned int ie : 1; /** MSI Revert to Single Message. */ unsigned int mrsm : 1; /** Reserved. */ unsigned int reserved : 28; /** AHCI Enable. */ unsigned int ae : 1; }; uint32_t u32; } ahci_ghc_ghc_t; /** AHCI Enable mask bit. */ #define AHCI_GHC_GHC_AE 0x80000000 /** AHCI Interrupt Enable mask bit. */ #define AHCI_GHC_GHC_IE 0x00000002 /** AHCI Memory register Interrupt pending register. */ typedef uint32_t ahci_ghc_is_t; /** AHCI GHC register offset. */ #define AHCI_GHC_IS_REGISTER_OFFSET 2 /** AHCI ports registers offset. */ #define AHCI_PORTS_REGISTERS_OFFSET 64 /** AHCI port registers size. */ #define AHCI_PORT_REGISTERS_SIZE 32 /** AHCI port IS register offset. */ #define AHCI_PORT_IS_REGISTER_OFFSET 4 /** AHCI Memory register Ports implemented. */ typedef struct { /** If a bit is set to 1, the corresponding port * is available for software use. */ uint32_t u32; } ahci_ghc_pi_t; /** AHCI Memory register AHCI version. */ typedef struct { /** Indicates the minor version */ uint16_t mnr; /** Indicates the major version */ uint16_t mjr; } ahci_ghc_vs_t; /** AHCI Memory register Command completion coalesce control. */ typedef union { struct { /** Enable CCC features. */ unsigned int en : 1; /** Reserved. */ unsigned int reserved : 2; /** Interrupt number for CCC. */ unsigned int intr : 5; /** Number of command completions that are necessary to cause * a CCC interrupt. */ uint8_t cc; /** Timeout value in ms. */ uint16_t tv; }; uint32_t u32; } ahci_ghc_ccc_ctl_t; /** AHCI Memory register Command completion coalescing ports. */ typedef struct { /** If a bit is set to 1, the corresponding port is * part of the command completion coalescing feature. */ uint32_t u32; } ahci_ghc_ccc_ports_t; /** AHCI Memory register Enclosure management location. */ typedef struct { /** Size of the transmit message buffer area in dwords. */ uint16_t sz; /* * Offset of the transmit message buffer area in dwords * from the beginning of ABAR */ uint16_t ofst; } ahci_ghc_em_loc; /** AHCI Memory register Enclosure management control. */ typedef union { struct { /** Message received. */ unsigned int mr : 1; /** Reserved. */ unsigned int reserved : 7; /** Transmit message. */ unsigned int tm : 1; /** Reset. */ unsigned int rst : 1; /** Reserved. */ unsigned int reserved2 : 6; /** LED message types. */ unsigned int led : 1; /** Support SAFT-TE message type. */ unsigned int safte : 1; /** Support SES-2 message type. */ unsigned int ses2 : 1; /** Support SGPIO register. */ unsigned int sgpio : 1; /** Reserved. */ unsigned int reserved3 : 4; /** Single message buffer. */ unsigned int smb : 1; /** Support transmitting only. */ unsigned int xmt : 1; /** Activity LED hardware driven. */ unsigned int alhd : 1; /** Port multiplier support. */ unsigned int pm : 1; /** Reserved. */ unsigned int reserved4 : 4; }; uint32_t u32; } ahci_ghc_em_ctl_t; /** AHCI Memory register HBA capatibilities extended. */ typedef union { struct { /** HBA support BIOS/OS handoff mechanism, * implemented BOHC register. */ unsigned int boh : 1; /** Support for NVMHCI register. */ unsigned int nvmp : 1; /** Automatic partial to slumber transition support. */ unsigned int apst : 1; /** Reserved. */ unsigned int reserved : 29; }; uint32_t u32; } ahci_ghc_cap2_t; /** AHCI Memory register BIOS/OS Handoff control and status. */ typedef union { struct { /** BIOS Owned semaphore. */ unsigned int bos : 1; /** OS Owned semaphore. */ unsigned int oos : 1; /** SMI on OS ownership change enable. */ unsigned int sooe : 1; /** OS ownership change. */ unsigned int ooc : 1; /** BIOS Busy. */ unsigned int bb : 1; /** Reserved. */ unsigned int reserved : 27; }; uint32_t u32; } ahci_ghc_bohc_t; /** AHCI Memory register Generic Host Control. */ typedef struct { /** Host Capabilities */ uint32_t cap; /** Global Host Control */ uint32_t ghc; /** Interrupt Status */ ahci_ghc_is_t is; /** Ports Implemented */ uint32_t pi; /** Version */ uint32_t vs; /** Command Completion Coalescing Control */ uint32_t ccc_ctl; /** Command Completion Coalescing Ports */ uint32_t ccc_ports; /** Enclosure Management Location */ uint32_t em_loc; /** Enclosure Management Control */ uint32_t em_ctl; /** Host Capabilities Extended */ uint32_t cap2; /** BIOS/OS Handoff Control and Status */ uint32_t bohc; } ahci_ghc_t; /** AHCI Memory register Port x Command List Base Address. */ typedef union { struct { /** Reserved. */ unsigned int reserved : 10; /** Command List Base Address (CLB) - Indicates the 32-bit base physical * address for the command list for this port. This base is used when * fetching commands to execute. The structure pointed to by this * address range is 1K-bytes in length. This address must be 1K-byte * aligned as indicated by bits 09:00 being read only. */ unsigned int clb : 22; }; uint32_t u32; } ahci_port_clb_t; /** AHCI Memory register Port x Command List Base Address Upper 32-Bits. */ typedef struct { /** Command List Base Address Upper (CLBU): Indicates the upper 32-bits * for the command list base physical address for this port. This base * is used when fetching commands to execute. This register shall * be read only for HBAs that do not support 64-bit addressing. */ uint32_t u32; } ahci_port_clbu_t; /** AHCI Memory register Port x FIS Base Address. */ typedef union { struct { /** Reserved. */ unsigned int reserved : 8; /** FIS Base Address (FB) - Indicates the 32-bit base physical address * for received FISes. The structure pointed to by this address range * is 256 bytes in length. This address must be 256-byte aligned as * indicated by bits 07:00 being read only. When FIS-based switching * is in use, this structure is 4KB in length and the address shall be * 4KB aligned. */ unsigned int fb : 24; }; uint32_t u32; } ahci_port_fb_t; /** AHCI Memory register Port x FIS Base Address Upper 32-Bits. */ typedef struct { /** FIS Base Address Upper (FBU) - Indicates the upper 32-bits * for the received FIS base physical address for this port. This register * shall be read only for HBAs that do not support 64-bit addressing. */ uint32_t u32; } ahci_port_fbu_t; /** AHCI Memory register Port x Interrupt Status. */ typedef uint32_t ahci_port_is_t; #define AHCI_PORT_IS_DHRS (1 << 0) #define AHCI_PORT_IS_PSS (1 << 1) #define AHCI_PORT_IS_DSS (1 << 2) #define AHCI_PORT_IS_SDBS (1 << 3) #define AHCI_PORT_IS_UFS (1 << 4) #define AHCI_PORT_IS_DPS (1 << 5) #define AHCI_PORT_IS_PCS (1 << 6) #define AHCI_PORT_IS_DMPS (1 << 7) #define AHCI_PORT_IS_PRCS (1 << 22) #define AHCI_PORT_IS_IPMS (1 << 23) #define AHCI_PORT_IS_OFS (1 << 24) #define AHCI_PORT_IS_INFS (1 << 26) #define AHCI_PORT_IS_IFS (1 << 27) #define AHCI_PORT_IS_HDBS (1 << 28) #define AHCI_PORT_IS_HBFS (1 << 29) #define AHCI_PORT_IS_TFES (1 << 30) #define AHCI_PORT_IS_CPDS (1 << 31) #define AHCI_PORT_END_OF_OPERATION \ (AHCI_PORT_IS_DHRS | \ AHCI_PORT_IS_SDBS ) #define AHCI_PORT_IS_ERROR \ (AHCI_PORT_IS_UFS | \ AHCI_PORT_IS_PCS | \ AHCI_PORT_IS_DMPS | \ AHCI_PORT_IS_PRCS | \ AHCI_PORT_IS_IPMS | \ AHCI_PORT_IS_OFS | \ AHCI_PORT_IS_INFS | \ AHCI_PORT_IS_IFS | \ AHCI_PORT_IS_HDBS | \ AHCI_PORT_IS_HBFS | \ AHCI_PORT_IS_TFES | \ AHCI_PORT_IS_CPDS) #define AHCI_PORT_IS_PERMANENT_ERROR \ (AHCI_PORT_IS_PCS | \ AHCI_PORT_IS_DMPS | \ AHCI_PORT_IS_PRCS | \ AHCI_PORT_IS_IPMS | \ AHCI_PORT_IS_CPDS ) /** Evaluate end of operation status from port interrupt status. * * @param port_is Value of port interrupt status. * * @return Indicate end of operation status. * */ static inline int ahci_port_is_end_of_operation(ahci_port_is_t port_is) { return port_is & AHCI_PORT_END_OF_OPERATION; } /** Evaluate error status from port interrupt status. * * @param port_is Value of port interrupt status. * * @return Indicate error status. * */ static inline int ahci_port_is_error(ahci_port_is_t port_is) { return port_is & AHCI_PORT_IS_ERROR; } /** Evaluate permanent error status from port interrupt status. * * @param port_is Value of port interrupt status. * * @return Indicate permanent error status. * */ static inline int ahci_port_is_permanent_error(ahci_port_is_t port_is) { return port_is & AHCI_PORT_IS_PERMANENT_ERROR; } /** Evaluate task file error status from port interrupt status. * * @param port_is Value of port interrupt status. * * @return Indicate error status. * */ static inline int ahci_port_is_tfes(ahci_port_is_t port_is) { return port_is & AHCI_PORT_IS_TFES; } /** AHCI Memory register Port x Interrupt Enable. */ typedef union { struct { /** Device to Host Register FIS Interrupt Enable. */ unsigned int dhre : 1; /** PIO Setup FIS Interrupt Enable. */ unsigned int pse : 1; /** DMA Setup FIS Interrupt Enable. */ unsigned int dse : 1; /** Set Device Bits Interrupt Eenable. */ unsigned int sdbe : 1; /** Unknown FIS Interrupt Enable. */ unsigned int ufe : 1; /** Descriptor Processed Interrupt Enable. */ unsigned int dpe : 1; /** Port Change Interrupt Enable. */ unsigned int pce : 1; /** Device Mechanical Presence Enable. */ unsigned int dmpe : 1; /** Reserved. */ unsigned int reserved1 : 14; /** PhyRdy Change Interrupt Enable. */ unsigned int prce : 1; /** Incorrect Port Multiplier Enable. */ unsigned int ipme : 1; /** Overflow Status Enable. */ unsigned int ofe : 1; /** Reserved. */ unsigned int reserved2 : 1; /** Interface Non-fatal Error Enable. */ unsigned int infe : 1; /** Interface Fatal Error Enable. */ unsigned int ife : 1; /** Host Bus Data Error Enable. */ unsigned int hbde : 1; /** Host Bus Fatal Error Enable. */ unsigned int hbfe : 1; /** Task File Error Enable. */ unsigned int tfee : 1; /** Cold Port Detect Enable. */ unsigned int cpde : 1; }; uint32_t u32; } ahci_port_ie_t; /** AHCI Memory register Port x Command and Status. */ typedef union { struct { /** Start - when set, the HBA may process the command list. */ unsigned int st : 1; /** Spin-Up Device. */ unsigned int sud : 1; /** Power On Device. */ unsigned int pod : 1; /** Command List Override. */ unsigned int clo : 1; /** FIS Receive Enable. */ unsigned int fre : 1; /** Reserved. */ unsigned int reserved : 3; /** Current Command Slot. */ unsigned int ccs : 5; /** Mechanical Presence Switch State. */ unsigned int mpss : 1; /** FIS Receive Running. */ unsigned int fr : 1; /** Command List Running. */ unsigned int cr : 1; /** Cold Presence State. */ unsigned int cps : 1; /** Port Multiplier Attached. */ unsigned int pma : 1; /** Hot Plug Capable Port. */ unsigned int hpcp : 1; /** Mechanical Presence Switch Attached to Port. */ unsigned int mpsp : 1; /** Cold Presence Detection. */ unsigned int cpd : 1; /** External SATA Port. */ unsigned int esp : 1; /** FIS-based Switching Capable Port. */ unsigned int fbscp : 1; /** Automatic Partial to Slumber Transitions Enabled. */ unsigned int apste : 1; /** Device is ATAPI. */ unsigned int atapi : 1; /** Drive LED on ATAPI Enable. */ unsigned int dlae : 1; /** Aggressive Link Power Management Enable. */ unsigned int alpe : 1; /** Aggressive Slumber / Partial. */ unsigned int asp : 1; /** Interface Communication Control. * Values: * 7h - fh Reserved, * 6h Slumber - This shall cause the HBA to request a transition * of the interface to the Slumber state, * 3h - 5h Reserved, * 2h Partial - This shall cause the HBA to request a transition * of the interface to the Partial state, * 1h Active, * 0h No-Op / Idle. */ unsigned int icc : 4; }; uint32_t u32; } ahci_port_cmd_t; /** AHCI Memory register Port x Task File Data. */ typedef union { struct { /** Status (STS): Contains the latest copy of the task file * status register. */ uint8_t sts; /** Error (ERR) - Contains the latest copy of the task file * error register. */ uint8_t err; /** Reserved. */ uint16_t reserved; }; uint32_t u32; } ahci_port_tfd_t; /** AHCI Memory register Port x Signature. */ typedef union { struct { /** Sector Count Register */ uint8_t sector_count; /** LBA Low Register */ uint8_t lba_lr; /** LBA Mid Register */ uint8_t lba_mr; /** LBA High Register */ uint8_t lba_hr; }; uint32_t u32; } ahci_port_sig_t; /** AHCI Memory register Port x Serial ATA Status (SCR0: SStatus). */ typedef union { struct { /** Device Detection */ unsigned int det : 4; /** Current Interface Speed */ unsigned int spd : 4; /** Interface Power Management */ unsigned int ipm : 4; /** Reserved. */ unsigned int reserved : 20; }; uint32_t u32; } ahci_port_ssts_t; /** Device detection active status. */ #define AHCI_PORT_SSTS_DET_ACTIVE 3 /** AHCI Memory register Port x Serial ATA Control (SCR2: SControl). */ typedef union { struct { /** Device Detection Initialization */ unsigned int det : 4; /** Speed Allowed */ unsigned int spd : 4; /** Interface Power Management Transitions Allowed */ unsigned int ipm : 4; /** Reserved. */ unsigned int reserved : 20; }; uint32_t u32; } ahci_port_sctl_t; /** AHCI Memory register Port x Port x Serial ATA Error (SCR1: SError). */ typedef struct { /** Error (ERR) - The ERR field contains error information for use * by host software in determining the appropriate response to the * error condition. */ uint16_t err; /** Diagnostics (DIAG) - Contains diagnostic error information for use * by diagnostic software in validating correct operation or isolating * failure modes. */ uint16_t diag; } ahci_port_serr_t; /** AHCI Memory register Port x Serial ATA Active (SCR3: SActive). */ typedef struct { /** Device Status - Each bit corresponds to the TAG and * command slot of a native queued command, where bit 0 corresponds * to TAG 0 and command slot 0. */ uint32_t u32; } ahci_port_sact_t; /** AHCI Memory register Port x Command Issue. */ typedef struct { /** Commands Issued - Each bit corresponds to a command slot, * where bit 0 corresponds to command slot 0. */ uint32_t u32; } ahci_port_ci_t; /** AHCI Memory register Port x Serial ATA Notification * (SCR4: SNotification). */ typedef struct { /** PM Notify (PMN): This field indicates whether a particular device with * the corresponding PM Port number issued a Set Device Bits FIS * to the host with the Notification bit set. */ uint16_t pmn; /** Reserved. */ uint16_t reserved; } ahci_port_sntf_t; /** AHCI Memory register Port x FIS-based Switching Control. * This register is used to control and obtain status * for Port Multiplier FIS-based switching. */ typedef union { struct { /** Enable */ unsigned int en : 1; /** Device Error Clear */ unsigned int dec : 1; /** Single Device Error */ unsigned int sde : 1; /** Reserved. */ unsigned int reserved1 : 5; /** Device To Issue */ unsigned int dev : 1; /** Active Device Optimization */ unsigned int ado : 1; /** Device With Error */ unsigned int dwe : 1; /** Reserved. */ unsigned int reserved2 : 1; }; uint32_t u32; } ahci_port_fbs_t; /** AHCI Memory register Port. */ typedef volatile struct { /** Port x Command List Base Address. */ uint32_t pxclb; /** Port x Command List Base Address Upper 32-Bits. */ uint32_t pxclbu; /** Port x FIS Base Address. */ uint32_t pxfb; /** Port x FIS Base Address Upper 32-Bits. */ uint32_t pxfbu; /** Port x Interrupt Status. */ ahci_port_is_t pxis; /** Port x Interrupt Enable. */ uint32_t pxie; /** Port x Command and Status. */ uint32_t pxcmd; /** Reserved. */ uint32_t reserved1; /** Port x Task File Data. */ uint32_t pxtfd; /** Port x Signature. */ uint32_t pxsig; /** Port x Serial ATA Status (SCR0: SStatus). */ uint32_t pxssts; /** Port x Serial ATA Control (SCR2: SControl). */ uint32_t pxsctl; /** Port x Serial ATA Error (SCR1: SError). */ uint32_t pxserr; /** Port x Serial ATA Active (SCR3: SActive). */ uint32_t pxsact; /** Port x Command Issue. */ uint32_t pxci; /** Port x Serial ATA Notification (SCR4: SNotification). */ uint32_t pxsntf; /** Port x FIS-based Switching Control. */ uint32_t pxfbs; /** Reserved. */ uint32_t reserved2[11]; /** Port x Vendor Specific. */ uint32_t pxvs[4]; } ahci_port_t; /** AHCI Memory Registers. */ typedef volatile struct { /** Generic Host Control. */ ahci_ghc_t ghc; /** Reserved. */ uint32_t reserved[13]; /** Reserved for NVMHCI. */ uint32_t reservedfornvmhci[16]; /** Vendor Specific registers. */ uint32_t vendorspecificsregs[24]; /** Ports. */ ahci_port_t ports[AHCI_MAX_PORTS]; } ahci_memregs_t; /** AHCI Command header entry. * * This structure is not an AHCI register. * */ typedef volatile struct { /** Flags. */ uint16_t flags; /** Physical Region Descriptor Table Length. */ uint16_t prdtl; /** Physical Region Descriptor Byte Count. */ uint32_t bytesprocessed; /** Command Table Descriptor Base Address. */ uint32_t cmdtable; /** Command Table Descriptor Base Address Upper 32-bits. */ uint32_t cmdtableu; } ahci_cmdhdr_t; /** Clear Busy upon R_OK (C) flag. */ #define AHCI_CMDHDR_FLAGS_CLEAR_BUSY_UPON_OK 0x0400 /** Write operation flag. */ #define AHCI_CMDHDR_FLAGS_WRITE 0x0040 /** 2 DW length command flag. */ #define AHCI_CMDHDR_FLAGS_2DWCMD 0x0002 /** 5 DW length command flag. */ #define AHCI_CMDHDR_FLAGS_5DWCMD 0x0005 /** AHCI Command Physical Region Descriptor entry. * * This structure is not an AHCI register. * */ typedef volatile struct { /** Word aligned 32-bit data base address. */ uint32_t data_address_low; /** Upper data base address, valid only for 64-bit HBA addressing. */ uint32_t data_address_upper; /** Reserved. */ uint32_t reserved1; /** Data byte count */ unsigned int dbc : 22; /** Reserved */ unsigned int reserved2 : 9; /** Set Interrupt on each operation completion */ unsigned int ioc : 1; } ahci_cmd_prdt_t; #endif