1 | /*␊ |
2 | * Copyright 2008 mackerintel␊ |
3 | */␊ |
4 | ␊ |
5 | /*␊ |
6 | * cparm : cleaned, moved into a module␊ |
7 | */␊ |
8 | ␊ |
9 | #include "libsaio.h"␊ |
10 | #include "boot.h"␊ |
11 | #include "bootstruct.h"␊ |
12 | #include "acpi.h"␊ |
13 | #include "efi_tables.h"␊ |
14 | #include "fake_efi.h"␊ |
15 | #include "acpi_patcher.h"␊ |
16 | #include "platform.h"␊ |
17 | #include "cpu.h"␊ |
18 | #include "aml_generator.h"␊ |
19 | #include "modules.h"␊ |
20 | #include "xml.h"␊ |
21 | ␊ |
22 | #ifndef DEBUG_ACPI␊ |
23 | #define DEBUG_ACPI 0␊ |
24 | #endif␊ |
25 | ␊ |
26 | #if DEBUG_ACPI==2␊ |
27 | #define DBG(x...) {printf(x); sleep(1);}␊ |
28 | #elif DEBUG_ACPI==1␊ |
29 | #define DBG(x...) printf(x)␊ |
30 | #else␊ |
31 | #define DBG(x...)␊ |
32 | #endif␊ |
33 | ␊ |
34 | ␊ |
35 | extern uint64_t acpi10_p;␊ |
36 | extern uint64_t acpi20_p;␊ |
37 | extern EFI_STATUS addConfigurationTable();␊ |
38 | ␊ |
39 | extern EFI_GUID gEfiAcpiTableGuid;␊ |
40 | extern EFI_GUID gEfiAcpi20TableGuid;␊ |
41 | ␊ |
42 | ␊ |
43 | #define __RES(s, u)␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
44 | static inline unsigned u␉␉␉␉␉␉␉␉␉␉\␊ |
45 | resolve_##s(unsigned u defaultentry, char *str, int base) \␊ |
46 | {␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
47 | ␉unsigned u entry = defaultentry;␉␉␉␉␉␉␉\␊ |
48 | ␉if (str && (strcmp(str,"Default") != 0)) {␉␉␉␉␉\␊ |
49 | ␉entry = strtoul((const char *)str, NULL,base);␉␉␉␉\␊ |
50 | ␉}␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
51 | ␉return entry;␉␉␉␉␉␉␉␉␉␉␉␉\␊ |
52 | }␊ |
53 | ␊ |
54 | __RES(pss, long) ␊ |
55 | __RES(cst, int) ␊ |
56 | ␊ |
57 | #define tableSign(table, sgn) (table[0]==sgn[0] && table[1]==sgn[1] && table[2]==sgn[2] && table[3]==sgn[3])␊ |
58 | ␊ |
59 | void *loadSSDTTable(int ssdt_number)␊ |
60 | {␉␊ |
61 | ␉int fd = -1;␊ |
62 | ␉char dirspec[512];␊ |
63 | ␉char filename[512];␊ |
64 | ␉const char * overriden_pathname=NULL;␊ |
65 | ␉int len=0;␊ |
66 | ␉␊ |
67 | ␉// Check booting partition␊ |
68 | ␉␊ |
69 | ␉// Rek: if user specified a full path name then take it in consideration␊ |
70 | ␉if (getValueForKey(kSSDT, &overriden_pathname, &len, ␊ |
71 | ␉␉␉␉␉ &bootInfo->bootConfig))␊ |
72 | ␉{␊ |
73 | ␉␉sprintf(filename, "%s-%d.aml", overriden_pathname, ssdt_number); // start searching root␉␉␊ |
74 | ␉}␊ |
75 | ␉else␊ |
76 | ␉␉sprintf(filename, "SSDT-%d.aml", ssdt_number);␊ |
77 | ␉␊ |
78 | ␉sprintf(dirspec, "/%s", filename); // start searching root␊ |
79 | ␉␊ |
80 | ␉fd=open (dirspec,0);␊ |
81 | ␉␊ |
82 | ␉if (fd<0)␊ |
83 | ␉{␉// Check Extra on booting partition␊ |
84 | ␉␉sprintf(dirspec,"/Extra/%s",filename);␊ |
85 | ␉␉fd=open (dirspec,0);␊ |
86 | ␉␉if (fd<0)␊ |
87 | ␉␉{␉// Fall back to booter partition␊ |
88 | ␉␉␉sprintf(dirspec,"bt(0,0)/Extra/%s",filename);␊ |
89 | ␉␉␉fd=open (dirspec,0);␊ |
90 | ␉␉␉if (fd<0)␊ |
91 | ␉␉␉{␊ |
92 | ␉␉␉␉DBG("SSDT Table not found: %s\n", filename);␊ |
93 | ␉␉␉␉return NULL;␊ |
94 | ␉␉␉}␊ |
95 | ␉␉}␊ |
96 | ␉}␉␊ |
97 | ␉␊ |
98 | ␉void *tableAddr=(void*)AllocateKernelMemory(file_size (fd));␊ |
99 | ␉if (tableAddr)␊ |
100 | ␉{␊ |
101 | ␉␉if (read (fd, tableAddr, file_size (fd))!=file_size (fd))␊ |
102 | ␉␉{␊ |
103 | ␉␉␉printf("Couldn't read table %s\n",dirspec);␊ |
104 | ␉␉␉free (tableAddr);␊ |
105 | ␉␉␉close (fd);␊ |
106 | ␉␉␉return NULL;␊ |
107 | ␉␉}␊ |
108 | ␉␉␊ |
109 | ␉␉printf("Valid SSDT Table found: %s\n", filename);␊ |
110 | ␉␉DBG("Table %s read and stored at: %x\n", dirspec, tableAddr);␊ |
111 | ␉␉close (fd);␊ |
112 | ␉␉return tableAddr;␊ |
113 | ␉}␊ |
114 | ␉␊ |
115 | ␉printf("Couldn't allocate memory for table %s\n", dirspec);␊ |
116 | ␉close (fd);␊ |
117 | ␉␊ |
118 | ␉return NULL;␊ |
119 | }␊ |
120 | ␊ |
121 | void *loadACPITable(char *key)␊ |
122 | {␉␊ |
123 | ␉int fd = -1;␊ |
124 | ␉char dirspec[512];␊ |
125 | ␉char filename[512];␊ |
126 | ␉const char * overriden_pathname=NULL;␊ |
127 | ␉int len=0;␊ |
128 | ␉␉␊ |
129 | ␉DBG("Searching for %s.aml file ...\n", key);␊ |
130 | ␉// Check booting partition␉␊ |
131 | ␊ |
132 | ␉// Rek: if user specified a full path name then take it in consideration␊ |
133 | ␉if (getValueForKey(key, &overriden_pathname, &len, ␊ |
134 | ␉␉␉␉␉ &bootInfo->bootConfig))␊ |
135 | ␉{␉␉␊ |
136 | ␉␉sprintf(filename, "%s", overriden_pathname);␉␉␊ |
137 | ␉}␊ |
138 | ␉else␉␉␊ |
139 | ␉␉sprintf(filename, "%s.aml", key);␊ |
140 | ␉␉␊ |
141 | ␉␊ |
142 | ␉sprintf(dirspec, "/%s", filename); // start searching root␊ |
143 | ␉␊ |
144 | ␉fd=open (dirspec,0);␊ |
145 | ␉␊ |
146 | ␉if (fd<0)␊ |
147 | ␉{␉␊ |
148 | ␉␉// Check Extra on booting partition␊ |
149 | ␉␉sprintf(dirspec,"/Extra/%s",filename);␊ |
150 | ␉␉fd=open (dirspec,0);␊ |
151 | ␉␉if (fd<0)␊ |
152 | ␉␉{␉// Fall back to booter partition␊ |
153 | ␉␉␉sprintf(dirspec,"bt(0,0)/Extra/%s",filename);␊ |
154 | ␉␉␉fd=open (dirspec,0);␊ |
155 | ␉␉␉if (fd<0)␊ |
156 | ␉␉␉{␉␉␉␉␊ |
157 | ␉␉␉␉DBG("ACPI Table not found: %s\n", key);␊ |
158 | ␉␉␉␉return NULL;␊ |
159 | ␉␉␉}␊ |
160 | ␉␉␉␊ |
161 | ␉␉}␊ |
162 | ␉␉␊ |
163 | ␉}␉␉␊ |
164 | ␉␊ |
165 | ␉void *tableAddr=(void*)AllocateKernelMemory(file_size (fd));␊ |
166 | ␉if (tableAddr)␊ |
167 | ␉{␊ |
168 | ␉␉if (read (fd, tableAddr, file_size (fd))!=file_size (fd))␊ |
169 | ␉␉{␊ |
170 | ␉␉␉printf("Couldn't read table %s\n",key);␊ |
171 | ␉␉␉free (tableAddr);␊ |
172 | ␉␉␉close (fd);␊ |
173 | ␉␉␉return NULL;␊ |
174 | ␉␉}␊ |
175 | ␉␉verbose("Valid ACPI Table found: %s\n", key);␊ |
176 | ␉␉DBG("Table %s read and stored at: %x\n", key, tableAddr);␊ |
177 | ␉␉close (fd);␊ |
178 | ␉␉return tableAddr;␊ |
179 | ␉}␊ |
180 | ␉␊ |
181 | ␉printf("Couldn't allocate memory for table %s\n", key);␊ |
182 | ␉close (fd);␊ |
183 | ␉␊ |
184 | ␉return NULL;␊ |
185 | }␊ |
186 | ␊ |
187 | uint8_t␉acpi_cpu_count = 0;␊ |
188 | char* acpi_cpu_name[32];␊ |
189 | ␊ |
190 | void get_acpi_cpu_names(unsigned char* dsdt, uint32_t length)␊ |
191 | {␊ |
192 | ␉uint32_t i;␊ |
193 | ␉␊ |
194 | ␉for (i=0; i<length-7; i++) ␊ |
195 | ␉{␊ |
196 | ␉␉if (dsdt[i] == 0x5B && dsdt[i+1] == 0x83) // ProcessorOP␊ |
197 | ␉␉{␊ |
198 | ␉␉␉uint32_t offset = i + 3 + (dsdt[i+2] >> 6);␊ |
199 | ␉␉␉␊ |
200 | ␉␉␉bool add_name = true;␊ |
201 | ␊ |
202 | ␉␉␉uint8_t j;␊ |
203 | ␉␉␉␊ |
204 | ␉␉␉for (j=0; j<4; j++) ␊ |
205 | ␉␉␉{␊ |
206 | ␉␉␉␉char c = dsdt[offset+j];␊ |
207 | ␉␉␉␉␊ |
208 | ␉␉␉␉if (!aml_isvalidchar(c)) ␊ |
209 | ␉␉␉␉{␊ |
210 | ␉␉␉␉␉add_name = false;␊ |
211 | ␉␉␉␉␉verbose("Invalid character found in ProcessorOP 0x%x!\n", c);␊ |
212 | ␉␉␉␉␉break;␊ |
213 | ␉␉␉␉}␊ |
214 | ␉␉␉}␊ |
215 | ␉␉␉␊ |
216 | ␉␉␉if (add_name) ␊ |
217 | ␉␉␉{␊ |
218 | ␉␉␉␉acpi_cpu_name[acpi_cpu_count] = malloc(4);␊ |
219 | ␉␉␉␉memcpy(acpi_cpu_name[acpi_cpu_count], dsdt+offset, 4);␊ |
220 | ␉␉␉␉i = offset + 5;␊ |
221 | ␉␉␉␉␊ |
222 | ␉␉␉␉verbose("Found ACPI CPU: %c%c%c%c\n", acpi_cpu_name[acpi_cpu_count][0], acpi_cpu_name[acpi_cpu_count][1], acpi_cpu_name[acpi_cpu_count][2], acpi_cpu_name[acpi_cpu_count][3]);␊ |
223 | ␉␉␉␉␊ |
224 | ␉␉␉␉if (++acpi_cpu_count == 32) return;␊ |
225 | ␉␉␉}␊ |
226 | ␉␉}␊ |
227 | ␉}␊ |
228 | }␊ |
229 | ␊ |
230 | ␉␉␉␉␉ ␊ |
231 | struct acpi_2_ssdt *generate_cst_ssdt(struct acpi_2_fadt* fadt)␊ |
232 | {␉␊ |
233 | ␉char ssdt_header[] =␊ |
234 | ␉{␊ |
235 | ␉␉0x53, 0x53, 0x44, 0x54, 0xE7, 0x00, 0x00, 0x00, /* SSDT.... */␊ |
236 | ␉␉0x01, 0x17, 0x50, 0x6D, 0x52, 0x65, 0x66, 0x41, /* ..PmRefA */␊ |
237 | ␉␉0x43, 0x70, 0x75, 0x43, 0x73, 0x74, 0x00, 0x00, /* CpuCst.. */␊ |
238 | ␉␉0x00, 0x10, 0x00, 0x00, 0x49, 0x4E, 0x54, 0x4C, /* ....INTL */␊ |
239 | ␉␉0x31, 0x03, 0x10, 0x20 ␉␉␉␉␉␉␉/* 1.._␉␉*/␊ |
240 | ␉};␊ |
241 | ␉␊ |
242 | ␉char cstate_resource_template[] = ␊ |
243 | ␉{␊ |
244 | ␉␉0x11, 0x14, 0x0A, 0x11, 0x82, 0x0C, 0x00, 0x7F, ␊ |
245 | ␉␉0x01, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, ␊ |
246 | ␉␉0x00, 0x00, 0x00, 0x79, 0x00␊ |
247 | ␉};␊ |
248 | ␉␊ |
249 | ␉if (Platform->CPU.Vendor != 0x756E6547) {␊ |
250 | ␉␉verbose ("Not an Intel platform: C-States will not be generated !!!\n");␊ |
251 | ␉␉return NULL;␊ |
252 | ␉}␊ |
253 | ␉␊ |
254 | ␉if (fadt == NULL) {␊ |
255 | ␉␉verbose ("FACP not exists: C-States will not be generated !!!\n");␊ |
256 | ␉␉return NULL;␊ |
257 | ␉}␊ |
258 | ␉␉␊ |
259 | ␉struct acpi_2_dsdt* dsdt = (void*)fadt->DSDT;␊ |
260 | ␉␊ |
261 | ␉if (dsdt == NULL) {␊ |
262 | ␉␉verbose ("DSDT not found: C-States will not be generated !!!\n");␊ |
263 | ␉␉return NULL;␊ |
264 | ␉}␊ |
265 | ␉␊ |
266 | ␉if (acpi_cpu_count == 0) ␊ |
267 | ␉␉get_acpi_cpu_names((void*)dsdt, dsdt->Length);␊ |
268 | ␉␊ |
269 | ␉if (acpi_cpu_count > 0) ␊ |
270 | ␉{␊ |
271 | ␉␉bool c2_enabled = fadt->C2_Latency < 100;␊ |
272 | ␉␉bool c3_enabled = fadt->C3_Latency < 1000;␊ |
273 | ␉␉bool c4_enabled = false;␊ |
274 | ␉␉␊ |
275 | ␉␉getBoolForKey(kEnableC4State, &c4_enabled, &bootInfo->bootConfig);␊ |
276 | ␊ |
277 | ␉␉unsigned char cstates_count = 1 + (c2_enabled ? 1 : 0) + ((c3_enabled || c4_enabled) ? 1 : 0);␊ |
278 | ␉␉char *Lat = NULL, *Pw = NULL, *tmpstr =NULL;␊ |
279 | ␉␉int base = 16;␊ |
280 | ␉␉TagPtr personality = XMLCastDict(XMLGetProperty(bootInfo->bootConfig.dictionary, (const char*)"C-States"));␊ |
281 | ␉␉␊ |
282 | ␉␉if (tmpstr = XMLCastString(XMLGetProperty(personality, (const char*)"Base"))) {␊ |
283 | ␉␉␉␊ |
284 | ␉␉␉int mybase = strtol(tmpstr, NULL, 10);␉␊ |
285 | ␉␉␉␊ |
286 | ␉␉␉if (mybase == 8 || mybase == 10 || mybase == 16 ) ␊ |
287 | ␉␉␉␉base = mybase;␉␉␉␉␉␉␉␉␉␊ |
288 | ␉␉}␊ |
289 | ␉␉␊ |
290 | ␉␉struct aml_chunk* root = aml_create_node(NULL);␊ |
291 | ␉␉␉aml_add_buffer(root, ssdt_header, sizeof(ssdt_header)); // SSDT header␊ |
292 | ␉␉␉struct aml_chunk* scop = aml_add_scope(root, "\\_PR_");␊ |
293 | ␉␉␉␉struct aml_chunk* name = aml_add_name(scop, "CST_");␊ |
294 | ␉␉␉␉␉struct aml_chunk* pack = aml_add_package(name);␊ |
295 | ␉␉␉␉␉␉aml_add_byte(pack, cstates_count);␊ |
296 | ␉␉␊ |
297 | ␉␉␉␉␉␉struct aml_chunk* tmpl = aml_add_package(pack);␊ |
298 | ␉␉␉␉␉␉␉TagPtr match_Status = XMLGetProperty(personality, (const char*)"C1");␊ |
299 | ␉␉␉␉␉␉␉if (match_Status) {␉␊ |
300 | ␉␉␉␉␉␉␉␉Pw = XMLCastString(XMLGetProperty(match_Status, (const char*)"Power"));␊ |
301 | ␉␉␉␉␉␉␉␉Lat = XMLCastString(XMLGetProperty(match_Status, (const char*)"Latency"));␊ |
302 | ␉␉␉␉␉␉␉}␊ |
303 | ␉␉␉␉␉␉␉cstate_resource_template[11] = 0x00; // C1␊ |
304 | ␉␉␉␉␉␉␉aml_add_buffer(tmpl, cstate_resource_template, sizeof(cstate_resource_template));␊ |
305 | ␉␉␉␉␉␉␉aml_add_byte(tmpl, 0x01); // C1␊ |
306 | ␉␉␉␉␉␉␉aml_add_byte(tmpl, (unsigned char)resolve_cst(0x01, Lat, base)); // Latency␊ |
307 | ␉␉␉␉␉␉␉aml_add_word(tmpl, resolve_cst(0x03e8, Pw, base)); // Power␊ |
308 | ␉␉// C2␊ |
309 | ␉␉if (c2_enabled) ␊ |
310 | ␉␉{␊ |
311 | ␉␉␉tmpl = aml_add_package(pack);␊ |
312 | ␉␉␉Lat = NULL; ␊ |
313 | ␉␉␉Pw = NULL;␊ |
314 | ␉␉␉match_Status = XMLGetProperty(personality, (const char*)"C2");␊ |
315 | ␉␉␉if (match_Status) {␉␊ |
316 | ␉␉␉␉Pw = XMLCastString(XMLGetProperty(match_Status, (const char*)"Power"));␊ |
317 | ␉␉␉␉Lat = XMLCastString(XMLGetProperty(match_Status, (const char*)"Latency"));␊ |
318 | ␉␉␉}␊ |
319 | ␉␉␉␊ |
320 | ␉␉␉cstate_resource_template[11] = 0x10; // C2␊ |
321 | ␉␉␉aml_add_buffer(tmpl, cstate_resource_template, sizeof(cstate_resource_template));␊ |
322 | ␉␉␉aml_add_byte(tmpl, 0x02); // C2␉␉␉␉␊ |
323 | ␉␉␉aml_add_word(tmpl, resolve_cst(fadt->C2_Latency, Lat, base)); // Latency␊ |
324 | ␉␉␉aml_add_word(tmpl, resolve_cst(0x01f4, Pw, base)); // Power␊ |
325 | ␉␉}␊ |
326 | ␉␉␊ |
327 | ␉␉// C4␊ |
328 | ␉␉if (c4_enabled) ␊ |
329 | ␉␉{␊ |
330 | ␉␉␉tmpl = aml_add_package(pack);␊ |
331 | ␉␉␉Lat = NULL; ␊ |
332 | ␉␉␉Pw = NULL;␊ |
333 | ␉␉␉match_Status = XMLGetProperty(personality, (const char*)"C4"); ␊ |
334 | ␉␉␉if (match_Status) {␉␊ |
335 | ␉␉␉␉Pw = XMLCastString(XMLGetProperty(match_Status, (const char*)"Power"));␊ |
336 | ␉␉␉␉Lat = XMLCastString(XMLGetProperty(match_Status, (const char*)"Latency"));␊ |
337 | ␉␉␉}␊ |
338 | ␉␉␉cstate_resource_template[11] = 0x30; // C4␊ |
339 | ␉␉␉aml_add_buffer(tmpl, cstate_resource_template, sizeof(cstate_resource_template));␊ |
340 | ␉␉␉aml_add_byte(tmpl, 0x04); // C4␉␊ |
341 | ␉␉␉aml_add_word(tmpl, resolve_cst(fadt->C3_Latency / 2, Lat, base)); // TODO: right latency for C4␊ |
342 | ␉␉␉aml_add_word(tmpl, resolve_cst(0xfa, Pw, base)); // Power␊ |
343 | ␉␉␉␊ |
344 | ␉␉}␉␉␊ |
345 | ␉␉// C3␊ |
346 | ␉␉else if (c3_enabled) ␊ |
347 | ␉␉{␊ |
348 | ␉␉␉tmpl = aml_add_package(pack);␊ |
349 | ␉␉␉Lat = NULL; ␊ |
350 | ␉␉␉Pw = NULL;␊ |
351 | ␉␉␉match_Status = XMLGetProperty(personality, (const char*)"C3"); ␊ |
352 | ␉␉␉if (match_Status) {␉␊ |
353 | ␉␉␉␉Pw = XMLCastString(XMLGetProperty(match_Status, (const char*)"Power"));␊ |
354 | ␉␉␉␉Lat = XMLCastString(XMLGetProperty(match_Status, (const char*)"Latency"));␊ |
355 | ␉␉␉}␊ |
356 | ␉␉␉cstate_resource_template[11] = 0x20; // C3␊ |
357 | ␉␉␉aml_add_buffer(tmpl, cstate_resource_template, sizeof(cstate_resource_template));␊ |
358 | ␉␉␉aml_add_byte(tmpl, 0x03); // C3␉␉␉␉␊ |
359 | ␉␉␉aml_add_word(tmpl, resolve_cst(fadt->C3_Latency , Lat, base)); ␊ |
360 | ␉␉␉aml_add_word(tmpl, resolve_cst(0x015e, Pw, base)); // Power␊ |
361 | ␉␉␉␊ |
362 | ␉␉}␊ |
363 | ␉␉␊ |
364 | ␉␉␉␉␉␊ |
365 | ␉␉␉// Aliaces␊ |
366 | ␉␉␉int i;␊ |
367 | ␉␉␉for (i = 0; i < acpi_cpu_count; i++) ␊ |
368 | ␉␉␉{␊ |
369 | ␉␉␉␉char name[9];␊ |
370 | ␉␉␉␉sprintf(name, "_PR_%c%c%c%c", acpi_cpu_name[i][0], acpi_cpu_name[i][1], acpi_cpu_name[i][2], acpi_cpu_name[i][3]);␊ |
371 | ␉␉␉␉␊ |
372 | ␉␉␉␉scop = aml_add_scope(root, name);␊ |
373 | ␉␉␉␉␉aml_add_alias(scop, "CST_", "_CST");␊ |
374 | ␉␉␉}␊ |
375 | ␉␉␊ |
376 | ␉␉aml_calculate_size(root);␊ |
377 | ␉␉␊ |
378 | ␉␉struct acpi_2_ssdt *ssdt = (struct acpi_2_ssdt *)AllocateKernelMemory(root->Size);␊ |
379 | ␉␊ |
380 | ␉␉aml_write_node(root, (void*)ssdt, 0);␊ |
381 | ␉␉␊ |
382 | ␉␉ssdt->Length = root->Size;␊ |
383 | ␉␉ssdt->Checksum = 0;␊ |
384 | ␉␉ssdt->Checksum = 256 - checksum8(ssdt, ssdt->Length);␊ |
385 | ␉␉␊ |
386 | ␉␉aml_destroy_node(root);␉␉␊ |
387 | ␉␉␉␉␊ |
388 | ␉␉verbose ("SSDT with CPU C-States generated successfully\n");␊ |
389 | ␉␉␊ |
390 | ␉␉return ssdt;␊ |
391 | ␉}␊ |
392 | ␉else ␊ |
393 | ␉{␊ |
394 | ␉␉verbose ("ACPI CPUs not found: C-States not generated !!!\n");␊ |
395 | ␉}␊ |
396 | ␊ |
397 | ␉return NULL;␊ |
398 | }␊ |
399 | ␊ |
400 | struct acpi_2_ssdt *generate_pss_ssdt(struct acpi_2_dsdt* dsdt)␊ |
401 | {␉␉␊ |
402 | ␉␊ |
403 | ␉char ssdt_header[] =␊ |
404 | ␉{␊ |
405 | ␉␉0x53, 0x53, 0x44, 0x54, 0x7E, 0x00, 0x00, 0x00, /* SSDT.... */␊ |
406 | ␉␉0x01, 0x6A, 0x50, 0x6D, 0x52, 0x65, 0x66, 0x00, /* ..PmRef. */␊ |
407 | ␉␉0x43, 0x70, 0x75, 0x50, 0x6D, 0x00, 0x00, 0x00, /* CpuPm... */␊ |
408 | ␉␉0x00, 0x30, 0x00, 0x00, 0x49, 0x4E, 0x54, 0x4C, /* .0..INTL */␊ |
409 | ␉␉0x31, 0x03, 0x10, 0x20,␉␉␉␉␉␉␉/* 1.._␉␉*/␊ |
410 | ␉};␊ |
411 | ␉␉␊ |
412 | ␉if (Platform->CPU.Vendor != 0x756E6547) {␊ |
413 | ␉␉verbose ("Not an Intel platform: P-States will not be generated !!!\n");␊ |
414 | ␉␉return NULL;␊ |
415 | ␉}␊ |
416 | ␉␊ |
417 | ␉if (!(Platform->CPU.Features & CPU_FEATURE_MSR)) {␊ |
418 | ␉␉verbose ("Unsupported CPU: P-States will not be generated !!!\n");␊ |
419 | ␉␉return NULL;␊ |
420 | ␉}␊ |
421 | ␉␊ |
422 | ␉if (acpi_cpu_count == 0) ␊ |
423 | ␉␉get_acpi_cpu_names((void*)dsdt, dsdt->Length);␊ |
424 | ␉␊ |
425 | ␉if (acpi_cpu_count > 0) ␊ |
426 | ␉{␊ |
427 | ␉␉struct p_state initial, maximum, minimum, p_states[32];␊ |
428 | ␉␉uint8_t p_states_count = 0;␉␉␊ |
429 | ␉␉␊ |
430 | ␉␉// Retrieving P-States, ported from code by superhai (c)␊ |
431 | ␉␉switch (Platform->CPU.Family) {␊ |
432 | ␉␉␉case 0x06: ␊ |
433 | ␉␉␉{␊ |
434 | ␉␉␉␉switch (Platform->CPU.Model) ␊ |
435 | ␉␉␉␉{␊ |
436 | ␉␉␉␉␉case 0x0D: // ?␊ |
437 | ␉␉␉␉␉case CPU_MODEL_YONAH: // Yonah␊ |
438 | ␉␉␉␉␉case CPU_MODEL_MEROM: // Merom␊ |
439 | ␉␉␉␉␉case CPU_MODEL_PENRYN: // Penryn␊ |
440 | ␉␉␉␉␉case CPU_MODEL_ATOM: // Intel Atom (45nm)␊ |
441 | ␉␉␉␉␉{␊ |
442 | ␉␉␉␉␉␉bool cpu_dynamic_fsb = false;␊ |
443 | ␉␉␉␉␉␉␊ |
444 | ␉␉␉␉␉␉if (rdmsr64(MSR_IA32_EXT_CONFIG) & (1 << 27)) ␊ |
445 | ␉␉␉␉␉␉{␊ |
446 | ␉␉␉␉␉␉␉wrmsr64(MSR_IA32_EXT_CONFIG, (rdmsr64(MSR_IA32_EXT_CONFIG) | (1 << 28))); ␊ |
447 | ␉␉␉␉␉␉␉delay(1);␊ |
448 | ␉␉␉␉␉␉␉cpu_dynamic_fsb = rdmsr64(MSR_IA32_EXT_CONFIG) & (1 << 28);␊ |
449 | ␉␉␉␉␉␉}␊ |
450 | ␉␉␉␉␉␉␊ |
451 | ␉␉␉␉␉␉bool cpu_noninteger_bus_ratio = (rdmsr64(MSR_IA32_PERF_STATUS) & (1ULL << 46));␊ |
452 | ␉␉␉␉␉␉␊ |
453 | ␉␉␉␉␉␉initial.Control = rdmsr64(MSR_IA32_PERF_STATUS);␊ |
454 | ␉␉␉␉␉␉␊ |
455 | ␉␉␉␉␉␉maximum.Control = ((rdmsr64(MSR_IA32_PERF_STATUS) >> 32) & 0x1F3F) | (0x4000 * cpu_noninteger_bus_ratio);␊ |
456 | ␉␉␉␉␉␉maximum.CID = ((maximum.FID & 0x1F) << 1) | cpu_noninteger_bus_ratio;␊ |
457 | ␉␉␉␉␉␉␊ |
458 | ␉␉␉␉␉␉minimum.FID = ((rdmsr64(MSR_IA32_PERF_STATUS) >> 24) & 0x1F) | (0x80 * cpu_dynamic_fsb);␊ |
459 | ␉␉␉␉␉␉minimum.VID = ((rdmsr64(MSR_IA32_PERF_STATUS) >> 48) & 0x3F);␊ |
460 | ␉␉␉␉␉␉␊ |
461 | ␉␉␉␉␉␉if (minimum.FID == 0) ␊ |
462 | ␉␉␉␉␉␉{␊ |
463 | ␉␉␉␉␉␉␉uint64_t msr;␊ |
464 | ␉␉␉␉␉␉␉uint8_t i;␊ |
465 | ␉␉␉␉␉␉␉// Probe for lowest fid␊ |
466 | ␉␉␉␉␉␉␉for (i = maximum.FID; i >= 0x6; i--) ␊ |
467 | ␉␉␉␉␉␉␉{␊ |
468 | ␉␉␉␉␉␉␉␉msr = rdmsr64(MSR_IA32_PERF_CONTROL);␊ |
469 | ␉␉␉␉␉␉␉␉wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (i << 8) | minimum.VID);␊ |
470 | ␉␉␉␉␉␉␉␉intel_waitforsts();␊ |
471 | ␉␉␉␉␉␉␉␉minimum.FID = (rdmsr64(MSR_IA32_PERF_STATUS) >> 8) & 0x1F; ␊ |
472 | ␉␉␉␉␉␉␉␉delay(1);␊ |
473 | ␉␉␉␉␉␉␉}␊ |
474 | ␉␉␉␉␉␉␉␊ |
475 | ␉␉␉␉␉␉␉msr = rdmsr64(MSR_IA32_PERF_CONTROL);␊ |
476 | ␉␉␉␉␉␉␉wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (maximum.FID << 8) | maximum.VID);␊ |
477 | ␉␉␉␉␉␉␉intel_waitforsts();␊ |
478 | ␉␉␉␉␉␉}␊ |
479 | ␉␉␉␉␉␉␊ |
480 | ␉␉␉␉␉␉if (minimum.VID == maximum.VID) ␊ |
481 | ␉␉␉␉␉␉{␉␊ |
482 | ␉␉␉␉␉␉␉uint64_t msr;␊ |
483 | ␉␉␉␉␉␉␉uint8_t i;␊ |
484 | ␉␉␉␉␉␉␉// Probe for lowest vid␊ |
485 | ␉␉␉␉␉␉␉for (i = maximum.VID; i > 0xA; i--) ␊ |
486 | ␉␉␉␉␉␉␉{␊ |
487 | ␉␉␉␉␉␉␉␉msr = rdmsr64(MSR_IA32_PERF_CONTROL);␊ |
488 | ␉␉␉␉␉␉␉␉wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (minimum.FID << 8) | i);␊ |
489 | ␉␉␉␉␉␉␉␉intel_waitforsts();␊ |
490 | ␉␉␉␉␉␉␉␉minimum.VID = rdmsr64(MSR_IA32_PERF_STATUS) & 0x3F; ␊ |
491 | ␉␉␉␉␉␉␉␉delay(1);␊ |
492 | ␉␉␉␉␉␉␉}␊ |
493 | ␉␉␉␉␉␉␉␊ |
494 | ␉␉␉␉␉␉␉msr = rdmsr64(MSR_IA32_PERF_CONTROL);␊ |
495 | ␉␉␉␉␉␉␉wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (maximum.FID << 8) | maximum.VID);␊ |
496 | ␉␉␉␉␉␉␉intel_waitforsts();␊ |
497 | ␉␉␉␉␉␉}␊ |
498 | ␉␉␉␉␉␉␊ |
499 | ␉␉␉␉␉␉minimum.CID = ((minimum.FID & 0x1F) << 1) >> cpu_dynamic_fsb;␊ |
500 | ␉␉␉␉␉␉␊ |
501 | ␉␉␉␉␉␉// Sanity check␊ |
502 | ␉␉␉␉␉␉if (maximum.CID < minimum.CID) ␊ |
503 | ␉␉␉␉␉␉{␊ |
504 | ␉␉␉␉␉␉␉DBG("Insane FID values!");␊ |
505 | ␉␉␉␉␉␉␉p_states_count = 0;␊ |
506 | ␉␉␉␉␉␉}␊ |
507 | ␉␉␉␉␉␉else␊ |
508 | ␉␉␉␉␉␉{␊ |
509 | ␉␉␉␉␉␉␉// Finalize P-States␊ |
510 | ␉␉␉␉␉␉␉// Find how many P-States machine supports␊ |
511 | ␉␉␉␉␉␉␉p_states_count = maximum.CID - minimum.CID + 1;␊ |
512 | ␉␉␉␉␉␉␉␊ |
513 | ␉␉␉␉␉␉␉if (p_states_count > 32) ␊ |
514 | ␉␉␉␉␉␉␉␉p_states_count = 32;␊ |
515 | ␉␉␉␉␉␉␉␊ |
516 | ␉␉␉␉␉␉␉uint8_t vidstep;␊ |
517 | ␉␉␉␉␉␉␉uint8_t i = 0, u, invalid = 0;␊ |
518 | ␉␉␉␉␉␉␉␊ |
519 | ␉␉␉␉␉␉␉vidstep = ((maximum.VID << 2) - (minimum.VID << 2)) / (p_states_count - 1);␊ |
520 | ␉␉␉␉␉␉␉␊ |
521 | ␉␉␉␉␉␉␉for (u = 0; u < p_states_count; u++) ␊ |
522 | ␉␉␉␉␉␉␉{␊ |
523 | ␉␉␉␉␉␉␉␉i = u - invalid;␊ |
524 | ␉␉␉␉␉␉␉␉␊ |
525 | ␉␉␉␉␉␉␉␉p_states[i].CID = maximum.CID - u;␊ |
526 | ␉␉␉␉␉␉␉␉p_states[i].FID = (p_states[i].CID >> 1);␊ |
527 | ␉␉␉␉␉␉␉␉␊ |
528 | ␉␉␉␉␉␉␉␉if (p_states[i].FID < 0x6) ␊ |
529 | ␉␉␉␉␉␉␉␉{␊ |
530 | ␉␉␉␉␉␉␉␉␉if (cpu_dynamic_fsb) ␊ |
531 | ␉␉␉␉␉␉␉␉␉␉p_states[i].FID = (p_states[i].FID << 1) | 0x80;␊ |
532 | ␉␉␉␉␉␉␉␉} ␊ |
533 | ␉␉␉␉␉␉␉␉else if (cpu_noninteger_bus_ratio) ␊ |
534 | ␉␉␉␉␉␉␉␉{␊ |
535 | ␉␉␉␉␉␉␉␉␉p_states[i].FID = p_states[i].FID | (0x40 * (p_states[i].CID & 0x1));␊ |
536 | ␉␉␉␉␉␉␉␉}␊ |
537 | ␉␉␉␉␉␉␉␉␊ |
538 | ␉␉␉␉␉␉␉␉if (i && p_states[i].FID == p_states[i-1].FID)␊ |
539 | ␉␉␉␉␉␉␉␉␉invalid++;␊ |
540 | ␉␉␉␉␉␉␉␉␊ |
541 | ␉␉␉␉␉␉␉␉p_states[i].VID = ((maximum.VID << 2) - (vidstep * u)) >> 2;␊ |
542 | ␉␉␉␉␉␉␉␉␊ |
543 | ␉␉␉␉␉␉␉␉uint32_t multiplier = p_states[i].FID & 0x1f;␉␉// = 0x08␊ |
544 | ␉␉␉␉␉␉␉␉bool half = p_states[i].FID & 0x40;␉␉␉␉␉// = 0x01␊ |
545 | ␉␉␉␉␉␉␉␉bool dfsb = p_states[i].FID & 0x80;␉␉␉␉␉// = 0x00␊ |
546 | ␉␉␉␉␉␉␉␉uint32_t fsb = Platform->CPU.FSBFrequency / 1000000; // = 400␊ |
547 | ␉␉␉␉␉␉␉␉uint32_t halffsb = (fsb + 1) >> 1;␉␉␉␉␉// = 200␊ |
548 | ␉␉␉␉␉␉␉␉uint32_t frequency = (multiplier * fsb);␉␉␉// = 3200␊ |
549 | ␉␉␉␉␉␉␉␉␊ |
550 | ␉␉␉␉␉␉␉␉p_states[i].Frequency = (frequency + (half * halffsb)) >> dfsb;␉// = 3200 + 200 = 3400␊ |
551 | ␉␉␉␉␉␉␉}␊ |
552 | ␉␉␉␉␉␉␉␊ |
553 | ␉␉␉␉␉␉␉p_states_count -= invalid;␊ |
554 | ␉␉␉␉␉␉}␊ |
555 | ␉␉␉␉␉␉break;␊ |
556 | ␉␉␉␉␉} ␊ |
557 | ␉␉␉␉␉case CPU_MODEL_FIELDS:␊ |
558 | ␉␉␉␉␉case CPU_MODEL_DALES:␊ |
559 | ␉␉␉␉␉case CPU_MODEL_DALES_32NM:␊ |
560 | ␉␉␉␉␉case CPU_MODEL_NEHALEM: ␊ |
561 | ␉␉␉␉␉case CPU_MODEL_NEHALEM_EX:␊ |
562 | ␉␉␉␉␉case CPU_MODEL_WESTMERE:␊ |
563 | ␉␉␉␉␉case CPU_MODEL_WESTMERE_EX:␊ |
564 | ␉␉␉␉␉{␉␉␊ |
565 | ␉␉␉␉␉␉maximum.Control = rdmsr64(MSR_IA32_PERF_STATUS) & 0xff; // Seems it always contains maximum multiplier value (with turbo, that's we need)...␊ |
566 | ␉␉␉␉␉␉minimum.Control = (rdmsr64(MSR_PLATFORM_INFO) >> 40) & 0xff;␊ |
567 | ␉␉␉␉␉␉␊ |
568 | ␉␉␉␉␉␉verbose("P-States: min 0x%x, max 0x%x\n", minimum.Control, maximum.Control);␊ |
569 | ␉␉␉␉␉␉␊ |
570 | ␉␉␉␉␉␉// Sanity check␊ |
571 | ␉␉␉␉␉␉if (maximum.Control < minimum.Control) ␊ |
572 | ␉␉␉␉␉␉{␊ |
573 | ␉␉␉␉␉␉␉DBG("Insane control values!");␊ |
574 | ␉␉␉␉␉␉␉p_states_count = 0;␊ |
575 | ␉␉␉␉␉␉}␊ |
576 | ␉␉␉␉␉␉else␊ |
577 | ␉␉␉␉␉␉{␊ |
578 | ␉␉␉␉␉␉␉uint8_t i;␊ |
579 | ␉␉␉␉␉␉␉p_states_count = 0;␊ |
580 | ␉␉␉␉␉␉␉␊ |
581 | ␉␉␉␉␉␉␉for (i = maximum.Control; i >= minimum.Control; i--) ␊ |
582 | ␉␉␉␉␉␉␉{␊ |
583 | ␉␉␉␉␉␉␉␉p_states[p_states_count].Control = i;␊ |
584 | ␉␉␉␉␉␉␉␉p_states[p_states_count].CID = p_states[p_states_count].Control << 1;␊ |
585 | ␉␉␉␉␉␉␉␉p_states[p_states_count].Frequency = (Platform->CPU.FSBFrequency / 1000000) * i;␊ |
586 | ␉␉␉␉␉␉␉␉p_states_count++;␊ |
587 | ␉␉␉␉␉␉␉}␊ |
588 | ␉␉␉␉␉␉}␊ |
589 | ␉␉␉␉␉␉␊ |
590 | ␉␉␉␉␉␉break;␊ |
591 | ␉␉␉␉␉}␊ |
592 | ␉␉␉␉␉default:␊ |
593 | ␉␉␉␉␉␉verbose ("Unsupported CPU: P-States not generated !!!\n");␊ |
594 | ␉␉␉␉␉␉break;␊ |
595 | ␉␉␉␉}␊ |
596 | ␉␉␉}␊ |
597 | ␉␉}␊ |
598 | ␉␉␊ |
599 | ␉␉// Generating SSDT␊ |
600 | ␉␉if (p_states_count) ␊ |
601 | ␉␉{␉␊ |
602 | ␉␉␉int i;␊ |
603 | ␉␉␉␊ |
604 | ␉␉␉struct aml_chunk* root = aml_create_node(NULL);␊ |
605 | ␉␉␉␉aml_add_buffer(root, ssdt_header, sizeof(ssdt_header)); // SSDT header␊ |
606 | ␉␉␉␉␉struct aml_chunk* scop = aml_add_scope(root, "\\_PR_");␊ |
607 | ␉␉␉␉␉␉struct aml_chunk* name = aml_add_name(scop, "PSS_");␊ |
608 | ␉␉␉␉␉␉␉struct aml_chunk* pack = aml_add_package(name);␊ |
609 | ␉␉␉␊ |
610 | ␉␉␉␉␉␉␉␉uint8_t minPSratio = (p_states[p_states_count-1].Frequency / (Platform->CPU.FSBFrequency / 10000000 ));␊ |
611 | ␉␉␉␉␉␉␉␉uint8_t maxPSratio = (p_states[0].Frequency / (Platform->CPU.FSBFrequency / 10000000 ));␊ |
612 | ␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␊ |
613 | ␉␉␉␉␉␉␉␉uint8_t cpu_div = Platform->CPU.CurrDiv;␊ |
614 | ␉␉␉␉␉␉␉␉uint8_t cpu_ratio = 0;␊ |
615 | ␉␉␉␊ |
616 | ␉␉␉␉␉␉␉␉if (cpu_div) ␉␉␉␉␉␉␉␉␊ |
617 | ␉␉␉␉␉␉␉␉␉cpu_ratio = (Platform->CPU.CurrCoef * 10) + 5;␉␉␉␉␉␉␉␉␊ |
618 | ␉␉␉␉␉␉␉␉else ␉␉␉␉␉␉␉␉␊ |
619 | ␉␉␉␉␉␉␉␉␉cpu_ratio = Platform->CPU.CurrCoef * 10;␊ |
620 | ␉␉␉␉␉␉␉␉␊ |
621 | ␉␉␉␊ |
622 | ␉␉␉␉␉␉␉␉int user_max_ratio = 0;␊ |
623 | ␉␉␉␉␉␉␉␉getIntForKey(kMaxRatio, &user_max_ratio, &bootInfo->bootConfig);␊ |
624 | ␉␉␉␉␉␉␉␉if (user_max_ratio >= minPSratio && maxPSratio >= user_max_ratio) {␉␉␉␉␉␉␉␉␉␊ |
625 | ␉␉␉␉␊ |
626 | ␉␉␉␉␉␉␉␉␉uint8_t maxcurrdiv = 0, maxcurrcoef = (int)(user_max_ratio / 10);␉␉␉␉␉␉␉␉␉␊ |
627 | ␉␉␉␉␊ |
628 | ␉␉␉␉␉␉␉␉␉uint8_t maxdiv = user_max_ratio - (maxcurrcoef * 10);␊ |
629 | ␉␉␉␉␉␉␉␉␉if (maxdiv > 0)␊ |
630 | ␉␉␉␉␉␉␉␉␉␉maxcurrdiv = 1;␊ |
631 | ␉␉␉␉␊ |
632 | ␉␉␉␉␉␉␉␉␉if (maxcurrdiv) ␉␉␉␉␉␉␉␉␉␊ |
633 | ␉␉␉␉␉␉␉␉␉␉cpu_ratio = (maxcurrcoef * 10) + 5;␉␉␉␉␉␉␉␉␉␊ |
634 | ␉␉␉␉␉␉␉␉␉else ␉␉␉␉␉␉␉␉␉␊ |
635 | ␉␉␉␉␉␉␉␉␉␉cpu_ratio = maxcurrcoef * 10;␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␊ |
636 | ␉␉␉␉␉␉␉␉}␊ |
637 | ␉␉␉␊ |
638 | ␉␉␉␉␉␉␉␉int user_min_ratio = 0;␊ |
639 | ␉␉␉␉␉␉␉␉getIntForKey(kMinRatio, &user_min_ratio, &bootInfo->bootConfig);␊ |
640 | ␉␉␉␉␉␉␉␉if (user_min_ratio >= minPSratio && cpu_ratio >= user_min_ratio) {␊ |
641 | ␉␉␉␉␊ |
642 | ␉␉␉␉␉␉␉␉␉uint8_t mincurrdiv = 0, mincurrcoef = (int)(user_min_ratio / 10);␉␉␉␉␉␉␉␉␉␊ |
643 | ␉␉␉␉␊ |
644 | ␉␉␉␉␉␉␉␉␉uint8_t mindiv = user_min_ratio - (mincurrcoef * 10);␊ |
645 | ␉␉␉␉␊ |
646 | ␉␉␉␉␉␉␉␉␉if (mindiv > 0)␊ |
647 | ␉␉␉␉␉␉␉␉␉␉mincurrdiv = 1;␉␉␉␉␉␉␉␉␉␊ |
648 | ␉␉␉␉␊ |
649 | ␉␉␉␉␉␉␉␉␉if (mincurrdiv) ␉␉␉␉␉␉␉␉␉␊ |
650 | ␉␉␉␉␉␉␉␉␉␉minPSratio = (mincurrcoef * 10) + 5;␉␉␉␉␉␉␉␉␉␊ |
651 | ␉␉␉␉␉␉␉␉␉else ␉␉␉␉␉␉␉␉␉␊ |
652 | ␉␉␉␉␉␉␉␉␉␉minPSratio = mincurrcoef * 10;␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␊ |
653 | ␉␉␉␉␊ |
654 | ␉␉␉␉␉␉␉␉}␊ |
655 | ␉␉␉␊ |
656 | ␉␉␉␉␉␉␉␉if (maxPSratio >= cpu_ratio && cpu_ratio >= minPSratio)␉maxPSratio = cpu_ratio;␉␉␉␉␉␉␉␉␉␉␉␉␉␊ |
657 | ␉␉␉␊ |
658 | ␉␉␉␉␉␉␉␉TagPtr personality = XMLCastDict(XMLGetProperty(bootInfo->bootConfig.dictionary, (const char*)"P-States"));␊ |
659 | ␉␉␉␉␉␉␉␉char* MatchStat = 0;␊ |
660 | ␉␉␉␉␉␉␉␉int dropPSS = 0, Pstatus = 0, base = 16;␉␉␉␉␉␉␉␉␊ |
661 | ␉␉␉␉␉␉␉␉int expert = 0;/* Default: 0 , mean mixed mode | expert mode : 1 , mean add only p-states found in boot.plist*/␊ |
662 | ␉␉␉␉␉␉␉␉char *tmpstr = XMLCastString(XMLGetProperty(personality, (const char*)"Mode"));␊ |
663 | ␉␉␉␉␉␉␊ |
664 | ␉␉␉␉␉␉␉␉if (strcmp(tmpstr,"Expert") == 0) {␊ |
665 | ␉␉␉␉␉␉␉␉␉␉p_states_count = (XMLTagCount(personality)) - 1 ; // - 1 = - ("Mode" tag) ␉␉␉␉␉␉␉␉␉␉␊ |
666 | ␉␉␉␉␉␉␉␉␉␉expert = 1;␊ |
667 | ␉␉␉␉␉␉␉␉}␊ |
668 | ␉␉␉␊ |
669 | ␉␉␉␉␉␉␉␊ |
670 | ␉␉␉␉␉␉␉␉if (tmpstr = XMLCastString(XMLGetProperty(personality, (const char*)"Base"))) {␊ |
671 | ␉␉␉␉␉␉␉␉␉␊ |
672 | ␉␉␉␉␉␉␉␉␉if (expert) p_states_count--; // -= ("Base" tag) ␊ |
673 | ␉␉␉␉␉␉␉␉␉␊ |
674 | ␉␉␉␉␉␉␉␉␉int mybase = strtol(tmpstr, NULL, 10);␉␊ |
675 | ␉␉␉␉␉␉␉␉␉␊ |
676 | ␉␉␉␉␉␉␉␉␉if (mybase == 8 || mybase == 10 || mybase == 16 )␊ |
677 | ␉␉␉␉␉␉␉␉␉␉base = mybase;␉␉␉␉␉␉␉␉␉␊ |
678 | ␉␉␉␉␉␉␉␉}␊ |
679 | ␉␉␉␊ |
680 | ␉␉␉␉␉␉␉␉for (i = 0; i < p_states_count; i++) ␊ |
681 | ␉␉␉␉␉␉␉␉{␉␉␉␉␉␉␉␉␉␊ |
682 | ␉␉␉␉␉␉␉␉␉sprintf(MatchStat, "%d",i);␊ |
683 | ␉␉␉␉␉␉␉␉␉TagPtr match_Status = XMLGetProperty(personality, (const char*)MatchStat); ␉␉␉␉␉␉␉␉ ␊ |
684 | ␉␉␉␉␉␉␉␉␉␊ |
685 | ␉␉␉␉␉␉␉␉␉char *Lat1 = NULL, *clk = NULL, *Pw = NULL, *Lat2 = NULL, *Ctrl = NULL ;␊ |
686 | ␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␊ |
687 | ␉␉␉␉␉␉␉␉␉if (match_Status) {␉␉␉␉␉␉␉␉␉␉␉␉␊ |
688 | ␉␉␉␉␉␉␉␉␉ ␉␉␉␉␉␉␉␉␉␊ |
689 | ␉␉␉␉␉␉␉␉␉␉clk = XMLCastString(XMLGetProperty(match_Status, (const char*)"CoreFreq"));␊ |
690 | ␉␉␉␉␉␉␉␉␉␉Pw = XMLCastString(XMLGetProperty(match_Status, (const char*)"Power"));␊ |
691 | ␉␉␉␉␉␉␉␉␉␉Lat1 = XMLCastString(XMLGetProperty(match_Status, (const char*)"Transition Latency"));␊ |
692 | ␉␉␉␉␉␉␉␉␉␉Lat2 = XMLCastString(XMLGetProperty(match_Status, (const char*)"Bus Master Latency"));␊ |
693 | ␉␉␉␉␉␉␉␉␉␉Ctrl = XMLCastString(XMLGetProperty(match_Status, (const char*)"Control"));␊ |
694 | ␉␉␉␉␉␉␉␉␉␊ |
695 | ␊ |
696 | ␉␉␉␉␉␉␉␉␉} else if (expert) ␊ |
697 | ␉␉␉␉␉␉␉␉␉␉continue;␊ |
698 | ␊ |
699 | ␊ |
700 | ␉␉␉␉␉␉␉␉␉unsigned long Frequency = 0x00000000;␊ |
701 | ␉␉␉␉␉␉␉␉␉␊ |
702 | ␉␉␉␉␉␉␉␉␉if (!expert) Frequency = p_states[i].Frequency;␊ |
703 | ␉␉␉␉␉␉␉␉␉␊ |
704 | ␉␉␉␉␉␉␉␉␉if (clk) ␊ |
705 | ␉␉␉␉␉␉␉␉␉␉Frequency = strtoul((const char *)clk, NULL,base);␊ |
706 | ␉␉␉␉␉␉␉␉␉␊ |
707 | ␉␉␉␉␉␉␉␉␉if (!Frequency || Frequency > p_states[0].Frequency ) continue;␊ |
708 | ␉␉␉␉␉␉␉␉␉␊ |
709 | ␉␉␉␉␉␉␉␉␉uint8_t curr_ratio = (Frequency / (Platform->CPU.FSBFrequency / 10000000 ));␊ |
710 | ␉␉␉␉␉␉␉␉␉␊ |
711 | ␉␉␉␉␉␉␉␉␉if (curr_ratio > maxPSratio || minPSratio > curr_ratio)␊ |
712 | ␉␉␉␉␉␉␉␉␉␉goto dropPstate;␊ |
713 | ␉␉␉␉␉␉␉␉␉␊ |
714 | ␉␉␉␉␉␉␉␉␉struct aml_chunk* pstt = aml_add_package(pack);␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␊ |
715 | ␉␉␉␉␉␉␉␉␉aml_add_dword(pstt, Frequency); // CoreFreq (in MHz).␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␊ |
716 | ␉␉␉␉␉␉␉␉␉aml_add_dword(pstt, resolve_pss(0x00000000, Pw, base)); // Power (in milliWatts)␉␉␉␉␉␉␉␉␉␊ |
717 | ␉␉␉␉␉␉␉␉␉aml_add_dword(pstt, resolve_pss(0x0000000A, Lat1, base)); // Transition Latency (in microseconds).␉␉␉␉␉␉␉␉␉␊ |
718 | ␉␉␉␉␉␉␉␉␉aml_add_dword(pstt, resolve_pss(0x0000000A, Lat2, base)); // Bus Master Latency (in microseconds).␉␉␉␉␉␉␉␉␉␊ |
719 | ␉␉␉␉␉␉␉␉␉unsigned long Control = 0x00000000;␊ |
720 | ␉␉␉␉␉␉␉␉␉if (!expert) Control = p_states[i].Control;␉␉␉␉␉␉␉␉␉␊ |
721 | ␉␉␉␉␉␉␉␉␉aml_add_dword(pstt, resolve_pss(Control, Ctrl, base)); // Control␉␉␉␉␉␉␉␉␉␊ |
722 | ␉␉␉␉␉␉␉␉␉Pstatus++;␊ |
723 | ␉␉␉␉␉␉␉␉␉aml_add_dword(pstt, Pstatus); // Status␉␉␉␉␉␉␉␉␉␊ |
724 | ␉␉␉␉␉␉␉␉␉continue;␉␉␉␉␉␉␉␉␉␉␉␉␉␉␉␊ |
725 | dropPstate:␊ |
726 | #if DEBUG_ACPI␉␉␉␉␉␉␉␉␊ |
727 | ␉␉␉␉␉␉␉␉␉verbose("state with cpu frequency :%d and ratio :%d will be dropped\n",p_states[i].Frequency,curr_ratio);␉␉␉␉␉␉␉␉␉␊ |
728 | #endif␊ |
729 | ␉␉␉␉␉␉␉␉␉dropPSS++;␊ |
730 | ␉␉␉␉␉␉␉␉␉␊ |
731 | ␊ |
732 | ␉␉␉␉␉␉␉␉}␉␉␉␊ |
733 | ␉␉␉␊ |
734 | ␉␉␉// Add aliaces␊ |
735 | ␉␉␉for (i = 0; i < acpi_cpu_count; i++) ␊ |
736 | ␉␉␉{␊ |
737 | ␉␉␉␉char name[9];␊ |
738 | ␉␉␉␉sprintf(name, "_PR_%c%c%c%c", acpi_cpu_name[i][0], acpi_cpu_name[i][1], acpi_cpu_name[i][2], acpi_cpu_name[i][3]);␊ |
739 | ␉␉␉␉␊ |
740 | ␉␉␉␉scop = aml_add_scope(root, name);␊ |
741 | ␉␉␉␉aml_add_alias(scop, "PSS_", "_PSS");␊ |
742 | ␉␉␉}␊ |
743 | ␉␉␉␊ |
744 | ␉␉␉aml_calculate_size(root);␊ |
745 | ␉␉␉␊ |
746 | ␉␉␉struct acpi_2_ssdt *ssdt = (struct acpi_2_ssdt *)AllocateKernelMemory(root->Size);␊ |
747 | ␉␉␉␊ |
748 | ␉␉␉aml_write_node(root, (void*)ssdt, 0);␊ |
749 | ␉␉␉␊ |
750 | ␉␉␉ssdt->Length = root->Size;␊ |
751 | ␉␉␉ssdt->Checksum = 0;␊ |
752 | ␉␉␉ssdt->Checksum = 256 - checksum8(ssdt, ssdt->Length);␊ |
753 | ␉␉␉␊ |
754 | ␉␉␉aml_destroy_node(root);␉␉␉␊ |
755 | ␉␉␉␊ |
756 | ␉␉␉verbose ("SSDT with CPU P-States generated successfully");␊ |
757 | ␉␉␉␊ |
758 | ␉␉␉if (dropPSS)␊ |
759 | ␉␉␉verbose(", %d P-state(s) dropped",dropPSS);␊ |
760 | ␉␉␉␊ |
761 | ␉␉␉verbose("\n");␊ |
762 | ␉␉␉␊ |
763 | ␉␉␉return ssdt;␊ |
764 | ␉␉}␊ |
765 | ␉}␊ |
766 | ␉else ␊ |
767 | ␉{␊ |
768 | ␉␉verbose ("ACPI CPUs not found: P-States not generated !!!\n");␊ |
769 | ␉}␊ |
770 | ␉␊ |
771 | ␉return NULL;␊ |
772 | }␊ |
773 | ␊ |
774 | static ␊ |
775 | struct acpi_2_gas FillGASStruct(uint32_t Address, uint8_t Length)␊ |
776 | {␊ |
777 | ␉struct acpi_2_gas TmpGAS;␊ |
778 | ␉␊ |
779 | ␉TmpGAS.Address_Space_ID = 1; /* I/O Address */␊ |
780 | ␉␊ |
781 | ␉if (Address == 0)␊ |
782 | ␉{␊ |
783 | ␉␉TmpGAS.Register_Bit_Width = 0;␊ |
784 | ␉} else {␊ |
785 | ␉␉TmpGAS.Register_Bit_Width = Length * 8;␊ |
786 | ␉}␊ |
787 | ␉␊ |
788 | ␉TmpGAS.Register_Bit_Offset = 0;␊ |
789 | ␉TmpGAS.Access_Size = 0; /* Not set for Legacy reasons... */␊ |
790 | ␉TmpGAS.Address = (uint64_t)Address;␊ |
791 | ␉␊ |
792 | ␉return(TmpGAS);␊ |
793 | }␊ |
794 | ␊ |
795 | struct acpi_2_fadt *␊ |
796 | patch_fadt(struct acpi_2_fadt *fadt, struct acpi_2_facs *new_facs, struct acpi_2_dsdt *new_dsdt, bool UpdateFADT)␊ |
797 | {␉␉␊ |
798 | extern void setupSystemType(); ␊ |
799 | ␉␊ |
800 | ␉struct acpi_2_fadt *fadt_mod;␊ |
801 | ␉struct acpi_2_fadt *fadt_file = (struct acpi_2_fadt *)loadACPITable(kFADT); ␊ |
802 | ␉bool fadt_rev2_needed = false;␊ |
803 | ␉bool fix_restart = false;␉␊ |
804 | ␉const char * value;␊ |
805 | ␉␊ |
806 | ␉// Restart Fix␊ |
807 | ␉if (Platform->CPU.Vendor == 0x756E6547) {␉/* Intel */␊ |
808 | ␉␉fix_restart = true;␊ |
809 | ␉␉getBoolForKey(kRestartFix, &fix_restart, &bootInfo->bootConfig);␊ |
810 | ␉} else {␊ |
811 | ␉␉verbose ("Not an Intel platform: Restart Fix not applied !!!\n");␊ |
812 | ␉}␊ |
813 | ␉␊ |
814 | ␉if (fix_restart)␊ |
815 | ␉␉fadt_rev2_needed = true;␊ |
816 | ␉␊ |
817 | ␉// Allocate new fadt table␊ |
818 | ␉if ((UpdateFADT) && (((fadt_file) && (fadt_file->Length < sizeof(struct acpi_2_fadt))) ||␊ |
819 | ␉␉␉␉␉␉ ((!fadt_file) && (fadt->Length < sizeof(struct acpi_2_fadt))))) ␊ |
820 | ␉{␊ |
821 | ␉␉if (fadt_file)␊ |
822 | ␉␉{␊ |
823 | ␉␉␉if (fadt_file->Length < 0xF4)␊ |
824 | ␉␉␉{␊ |
825 | ␉␉␉␉fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(0xF4);␊ |
826 | ␉␉␉␉memcpy(fadt_mod, fadt_file, fadt_file->Length);␊ |
827 | ␉␉␉␉fadt_mod->Length = 0xF4;␊ |
828 | ␉␉␉}␊ |
829 | ␉␉␉else␊ |
830 | ␉␉␉{␊ |
831 | ␉␉␉␉␊ |
832 | ␉␉␉␉fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(fadt_file->Length);␊ |
833 | ␉␉␉␉memcpy(fadt_mod, fadt_file, fadt_file->Length);␊ |
834 | ␉␉␉}␊ |
835 | ␉␉}␊ |
836 | ␉␉else ␊ |
837 | ␉␉{␊ |
838 | ␉␉␉if (fadt->Length < 0xF4)␊ |
839 | ␉␉␉{␊ |
840 | ␉␉␉␉fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(0xF4);␊ |
841 | ␉␉␉␉memcpy(fadt_mod, fadt, fadt->Length);␊ |
842 | ␉␉␉␉fadt_mod->Length = 0xF4;␊ |
843 | ␉␉␉}␊ |
844 | ␉␉␉else␊ |
845 | ␉␉␉{␊ |
846 | ␉␉␉␉␊ |
847 | ␉␉␉␉fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(fadt->Length);␉␊ |
848 | ␉␉␉␉memcpy(fadt_mod, fadt, fadt->Length);␊ |
849 | ␉␉␉}␉␉ ␊ |
850 | ␉␉}␉␉␊ |
851 | ␊ |
852 | ␉␉fadt_mod->Revision = 0x04; // FADT rev 4␊ |
853 | ␉␉fadt_mod->RESET_REG = FillGASStruct(0, 0);␊ |
854 | ␉␉fadt_mod->Reset_Value = 0;␊ |
855 | ␉␉fadt_mod->Reserved[0] = 0;␊ |
856 | ␉␉fadt_mod->Reserved[1] = 0;␊ |
857 | ␉␉fadt_mod->Reserved[2] = 0;␊ |
858 | ␉␉fadt_mod->X_PM1a_EVT_BLK = FillGASStruct(fadt_mod->PM1A_Event_Block_Address, fadt_mod->PM1_Event_Block_Length);␊ |
859 | ␉␉fadt_mod->X_PM1b_EVT_BLK = FillGASStruct(fadt_mod->PM1B_Event_Block_Address, fadt_mod->PM1_Event_Block_Length);␊ |
860 | ␉␉fadt_mod->X_PM1a_CNT_BLK = FillGASStruct(fadt_mod->PM1A_Control_Block_Address, fadt_mod->PM1_Control_Block_Length);␊ |
861 | ␉␉fadt_mod->X_PM1b_CNT_BLK = FillGASStruct(fadt_mod->PM1B_Control_Block_Address, fadt_mod->PM1_Control_Block_Length);␊ |
862 | ␉␉fadt_mod->X_PM2_CNT_BLK = FillGASStruct(fadt_mod->PM2_Control_Block_Address, fadt_mod->PM2_Control_Block_Length);␊ |
863 | ␉␉fadt_mod->X_PM_TMR_BLK = FillGASStruct(fadt_mod->PM_Timer_Block_Address, fadt_mod->PM_Timer_Block_Length);␊ |
864 | ␉␉fadt_mod->X_GPE0_BLK = FillGASStruct(fadt_mod->GPE0_Block_Address, fadt_mod->GPE0_Block_Length);␊ |
865 | ␉␉fadt_mod->X_GPE1_BLK = FillGASStruct(fadt_mod->GPE1_Block_Address, fadt_mod->GPE1_Block_Length);␊ |
866 | ␉␉verbose("Converted ACPI V%d FADT to ACPI V4 FADT\n", (fadt) ? fadt->Revision : fadt->Revision);␊ |
867 | ␉} else {␊ |
868 | ␉␉␊ |
869 | ␉␉if (fadt_file) {␊ |
870 | ␉␉␉if (fadt_file->Length < 0x84 && fadt_rev2_needed)␊ |
871 | ␉␉␉{␊ |
872 | ␉␉␉␉fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(0x84);␊ |
873 | ␉␉␉␉memcpy(fadt_mod, fadt_file, fadt_file->Length);␊ |
874 | ␉␉␉␉fadt_mod->Length = 0x84;␊ |
875 | ␉␉␉␉fadt_mod->Revision = 0x02; // FADT rev 2 (ACPI 1.0B MS extensions)␊ |
876 | ␉␉␉} else {␊ |
877 | ␉␉␉␉fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(fadt_file->Length);␊ |
878 | ␉␉␉␉memcpy(fadt_mod, fadt_file, fadt_file->Length);␊ |
879 | ␉␉␉}␊ |
880 | ␊ |
881 | ␉␉} else {␊ |
882 | ␉␉␉if (fadt->Length < 0x84 && fadt_rev2_needed)␊ |
883 | ␉␉␉{␊ |
884 | ␉␉␉␉fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(0x84);␊ |
885 | ␉␉␉␉memcpy(fadt_mod, fadt, fadt->Length);␊ |
886 | ␉␉␉␉fadt_mod->Length = 0x84;␊ |
887 | ␉␉␉␉fadt_mod->Revision = 0x02; // FADT rev 2 (ACPI 1.0B MS extensions)␊ |
888 | ␉␉␉} else {␊ |
889 | ␉␉␉␉fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(fadt->Length);␊ |
890 | ␉␉␉␉memcpy(fadt_mod, fadt, fadt->Length);␊ |
891 | ␉␉␉}␊ |
892 | ␊ |
893 | ␉␉}␉␉␊ |
894 | ␉}␊ |
895 | ␊ |
896 | ␉uint8_t Type = PMProfileError;␊ |
897 | ␉// Determine system type / PM_Model␊ |
898 | ␉␊ |
899 | ␉// Fix System-type if needed (should never happen)␊ |
900 | ␉if (Platform->Type > MaxSupportedPMProfile) ␊ |
901 | ␉{␊ |
902 | ␉␉if(fadt_mod->PM_Profile <= MaxSupportedPMProfile)␊ |
903 | ␉␉␉Platform->Type = fadt_mod->PM_Profile; // get the fadt if correct␊ |
904 | ␉␉else ␊ |
905 | ␉␉␉Platform->Type = 1;␉␉/* Set a fixed value (Desktop) */␊ |
906 | ␉}␊ |
907 | ␉␊ |
908 | ␉// If needed, set System-type from PM_Profile (if valid) else set PM_Profile with a fixed the System-type ␊ |
909 | ␉// Give prior to the FADT pm profile, allow to also control this value with a patched FADT table␊ |
910 | ␉if (fadt_mod->PM_Profile != Platform->Type) ␊ |
911 | ␉{␊ |
912 | ␉␉bool val = false; ␊ |
913 | ␉␉getBoolForKey("PreferInternalProfileDetect", &val, &bootInfo->bootConfig); // if true Give prior to the profile resolved trought the CPU model␊ |
914 | ␉␉␊ |
915 | ␉␉if (fadt_mod->PM_Profile <= MaxSupportedPMProfile && !val) {␊ |
916 | ␉␉␉Platform->Type = fadt_mod->PM_Profile;␊ |
917 | ␉␉} else {␊ |
918 | ␉␉␉fadt_mod->PM_Profile = Platform->Type;␊ |
919 | ␉␉}␉␉␊ |
920 | ␉␉␊ |
921 | ␉}␊ |
922 | ␉␊ |
923 | ␉// Set PM_Profile and System-type if user wanted this value to be forced␊ |
924 | ␉if ( (value=getStringForKey("SystemType", &bootInfo->bootConfig))!=NULL)␊ |
925 | ␉␉if ((Type = (unsigned char) strtoul(value, NULL, 10) ) <= MaxSupportedPMProfile)␊ |
926 | ␉␉{␊ |
927 | ␉␉␉verbose("FADT: changing Preferred_PM_Profile from 0x%02x to 0x%02x\n", fadt->PM_Profile, Type);␊ |
928 | ␉␉␉fadt_mod->PM_Profile = Platform->Type = Type;␊ |
929 | ␉␉} else verbose("Error: system-type must be 0..6. Defaulting to %d !\n", Platform->Type);␊ |
930 | ␉␊ |
931 | ␉␉␊ |
932 | ␉// Patch FADT to fix restart␊ |
933 | ␉if (fix_restart)␊ |
934 | ␉{␊ |
935 | ␉␉fadt_mod->Flags|= 0x400;␊ |
936 | ␉␉fadt_mod->RESET_REG = FillGASStruct(0x0cf9, 1);␊ |
937 | ␉␉fadt_mod->Reset_Value = 0x06;␊ |
938 | ␉␉verbose("FADT: Restart Fix applied !\n");␊ |
939 | ␉}␊ |
940 | ␉␊ |
941 | ␉bool aspm = false;␊ |
942 | ␉if (getBoolForKey(kEnableASPM, &aspm, &bootInfo->bootConfig) && aspm) {␊ |
943 | ␉␉fadt_mod->Boot_Flags = 0x0000; ␊ |
944 | ␉}␊ |
945 | ␉␊ |
946 | ␊ |
947 | ␉// Patch FACS Address␊ |
948 | ␉if (new_facs) {␊ |
949 | ␉␉fadt_mod->FIRMWARE_CTRL=(uint32_t)new_facs;␉␊ |
950 | ␉␉if ((uint32_t)(&(fadt_mod->X_FIRMWARE_CTRL))-(uint32_t)fadt_mod+8<=fadt_mod->Length)␊ |
951 | ␉␉␉fadt_mod->X_FIRMWARE_CTRL=(uint32_t)new_facs;␊ |
952 | ␉␉Platform->hardware_signature = ␉new_facs->hardware_signature;␊ |
953 | ␉} else {␊ |
954 | ␉␉fadt_mod->FIRMWARE_CTRL=(uint32_t)fadt->FIRMWARE_CTRL;␊ |
955 | ␉␉if ((uint32_t)(&(fadt_mod->X_FIRMWARE_CTRL))-(uint32_t)fadt_mod+8<=fadt_mod->Length)␊ |
956 | ␉␉␉fadt_mod->X_FIRMWARE_CTRL=(uint32_t)fadt->FIRMWARE_CTRL;␊ |
957 | ␉␉␉␉␊ |
958 | ␉␉Platform->hardware_signature = ␉((struct acpi_2_facs *)fadt->FIRMWARE_CTRL)->hardware_signature;␊ |
959 | ␉}␊ |
960 | ␉DBG("setting hardware_signature to %x \n",Platform->hardware_signature);␊ |
961 | ␊ |
962 | ␉␊ |
963 | ␉␊ |
964 | ␉// Patch DSDT Address if we have loaded a DSDT table␊ |
965 | ␉if(new_dsdt)␊ |
966 | ␉{␉␉␊ |
967 | ␉␉␊ |
968 | ␉␉fadt_mod->DSDT=(uint32_t)new_dsdt;␊ |
969 | ␉␉if ((uint32_t)(&(fadt_mod->X_DSDT))-(uint32_t)fadt_mod+8<=fadt_mod->Length)␊ |
970 | ␉␉␉fadt_mod->X_DSDT=(uint32_t)new_dsdt;␉␉␊ |
971 | ␉␉␊ |
972 | ␉}␊ |
973 | ␉␊ |
974 | ␉// Correct the checksum␊ |
975 | ␉fadt_mod->Checksum=0;␊ |
976 | ␉fadt_mod->Checksum=256-checksum8(fadt_mod,fadt_mod->Length);␊ |
977 | ␉␊ |
978 | ␉return fadt_mod;␊ |
979 | }␊ |
980 | ␊ |
981 | static uint32_t const MACH_SIG_MP␉␉= 0x00000200;␊ |
982 | static uint32_t const MACH_SIG_ZERO␉␉= 0x00000000;␊ |
983 | ␊ |
984 | struct acpi_2_facs* generate_facs(bool updatefacs)␊ |
985 | {␊ |
986 | ␉struct acpi_2_facs *facs_mod=(struct acpi_2_facs *)AllocateKernelMemory(sizeof(struct acpi_2_facs));␊ |
987 | ␉bzero(facs_mod, sizeof(struct acpi_2_facs));␊ |
988 | ␉␊ |
989 | ␉memcpy(facs_mod->Signature, "FACS", 4);␊ |
990 | ␉facs_mod->Length = sizeof(struct acpi_2_facs);␊ |
991 | ␉␊ |
992 | ␉if (!gPlatformName)␊ |
993 | ␉␉local_readSMBIOS(1);␊ |
994 | ␉␊ |
995 | ␉//TODO : populate␊ |
996 | ␉if (strstr("MacPro", gPlatformName) == 0) {␊ |
997 | ␉␉facs_mod->hardware_signature = MACH_SIG_MP;␊ |
998 | ␉}␊ |
999 | ␉else {␊ |
1000 | ␉␉facs_mod->hardware_signature = MACH_SIG_ZERO;␊ |
1001 | ␉}␊ |
1002 | ␉facs_mod->firmware_waking_vector = 0;␊ |
1003 | ␉facs_mod->global_lock = 0;␊ |
1004 | ␉facs_mod->flags = 0;␊ |
1005 | ␉facs_mod->x_firmware_waking_vector = 0;␊ |
1006 | ␉␊ |
1007 | ␉facs_mod->version = updatefacs; /* ACPI 1.0: 0, ACPI 2.0/3.0: 1, ACPI 4.0: 2 */␊ |
1008 | ␉return facs_mod;␊ |
1009 | }␊ |
1010 | ␊ |
1011 | /* Setup ACPI. Replace DSDT if DSDT.aml is found */␊ |
1012 | int setupAcpi(void)␊ |
1013 | {␉␊ |
1014 | ␉int version;␊ |
1015 | ␉void *new_dsdt=NULL, *new_hpet=NULL, *new_sbst=NULL, *new_ecdt=NULL, *new_asft=NULL, *new_dmar=NULL, *new_apic=NULL, *new_mcfg=NULL, *new_facs=NULL, *new_ssdts[14];␊ |
1016 | ␉␊ |
1017 | ␉struct acpi_2_ssdt *new_ssdt[17]; // 15 + 2 additional tables for pss & cst ␊ |
1018 | ␉struct acpi_2_fadt *fadt; // will be used in CST generator␊ |
1019 | ␉␊ |
1020 | ␉bool oem_facs=false, oem_dsdt=false, oem_ssdt=false, oem_hpet=false, oem_sbst=false, oem_ecdt=false, oem_asft=false, oem_dmar=false, oem_apic=false, oem_mcfg=false;␊ |
1021 | ␉bool update_acpi=false, gen_xsdt=false;␊ |
1022 | ␉bool hpet_replaced=false, sbst_replaced=false, ecdt_replaced=false, asft_replaced=false, dmar_replaced=false, apic_replaced=false, mcfg_replaced=false;␊ |
1023 | ␉bool hpet_added=false, sbst_added=false, ecdt_added=false, asft_added=false, dmar_added=false, apic_added=false, mcfg_added=false;␊ |
1024 | ␉bool gen_facs=false, gen_csta=false, gen_psta=false, speed_step=false;␊ |
1025 | ␉␊ |
1026 | ␉bool quick_ssdt= false; ␊ |
1027 | ␉// Quick ssdt search, ␊ |
1028 | ␉// first try to find ssdt-0.aml, if the file do not exist we␊ |
1029 | ␉// stop searching here, else ssdt-0.aml is loaded and we try ␊ |
1030 | ␉// to find ssdt-1.aml, etc .........␊ |
1031 | ␉␊ |
1032 | ␉int curssdt=0, loadtotssdt=0, totssdt=0, newtotssdt=0;␊ |
1033 | ␉␊ |
1034 | ␉{␊ |
1035 | ␉␉bool tmpval;␊ |
1036 | ␉␉␊ |
1037 | ␉␉oem_dsdt=getBoolForKey(kOEMDSDT, &tmpval, &bootInfo->bootConfig)&&tmpval;␊ |
1038 | ␉␉oem_ssdt=getBoolForKey(kOEMSSDT, &tmpval, &bootInfo->bootConfig)&&tmpval;␊ |
1039 | ␉␉oem_hpet=getBoolForKey(kOEMHPET, &tmpval, &bootInfo->bootConfig)&&tmpval;␊ |
1040 | ␉␉oem_sbst=getBoolForKey(kOEMSBST, &tmpval, &bootInfo->bootConfig)&&tmpval;␊ |
1041 | ␉␉oem_ecdt=getBoolForKey(kOEMECDT, &tmpval, &bootInfo->bootConfig)&&tmpval;␊ |
1042 | ␉␉oem_asft=getBoolForKey(kOEMASFT, &tmpval, &bootInfo->bootConfig)&&tmpval;␊ |
1043 | ␉␉oem_dmar=getBoolForKey(kOEMDMAR, &tmpval, &bootInfo->bootConfig)&&tmpval;␊ |
1044 | ␉␉oem_apic=getBoolForKey(kOEMAPIC, &tmpval, &bootInfo->bootConfig)&&tmpval;␊ |
1045 | ␉␉oem_mcfg=getBoolForKey(kOEMMCFG, &tmpval, &bootInfo->bootConfig)&&tmpval;␊ |
1046 | ␉␉oem_facs=getBoolForKey(kOEMFACS, &tmpval, &bootInfo->bootConfig)&&tmpval;␊ |
1047 | ␉␉␊ |
1048 | ␉␉gen_csta=getBoolForKey(kGenerateCStates, &tmpval, &bootInfo->bootConfig)&&tmpval;␊ |
1049 | ␉␉gen_psta=getBoolForKey(kGeneratePStates, &tmpval, &bootInfo->bootConfig)&&tmpval;␊ |
1050 | ␉␉gen_facs=getBoolForKey(kGenerateFACS, &tmpval, &bootInfo->bootConfig)&&tmpval;␊ |
1051 | ␊ |
1052 | ␉␉update_acpi=getBoolForKey(kUpdateACPI, &tmpval, &bootInfo->bootConfig)&&tmpval;␊ |
1053 | ␉␉␊ |
1054 | ␉␉quick_ssdt=getBoolForKey(kQSSDT, &tmpval, &bootInfo->bootConfig)&&tmpval;␊ |
1055 | ␉␉␊ |
1056 | ␉␉speed_step=getBoolForKey(kSpeedstep, &tmpval, &bootInfo->bootConfig)&&tmpval;␊ |
1057 | ␉␉␊ |
1058 | ␉} ␉␊ |
1059 | ␉␉␉␊ |
1060 | ␉if (speed_step) {␊ |
1061 | ␉␉gen_psta= true;␊ |
1062 | ␉␉gen_csta= true;␊ |
1063 | ␉}␉␊ |
1064 | ␉␉␉␊ |
1065 | ␉// Load replacement ACPI tables␊ |
1066 | ␉if (!oem_dsdt)␊ |
1067 | ␉␉new_dsdt=loadACPITable(kDSDT);␊ |
1068 | ␉␊ |
1069 | ␉␊ |
1070 | ␉if (!oem_hpet)␊ |
1071 | ␉␉new_hpet=loadACPITable(kHPET);␊ |
1072 | ␉␊ |
1073 | ␉␊ |
1074 | ␉if (!oem_sbst)␊ |
1075 | ␉␉new_sbst=loadACPITable(kSBST);␊ |
1076 | ␉␊ |
1077 | ␉␊ |
1078 | ␉if (!oem_ecdt)␊ |
1079 | ␉␉new_ecdt=loadACPITable(kECDT);␊ |
1080 | ␉␊ |
1081 | ␉␊ |
1082 | ␉if (!oem_asft)␊ |
1083 | ␉␉new_asft=loadACPITable(kASFT);␊ |
1084 | ␉␊ |
1085 | ␉␊ |
1086 | ␉if (!oem_dmar)␊ |
1087 | ␉␉new_dmar=loadACPITable(kDMAR);␊ |
1088 | ␉␊ |
1089 | ␉␊ |
1090 | ␉if (!oem_apic)␊ |
1091 | ␉␉new_apic=loadACPITable(kAPIC);␊ |
1092 | ␉␊ |
1093 | ␉␊ |
1094 | ␉if (!oem_mcfg)␊ |
1095 | ␉␉new_mcfg=loadACPITable(kMCFG);␊ |
1096 | ␉␊ |
1097 | ␉if (!oem_facs)␊ |
1098 | ␉␉new_facs=loadACPITable(kFACS);␊ |
1099 | ␉␊ |
1100 | ␉if (!new_facs && gen_facs) new_facs = generate_facs(update_acpi);␊ |
1101 | ␉␊ |
1102 | ␉␊ |
1103 | ␉if (!oem_ssdt)␊ |
1104 | ␉{ ␊ |
1105 | ␉␉␊ |
1106 | ␉␉for (curssdt=0;curssdt<15;curssdt++)␊ |
1107 | ␉␉{␊ |
1108 | ␉␉␉new_ssdt[curssdt]=loadSSDTTable(curssdt);␊ |
1109 | ␉␉␉␊ |
1110 | ␉␉␉if (new_ssdt[curssdt])␊ |
1111 | ␉␉␉␉loadtotssdt++;␉␉␉␊ |
1112 | ␉␉␉else if (quick_ssdt)␉␉␉␉␊ |
1113 | ␉␉␉␉break;␉␉␊ |
1114 | ␉␉␉␊ |
1115 | ␉␉}␊ |
1116 | ␉␉␉␉␉␊ |
1117 | ␉␉curssdt=0;␊ |
1118 | ␉␉␊ |
1119 | ␉}␊ |
1120 | ␉␉␊ |
1121 | ␉DBG("New ACPI tables Loaded in memory\n");␊ |
1122 | ␉TagPtr DropTables_p = XMLCastDict(XMLGetProperty(bootInfo->bootConfig.dictionary, (const char*)"ACPIDropTables"));␊ |
1123 | ␉// Do the same procedure for both versions of ACPI␊ |
1124 | ␉for (version=0; version<2; version++) {␊ |
1125 | ␉␉struct acpi_2_rsdp *rsdp_mod, *rsdp_conv=(struct acpi_2_rsdp *)0;␊ |
1126 | ␉␉struct acpi_2_rsdt *rsdt, *rsdt_mod;␊ |
1127 | ␉␉struct acpi_2_xsdt *xsdt_conv = (struct acpi_2_xsdt *)0;␊ |
1128 | ␉␉int rsdplength;␊ |
1129 | ␉␉␉␉␊ |
1130 | ␉␉// Find original rsdp␊ |
1131 | ␉␉struct acpi_2_rsdp *rsdp=(struct acpi_2_rsdp *)(version?((struct acpi_2_rsdp *)(uint32_t)acpi20_p):((struct acpi_2_rsdp *)(uint32_t)acpi10_p));␊ |
1132 | ␉␉␊ |
1133 | ␉␉if ((update_acpi) && (rsdp->Revision == 0))␊ |
1134 | ␉␉{␊ |
1135 | ␉␉␉rsdp_conv = (struct acpi_2_rsdp *)AllocateKernelMemory(sizeof(struct acpi_2_rsdp));␊ |
1136 | ␉␉␉memcpy(rsdp_conv, rsdp, 20);␊ |
1137 | ␉␉␉␊ |
1138 | ␉␉␉/* Add/change fields */␊ |
1139 | ␉␉␉rsdp_conv->Revision = 2; /* ACPI version 3 */␊ |
1140 | ␉␉␉rsdp_conv->Length = sizeof(struct acpi_2_rsdp);␊ |
1141 | ␉␉␉␊ |
1142 | ␉␉␉/* Correct checksums */␊ |
1143 | ␉␉␉rsdp_conv->Checksum = 0;␊ |
1144 | ␉␉␉rsdp_conv->Checksum = 256-checksum8(rsdp_conv, 20);␊ |
1145 | ␉␉␉rsdp_conv->ExtendedChecksum = 0;␊ |
1146 | ␉␉␉rsdp_conv->ExtendedChecksum = 256-checksum8(rsdp_conv, rsdp_conv->Length);␊ |
1147 | ␉␉␉␊ |
1148 | ␉␉␉rsdp = rsdp_conv;␊ |
1149 | ␉␉␉␊ |
1150 | ␉␉␉gen_xsdt = true;␊ |
1151 | ␉␉␉version = 1;␊ |
1152 | ␉␉␉␊ |
1153 | ␉␉␉addConfigurationTable(&gEfiAcpiTableGuid, NULL, "ACPI");␊ |
1154 | ␉␉␉␊ |
1155 | ␉␉␉verbose("Converted ACPI RSD PTR version 1 to version 3\n");␊ |
1156 | ␉␉}␊ |
1157 | ␉␉if (!rsdp)␊ |
1158 | ␉␉{␊ |
1159 | ␉␉␉DBG("No ACPI version %d found. Ignoring\n", version+1);␊ |
1160 | ␉␉␉if (version)␊ |
1161 | ␉␉␉␉addConfigurationTable(&gEfiAcpi20TableGuid, NULL, "ACPI_20");␊ |
1162 | ␉␉␉else␊ |
1163 | ␉␉␉␉addConfigurationTable(&gEfiAcpiTableGuid, NULL, "ACPI");␊ |
1164 | ␉␉␉continue;␊ |
1165 | ␉␉}␊ |
1166 | ␉␉rsdplength=version?rsdp->Length:20;␊ |
1167 | ␉␉␊ |
1168 | ␉␉DBG("RSDP version %d found @%x. Length=%d\n",version+1,rsdp,rsdplength);␊ |
1169 | ␉␉␊ |
1170 | ␉␉/* FIXME: no check that memory allocation succeeded ␊ |
1171 | ␉␉ * Copy and patch RSDP,RSDT, XSDT and FADT␊ |
1172 | ␉␉ * For more info see ACPI Specification pages 110 and following␊ |
1173 | ␉␉ */␊ |
1174 | ␉␉␊ |
1175 | ␉␉if (gen_xsdt)␊ |
1176 | ␉␉{␊ |
1177 | ␉␉␉rsdp_mod=rsdp_conv;␊ |
1178 | ␉␉} else {␊ |
1179 | ␉␉␉rsdp_mod=(struct acpi_2_rsdp *) AllocateKernelMemory(rsdplength);␊ |
1180 | ␉␉␉memcpy(rsdp_mod, rsdp, rsdplength);␊ |
1181 | ␉␉}␊ |
1182 | ␉␉␊ |
1183 | ␉␉rsdt=(struct acpi_2_rsdt *)(rsdp->RsdtAddress);␊ |
1184 | ␉␉␊ |
1185 | ␉␉DBG("RSDT @%x, Length %d\n",rsdt, rsdt->Length);␊ |
1186 | ␉␉␊ |
1187 | ␉␉if (rsdt && (uint32_t)rsdt !=0xffffffff && rsdt->Length<0x10000)␊ |
1188 | ␉␉{␉␉␉␊ |
1189 | ␉␉␉int dropoffset=0, i;␊ |
1190 | ␉␉␉␊ |
1191 | ␉␉␉rsdt_mod=(struct acpi_2_rsdt *)AllocateKernelMemory(rsdt->Length); ␊ |
1192 | ␉␉␉memcpy (rsdt_mod, rsdt, rsdt->Length);␊ |
1193 | ␉␉␉rsdp_mod->RsdtAddress=(uint32_t)rsdt_mod;␊ |
1194 | ␉␉␉␊ |
1195 | ␉␉␉int rsdt_entries_num=(rsdt_mod->Length-sizeof(struct acpi_2_rsdt))/4;␊ |
1196 | ␉␉␉uint32_t *rsdt_entries=(uint32_t *)(rsdt_mod+1);␊ |
1197 | ␉␉␉␊ |
1198 | ␉␉␉if (gen_xsdt)␊ |
1199 | ␉␉␉{␉␉␉␉␊ |
1200 | ␉␉␉␉xsdt_conv=(struct acpi_2_xsdt *)AllocateKernelMemory(sizeof(struct acpi_2_xsdt)+(rsdt_entries_num * 8));␊ |
1201 | ␉␉␉␉memcpy(xsdt_conv, rsdt, sizeof(struct acpi_2_rsdt));␊ |
1202 | ␉␉␉␉␊ |
1203 | ␉␉␉␉xsdt_conv->Signature[0] = 'X';␊ |
1204 | ␉␉␉␉xsdt_conv->Signature[1] = 'S';␊ |
1205 | ␉␉␉␉xsdt_conv->Signature[2] = 'D';␊ |
1206 | ␉␉␉␉xsdt_conv->Signature[3] = 'T';␊ |
1207 | ␉␉␉␉xsdt_conv->Length = sizeof(struct acpi_2_xsdt)+(rsdt_entries_num * 8);␊ |
1208 | ␉␉␉␉␊ |
1209 | ␉␉␉␉uint64_t *xsdt_conv_entries=(uint64_t *)(xsdt_conv+1);␊ |
1210 | ␉␉␉␉␊ |
1211 | ␉␉␉␉for (i=0;i<rsdt_entries_num;i++)␊ |
1212 | ␉␉␉␉{␊ |
1213 | ␉␉␉␉␉xsdt_conv_entries[i] = (uint64_t)rsdt_entries[i];␊ |
1214 | ␉␉␉␉}␊ |
1215 | ␉␉␉␉␊ |
1216 | ␉␉␉␉xsdt_conv->Checksum = 0;␊ |
1217 | ␉␉␉␉xsdt_conv->Checksum = 256-checksum8(xsdt_conv, xsdt_conv->Length);␊ |
1218 | ␉␉␉␉␊ |
1219 | ␉␉␉␉rsdp->XsdtAddress = (uint32_t)xsdt_conv;␊ |
1220 | ␉␉␉␉␊ |
1221 | ␉␉␉␉rsdp->ExtendedChecksum = 0;␊ |
1222 | ␉␉␉␉rsdp->ExtendedChecksum = 256-checksum8(rsdp, rsdp->Length);␊ |
1223 | ␉␉␉␉␊ |
1224 | ␉␉␉␉verbose("Converted RSDT table to XSDT table\n");␊ |
1225 | ␉␉␉}␊ |
1226 | ␉␉␉␊ |
1227 | ␉␉␉for (i=0;i<rsdt_entries_num;i++)␊ |
1228 | ␉␉␉{␊ |
1229 | ␉␉␉␉char *table=(char *)(rsdt_entries[i]);␊ |
1230 | ␉␉␉␉if (!table)␊ |
1231 | ␉␉␉␉␉continue;␊ |
1232 | ␉␉␉␉␊ |
1233 | ␉␉␉␉DBG("TABLE %c%c%c%c,",table[0],table[1],table[2],table[3]);␊ |
1234 | ␉␉␉␉␊ |
1235 | ␉␉␉␉rsdt_entries[i-dropoffset]=rsdt_entries[i];␊ |
1236 | ␉␉␉␉␊ |
1237 | ␉␉␉␉char table4[4];␊ |
1238 | ␉␉␉␉strlcpy(table4, table, sizeof(table4)+1);␊ |
1239 | ␉␉␉␉TagPtr match_drop = XMLGetProperty(DropTables_p, (const char*)table4);␊ |
1240 | ␉␉␉␉if ( match_drop ) {␊ |
1241 | ␉␉␉␉␉char *tmpstr = XMLCastString(match_drop);␊ |
1242 | ␉␉␉␉␉if (strcmp(tmpstr,"No") != 0) {␉␉␉␉␉␉␊ |
1243 | ␉␉␉␉␉␉dropoffset++;␊ |
1244 | ␉␉␉␉␉␉DBG("%s table dropped\n",table4);␊ |
1245 | ␉␉␉␉␉␉continue;␊ |
1246 | ␉␉␉␉␉}␊ |
1247 | ␉␉␉␉}␊ |
1248 | ␉␉␉␉␉␉␉␉␉␉␉␉␊ |
1249 | ␉␉␉␉if ((!(oem_hpet)) && tableSign(table, "HPET"))␊ |
1250 | ␉␉␉␉{␊ |
1251 | ␉␉␉␉␉DBG("HPET found\n");␊ |
1252 | ␉␉␉␉␉if (new_hpet)␊ |
1253 | ␉␉␉␉␉{␊ |
1254 | ␉␉␉␉␉␉rsdt_entries[i-dropoffset]=(uint32_t)new_hpet;␊ |
1255 | ␉␉␉␉␉␉hpet_replaced=true;␊ |
1256 | ␉␉␉␉␉}␊ |
1257 | ␉␉␉␉␉continue;␊ |
1258 | ␉␉␉␉}␊ |
1259 | ␉␉␉␉if ((!(oem_sbst)) && tableSign(table, "SBST"))␊ |
1260 | ␉␉␉␉{␊ |
1261 | ␉␉␉␉␉DBG("SBST found\n");␊ |
1262 | ␉␉␉␉␉if (new_sbst)␊ |
1263 | ␉␉␉␉␉{␊ |
1264 | ␉␉␉␉␉␉rsdt_entries[i-dropoffset]=(uint32_t)new_sbst;␊ |
1265 | ␉␉␉␉␉␉sbst_replaced=true;␊ |
1266 | ␉␉␉␉␉}␊ |
1267 | ␉␉␉␉␉continue;␊ |
1268 | ␉␉␉␉}␊ |
1269 | ␉␉␉␉if ((!(oem_ecdt)) && tableSign(table, "ECDT"))␊ |
1270 | ␉␉␉␉{␊ |
1271 | ␉␉␉␉␉DBG("ECDT found\n");␊ |
1272 | ␉␉␉␉␉␊ |
1273 | ␉␉␉␉␉if (new_ecdt)␊ |
1274 | ␉␉␉␉␉{␊ |
1275 | ␉␉␉␉␉␉rsdt_entries[i-dropoffset]=(uint32_t)new_ecdt;␊ |
1276 | ␉␉␉␉␉␉ecdt_replaced=true;␊ |
1277 | ␉␉␉␉␉}␊ |
1278 | ␉␉␉␉␉␊ |
1279 | ␉␉␉␉␉continue;␊ |
1280 | ␉␉␉␉}␊ |
1281 | ␉␉␉␉if ((!(oem_asft)) && tableSign(table, "ASF!"))␊ |
1282 | ␉␉␉␉{␊ |
1283 | ␉␉␉␉␉DBG("ASF! found\n");␊ |
1284 | ␉␉␉␉␉if (new_asft)␊ |
1285 | ␉␉␉␉␉{␊ |
1286 | ␉␉␉␉␉␉rsdt_entries[i-dropoffset]=(uint32_t)new_asft;␊ |
1287 | ␉␉␉␉␉␉asft_replaced=true;␊ |
1288 | ␉␉␉␉␉}␊ |
1289 | ␉␉␉␉␉continue;␊ |
1290 | ␉␉␉␉}␊ |
1291 | ␉␉␉␉if ((!(oem_dmar)) && tableSign(table, "DMAR"))␊ |
1292 | ␉␉␉␉{␊ |
1293 | ␉␉␉␉␉DBG("DMAR found\n");␊ |
1294 | ␉␉␉␉␉if (new_dmar)␊ |
1295 | ␉␉␉␉␉{␊ |
1296 | ␉␉␉␉␉␉rsdt_entries[i-dropoffset]=(uint32_t)new_dmar;␊ |
1297 | ␉␉␉␉␉␉dmar_replaced=true;␊ |
1298 | ␉␉␉␉␉}␊ |
1299 | ␉␉␉␉␉continue;␊ |
1300 | ␉␉␉␉}␊ |
1301 | ␉␉␉␉if ((!(oem_apic)) && tableSign(table, "APIC"))␊ |
1302 | ␉␉␉␉{␊ |
1303 | ␉␉␉␉␉DBG("APIC found\n");␊ |
1304 | ␉␉␉␉␉if (new_apic)␊ |
1305 | ␉␉␉␉␉{␊ |
1306 | ␉␉␉␉␉␉rsdt_entries[i-dropoffset]=(uint32_t)new_apic;␊ |
1307 | ␉␉␉␉␉␉apic_replaced=true;␊ |
1308 | ␉␉␉␉␉}␊ |
1309 | ␉␉␉␉␉continue;␊ |
1310 | ␉␉␉␉}␊ |
1311 | ␉␉␉␉if ((!(oem_mcfg)) && tableSign(table, "MCFG"))␊ |
1312 | ␉␉␉␉{␊ |
1313 | ␉␉␉␉␉DBG("MCFG found\n");␊ |
1314 | ␉␉␉␉␉if (new_mcfg)␊ |
1315 | ␉␉␉␉␉{␊ |
1316 | ␉␉␉␉␉␉rsdt_entries[i-dropoffset]=(uint32_t)new_mcfg;␊ |
1317 | ␉␉␉␉␉␉mcfg_replaced=true;␊ |
1318 | ␉␉␉␉␉}␊ |
1319 | ␉␉␉␉␉continue;␊ |
1320 | ␉␉␉␉}␊ |
1321 | ␉␉␉␉if ((!(oem_ssdt)) && tableSign(table, "SSDT"))␊ |
1322 | ␉␉␉␉{␊ |
1323 | ␉␉␉␉␉DBG("SSDT %d found", curssdt);␊ |
1324 | ␉␉␉␉␉if (new_ssdts[curssdt])␊ |
1325 | ␉␉␉␉␉{␊ |
1326 | ␉␉␉␉␉␉DBG(" and replaced");␊ |
1327 | ␉␉␉␉␉␉rsdt_entries[i-dropoffset]=(uint32_t)new_ssdts[curssdt];␊ |
1328 | ␉␉␉␉␉␉totssdt++;␊ |
1329 | ␉␉␉␉␉}␊ |
1330 | ␉␉␉␉␉DBG("\n");␊ |
1331 | ␉␉␉␉␉curssdt++;␊ |
1332 | ␉␉␉␉␉continue;␊ |
1333 | ␉␉␉␉}␊ |
1334 | ␉␉␉␉if ((!(oem_dsdt)) && tableSign(table, "DSDT"))␊ |
1335 | ␉␉␉␉{␉␉␉␉␉␉␉␉␉␉␊ |
1336 | ␉␉␉␉␉DBG("DSDT found\n");␊ |
1337 | ␉␉␉␉␉rsdt_entries[i-dropoffset]=(uint32_t)new_dsdt;␊ |
1338 | ␉␉␉␉␉continue;␉␉␉␉␊ |
1339 | ␉␉␉␉}␊ |
1340 | ␉␉␉␉if (tableSign(table, "FACP"))␊ |
1341 | ␉␉␉␉{␉␉␉␉␉␊ |
1342 | ␉␉␉␉␉fadt=(struct acpi_2_fadt *)rsdt_entries[i];␊ |
1343 | ␉␉␉␉␉␊ |
1344 | ␉␉␉␉␉DBG("FADT found @%x, Length %d\n",fadt, fadt->Length);␊ |
1345 | ␉␉␉␉␉␊ |
1346 | ␉␉␉␉␉if (!fadt || (uint32_t)fadt == 0xffffffff || fadt->Length>0x10000)␊ |
1347 | ␉␉␉␉␉{␊ |
1348 | ␉␉␉␉␉␉printf("FADT incorrect. Not modified\n");␊ |
1349 | ␉␉␉␉␉␉continue;␊ |
1350 | ␉␉␉␉␉}␊ |
1351 | ␉␉␉␉␉verbose("Attempting to patch FADT entry of RSDT\n");␊ |
1352 | ␉␉␉␉␉struct acpi_2_fadt *fadt_mod = patch_fadt(fadt, new_facs, new_dsdt, update_acpi);␊ |
1353 | ␉␉␉␉␉␊ |
1354 | ␉␉␉␉␉rsdt_entries[i-dropoffset]=(uint32_t)fadt_mod;␊ |
1355 | ␉␉␉␉␉␊ |
1356 | ␉␉␉␉␉if (!oem_ssdt)␊ |
1357 | ␉␉␉␉␉{␊ |
1358 | ␉␉␉␉␉␉// Generate _CST SSDT␊ |
1359 | ␉␉␉␉␉␉if ( gen_csta && (new_ssdt[loadtotssdt] = generate_cst_ssdt(fadt_mod)))␊ |
1360 | ␉␉␉␉␉␉{␊ |
1361 | ␉␉␉␉␉␉␉gen_csta= false;␊ |
1362 | ␉␉␉␉␉␉␉loadtotssdt++;␊ |
1363 | ␉␉␉␉␉␉}␊ |
1364 | ␉␉␉␉␉␉␊ |
1365 | ␉␉␉␉␉␉// Generating _PSS SSDT␊ |
1366 | ␉␉␉␉␉␉ if (gen_psta && (new_ssdt[loadtotssdt] = generate_pss_ssdt((void*)fadt_mod->DSDT)))␊ |
1367 | ␉␉␉␉␉␉ {␊ |
1368 | ␉␉␉␉␉␉␉ gen_psta= false;␊ |
1369 | ␉␉␉␉␉␉␉ loadtotssdt++;␊ |
1370 | ␉␉␉␉␉␉ }␉␉␉␉␉␉␉␉␉␉␊ |
1371 | ␉␉␉␉␉␉␊ |
1372 | ␉␉␉␉␉}␊ |
1373 | ␉␉␉␉␉␊ |
1374 | ␉␉␉␉␉continue;␊ |
1375 | ␉␉␉␉}␊ |
1376 | ␉␉␉}␊ |
1377 | ␉␉␉DBG("\n");␊ |
1378 | ␉␉␉␊ |
1379 | ␉␉␉if ((!oem_hpet) && (!hpet_replaced))␊ |
1380 | ␉␉␉{␊ |
1381 | ␉␉␉␉if (new_hpet)␊ |
1382 | ␉␉␉␉{␊ |
1383 | ␉␉␉␉␉rsdt_entries[i-dropoffset]=(uint32_t)new_hpet;␊ |
1384 | ␉␉␉␉␉hpet_added=true;␊ |
1385 | ␉␉␉␉␉i++;␊ |
1386 | ␉␉␉␉}␊ |
1387 | ␉␉␉}␊ |
1388 | ␉␉␉␊ |
1389 | ␉␉␉if ((!oem_sbst) && (!sbst_replaced))␊ |
1390 | ␉␉␉{␊ |
1391 | ␉␉␉␉if (new_sbst)␊ |
1392 | ␉␉␉␉{␊ |
1393 | ␉␉␉␉␉rsdt_entries[i-dropoffset]=(uint32_t)new_sbst;␊ |
1394 | ␉␉␉␉␉sbst_added=true;␊ |
1395 | ␉␉␉␉␉i++;␊ |
1396 | ␉␉␉␉}␊ |
1397 | ␉␉␉}␊ |
1398 | ␉␉␉␊ |
1399 | ␉␉␉if ((!oem_ecdt) && (!ecdt_replaced))␊ |
1400 | ␉␉␉{␊ |
1401 | ␉␉␉␉if (new_ecdt)␊ |
1402 | ␉␉␉␉{␉␉␉␉␉␉␉␉␉␉␊ |
1403 | ␉␉␉␉␉rsdt_entries[i-dropoffset]=(uint32_t)new_ecdt;␊ |
1404 | ␉␉␉␉␉ecdt_added=true;␊ |
1405 | ␉␉␉␉␉i++;␊ |
1406 | ␉␉␉␉}␊ |
1407 | ␉␉␉}␊ |
1408 | ␉␉␉␊ |
1409 | ␉␉␉if ((!oem_asft) && (!asft_replaced))␊ |
1410 | ␉␉␉{␊ |
1411 | ␉␉␉␉if (new_asft)␊ |
1412 | ␉␉␉␉{␊ |
1413 | ␉␉␉␉␉rsdt_entries[i-dropoffset]=(uint32_t)new_asft;␊ |
1414 | ␉␉␉␉␉asft_added=true;␊ |
1415 | ␉␉␉␉␉i++;␊ |
1416 | ␉␉␉␉}␊ |
1417 | ␉␉␉}␊ |
1418 | ␉␉␉␊ |
1419 | ␉␉␉if ((!oem_dmar) && (!dmar_replaced))␊ |
1420 | ␉␉␉{␊ |
1421 | ␉␉␉␉if (new_dmar)␊ |
1422 | ␉␉␉␉{␊ |
1423 | ␉␉␉␉␉rsdt_entries[i-dropoffset]=(uint32_t)new_dmar;␊ |
1424 | ␉␉␉␉␉dmar_added=true;␊ |
1425 | ␉␉␉␉␉i++;␊ |
1426 | ␉␉␉␉}␊ |
1427 | ␉␉␉}␊ |
1428 | ␉␉␉␊ |
1429 | ␉␉␉if ((!oem_apic) && (!apic_replaced))␊ |
1430 | ␉␉␉{␊ |
1431 | ␉␉␉␉if (new_apic)␊ |
1432 | ␉␉␉␉{␊ |
1433 | ␉␉␉␉␉rsdt_entries[i-dropoffset]=(uint32_t)new_apic;␊ |
1434 | ␉␉␉␉␉apic_added=true;␊ |
1435 | ␉␉␉␉␉i++;␊ |
1436 | ␉␉␉␉}␊ |
1437 | ␉␉␉}␊ |
1438 | ␉␉␉␊ |
1439 | ␉␉␉if ((!oem_mcfg) && (!mcfg_replaced))␊ |
1440 | ␉␉␉{␊ |
1441 | ␉␉␉␉if (new_mcfg)␊ |
1442 | ␉␉␉␉{␊ |
1443 | ␉␉␉␉␉rsdt_entries[i-dropoffset]=(uint32_t)new_mcfg;␊ |
1444 | ␉␉␉␉␉mcfg_added=true;␊ |
1445 | ␉␉␉␉␉i++;␊ |
1446 | ␉␉␉␉}␊ |
1447 | ␉␉␉}␊ |
1448 | ␉␉␉␊ |
1449 | ␉␉␉if (!oem_ssdt)␊ |
1450 | ␉␉␉{ ␉␉␉␊ |
1451 | ␉␉␉␉while ((totssdt < loadtotssdt) && (curssdt < 17))␊ |
1452 | ␉␉␉␉{␊ |
1453 | ␉␉␉␉␉if (new_ssdt[curssdt])␊ |
1454 | ␉␉␉␉␉{␊ |
1455 | ␉␉␉␉␉␉DBG("adding SSDT %d\n", curssdt);␉␉␉␉␉␉␊ |
1456 | ␉␉␉␉␉␉rsdt_entries[i-dropoffset]=(uint32_t)new_ssdt[curssdt];␊ |
1457 | ␉␉␉␉␉␉totssdt++;␊ |
1458 | ␉␉␉␉␉␉newtotssdt++;␊ |
1459 | ␉␉␉␉␉␉i++;␊ |
1460 | ␉␉␉␉␉} else if (quick_ssdt) {␉␉␉␉␊ |
1461 | ␉␉␉␉␉␉break;␉␉␉␉␉␉␉␉␊ |
1462 | ␉␉␉␉␉}␊ |
1463 | ␉␉␉␉␉␊ |
1464 | ␉␉␉␉␉curssdt++;␊ |
1465 | ␉␉␉␉}␊ |
1466 | ␉␉␉}␊ |
1467 | ␉␉␉␊ |
1468 | ␉␉␉// Correct the checksum of RSDT␊ |
1469 | ␉␉␉rsdt_mod->Length-=4*dropoffset;␊ |
1470 | ␉␉␉rsdt_mod->Length+=4*newtotssdt;␊ |
1471 | ␉␉␉if (hpet_added)␊ |
1472 | ␉␉␉␉rsdt_mod->Length+=4;␊ |
1473 | ␉␉␉if (sbst_added)␊ |
1474 | ␉␉␉␉rsdt_mod->Length+=4;␊ |
1475 | ␉␉␉if (ecdt_added)␊ |
1476 | ␉␉␉␉rsdt_mod->Length+=4;␊ |
1477 | ␉␉␉if (asft_added)␊ |
1478 | ␉␉␉␉rsdt_mod->Length+=4;␊ |
1479 | ␉␉␉if (dmar_added)␊ |
1480 | ␉␉␉␉rsdt_mod->Length+=4;␊ |
1481 | ␉␉␉if (apic_added)␊ |
1482 | ␉␉␉␉rsdt_mod->Length+=4;␊ |
1483 | ␉␉␉if (mcfg_added)␊ |
1484 | ␉␉␉␉rsdt_mod->Length+=4;␊ |
1485 | ␉␉␉␊ |
1486 | ␉␉␉DBG("RSDT: Original checksum %d, ", rsdt_mod->Checksum);␊ |
1487 | ␉␉␉␊ |
1488 | ␉␉␉rsdt_mod->Checksum=0;␊ |
1489 | ␉␉␉rsdt_mod->Checksum=256-checksum8(rsdt_mod,rsdt_mod->Length);␊ |
1490 | ␉␉␉␊ |
1491 | ␉␉␉DBG("New checksum %d at %x\n", rsdt_mod->Checksum,rsdt_mod);␊ |
1492 | ␉␉␉␊ |
1493 | ␉␉}␊ |
1494 | ␉␉else␊ |
1495 | ␉␉{␊ |
1496 | ␉␉␉rsdp_mod->RsdtAddress=0;␊ |
1497 | ␉␉␉printf("RSDT not found or RSDT incorrect\n");␊ |
1498 | ␉␉}␊ |
1499 | ␉␉␊ |
1500 | ␉␉if (version)␊ |
1501 | ␉␉{␊ |
1502 | ␉␉␉struct acpi_2_xsdt *xsdt, *xsdt_mod;␊ |
1503 | ␉␉␉␊ |
1504 | ␉␉␉// FIXME: handle 64-bit address correctly␊ |
1505 | ␉␉␉␊ |
1506 | ␉␉␉if (gen_xsdt)␊ |
1507 | ␉␉␉␉xsdt=xsdt_conv;␊ |
1508 | ␉␉␉else␊ |
1509 | ␉␉␉␉xsdt=(struct acpi_2_xsdt*) ((uint32_t)rsdp->XsdtAddress);␊ |
1510 | ␉␉␉␊ |
1511 | ␉␉␉DBG("XSDT @%x;%x, Length=%d\n", (uint32_t)(rsdp->XsdtAddress>>32),(uint32_t)rsdp->XsdtAddress,␊ |
1512 | ␉␉␉␉xsdt->Length);␊ |
1513 | ␉␉␉if (xsdt && (uint64_t)rsdp->XsdtAddress<0xffffffff && xsdt->Length<0x10000)␊ |
1514 | ␉␉␉{␉␉␉␉␊ |
1515 | ␉␉␉␉int dropoffset=0, i;␊ |
1516 | ␉␉␉␉curssdt=0, totssdt=0, newtotssdt=0;␊ |
1517 | ␉␉␉␉hpet_replaced=false, hpet_added=false;␊ |
1518 | ␉␉␉␉sbst_replaced=false, sbst_added=false;␊ |
1519 | ␉␉␉␉ecdt_replaced=false, ecdt_added=false;␊ |
1520 | ␉␉␉␉asft_replaced=false, asft_added=false;␊ |
1521 | ␉␉␉␉dmar_replaced=false, dmar_added=false;␊ |
1522 | ␉␉␉␉apic_replaced=false, apic_added=false;␊ |
1523 | ␉␉␉␉mcfg_replaced=false, mcfg_added=false;␊ |
1524 | ␉␉␉␉␊ |
1525 | ␉␉␉␉if (gen_xsdt)␊ |
1526 | ␉␉␉␉␉xsdt_mod=xsdt;␊ |
1527 | ␉␉␉␉else␊ |
1528 | ␉␉␉␉{␊ |
1529 | ␉␉␉␉␉xsdt_mod=(struct acpi_2_xsdt*)AllocateKernelMemory(xsdt->Length); ␊ |
1530 | ␉␉␉␉␉memcpy(xsdt_mod, xsdt, xsdt->Length);␊ |
1531 | ␉␉␉␉}␊ |
1532 | ␉␉␉␉␊ |
1533 | ␉␉␉␉rsdp_mod->XsdtAddress=(uint32_t)xsdt_mod;␊ |
1534 | ␉␉␉␉int xsdt_entries_num=(xsdt_mod->Length-sizeof(struct acpi_2_xsdt))/8;␊ |
1535 | ␉␉␉␉uint64_t *xsdt_entries=(uint64_t *)(xsdt_mod+1);␊ |
1536 | ␉␉␉␉for (i=0;i<xsdt_entries_num;i++)␊ |
1537 | ␉␉␉␉{␊ |
1538 | ␉␉␉␉␉char *table=(char *)((uint32_t)(xsdt_entries[i]));␊ |
1539 | ␉␉␉␉␉if (!table)␊ |
1540 | ␉␉␉␉␉␉continue;␊ |
1541 | ␉␉␉␉␉␊ |
1542 | ␉␉␉␉␉xsdt_entries[i-dropoffset]=xsdt_entries[i];␊ |
1543 | ␉␉␉␉␉␊ |
1544 | ␉␉␉␉␉char table4[4];␊ |
1545 | ␉␉␉␉␉strlcpy(table4, table, sizeof(table4)+1);␊ |
1546 | ␉␉␉␉␉TagPtr match_drop = XMLGetProperty(DropTables_p, (const char*)table4);␊ |
1547 | ␉␉␉␉␉if ( match_drop ) {␊ |
1548 | ␉␉␉␉␉␉char *tmpstr = XMLCastString(match_drop);␊ |
1549 | ␉␉␉␉␉␉if (strcmp(tmpstr,"No") != 0) {␊ |
1550 | ␉␉␉␉␉␉␉dropoffset++;␊ |
1551 | ␉␉␉␉␉␉␉DBG("%s table dropped\n",table4);␊ |
1552 | ␉␉␉␉␉␉␉continue;␊ |
1553 | ␉␉␉␉␉␉}␊ |
1554 | ␉␉␉␉␉}␊ |
1555 | ␉␉␉␉␉␊ |
1556 | ␉␉␉␉␉if ((!(oem_hpet)) && tableSign(table, "HPET"))␊ |
1557 | ␉␉␉␉␉{␊ |
1558 | ␉␉␉␉␉␉DBG("HPET found\n");␊ |
1559 | ␉␉␉␉␉␉if (new_hpet)␊ |
1560 | ␉␉␉␉␉␉{␊ |
1561 | ␉␉␉␉␉␉␉xsdt_entries[i-dropoffset]=(uint32_t)new_hpet;␊ |
1562 | ␉␉␉␉␉␉␉hpet_replaced=true;␊ |
1563 | ␉␉␉␉␉␉}␊ |
1564 | ␉␉␉␉␉␉continue;␊ |
1565 | ␉␉␉␉␉}␊ |
1566 | ␉␉␉␉␉if ((!(oem_sbst)) && tableSign(table, "SBST"))␊ |
1567 | ␉␉␉␉␉{␊ |
1568 | ␉␉␉␉␉␉DBG("SBST found\n");␊ |
1569 | ␉␉␉␉␉␉if (new_sbst)␊ |
1570 | ␉␉␉␉␉␉{␊ |
1571 | ␉␉␉␉␉␉␉xsdt_entries[i-dropoffset]=(uint32_t)new_sbst;␊ |
1572 | ␉␉␉␉␉␉␉sbst_replaced=true;␊ |
1573 | ␉␉␉␉␉␉}␊ |
1574 | ␉␉␉␉␉␉continue;␊ |
1575 | ␉␉␉␉␉}␊ |
1576 | ␉␉␉␉␉if ((!(oem_ecdt)) && tableSign(table, "ECDT"))␊ |
1577 | ␉␉␉␉␉{␊ |
1578 | ␉␉␉␉␉␉DBG("ECDT found\n");␊ |
1579 | ␉␉␉␉␉␉␊ |
1580 | ␉␉␉␉␉␉if (new_ecdt)␊ |
1581 | ␉␉␉␉␉␉{␊ |
1582 | ␉␉␉␉␉␉␉xsdt_entries[i-dropoffset]=(uint32_t)new_ecdt;␊ |
1583 | ␉␉␉␉␉␉␉ecdt_replaced=true;␊ |
1584 | ␉␉␉␉␉␉}␊ |
1585 | ␉␉␉␉␉␉␊ |
1586 | ␉␉␉␉␉␉continue;␊ |
1587 | ␉␉␉␉␉}␊ |
1588 | ␉␉␉␉␉if ((!(oem_asft)) && tableSign(table, "ASF!"))␊ |
1589 | ␉␉␉␉␉{␊ |
1590 | ␉␉␉␉␉␉DBG("ASF! found\n");␊ |
1591 | ␉␉␉␉␉␉if (new_asft)␊ |
1592 | ␉␉␉␉␉␉{␊ |
1593 | ␉␉␉␉␉␉␉xsdt_entries[i-dropoffset]=(uint32_t)new_asft;␊ |
1594 | ␉␉␉␉␉␉␉asft_replaced=true;␊ |
1595 | ␉␉␉␉␉␉}␊ |
1596 | ␉␉␉␉␉␉continue;␊ |
1597 | ␉␉␉␉␉}␊ |
1598 | ␉␉␉␉␉if ((!(oem_dmar)) && tableSign(table, "DMAR"))␊ |
1599 | ␉␉␉␉␉{␊ |
1600 | ␉␉␉␉␉␉DBG("DMAR found\n");␊ |
1601 | ␉␉␉␉␉␉if (new_dmar)␊ |
1602 | ␉␉␉␉␉␉{␊ |
1603 | ␉␉␉␉␉␉␉xsdt_entries[i-dropoffset]=(uint32_t)new_dmar;␊ |
1604 | ␉␉␉␉␉␉␉dmar_replaced=true;␊ |
1605 | ␉␉␉␉␉␉}␊ |
1606 | ␉␉␉␉␉␉continue;␊ |
1607 | ␉␉␉␉␉}␊ |
1608 | ␉␉␉␉␉if ((!(oem_apic)) && tableSign(table, "APIC"))␊ |
1609 | ␉␉␉␉␉{␊ |
1610 | ␉␉␉␉␉␉DBG("APIC found\n");␊ |
1611 | ␉␉␉␉␉␉if (new_apic)␊ |
1612 | ␉␉␉␉␉␉{␊ |
1613 | ␉␉␉␉␉␉␉xsdt_entries[i-dropoffset]=(uint32_t)new_apic;␊ |
1614 | ␉␉␉␉␉␉␉apic_replaced=true;␊ |
1615 | ␉␉␉␉␉␉}␊ |
1616 | ␉␉␉␉␉␉continue;␊ |
1617 | ␉␉␉␉␉}␊ |
1618 | ␉␉␉␉␉if ((!(oem_mcfg)) && tableSign(table, "MCFG"))␊ |
1619 | ␉␉␉␉␉{␊ |
1620 | ␉␉␉␉␉␉DBG("MCFG found\n");␊ |
1621 | ␉␉␉␉␉␉if (new_mcfg)␊ |
1622 | ␉␉␉␉␉␉{␊ |
1623 | ␉␉␉␉␉␉␉xsdt_entries[i-dropoffset]=(uint32_t)new_mcfg;␊ |
1624 | ␉␉␉␉␉␉␉mcfg_replaced=true;␊ |
1625 | ␉␉␉␉␉␉}␊ |
1626 | ␉␉␉␉␉␉continue;␊ |
1627 | ␉␉␉␉␉}␊ |
1628 | ␉␉␉␉␉if ((!(oem_ssdt)) && tableSign(table, "SSDT"))␊ |
1629 | ␉␉␉␉␉{␊ |
1630 | ␉␉␉␉␉␉DBG("SSDT %d found", curssdt);␊ |
1631 | ␉␉␉␉␉␉if (new_ssdts[curssdt])␊ |
1632 | ␉␉␉␉␉␉{␊ |
1633 | ␉␉␉␉␉␉␉DBG(" and replaced");␊ |
1634 | ␉␉␉␉␉␉␉xsdt_entries[i-dropoffset]=(uint32_t)new_ssdts[curssdt];␊ |
1635 | ␉␉␉␉␉␉␉totssdt++;␊ |
1636 | ␉␉␉␉␉␉}␊ |
1637 | ␉␉␉␉␉␉DBG("\n");␊ |
1638 | ␉␉␉␉␉␉curssdt++;␊ |
1639 | ␉␉␉␉␉␉continue;␊ |
1640 | ␉␉␉␉␉}␊ |
1641 | ␉␉␉␉␉if ((!(oem_dsdt)) && tableSign(table, "DSDT"))␊ |
1642 | ␉␉␉␉␉{␊ |
1643 | ␉␉␉␉␉␉DBG("DSDT found\n");␊ |
1644 | ␉␉␉␉␉␉␊ |
1645 | ␉␉␉␉␉␉xsdt_entries[i-dropoffset]=(uint32_t)new_dsdt;␊ |
1646 | ␉␉␉␉␉␉␊ |
1647 | ␉␉␉␉␉␉DBG("TABLE %c%c%c%c@%x,",table[0],table[1],table[2],table[3],xsdt_entries[i]);␊ |
1648 | ␉␉␉␉␉␉␊ |
1649 | ␉␉␉␉␉␉continue;␊ |
1650 | ␉␉␉␉␉␉␊ |
1651 | ␉␉␉␉␉}␊ |
1652 | ␉␉␉␉␉if (tableSign(table, "FACP"))␊ |
1653 | ␉␉␉␉␉{␊ |
1654 | ␉␉␉␉␉␉fadt=(struct acpi_2_fadt *)(uint32_t)xsdt_entries[i];␊ |
1655 | ␉␉␉␉␉␉␊ |
1656 | ␉␉␉␉␉␉DBG("FADT found @%x,%x, Length %d\n",(uint32_t)(xsdt_entries[i]>>32),fadt, ␊ |
1657 | ␉␉␉␉␉␉␉fadt->Length);␊ |
1658 | ␉␉␉␉␉␉␊ |
1659 | ␉␉␉␉␉␉if (!fadt || (uint64_t)xsdt_entries[i] >= 0xffffffff || fadt->Length>0x10000)␊ |
1660 | ␉␉␉␉␉␉{␊ |
1661 | ␉␉␉␉␉␉␉verbose("FADT incorrect or after 4GB. Dropping XSDT\n");␊ |
1662 | ␉␉␉␉␉␉␉goto drop_xsdt;␊ |
1663 | ␉␉␉␉␉␉}␊ |
1664 | ␉␉␉␉␉␉verbose("Attempting to patch FADT entry of XSDT\n");␊ |
1665 | ␉␉␉␉␉␉struct acpi_2_fadt *fadt_mod = patch_fadt(fadt, new_facs, new_dsdt, update_acpi);␊ |
1666 | ␉␉␉␉␉␉␊ |
1667 | ␉␉␉␉␉␉␊ |
1668 | ␉␉␉␉␉␉xsdt_entries[i-dropoffset]=(uint32_t)fadt_mod;␊ |
1669 | ␉␉␉␉␉␉␊ |
1670 | ␉␉␉␉␉␉DBG("TABLE %c%c%c%c@%x,",table[0],table[1],table[2],table[3],xsdt_entries[i]);␊ |
1671 | ␉␉␉␉␉␉␊ |
1672 | ␉␉␉␉␉␉if (!oem_ssdt)␊ |
1673 | ␉␉␉␉␉␉ {␊ |
1674 | ␉␉␉␉␉␉␉ // Generate _CST SSDT␊ |
1675 | ␉␉␉␉␉␉␉ if ( gen_csta && (new_ssdt[loadtotssdt] = generate_cst_ssdt(fadt_mod)))␊ |
1676 | ␉␉␉␉␉␉␉ {␊ |
1677 | ␉␉␉␉␉␉␉␉␉gen_csta= false;␊ |
1678 | ␉␉␉␉␉␉␉␉␉loadtotssdt++;␊ |
1679 | ␉␉␉␉␉␉␉ }␊ |
1680 | ␉␉␉␉␉␉ ␊ |
1681 | ␉␉␉␉␉␉␉ // Generating _PSS SSDT␊ |
1682 | ␉␉␉␉␉␉␉ if (gen_psta && (new_ssdt[loadtotssdt] = generate_pss_ssdt((void*)fadt_mod->DSDT)))␊ |
1683 | ␉␉␉␉␉␉␉ {␊ |
1684 | ␉␉␉␉␉␉␉␉␉gen_psta= false;␊ |
1685 | ␉␉␉␉␉␉␉␉␉loadtotssdt++;␊ |
1686 | ␉␉␉␉␉␉␉ }␊ |
1687 | ␉␉␉␉␉␉ }␊ |
1688 | ␉␉␉␉␉␉␊ |
1689 | ␉␉␉␉␉␉␊ |
1690 | ␉␉␉␉␉␉continue;␊ |
1691 | ␉␉␉␉␉}␊ |
1692 | ␉␉␉␉␉␊ |
1693 | ␉␉␉␉␉DBG("TABLE %c%c%c%c@%x,",table[0],table[1],table[2],table[3],xsdt_entries[i]);␊ |
1694 | ␉␉␉␉␉␊ |
1695 | ␉␉␉␉}␊ |
1696 | ␉␉␉␉␊ |
1697 | ␉␉␉␉if ((!oem_hpet) && (!hpet_replaced))␊ |
1698 | ␉␉␉␉{␊ |
1699 | ␉␉␉␉␉if (new_hpet)␊ |
1700 | ␉␉␉␉␉{␊ |
1701 | ␉␉␉␉␉␉xsdt_entries[i-dropoffset]=(uint32_t)new_hpet;␊ |
1702 | ␉␉␉␉␉␉hpet_added=true;␊ |
1703 | ␉␉␉␉␉␉i++;␊ |
1704 | ␉␉␉␉␉}␊ |
1705 | ␉␉␉␉}␊ |
1706 | ␉␉␉␉␊ |
1707 | ␉␉␉␉if ((!oem_sbst) && (!sbst_replaced))␊ |
1708 | ␉␉␉␉{␊ |
1709 | ␉␉␉␉␉if (new_sbst)␊ |
1710 | ␉␉␉␉␉{␊ |
1711 | ␉␉␉␉␉␉xsdt_entries[i-dropoffset]=(uint32_t)new_sbst;␊ |
1712 | ␉␉␉␉␉␉sbst_added=true;␊ |
1713 | ␉␉␉␉␉␉i++;␊ |
1714 | ␉␉␉␉␉}␊ |
1715 | ␉␉␉␉}␊ |
1716 | ␉␉␉␉␊ |
1717 | ␉␉␉␉if ((!oem_ecdt) && (!ecdt_replaced))␊ |
1718 | ␉␉␉␉{␊ |
1719 | ␉␉␉␉␉if (new_ecdt)␊ |
1720 | ␉␉␉␉␉{␊ |
1721 | ␉␉␉␉␉␉␊ |
1722 | ␉␉␉␉␉␉xsdt_entries[i-dropoffset]=(uint32_t)new_ecdt;␊ |
1723 | ␉␉␉␉␉␉ecdt_added=true;␊ |
1724 | ␉␉␉␉␉␉i++;␊ |
1725 | ␉␉␉␉␉}␊ |
1726 | ␉␉␉␉}␊ |
1727 | ␉␉␉␉␊ |
1728 | ␉␉␉␉if ((!oem_asft) && (!asft_replaced))␊ |
1729 | ␉␉␉␉{␊ |
1730 | ␉␉␉␉␉if (new_asft)␊ |
1731 | ␉␉␉␉␉{␊ |
1732 | ␉␉␉␉␉␉xsdt_entries[i-dropoffset]=(uint32_t)new_asft;␊ |
1733 | ␉␉␉␉␉␉asft_added=true;␊ |
1734 | ␉␉␉␉␉␉i++;␊ |
1735 | ␉␉␉␉␉}␊ |
1736 | ␉␉␉␉}␊ |
1737 | ␉␉␉␉␊ |
1738 | ␉␉␉␉if ((!oem_dmar) && (!dmar_replaced))␊ |
1739 | ␉␉␉␉{␊ |
1740 | ␉␉␉␉␉if (new_dmar)␊ |
1741 | ␉␉␉␉␉{␊ |
1742 | ␉␉␉␉␉␉xsdt_entries[i-dropoffset]=(uint32_t)new_dmar;␊ |
1743 | ␉␉␉␉␉␉dmar_added=true;␊ |
1744 | ␉␉␉␉␉␉i++;␊ |
1745 | ␉␉␉␉␉}␊ |
1746 | ␉␉␉␉}␊ |
1747 | ␉␉␉␉␊ |
1748 | ␉␉␉␉if ((!oem_apic) && (!apic_replaced))␊ |
1749 | ␉␉␉␉{␊ |
1750 | ␉␉␉␉␉if (new_apic)␊ |
1751 | ␉␉␉␉␉{␊ |
1752 | ␉␉␉␉␉␉xsdt_entries[i-dropoffset]=(uint32_t)new_apic;␊ |
1753 | ␉␉␉␉␉␉apic_added=true;␊ |
1754 | ␉␉␉␉␉␉i++;␊ |
1755 | ␉␉␉␉␉}␊ |
1756 | ␉␉␉␉}␊ |
1757 | ␉␉␉␉␊ |
1758 | ␉␉␉␉if ((!oem_mcfg) && (!mcfg_replaced))␊ |
1759 | ␉␉␉␉{␊ |
1760 | ␉␉␉␉␉if (new_mcfg)␊ |
1761 | ␉␉␉␉␉{␊ |
1762 | ␉␉␉␉␉␉xsdt_entries[i-dropoffset]=(uint32_t)new_mcfg;␊ |
1763 | ␉␉␉␉␉␉mcfg_added=true;␊ |
1764 | ␉␉␉␉␉␉i++;␊ |
1765 | ␉␉␉␉␉}␊ |
1766 | ␉␉␉␉}␊ |
1767 | ␉␉␉␉␊ |
1768 | ␉␉␉␉if (!oem_ssdt)␊ |
1769 | ␉␉␉␉{ ␉␉␉␊ |
1770 | ␉␉␉␉␉while ((totssdt < loadtotssdt) && (curssdt < 17))␊ |
1771 | ␉␉␉␉␉{␊ |
1772 | ␉␉␉␉␉␉if (new_ssdt[curssdt])␊ |
1773 | ␉␉␉␉␉␉{␊ |
1774 | ␉␉␉␉␉␉␉DBG("adding SSDT %d\n", curssdt);␊ |
1775 | ␉␉␉␉␉␉␉xsdt_entries[i-dropoffset]=(uint32_t)new_ssdt[curssdt];␊ |
1776 | ␉␉␉␉␉␉␉totssdt++;␊ |
1777 | ␉␉␉␉␉␉␉newtotssdt++;␊ |
1778 | ␉␉␉␉␉␉␉i++;␊ |
1779 | ␉␉␉␉␉␉} else if (quick_ssdt){␉␉␉␉␊ |
1780 | ␉␉␉␉␉␉␉break;␉␉␉␉␉␉␉␉␊ |
1781 | ␉␉␉␉␉␉}␊ |
1782 | ␉␉␉␉␉␉␊ |
1783 | ␉␉␉␉␉␉curssdt++;␊ |
1784 | ␉␉␉␉␉}␊ |
1785 | ␉␉␉␉}␊ |
1786 | ␉␉␉␉␊ |
1787 | ␉␉␉␉// Correct the checksum of XSDT␊ |
1788 | ␉␉␉␉xsdt_mod->Length-=8*dropoffset;␊ |
1789 | ␉␉␉␉xsdt_mod->Length+=8*newtotssdt;␊ |
1790 | ␉␉␉␉if (hpet_added)␊ |
1791 | ␉␉␉␉␉xsdt_mod->Length+=8;␊ |
1792 | ␉␉␉␉if (sbst_added)␊ |
1793 | ␉␉␉␉␉xsdt_mod->Length+=8;␊ |
1794 | ␉␉␉␉if (ecdt_added)␊ |
1795 | ␉␉␉␉␉xsdt_mod->Length+=8;␊ |
1796 | ␉␉␉␉if (asft_added)␊ |
1797 | ␉␉␉␉␉xsdt_mod->Length+=8;␊ |
1798 | ␉␉␉␉if (dmar_added)␊ |
1799 | ␉␉␉␉␉xsdt_mod->Length+=8;␊ |
1800 | ␉␉␉␉if (apic_added)␊ |
1801 | ␉␉␉␉␉xsdt_mod->Length+=8;␊ |
1802 | ␉␉␉␉if (mcfg_added)␊ |
1803 | ␉␉␉␉␉xsdt_mod->Length+=8;␊ |
1804 | ␉␉␉␉␊ |
1805 | ␉␉␉␉xsdt_mod->Checksum=0;␊ |
1806 | ␉␉␉␉xsdt_mod->Checksum=256-checksum8(xsdt_mod,xsdt_mod->Length);␊ |
1807 | ␉␉␉}␊ |
1808 | ␉␉␉else␊ |
1809 | ␉␉␉{␊ |
1810 | ␉␉␉drop_xsdt:␊ |
1811 | ␉␉␉␉␊ |
1812 | ␉␉␉␉DBG("About to drop XSDT\n");␊ |
1813 | ␉␉␉␉␊ |
1814 | ␉␉␉␉/*FIXME: Now we just hope that if MacOS doesn't find XSDT it reverts to RSDT. ␊ |
1815 | ␉␉␉␉ * A Better strategy would be to generate␊ |
1816 | ␉␉␉␉ */␊ |
1817 | ␉␉␉␉␊ |
1818 | ␉␉␉␉rsdp_mod->XsdtAddress=0xffffffffffffffffLL;␊ |
1819 | ␉␉␉␉verbose("XSDT not found or XSDT incorrect\n");␊ |
1820 | ␉␉␉}␊ |
1821 | ␉␉}␊ |
1822 | ␉␉␊ |
1823 | ␉␉// Correct the checksum of RSDP ␊ |
1824 | ␉␉␊ |
1825 | ␉␉DBG("RSDP: Original checksum %d, ", rsdp_mod->Checksum);␊ |
1826 | ␉␉␊ |
1827 | ␉␉rsdp_mod->Checksum=0;␊ |
1828 | ␉␉rsdp_mod->Checksum=256-checksum8(rsdp_mod,20);␊ |
1829 | ␉␉␊ |
1830 | ␉␉DBG("New checksum %d\n", rsdp_mod->Checksum);␊ |
1831 | ␉␉␊ |
1832 | ␉␉if (version)␊ |
1833 | ␉␉{␊ |
1834 | ␉␉␉DBG("RSDP: Original extended checksum %d", rsdp_mod->ExtendedChecksum);␊ |
1835 | ␉␉␉␊ |
1836 | ␉␉␉rsdp_mod->ExtendedChecksum=0;␊ |
1837 | ␉␉␉rsdp_mod->ExtendedChecksum=256-checksum8(rsdp_mod,rsdp_mod->Length);␊ |
1838 | ␉␉␉␊ |
1839 | ␉␉␉DBG("New extended checksum %d\n", rsdp_mod->ExtendedChecksum);␊ |
1840 | ␉␉␉␊ |
1841 | ␉␉}␊ |
1842 | ␉␉␊ |
1843 | ␉␉verbose("Patched ACPI version %d\n", version+1);␉␉␊ |
1844 | ␉␉if (version)␊ |
1845 | ␉␉{␊ |
1846 | ␉␉␉/* XXX aserebln why uint32 cast if pointer is uint64 ? */␊ |
1847 | ␉␉␉acpi20_p = (uint32_t)rsdp_mod;␊ |
1848 | ␉␉␉addConfigurationTable(&gEfiAcpi20TableGuid, &acpi20_p, "ACPI_20");␊ |
1849 | ␉␉}␊ |
1850 | ␉␉else␊ |
1851 | ␉␉{␊ |
1852 | ␉␉␉/* XXX aserebln why uint32 cast if pointer is uint64 ? */␊ |
1853 | ␉␉␉acpi10_p = (uint32_t)rsdp_mod;␊ |
1854 | ␉␉␉addConfigurationTable(&gEfiAcpiTableGuid, &acpi10_p, "ACPI");␊ |
1855 | ␉␉}␊ |
1856 | ␉}␊ |
1857 | #if DEBUG_DSDT␊ |
1858 | ␉printf("Press a key to continue... (DEBUG_DSDT)\n");␊ |
1859 | ␉getc();␊ |
1860 | #endif␊ |
1861 | ␉return 1;␊ |
1862 | ␉␊ |
1863 | } |