From 3affd0ece8f6af300e6b33eb796da59bd46037a2 Mon Sep 17 00:00:00 2001 From: phcoder Date: Wed, 14 Oct 2009 10:11:59 +0200 Subject: [PATCH 1/5] libpci initial stuff --- Makefile.in | 2 ++ bus/pci.c | 23 ++++++++--------- bus/usb/ohci.c | 6 ++--- bus/usb/uhci.c | 6 ++--- commands/lspci.c | 11 +++++--- conf/i386-pc.rmk | 7 ++++- configure.ac | 11 +++++++- disk/ata.c | 11 ++++---- include/grub/i386/pci.h | 5 ++++ include/grub/pci.h | 45 ++++++++++++++++++++++++++------ util/pci.c | 57 +++++++++++++++++++++++++++++++++++++++++ 11 files changed, 147 insertions(+), 37 deletions(-) create mode 100644 util/pci.c diff --git a/Makefile.in b/Makefile.in index e0edbdb04..4e45dc569 100644 --- a/Makefile.in +++ b/Makefile.in @@ -100,12 +100,14 @@ endif 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@ diff --git a/bus/pci.c b/bus/pci.c index 2c29c03ab..fe4cad181 100644 --- a/bus/pci.c +++ b/bus/pci.c @@ -21,41 +21,40 @@ #include 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; diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index 32fb7cf91..5fe9c9507 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -113,7 +113,7 @@ grub_ohci_writereg32 (struct grub_ohci *o, /* 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; @@ -126,7 +126,7 @@ grub_ohci_pci_iter (int bus, int device, int func, 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; @@ -138,7 +138,7 @@ grub_ohci_pci_iter (int bus, int device, int func, 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 diff --git a/bus/usb/uhci.c b/bus/usb/uhci.c index 88ff5b3d8..0d3daa5f1 100644 --- a/bus/usb/uhci.c +++ b/bus/usb/uhci.c @@ -138,7 +138,7 @@ grub_uhci_portstatus (grub_usb_controller_t dev, /* 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; @@ -151,7 +151,7 @@ grub_uhci_pci_iter (int bus, int device, int func, 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; @@ -163,7 +163,7 @@ grub_uhci_pci_iter (int bus, int device, int func, 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)) diff --git a/commands/lspci.c b/commands/lspci.c index 5b3360a37..10618c7a9 100644 --- a/commands/lspci.c +++ b/commands/lspci.c @@ -115,15 +115,16 @@ grub_pci_get_class (int class, int subclass) } 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, @@ -142,6 +143,8 @@ grub_lspci_iter (int bus, int dev, int func, grub_pci_id_t pciid) grub_printf ("\n"); + grub_pci_close (dev); + return 0; } diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index bf8fbfb9d..107ae7a22 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -165,7 +165,12 @@ grub_emu_LDFLAGS = $(LIBCURSES) 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. diff --git a/configure.ac b/configure.ac index 3e4da66c8..5a98e3433 100644 --- a/configure.ac +++ b/configure.ac @@ -499,6 +499,10 @@ AC_ARG_ENABLE([grub-emu], 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 @@ -541,7 +545,7 @@ AC_CHECK_LIB([usb], [usb_claim_interface], [LIBUSB="-lusb"], 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 @@ -550,8 +554,13 @@ else 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], diff --git a/disk/ata.c b/disk/ata.c index 78d396526..ef6b44184 100644 --- a/disk/ata.c +++ b/disk/ata.c @@ -388,7 +388,7 @@ grub_ata_device_initialize (int port, int device, int addr, int addr2) } 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 }; @@ -402,7 +402,7 @@ grub_ata_pciinit (int bus, int device, int func, 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. */ @@ -429,9 +429,9 @@ grub_ata_pciinit (int bus, int device, int func, { /* 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. */ @@ -444,7 +444,8 @@ grub_ata_pciinit (int bus, int device, int func, 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) { diff --git a/include/grub/i386/pci.h b/include/grub/i386/pci.h index 996f64245..c8de9ff32 100644 --- a/include/grub/i386/pci.h +++ b/include/grub/i386/pci.h @@ -67,4 +67,9 @@ grub_pci_write_byte (grub_pci_address_t addr, grub_uint8_t data) 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 */ diff --git a/include/grub/pci.h b/include/grub/pci.h index 7c8b50528..2bea05410 100644 --- a/include/grub/pci.h +++ b/include/grub/pci.h @@ -1,6 +1,6 @@ /* * 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 @@ -36,15 +36,44 @@ #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); -typedef grub_uint32_t grub_pci_address_t; -grub_pci_address_t EXPORT_FUNC(grub_pci_make_address) (int bus, int device, - int function, int reg); +#ifdef GRUB_UTIL +#include +#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; +} + +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 +#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); -#include - #endif /* GRUB_PCI_H */ diff --git a/util/pci.c b/util/pci.c new file mode 100644 index 000000000..99962c31d --- /dev/null +++ b/util/pci.c @@ -0,0 +1,57 @@ +/* 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 . + */ + +#include +#include + +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); +} From 325c8258e7c31a5acea560cd9e9965a3a9d933c3 Mon Sep 17 00:00:00 2001 From: phcoder Date: Wed, 14 Oct 2009 10:36:37 +0200 Subject: [PATCH 2/5] lspci works in grub-emu --- commands/lspci.c | 6 +-- configure.ac | 35 +++++++++++++++- include/grub/i386/pci.h | 5 --- include/grub/pciutils.h | 88 +++++++++++++++++++++++++++++++++++++++++ util/pci.c | 7 +--- 5 files changed, 125 insertions(+), 16 deletions(-) create mode 100644 include/grub/pciutils.h diff --git a/commands/lspci.c b/commands/lspci.c index 10618c7a9..bcaafa4f8 100644 --- a/commands/lspci.c +++ b/commands/lspci.c @@ -143,8 +143,6 @@ grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) grub_printf ("\n"); - grub_pci_close (dev); - return 0; } @@ -159,13 +157,13 @@ grub_cmd_lspci (grub_command_t cmd __attribute__ ((unused)), static grub_command_t cmd; -GRUB_MOD_INIT(pci) +GRUB_MOD_INIT(lspci) { cmd = grub_register_command ("lspci", grub_cmd_lspci, 0, "List PCI devices"); } -GRUB_MOD_FINI(pci) +GRUB_MOD_FINI(lspci) { grub_unregister_command (cmd); } diff --git a/configure.ac b/configure.ac index 5a98e3433..ceb81881a 100644 --- a/configure.ac +++ b/configure.ac @@ -531,9 +531,14 @@ else enable_grub_emu=no grub_emu_usb_excuse="grub-emu isn't built" fi +if test x"$enable_grub_emu_pci" = xyes ; then + grub_emu_usb_excuse="conflicts with PCI support" +fi + if test x"$enable_grub_emu_usb" = xno ; then grub_emu_usb_excuse="explicitly disabled" fi + [if [ x"$grub_emu_usb_excuse" = x ]; then # Check for libusb libraries.] AC_CHECK_LIB([usb], [usb_claim_interface], [LIBUSB="-lusb"], @@ -555,7 +560,29 @@ enable_grub_emu_usb=no fi if test x"$enable_grub_emu_pci" != xyes ; then - enable_grub_emu_pci = no + grub_emu_pci_excuse="not enabled" +fi + +if test x"$enable_grub_emu_usb" = xyes ; then + grub_emu_pci_excuse="conflicts with USB support" +fi + +[if [ x"$grub_emu_pci_excuse" = x ]; then + # Check for libpci libraries.] + AC_CHECK_LIB([pci], [pci_alloc], [LIBPCI="-lpci"], + [grub_emu_pci_excuse=["need libpci library"]]) + AC_SUBST([LIBPCI]) +[fi] +[if [ x"$grub_emu_pci_excuse" = x ]; then + # Check for headers.] + AC_CHECK_HEADERS([pci/pci.h], [], + [grub_emu_pci_excuse=["need libpci headers"]]) +[fi] + +if test x"$grub_emu_pci_excuse" = x ; then +enable_grub_emu_pci=yes +else +enable_grub_emu_pci=no fi AC_SUBST([enable_grub_emu]) @@ -634,6 +661,12 @@ echo USB support for grub-emu: Yes else echo USB support for grub-emu: No "($grub_emu_usb_excuse)" fi +if [ x"$grub_emu_pci_excuse" = x ]; then +echo PCI support for grub-emu: Yes +else +echo PCI support for grub-emu: No "($grub_emu_pci_excuse)" +fi + if [ x"$enable_mm_debug" = xyes ]; then echo With memory debugging: Yes else diff --git a/include/grub/i386/pci.h b/include/grub/i386/pci.h index c8de9ff32..996f64245 100644 --- a/include/grub/i386/pci.h +++ b/include/grub/i386/pci.h @@ -67,9 +67,4 @@ grub_pci_write_byte (grub_pci_address_t addr, grub_uint8_t data) 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 */ diff --git a/include/grub/pciutils.h b/include/grub/pciutils.h new file mode 100644 index 000000000..5ce612fee --- /dev/null +++ b/include/grub/pciutils.h @@ -0,0 +1,88 @@ +/* + * GRUB -- GRand Unified Bootloader + * 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 + * 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 . + */ + +#ifndef GRUB_PCIUTILS_H +#define GRUB_PCIUTILS_H 1 + +#include + +typedef struct pci_dev *grub_pci_device_t; + +static inline int +grub_pci_get_bus (grub_pci_device_t dev) +{ + return dev->bus; +} + +static inline int +grub_pci_get_device (grub_pci_device_t dev) +{ + return dev->dev; +} + +static inline int +grub_pci_get_function (grub_pci_device_t dev) +{ + return dev->func; +} + +struct grub_pci_address +{ + grub_pci_device_t dev; + int pos; +}; + +typedef struct grub_pci_address grub_pci_address_t; + +static inline grub_uint32_t +grub_pci_read (grub_pci_address_t addr) +{ + return pci_read_long (addr.dev, addr.pos); +} + +static inline grub_uint16_t +grub_pci_read_word (grub_pci_address_t addr) +{ + return pci_read_word (addr.dev, addr.pos); +} + +static inline grub_uint8_t +grub_pci_read_byte (grub_pci_address_t addr) +{ + return pci_read_byte (addr.dev, addr.pos); +} + +static inline void +grub_pci_write (grub_pci_address_t addr, grub_uint32_t data) +{ + pci_write_long (addr.dev, addr.pos, data); +} + +static inline void +grub_pci_write_word (grub_pci_address_t addr, grub_uint16_t data) +{ + pci_write_word (addr.dev, addr.pos, data); +} + +static inline void +grub_pci_write_byte (grub_pci_address_t addr, grub_uint8_t data) +{ + pci_write_byte (addr.dev, addr.pos, data); +} + +#endif /* GRUB_PCIUTILS_H */ diff --git a/util/pci.c b/util/pci.c index 99962c31d..e17068149 100644 --- a/util/pci.c +++ b/util/pci.c @@ -31,12 +31,6 @@ grub_pci_make_address (grub_pci_device_t dev, int reg) return ret; } -void -grub_pci_close (grub_pci_device_t dev) -{ - pci_free_dev (dev); -} - void grub_pci_iterate (grub_pci_iteratefunc_t hook) { @@ -49,6 +43,7 @@ GRUB_MOD_INIT (pci) { acc = pci_alloc (); pci_init (acc); + pci_scan_bus (acc); } GRUB_MOD_FINI (pci) From 459fed4b98162b84b93b4e9b77ab2895bae29bf1 Mon Sep 17 00:00:00 2001 From: phcoder Date: Wed, 14 Oct 2009 18:17:18 +0200 Subject: [PATCH 3/5] pciaccess --- Makefile.in | 2 +- conf/i386-pc.rmk | 2 +- configure.ac | 8 ++++---- include/grub/i386/pci.h | 16 ++++++++++++++++ include/grub/pciutils.h | 31 ++++++++++++++++++++++-------- util/pci.c | 42 ++++++++++++++++++++++++++++++++--------- 6 files changed, 78 insertions(+), 23 deletions(-) diff --git a/Makefile.in b/Makefile.in index 4e45dc569..1733f1c01 100644 --- a/Makefile.in +++ b/Makefile.in @@ -100,7 +100,7 @@ endif AWK = @AWK@ LIBCURSES = @LIBCURSES@ LIBUSB = @LIBUSB@ -LIBPCI = @LIBPCI@ +LIBPCIACCESS = @LIBPCIACCESS@ YACC = @YACC@ UNIFONT_BDF = @UNIFONT_BDF@ diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index 107ae7a22..e4b89a8b9 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -170,7 +170,7 @@ endif ifeq ($(enable_grub_emu_pci), yes) grub_emu_SOURCES += util/pci.c commands/lspci.c -grub_emu_LDFLAGS += $(LIBPCI) +grub_emu_LDFLAGS += $(LIBPCIACCESS) endif # Scripts. diff --git a/configure.ac b/configure.ac index ceb81881a..5473ac3a3 100644 --- a/configure.ac +++ b/configure.ac @@ -569,14 +569,14 @@ fi [if [ x"$grub_emu_pci_excuse" = x ]; then # Check for libpci libraries.] - AC_CHECK_LIB([pci], [pci_alloc], [LIBPCI="-lpci"], - [grub_emu_pci_excuse=["need libpci library"]]) - AC_SUBST([LIBPCI]) + AC_CHECK_LIB([pciaccess], [pci_system_init], [LIBPCIACCESS="-lpciaccess"], + [grub_emu_pci_excuse=["need libpciaccess library"]]) + AC_SUBST([LIBPCIACCESS]) [fi] [if [ x"$grub_emu_pci_excuse" = x ]; then # Check for headers.] AC_CHECK_HEADERS([pci/pci.h], [], - [grub_emu_pci_excuse=["need libpci headers"]]) + [grub_emu_pci_excuse=["need libpciaccess headers"]]) [fi] if test x"$grub_emu_pci_excuse" = x ; then diff --git a/include/grub/i386/pci.h b/include/grub/i386/pci.h index 996f64245..5b5f5f0df 100644 --- a/include/grub/i386/pci.h +++ b/include/grub/i386/pci.h @@ -67,4 +67,20 @@ grub_pci_write_byte (grub_pci_address_t addr, grub_uint8_t data) grub_outb (data, GRUB_PCI_DATA_REG + (addr & 3)); } +static inline void * +grub_pci_device_map_range (grub_pci_device_t dev __attribute__ ((unused)), + grub_addr_t base, + grub_size_t size __attribute__ ((unused))) +{ + return (void *) base; +} + +static inline void +grub_pci_device_unmap_range (grub_pci_device_t dev __attribute__ ((unused)), + void *mem __attribute__ ((unused)), + grub_size_t size __attribute__ ((unused))) +{ +} + + #endif /* GRUB_CPU_PCI_H */ diff --git a/include/grub/pciutils.h b/include/grub/pciutils.h index 5ce612fee..36d47e5c8 100644 --- a/include/grub/pciutils.h +++ b/include/grub/pciutils.h @@ -19,9 +19,9 @@ #ifndef GRUB_PCIUTILS_H #define GRUB_PCIUTILS_H 1 -#include +#include -typedef struct pci_dev *grub_pci_device_t; +typedef struct pci_device *grub_pci_device_t; static inline int grub_pci_get_bus (grub_pci_device_t dev) @@ -52,37 +52,52 @@ typedef struct grub_pci_address grub_pci_address_t; static inline grub_uint32_t grub_pci_read (grub_pci_address_t addr) { - return pci_read_long (addr.dev, addr.pos); + grub_uint32_t ret; + pci_device_cfg_read_u32 (addr.dev, &ret, addr.pos); + return ret; } static inline grub_uint16_t grub_pci_read_word (grub_pci_address_t addr) { - return pci_read_word (addr.dev, addr.pos); + grub_uint16_t ret; + pci_device_cfg_read_u16 (addr.dev, &ret, addr.pos); + return ret; } static inline grub_uint8_t grub_pci_read_byte (grub_pci_address_t addr) { - return pci_read_byte (addr.dev, addr.pos); + grub_uint8_t ret; + pci_device_cfg_read_u8 (addr.dev, &ret, addr.pos); + return ret; } static inline void grub_pci_write (grub_pci_address_t addr, grub_uint32_t data) { - pci_write_long (addr.dev, addr.pos, data); + pci_device_cfg_write_u32 (addr.dev, data, addr.pos); } static inline void grub_pci_write_word (grub_pci_address_t addr, grub_uint16_t data) { - pci_write_word (addr.dev, addr.pos, data); + pci_device_cfg_write_u16 (addr.dev, data, addr.pos); } static inline void grub_pci_write_byte (grub_pci_address_t addr, grub_uint8_t data) { - pci_write_byte (addr.dev, addr.pos, data); + pci_device_cfg_write_u8 (addr.dev, data, addr.pos); } +void * +grub_pci_device_map_range (grub_pci_device_t dev, grub_addr_t base, + grub_size_t size); + +void +grub_pci_device_unmap_range (grub_pci_device_t dev, void *mem, + grub_size_t size); + + #endif /* GRUB_PCIUTILS_H */ diff --git a/util/pci.c b/util/pci.c index e17068149..8915068aa 100644 --- a/util/pci.c +++ b/util/pci.c @@ -19,8 +19,7 @@ #include #include - -struct pci_access *acc = 0; +#include grub_pci_address_t grub_pci_make_address (grub_pci_device_t dev, int reg) @@ -34,19 +33,44 @@ grub_pci_make_address (grub_pci_device_t dev, int reg) 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)); + struct pci_device_iterator *iter; + struct pci_slot_match slot; + struct pci_device *dev; + slot.domain = PCI_MATCH_ANY; + slot.bus = PCI_MATCH_ANY; + slot.dev = PCI_MATCH_ANY; + slot.func = PCI_MATCH_ANY; + iter = pci_slot_match_iterator_create (&slot); + while ((dev = pci_device_next (iter))) + hook (dev, dev->vendor_id | (dev->device_id << 16)); + pci_iterator_destroy (iter); +} + +void * +grub_pci_device_map_range (grub_pci_device_t dev, grub_addr_t base, + grub_size_t size) +{ + void *addr; + int err; + err = pci_device_map_range(dev, base, size, PCI_DEV_MAP_FLAG_WRITABLE, &addr); + if (err) + grub_util_error ("mapping 0x%x failed (error %d)\n", base, err); + return addr; +} + +void +grub_pci_device_unmap_range (grub_pci_device_t dev, void *mem, + grub_size_t size) +{ + pci_device_unmap_range (dev, mem, size); } GRUB_MOD_INIT (pci) { - acc = pci_alloc (); - pci_init (acc); - pci_scan_bus (acc); + pci_system_init (); } GRUB_MOD_FINI (pci) { - pci_cleanup (acc); + pci_system_cleanup (); } From 181aaf0e597d5e238de60337dc641f6a8f071318 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 30 Nov 2009 19:09:11 +0100 Subject: [PATCH 4/5] Merged mainline into pci --- commands/efi/fixvideo.c | 4 ++-- commands/efi/loadbios.c | 6 ++++-- loader/i386/efi/linux.c | 9 +++++---- loader/i386/efi/xnu.c | 9 +++++---- video/efi_uga.c | 9 +++++---- 5 files changed, 21 insertions(+), 16 deletions(-) diff --git a/commands/efi/fixvideo.c b/commands/efi/fixvideo.c index f97d83787..685662237 100644 --- a/commands/efi/fixvideo.c +++ b/commands/efi/fixvideo.c @@ -38,11 +38,11 @@ static struct grub_video_patch }; static int NESTED_FUNC_ATTR -scan_card (int bus, int dev, int func, grub_pci_id_t pciid) +scan_card (grub_pci_device_t dev, grub_pci_id_t pciid) { grub_pci_address_t addr; - addr = grub_pci_make_address (bus, dev, func, 2); + addr = grub_pci_make_address (dev, 2); if (grub_pci_read_byte (addr + 3) == 0x3) { struct grub_video_patch *p = video_patches; diff --git a/commands/efi/loadbios.c b/commands/efi/loadbios.c index 9967bb122..23586b269 100644 --- a/commands/efi/loadbios.c +++ b/commands/efi/loadbios.c @@ -41,6 +41,7 @@ enable_rom_area (void) { grub_pci_address_t addr; grub_uint32_t *rom_ptr; + grub_pci_device_t dev = { .bus = 0, .device = 0, .function = 0}; rom_ptr = (grub_uint32_t *) VBIOS_ADDR; if (*rom_ptr != BLANK_MEM) @@ -49,7 +50,7 @@ enable_rom_area (void) return 0; } - addr = grub_pci_make_address (0, 0, 0, 36); + addr = grub_pci_make_address (dev, 36); grub_pci_write_byte (addr++, 0x30); grub_pci_write_byte (addr++, 0x33); grub_pci_write_byte (addr++, 0x33); @@ -73,8 +74,9 @@ static void lock_rom_area (void) { grub_pci_address_t addr; + grub_pci_device_t dev = { .bus = 0, .device = 0, .function = 0}; - addr = grub_pci_make_address (0, 0, 0, 36); + addr = grub_pci_make_address (dev, 36); grub_pci_write_byte (addr++, 0x10); grub_pci_write_byte (addr++, 0x11); grub_pci_write_byte (addr++, 0x11); diff --git a/loader/i386/efi/linux.c b/loader/i386/efi/linux.c index f96c60e11..8cd4d23f2 100644 --- a/loader/i386/efi/linux.c +++ b/loader/i386/efi/linux.c @@ -469,21 +469,22 @@ find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len) { int found = 0; - auto int NESTED_FUNC_ATTR find_card (int bus, int dev, int func, + auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid); - int NESTED_FUNC_ATTR find_card (int bus, int dev, int func, + int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid) { grub_pci_address_t addr; - addr = grub_pci_make_address (bus, dev, func, 2); + addr = grub_pci_make_address (dev, 2); if (grub_pci_read (addr) >> 24 == 0x3) { int i; grub_printf ("Display controller: %d:%d.%d\nDevice id: %x\n", - bus, dev, func, pciid); + grub_pci_get_bus (dev), grub_pci_get_device (dev), + grub_pci_get_function (dev), pciid); addr += 8; for (i = 0; i < 6; i++, addr += 4) { diff --git a/loader/i386/efi/xnu.c b/loader/i386/efi/xnu.c index 5085cdbea..236732804 100644 --- a/loader/i386/efi/xnu.c +++ b/loader/i386/efi/xnu.c @@ -71,21 +71,22 @@ find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len) { int found = 0; - auto int NESTED_FUNC_ATTR find_card (int bus, int dev, int func, + auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid); - int NESTED_FUNC_ATTR find_card (int bus, int dev, int func, + int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid) { grub_pci_address_t addr; - addr = grub_pci_make_address (bus, dev, func, 2); + addr = grub_pci_make_address (dev, 2); if (grub_pci_read (addr) >> 24 == 0x3) { int i; grub_printf ("Display controller: %d:%d.%d\nDevice id: %x\n", - bus, dev, func, pciid); + grub_pci_get_bus (dev), grub_pci_get_device (dev), + grub_pci_get_function (dev), pciid); addr += 8; for (i = 0; i < 6; i++, addr += 4) { diff --git a/video/efi_uga.c b/video/efi_uga.c index 31062c5f5..9bca64306 100644 --- a/video/efi_uga.c +++ b/video/efi_uga.c @@ -84,21 +84,22 @@ find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len) { int found = 0; - auto int NESTED_FUNC_ATTR find_card (int bus, int dev, int func, + auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid); - int NESTED_FUNC_ATTR find_card (int bus, int dev, int func, + int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid) { grub_pci_address_t addr; - addr = grub_pci_make_address (bus, dev, func, 2); + addr = grub_pci_make_address (dev, 2); if (grub_pci_read (addr) >> 24 == 0x3) { int i; grub_dprintf ("fb", "Display controller: %d:%d.%d\nDevice id: %x\n", - bus, dev, func, pciid); + grub_pci_get_bus (dev), grub_pci_get_device (dev), + grub_pci_get_function (dev), pciid); addr += 8; for (i = 0; i < 6; i++, addr += 4) { From 14040ebf932c9b12f99ec71331f6c616e1552d2d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Dec 2009 09:03:51 +0100 Subject: [PATCH 5/5] ChangeLog --- ChangeLog.pciaccess | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 ChangeLog.pciaccess diff --git a/ChangeLog.pciaccess b/ChangeLog.pciaccess new file mode 100644 index 000000000..b402a3b60 --- /dev/null +++ b/ChangeLog.pciaccess @@ -0,0 +1,22 @@ +2009-12-02 Vladimir Serbinenko + + libpciaccess support. + + * Makefile.in (LIBPCIACCESS): New variable. + (enable_grub_emu_pci): Likewise. + * conf/any-emu.rmk (grub_emu_SOURCES) [enable_grub_emu_pci]: Add + util/pci.c and commands/lspci.c. + (grub_emu_LDFLAGS) [enable_grub_emu_pci]: Add $(LIBPCIACCESS). + * configure.ac (grub-emu-pci): New option. + * include/grub/i386/pci.h (grub_pci_device_map_range): New function. + (grub_pci_device_unmap_range): Likewise. + * include/grub/pci.h [GRUB_UTIL]: Include grub/pciutils.h. + (grub_pci_device) [!GRUB_UTIL]: New structure. All users updated. + (grub_pci_address_t) [!GRUB_UTIL]: New type. + (grub_pci_device_t) [!GRUB_UTIL]: Likewise. + (grub_pci_get_bus) [!GRUB_UTIL]: New function. + (grub_pci_get_device) [!GRUB_UTIL]: Likewise. + (grub_pci_get_function) [!GRUB_UTIL]: Likewise. + * include/grub/pciutils.h: New file. + * util/pci.c: Likewise. +