Chameleon

Chameleon Svn Source Tree

Root/branches/andyvand/i386/libsaio/pci_setup.c

1#include "libsaio.h"
2#include "boot.h"
3#include "bootstruct.h"
4#include "pci.h"
5#include "nvidia.h"
6#include "ati.h"
7#include "gma.h"
8#include "device_inject.h"
9
10extern void set_eth_builtin(pci_dt_t *eth_dev);
11extern int ehci_acquire(pci_dt_t *pci_dev);
12extern int legacy_off(pci_dt_t *pci_dev);
13extern int uhci_reset(pci_dt_t *pci_dev);
14extern void force_enable_hpet(pci_dt_t *lpc_dev);
15
16static int PciToEfiOverride(const char * propKey,
17 unsigned long numbers[],
18 unsigned long maxArrayCount )
19{
20 char * propStr;
21 unsigned long count = 0;
22
23 propStr = newStringForKey( (char *) propKey , &bootInfo->pciConfig );
24 if ( propStr )
25 {
26 char * delimiter = propStr;
27 char * p = propStr;
28
29 while ( count < maxArrayCount && *p != '\0' )
30 {
31 unsigned long val = strtoul( p, &delimiter, 16 );
32 if ( p != delimiter )
33 {
34 numbers[count++] = val;
35 p = delimiter;
36 }
37 while ( ( *p != '\0' ) && !isdigit(*p) )
38 p++;
39 }
40
41 free( propStr );
42 }
43
44 return count;
45}
46
47int hasPciToEfiMapping = -1;/* -1: not loaded, 0: does not exist, 1: loaded */
48
49void setup_pci_devs(pci_dt_t *pci_dt)
50{
51char *devicepath;
52bool do_eth_devprop, do_gfx_devprop, fix_ehci, fix_legoff, fix_uhci, fix_usb, do_enable_hpet;
53pci_dt_t *current = pci_dt;
54char override_key[512];
55 unsigned long id_array[4];
56 int id_count;
57 char* id_keys[4] = { "vendor-id", "device-id", "subsystem-vendor-id", "subsystem-id" };
58 int i;
59 struct DevPropDevice* device;
60 struct DevPropString *deviceString;
61
62do_eth_devprop = do_gfx_devprop = fix_ehci = fix_legoff = fix_uhci = fix_usb = do_enable_hpet = false;
63
64getBoolForKey(kEthernetBuiltIn, &do_eth_devprop, &bootInfo->bootConfig);
65getBoolForKey(kGraphicsEnabler, &do_gfx_devprop, &bootInfo->bootConfig);
66if (getBoolForKey(kUSBBusFix, &fix_usb, &bootInfo->bootConfig) && fix_usb) {
67fix_ehci = fix_uhci = true;
68} else {
69getBoolForKey(kEHCIacquire, &fix_ehci, &bootInfo->bootConfig);
70getBoolForKey(kUHCIreset, &fix_uhci, &bootInfo->bootConfig);
71}
72getBoolForKey(kUSBLegacyOff, &fix_legoff, &bootInfo->bootConfig);
73getBoolForKey(kForceHPET, &do_enable_hpet, &bootInfo->bootConfig);
74
75// Get some PCI stuff
76
77if (hasPciToEfiMapping == -1)
78 {
79 hasPciToEfiMapping = (loadSystemConfig("", &bootInfo->pciConfig, "pci.plist", true) == 0 ? 1 : 0);
80 if (hasPciToEfiMapping)
81verbose("pci.plist is found.\n");
82}
83
84while (current)
85{
86devicepath = get_pci_dev_path(current);
87
88switch (current->class_id)
89{
90case PCI_CLASS_NETWORK_ETHERNET:
91if (do_eth_devprop)
92set_eth_builtin(current);
93break;
94
95case PCI_CLASS_DISPLAY_VGA:
96case PCI_CLASS_DISPLAY_OTHER:
97if (do_gfx_devprop)
98switch (current->vendor_id)
99{
100case PCI_VENDOR_ID_ATI:
101verbose("ATI VGA Controller [%04x:%04x] :: %s \n",
102current->vendor_id, current->device_id, devicepath);
103setup_ati_devprop(current);
104break;
105
106case PCI_VENDOR_ID_INTEL:
107verbose("Intel Graphics Controller [%04x:%04x] :: %s \n",
108current->vendor_id, current->device_id, devicepath);
109setup_gma_devprop(current);
110break;
111
112case PCI_VENDOR_ID_NVIDIA:
113setup_nvidia_devprop(current);
114break;
115}
116break;
117
118case PCI_CLASS_SERIAL_USB:
119switch (pci_config_read8(current->dev.addr, PCI_CLASS_PROG))
120{
121/* EHCI */
122case 0x20:
123 if (fix_ehci)
124ehci_acquire(current);
125if (fix_legoff)
126legacy_off(current);
127break;
128
129/* UHCI */
130case 0x00:
131 if (fix_uhci)
132uhci_reset(current);
133break;
134}
135break;
136
137case PCI_CLASS_BRIDGE_ISA:
138if (do_enable_hpet)
139force_enable_hpet(current);
140break;
141}
142
143setup_pci_devs(current->children);
144
145 if (hasPciToEfiMapping)
146 {
147 /* Device ID override injection */
148 memset(id_array, sizeof(id_array), 0);
149 sprintf(override_key, "pci%04x,%04x", current->vendor_id, current->device_id);
150 id_count = PciToEfiOverride(override_key, id_array, 4);
151 device = NULL;
152
153 for (i = 0; i < id_count; i++)
154 {
155 uint8_t fourOctets[4];
156 uint32_t id = id_array[i];
157 if (id == 0)
158 {
159 if (i == 0)
160 id = current->vendor_id;
161 else if (i == 1)
162 id = current->device_id;
163 else
164 continue;
165 }
166
167 fourOctets[0] = id;
168 fourOctets[1] = id >> 8;
169 fourOctets[2] = 0;
170 fourOctets[3] = 0;
171 if (id != 0)
172 {
173 if (device == NULL)
174 {
175 device = devprop_find_device(devicepath);
176 if (device == NULL)
177 {
178 deviceString = devprop_create_string();
179 device = devprop_add_device(deviceString, devicepath);
180 }
181 }
182 devprop_add_value(device, id_keys[i], fourOctets, sizeof(fourOctets));
183 verbose("%s: %s 0x%02x\n", override_key, id_keys[i], id);
184 }
185 }
186 }
187
188 current = current->next;
189 }
190}
191

Archive Download this file

Revision: 141