blob: 405a7009bc4badbf341d6a8c83624ef2f48220b1 [file] [log] [blame]
Marc Jones8ae8c882007-12-19 01:32:08 +00001/*
Stefan Reinauer7e61e452008-01-18 10:35:56 +00002 * This file is part of the coreboot project.
Marc Jones8ae8c882007-12-19 01:32:08 +00003 *
4 * Copyright (C) 2007 Advanced Micro Devices, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
Marc Jones8ae8c882007-12-19 01:32:08 +000014 */
15
Damien Zammit75a3d1f2016-11-28 00:29:10 +110016#include "debug.h"
17#include <console/console.h>
18#include <arch/io.h>
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +020019#include <device/pci_ops.h>
Damien Zammit75a3d1f2016-11-28 00:29:10 +110020#include <device/pci_def.h>
Myles Watson075fbe82010-04-15 05:19:29 +000021#include <delay.h>
Marc Jones8ae8c882007-12-19 01:32:08 +000022
Damien Zammit75a3d1f2016-11-28 00:29:10 +110023void print_debug_addr(const char *str, void *val)
Marc Jones8ae8c882007-12-19 01:32:08 +000024{
Martin Roth77a58b92017-06-24 14:45:48 -060025#if IS_ENABLED(CONFIG_DEBUG_CAR)
Myles Watson08e0fb82010-03-22 16:33:25 +000026 printk(BIOS_DEBUG, "------Address debug: %s%p------\n", str, val);
Marc Jones8ae8c882007-12-19 01:32:08 +000027#endif
28}
29
Damien Zammit75a3d1f2016-11-28 00:29:10 +110030void print_debug_pci_dev(u32 dev)
Marc Jones8ae8c882007-12-19 01:32:08 +000031{
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000032 printk(BIOS_DEBUG, "PCI: %02x:%02x.%02x", (dev>>20) & 0xff, (dev>>15) & 0x1f, (dev>>12) & 0x7);
Marc Jones8ae8c882007-12-19 01:32:08 +000033}
34
Damien Zammit75a3d1f2016-11-28 00:29:10 +110035void print_pci_devices(void)
Marc Jones8ae8c882007-12-19 01:32:08 +000036{
Antonello Dettorif65ccb22016-09-03 10:45:33 +020037 pci_devfn_t dev;
Elyes HAOUAS5a7e72f2016-08-23 21:36:02 +020038 for (dev = PCI_DEV(0, 0, 0);
Marc Jones8ae8c882007-12-19 01:32:08 +000039 dev <= PCI_DEV(0xff, 0x1f, 0x7);
40 dev += PCI_DEV(0,0,1)) {
41 u32 id;
42 id = pci_read_config32(dev, PCI_VENDOR_ID);
43 if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
44 (((id >> 16) & 0xffff) == 0xffff) ||
45 (((id >> 16) & 0xffff) == 0x0000)) {
46 continue;
47 }
48 print_debug_pci_dev(dev);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000049 printk(BIOS_DEBUG, " %04x:%04x\n", (id & 0xffff), (id>>16));
Elyes HAOUAS5a7e72f2016-08-23 21:36:02 +020050 if (((dev>>12) & 0x07) == 0) {
Marc Jones8ae8c882007-12-19 01:32:08 +000051 u8 hdr_type;
52 hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
Elyes HAOUAS5a7e72f2016-08-23 21:36:02 +020053 if ((hdr_type & 0x80) != 0x80) {
Marc Jones8ae8c882007-12-19 01:32:08 +000054 dev += PCI_DEV(0,0,7);
55 }
56 }
57 }
58}
59
Damien Zammit75a3d1f2016-11-28 00:29:10 +110060void print_pci_devices_on_bus(u32 busn)
Marc Jones8ae8c882007-12-19 01:32:08 +000061{
Antonello Dettorif65ccb22016-09-03 10:45:33 +020062 pci_devfn_t dev;
Elyes HAOUAS5a7e72f2016-08-23 21:36:02 +020063 for (dev = PCI_DEV(busn, 0, 0);
Marc Jones8ae8c882007-12-19 01:32:08 +000064 dev <= PCI_DEV(busn, 0x1f, 0x7);
65 dev += PCI_DEV(0,0,1)) {
66 u32 id;
67 id = pci_read_config32(dev, PCI_VENDOR_ID);
68 if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
69 (((id >> 16) & 0xffff) == 0xffff) ||
70 (((id >> 16) & 0xffff) == 0x0000)) {
71 continue;
72 }
73 print_debug_pci_dev(dev);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000074 printk(BIOS_DEBUG, " %04x:%04x\n", (id & 0xffff), (id>>16));
Elyes HAOUAS5a7e72f2016-08-23 21:36:02 +020075 if (((dev>>12) & 0x07) == 0) {
Marc Jones8ae8c882007-12-19 01:32:08 +000076 u8 hdr_type;
77 hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
Elyes HAOUAS5a7e72f2016-08-23 21:36:02 +020078 if ((hdr_type & 0x80) != 0x80) {
Marc Jones8ae8c882007-12-19 01:32:08 +000079 dev += PCI_DEV(0,0,7);
80 }
81 }
82 }
83}
84
Damien Zammit75a3d1f2016-11-28 00:29:10 +110085void dump_pci_device_range(u32 dev, u32 start_reg, u32 size)
Marc Jones8ae8c882007-12-19 01:32:08 +000086{
87 int i;
88 print_debug_pci_dev(dev);
89 int j;
90 int end = start_reg + size;
91
Elyes HAOUAS5a7e72f2016-08-23 21:36:02 +020092 for (i = start_reg; i < end; i+=4) {
Marc Jones8ae8c882007-12-19 01:32:08 +000093 u32 val;
94 if ((i & 0x0f) == 0) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000095 printk(BIOS_DEBUG, "\n%04x:",i);
Marc Jones8ae8c882007-12-19 01:32:08 +000096 }
97 val = pci_read_config32(dev, i);
Elyes HAOUAS04f8fd92016-09-19 10:24:34 -060098 for (j = 0; j < 4; j++) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000099 printk(BIOS_DEBUG, " %02x", val & 0xff);
Marc Jones8ae8c882007-12-19 01:32:08 +0000100 val >>= 8;
101 }
102 }
Stefan Reinauer65b72ab2015-01-05 12:59:54 -0800103 printk(BIOS_DEBUG, "\n");
Marc Jones8ae8c882007-12-19 01:32:08 +0000104}
Myles Watson075fbe82010-04-15 05:19:29 +0000105
Damien Zammit75a3d1f2016-11-28 00:29:10 +1100106void dump_pci_device(u32 dev)
Marc Jones8ae8c882007-12-19 01:32:08 +0000107{
108 dump_pci_device_range(dev, 0, 4096);
109}
Myles Watson075fbe82010-04-15 05:19:29 +0000110
Damien Zammit75a3d1f2016-11-28 00:29:10 +1100111void dump_pci_device_index_wait_range(u32 dev, u32 index_reg, u32 start,
Marc Jones8ae8c882007-12-19 01:32:08 +0000112 u32 size)
113{
114 int i;
115 int end = start + size;
116 print_debug_pci_dev(dev);
Stefan Reinauer65b72ab2015-01-05 12:59:54 -0800117 printk(BIOS_DEBUG, " -- index_reg=%08x", index_reg);
Marc Jones8ae8c882007-12-19 01:32:08 +0000118
Elyes HAOUAS5a7e72f2016-08-23 21:36:02 +0200119 for (i = start; i < end; i++) {
Marc Jones8ae8c882007-12-19 01:32:08 +0000120 u32 val;
121 int j;
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000122 printk(BIOS_DEBUG, "\n%02x:",i);
Marc Jones8ae8c882007-12-19 01:32:08 +0000123 val = pci_read_config32_index_wait(dev, index_reg, i);
Elyes HAOUAS04f8fd92016-09-19 10:24:34 -0600124 for (j = 0; j < 4; j++) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000125 printk(BIOS_DEBUG, " %02x", val & 0xff);
Marc Jones8ae8c882007-12-19 01:32:08 +0000126 val >>= 8;
127 }
128
129 }
Stefan Reinauer65b72ab2015-01-05 12:59:54 -0800130 printk(BIOS_DEBUG, "\n");
Marc Jones8ae8c882007-12-19 01:32:08 +0000131}
Myles Watson075fbe82010-04-15 05:19:29 +0000132
Damien Zammit75a3d1f2016-11-28 00:29:10 +1100133void dump_pci_device_index_wait(u32 dev, u32 index_reg)
Marc Jones8ae8c882007-12-19 01:32:08 +0000134{
135 dump_pci_device_index_wait_range(dev, index_reg, 0, 0x54);
136 dump_pci_device_index_wait_range(dev, index_reg, 0x100, 0x08); //DIMM1 when memclk > 400Hz
Marc Jones8ae8c882007-12-19 01:32:08 +0000137}
138
Damien Zammit75a3d1f2016-11-28 00:29:10 +1100139void dump_pci_device_index(u32 dev, u32 index_reg, u32 type, u32 length)
Marc Jones8ae8c882007-12-19 01:32:08 +0000140{
141 int i;
142 print_debug_pci_dev(dev);
143
Stefan Reinauer65b72ab2015-01-05 12:59:54 -0800144 printk(BIOS_DEBUG, " index reg: %04x type: %02x", index_reg, type);
Marc Jones8ae8c882007-12-19 01:32:08 +0000145
146 type<<=28;
147
Elyes HAOUAS5a7e72f2016-08-23 21:36:02 +0200148 for (i = 0; i < length; i++) {
Marc Jones8ae8c882007-12-19 01:32:08 +0000149 u32 val;
150 if ((i & 0x0f) == 0) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000151 printk(BIOS_DEBUG, "\n%02x:",i);
Marc Jones8ae8c882007-12-19 01:32:08 +0000152 }
153 val = pci_read_config32_index(dev, index_reg, i|type);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000154 printk(BIOS_DEBUG, " %08x", val);
Marc Jones8ae8c882007-12-19 01:32:08 +0000155 }
Stefan Reinauer65b72ab2015-01-05 12:59:54 -0800156 printk(BIOS_DEBUG, "\n");
Marc Jones8ae8c882007-12-19 01:32:08 +0000157}
158
Damien Zammit75a3d1f2016-11-28 00:29:10 +1100159void dump_pci_devices(void)
Marc Jones8ae8c882007-12-19 01:32:08 +0000160{
Antonello Dettorif65ccb22016-09-03 10:45:33 +0200161 pci_devfn_t dev;
Elyes HAOUAS5a7e72f2016-08-23 21:36:02 +0200162 for (dev = PCI_DEV(0, 0, 0);
Marc Jones8ae8c882007-12-19 01:32:08 +0000163 dev <= PCI_DEV(0xff, 0x1f, 0x7);
164 dev += PCI_DEV(0,0,1)) {
165 u32 id;
166 id = pci_read_config32(dev, PCI_VENDOR_ID);
167 if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
168 (((id >> 16) & 0xffff) == 0xffff) ||
169 (((id >> 16) & 0xffff) == 0x0000)) {
170 continue;
171 }
172 dump_pci_device(dev);
173
Elyes HAOUAS5a7e72f2016-08-23 21:36:02 +0200174 if (((dev>>12) & 0x07) == 0) {
Marc Jones8ae8c882007-12-19 01:32:08 +0000175 u8 hdr_type;
176 hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
Elyes HAOUAS5a7e72f2016-08-23 21:36:02 +0200177 if ((hdr_type & 0x80) != 0x80) {
Marc Jones8ae8c882007-12-19 01:32:08 +0000178 dev += PCI_DEV(0,0,7);
179 }
180 }
181 }
182}
183
Damien Zammit75a3d1f2016-11-28 00:29:10 +1100184void dump_pci_devices_on_bus(u32 busn)
Marc Jones8ae8c882007-12-19 01:32:08 +0000185{
Antonello Dettorif65ccb22016-09-03 10:45:33 +0200186 pci_devfn_t dev;
Elyes HAOUAS5a7e72f2016-08-23 21:36:02 +0200187 for (dev = PCI_DEV(busn, 0, 0);
Marc Jones8ae8c882007-12-19 01:32:08 +0000188 dev <= PCI_DEV(busn, 0x1f, 0x7);
189 dev += PCI_DEV(0,0,1)) {
190 u32 id;
191 id = pci_read_config32(dev, PCI_VENDOR_ID);
192 if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
193 (((id >> 16) & 0xffff) == 0xffff) ||
194 (((id >> 16) & 0xffff) == 0x0000)) {
195 continue;
196 }
197 dump_pci_device(dev);
198
Elyes HAOUAS5a7e72f2016-08-23 21:36:02 +0200199 if (((dev>>12) & 0x07) == 0) {
Marc Jones8ae8c882007-12-19 01:32:08 +0000200 u8 hdr_type;
201 hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
Elyes HAOUAS5a7e72f2016-08-23 21:36:02 +0200202 if ((hdr_type & 0x80) != 0x80) {
Marc Jones8ae8c882007-12-19 01:32:08 +0000203 dev += PCI_DEV(0,0,7);
204 }
205 }
206 }
207}
208
Martin Roth77a58b92017-06-24 14:45:48 -0600209#if IS_ENABLED(CONFIG_DEBUG_SMBUS)
Damien Zammit75a3d1f2016-11-28 00:29:10 +1100210void dump_spd_registers(const struct mem_controller *ctrl)
Marc Jones8ae8c882007-12-19 01:32:08 +0000211{
212 int i;
Stefan Reinauer65b72ab2015-01-05 12:59:54 -0800213 printk(BIOS_DEBUG, "\n");
Elyes HAOUAS5a7e72f2016-08-23 21:36:02 +0200214 for (i = 0; i < DIMM_SOCKETS; i++) {
Marc Jones8ae8c882007-12-19 01:32:08 +0000215 u32 device;
216 device = ctrl->spd_addr[i];
217 if (device) {
218 int j;
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000219 printk(BIOS_DEBUG, "dimm: %02x.0: %02x", i, device);
Elyes HAOUAS5a7e72f2016-08-23 21:36:02 +0200220 for (j = 0; j < 128; j++) {
Marc Jones8ae8c882007-12-19 01:32:08 +0000221 int status;
222 u8 byte;
223 if ((j & 0xf) == 0) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000224 printk(BIOS_DEBUG, "\n%02x: ", j);
Marc Jones8ae8c882007-12-19 01:32:08 +0000225 }
226 status = smbus_read_byte(device, j);
227 if (status < 0) {
228 break;
229 }
230 byte = status & 0xff;
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000231 printk(BIOS_DEBUG, "%02x ", byte);
Marc Jones8ae8c882007-12-19 01:32:08 +0000232 }
Stefan Reinauer65b72ab2015-01-05 12:59:54 -0800233 printk(BIOS_DEBUG, "\n");
Marc Jones8ae8c882007-12-19 01:32:08 +0000234 }
235 device = ctrl->spd_addr[i+DIMM_SOCKETS];
236 if (device) {
237 int j;
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000238 printk(BIOS_DEBUG, "dimm: %02x.1: %02x", i, device);
Elyes HAOUAS5a7e72f2016-08-23 21:36:02 +0200239 for (j = 0; j < 128; j++) {
Marc Jones8ae8c882007-12-19 01:32:08 +0000240 int status;
241 u8 byte;
242 if ((j & 0xf) == 0) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000243 printk(BIOS_DEBUG, "\n%02x: ", j);
Marc Jones8ae8c882007-12-19 01:32:08 +0000244 }
245 status = smbus_read_byte(device, j);
246 if (status < 0) {
247 break;
248 }
249 byte = status & 0xff;
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000250 printk(BIOS_DEBUG, "%02x ", byte);
Marc Jones8ae8c882007-12-19 01:32:08 +0000251 }
Stefan Reinauer65b72ab2015-01-05 12:59:54 -0800252 printk(BIOS_DEBUG, "\n");
Marc Jones8ae8c882007-12-19 01:32:08 +0000253 }
254 }
255}
Damien Zammit75a3d1f2016-11-28 00:29:10 +1100256
257void dump_smbus_registers(void)
Marc Jones8ae8c882007-12-19 01:32:08 +0000258{
259 u32 device;
Stefan Reinauer65b72ab2015-01-05 12:59:54 -0800260 printk(BIOS_DEBUG, "\n");
Elyes HAOUAS5a7e72f2016-08-23 21:36:02 +0200261 for (device = 1; device < 0x80; device++) {
Marc Jones8ae8c882007-12-19 01:32:08 +0000262 int j;
Elyes HAOUAS04f8fd92016-09-19 10:24:34 -0600263 if (smbus_read_byte(device, 0) < 0) continue;
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000264 printk(BIOS_DEBUG, "smbus: %02x", device);
Elyes HAOUAS5a7e72f2016-08-23 21:36:02 +0200265 for (j = 0; j < 256; j++) {
Marc Jones8ae8c882007-12-19 01:32:08 +0000266 int status;
267 u8 byte;
268 status = smbus_read_byte(device, j);
269 if (status < 0) {
270 break;
271 }
272 if ((j & 0xf) == 0) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000273 printk(BIOS_DEBUG, "\n%02x: ",j);
Marc Jones8ae8c882007-12-19 01:32:08 +0000274 }
275 byte = status & 0xff;
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000276 printk(BIOS_DEBUG, "%02x ", byte);
Marc Jones8ae8c882007-12-19 01:32:08 +0000277 }
Stefan Reinauer65b72ab2015-01-05 12:59:54 -0800278 printk(BIOS_DEBUG, "\n");
Marc Jones8ae8c882007-12-19 01:32:08 +0000279 }
280}
281#endif
Damien Zammit75a3d1f2016-11-28 00:29:10 +1100282
283void dump_io_resources(u32 port)
Marc Jones8ae8c882007-12-19 01:32:08 +0000284{
285
286 int i;
Stefan Reinauer2d85fbed2010-04-14 15:44:21 +0000287 udelay(2000);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000288 printk(BIOS_DEBUG, "%04x:\n", port);
Elyes HAOUAS04f8fd92016-09-19 10:24:34 -0600289 for (i = 0; i < 256; i++) {
Marc Jones8ae8c882007-12-19 01:32:08 +0000290 u8 val;
291 if ((i & 0x0f) == 0) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000292 printk(BIOS_DEBUG, "%02x:", i);
Marc Jones8ae8c882007-12-19 01:32:08 +0000293 }
294 val = inb(port);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000295 printk(BIOS_DEBUG, " %02x",val);
Marc Jones8ae8c882007-12-19 01:32:08 +0000296 if ((i & 0x0f) == 0x0f) {
Stefan Reinauer65b72ab2015-01-05 12:59:54 -0800297 printk(BIOS_DEBUG, "\n");
Marc Jones8ae8c882007-12-19 01:32:08 +0000298 }
299 port++;
300 }
301}
302
Damien Zammit75a3d1f2016-11-28 00:29:10 +1100303#if IS_ENABLED(CONFIG_DIMM_DDR2)
304void print_tx(const char *strval, u32 val)
305{
Martin Roth77a58b92017-06-24 14:45:48 -0600306#if IS_ENABLED(CONFIG_DEBUG_RAM_SETUP)
Damien Zammit75a3d1f2016-11-28 00:29:10 +1100307 printk(BIOS_DEBUG, "%s%08x\n", strval, val);
308#endif
309}
310
311void print_t(const char *strval)
312{
Martin Roth77a58b92017-06-24 14:45:48 -0600313#if IS_ENABLED(CONFIG_DEBUG_RAM_SETUP)
Damien Zammit75a3d1f2016-11-28 00:29:10 +1100314 printk(BIOS_DEBUG, "%s", strval);
315#endif
316}
317#endif /* CONFIG_DIMM_DDR2 */
318
319void print_tf(const char *func, const char *strval)
320{
Martin Roth77a58b92017-06-24 14:45:48 -0600321#if IS_ENABLED(CONFIG_DEBUG_RAM_SETUP)
Damien Zammit75a3d1f2016-11-28 00:29:10 +1100322 printk(BIOS_DEBUG, "%s: %s", func, strval);
323#endif
324}