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_offset
= 0;
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_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 printf("\n============= AHCI Configuration Registers ==============\n\n");
121 for (i
= 0; i
< ahci_cfg_registers_size
; i
++) {
122 switch (ahci_cfg_registers
[i
].size
) {
124 printf("0x%04x: 0x%08x (%s)\n",
125 ahci_cfg_registers
[i
].addr
,
126 pci_read_long(ahci
, ahci_cfg_registers
[i
].addr
),
127 ahci_cfg_registers
[i
].name
);
130 printf("0x%04x: 0x%04x (%s)\n",
131 ahci_cfg_registers
[i
].addr
,
132 pci_read_word(ahci
, ahci_cfg_registers
[i
].addr
),
133 ahci_cfg_registers
[i
].name
);
136 printf("0x%04x: 0x%02x (%s)\n",
137 ahci_cfg_registers
[i
].addr
,
138 pci_read_byte(ahci
, ahci_cfg_registers
[i
].addr
),
139 ahci_cfg_registers
[i
].name
);
144 printf("\n============= SATA Initialization Registers ==============\n\n");
145 for (i
= 0; i
< ahci_sir_registers_size
; i
++) {
146 pci_write_byte(ahci
, ahci_sir_offset
, ahci_sir_registers
[i
].addr
);
147 switch (ahci_sir_registers
[i
].size
) {
149 printf("0x%02x: 0x%08x (%s)\n",
150 ahci_sir_registers
[i
].addr
,
151 pci_read_long(ahci
, ahci_sir_offset
),
152 ahci_sir_registers
[i
].name
);
155 printf("0x%02x: 0x%04x (%s)\n",
156 ahci_sir_registers
[i
].addr
,
157 pci_read_word(ahci
, ahci_sir_offset
),
158 ahci_sir_registers
[i
].name
);
161 printf("0x%02x: 0x%02x (%s)\n",
162 ahci_sir_registers
[i
].addr
,
163 pci_read_byte(ahci
, ahci_sir_offset
),
164 ahci_sir_registers
[i
].name
);
169 const pciaddr_t ahci_phys
= ahci
->base_addr
[5] & ~0x7ULL
;
170 printf("\n============= ABAR ==============\n\n");
171 printf("ABAR = 0x%08llx (MEM)\n\n", (unsigned long long)ahci_phys
);
172 const uint8_t *const mmio
= map_physical(ahci_phys
, ahci_registers_size
);
174 perror("Error mapping MMIO");
178 puts("Generic Host Control Registers:");
179 for (i
= 0; i
< 0x100; i
+= 4) {
180 if (i
/ 4 < NUM_GHC
) {
181 printf("0x%03zx: 0x%08x (%s)\n",
182 i
, read32(mmio
+ i
), ghc_regs
[i
/ 4]);
183 } else if (read32(mmio
+ i
)) {
184 printf("0x%03zx: 0x%08x (Reserved)\n", i
,
189 const size_t max_ports
= (ahci_registers_size
- 0x100) / 0x80;
190 for (i
= 0; i
< max_ports
; i
++) {
191 if (read32(mmio
+ 0x0c) & 1 << i
)
195 puts("\nOther registers:");
196 for (i
= 0x500; i
< ahci_registers_size
; i
+= 4) {
197 if (read32(mmio
+ i
))
198 printf("0x%03zx: 0x%08x\n", i
, read32(mmio
+ i
));
201 unmap_physical((void *)mmio
, ahci_registers_size
);