Blame view

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