Bug#594967: Bug #594967: [poulsbo] grub-pc Hangs After "Welcome to GRUB!"
Colin Watson
cjwatson at debian.org
Mon Jan 3 11:48:27 UTC 2011
On Mon, Jan 03, 2011 at 11:04:17AM +0000, Steve McIntyre wrote:
> On Mon, Jan 03, 2011 at 12:13:01AM +0000, Colin Watson wrote:
> >Whoops, I forgot to right-shift the header word. Can you try 4.iso
> >instead, at the same location? I also made it handle PCI-to-CardBus
> >bridges the same way as PCI-to-PCI bridges since that's what pciutils
> >does.
> >
> >(In addition to 'set debug=pci', I'd recommend also doing 'set pager=1'
> >so that lspci's output will be paged.)
>
> 4.iso:
>
> grub> set debug=pci
> grub> set pager=1
> grub> lspci
> bus/pci.c:92: bus 0x0
> 00:00.0 8086:8100 [0600] Host Bridge
> 00:02.0 8086:8108 [0300] VGA Controller
> 00:1b.0 8086:811b [0403] Multimedia device
> bus/pci.c:143: bridge range 0x2-0x2
> 00:1c.0 8086:8110 [0604] PCI-PCI Bridge
> bus/pci.c:143: bridge range 0x3-0x3
> 00:1c.1 8086:8112 [0604] PCI-PCI Bridge
> 00:1d.0 8086:8114 [0c03] USB Controller
> 00:1d.1 8086:8115 [0c03] USB Controller
> 00:1d.2 8086:8116 [0c03] USB Controller
> 00:1d.7 8086:8117 [0c03] USB Controller [PI 20]
> 00:1f.0 8086:8119 [0601] ISA Bridge
> 00:1f.1 8086:811a [0101] IDE Controller [PI 80]
> bus/pci.c:92: bus 0x2
> 02:00.0 10ec:8136 [0200] Ethernet Controller
> bus/pci.c:92: bus 0x3
> 03:00.0 168c:001c [0200] Ethernet Controller
> grub>
This looks right to me. Excellent. Vladimir, how does this patch look,
on top of my previous one? (This is edited slightly relative to what
Steve tested, to make sure that the bus number never overflows
bus_present; this will never happen on x86 but might happen on other
architectures. I've smoke-tested this change.)
2011-01-03 Colin Watson <cjwatson at ubuntu.com>
* grub-core/bus/pci.c (grub_pci_iterate): Only scan bus 0 plus any
buses linked by PCI-to-PCI or PCI-to-CardBus bridges.
* include/grub/pci.h: Add definitions for bridges.
=== modified file 'grub-core/bus/pci.c'
--- grub-core/bus/pci.c 2010-06-30 00:30:05 +0000
+++ grub-core/bus/pci.c 2011-01-03 00:05:27 +0000
@@ -20,6 +20,7 @@
#include <grub/dl.h>
#include <grub/pci.h>
#include <grub/mm.h>
+#include <grub/misc.h>
/* FIXME: correctly support 64-bit architectures. */
/* #if GRUB_TARGET_SIZEOF_VOID_P == 4 */
@@ -78,9 +79,18 @@ grub_pci_iterate (grub_pci_iteratefunc_t
grub_pci_address_t addr;
grub_pci_id_t id;
grub_uint32_t hdr;
+ grub_uint8_t bus_present[(GRUB_PCI_NUM_BUS + 7) / 8];
+
+ grub_memset (bus_present, 0, sizeof (bus_present));
+ bus_present[0] = 1; /* bus 0 is always enabled */
for (dev.bus = 0; dev.bus < GRUB_PCI_NUM_BUS; dev.bus++)
{
+ if (!(bus_present[dev.bus / 8] & (1 << (dev.bus % 8))))
+ continue;
+
+ grub_dprintf ("pci", "bus 0x%x\n", dev.bus);
+
for (dev.device = 0; dev.device < GRUB_PCI_NUM_DEVICES; dev.device++)
{
for (dev.function = 0; dev.function < 8; dev.function++)
@@ -112,6 +119,38 @@ grub_pci_iterate (grub_pci_iteratefunc_t
continue;
#endif
+ /* On bus 0, look for PCI-to-PCI bridges and mark all buses
+ within their ranges as present. */
+ if (dev.bus == 0)
+ {
+ addr = grub_pci_make_address (dev, GRUB_PCI_REG_CACHELINE);
+ hdr = grub_pci_read (addr);
+
+ switch ((hdr >> 16) & 0x7F) {
+ case GRUB_PCI_HEADER_PCI_BRIDGE:
+ case GRUB_PCI_HEADER_CARDBUS_BRIDGE:
+ {
+ grub_uint32_t bus_numbers;
+ grub_uint32_t secondary, subordinate, i;
+
+ addr = grub_pci_make_address
+ (dev, GRUB_PCI_REG_SEC_LAT_TIMER);
+ bus_numbers = grub_pci_read (addr);
+ secondary = (bus_numbers >> 8) & 0xFF;
+ subordinate = (bus_numbers >> 16) & 0xFF;
+
+ grub_dprintf ("pci", "bridge range 0x%x-0x%x\n",
+ secondary, subordinate);
+
+ for (i = secondary;
+ i <= subordinate && i < GRUB_PCI_NUM_BUS; i++)
+ bus_present[i / 8] |= (1 << (i % 8));
+
+ break;
+ }
+ }
+ }
+
if (hook (dev, id))
return;
=== modified file 'include/grub/pci.h'
--- include/grub/pci.h 2010-08-11 02:18:07 +0000
+++ include/grub/pci.h 2011-01-02 17:32:28 +0000
@@ -68,6 +68,24 @@
#define GRUB_PCI_REG_MIN_GNT 0x3e
#define GRUB_PCI_REG_MAX_LAT 0x3f
+/* Alternative register meanings if header type is 1 (PCI-to-PCI bridge). */
+#define GRUB_PCI_REG_SEC_LAT_TIMER 0x18
+#define GRUB_PCI_REG_SUB_BUS_NUMBER 0x19
+#define GRUB_PCI_REG_SEC_BUS_NUMBER 0x1a
+#define GRUB_PCI_REG_PRI_BUS_NUMBER 0x1b
+#define GRUB_PCI_REG_SEC_STATUS 0x1c
+#define GRUB_PCI_REG_IO_LIMIT 0x1e
+#define GRUB_PCI_REG_IO_BASE 0x1f
+#define GRUB_PCI_REG_MEM_LIMIT 0x20
+#define GRUB_PCI_REG_MEM_BASE 0x22
+#define GRUB_PCI_REG_PF_MEM_LIMIT 0x24
+#define GRUB_PCI_REG_PF_MEM_BASE 0x26
+#define GRUB_PCI_REG_PF_MEM_BASE_HI 0x28
+#define GRUB_PCI_REG_PF_MEM_LIMIT_HI 0x2c
+#define GRUB_PCI_REG_IO_LIMIT_HI 0x30
+#define GRUB_PCI_REG_IO_BASE_HI 0x32
+#define GRUB_PCI_REG_BRIDGE_CONTROL 0x3c
+
#define GRUB_PCI_COMMAND_IO_ENABLED 0x0001
#define GRUB_PCI_COMMAND_MEM_ENABLED 0x0002
#define GRUB_PCI_COMMAND_BUS_MASTER 0x0004
@@ -82,6 +100,10 @@
#define GRUB_PCI_STATUS_DEVSEL_TIMING_MASK 0x0600
#define GRUB_PCI_CLASS_SUBCLASS_VGA 0x0300
+#define GRUB_PCI_HEADER_GENERAL 0x0
+#define GRUB_PCI_HEADER_PCI_BRIDGE 0x1
+#define GRUB_PCI_HEADER_CARDBUS_BRIDGE 0x2
+
#ifndef ASM_FILE
typedef grub_uint32_t grub_pci_id_t;
Thanks,
--
Colin Watson [cjwatson at debian.org]
More information about the Pkg-grub-devel
mailing list