AWK = @AWK@
LIBCURSES = @LIBCURSES@
LIBUSB = @LIBUSB@
+LIBPCI = @LIBPCI@
YACC = @YACC@
UNIFONT_BDF = @UNIFONT_BDF@
# Options.
enable_grub_emu = @enable_grub_emu@
enable_grub_emu_usb = @enable_grub_emu_usb@
+enable_grub_emu_pci = @enable_grub_emu_pci@
enable_grub_fstest = @enable_grub_fstest@
enable_grub_pe2elf = @enable_grub_pe2elf@
enable_grub_mkfont = @enable_grub_mkfont@
#include <grub/pci.h>
grub_pci_address_t
-grub_pci_make_address (int bus, int device, int function, int reg)
+grub_pci_make_address (grub_pci_device_t dev, int reg)
{
- return (1 << 31) | (bus << 16) | (device << 11) | (function << 8) | (reg << 2);
+ return (1 << 31) | (dev.bus << 16) | (dev.device << 11)
+ | (dev.function << 8) | (reg << 2);
}
void
grub_pci_iterate (grub_pci_iteratefunc_t hook)
{
- int bus;
- int dev;
- int func;
+ grub_pci_device_t dev;
grub_pci_address_t addr;
grub_pci_id_t id;
grub_uint32_t hdr;
- for (bus = 0; bus < 256; bus++)
+ for (dev.bus = 0; dev.bus < 256; dev.bus++)
{
- for (dev = 0; dev < 32; dev++)
+ for (dev.device = 0; dev.device < 32; dev.device++)
{
- for (func = 0; func < 8; func++)
+ for (dev.function = 0; dev.function < 8; dev.function++)
{
- addr = grub_pci_make_address (bus, dev, func, 0);
+ addr = grub_pci_make_address (dev, 0);
id = grub_pci_read (addr);
/* Check if there is a device present. */
if (id >> 16 == 0xFFFF)
continue;
- if (hook (bus, dev, func, id))
+ if (hook (dev, id))
return;
/* Probe only func = 0 if the device if not multifunction */
- if (func == 0)
+ if (dev.function == 0)
{
- addr = grub_pci_make_address (bus, dev, func, 3);
+ addr = grub_pci_make_address (dev, 3);
hdr = grub_pci_read (addr);
if (!(hdr & 0x800000))
break;
/* Iterate over all PCI devices. Determine if a device is an OHCI
controller. If this is the case, initialize it. */
static int NESTED_FUNC_ATTR
-grub_ohci_pci_iter (int bus, int device, int func,
+grub_ohci_pci_iter (grub_pci_device_t dev,
grub_pci_id_t pciid __attribute__((unused)))
{
grub_uint32_t class_code;
grub_uint32_t revision;
grub_uint32_t frame_interval;
- addr = grub_pci_make_address (bus, device, func, 2);
+ addr = grub_pci_make_address (dev, 2);
class_code = grub_pci_read (addr) >> 8;
interf = class_code & 0xFF;
return 0;
/* Determine IO base address. */
- addr = grub_pci_make_address (bus, device, func, 4);
+ addr = grub_pci_make_address (dev, 4);
base = grub_pci_read (addr);
#if 0
/* Iterate over all PCI devices. Determine if a device is an UHCI
controller. If this is the case, initialize it. */
static int NESTED_FUNC_ATTR
-grub_uhci_pci_iter (int bus, int device, int func,
+grub_uhci_pci_iter (grub_pci_device_t dev,
grub_pci_id_t pciid __attribute__((unused)))
{
grub_uint32_t class_code;
struct grub_uhci *u;
int i;
- addr = grub_pci_make_address (bus, device, func, 2);
+ addr = grub_pci_make_address (dev, 2);
class_code = grub_pci_read (addr) >> 8;
interf = class_code & 0xFF;
return 0;
/* Determine IO base address. */
- addr = grub_pci_make_address (bus, device, func, 8);
+ addr = grub_pci_make_address (dev, 8);
base = grub_pci_read (addr);
/* Stop if there is no IO space base address defined. */
if (! (base & 1))
}
static int NESTED_FUNC_ATTR
-grub_lspci_iter (int bus, int dev, int func, grub_pci_id_t pciid)
+grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid)
{
grub_uint32_t class;
const char *sclass;
grub_pci_address_t addr;
- grub_printf ("%02x:%02x.%x %04x:%04x", bus, dev, func, pciid & 0xFFFF,
- pciid >> 16);
- addr = grub_pci_make_address (bus, dev, func, 2);
+ grub_printf ("%02x:%02x.%x %04x:%04x", grub_pci_get_bus (dev),
+ grub_pci_get_device (dev), grub_pci_get_function (dev),
+ pciid & 0xFFFF, pciid >> 16);
+ addr = grub_pci_make_address (dev, 2);
class = grub_pci_read (addr);
/* Lookup the class name, if there isn't a specific one,
grub_printf ("\n");
+ grub_pci_close (dev);
+
return 0;
}
ifeq ($(enable_grub_emu_usb), yes)
grub_emu_SOURCES += disk/usbms.c util/usb.c bus/usb/usb.c \
commands/usbtest.c
-grub_emu_LDFLAGS += $(LIBCURSES) $(LIBUSB)
+grub_emu_LDFLAGS += $(LIBUSB)
+endif
+
+ifeq ($(enable_grub_emu_pci), yes)
+grub_emu_SOURCES += util/pci.c commands/lspci.c
+grub_emu_LDFLAGS += $(LIBPCI)
endif
# Scripts.
AC_ARG_ENABLE([grub-emu-usb],
[AS_HELP_STRING([--enable-grub-emu-usb],
[build and install the `grub-emu' debugging utility with USB support (default=guessed)])])
+AC_ARG_ENABLE([grub-emu-pci],
+ [AS_HELP_STRING([--enable-grub-emu-pci],
+ [build and install the `grub-emu' debugging utility with PCI support (potentially dangerous) (default=no)])])
+
if test x"$enable_grub_emu" = xno ; then
grub_emu_excuse="explicitly disabled"
fi
AC_CHECK_HEADERS([usb.h], [],
[grub_emu_usb_excuse=["need libusb headers"]])
[fi]
-if test x"enable_grub_emu_usb" = xyes && test x"$grub_emu_usb_excuse" != x ; then
+if test x"$enable_grub_emu_usb" = xyes && test x"$grub_emu_usb_excuse" != x ; then
AC_MSG_ERROR([USB support for grub-emu was explicitly requested but can't be compiled])
fi
if test x"$grub_emu_usb_excuse" = x ; then
enable_grub_emu_usb=no
fi
+if test x"$enable_grub_emu_pci" != xyes ; then
+ enable_grub_emu_pci = no
+fi
+
AC_SUBST([enable_grub_emu])
AC_SUBST([enable_grub_emu_usb])
+AC_SUBST([enable_grub_emu_pci])
AC_ARG_ENABLE([grub-fstest],
[AS_HELP_STRING([--enable-grub-fstest],
}
static int NESTED_FUNC_ATTR
-grub_ata_pciinit (int bus, int device, int func,
+grub_ata_pciinit (grub_pci_device_t dev,
grub_pci_id_t pciid __attribute__((unused)))
{
static int compat_use[2] = { 0 };
static int controller = 0;
/* Read class. */
- addr = grub_pci_make_address (bus, device, func, 2);
+ addr = grub_pci_make_address (dev, 2);
class = grub_pci_read (addr);
/* Check if this class ID matches that of a PCI IDE Controller. */
{
/* Read the BARs, which either contain a mmapped IO address
or the IO port address. */
- addr = grub_pci_make_address (bus, device, func, 4 + 2 * i);
+ addr = grub_pci_make_address (dev, 4 + 2 * i);
bar1 = grub_pci_read (addr);
- addr = grub_pci_make_address (bus, device, func, 5 + 2 * i);
+ addr = grub_pci_make_address (dev, 5 + 2 * i);
bar2 = grub_pci_read (addr);
/* Check if the BARs describe an IO region. */
grub_dprintf ("ata",
"PCI dev (%d,%d,%d) compat=%d rega=0x%x regb=0x%x\n",
- bus, device, func, compat, rega, regb);
+ grub_pci_get_bus (dev), grub_pci_get_device (dev),
+ grub_pci_get_function (dev), compat, rega, regb);
if (rega && regb)
{
grub_outb (data, GRUB_PCI_DATA_REG + (addr & 3));
}
+static inline void
+grub_pci_close (grub_pci_device_t dev __attribute__ ((unused)))
+{
+}
+
#endif /* GRUB_CPU_PCI_H */
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2008 Free Software Foundation, Inc.
+ * Copyright (C) 2008,2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#define GRUB_PCI_ADDR_IO_MASK ~0x03
typedef grub_uint32_t grub_pci_id_t;
-typedef int NESTED_FUNC_ATTR (*grub_pci_iteratefunc_t)
- (int bus, int device, int func, grub_pci_id_t pciid);
+
+#ifdef GRUB_UTIL
+#include <grub/pciutils.h>
+#else
typedef grub_uint32_t grub_pci_address_t;
+struct grub_pci_device
+{
+ int bus;
+ int device;
+ int function;
+};
+typedef struct grub_pci_device grub_pci_device_t;
+static inline int
+grub_pci_get_bus (grub_pci_device_t dev)
+{
+ return dev.bus;
+}
-grub_pci_address_t EXPORT_FUNC(grub_pci_make_address) (int bus, int device,
- int function, int reg);
-
-void EXPORT_FUNC(grub_pci_iterate) (grub_pci_iteratefunc_t hook);
+static inline int
+grub_pci_get_device (grub_pci_device_t dev)
+{
+ return dev.device;
+}
+static inline int
+grub_pci_get_function (grub_pci_device_t dev)
+{
+ return dev.function;
+}
#include <grub/cpu/pci.h>
+#endif
+
+typedef int NESTED_FUNC_ATTR (*grub_pci_iteratefunc_t)
+ (grub_pci_device_t dev, grub_pci_id_t pciid);
+
+grub_pci_address_t EXPORT_FUNC(grub_pci_make_address) (grub_pci_device_t dev,
+ int reg);
+
+void EXPORT_FUNC(grub_pci_iterate) (grub_pci_iteratefunc_t hook);
#endif /* GRUB_PCI_H */
--- /dev/null
+/* pci.c - Generic PCI interfaces. */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2007,2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/pci.h>
+#include <grub/dl.h>
+
+struct pci_access *acc = 0;
+
+grub_pci_address_t
+grub_pci_make_address (grub_pci_device_t dev, int reg)
+{
+ grub_pci_address_t ret;
+ ret.dev = dev;
+ ret.pos = reg << 2;
+ return ret;
+}
+
+void
+grub_pci_close (grub_pci_device_t dev)
+{
+ pci_free_dev (dev);
+}
+
+void
+grub_pci_iterate (grub_pci_iteratefunc_t hook)
+{
+ grub_pci_device_t cur;
+ for (cur = acc->devices; cur; cur = cur->next)
+ hook (cur, cur->vendor_id|(cur->device_id << 16));
+}
+
+GRUB_MOD_INIT (pci)
+{
+ acc = pci_alloc ();
+ pci_init (acc);
+}
+
+GRUB_MOD_FINI (pci)
+{
+ pci_cleanup (acc);
+}