linux/arch/x86/pci/early.c
<<
>>
Prefs
   1#include <linux/kernel.h>
   2#include <linux/pci.h>
   3#include <asm/pci-direct.h>
   4#include <asm/io.h>
   5#include <asm/pci_x86.h>
   6
   7/* Direct PCI access. This is used for PCI accesses in early boot before
   8   the PCI subsystem works. */
   9
  10u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset)
  11{
  12        u32 v;
  13        outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
  14        v = inl(0xcfc);
  15        return v;
  16}
  17
  18u8 read_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset)
  19{
  20        u8 v;
  21        outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
  22        v = inb(0xcfc + (offset&3));
  23        return v;
  24}
  25
  26u16 read_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset)
  27{
  28        u16 v;
  29        outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
  30        v = inw(0xcfc + (offset&2));
  31        return v;
  32}
  33
  34void write_pci_config(u8 bus, u8 slot, u8 func, u8 offset,
  35                                    u32 val)
  36{
  37        outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
  38        outl(val, 0xcfc);
  39}
  40
  41void write_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset, u8 val)
  42{
  43        outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
  44        outb(val, 0xcfc + (offset&3));
  45}
  46
  47void write_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset, u16 val)
  48{
  49        outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
  50        outw(val, 0xcfc + (offset&2));
  51}
  52
  53int early_pci_allowed(void)
  54{
  55        return (pci_probe & (PCI_PROBE_CONF1|PCI_PROBE_NOEARLY)) ==
  56                        PCI_PROBE_CONF1;
  57}
  58
  59void early_dump_pci_device(u8 bus, u8 slot, u8 func)
  60{
  61        int i;
  62        int j;
  63        u32 val;
  64
  65        printk(KERN_INFO "pci 0000:%02x:%02x.%d config space:",
  66               bus, slot, func);
  67
  68        for (i = 0; i < 256; i += 4) {
  69                if (!(i & 0x0f))
  70                        printk("\n  %02x:",i);
  71
  72                val = read_pci_config(bus, slot, func, i);
  73                for (j = 0; j < 4; j++) {
  74                        printk(" %02x", val & 0xff);
  75                        val >>= 8;
  76                }
  77        }
  78        printk("\n");
  79}
  80
  81void early_dump_pci_devices(void)
  82{
  83        unsigned bus, slot, func;
  84
  85        if (!early_pci_allowed())
  86                return;
  87
  88        for (bus = 0; bus < 256; bus++) {
  89                for (slot = 0; slot < 32; slot++) {
  90                        for (func = 0; func < 8; func++) {
  91                                u32 class;
  92                                u8 type;
  93
  94                                class = read_pci_config(bus, slot, func,
  95                                                        PCI_CLASS_REVISION);
  96                                if (class == 0xffffffff)
  97                                        continue;
  98
  99                                early_dump_pci_device(bus, slot, func);
 100
 101                                if (func == 0) {
 102                                        type = read_pci_config_byte(bus, slot,
 103                                                                    func,
 104                                                               PCI_HEADER_TYPE);
 105                                        if (!(type & 0x80))
 106                                                break;
 107                                }
 108                        }
 109                }
 110        }
 111}
 112