summaryrefslogtreecommitdiff
path: root/kernel/include/sata.h
blob: 37052187b9a8ebad191d8b91d4ca2f5dba62b104 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#ifndef SATA_H
#define SATA_H

#include <types.h>

#define ATA_CMD_IDENTIFY 0xEC

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 struct tagFIS_REG_H2D {
	// DWORD 0
	uint8_t fis_type; // FIS_TYPE_REG_H2D

	uint8_t pmport : 4; // Port multiplier
	uint8_t rsv0 : 3; // Reserved
	uint8_t c : 1; // 1: Command, 0: Control

	uint8_t command; // Command register
	uint8_t featurel; // Feature register, 7:0

	// DWORD 1
	uint8_t lba0; // LBA low register, 7:0
	uint8_t lba1; // LBA mid register, 15:8
	uint8_t lba2; // LBA high register, 23:16
	uint8_t device; // Device register

	// DWORD 2
	uint8_t lba3; // LBA register, 31:24
	uint8_t lba4; // LBA register, 39:32
	uint8_t lba5; // LBA register, 47:40
	uint8_t featureh; // Feature register, 15:8

	// DWORD 3
	uint8_t countl; // Count register, 7:0
	uint8_t counth; // Count register, 15:8
	uint8_t icc; // Isochronous command completion
	uint8_t control; // Control register

	// DWORD 4
	uint8_t rsv1[4]; // Reserved
} FIS_REG_H2D;

typedef struct tagFIS_REG_D2H {
	// DWORD 0
	uint8_t fis_type; // FIS_TYPE_REG_D2H

	uint8_t pmport : 4; // Port multiplier
	uint8_t rsv0 : 2; // Reserved
	uint8_t i : 1; // Interrupt bit
	uint8_t rsv1 : 1; // Reserved

	uint8_t status; // Status register
	uint8_t error; // Error register

	// DWORD 1
	uint8_t lba0; // LBA low register, 7:0
	uint8_t lba1; // LBA mid register, 15:8
	uint8_t lba2; // LBA high register, 23:16
	uint8_t device; // Device register

	// DWORD 2
	uint8_t lba3; // LBA register, 31:24
	uint8_t lba4; // LBA register, 39:32
	uint8_t lba5; // LBA register, 47:40
	uint8_t rsv2; // Reserved

	// DWORD 3
	uint8_t countl; // Count register, 7:0
	uint8_t counth; // Count register, 15:8
	uint8_t rsv3[2]; // Reserved

	// DWORD 4
	uint8_t rsv4[4]; // Reserved
} FIS_REG_D2H;

typedef struct tagFIS_DATA {
	// DWORD 0
	uint8_t fis_type; // FIS_TYPE_DATA

	uint8_t pmport : 4; // Port multiplier
	uint8_t rsv0 : 4; // Reserved

	uint8_t rsv1[2]; // Reserved

	// DWORD 1 ~ N
	uint32_t data[1]; // Payload
} FIS_DATA;

typedef struct tagFIS_PIO_SETUP {
	// DWORD 0
	uint8_t fis_type; // FIS_TYPE_PIO_SETUP

	uint8_t pmport : 4; // Port multiplier
	uint8_t rsv0 : 1; // Reserved
	uint8_t d : 1; // Data transfer direction, 1 - device to host
	uint8_t i : 1; // Interrupt bit
	uint8_t rsv1 : 1;

	uint8_t status; // Status register
	uint8_t error; // Error register

	// DWORD 1
	uint8_t lba0; // LBA low register, 7:0
	uint8_t lba1; // LBA mid register, 15:8
	uint8_t lba2; // LBA high register, 23:16
	uint8_t device; // Device register

	// DWORD 2
	uint8_t lba3; // LBA register, 31:24
	uint8_t lba4; // LBA register, 39:32
	uint8_t lba5; // LBA register, 47:40
	uint8_t rsv2; // Reserved

	// DWORD 3
	uint8_t countl; // Count register, 7:0
	uint8_t counth; // Count register, 15:8
	uint8_t rsv3; // Reserved
	uint8_t e_status; // New value of status register

	// DWORD 4
	uint16_t tc; // Transfer count
	uint8_t rsv4[2]; // Reserved
} FIS_PIO_SETUP;

typedef struct tagFIS_DMA_SETUP {
	// DWORD 0
	uint8_t fis_type; // FIS_TYPE_DMA_SETUP

	uint8_t pmport : 4; // Port multiplier
	uint8_t rsv0 : 1; // Reserved
	uint8_t d : 1; // Data transfer direction, 1 - device to host
	uint8_t i : 1; // Interrupt bit
	uint8_t a : 1; // Auto-activate. Specifies if DMA Activate FIS is needed

	uint8_t rsved[2]; // Reserved

	//DWORD 1&2

	uint64_t 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.

	//DWORD 3
	uint32_t rsvd; //More reserved

	//DWORD 4
	uint32_t DMAbufOffset; //Byte offset into buffer. First 2 bits must be 0

	//DWORD 5
	uint32_t TransferCount; //Number of bytes to transfer. Bit 0 must be 0

	//DWORD 6
	uint32_t resvd; //Reserved

} FIS_DMA_SETUP;

void ahci(void);

#endif