fix: (blkio) enforce disk io buffer size alignment (to block size)
[lunaix-os.git] / lunaix-os / includes / hal / ahci / hba.h
1 #ifndef __LUNAIX_HBA_H
2 #define __LUNAIX_HBA_H
3
4 #include <lunaix/blkio.h>
5 #include <lunaix/buffer.h>
6 #include <lunaix/types.h>
7
8 #define HBA_RCAP 0
9 #define HBA_RGHC 1
10 #define HBA_RIS 2
11 #define HBA_RPI 3
12 #define HBA_RVER 4
13
14 #define HBA_RPBASE (0x40)
15 #define HBA_RPSIZE (0x80 >> 2)
16 #define HBA_RPxCLB 0
17 #define HBA_RPxFB 2
18 #define HBA_RPxIS 4
19 #define HBA_RPxIE 5
20 #define HBA_RPxCMD 6
21 #define HBA_RPxTFD 8
22 #define HBA_RPxSIG 9
23 #define HBA_RPxSSTS 10
24 #define HBA_RPxSCTL 11
25 #define HBA_RPxSERR 12
26 #define HBA_RPxSACT 13
27 #define HBA_RPxCI 14
28 #define HBA_RPxSNTF 15
29 #define HBA_RPxFBS 16
30
31 #define HBA_PxCMD_FRE (1 << 4)
32 #define HBA_PxCMD_CR (1 << 15)
33 #define HBA_PxCMD_FR (1 << 14)
34 #define HBA_PxCMD_ST (1)
35 #define HBA_PxINTR_DMA (1 << 2)
36 #define HBA_PxINTR_DHR (1)
37 #define HBA_PxINTR_DPS (1 << 5)
38 #define HBA_PxINTR_TFE (1 << 30)
39 #define HBA_PxINTR_HBF (1 << 29)
40 #define HBA_PxINTR_HBD (1 << 28)
41 #define HBA_PxINTR_IF (1 << 27)
42 #define HBA_PxINTR_NIF (1 << 26)
43 #define HBA_PxINTR_OF (1 << 24)
44 #define HBA_PxTFD_ERR (1)
45 #define HBA_PxTFD_BSY (1 << 7)
46 #define HBA_PxTFD_DRQ (1 << 3)
47
48 #define HBA_FATAL                                                              \
49     (HBA_PxINTR_TFE | HBA_PxINTR_HBF | HBA_PxINTR_HBD | HBA_PxINTR_IF)
50
51 #define HBA_NONFATAL (HBA_PxINTR_NIF | HBA_PxINTR_OF)
52
53 #define HBA_RGHC_ACHI_ENABLE (1 << 31)
54 #define HBA_RGHC_INTR_ENABLE (1 << 1)
55 #define HBA_RGHC_RESET 1
56
57 #define HBA_RPxSSTS_PWR(x) (((x) >> 8) & 0xf)
58 #define HBA_RPxSSTS_IF(x) (((x) >> 4) & 0xf)
59 #define HBA_RPxSSTS_PHYSTATE(x) ((x)&0xf)
60
61 #define hba_clear_reg(reg) (reg) = -1
62
63 #define HBA_DEV_SIG_ATAPI 0xeb140101
64 #define HBA_DEV_SIG_ATA 0x00000101
65
66 #define __HBA_PACKED__ __attribute__((packed))
67
68 typedef unsigned int hba_reg_t;
69
70 #define HBA_CMDH_FIS_LEN(fis_bytes) (((fis_bytes) / 4) & 0x1f)
71 #define HBA_CMDH_ATAPI (1 << 5)
72 #define HBA_CMDH_WRITE (1 << 6)
73 #define HBA_CMDH_PREFETCH (1 << 7)
74 #define HBA_CMDH_R (1 << 8)
75 #define HBA_CMDH_CLR_BUSY (1 << 10)
76 #define HBA_CMDH_PRDT_LEN(entries) (((entries)&0xffff) << 16)
77
78 #define HBA_MAX_PRDTE 4
79
80 struct hba_cmdh
81 {
82     uint16_t options;
83     uint16_t prdt_len;
84     uint32_t transferred_size;
85     uint32_t cmd_table_base;
86     uint32_t reserved[5];
87 } __HBA_PACKED__;
88
89 #define HBA_PRDTE_BYTE_CNT(cnt) ((cnt & 0x3FFFFF) | 0x1)
90
91 struct hba_prdte
92 {
93     uint32_t data_base;
94     uint32_t reserved[2];
95     uint32_t byte_count;
96 } __HBA_PACKED__;
97
98 struct hba_cmdt
99 {
100     uint8_t command_fis[64];
101     uint8_t atapi_cmd[16];
102     uint8_t reserved[0x30];
103     struct hba_prdte entries[HBA_MAX_PRDTE];
104 } __HBA_PACKED__;
105
106 #define HBA_DEV_FEXTLBA 1
107 #define HBA_DEV_FATAPI (1 << 1)
108
109 struct hba_port;
110 struct ahci_hba;
111
112 struct hba_device
113 {
114     char serial_num[20];
115     char model[40];
116     uint32_t flags;
117     uint64_t max_lba;
118     uint32_t block_size;
119     uint64_t wwn;
120     uint8_t cbd_size;
121     struct
122     {
123         uint8_t sense_key;
124         uint8_t error;
125         uint8_t status;
126         uint8_t reserve;
127     } last_result;
128     uint32_t alignment_offset;
129     uint32_t block_per_sec;
130     uint32_t capabilities;
131     struct hba_port* port;
132     struct ahci_hba* hba;
133
134     struct
135     {
136         int (*identify)(struct hba_device* dev);
137         void (*submit)(struct hba_device* dev, struct blkio_req* io_req);
138     } ops;
139 };
140
141 struct hba_cmd_state
142 {
143     struct hba_cmdt* cmd_table;
144     void* state_ctx;
145 };
146
147 struct hba_cmd_context
148 {
149     struct hba_cmd_state* issued[32];
150     u32_t tracked_ci;
151 };
152
153 struct hba_port
154 {
155     volatile hba_reg_t* regs;
156     unsigned int ssts;
157     struct hba_cmdh* cmdlst;
158     struct hba_cmd_context cmdctx;
159     void* fis;
160     struct hba_device* device;
161     struct ahci_hba* hba;
162 };
163
164 struct ahci_hba
165 {
166     volatile hba_reg_t* base;
167     unsigned int ports_num;
168     unsigned int ports_bmp;
169     unsigned int cmd_slots;
170     unsigned int version;
171     struct hba_port* ports[32];
172 };
173
174 int
175 hba_prepare_cmd(struct hba_port* port,
176                 struct hba_cmdt** cmdt,
177                 struct hba_cmdh** cmdh);
178
179 int
180 hba_bind_vbuf(struct hba_cmdh* cmdh,
181               struct hba_cmdt* cmdt,
182               struct vecbuf* vbuf);
183
184 int
185 hba_bind_sbuf(struct hba_cmdh* cmdh, struct hba_cmdt* cmdt, struct membuf mbuf);
186
187 #endif /* __LUNAIX_HBA_H */