1 /* ahci.c: dump AHCI registers */
2 /* SPDX-License-Identifier: GPL-2.0-only */
9 static const char *ghc_regs
[] = {
10 "CAP", "GHC", "IS", "PI",
11 "VS", "CCC_CTL", "CCC_PORTS", "EM_LOC",
12 "EM_CTL", "CAP2", "BOHC"
15 static const char *port_ctl_regs
[] = {
16 "PxCLB", "PxCLBU", "PxFB", "PxFBU",
17 "PxIS", "PxIE", "PxCMD", "Reserved",
18 "PxTFD", "PxSIG", "PxSSTS", "PxSCTL",
19 "PxSERR", "PxSACT", "PxCI", "PxSNTF",
20 "PxFBS", "PxDEVSLP", "Reserved"
23 static const io_register_t sunrise_ahci_cfg_registers
[] = {
64 static const io_register_t sunrise_ahci_sir_registers
[] = {
66 {0x90, 4, "SATA_MPHY_PG"},
70 #define NUM_GHC (sizeof(ghc_regs)/sizeof(ghc_regs[0]))
71 #define NUM_PORTCTL (sizeof(port_ctl_regs)/sizeof(port_ctl_regs[0]))
73 static void print_port(const uint8_t *const mmio
, size_t port
)
76 printf("\nPort %zu Control Registers:\n", port
);
77 const uint8_t *const mmio_port
= mmio
+ 0x100 + port
* 0x80;
78 for (i
= 0; i
< 0x80; i
+= 4) {
79 if (i
/ 4 < NUM_PORTCTL
) {
80 printf("0x%03zx: 0x%08x (%s)\n",
81 (size_t)(mmio_port
- mmio
) + i
,
82 read32(mmio_port
+ i
), port_ctl_regs
[i
/ 4]);
83 } else if (read32(mmio_port
+ i
)) {
84 printf("0x%03zx: 0x%08x (Reserved)\n",
85 (size_t)(mmio_port
- mmio
) + i
,
86 read32(mmio_port
+ i
));
91 int print_ahci(struct pci_dev
*ahci
)
93 size_t ahci_registers_size
= 0, i
;
94 size_t ahci_cfg_registers_size
= 0;
95 const io_register_t
*ahci_cfg_registers
;
96 size_t ahci_sir_index_offset
= 0, ahci_sir_data_offset
;
97 size_t ahci_sir_registers_size
= 0;
98 const io_register_t
*ahci_sir_registers
;
101 puts("No SATA device found");
104 printf("\n============= AHCI Registers ==============\n\n");
106 switch (ahci
->device_id
) {
107 case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_SATA
:
108 case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_SATA
:
109 ahci_registers_size
= 0x800;
110 ahci_sir_index_offset
= 0xa0;
111 ahci_cfg_registers
= sunrise_ahci_cfg_registers
;
112 ahci_cfg_registers_size
= ARRAY_SIZE(sunrise_ahci_cfg_registers
);
113 ahci_sir_registers
= sunrise_ahci_sir_registers
;
114 ahci_sir_registers_size
= ARRAY_SIZE(sunrise_ahci_sir_registers
);
117 ahci_registers_size
= 0x400;
120 ahci_sir_data_offset
= ahci_sir_index_offset
+ 4;
122 printf("\n============= AHCI Configuration Registers ==============\n\n");
123 for (i
= 0; i
< ahci_cfg_registers_size
; i
++) {
124 switch (ahci_cfg_registers
[i
].size
) {
126 printf("0x%04x: 0x%08x (%s)\n",
127 ahci_cfg_registers
[i
].addr
,
128 pci_read_long(ahci
, ahci_cfg_registers
[i
].addr
),
129 ahci_cfg_registers
[i
].name
);
132 printf("0x%04x: 0x%04x (%s)\n",
133 ahci_cfg_registers
[i
].addr
,
134 pci_read_word(ahci
, ahci_cfg_registers
[i
].addr
),
135 ahci_cfg_registers
[i
].name
);
138 printf("0x%04x: 0x%02x (%s)\n",
139 ahci_cfg_registers
[i
].addr
,
140 pci_read_byte(ahci
, ahci_cfg_registers
[i
].addr
),
141 ahci_cfg_registers
[i
].name
);
146 printf("\n============= SATA Initialization Registers ==============\n\n");
147 for (i
= 0; i
< ahci_sir_registers_size
; i
++) {
148 pci_write_byte(ahci
, ahci_sir_index_offset
, ahci_sir_registers
[i
].addr
);
149 switch (ahci_sir_registers
[i
].size
) {
151 printf("0x%02x: 0x%08x (%s)\n",
152 ahci_sir_registers
[i
].addr
,
153 pci_read_long(ahci
, ahci_sir_data_offset
),
154 ahci_sir_registers
[i
].name
);
157 printf("0x%02x: 0x%04x (%s)\n",
158 ahci_sir_registers
[i
].addr
,
159 pci_read_word(ahci
, ahci_sir_data_offset
),
160 ahci_sir_registers
[i
].name
);
163 printf("0x%02x: 0x%02x (%s)\n",
164 ahci_sir_registers
[i
].addr
,
165 pci_read_byte(ahci
, ahci_sir_data_offset
),
166 ahci_sir_registers
[i
].name
);
171 const pciaddr_t ahci_phys
= ahci
->base_addr
[5] & ~0x7ULL
;
172 printf("\n============= ABAR ==============\n\n");
173 printf("ABAR = 0x%08llx (MEM)\n\n", (unsigned long long)ahci_phys
);
174 const uint8_t *const mmio
= map_physical(ahci_phys
, ahci_registers_size
);
176 perror("Error mapping MMIO");
180 puts("Generic Host Control Registers:");
181 for (i
= 0; i
< 0x100; i
+= 4) {
182 if (i
/ 4 < NUM_GHC
) {
183 printf("0x%03zx: 0x%08x (%s)\n",
184 i
, read32(mmio
+ i
), ghc_regs
[i
/ 4]);
185 } else if (read32(mmio
+ i
)) {
186 printf("0x%03zx: 0x%08x (Reserved)\n", i
,
191 const size_t max_ports
= (ahci_registers_size
- 0x100) / 0x80;
192 for (i
= 0; i
< max_ports
; i
++) {
193 if (read32(mmio
+ 0x0c) & 1 << i
)
197 puts("\nOther registers:");
198 for (i
= 0x500; i
< ahci_registers_size
; i
+= 4) {
199 if (read32(mmio
+ i
))
200 printf("0x%03zx: 0x%08x\n", i
, read32(mmio
+ i
));
203 unmap_physical((void *)mmio
, ahci_registers_size
);