X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/6195e9739894771c56ea9bd3cba7bd7d04d8e7bc..f05a333a0f27f401ff32cfd2e74364ee4ecc893a:/lunaix-os/includes/hal/ahci/ahci.h diff --git a/lunaix-os/includes/hal/ahci/ahci.h b/lunaix-os/includes/hal/ahci/ahci.h new file mode 100644 index 0000000..c0c483a --- /dev/null +++ b/lunaix-os/includes/hal/ahci/ahci.h @@ -0,0 +1,173 @@ +#ifndef __LUNAIX_AHCI_H +#define __LUNAIX_AHCI_H + +#include + +/* + * Macro naming rule: + * HBA_R[xxx] + * HBA Register [xxx] + * e.g. HBA_RPxCLB is Register PxCLB + * + * All registers offset are 0 based index of a DWORD array + */ + +#define AHCI_HBA_CLASS 0x10601 + +#define HBA_RCAP 0 +#define HBA_RGHC 1 +#define HBA_RIS 2 +#define HBA_RPI 3 +#define HBA_RVER 4 + +#define HBA_RPBASE (0x40) +#define HBA_RPSIZE (0x80 >> 2) +#define HBA_RPxCLB 0 +#define HBA_RPxFB 2 +#define HBA_RPxIS 4 +#define HBA_RPxIE 5 +#define HBA_RPxCMD 6 +#define HBA_RPxTFD 8 +#define HBA_RPxSIG 9 +#define HBA_RPxSSTS 10 +#define HBA_RPxSCTL 11 +#define HBA_RPxSERR 12 +#define HBA_RPxSACT 13 +#define HBA_RPxCI 14 +#define HBA_RPxSNTF 15 +#define HBA_RPxFBS 16 + +#define HBA_PxCMD_FRE (1 << 4) +#define HBA_PxCMD_CR (1 << 15) +#define HBA_PxCMD_FR (1 << 14) +#define HBA_PxCMD_ST (1) +#define HBA_PxINTR_DMA (1 << 2) +#define HBA_PxINTR_D2HR (1) + +#define HBA_RGHC_ACHI_ENABLE (1 << 31) +#define HBA_RGHC_INTR_ENABLE (1 << 1) +#define HBA_RGHC_RESET 1 + +#define HBA_RPxSSTS_PWR(x) (((x) >> 8) & 0xf) +#define HBA_RPxSSTS_IF(x) (((x) >> 4) & 0xf) +#define HBA_RPxSSTS_PHYSTATE(x) ((x)&0xf) + +#define HBA_DEV_SIG_ATAPI 0xeb140101 +#define HBA_DEV_SIG_ATA 0x00000101 + +#define __HBA_PACKED__ __attribute__((packed)) + +typedef unsigned int hba_reg_t; + +#define HBA_CMDH_FIS_LEN(fis_bytes) (((fis_bytes) / 4) & 0x1f) +#define HBA_CMDH_ATAPI (1 << 5) +#define HBA_CMDH_WRITE (1 << 6) +#define HBA_CMDH_PREFETCH (1 << 7) +#define HBA_CMDH_R (1 << 8) +#define HBA_CMDH_CLR_BUSY (1 << 10) +#define HBA_CMDH_PRDT_LEN(entries) (((entries)&0xffff) << 16) + +struct ahci_hba_cmdh +{ + uint16_t options; + uint16_t prdt_len; + uint32_t transferred_size; + uint32_t cmd_table_base; + uint32_t reserved[5]; +} __HBA_PACKED__; + +#define HBA_PRDTE_BYTE_CNT(cnt) ((cnt & 0x3FFFFF) | 0x1) + +struct ahci_hba_prdte +{ + uint32_t data_base; + uint32_t reserved[2]; + uint32_t byte_count; +} __HBA_PACKED__; + +struct ahci_hba_cmdt +{ + uint8_t command_fis[64]; + uint8_t atapi_cmd[16]; + uint8_t reserved[0x30]; + struct ahci_hba_prdte entries[3]; +} __HBA_PACKED__; + +#define SATA_REG_FIS_D2H 0x34 +#define SATA_REG_FIS_H2D 0x27 +#define SATA_REG_FIS_COMMAND 0x80 +#define SATA_LBA_COMPONENT(lba, offset) ((((lba_lo) >> (offset)) & 0xff)) + +struct sata_fis_head +{ + uint8_t type; + uint8_t options; + uint8_t status_cmd; + uint8_t feat_err; +} __HBA_PACKED__; + +struct sata_reg_fis +{ + struct sata_fis_head head; + + uint8_t lba0, lba8, lba16; + uint8_t dev; + uint8_t lba24, lba32, lba40; + uint8_t reserved1; + + uint16_t count; + + uint8_t reserved[6]; +} __HBA_PACKED__; + +struct sata_data_fis +{ + struct sata_fis_head head; + + uint8_t data[0]; +} __HBA_PACKED__; + +struct ahci_device_info +{ + char serial_num[20]; + char model[40]; + uint32_t max_lba; + uint32_t sector_size; + uint8_t wwn[8]; +}; + +struct ahci_port +{ + volatile hba_reg_t* regs; + unsigned int ssts; + struct ahci_hba_cmdh* cmdlst; + struct sata_fis_head* fis; + struct ahci_device_info* device_info; +}; + +struct ahci_hba +{ + volatile hba_reg_t* base; + unsigned int ports_num; + unsigned int cmd_slots; + unsigned int version; + struct ahci_port* ports[32]; +}; + +#define ATA_IDENTIFY_DEVICE 0xec +#define ATA_IDENTIFY_PAKCET_DEVICE 0xa1 + +/** + * @brief 初始化AHCI与HBA + * + */ +void +ahci_init(); + +void +ahci_list_device(); + +int +ahci_identify_device(struct ahci_port* port); + +#endif /* __LUNAIX_AHCI_H */