ahcireg.h revision 2fcbc377041d659446ded306a92901b4b0753b68
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _AHCIREG_H
#define _AHCIREG_H
#pragma ident "%Z%%M% %I% %E% SMI"
#ifdef __cplusplus
extern "C" {
#endif
#define AHCI_MAX_PORTS 32
#define AHCI_PORT_MAX_CMD_SLOTS 32
#define VIA_VENID 0x1106
/*
* In AHCI spec, command table contains a list of 0 (no data transfer)
*/
#define AHCI_MAX_PRDT_NUMBER 65535
#define AHCI_MIN_PRDT_NUMBER 1
/*
* if misaligned, and it's tuable by setting ahci_dma_prdt_number in
*/
#define AHCI_PRDT_NUMBER 257
/* AHCI base address */
/* various global HBA capability bits */
/* various global HBA control bits */
/* various global HBA Command Completion Coalescing (CCC) control bits */
#define AHCI_HBA_CCC_CTL_INT_SHIFT 3
#define AHCI_HBA_CCC_CTL_CC_SHIFT 8
#define AHCI_HBA_CCC_CTL_TV_SHIFT 16
/* global HBA Enclosure Management Location (EM_LOC) */
#define AHCI_HBA_EM_LOC_OFST_SHIFT 16
/* global HBA Enclosure Management Control (EM_CTL) bits */
/* global HBA registers definitions */
/* HBA Capabilities */
/* Global HBA Control */
/* Interrupt Status Register */
/* Ports Implemented */
/* AHCI Version */
/* Command Completion Coalescing Control */
/* Command Completion Coalescing Ports */
#define AHCI_GLOBAL_CCC_PORTS(ahci_ctlp) \
/* Enclosure Management Location */
/* Enclosure Management Control */
/* various port interrupt bits */
/* Device to Host Register FIS Interrupt */
#define AHCI_INTR_STATUS_DHRS (0x1 << 0)
/* PIO Setup FIS Interrupt */
/* DMA Setup FIS Interrupt */
/* Set Device Bits Interrupt */
/* Unknown FIS Interrupt */
/* Descriptor Processed */
/* Port Connect Change Status */
/* Device Mechanical Presence Status */
/* PhyRdy Change Status */
/* Incorrect Port Multiplier Status */
/* Overflow Status */
/* Interface Non-fatal Error Status */
/* Interface Fatal Error Status */
/* Host Bus Data Error Status */
/* Host Bus Fatal Error Status */
/* Task File Error Status */
/* Cold Port Detect Status */
#define AHCI_PORT_INTR_MASK 0xfec000ff
/* port command and status bits */
/* Mechanical presence switch state */
/* Mechanical presence switch attached to port */
/* Aggressive link power magament enable */
/* Interface communication control */
#define AHCI_CMD_STATUS_CCS_SHIFT 8
#define AHCI_CMD_STATUS_ICC_SHIFT 28
/* port task file data bits */
#define AHCI_TFD_STS_MASK 0x000000ff
#define AHCI_TFD_ERR_MASK 0x0000ff00
#define AHCI_TFD_STS_ERR (0x1 << 0)
#define AHCI_TFD_ERR_SHIFT 8
/* port SATA status bit fields */
#define AHCI_SSTATUS_DET_MASK 0x0000000f
#define AHCI_SSTATUS_SPD_MASK 0x000000f0
#define AHCI_SSTATUS_IPM_MASK 0x00000f00
#define AHCI_SSTATUS_SPD_SHIFT 4
#define AHCI_SSTATUS_IPM_SHIFT 8
#define AHCI_SSTATUS_GET_DET(x) (x & AHCI_SSTATUS_DET_MASK)
#define AHCI_SSTATUS_SET_DET(x, new_val) \
#define AHCI_SSTATUS_GET_IPM(x) \
((x & AHCI_SSTATUS_IPM_MASK) >> AHCI_SSTATUS_IPM_SHIFT)
/* port SATA control bit fields */
#define AHCI_SCONTROL_DET_MASK 0x0000000f
#define AHCI_SCONTROL_GET_DET(x) (x & AHCI_SCONTROL_DET_MASK)
#define AHCI_SCONTROL_SET_DET(x, new_val) \
/* port SATA error bit fields */
/* Recovered Data Integrity Error */
#define AHCI_SERROR_ERR_I (0x1 << 0)
/* Recovered Communications Error */
/* Transient Data Integrity Error */
/* Persistent Communication or Data Integrity Error */
/* Protocol Error */
/* Internal Error */
/* PhyRdy Change */
/* Phy Internal Error */
/* Comm Wake */
/* 10B to 8B Decode Error */
/* Disparity Error */
/* CRC Error */
/* Handshake Error */
/* Link Sequence Error */
/* Transport State Transion Error */
/* Unknown FIS Type */
/* Exchanged */
#define AHCI_SERROR_CLEAR_ALL 0xffffffff
/* per port registers offset */
/* Command List Base Address */
/* Command List Base Address Upper 32-Bits */
/* FIS Base Address */
/* FIS Base Address Upper 32-Bits */
/* Interrupt Status */
/* Interrupt Enable */
/* Command and Status */
/* Task File Data */
/* Signature */
/* Serial ATA Status (SCR0:SStatus) */
/* Serial ATA Control (SCR2:SControl) */
/* Serial ATA Error (SCR1:SError) */
/* Serial ATA Active (SCR3:SActive) */
/* Command Issue */
/* SNotification */
#define AHCI_SLOT_MASK(ahci_ctlp) \
/* Device signatures */
#define AHCI_SIGNATURE_PORT_MULTIPLIER 0x96690101
#define AHCI_SIGNATURE_ATAPI 0xeb140101
#define AHCI_SIGNATURE_DISK 0x00000101
#define AHCI_SIGNATURE_NONE 0xffffffff
/*
* The address of the control port for the port multiplier, which is
* used for control and status communication with the port multiplier
* itself.
*/
#define AHCI_PORTMULT_CONTROL_PORT 0x0f
#define AHCI_H2D_REGISTER_FIS_TYPE 0x27
#define AHCI_H2D_REGISTER_FIS_LENGTH 5
/* Register - Host to Device FIS (from SATA spec) */
typedef struct ahci_fis_h2d_register {
/* offset 0x00 */
#define GET_FIS_COMMAND(fis) \
#define GET_FIS_FEATURES(fis) \
/* offset 0x04 */
#define GET_FIS_SECTOR(fis) \
#define GET_FIS_CYL_LOW(fis) \
#define GET_FIS_CYL_HI(fis) \
#define GET_FIS_DEV_HEAD(fis) \
/* offset 0x08 */
#define GET_FIS_SECTOR_EXP(fis) \
((sectorexp & 0xff)))
#define GET_FIS_CYL_LOW_EXP(fis) \
#define GET_FIS_CYL_HI_EXP(fis) \
/* offset 0x0c */
#define GET_FIS_SECTOR_COUNT(fis) \
((sector_count & 0xff)))
#define GET_FIS_SECTOR_COUNT_EXP(fis) \
/* offset 0x10 */
/* Register - Device to Host FIS (from SATA spec) */
typedef struct ahci_fis_d2h_register {
/* offset 0x00 */
#define GET_RFIS_STATUS(fis) \
#define GET_RFIS_ERROR(fis) \
/* offset 0x04 */
#define GET_RFIS_CYL_LOW(fis) \
#define GET_RFIS_CYL_MID(fis) \
#define GET_RFIS_CYL_HI(fis) \
#define GET_RFIS_DEV_HEAD(fis) \
/* offset 0x08 */
#define GET_RFIS_CYL_LOW_EXP(fis) \
#define GET_RFIS_CYL_MID_EXP(fis) \
#define GET_RFIS_CYL_HI_EXP(fis) \
/* offset 0x0c */
#define GET_RFIS_SECTOR_COUNT(fis) \
#define GET_RFIS_SECTOR_COUNT_EXP(fis) \
/* offset 0x10 */
/* Set Device Bits - Device to Host FIS (from SATA spec) */
typedef struct ahci_fis_set_device_bits {
/* offset 0x00 */
/* offset 0x04 */
/* DMA Setup - Device to Host or Host to Device (from SATA spec) */
typedef struct ahci_fis_dma_setup {
/* offset 0x00 */
/* offset 0x04 */
/* offset 0x08 */
/* offset 0x0c */
/* offset 0x10 */
/* offset 0x14 */
/* offset 0x18 */
/* PIO Setup - Device to Host FIS (from SATA spec) */
typedef struct ahci_fis_pio_setup {
/* offset 0x00 */
/* offset 0x04 */
/* offset 0x08 */
/* offset 0x0c */
/* offset 0x10 */
/* BIST Active - Host to Device or Device to Host (from SATA spec) */
typedef struct ahci_fis_bist_active {
/* offset 0x00 */
/* offset 0x04 */
/* offset 0x08 */
/* Up to 64 bytes */
typedef struct ahci_fis_unknown {
/*
* This is a software constructed FIS. For data transfer,
* this is the H2D Register FIS format as specified in
* the Serial ATA 1.0a specification. Valid Command FIS
* length are 2 to 16 Dwords.
*/
typedef struct ahci_fis_command {
union {
} ahcifc_fis;
/* Received FISes structure - size 100h */
typedef struct ahci_rcvd_fis {
/* offset 0x00 - DMA Setup FIS */
/* offset 0x20 - PIO Setup FIS */
/* offset 0x40 - D2H Register FIS */
/* offset 0x58 - Set Device Bits FIS */
/* offset 0x60 - Unknown FIS */
/* offset 0xa0h - Reserved */
/*
* XXX to be supported in second phase
*
* ATAPI command structure - 12 or 16 bytes
*/
typedef struct atapi_cmd {
} atapi_cmd_t;
/* physical region description table (PRDT) item structure */
typedef struct ahci_prdt_item {
/* DW 0 - Data Base Address */
/* DW 1 - Data Base Address Upper */
/* DW 2 - Reserved */
/* DW 3 - Description Information */
#define GET_PRDT_ITEM_INTR_ON_COMPLETION(prdt_item) \
#define GET_PRDT_ITEM_DATA_BYTE_COUNT(prdt_item) \
/* command table structure */
typedef struct ahci_cmd_table {
/* offset 0x00 - Command FIS */
/* offset 0x40 - ATAPI Command */
/* offset 0x50 - Reserved */
/* offset 0x80 - Physical Region Description Table */
/* command head structure - size 20h */
typedef struct ahci_cmd_header {
/* DW 0 - Description Information */
#define BZERO_DESCR_INFO(cmd_header) \
(cmd_header->ahcich_descr_info = 0)
#define GET_PRD_TABLE_LENGTH(cmd_header) \
#define GET_PORT_MULTI_PORT(cmd_header) \
#define GET_CLEAR_BUSY_UPON_R_OK(cmd_header) \
#define GET_BIST(cmd_header) \
#define GET_RESET(cmd_header) \
#define GET_PREFETCHABLE(cmd_header) \
#define GET_WRITE(cmd_header) \
#define GET_ATAPI(cmd_header) \
#define GET_COMMAND_FIS_LENGTH(cmd_header) \
/* DW 1 - Physical Region Descriptor Byte Count */
#define BZERO_PRD_BYTE_COUNT(cmd_header) \
(cmd_header->ahcich_prd_byte_count = 0)
/* DW 2 - Command Table Base Address */
/* DW 3 - Command Table Base Address Upper */
/* DW 4-7 - Reserved */
#ifdef __cplusplus
}
#endif
#endif /* _AHCIREG_H */