quinn-os/ahci.h
2021-12-19 21:22:17 +10:00

297 lines
9.2 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifndef __AHCI_H__
#define __AHCI_H__
typedef enum
{
FIS_TYPE_REG_H2D = 0x27, // Register FIS - host to device
FIS_TYPE_REG_D2H = 0x34, // Register FIS - device to host
FIS_TYPE_DMA_ACT = 0x39, // DMA activate FIS - device to host
FIS_TYPE_DMA_SETUP = 0x41, // DMA setup FIS - bidirectional
FIS_TYPE_DATA = 0x46, // Data FIS - bidirectional
FIS_TYPE_BIST = 0x58, // BIST activate FIS - bidirectional
FIS_TYPE_PIO_SETUP = 0x5F, // PIO setup FIS - device to host
FIS_TYPE_DEV_BITS = 0xA1, // Set device bits FIS - device to host
} FIS_TYPE;
typedef volatile struct tagHBA_PORT
{
unsigned long clb; // 0x00, command list base address, 1K-byte aligned
unsigned long clbu; // 0x04, command list base address upper 32 bits
unsigned long fb; // 0x08, FIS base address, 256-byte aligned
unsigned long fbu; // 0x0C, FIS base address upper 32 bits
unsigned long is; // 0x10, interrupt status
unsigned long ie; // 0x14, interrupt enable
unsigned long cmd; // 0x18, command and status
unsigned long rsv0; // 0x1C, Reserved
unsigned long tfd; // 0x20, task file data
unsigned long sig; // 0x24, signature
unsigned long ssts; // 0x28, SATA status (SCR0:SStatus)
unsigned long sctl; // 0x2C, SATA control (SCR2:SControl)
unsigned long serr; // 0x30, SATA error (SCR1:SError)
unsigned long sact; // 0x34, SATA active (SCR3:SActive)
unsigned long ci; // 0x38, command issue
unsigned long sntf; // 0x3C, SATA notification (SCR4:SNotification)
unsigned long fbs; // 0x40, FIS-based switch control
unsigned long rsv1[11]; // 0x44 ~ 0x6F, Reserved
unsigned long vendor[4]; // 0x70 ~ 0x7F, vendor specific
} HBA_PORT;
typedef struct tagFIS_REG_H2D
{
// DWORD 0
unsigned char fis_type; // FIS_TYPE_REG_H2D
unsigned char pmport:4; // Port multiplier
unsigned char rsv0:3; // Reserved
unsigned char c:1; // 1: Command, 0: Control
unsigned char command; // Command register
unsigned char featurel; // Feature register, 7:0
// DWORD 1
unsigned char lba0; // LBA low register, 7:0
unsigned char lba1; // LBA mid register, 15:8
unsigned char lba2; // LBA high register, 23:16
unsigned char device; // Device register
// DWORD 2
unsigned char lba3; // LBA register, 31:24
unsigned char lba4; // LBA register, 39:32
unsigned char lba5; // LBA register, 47:40
unsigned char featureh; // Feature register, 15:8
// DWORD 3
unsigned char countl; // Count register, 7:0
unsigned char counth; // Count register, 15:8
unsigned char icc; // Isochronous command completion
unsigned char control; // Control register
// DWORD 4
unsigned char rsv1[4]; // Reserved
} FIS_REG_H2D;
typedef struct tagFIS_REG_D2H
{
// DWORD 0
unsigned char fis_type; // FIS_TYPE_REG_D2H
unsigned char pmport:4; // Port multiplier
unsigned char rsv0:2; // Reserved
unsigned char i:1; // Interrupt bit
unsigned char rsv1:1; // Reserved
unsigned char status; // Status register
unsigned char error; // Error register
// DWORD 1
unsigned char lba0; // LBA low register, 7:0
unsigned char lba1; // LBA mid register, 15:8
unsigned char lba2; // LBA high register, 23:16
unsigned char device; // Device register
// DWORD 2
unsigned char lba3; // LBA register, 31:24
unsigned char lba4; // LBA register, 39:32
unsigned char lba5; // LBA register, 47:40
unsigned char rsv2; // Reserved
// DWORD 3
unsigned char countl; // Count register, 7:0
unsigned char counth; // Count register, 15:8
unsigned char rsv3[2]; // Reserved
// DWORD 4
unsigned char rsv4[4]; // Reserved
} FIS_REG_D2H;
typedef struct tagFIS_DATA
{
// DWORD 0
unsigned char fis_type; // FIS_TYPE_DATA
unsigned char pmport:4; // Port multiplier
unsigned char rsv0:4; // Reserved
unsigned char rsv1[2]; // Reserved
// DWORD 1 ~ N
unsigned long data[1]; // Payload
} FIS_DATA;
typedef struct tagFIS_PIO_SETUP
{
// DWORD 0
unsigned char fis_type; // FIS_TYPE_PIO_SETUP
unsigned char pmport:4; // Port multiplier
unsigned char rsv0:1; // Reserved
unsigned char d:1; // Data transfer direction, 1 - device to host
unsigned char i:1; // Interrupt bit
unsigned char rsv1:1;
unsigned char status; // Status register
unsigned char error; // Error register
// DWORD 1
unsigned char lba0; // LBA low register, 7:0
unsigned char lba1; // LBA mid register, 15:8
unsigned char lba2; // LBA high register, 23:16
unsigned char device; // Device register
// DWORD 2
unsigned char lba3; // LBA register, 31:24
unsigned char lba4; // LBA register, 39:32
unsigned char lba5; // LBA register, 47:40
unsigned char rsv2; // Reserved
// DWORD 3
unsigned char countl; // Count register, 7:0
unsigned char counth; // Count register, 15:8
unsigned char rsv3; // Reserved
unsigned char e_status; // New value of status register
// DWORD 4
unsigned short tc; // Transfer count
unsigned char rsv4[2]; // Reserved
} FIS_PIO_SETUP;
typedef struct tagFIS_DMA_SETUP
{
// DWORD 0
unsigned char fis_type; // FIS_TYPE_DMA_SETUP
unsigned char pmport:4; // Port multiplier
unsigned char rsv0:1; // Reserved
unsigned char d:1; // Data transfer direction, 1 - device to host
unsigned char i:1; // Interrupt bit
unsigned char a:1; // Auto-activate. Specifies if DMA Activate FIS is needed
unsigned char rsved[2]; // Reserved
unsigned long long DMAbufferID; // DMA Buffer Identifier. Used to Identify DMA buffer in host memory. SATA Spec says host specific and not in Spec. Trying AHCI spec might work.
unsigned long rsvd; //More reserved
unsigned long DMAbufOffset; //Byte offset into buffer. First 2 bits must be 0
unsigned long TransferCount; //Number of bytes to transfer. Bit 0 must be 0
unsigned long resvd; //Reserved
} FIS_DMA_SETUP;
typedef volatile struct tagHBA_MEM
{
// 0x00 - 0x2B, Generic Host Control
unsigned long cap; // 0x00, Host capability
unsigned long ghc; // 0x04, Global host control
unsigned long is; // 0x08, Interrupt status
unsigned long pi; // 0x0C, Port implemented
unsigned long vs; // 0x10, Version
unsigned long ccc_ctl; // 0x14, Command completion coalescing control
unsigned long ccc_pts; // 0x18, Command completion coalescing ports
unsigned long em_loc; // 0x1C, Enclosure management location
unsigned long em_ctl; // 0x20, Enclosure management control
unsigned long cap2; // 0x24, Host capabilities extended
unsigned long bohc; // 0x28, BIOS/OS handoff control and status
// 0x2C - 0x9F, Reserved
unsigned char rsv[0xA0-0x2C];
// 0xA0 - 0xFF, Vendor specific registers
unsigned char vendor[0x100-0xA0];
// 0x100 - 0x10FF, Port control registers
HBA_PORT ports[1]; // 1 ~ 32
} HBA_MEM;
/*
typedef volatile struct tagHBA_FIS
{
// 0x00
FIS_DMA_SETUP dsfis; // DMA Setup FIS
unsigned char pad0[4];
// 0x20
FIS_PIO_SETUP psfis; // PIO Setup FIS
unsigned char pad1[12];
// 0x40
FIS_REG_D2H rfis; // Register Device to Host FIS
unsigned char pad2[4];
// 0x58
FIS_DEV_BITS sdbfis; // Set Device Bit FIS
// 0x60
unsigned char ufis[64];
// 0xA0
unsigned char rsv[0x100-0xA0];
} HBA_FIS;
*/
typedef struct tagHBA_CMD_HEADER
{
// DW0
unsigned char cfl:5; // Command FIS length in DWORDS, 2 ~ 16
unsigned char a:1; // ATAPI
unsigned char w:1; // Write, 1: H2D, 0: D2H
unsigned char p:1; // Prefetchable
unsigned char r:1; // Reset
unsigned char b:1; // BIST
unsigned char c:1; // Clear busy upon R_OK
unsigned char rsv0:1; // Reserved
unsigned char pmp:4; // Port multiplier port
unsigned short prdtl; // Physical region descriptor table length in entries
// DW1
volatile
unsigned long prdbc; // Physical region descriptor byte count transferred
// DW2, 3
unsigned long ctba; // Command table descriptor base address
unsigned long ctbau; // Command table descriptor base address upper 32 bits
// DW4 - 7
unsigned long rsv1[4]; // Reserved
} HBA_CMD_HEADER;
typedef struct tagHBA_PRDT_ENTRY
{
unsigned long dba; // Data base address
unsigned long dbau; // Data base address upper 32 bits
unsigned long rsv0; // Reserved
// DW3
unsigned long dbc:22; // Byte count, 4M max
unsigned long rsv1:9; // Reserved
unsigned long i:1; // Interrupt on completion
} HBA_PRDT_ENTRY;
typedef struct tagHBA_CMD_TBL
{
// 0x00
unsigned char cfis[64]; // Command FIS
// 0x40
unsigned char acmd[16]; // ATAPI command, 12 or 16 bytes
// 0x50
unsigned char rsv[48]; // Reserved
// 0x80
HBA_PRDT_ENTRY prdt_entry[1]; // Physical region descriptor table entries, 0 ~ 65535
} HBA_CMD_TBL;
struct ahci_slot_t {
unsigned long base;
unsigned long base_phys;
unsigned long prdt_base;
unsigned long prdt_base_phys;
int port;
};
struct ahci_device_t {
struct pci_device *pci_dev;
HBA_MEM *abar;
struct ahci_slot_t **devices;
int count;
};
extern void init_ahci();
extern int ahci_read_sectors(struct ahci_device_t *dev, int pt, unsigned long startl, unsigned long starth, unsigned long count, unsigned char *buf);
extern int ahci_write_sectors(struct ahci_device_t *dev, int pt, unsigned long startl, unsigned long starth, unsigned long count, unsigned char *buf);
#endif