Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2 | pj | 1 | #include <ll/i386/hw-instr.h> |
2 | #include <ll/i386/hw-data.h> |
||
3 | #include <ll/i386/hw-arch.h> |
||
4 | #include <ll/i386/hw-io.h> |
||
5 | #include <ll/i386/cons.h> |
||
6 | |||
7 | #include <ll/stdlib.h> |
||
8 | |||
9 | |||
10 | |||
11 | #include <drivers/llpci.h> |
||
12 | #include <drivers/pci.h> |
||
13 | #include <drivers/linuxpci.h> |
||
14 | |||
15 | static int ndev = 0; |
||
16 | static struct pci_des pci_devs[N_MAX_DEVS]; |
||
17 | |||
18 | /* scan the bus to find all the connected devices */ |
||
19 | int scan_bus(struct pci_des *p_des) |
||
20 | { |
||
21 | int ndev; |
||
22 | DWORD tmp; |
||
23 | BYTE hdr; |
||
24 | int j, ok; |
||
25 | BYTE bus, b; |
||
26 | WORD dev; |
||
27 | int present; |
||
28 | |||
29 | if (pcibios_present() == 0) return -1; |
||
30 | ndev = 0; |
||
31 | |||
32 | for (bus = 0; bus <= 0; bus++) { |
||
33 | for (dev = 0; dev <= 0xFF; dev++) { |
||
34 | present = 0; |
||
35 | if ((dev & 0x07) == 0) { |
||
36 | present = pcibios_read_config_byte(bus, dev, 0x0e, &hdr); |
||
37 | } |
||
38 | if (hdr & 0x80) { |
||
39 | present = 1; |
||
40 | } |
||
41 | if (present) { |
||
42 | ok = pcibios_read_config_dword(bus, dev, 0, &tmp); |
||
43 | if ( ok && (((tmp & 0xFFFF) != 0xFFFF) && ((tmp >> 16) != 0xFFFF))) { |
||
44 | p_des[ndev].bus = bus; |
||
45 | p_des[ndev].dev = dev; |
||
46 | for (j = 0; j <= 255; j++) { |
||
47 | pcibios_read_config_byte(bus, dev, j, &b); |
||
48 | p_des[ndev].mem[j] = b; |
||
49 | } |
||
50 | ndev++; |
||
51 | } |
||
52 | } |
||
53 | } |
||
54 | } |
||
55 | return ndev; |
||
56 | } |
||
57 | |||
58 | struct pci_regs *pci_device(WORD vendor, WORD device, WORD index, BYTE *bus, BYTE *dev) |
||
59 | { |
||
60 | int i, curr; |
||
61 | struct pci_regs *regs; |
||
62 | |||
63 | curr = 0; |
||
64 | for (i = 0; i < ndev; i++) { |
||
65 | regs = (struct pci_regs *)pci_devs[i].mem; |
||
66 | if ((regs->VendorId == vendor) && (regs->DeviceId == device)) { |
||
67 | if (curr == index) { |
||
68 | *dev = pci_devs[i].dev; |
||
69 | *bus = pci_devs[i].bus; |
||
70 | return regs; |
||
71 | } |
||
72 | ++curr; |
||
73 | } |
||
74 | } |
||
75 | return NULL; |
||
76 | } |
||
77 | |||
78 | struct pci_regs *pci_class(DWORD class_code, WORD index, BYTE *bus, BYTE *dev) |
||
79 | { |
||
80 | int i, curr; |
||
81 | struct pci_regs *regs; |
||
82 | |||
83 | curr = 0; |
||
84 | for (i = 0; i < ndev; i++) { |
||
85 | regs = (struct pci_regs *)pci_devs[i].mem; |
||
86 | if ((regs->ClassCode << 8) == class_code) { |
||
87 | if (curr == index) { |
||
88 | *dev = pci_devs[i].dev; |
||
89 | *bus = pci_devs[i].bus; |
||
90 | return regs; |
||
91 | } |
||
92 | ++curr; |
||
93 | } |
||
94 | } |
||
95 | return NULL; |
||
96 | } |
||
97 | |||
98 | int pcibios_find_device(WORD vendor, WORD device, WORD index, BYTE *bus, BYTE *dev) |
||
99 | { |
||
100 | |||
101 | if (pci_device(vendor, device, index, bus, dev) != NULL) { |
||
102 | return PCIBIOS_SUCCESSFUL; |
||
103 | } else { |
||
104 | return PCIBIOS_DEVICE_NOT_FOUND; |
||
105 | } |
||
106 | } |
||
107 | int pcibios_find_class(DWORD class_code, WORD index, BYTE *bus, BYTE *dev) |
||
108 | { |
||
109 | |||
110 | if (pci_class(class_code, index, bus, dev) != NULL) { |
||
111 | cprintf("PCIBIOS_FIND_CLASS: found at bus %d, dev %d\n", *bus, *dev); |
||
112 | return PCIBIOS_SUCCESSFUL; |
||
113 | } else { |
||
114 | return PCIBIOS_DEVICE_NOT_FOUND; |
||
115 | } |
||
116 | } |
||
117 | |||
118 | |||
119 | /* shows the detected devices */ |
||
120 | void pci_show(void) |
||
121 | { |
||
122 | int i; |
||
123 | struct pci_regs *r; |
||
124 | |||
125 | cprintf(" DevLib PCI support\n\n"); |
||
126 | cprintf(" PCI config type %d\n", pcibios_present()); |
||
127 | cprintf(" %d PCI devices found:\n\n", ndev); |
||
128 | for(i = 0; i < ndev; i++) { |
||
129 | cprintf(" %d: bus %d dev %d\n",i , pci_devs[i].bus, pci_devs[i].dev); |
||
130 | r = (struct pci_regs *) pci_devs[i].mem; |
||
131 | cprintf(" Vendor: %s", pci_strvendor(r->VendorId)); |
||
132 | cprintf(" Class: %s\n", pci_strclass(r->ClassCode << 8)); |
||
133 | } |
||
134 | } |
||
135 | |||
136 | /*Linux-->unsigned long pci_init(unsigned long mem_start, unsigned long mem_end) */ |
||
137 | /* H-PCI --> void pci_init(void) */ |
||
138 | /* (mem_start/mem_end have no sense) */ |
||
139 | |||
140 | int pci_init(void) |
||
141 | { |
||
142 | if (pcibios_init() == -1) { |
||
143 | return -1; |
||
144 | } |
||
145 | ndev = scan_bus(pci_devs); |
||
146 | return 1; |
||
147 | } |