From 58c6922006416788153864a30c36cbc5d7759d8e Mon Sep 17 00:00:00 2001 From: marco_g Date: Sat, 2 Feb 2008 15:33:05 +0000 Subject: [PATCH] 2008-02-02 Marco Gerards * bus/pci.c: New file. * include/grub/pci.h: Likewise. * include/grub/i386/pc/pci.h: Likewise. * commands/lspci.c: Likewise. * conf/i386-pc.rmk (pkglib_MODULES): Add `pci.mod' and `lspci.mod'. (pci_mod_SOURCES): New variable. (pci_mod_CFLAGS): Likewise. (pci_mod_LDFLAGS): Likewise. (lspci_mod_SOURCES): Likewise. (lspci_mod_CFLAGS): Likewise. (lspci_mod_LDFLAGS): Likewise. --- ChangeLog | 19 +++++ bus/pci.c | 56 +++++++++++++ commands/lspci.c | 163 +++++++++++++++++++++++++++++++++++++ conf/i386-pc.mk | 106 +++++++++++++++++++++++- conf/i386-pc.rmk | 12 ++- include/grub/i386/pc/pci.h | 35 ++++++++ include/grub/pci.h | 37 +++++++++ 7 files changed, 426 insertions(+), 2 deletions(-) create mode 100644 bus/pci.c create mode 100644 commands/lspci.c create mode 100644 include/grub/i386/pc/pci.h create mode 100644 include/grub/pci.h diff --git a/ChangeLog b/ChangeLog index 6e4177f0a..7be624ced 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2008-02-02 Marco Gerards + + * bus/pci.c: New file. + + * include/grub/pci.h: Likewise. + + * include/grub/i386/pc/pci.h: Likewise. + + * commands/lspci.c: Likewise. + + * conf/i386-pc.rmk (pkglib_MODULES): Add `pci.mod' and + `lspci.mod'. + (pci_mod_SOURCES): New variable. + (pci_mod_CFLAGS): Likewise. + (pci_mod_LDFLAGS): Likewise. + (lspci_mod_SOURCES): Likewise. + (lspci_mod_CFLAGS): Likewise. + (lspci_mod_LDFLAGS): Likewise. + 2008-02-02 Bean * fs/ufs.c (INODE_BLKSZ): Fix incorrect value. diff --git a/bus/pci.c b/bus/pci.c new file mode 100644 index 000000000..a091f4982 --- /dev/null +++ b/bus/pci.c @@ -0,0 +1,56 @@ +/* pci.c - Generic PCI interfaces. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007 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 + +grub_pci_address_t +grub_pci_make_address (int bus, int device, int function, int reg) +{ + return (1 << 31) | (bus << 16) | (device << 11) | (function << 8) | (reg << 2); +} + +void +grub_pci_iterate (grub_pci_iteratefunc_t hook) +{ + int bus; + int dev; + int func; + grub_pci_address_t addr; + grub_pci_id_t id; + + for (bus = 0; bus < 256; bus++) + { + for (dev = 0; dev < 32; dev++) + { + for (func = 0; func < 3; func++) + { + addr = grub_pci_make_address (bus, dev, func, 0); + id = grub_pci_read (addr); + + /* Check if there is a device present. */ + if (id >> 16 == 0xFFFF) + continue; + + if (hook (bus, dev, func, id)) + return; + } + } + } +} diff --git a/commands/lspci.c b/commands/lspci.c new file mode 100644 index 000000000..d7d27834a --- /dev/null +++ b/commands/lspci.c @@ -0,0 +1,163 @@ +/* lspci.c - List PCI devices. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 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 +#include +#include + +struct grub_pci_classname +{ + int class; + int subclass; + char *desc; +}; + +static const struct grub_pci_classname grub_pci_classes[] = + { + { 0, 0, "" }, + { 1, 0, "SCSCI Controller" }, + { 1, 1, "IDE Controller" }, + { 1, 2, "Floppy Controller" }, + { 1, 3, "IPI Controller" }, + { 1, 4, "RAID Controller" }, + { 1, 0x80, "Mass storage Controller" }, + { 2, 0, "Ethernet Controller" }, + { 2, 1, "Token Ring Controller" }, + { 2, 2, "FDDI Controller" }, + { 2, 3, "ATM Controller" }, + { 2, 4, "ISDN Controller" }, + { 2, 0x80, "Network controller" }, + { 3, 0, "VGA Controller" }, + { 3, 1, "XGA Controller" }, + { 3, 2, "3D Controller" }, + { 3, 0x80, "Display Controller" }, + { 4, 0, "Multimedia Video Device" }, + { 4, 1, "Multimedia Audio Device" }, + { 4, 2, "Multimedia Telephony Device" }, + { 4, 0x80, "Multimedia device" }, + { 5, 0, "RAM Controller" }, + { 5, 1, "Flash Memory Controller" }, + { 5, 0x80, "Memory Controller" }, + { 6, 0, "Host Bridge" }, + { 6, 1, "ISA Bridge" }, + { 6, 2, "EISA Bride" }, + { 6, 3, "MCA Bridge" }, + { 6, 4, "PCI-PCI Bridge" }, + { 6, 5, "PCMCIA Bridge" }, + { 6, 6, "NuBus Bridge" }, + { 6, 7, "CardBus Bridge" }, + { 6, 8, "Raceway Bridge" }, + { 6, 0x80, "Unknown Bridge" }, + { 7, 0x80, "Communication controller" }, + { 8, 0x80, "System hardware" }, + { 9, 0, "Keyboard Controller" }, + { 9, 1, "Digitizer" }, + { 9, 2, "Mouse Controller" }, + { 9, 3, "Scanner Controller" }, + { 9, 4, "Gameport Controller" }, + { 9, 0x80, "Unknown Input Device" }, + { 10, 0, "Generic Docking Station" }, + { 10, 0x80, "Unkown Docking Station" }, + { 11, 0, "80386 Processor" }, + { 11, 1, "80486 Processor" }, + { 11, 2, "Pentium Processor" }, + { 11, 0x10, "Alpha Processor" }, + { 11, 0x20, "PowerPC Processor" }, + { 11, 0x30, "MIPS Processor" }, + { 11, 0x40, "Co-Processor" }, + { 11, 0x80, "Unkown Processor" }, + { 12, 0x80, "Serial Bus Controller" }, + { 13, 0x80, "Wireless Controller" }, + { 14, 0, "I2O" }, + { 15, 0, "iRDA Controller" }, + { 15, 1, "Consumer IR" }, + { 15, 0x10, "RF-Controller" }, + { 15, 0x80, "Satellite Communication Controller" }, + { 16, 0, "Network Decryption" }, + { 16, 1, "Entertainment Decryption" }, + { 16, 0x80, "Unkown Decryption Controller" }, + { 17, 0, "Digital IO Module" }, + { 17, 0x80, "Unkown Data Input System" }, + { 0, 0, 0 }, + }; + +static const char * +grub_pci_get_class (int class, int subclass) +{ + const struct grub_pci_classname *curr = grub_pci_classes; + + while (curr->desc) + { + if (curr->class == class && curr->subclass == subclass) + return curr->desc; + curr++; + } + + return 0; +} + +static int +grub_lspci_iter (int bus, int dev, int func, grub_pci_id_t pciid) +{ + grub_uint32_t class; + const char *sclass; + grub_pci_address_t addr; + + grub_printf ("%02x:%02x.%x %04x:%04x.%d", 0, dev, func, pciid >> 16, pciid & 0xFFFF, func); + addr = grub_pci_make_address (bus, dev, func, 2); + class = grub_pci_read (addr); + + /* Lookup the class name, if there isn't a specific one, + retry with 0x80 to get the generic class name. */ + sclass = grub_pci_get_class (class >> 24, (class >> 16) & 0xFF); + if (! sclass) + sclass = grub_pci_get_class (class >> 24, 0x80); + if (! sclass) + sclass = ""; + + grub_printf (" %s\n", sclass); + + return 0; +} + +static grub_err_t +grub_cmd_lspci (struct grub_arg_list *state __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) +{ + grub_pci_iterate (grub_lspci_iter); + return GRUB_ERR_NONE; +} + + + + +GRUB_MOD_INIT(pci) +{ + (void) mod; /* To stop warning. */ + grub_register_command ("lspci", grub_cmd_lspci, GRUB_COMMAND_FLAG_BOTH, + "lspci", "List PCI devices", 0); +} + + +GRUB_MOD_FINI(pci) +{ + grub_unregister_command ("lspci"); +} diff --git a/conf/i386-pc.mk b/conf/i386-pc.mk index 9c5b90f7f..215cba003 100644 --- a/conf/i386-pc.mk +++ b/conf/i386-pc.mk @@ -793,7 +793,7 @@ pkglib_MODULES = biosdisk.mod _chain.mod _linux.mod linux.mod normal.mod \ _multiboot.mod chain.mod multiboot.mod reboot.mod halt.mod \ vbe.mod vbetest.mod vbeinfo.mod video.mod gfxterm.mod \ videotest.mod play.mod bitmap.mod tga.mod cpuid.mod serial.mod \ - ata.mod vga.mod memdisk.mod jpeg.mod png.mod + ata.mod vga.mod memdisk.mod jpeg.mod png.mod pci.mod lspci.mod # For biosdisk.mod. biosdisk_mod_SOURCES = disk/i386/pc/biosdisk.c @@ -2457,4 +2457,108 @@ fs-png_mod-video_readers_png.lst: video/readers/png.c $(video/readers/png.c_DEPE png_mod_CFLAGS = $(COMMON_CFLAGS) png_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For pci.mod +pci_mod_SOURCES = bus/pci.c +CLEANFILES += pci.mod mod-pci.o mod-pci.c pre-pci.o pci_mod-bus_pci.o und-pci.lst +ifneq ($(pci_mod_EXPORTS),no) +CLEANFILES += def-pci.lst +DEFSYMFILES += def-pci.lst +endif +MOSTLYCLEANFILES += pci_mod-bus_pci.d +UNDSYMFILES += und-pci.lst + +pci.mod: pre-pci.o mod-pci.o + -rm -f $@ + $(TARGET_CC) $(pci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ $^ + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -R .note -R .comment $@ + +pre-pci.o: $(pci_mod_DEPENDENCIES) pci_mod-bus_pci.o + -rm -f $@ + $(TARGET_CC) $(pci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pci_mod-bus_pci.o + +mod-pci.o: mod-pci.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -c -o $@ $< + +mod-pci.c: moddep.lst genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'pci' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(pci_mod_EXPORTS),no) +def-pci.lst: pre-pci.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 pci/' > $@ +endif + +und-pci.lst: pre-pci.o + echo 'pci' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +pci_mod-bus_pci.o: bus/pci.c $(bus/pci.c_DEPENDENCIES) + $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -MD -c -o $@ $< +-include pci_mod-bus_pci.d + +CLEANFILES += cmd-pci_mod-bus_pci.lst fs-pci_mod-bus_pci.lst +COMMANDFILES += cmd-pci_mod-bus_pci.lst +FSFILES += fs-pci_mod-bus_pci.lst + +cmd-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh pci > $@ || (rm -f $@; exit 1) + +fs-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh pci > $@ || (rm -f $@; exit 1) + + +pci_mod_CFLAGS = $(COMMON_CFLAGS) +pci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For lspci.mod +lspci_mod_SOURCES = commands/lspci.c +CLEANFILES += lspci.mod mod-lspci.o mod-lspci.c pre-lspci.o lspci_mod-commands_lspci.o und-lspci.lst +ifneq ($(lspci_mod_EXPORTS),no) +CLEANFILES += def-lspci.lst +DEFSYMFILES += def-lspci.lst +endif +MOSTLYCLEANFILES += lspci_mod-commands_lspci.d +UNDSYMFILES += und-lspci.lst + +lspci.mod: pre-lspci.o mod-lspci.o + -rm -f $@ + $(TARGET_CC) $(lspci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ $^ + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -R .note -R .comment $@ + +pre-lspci.o: $(lspci_mod_DEPENDENCIES) lspci_mod-commands_lspci.o + -rm -f $@ + $(TARGET_CC) $(lspci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ lspci_mod-commands_lspci.o + +mod-lspci.o: mod-lspci.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -c -o $@ $< + +mod-lspci.c: moddep.lst genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'lspci' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(lspci_mod_EXPORTS),no) +def-lspci.lst: pre-lspci.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 lspci/' > $@ +endif + +und-lspci.lst: pre-lspci.o + echo 'lspci' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +lspci_mod-commands_lspci.o: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -MD -c -o $@ $< +-include lspci_mod-commands_lspci.d + +CLEANFILES += cmd-lspci_mod-commands_lspci.lst fs-lspci_mod-commands_lspci.lst +COMMANDFILES += cmd-lspci_mod-commands_lspci.lst +FSFILES += fs-lspci_mod-commands_lspci.lst + +cmd-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh lspci > $@ || (rm -f $@; exit 1) + +fs-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh lspci > $@ || (rm -f $@; exit 1) + + +lspci_mod_CFLAGS = $(COMMON_CFLAGS) +lspci_mod_LDFLAGS = $(COMMON_LDFLAGS) + include $(srcdir)/conf/common.mk diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index 747b7935c..6b1f991c1 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -140,7 +140,7 @@ pkglib_MODULES = biosdisk.mod _chain.mod _linux.mod linux.mod normal.mod \ _multiboot.mod chain.mod multiboot.mod reboot.mod halt.mod \ vbe.mod vbetest.mod vbeinfo.mod video.mod gfxterm.mod \ videotest.mod play.mod bitmap.mod tga.mod cpuid.mod serial.mod \ - ata.mod vga.mod memdisk.mod jpeg.mod png.mod + ata.mod vga.mod memdisk.mod jpeg.mod png.mod pci.mod lspci.mod # For biosdisk.mod. biosdisk_mod_SOURCES = disk/i386/pc/biosdisk.c @@ -282,4 +282,14 @@ png_mod_SOURCES = video/readers/png.c png_mod_CFLAGS = $(COMMON_CFLAGS) png_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For pci.mod +pci_mod_SOURCES = bus/pci.c +pci_mod_CFLAGS = $(COMMON_CFLAGS) +pci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For lspci.mod +lspci_mod_SOURCES = commands/lspci.c +lspci_mod_CFLAGS = $(COMMON_CFLAGS) +lspci_mod_LDFLAGS = $(COMMON_LDFLAGS) + include $(srcdir)/conf/common.mk diff --git a/include/grub/i386/pc/pci.h b/include/grub/i386/pc/pci.h new file mode 100644 index 000000000..f4f08ab11 --- /dev/null +++ b/include/grub/i386/pc/pci.h @@ -0,0 +1,35 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 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_CPU_PCI_H +#define GRUB_CPU_PCI_H 1 + +#include +#include + +#define GRUB_PCI_ADDR_REG 0xcf8 +#define GRUB_PCI_DATA_REG 0xcfc + +static inline grub_uint32_t +grub_pci_read (grub_pci_address_t addr) +{ + grub_outl (addr, GRUB_PCI_ADDR_REG); + return grub_inl (GRUB_PCI_DATA_REG); +} + +#endif /* GRUB_CPU_PCI_H */ diff --git a/include/grub/pci.h b/include/grub/pci.h new file mode 100644 index 000000000..71088867b --- /dev/null +++ b/include/grub/pci.h @@ -0,0 +1,37 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 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_PCI_H +#define GRUB_PCI_H 1 + +#include +#include + +typedef grub_uint32_t grub_pci_id_t; +typedef int (*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); + +void EXPORT_FUNC(grub_pci_iterate) (grub_pci_iteratefunc_t hook); + +#include + +#endif /* GRUB_PCI_H */