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 | ␊ |
10 | extern void set_eth_builtin(pci_dt_t *eth_dev);␊ |
11 | extern int ehci_acquire(pci_dt_t *pci_dev);␊ |
12 | extern int legacy_off(pci_dt_t *pci_dev);␊ |
13 | extern int uhci_reset(pci_dt_t *pci_dev);␊ |
14 | extern void force_enable_hpet(pci_dt_t *lpc_dev);␊ |
15 | ␊ |
16 | static 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 | ␊ |
47 | int hasPciToEfiMapping = -1;␉/* -1: not loaded, 0: does not exist, 1: loaded */␊ |
48 | ␊ |
49 | void setup_pci_devs(pci_dt_t *pci_dt)␊ |
50 | {␊ |
51 | ␉char *devicepath;␊ |
52 | ␉bool do_eth_devprop, do_gfx_devprop, fix_ehci, fix_legoff, fix_uhci, fix_usb, do_enable_hpet;␊ |
53 | ␉pci_dt_t *current = pci_dt;␊ |
54 | ␉char 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 | ␊ |
62 | ␉do_eth_devprop = do_gfx_devprop = fix_ehci = fix_legoff = fix_uhci = fix_usb = do_enable_hpet = false;␊ |
63 | ␊ |
64 | ␉getBoolForKey(kEthernetBuiltIn, &do_eth_devprop, &bootInfo->bootConfig);␊ |
65 | ␉getBoolForKey(kGraphicsEnabler, &do_gfx_devprop, &bootInfo->bootConfig);␊ |
66 | ␉if (getBoolForKey(kUSBBusFix, &fix_usb, &bootInfo->bootConfig) && fix_usb) {␊ |
67 | ␉␉fix_ehci = fix_uhci = true;␊ |
68 | ␉} else {␊ |
69 | ␉␉getBoolForKey(kEHCIacquire, &fix_ehci, &bootInfo->bootConfig);␊ |
70 | ␉␉getBoolForKey(kUHCIreset, &fix_uhci, &bootInfo->bootConfig);␊ |
71 | ␉}␊ |
72 | ␉getBoolForKey(kUSBLegacyOff, &fix_legoff, &bootInfo->bootConfig);␊ |
73 | ␉getBoolForKey(kForceHPET, &do_enable_hpet, &bootInfo->bootConfig);␊ |
74 | ␊ |
75 | ␉// Get some PCI stuff␊ |
76 | ␊ |
77 | ␉if (hasPciToEfiMapping == -1)␊ |
78 | {␊ |
79 | ␉ hasPciToEfiMapping = (loadSystemConfig("", &bootInfo->pciConfig, "pci.plist", true) == 0 ? 1 : 0);␊ |
80 | ␉ if (hasPciToEfiMapping) ␊ |
81 | ␉␉verbose("pci.plist is found.\n");␊ |
82 | ␉}␊ |
83 | ␊ |
84 | ␉while (current)␊ |
85 | ␉{␊ |
86 | ␉␉devicepath = get_pci_dev_path(current);␊ |
87 | ␊ |
88 | ␉␉switch (current->class_id)␊ |
89 | ␉␉{␊ |
90 | ␉␉␉case PCI_CLASS_NETWORK_ETHERNET: ␊ |
91 | ␉␉␉␉if (do_eth_devprop)␊ |
92 | ␉␉␉␉␉set_eth_builtin(current);␊ |
93 | ␉␉␉␉break;␊ |
94 | ␉␉␉␉␊ |
95 | ␉␉␉case PCI_CLASS_DISPLAY_VGA:␊ |
96 | ␉␉␉case PCI_CLASS_DISPLAY_OTHER:␊ |
97 | ␉␉␉␉if (do_gfx_devprop)␊ |
98 | ␉␉␉␉␉switch (current->vendor_id)␊ |
99 | ␉␉␉␉␉{␊ |
100 | ␉␉␉␉␉␉case PCI_VENDOR_ID_ATI:␊ |
101 | ␉␉␉␉␉␉␉verbose("ATI VGA Controller [%04x:%04x] :: %s \n", ␊ |
102 | ␉␉␉␉␉␉␉current->vendor_id, current->device_id, devicepath);␊ |
103 | ␉␉␉␉␉␉␉setup_ati_devprop(current); ␊ |
104 | ␉␉␉␉␉␉␉break;␊ |
105 | ␉␉␉␉␉␊ |
106 | ␉␉␉␉␉␉case PCI_VENDOR_ID_INTEL: ␊ |
107 | ␉␉␉␉␉␉␉verbose("Intel Graphics Controller [%04x:%04x] :: %s \n",␊ |
108 | ␉␉␉␉␉␉␉current->vendor_id, current->device_id, devicepath);␊ |
109 | ␉␉␉␉␉␉␉setup_gma_devprop(current);␊ |
110 | ␉␉␉␉␉␉␉break;␊ |
111 | ␉␉␉␉␉␉␉␊ |
112 | ␉␉␉␉␉␉case PCI_VENDOR_ID_NVIDIA: ␊ |
113 | ␉␉␉␉␉␉␉setup_nvidia_devprop(current);␊ |
114 | ␉␉␉␉␉␉␉break;␊ |
115 | ␉␉␉␉␉}␊ |
116 | ␉␉␉␉break;␊ |
117 | ␊ |
118 | ␉␉␉case PCI_CLASS_SERIAL_USB:␊ |
119 | ␉␉␉␉switch (pci_config_read8(current->dev.addr, PCI_CLASS_PROG))␊ |
120 | ␉␉␉␉{␊ |
121 | ␉␉␉␉␉/* EHCI */␊ |
122 | ␉␉␉␉␉case 0x20:␊ |
123 | ␉␉␉␉ ␉if (fix_ehci)␊ |
124 | ␉␉␉␉␉␉␉ehci_acquire(current);␊ |
125 | ␉␉␉␉␉␉if (fix_legoff)␊ |
126 | ␉␉␉␉␉␉␉legacy_off(current);␊ |
127 | ␉␉␉␉␉␉break;␊ |
128 | ␊ |
129 | ␉␉␉␉␉/* UHCI */␊ |
130 | ␉␉␉␉␉case 0x00:␊ |
131 | ␉␉␉␉ ␉if (fix_uhci)␊ |
132 | ␉␉␉␉␉␉␉uhci_reset(current);␊ |
133 | ␉␉␉␉␉␉break;␊ |
134 | ␉␉␉␉}␊ |
135 | ␉␉␉␉break;␊ |
136 | ␊ |
137 | ␉␉␉case PCI_CLASS_BRIDGE_ISA:␊ |
138 | ␉␉␉␉if (do_enable_hpet)␊ |
139 | ␉␉␉␉␉force_enable_hpet(current);␊ |
140 | ␉␉␉␉break;␊ |
141 | ␉␉}␊ |
142 | ␉␉␊ |
143 | ␉␉setup_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 | |