Root/
Source at commit 1793 created 12 years 5 months ago. By blackosx, Attempt to overcome issue 211 by revising the code to remove all package .svn files before function makeSubstitutions() is called. The line it replaces should work but I can't figure out why it doesn't... | |
---|---|
1 | /*␊ |
2 | * Copyright 2008 mackerintel␊ |
3 | */␊ |
4 | ␊ |
5 | #include "libsaio.h"␊ |
6 | #include "boot.h"␊ |
7 | #include "bootstruct.h"␊ |
8 | #include "acpi.h"␊ |
9 | #include "efi_tables.h"␊ |
10 | #include "fake_efi.h"␊ |
11 | #include "acpi_patcher.h"␊ |
12 | #include "platform.h"␊ |
13 | #include "cpu.h"␊ |
14 | #include "aml_generator.h"␊ |
15 | ␊ |
16 | #ifndef DEBUG_ACPI␊ |
17 | #define DEBUG_ACPI 0␊ |
18 | #endif␊ |
19 | ␊ |
20 | #if DEBUG_ACPI==2␊ |
21 | #define DBG(x...) {printf(x); sleep(1);}␊ |
22 | #elif DEBUG_ACPI==1␊ |
23 | #define DBG(x...) printf(x)␊ |
24 | #else␊ |
25 | #define DBG(x...)␊ |
26 | #endif␊ |
27 | ␊ |
28 | // Slice: New signature compare function␊ |
29 | boolean_t tableSign(char *table, const char *sgn)␊ |
30 | {␊ |
31 | ␉int i;␊ |
32 | ␉for (i=0; i<4; i++) {␊ |
33 | ␉␉if ((table[i] &~0x20) != (sgn[i] &~0x20)) {␊ |
34 | ␉␉␉return false;␊ |
35 | ␉␉}␊ |
36 | ␉}␊ |
37 | ␉return true;␊ |
38 | }␊ |
39 | ␊ |
40 | /* Gets the ACPI 1.0 RSDP address */␊ |
41 | static struct acpi_2_rsdp* getAddressOfAcpiTable()␊ |
42 | {␊ |
43 | /* TODO: Before searching the BIOS space we are supposed to search the first 1K of the EBDA */␊ |
44 | ␉␊ |
45 | void *acpi_addr = (void*)ACPI_RANGE_START;␊ |
46 | for(; acpi_addr <= (void*)ACPI_RANGE_END; acpi_addr += 16)␊ |
47 | {␊ |
48 | if(*(uint64_t *)acpi_addr == ACPI_SIGNATURE_UINT64_LE)␊ |
49 | {␊ |
50 | uint8_t csum = checksum8(acpi_addr, 20);␊ |
51 | if(csum == 0)␊ |
52 | {␊ |
53 | // Only return the table if it is a true version 1.0 table (Revision 0)␊ |
54 | if(((struct acpi_2_rsdp*)acpi_addr)->Revision == 0)␊ |
55 | return acpi_addr;␊ |
56 | }␊ |
57 | }␊ |
58 | }␊ |
59 | return NULL;␊ |
60 | }␊ |
61 | ␊ |
62 | /* Gets the ACPI 2.0 RSDP address */␊ |
63 | static struct acpi_2_rsdp* getAddressOfAcpi20Table()␊ |
64 | {␊ |
65 | /* TODO: Before searching the BIOS space we are supposed to search the first 1K of the EBDA */␊ |
66 | ␉␊ |
67 | void *acpi_addr = (void*)ACPI_RANGE_START;␊ |
68 | for(; acpi_addr <= (void*)ACPI_RANGE_END; acpi_addr += 16)␊ |
69 | {␊ |
70 | if(*(uint64_t *)acpi_addr == ACPI_SIGNATURE_UINT64_LE)␊ |
71 | {␊ |
72 | uint8_t csum = checksum8(acpi_addr, 20);␊ |
73 | ␉␉␉␊ |
74 | /* Only assume this is a 2.0 or better table if the revision is greater than 0␊ |
75 | * NOTE: ACPI 3.0 spec only seems to say that 1.0 tables have revision 1␊ |
76 | * and that the current revision is 2.. I am going to assume that rev > 0 is 2.0.␊ |
77 | */␊ |
78 | ␉␉␉␊ |
79 | if(csum == 0 && (((struct acpi_2_rsdp*)acpi_addr)->Revision > 0))␊ |
80 | {␊ |
81 | uint8_t csum2 = checksum8(acpi_addr, sizeof(struct acpi_2_rsdp));␊ |
82 | if(csum2 == 0)␊ |
83 | return acpi_addr;␊ |
84 | }␊ |
85 | }␊ |
86 | }␊ |
87 | return NULL;␊ |
88 | }␊ |
89 | /** The folowing ACPI Table search algo. should be reused anywhere needed:*/␊ |
90 | int search_and_get_acpi_fd(const char * filename, const char ** outDirspec)␊ |
91 | {␊ |
92 | ␉int fd = 0;␊ |
93 | ␉char dirSpec[512] = "";␊ |
94 | ␉␊ |
95 | ␉// Try finding 'filename' in the usual places␊ |
96 | ␉// Start searching any potential location for ACPI Table␊ |
97 | ␉sprintf(dirSpec, "%s", filename); ␊ |
98 | ␉fd = open(dirSpec, 0);␊ |
99 | ␉if (fd < 0)␊ |
100 | ␉{␉␊ |
101 | ␉␉sprintf(dirSpec, "/Extra/%s", filename); ␊ |
102 | ␉␉fd = open(dirSpec, 0);␊ |
103 | ␉␉if (fd < 0)␊ |
104 | ␉␉{␊ |
105 | ␉␉␉sprintf(dirSpec, "bt(0,0)/Extra/%s", filename);␊ |
106 | ␉␉␉fd = open(dirSpec, 0);␊ |
107 | ␉␉}␊ |
108 | ␉}␊ |
109 | ␊ |
110 | ␉if (fd < 0)␊ |
111 | ␉{␊ |
112 | ␉␉// NOT FOUND:␊ |
113 | ␉␉verbose("ACPI table not found: %s\n", filename);␊ |
114 | ␉␉*dirSpec = '\0';␊ |
115 | ␉}␊ |
116 | ␊ |
117 | ␉if (outDirspec) *outDirspec = dirSpec; ␊ |
118 | ␉return fd;␊ |
119 | }␊ |
120 | ␊ |
121 | ␊ |
122 | void *loadACPITable (const char * filename)␊ |
123 | {␊ |
124 | ␉void *tableAddr;␊ |
125 | ␉const char * dirspec=NULL;␊ |
126 | ␉␊ |
127 | ␉int fd = search_and_get_acpi_fd(filename, &dirspec);␊ |
128 | ␉␊ |
129 | ␉if (fd>=0)␊ |
130 | ␉{␊ |
131 | ␉␉tableAddr=(void*)AllocateKernelMemory(file_size (fd));␊ |
132 | ␉␉if (tableAddr)␊ |
133 | ␉␉{␊ |
134 | ␉␉␉if (read (fd, tableAddr, file_size (fd))!=file_size (fd))␊ |
135 | ␉␉␉{␊ |
136 | ␉␉␉␉printf("Couldn't read table %s\n",dirspec);␊ |
137 | ␉␉␉␉free (tableAddr);␊ |
138 | ␉␉␉␉close (fd);␊ |
139 | ␉␉␉␉return NULL;␊ |
140 | ␉␉␉}␊ |
141 | ␉␉␉␊ |
142 | ␉␉␉DBG("Table %s read and stored at: %x\n", dirspec, tableAddr);␊ |
143 | ␉␉␉close (fd);␊ |
144 | ␉␉␉return tableAddr;␊ |
145 | ␉␉}␊ |
146 | ␉␉close (fd);␊ |
147 | ␉␉printf("Couldn't allocate memory for table \n", dirspec);␊ |
148 | ␉} ␊ |
149 | ␉//printf("Couldn't find table %s\n", filename);␊ |
150 | ␉return NULL;␊ |
151 | }␊ |
152 | ␊ |
153 | uint8_t␉acpi_cpu_count = 0;␊ |
154 | char* acpi_cpu_name[32];␊ |
155 | uint32_t acpi_cpu_p_blk = 0;␊ |
156 | ␊ |
157 | void get_acpi_cpu_names(unsigned char* dsdt, uint32_t length)␊ |
158 | {␊ |
159 | ␉uint32_t i;␊ |
160 | ␉␊ |
161 | ␉for (i=0; i<length-7; i++) ␊ |
162 | ␉{␊ |
163 | ␉␉if (dsdt[i] == 0x5B && dsdt[i+1] == 0x83) // ProcessorOP␊ |
164 | ␉␉{␊ |
165 | ␉␉␉uint32_t offset = i + 3 + (dsdt[i+2] >> 6);␊ |
166 | ␉␉␉␊ |
167 | ␉␉␉bool add_name = true;␊ |
168 | ␊ |
169 | ␉␉␉uint8_t j;␊ |
170 | ␉␉␉␊ |
171 | ␉␉␉for (j=0; j<4; j++) ␊ |
172 | ␉␉␉{␊ |
173 | ␉␉␉␉char c = dsdt[offset+j];␊ |
174 | ␉␉␉␉␊ |
175 | ␉␉␉␉if (!aml_isvalidchar(c)) ␊ |
176 | ␉␉␉␉{␊ |
177 | ␉␉␉␉␉add_name = false;␊ |
178 | ␉␉␉␉␉verbose("Invalid character found in ProcessorOP 0x%x!\n", c);␊ |
179 | ␉␉␉␉␉break;␊ |
180 | ␉␉␉␉}␊ |
181 | ␉␉␉}␊ |
182 | ␉␉␉␊ |
183 | ␉␉␉if (add_name) ␊ |
184 | ␉␉␉{␊ |
185 | ␉␉␉␉acpi_cpu_name[acpi_cpu_count] = malloc(4);␊ |
186 | ␉␉␉␉memcpy(acpi_cpu_name[acpi_cpu_count], dsdt+offset, 4);␊ |
187 | ␉␉␉␉i = offset + 5;␊ |
188 | ␊ |
189 | if (acpi_cpu_count == 0)␊ |
190 | acpi_cpu_p_blk = dsdt[i] | (dsdt[i+1] << 8);␊ |
191 | ␉␉␉␉␊ |
192 | ␉␉␉␉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]);␊ |
193 | ␉␉␉␉␊ |
194 | ␉␉␉␉if (++acpi_cpu_count == 32) return;␊ |
195 | ␉␉␉}␊ |
196 | ␉␉}␊ |
197 | ␉}␊ |
198 | }␊ |
199 | ␊ |
200 | struct acpi_2_ssdt *generate_cst_ssdt(struct acpi_2_fadt* fadt)␊ |
201 | {␊ |
202 | ␉char ssdt_header[] =␊ |
203 | ␉{␊ |
204 | ␉␉0x53, 0x53, 0x44, 0x54, 0xE7, 0x00, 0x00, 0x00, /* SSDT.... */␊ |
205 | ␉␉0x01, 0x17, 0x50, 0x6D, 0x52, 0x65, 0x66, 0x41, /* ..PmRefA */␊ |
206 | ␉␉0x43, 0x70, 0x75, 0x43, 0x73, 0x74, 0x00, 0x00, /* CpuCst.. */␊ |
207 | ␉␉0x00, 0x10, 0x00, 0x00, 0x49, 0x4E, 0x54, 0x4C, /* ....INTL */␊ |
208 | ␉␉0x31, 0x03, 0x10, 0x20␉␉␉␉␉␉␉/* 1.._␉␉*/␊ |
209 | ␉};␊ |
210 | ␉␊ |
211 | ␉char resource_template_register_fixedhw[] =␊ |
212 | ␉{␊ |
213 | ␉␉0x11, 0x14, 0x0A, 0x11, 0x82, 0x0C, 0x00, 0x7F,␊ |
214 | ␉␉0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,␊ |
215 | ␉␉0x00, 0x00, 0x01, 0x79, 0x00␊ |
216 | ␉};␊ |
217 | ␉␊ |
218 | ␉char resource_template_register_systemio[] =␊ |
219 | ␉{␊ |
220 | ␉␉0x11, 0x14, 0x0A, 0x11, 0x82, 0x0C, 0x00, 0x01,␊ |
221 | ␉␉0x08, 0x00, 0x00, 0x15, 0x04, 0x00, 0x00, 0x00,␊ |
222 | ␉␉0x00, 0x00, 0x00, 0x79, 0x00,␊ |
223 | ␉};␊ |
224 | ␉␊ |
225 | ␉if (Platform.CPU.Vendor != 0x756E6547) {␊ |
226 | ␉␉verbose ("Not an Intel platform: C-States will not be generated !!!\n");␊ |
227 | ␉␉return NULL;␊ |
228 | ␉}␊ |
229 | ␉␊ |
230 | ␉if (fadt == NULL) {␊ |
231 | ␉␉verbose ("FACP not exists: C-States will not be generated !!!\n");␊ |
232 | ␉␉return NULL;␊ |
233 | ␉}␊ |
234 | ␉␊ |
235 | ␉struct acpi_2_dsdt* dsdt = (void*)fadt->DSDT;␊ |
236 | ␉␊ |
237 | ␉if (dsdt == NULL) {␊ |
238 | ␉␉verbose ("DSDT not found: C-States will not be generated !!!\n");␊ |
239 | ␉␉return NULL;␊ |
240 | ␉}␊ |
241 | ␉␊ |
242 | ␉if (acpi_cpu_count == 0)␊ |
243 | ␉␉get_acpi_cpu_names((void*)dsdt, dsdt->Length);␊ |
244 | ␉␊ |
245 | ␉if (acpi_cpu_count > 0)␊ |
246 | ␉{␊ |
247 | ␉␉bool c2_enabled = false;␊ |
248 | ␉␉bool c3_enabled = false;␊ |
249 | ␉␉bool c4_enabled = false;␊ |
250 | ␉␉bool cst_using_systemio = false;␊ |
251 | ␉␉␊ |
252 | ␉␉getBoolForKey(kEnableC2State, &c2_enabled, &bootInfo->chameleonConfig);␊ |
253 | ␉␉getBoolForKey(kEnableC3State, &c3_enabled, &bootInfo->chameleonConfig);␊ |
254 | ␉␉getBoolForKey(kEnableC4State, &c4_enabled, &bootInfo->chameleonConfig);␊ |
255 | ␉␉getBoolForKey(kCSTUsingSystemIO, &cst_using_systemio, &bootInfo->chameleonConfig);␊ |
256 | ␉␉␊ |
257 | ␉␉c2_enabled = c2_enabled | (fadt->C2_Latency < 100);␊ |
258 | ␉␉c3_enabled = c3_enabled | (fadt->C3_Latency < 1000);␊ |
259 | ␉␉␊ |
260 | ␉␉unsigned char cstates_count = 1 + (c2_enabled ? 1 : 0) + (c3_enabled ? 1 : 0);␊ |
261 | ␉␉␊ |
262 | ␉␉struct aml_chunk* root = aml_create_node(NULL);␊ |
263 | ␉␉aml_add_buffer(root, ssdt_header, sizeof(ssdt_header)); // SSDT header␊ |
264 | ␉␉struct aml_chunk* scop = aml_add_scope(root, "\\_PR_");␊ |
265 | ␉␉struct aml_chunk* name = aml_add_name(scop, "CST_");␊ |
266 | ␉␉struct aml_chunk* pack = aml_add_package(name);␊ |
267 | ␉␉aml_add_byte(pack, cstates_count);␊ |
268 | ␉␉␊ |
269 | ␉␉struct aml_chunk* tmpl = aml_add_package(pack);␊ |
270 | ␉␉if (cst_using_systemio)␊ |
271 | ␉␉{␊ |
272 | ␉␉␉// C1␊ |
273 | ␉␉␉resource_template_register_fixedhw[8] = 0x00;␊ |
274 | ␉␉␉resource_template_register_fixedhw[9] = 0x00;␊ |
275 | ␉␉␉resource_template_register_fixedhw[18] = 0x00;␊ |
276 | ␉␉␉aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));␊ |
277 | ␉␉␉aml_add_byte(tmpl, 0x01); // C1␊ |
278 | ␉␉␉aml_add_word(tmpl, 0x0001); // Latency␊ |
279 | ␉␉␉aml_add_dword(tmpl, 0x000003e8); // Power␊ |
280 | ␉␉␉␊ |
281 | ␉␉␉uint8_t p_blk_lo, p_blk_hi;␊ |
282 | ␉␉␉␊ |
283 | ␉␉␉if (c2_enabled) // C2␊ |
284 | ␉␉␉{␊ |
285 | ␉␉␉␉p_blk_lo = acpi_cpu_p_blk + 4;␊ |
286 | ␉␉␉␉p_blk_hi = (acpi_cpu_p_blk + 4) >> 8;␊ |
287 | ␉␉␉␉␊ |
288 | ␉␉␉␉tmpl = aml_add_package(pack);␊ |
289 | ␉␉␉␉resource_template_register_systemio[11] = p_blk_lo; // C2␊ |
290 | ␉␉␉␉resource_template_register_systemio[12] = p_blk_hi; // C2␊ |
291 | ␉␉␉␉aml_add_buffer(tmpl, resource_template_register_systemio, sizeof(resource_template_register_systemio));␊ |
292 | ␉␉␉␉aml_add_byte(tmpl, 0x02); // C2␊ |
293 | ␉␉␉␉aml_add_word(tmpl, 0x0040); // Latency␊ |
294 | ␉␉␉␉aml_add_dword(tmpl, 0x000001f4); // Power␊ |
295 | ␉␉␉}␊ |
296 | ␉␉␉␊ |
297 | ␉␉␉if (c4_enabled) // C4␊ |
298 | ␉␉␉{␊ |
299 | ␉␉␉␉p_blk_lo = acpi_cpu_p_blk + 5;␊ |
300 | ␉␉␉␉p_blk_hi = (acpi_cpu_p_blk + 5) >> 8;␊ |
301 | ␉␉␉␉␊ |
302 | ␉␉␉␉tmpl = aml_add_package(pack);␊ |
303 | ␉␉␉␉resource_template_register_systemio[11] = p_blk_lo; // C4␊ |
304 | ␉␉␉␉resource_template_register_systemio[12] = p_blk_hi; // C4␊ |
305 | ␉␉␉␉aml_add_buffer(tmpl, resource_template_register_systemio, sizeof(resource_template_register_systemio));␊ |
306 | ␉␉␉␉aml_add_byte(tmpl, 0x04); // C4␊ |
307 | ␉␉␉␉aml_add_word(tmpl, 0x0080); // Latency␊ |
308 | ␉␉␉␉aml_add_dword(tmpl, 0x000000C8); // Power␊ |
309 | ␉␉␉}␊ |
310 | ␉␉␉else if (c3_enabled) // C3␊ |
311 | ␉␉␉{␊ |
312 | ␉␉␉␉p_blk_lo = acpi_cpu_p_blk + 5;␊ |
313 | ␉␉␉␉p_blk_hi = (acpi_cpu_p_blk + 5) >> 8;␊ |
314 | ␉␉␉␉␊ |
315 | ␉␉␉␉tmpl = aml_add_package(pack);␊ |
316 | ␉␉␉␉resource_template_register_systemio[11] = p_blk_lo; // C3␊ |
317 | ␉␉␉␉resource_template_register_systemio[12] = p_blk_hi; // C3␊ |
318 | ␉␉␉␉aml_add_buffer(tmpl, resource_template_register_systemio, sizeof(resource_template_register_systemio));␊ |
319 | ␉␉␉␉aml_add_byte(tmpl, 0x03);␉␉␉// C3␊ |
320 | ␉␉␉␉aml_add_word(tmpl, 0x0060);␉␉␉// Latency␊ |
321 | ␉␉␉␉aml_add_dword(tmpl, 0x0000015e);␉// Power␊ |
322 | ␉␉␉}␊ |
323 | ␉␉}␊ |
324 | ␉␉else␊ |
325 | ␉␉{␊ |
326 | ␉␉␉// C1␊ |
327 | ␉␉␉resource_template_register_fixedhw[11] = 0x00; // C1␊ |
328 | ␉␉␉aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));␊ |
329 | ␉␉␉aml_add_byte(tmpl, 0x01);␉␉␉// C1␊ |
330 | ␉␉␉aml_add_word(tmpl, 0x0001);␉␉␉// Latency␊ |
331 | ␉␉␉aml_add_dword(tmpl, 0x000003e8);␉// Power␊ |
332 | ␉␉␉␊ |
333 | ␉␉␉resource_template_register_fixedhw[18] = 0x03;␊ |
334 | ␉␉␉␊ |
335 | ␉␉␉if (c2_enabled) // C2␊ |
336 | ␉␉␉{␊ |
337 | ␉␉␉␉tmpl = aml_add_package(pack);␊ |
338 | ␉␉␉␉resource_template_register_fixedhw[11] = 0x10; // C2␊ |
339 | ␉␉␉␉aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));␊ |
340 | ␉␉␉␉aml_add_byte(tmpl, 0x02);␉␉␉// C2␊ |
341 | ␉␉␉␉aml_add_word(tmpl, 0x0040);␉␉␉// Latency␊ |
342 | ␉␉␉␉aml_add_dword(tmpl, 0x000001f4);␉// Power␊ |
343 | ␉␉␉}␊ |
344 | ␉␉␉␊ |
345 | ␉␉␉if (c4_enabled) // C4␊ |
346 | ␉␉␉{␊ |
347 | ␉␉␉␉tmpl = aml_add_package(pack);␊ |
348 | ␉␉␉␉resource_template_register_fixedhw[11] = 0x30; // C4␊ |
349 | ␉␉␉␉aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));␊ |
350 | ␉␉␉␉aml_add_byte(tmpl, 0x04);␉␉␉// C4␊ |
351 | ␉␉␉␉aml_add_word(tmpl, 0x0080);␉␉␉// Latency␊ |
352 | ␉␉␉␉aml_add_dword(tmpl, 0x000000C8);␉// Power␊ |
353 | ␉␉␉}␊ |
354 | ␉␉␉else if (c3_enabled)␊ |
355 | ␉␉␉{␊ |
356 | ␉␉␉␉tmpl = aml_add_package(pack);␊ |
357 | ␉␉␉␉resource_template_register_fixedhw[11] = 0x20; // C3␊ |
358 | ␉␉␉␉aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));␊ |
359 | ␉␉␉␉aml_add_byte(tmpl, 0x03);␉␉␉// C3␊ |
360 | ␉␉␉␉aml_add_word(tmpl, 0x0060);␉␉␉// Latency␊ |
361 | ␉␉␉␉aml_add_dword(tmpl, 0x0000015e);␉// Power␊ |
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 | ␉␉//dumpPhysAddr("C-States SSDT content: ", ssdt, ssdt->Length);␊ |
389 | ␉␉␊ |
390 | ␉␉verbose ("SSDT with CPU C-States generated successfully\n");␊ |
391 | ␉␉␊ |
392 | ␉␉return ssdt;␊ |
393 | ␉}␊ |
394 | ␉else␊ |
395 | ␉{␊ |
396 | ␉␉verbose ("ACPI CPUs not found: C-States not generated !!!\n");␊ |
397 | ␉}␊ |
398 | ␉␊ |
399 | ␉return NULL;␊ |
400 | }␊ |
401 | ␊ |
402 | struct acpi_2_ssdt *generate_pss_ssdt(struct acpi_2_dsdt* dsdt)␊ |
403 | {␉␊ |
404 | ␉char ssdt_header[] =␊ |
405 | ␉{␊ |
406 | ␉␉0x53, 0x53, 0x44, 0x54, 0x7E, 0x00, 0x00, 0x00, /* SSDT.... */␊ |
407 | ␉␉0x01, 0x6A, 0x50, 0x6D, 0x52, 0x65, 0x66, 0x00, /* ..PmRef. */␊ |
408 | ␉␉0x43, 0x70, 0x75, 0x50, 0x6D, 0x00, 0x00, 0x00, /* CpuPm... */␊ |
409 | ␉␉0x00, 0x30, 0x00, 0x00, 0x49, 0x4E, 0x54, 0x4C, /* .0..INTL */␊ |
410 | ␉␉0x31, 0x03, 0x10, 0x20,␉␉␉␉␉␉␉/* 1.._␉␉*/␊ |
411 | ␉};␊ |
412 | ␉␊ |
413 | ␉if (Platform.CPU.Vendor != 0x756E6547) {␊ |
414 | ␉␉verbose ("Not an Intel platform: P-States will not be generated !!!\n");␊ |
415 | ␉␉return NULL;␊ |
416 | ␉}␊ |
417 | ␉␊ |
418 | ␉if (!(Platform.CPU.Features & CPU_FEATURE_MSR)) {␊ |
419 | ␉␉verbose ("Unsupported CPU: P-States will not be generated !!!\n");␊ |
420 | ␉␉return NULL;␊ |
421 | ␉}␊ |
422 | ␉␊ |
423 | ␉if (acpi_cpu_count == 0) ␊ |
424 | ␉␉get_acpi_cpu_names((void*)dsdt, dsdt->Length);␊ |
425 | ␉␊ |
426 | ␉if (acpi_cpu_count > 0) ␊ |
427 | ␉{␊ |
428 | ␉␉struct p_state initial, maximum, minimum, p_states[32];␊ |
429 | ␉␉uint8_t p_states_count = 0;␉␉␊ |
430 | ␉␉␊ |
431 | ␉␉// Retrieving P-States, ported from code by superhai (c)␊ |
432 | ␉␉switch (Platform.CPU.Family) {␊ |
433 | ␉␉␉case 0x06: ␊ |
434 | ␉␉␉{␊ |
435 | ␉␉␉␉switch (Platform.CPU.Model) ␊ |
436 | ␉␉␉␉{␊ |
437 | ␉␉␉␉␉case CPU_MODEL_DOTHAN:␉// Intel Pentium M␊ |
438 | ␉␉␉␉␉case CPU_MODEL_YONAH:␉// Intel Mobile Core Solo, Duo␊ |
439 | ␉␉␉␉␉case CPU_MODEL_MEROM:␉// Intel Mobile Core 2 Solo, Duo, Xeon 30xx, Xeon 51xx, Xeon X53xx, Xeon E53xx, Xeon X32xx␊ |
440 | ␉␉␉␉␉case CPU_MODEL_PENRYN:␉// Intel Core 2 Solo, Duo, Quad, Extreme, Xeon X54xx, Xeon X33xx␊ |
441 | ␉␉␉␉␉case CPU_MODEL_ATOM:␉// Intel Atom (45nm)␊ |
442 | ␉␉␉␉␉{␊ |
443 | ␉␉␉␉␉␉bool cpu_dynamic_fsb = false;␊ |
444 | ␉␉␉␉␉␉␊ |
445 | ␉␉␉␉␉␉if (rdmsr64(MSR_IA32_EXT_CONFIG) & (1 << 27)) ␊ |
446 | ␉␉␉␉␉␉{␊ |
447 | ␉␉␉␉␉␉␉wrmsr64(MSR_IA32_EXT_CONFIG, (rdmsr64(MSR_IA32_EXT_CONFIG) | (1 << 28))); ␊ |
448 | ␉␉␉␉␉␉␉delay(1);␊ |
449 | ␉␉␉␉␉␉␉cpu_dynamic_fsb = rdmsr64(MSR_IA32_EXT_CONFIG) & (1 << 28);␊ |
450 | ␉␉␉␉␉␉}␊ |
451 | ␉␉␉␉␉␉␊ |
452 | ␉␉␉␉␉␉bool cpu_noninteger_bus_ratio = (rdmsr64(MSR_IA32_PERF_STATUS) & (1ULL << 46));␊ |
453 | ␉␉␉␉␉␉␊ |
454 | ␉␉␉␉␉␉initial.Control = rdmsr64(MSR_IA32_PERF_STATUS);␊ |
455 | ␉␉␉␉␉␉␊ |
456 | ␉␉␉␉␉␉maximum.Control = ((rdmsr64(MSR_IA32_PERF_STATUS) >> 32) & 0x1F3F) | (0x4000 * cpu_noninteger_bus_ratio);␊ |
457 | ␉␉␉␉␉␉maximum.CID = ((maximum.FID & 0x1F) << 1) | cpu_noninteger_bus_ratio;␊ |
458 | ␉␉␉␉␉␉␊ |
459 | ␉␉␉␉␉␉minimum.FID = ((rdmsr64(MSR_IA32_PERF_STATUS) >> 24) & 0x1F) | (0x80 * cpu_dynamic_fsb);␊ |
460 | ␉␉␉␉␉␉minimum.VID = ((rdmsr64(MSR_IA32_PERF_STATUS) >> 48) & 0x3F);␊ |
461 | ␉␉␉␉␉␉␊ |
462 | ␉␉␉␉␉␉if (minimum.FID == 0) ␊ |
463 | ␉␉␉␉␉␉{␊ |
464 | ␉␉␉␉␉␉␉uint64_t msr;␊ |
465 | ␉␉␉␉␉␉␉uint8_t i;␊ |
466 | ␉␉␉␉␉␉␉// Probe for lowest fid␊ |
467 | ␉␉␉␉␉␉␉for (i = maximum.FID; i >= 0x6; i--) ␊ |
468 | ␉␉␉␉␉␉␉{␊ |
469 | ␉␉␉␉␉␉␉␉msr = rdmsr64(MSR_IA32_PERF_CONTROL);␊ |
470 | ␉␉␉␉␉␉␉␉wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (i << 8) | minimum.VID);␊ |
471 | ␉␉␉␉␉␉␉␉intel_waitforsts();␊ |
472 | ␉␉␉␉␉␉␉␉minimum.FID = (rdmsr64(MSR_IA32_PERF_STATUS) >> 8) & 0x1F; ␊ |
473 | ␉␉␉␉␉␉␉␉delay(1);␊ |
474 | ␉␉␉␉␉␉␉}␊ |
475 | ␉␉␉␉␉␉␉␊ |
476 | ␉␉␉␉␉␉␉msr = rdmsr64(MSR_IA32_PERF_CONTROL);␊ |
477 | ␉␉␉␉␉␉␉wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (maximum.FID << 8) | maximum.VID);␊ |
478 | ␉␉␉␉␉␉␉intel_waitforsts();␊ |
479 | ␉␉␉␉␉␉}␊ |
480 | ␉␉␉␉␉␉␊ |
481 | ␉␉␉␉␉␉if (minimum.VID == maximum.VID) ␊ |
482 | ␉␉␉␉␉␉{␉␊ |
483 | ␉␉␉␉␉␉␉uint64_t msr;␊ |
484 | ␉␉␉␉␉␉␉uint8_t i;␊ |
485 | ␉␉␉␉␉␉␉// Probe for lowest vid␊ |
486 | ␉␉␉␉␉␉␉for (i = maximum.VID; i > 0xA; i--) ␊ |
487 | ␉␉␉␉␉␉␉{␊ |
488 | ␉␉␉␉␉␉␉␉msr = rdmsr64(MSR_IA32_PERF_CONTROL);␊ |
489 | ␉␉␉␉␉␉␉␉wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (minimum.FID << 8) | i);␊ |
490 | ␉␉␉␉␉␉␉␉intel_waitforsts();␊ |
491 | ␉␉␉␉␉␉␉␉minimum.VID = rdmsr64(MSR_IA32_PERF_STATUS) & 0x3F; ␊ |
492 | ␉␉␉␉␉␉␉␉delay(1);␊ |
493 | ␉␉␉␉␉␉␉}␊ |
494 | ␉␉␉␉␉␉␉␊ |
495 | ␉␉␉␉␉␉␉msr = rdmsr64(MSR_IA32_PERF_CONTROL);␊ |
496 | ␉␉␉␉␉␉␉wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (maximum.FID << 8) | maximum.VID);␊ |
497 | ␉␉␉␉␉␉␉intel_waitforsts();␊ |
498 | ␉␉␉␉␉␉}␊ |
499 | ␉␉␉␉␉␉␊ |
500 | ␉␉␉␉␉␉minimum.CID = ((minimum.FID & 0x1F) << 1) >> cpu_dynamic_fsb;␊ |
501 | ␉␉␉␉␉␉␊ |
502 | ␉␉␉␉␉␉// Sanity check␊ |
503 | ␉␉␉␉␉␉if (maximum.CID < minimum.CID) ␊ |
504 | ␉␉␉␉␉␉{␊ |
505 | ␉␉␉␉␉␉␉DBG("Insane FID values!");␊ |
506 | ␉␉␉␉␉␉␉p_states_count = 0;␊ |
507 | ␉␉␉␉␉␉}␊ |
508 | ␉␉␉␉␉␉else␊ |
509 | ␉␉␉␉␉␉{␊ |
510 | ␉␉␉␉␉␉␉// Finalize P-States␊ |
511 | ␉␉␉␉␉␉␉// Find how many P-States machine supports␊ |
512 | ␉␉␉␉␉␉␉p_states_count = maximum.CID - minimum.CID + 1;␊ |
513 | ␉␉␉␉␉␉␉␊ |
514 | ␉␉␉␉␉␉␉if (p_states_count > 32) ␊ |
515 | ␉␉␉␉␉␉␉␉p_states_count = 32;␊ |
516 | ␉␉␉␉␉␉␉␊ |
517 | ␉␉␉␉␉␉␉uint8_t vidstep;␊ |
518 | ␉␉␉␉␉␉␉uint8_t i = 0, u, invalid = 0;␊ |
519 | ␉␉␉␉␉␉␉␊ |
520 | ␉␉␉␉␉␉␉vidstep = ((maximum.VID << 2) - (minimum.VID << 2)) / (p_states_count - 1);␊ |
521 | ␉␉␉␉␉␉␉␊ |
522 | ␉␉␉␉␉␉␉for (u = 0; u < p_states_count; u++) ␊ |
523 | ␉␉␉␉␉␉␉{␊ |
524 | ␉␉␉␉␉␉␉␉i = u - invalid;␊ |
525 | ␉␉␉␉␉␉␉␉␊ |
526 | ␉␉␉␉␉␉␉␉p_states[i].CID = maximum.CID - u;␊ |
527 | ␉␉␉␉␉␉␉␉p_states[i].FID = (p_states[i].CID >> 1);␊ |
528 | ␉␉␉␉␉␉␉␉␊ |
529 | ␉␉␉␉␉␉␉␉if (p_states[i].FID < 0x6) ␊ |
530 | ␉␉␉␉␉␉␉␉{␊ |
531 | ␉␉␉␉␉␉␉␉␉if (cpu_dynamic_fsb) ␊ |
532 | ␉␉␉␉␉␉␉␉␉␉p_states[i].FID = (p_states[i].FID << 1) | 0x80;␊ |
533 | ␉␉␉␉␉␉␉␉} ␊ |
534 | ␉␉␉␉␉␉␉␉else if (cpu_noninteger_bus_ratio) ␊ |
535 | ␉␉␉␉␉␉␉␉{␊ |
536 | ␉␉␉␉␉␉␉␉␉p_states[i].FID = p_states[i].FID | (0x40 * (p_states[i].CID & 0x1));␊ |
537 | ␉␉␉␉␉␉␉␉}␊ |
538 | ␉␉␉␉␉␉␉␉␊ |
539 | ␉␉␉␉␉␉␉␉if (i && p_states[i].FID == p_states[i-1].FID)␊ |
540 | ␉␉␉␉␉␉␉␉␉invalid++;␊ |
541 | ␉␉␉␉␉␉␉␉␊ |
542 | ␉␉␉␉␉␉␉␉p_states[i].VID = ((maximum.VID << 2) - (vidstep * u)) >> 2;␊ |
543 | ␉␉␉␉␉␉␉␉␊ |
544 | ␉␉␉␉␉␉␉␉uint32_t multiplier = p_states[i].FID & 0x1f;␉␉// = 0x08␊ |
545 | ␉␉␉␉␉␉␉␉bool half = p_states[i].FID & 0x40;␉␉␉␉␉// = 0x01␊ |
546 | ␉␉␉␉␉␉␉␉bool dfsb = p_states[i].FID & 0x80;␉␉␉␉␉// = 0x00␊ |
547 | ␉␉␉␉␉␉␉␉uint32_t fsb = Platform.CPU.FSBFrequency / 1000000; // = 400␊ |
548 | ␉␉␉␉␉␉␉␉uint32_t halffsb = (fsb + 1) >> 1;␉␉␉␉␉// = 200␊ |
549 | ␉␉␉␉␉␉␉␉uint32_t frequency = (multiplier * fsb);␉␉␉// = 3200␊ |
550 | ␉␉␉␉␉␉␉␉␊ |
551 | ␉␉␉␉␉␉␉␉p_states[i].Frequency = (frequency + (half * halffsb)) >> dfsb;␉// = 3200 + 200 = 3400␊ |
552 | ␉␉␉␉␉␉␉}␊ |
553 | ␉␉␉␉␉␉␉␊ |
554 | ␉␉␉␉␉␉␉p_states_count -= invalid;␊ |
555 | ␉␉␉␉␉␉}␊ |
556 | ␉␉␉␉␉␉␊ |
557 | ␉␉␉␉␉␉break;␊ |
558 | ␉␉␉␉␉} ␊ |
559 | ␉␉␉␉␉case CPU_MODEL_FIELDS:␉␉// Intel Core i5, i7, Xeon X34xx LGA1156 (45nm)␊ |
560 | ␉␉␉␉␉case CPU_MODEL_DALES:␉␉␊ |
561 | ␉␉␉␉␉case CPU_MODEL_DALES_32NM:␉// Intel Core i3, i5 LGA1156 (32nm)␊ |
562 | ␉␉␉␉␉case CPU_MODEL_NEHALEM:␉␉// Intel Core i7, Xeon W35xx, Xeon X55xx, Xeon E55xx LGA1366 (45nm)␊ |
563 | ␉␉␉␉␉case CPU_MODEL_NEHALEM_EX:␉// Intel Xeon X75xx, Xeon X65xx, Xeon E75xx, Xeon E65xx␊ |
564 | ␉␉␉␉␉case CPU_MODEL_WESTMERE:␉// Intel Core i7, Xeon X56xx, Xeon E56xx, Xeon W36xx LGA1366 (32nm) 6 Core␊ |
565 | ␉␉␉␉␉case CPU_MODEL_WESTMERE_EX:␉// Intel Xeon E7␊ |
566 | ␉␉␉␉␉case CPU_MODEL_SANDY:␉␉// Intel Core i3, i5, i7 LGA1155 (32nm)␊ |
567 | ␉␉␉␉␉case CPU_MODEL_SANDY_XEON:␉// Intel Xeon E3␊ |
568 | ␉␉␉␉␉{␊ |
569 | ␉␉␉␉␉␉maximum.Control = rdmsr64(MSR_IA32_PERF_STATUS) & 0xff; // Seems it always contains maximum multiplier value (with turbo, that's we need)...␊ |
570 | ␉␉␉␉␉␉minimum.Control = (rdmsr64(MSR_PLATFORM_INFO) >> 40) & 0xff;␊ |
571 | ␉␉␉␉␉␉␊ |
572 | ␉␉␉␉␉␉verbose("P-States: min 0x%x, max 0x%x\n", minimum.Control, maximum.Control);␉␉␉␊ |
573 | ␉␉␉␉␉␉␊ |
574 | ␉␉␉␉␉␉// Sanity check␊ |
575 | ␉␉␉␉␉␉if (maximum.Control < minimum.Control) ␊ |
576 | ␉␉␉␉␉␉{␊ |
577 | ␉␉␉␉␉␉␉DBG("Insane control values!");␊ |
578 | ␉␉␉␉␉␉␉p_states_count = 0;␊ |
579 | ␉␉␉␉␉␉}␊ |
580 | ␉␉␉␉␉␉else␊ |
581 | ␉␉␉␉␉␉{␊ |
582 | ␉␉␉␉␉␉␉uint8_t i;␊ |
583 | ␉␉␉␉␉␉␉p_states_count = 0;␊ |
584 | ␉␉␉␉␉␉␉␊ |
585 | ␉␉␉␉␉␉␉for (i = maximum.Control; i >= minimum.Control; i--) ␊ |
586 | ␉␉␉␉␉␉␉{␊ |
587 | ␉␉␉␉␉␉␉␉p_states[p_states_count].Control = i;␊ |
588 | ␉␉␉␉␉␉␉␉p_states[p_states_count].CID = p_states[p_states_count].Control << 1;␊ |
589 | ␉␉␉␉␉␉␉␉p_states[p_states_count].Frequency = (Platform.CPU.FSBFrequency / 1000000) * i;␊ |
590 | ␉␉␉␉␉␉␉␉p_states_count++;␊ |
591 | ␉␉␉␉␉␉␉}␊ |
592 | ␉␉␉␉␉␉}␊ |
593 | ␉␉␉␉␉␉␊ |
594 | ␉␉␉␉␉␉break;␊ |
595 | ␉␉␉␉␉}␉␊ |
596 | ␉␉␉␉␉default:␊ |
597 | ␉␉␉␉␉␉verbose ("Unsupported CPU: P-States not generated !!!\n");␊ |
598 | ␉␉␉␉␉␉break;␊ |
599 | ␉␉␉␉}␊ |
600 | ␉␉␉}␊ |
601 | ␉␉}␊ |
602 | ␉␉␊ |
603 | ␉␉// Generating SSDT␊ |
604 | ␉␉if (p_states_count > 0) ␊ |
605 | ␉␉{␉␊ |
606 | ␉␉␉int i;␊ |
607 | ␉␉␉␊ |
608 | ␉␉␉struct aml_chunk* root = aml_create_node(NULL);␊ |
609 | ␉␉␉␉aml_add_buffer(root, ssdt_header, sizeof(ssdt_header)); // SSDT header␊ |
610 | ␉␉␉␉␉struct aml_chunk* scop = aml_add_scope(root, "\\_PR_");␊ |
611 | ␉␉␉␉␉␉struct aml_chunk* name = aml_add_name(scop, "PSS_");␊ |
612 | ␉␉␉␉␉␉␉struct aml_chunk* pack = aml_add_package(name);␊ |
613 | ␉␉␉␊ |
614 | ␉␉␉␉␉␉␉␉for (i = 0; i < p_states_count; i++) ␊ |
615 | ␉␉␉␉␉␉␉␉{␊ |
616 | ␉␉␉␉␉␉␉␉␉struct aml_chunk* pstt = aml_add_package(pack);␊ |
617 | ␉␉␉␉␉␉␉␉␉␊ |
618 | ␉␉␉␉␉␉␉␉␉aml_add_dword(pstt, p_states[i].Frequency);␊ |
619 | ␉␉␉␉␉␉␉␉␉aml_add_dword(pstt, 0x00000000); // Power␊ |
620 | ␉␉␉␉␉␉␉␉␉aml_add_dword(pstt, 0x0000000A); // Latency␊ |
621 | ␉␉␉␉␉␉␉␉␉aml_add_dword(pstt, 0x0000000A); // Latency␊ |
622 | ␉␉␉␉␉␉␉␉␉aml_add_dword(pstt, p_states[i].Control);␊ |
623 | ␉␉␉␉␉␉␉␉␉aml_add_dword(pstt, i+1); // Status␊ |
624 | ␉␉␉␉␉␉␉␉}␊ |
625 | ␉␉␉␉␊ |
626 | ␉␉␉// Add aliaces␊ |
627 | ␉␉␉for (i = 0; i < acpi_cpu_count; i++) ␊ |
628 | ␉␉␉{␊ |
629 | ␉␉␉␉char name[9];␊ |
630 | ␉␉␉␉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]);␊ |
631 | ␉␉␉␉␊ |
632 | ␉␉␉␉scop = aml_add_scope(root, name);␊ |
633 | ␉␉␉␉aml_add_alias(scop, "PSS_", "_PSS");␊ |
634 | ␉␉␉}␊ |
635 | ␉␉␉␊ |
636 | ␉␉␉aml_calculate_size(root);␊ |
637 | ␉␉␉␊ |
638 | ␉␉␉struct acpi_2_ssdt *ssdt = (struct acpi_2_ssdt *)AllocateKernelMemory(root->Size);␊ |
639 | ␉␉␉␊ |
640 | ␉␉␉aml_write_node(root, (void*)ssdt, 0);␊ |
641 | ␉␉␉␊ |
642 | ␉␉␉ssdt->Length = root->Size;␊ |
643 | ␉␉␉ssdt->Checksum = 0;␊ |
644 | ␉␉␉ssdt->Checksum = 256 - checksum8(ssdt, ssdt->Length);␊ |
645 | ␉␉␉␊ |
646 | ␉␉␉aml_destroy_node(root);␊ |
647 | ␉␉␉␊ |
648 | ␉␉␉//dumpPhysAddr("P-States SSDT content: ", ssdt, ssdt->Length);␊ |
649 | ␉␉␉␊ |
650 | ␉␉␉verbose ("SSDT with CPU P-States generated successfully\n");␊ |
651 | ␉␉␉␊ |
652 | ␉␉␉return ssdt;␊ |
653 | ␉␉}␊ |
654 | ␉}␊ |
655 | ␉else ␊ |
656 | ␉{␊ |
657 | ␉␉verbose ("ACPI CPUs not found: P-States not generated !!!\n");␊ |
658 | ␉}␊ |
659 | ␉␊ |
660 | ␉return NULL;␊ |
661 | }␊ |
662 | ␊ |
663 | struct acpi_2_fadt *patch_fadt(struct acpi_2_fadt *fadt, struct acpi_2_dsdt *new_dsdt)␊ |
664 | {␊ |
665 | ␉extern void setupSystemType(); ␊ |
666 | ␉␊ |
667 | ␉struct acpi_2_fadt *fadt_mod;␊ |
668 | ␉bool fadt_rev2_needed = false;␊ |
669 | ␉bool fix_restart;␊ |
670 | ␉const char * value;␊ |
671 | ␉␊ |
672 | ␉// Restart Fix␊ |
673 | ␉if (Platform.CPU.Vendor == 0x756E6547) {␉/* Intel */␊ |
674 | ␉␉fix_restart = true;␊ |
675 | ␉␉getBoolForKey(kRestartFix, &fix_restart, &bootInfo->chameleonConfig);␊ |
676 | ␉} else {␊ |
677 | ␉␉verbose ("Not an Intel platform: Restart Fix not applied !!!\n");␊ |
678 | ␉␉fix_restart = false;␊ |
679 | ␉}␊ |
680 | ␉␊ |
681 | ␉if (fix_restart) fadt_rev2_needed = true;␊ |
682 | ␉␊ |
683 | ␉// Allocate new fadt table␊ |
684 | ␉if (fadt->Length < 0x84 && fadt_rev2_needed)␊ |
685 | ␉{␊ |
686 | ␉␉fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(0x84);␊ |
687 | ␉␉memcpy(fadt_mod, fadt, fadt->Length);␊ |
688 | ␉␉fadt_mod->Length = 0x84;␊ |
689 | ␉␉fadt_mod->Revision = 0x02; // FADT rev 2 (ACPI 1.0B MS extensions)␊ |
690 | ␉}␊ |
691 | ␉else␊ |
692 | ␉{␊ |
693 | ␉␉fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(fadt->Length);␊ |
694 | ␉␉memcpy(fadt_mod, fadt, fadt->Length);␊ |
695 | ␉}␊ |
696 | ␉// Determine system type / PM_Model␊ |
697 | ␉if ( (value=getStringForKey(kSystemType, &bootInfo->chameleonConfig))!=NULL)␊ |
698 | ␉{␊ |
699 | ␉␉if (Platform.Type > 6) ␊ |
700 | ␉␉{␊ |
701 | ␉␉␉if(fadt_mod->PM_Profile<=6)␊ |
702 | ␉␉␉␉Platform.Type = fadt_mod->PM_Profile; // get the fadt if correct␊ |
703 | ␉␉␉else ␊ |
704 | ␉␉␉␉Platform.Type = 1;␉␉/* Set a fixed value (Desktop) */␊ |
705 | ␉␉␉verbose("Error: system-type must be 0..6. Defaulting to %d !\n", Platform.Type);␊ |
706 | ␉␉}␊ |
707 | ␉␉else␊ |
708 | ␉␉␉Platform.Type = (unsigned char) strtoul(value, NULL, 10);␊ |
709 | ␉}␊ |
710 | ␉// Set PM_Profile from System-type if only user wanted this value to be forced␊ |
711 | ␉if (fadt_mod->PM_Profile != Platform.Type) ␊ |
712 | ␉{␊ |
713 | ␉ if (value) ␊ |
714 | ␉␉{ // user has overriden the SystemType so take care of it in FACP␊ |
715 | ␉␉␉verbose("FADT: changing PM_Profile from 0x%02x to 0x%02x\n", fadt_mod->PM_Profile, Platform.Type);␊ |
716 | ␉␉␉fadt_mod->PM_Profile = Platform.Type;␊ |
717 | ␉ }␊ |
718 | ␉ else␊ |
719 | ␉ { // PM_Profile has a different value and no override has been set, so reflect the user value to ioregs␊ |
720 | ␉␉␉Platform.Type = fadt_mod->PM_Profile <= 6 ? fadt_mod->PM_Profile : 1;␊ |
721 | ␉ } ␊ |
722 | ␉}␊ |
723 | ␉// We now have to write the systemm-type in ioregs: we cannot do it before in setupDeviceTree()␊ |
724 | ␉// because we need to take care of facp original content, if it is correct.␊ |
725 | ␉setupSystemType();␊ |
726 | ␉␊ |
727 | ␉// Patch FADT to fix restart␊ |
728 | ␉if (fix_restart)␊ |
729 | ␉{␊ |
730 | ␉␉fadt_mod->Flags|= 0x400;␊ |
731 | ␉␉fadt_mod->Reset_SpaceID␉␉= 0x01; // System I/O␊ |
732 | ␉␉fadt_mod->Reset_BitWidth␉= 0x08; // 1 byte␊ |
733 | ␉␉fadt_mod->Reset_BitOffset␉= 0x00; // Offset 0␊ |
734 | ␉␉fadt_mod->Reset_AccessWidth␉= 0x01; // Byte access␊ |
735 | ␉␉fadt_mod->Reset_Address␉␉= 0x0cf9; // Address of the register␊ |
736 | ␉␉fadt_mod->Reset_Value␉␉= 0x06; // Value to write to reset the system␊ |
737 | ␉␉verbose("FADT: Restart Fix applied!\n");␊ |
738 | ␉}␊ |
739 | ␉␊ |
740 | ␉// Patch DSDT Address if we have loaded DSDT.aml␊ |
741 | ␉if(new_dsdt)␊ |
742 | ␉{␊ |
743 | ␉␉DBG("DSDT: Old @%x,%x, ",fadt_mod->DSDT,fadt_mod->X_DSDT);␊ |
744 | ␉␉␊ |
745 | ␉␉fadt_mod->DSDT=(uint32_t)new_dsdt;␊ |
746 | ␉␉if ((uint32_t)(&(fadt_mod->X_DSDT))-(uint32_t)fadt_mod+8<=fadt_mod->Length)␊ |
747 | ␉␉␉fadt_mod->X_DSDT=(uint32_t)new_dsdt;␊ |
748 | ␉␉␊ |
749 | ␉␉DBG("New @%x,%x\n",fadt_mod->DSDT,fadt_mod->X_DSDT);␊ |
750 | ␉␉␊ |
751 | ␉␉verbose("FADT: Using custom DSDT!\n");␊ |
752 | ␉}␊ |
753 | ␉␊ |
754 | ␉// Correct the checksum␊ |
755 | ␉fadt_mod->Checksum=0;␊ |
756 | ␉fadt_mod->Checksum=256-checksum8(fadt_mod,fadt_mod->Length);␊ |
757 | ␉␊ |
758 | ␉return fadt_mod;␊ |
759 | }␊ |
760 | ␊ |
761 | /* Setup ACPI without replacing DSDT. */␊ |
762 | int setupAcpiNoMod()␊ |
763 | {␊ |
764 | ␉//␉addConfigurationTable(&gEfiAcpiTableGuid, getAddressOfAcpiTable(), "ACPI");␊ |
765 | ␉//␉addConfigurationTable(&gEfiAcpi20TableGuid, getAddressOfAcpi20Table(), "ACPI_20");␊ |
766 | ␉/* XXX aserebln why uint32 cast if pointer is uint64 ? */␊ |
767 | ␉acpi10_p = (uint32_t)getAddressOfAcpiTable();␊ |
768 | ␉acpi20_p = (uint32_t)getAddressOfAcpi20Table();␊ |
769 | ␉addConfigurationTable(&gEfiAcpiTableGuid, &acpi10_p, "ACPI");␊ |
770 | ␉if(acpi20_p) addConfigurationTable(&gEfiAcpi20TableGuid, &acpi20_p, "ACPI_20");␊ |
771 | ␉return 1;␊ |
772 | }␊ |
773 | ␊ |
774 | /* Setup ACPI. Replace DSDT if DSDT.aml is found */␊ |
775 | int setupAcpi(void)␊ |
776 | {␊ |
777 | ␉int version;␊ |
778 | ␉void *new_dsdt;␊ |
779 | ␊ |
780 | ␉const char *filename;␊ |
781 | ␉char dirSpec[128];␊ |
782 | ␉int len = 0;␊ |
783 | ␊ |
784 | ␉// Try using the file specified with the DSDT option␊ |
785 | ␉if (getValueForKey(kDSDT, &filename, &len, &bootInfo->chameleonConfig))␊ |
786 | ␉{␊ |
787 | ␉␉sprintf(dirSpec, filename);␊ |
788 | ␉}␊ |
789 | ␉else␊ |
790 | ␉{␊ |
791 | ␉␉sprintf(dirSpec, "DSDT.aml");␊ |
792 | ␉}␊ |
793 | ␉␊ |
794 | ␉// Load replacement DSDT␊ |
795 | ␉new_dsdt = loadACPITable(dirSpec);␊ |
796 | ␉// Mozodojo: going to patch FACP and load SSDT's even if DSDT.aml is not present␊ |
797 | ␉/*if (!new_dsdt)␊ |
798 | ␉ {␊ |
799 | ␉ return setupAcpiNoMod();␊ |
800 | ␉ }*/␊ |
801 | ␉␊ |
802 | ␉// Mozodojo: Load additional SSDTs␊ |
803 | ␉struct acpi_2_ssdt *new_ssdt[32]; // 30 + 2 additional tables for pss & cst␊ |
804 | ␉int ssdt_count=0;␊ |
805 | ␉␊ |
806 | ␉// SSDT Options␊ |
807 | ␉bool drop_ssdt=false, generate_pstates=false, generate_cstates=false; ␊ |
808 | ␉␊ |
809 | ␉getBoolForKey(kDropSSDT, &drop_ssdt, &bootInfo->chameleonConfig);␊ |
810 | ␉getBoolForKey(kGeneratePStates, &generate_pstates, &bootInfo->chameleonConfig);␊ |
811 | ␉getBoolForKey(kGenerateCStates, &generate_cstates, &bootInfo->chameleonConfig);␊ |
812 | ␉␊ |
813 | ␉{␊ |
814 | ␉␉int i;␊ |
815 | ␉␉␊ |
816 | ␉␉for (i=0; i<30; i++)␊ |
817 | ␉␉{␊ |
818 | ␉␉␉char filename[512];␊ |
819 | ␊ |
820 | ␉␉␉sprintf(filename, i>0?"SSDT-%d.aml":"SSDT.aml", i);␊ |
821 | ␉␉␉␊ |
822 | ␉␉␉if(new_ssdt[ssdt_count] = loadACPITable(filename)) ␊ |
823 | ␉␉␉{␉␉␉␉␊ |
824 | ␉␉␉␉ssdt_count++;␊ |
825 | ␉␉␉}␊ |
826 | ␉␉␉else ␊ |
827 | ␉␉␉{␊ |
828 | ␉␉␉␉break;␊ |
829 | ␉␉␉}␊ |
830 | ␉␉}␊ |
831 | ␉}␊ |
832 | ␉␉␊ |
833 | ␉// Do the same procedure for both versions of ACPI␊ |
834 | ␉for (version=0; version<2; version++) {␊ |
835 | ␉␉struct acpi_2_rsdp *rsdp, *rsdp_mod;␊ |
836 | ␉␉struct acpi_2_rsdt *rsdt, *rsdt_mod;␊ |
837 | ␉␉int rsdplength;␊ |
838 | ␉␉␊ |
839 | ␉␉// Find original rsdp␊ |
840 | ␉␉rsdp=(struct acpi_2_rsdp *)(version?getAddressOfAcpi20Table():getAddressOfAcpiTable());␊ |
841 | ␉␉if (!rsdp)␊ |
842 | ␉␉{␊ |
843 | ␉␉␉DBG("No ACPI version %d found. Ignoring\n", version+1);␊ |
844 | ␉␉␉if (version)␊ |
845 | ␉␉␉␉addConfigurationTable(&gEfiAcpi20TableGuid, NULL, "ACPI_20");␊ |
846 | ␉␉␉else␊ |
847 | ␉␉␉␉addConfigurationTable(&gEfiAcpiTableGuid, NULL, "ACPI");␊ |
848 | ␉␉␉continue;␊ |
849 | ␉␉}␊ |
850 | ␉␉rsdplength=version?rsdp->Length:20;␊ |
851 | ␉␉␊ |
852 | ␉␉DBG("RSDP version %d found @%x. Length=%d\n",version+1,rsdp,rsdplength);␊ |
853 | ␉␉␊ |
854 | ␉␉/* FIXME: no check that memory allocation succeeded ␊ |
855 | ␉␉ * Copy and patch RSDP,RSDT, XSDT and FADT␊ |
856 | ␉␉ * For more info see ACPI Specification pages 110 and following␊ |
857 | ␉␉ */␊ |
858 | ␉␉␊ |
859 | ␉␉rsdp_mod=(struct acpi_2_rsdp *) AllocateKernelMemory(rsdplength);␊ |
860 | ␉␉memcpy(rsdp_mod, rsdp, rsdplength); ␊ |
861 | ␉␉rsdt=(struct acpi_2_rsdt *)(rsdp->RsdtAddress);␊ |
862 | ␉␉␊ |
863 | ␉␉DBG("RSDT @%x, Length %d\n",rsdt, rsdt->Length);␊ |
864 | ␉␉␊ |
865 | ␉␉if (rsdt && (uint32_t)rsdt !=0xffffffff && rsdt->Length<0x10000)␊ |
866 | ␉␉{␊ |
867 | ␉␉␉uint32_t *rsdt_entries;␊ |
868 | ␉␉␉int rsdt_entries_num;␊ |
869 | ␉␉␉int dropoffset=0, i;␊ |
870 | ␉␉␉␊ |
871 | ␉␉␉// mozo: using malloc cos I didn't found how to free already allocated kernel memory␊ |
872 | ␉␉␉rsdt_mod=(struct acpi_2_rsdt *)malloc(rsdt->Length); ␊ |
873 | ␉␉␉memcpy (rsdt_mod, rsdt, rsdt->Length);␊ |
874 | ␉␉␉rsdp_mod->RsdtAddress=(uint32_t)rsdt_mod;␊ |
875 | ␉␉␉rsdt_entries_num=(rsdt_mod->Length-sizeof(struct acpi_2_rsdt))/4;␊ |
876 | ␉␉␉rsdt_entries=(uint32_t *)(rsdt_mod+1);␊ |
877 | ␉␉␉for (i=0;i<rsdt_entries_num;i++)␊ |
878 | ␉␉␉{␊ |
879 | ␉␉␉␉char *table=(char *)(rsdt_entries[i]);␊ |
880 | ␉␉␉␉if (!table)␊ |
881 | ␉␉␉␉␉continue;␊ |
882 | ␉␉␉␉␊ |
883 | ␉␉␉␉DBG("TABLE %c%c%c%c,",table[0],table[1],table[2],table[3]);␊ |
884 | ␉␉␉␉␊ |
885 | ␉␉␉␉rsdt_entries[i-dropoffset]=rsdt_entries[i];␊ |
886 | ␉␉␉␉␊ |
887 | ␉␉␉␉if (drop_ssdt && tableSign(table, "SSDT"))␊ |
888 | ␉␉␉␉{␊ |
889 | ␉␉␉␉␉dropoffset++;␊ |
890 | ␉␉␉␉␉continue;␊ |
891 | ␉␉␉␉}␊ |
892 | ␉␉␉␉if (tableSign(table, "DSDT"))␊ |
893 | ␉␉␉␉{␊ |
894 | ␉␉␉␉␉DBG("DSDT found\n");␊ |
895 | ␉␉␉␉␉␊ |
896 | ␉␉␉␉␉if(new_dsdt)␊ |
897 | ␉␉␉␉␉␉rsdt_entries[i-dropoffset]=(uint32_t)new_dsdt;␊ |
898 | ␉␉␉␉␉␉␉␉␉␉␊ |
899 | ␉␉␉␉␉continue;␊ |
900 | ␉␉␉␉}␊ |
901 | ␉␉␉␉if (tableSign(table, "FACP"))␊ |
902 | ␉␉␉␉{␊ |
903 | ␉␉␉␉␉struct acpi_2_fadt *fadt, *fadt_mod;␊ |
904 | ␉␉␉␉␉fadt=(struct acpi_2_fadt *)rsdt_entries[i];␊ |
905 | ␉␉␉␉␉␊ |
906 | ␉␉␉␉␉DBG("FADT found @%x, Length %d\n",fadt, fadt->Length);␊ |
907 | ␉␉␉␉␉␊ |
908 | ␉␉␉␉␉if (!fadt || (uint32_t)fadt == 0xffffffff || fadt->Length>0x10000)␊ |
909 | ␉␉␉␉␉{␊ |
910 | ␉␉␉␉␉␉printf("FADT incorrect. Not modified\n");␊ |
911 | ␉␉␉␉␉␉continue;␊ |
912 | ␉␉␉␉␉}␊ |
913 | ␉␉␉␉␉␊ |
914 | ␉␉␉␉␉fadt_mod = patch_fadt(fadt, new_dsdt);␊ |
915 | ␉␉␉␉␉rsdt_entries[i-dropoffset]=(uint32_t)fadt_mod;␊ |
916 | ␉␉␉␉␉␊ |
917 | ␉␉␉␉␉// Generate _CST SSDT␊ |
918 | ␉␉␉␉␉if (generate_cstates && (new_ssdt[ssdt_count] = generate_cst_ssdt(fadt_mod)))␊ |
919 | ␉␉␉␉␉{␊ |
920 | ␉␉␉␉␉␉generate_cstates = false; // Generate SSDT only once!␊ |
921 | ␉␉␉␉␉␉ssdt_count++;␊ |
922 | ␉␉␉␉␉}␊ |
923 | ␉␉␉␉␉␊ |
924 | ␉␉␉␉␉// Generating _PSS SSDT␊ |
925 | ␉␉␉␉␉if (generate_pstates && (new_ssdt[ssdt_count] = generate_pss_ssdt((void*)fadt_mod->DSDT)))␊ |
926 | ␉␉␉␉␉{␊ |
927 | ␉␉␉␉␉␉generate_pstates = false; // Generate SSDT only once!␊ |
928 | ␉␉␉␉␉␉ssdt_count++;␊ |
929 | ␉␉␉␉␉}␊ |
930 | ␉␉␉␉␉␊ |
931 | ␉␉␉␉␉continue;␊ |
932 | ␉␉␉␉}␊ |
933 | ␉␉␉}␊ |
934 | ␉␉␉DBG("\n");␊ |
935 | ␉␉␉␊ |
936 | ␉␉␉// Allocate rsdt in Kernel memory area␊ |
937 | ␉␉␉rsdt_mod->Length += 4*ssdt_count - 4*dropoffset;␊ |
938 | ␉␉␉struct acpi_2_rsdt *rsdt_copy = (struct acpi_2_rsdt *)AllocateKernelMemory(rsdt_mod->Length);␊ |
939 | ␉␉␉memcpy (rsdt_copy, rsdt_mod, rsdt_mod->Length);␊ |
940 | ␉␉␉free(rsdt_mod); rsdt_mod = rsdt_copy;␊ |
941 | ␉␉␉rsdp_mod->RsdtAddress=(uint32_t)rsdt_mod;␊ |
942 | ␉␉␉rsdt_entries_num=(rsdt_mod->Length-sizeof(struct acpi_2_rsdt))/4;␊ |
943 | ␉␉␉rsdt_entries=(uint32_t *)(rsdt_mod+1);␊ |
944 | ␉␉␉␊ |
945 | ␉␉␉// Mozodojo: Insert additional SSDTs into RSDT␊ |
946 | ␉␉␉if(ssdt_count>0)␊ |
947 | ␉␉␉{␊ |
948 | ␉␉␉␉int j;␊ |
949 | ␉␉␉␉␊ |
950 | ␉␉␉␉for (j=0; j<ssdt_count; j++)␊ |
951 | ␉␉␉␉␉rsdt_entries[i-dropoffset+j]=(uint32_t)new_ssdt[j];␊ |
952 | ␉␉␉␉␉␊ |
953 | ␉␉␉␉verbose("RSDT: Added %d SSDT table(s)\n", ssdt_count);␊ |
954 | ␉␉␉}␊ |
955 | ␊ |
956 | ␉␉␉// Correct the checksum of RSDT␊ |
957 | ␉␉␉DBG("RSDT: Original checksum %d, ", rsdt_mod->Checksum);␊ |
958 | ␉␉␉␊ |
959 | ␉␉␉rsdt_mod->Checksum=0;␊ |
960 | ␉␉␉rsdt_mod->Checksum=256-checksum8(rsdt_mod,rsdt_mod->Length);␊ |
961 | ␉␉␉␊ |
962 | ␉␉␉DBG("New checksum %d at %x\n", rsdt_mod->Checksum,rsdt_mod);␊ |
963 | ␉␉}␊ |
964 | ␉␉else␊ |
965 | ␉␉{␊ |
966 | ␉␉␉rsdp_mod->RsdtAddress=0;␊ |
967 | ␉␉␉printf("RSDT not found or RSDT incorrect\n");␊ |
968 | ␉␉}␊ |
969 | ␉␉␊ |
970 | ␉␉if (version)␊ |
971 | ␉␉{␊ |
972 | ␉␉␉struct acpi_2_xsdt *xsdt, *xsdt_mod;␊ |
973 | ␉␉␉␊ |
974 | ␉␉␉// FIXME: handle 64-bit address correctly␊ |
975 | ␉␉␉␊ |
976 | ␉␉␉xsdt=(struct acpi_2_xsdt*) ((uint32_t)rsdp->XsdtAddress);␊ |
977 | ␉␉␉DBG("XSDT @%x;%x, Length=%d\n", (uint32_t)(rsdp->XsdtAddress>>32),(uint32_t)rsdp->XsdtAddress,␊ |
978 | ␉␉␉␉xsdt->Length);␊ |
979 | ␉␉␉if (xsdt && (uint64_t)rsdp->XsdtAddress<0xffffffff && xsdt->Length<0x10000)␊ |
980 | ␉␉␉{␊ |
981 | ␉␉␉␉uint64_t *xsdt_entries;␊ |
982 | ␉␉␉␉int xsdt_entries_num, i;␊ |
983 | ␉␉␉␉int dropoffset=0;␊ |
984 | ␉␉␉␉␊ |
985 | ␉␉␉␉// mozo: using malloc cos I didn't found how to free already allocated kernel memory␊ |
986 | ␉␉␉␉xsdt_mod=(struct acpi_2_xsdt*)malloc(xsdt->Length); ␊ |
987 | ␉␉␉␉memcpy(xsdt_mod, xsdt, xsdt->Length);␊ |
988 | ␉␉␉␉rsdp_mod->XsdtAddress=(uint32_t)xsdt_mod;␊ |
989 | ␉␉␉␉xsdt_entries_num=(xsdt_mod->Length-sizeof(struct acpi_2_xsdt))/8;␊ |
990 | ␉␉␉␉xsdt_entries=(uint64_t *)(xsdt_mod+1);␊ |
991 | ␉␉␉␉for (i=0;i<xsdt_entries_num;i++)␊ |
992 | ␉␉␉␉{␊ |
993 | ␉␉␉␉␉char *table=(char *)((uint32_t)(xsdt_entries[i]));␊ |
994 | ␉␉␉␉␉if (!table)␊ |
995 | ␉␉␉␉␉␉continue;␊ |
996 | ␉␉␉␉␉␊ |
997 | ␉␉␉␉␉xsdt_entries[i-dropoffset]=xsdt_entries[i];␊ |
998 | ␉␉␉␉␉␊ |
999 | ␉␉␉␉␉if (drop_ssdt && tableSign(table, "SSDT"))␊ |
1000 | ␉␉␉␉␉{␊ |
1001 | ␉␉␉␉␉␉dropoffset++;␊ |
1002 | ␉␉␉␉␉␉continue;␊ |
1003 | ␉␉␉␉␉}␉␉␉␉␉␊ |
1004 | ␉␉␉␉␉if (tableSign(table, "DSDT"))␊ |
1005 | ␉␉␉␉␉{␊ |
1006 | ␉␉␉␉␉␉DBG("DSDT found\n");␊ |
1007 | ␉␉␉␉␉␉␊ |
1008 | ␉␉␉␉␉␉if (new_dsdt) ␊ |
1009 | ␉␉␉␉␉␉␉xsdt_entries[i-dropoffset]=(uint32_t)new_dsdt;␊ |
1010 | ␉␉␉␉␉␉␊ |
1011 | ␉␉␉␉␉␉DBG("TABLE %c%c%c%c@%x,",table[0],table[1],table[2],table[3],xsdt_entries[i]);␊ |
1012 | ␉␉␉␉␉␉␊ |
1013 | ␉␉␉␉␉␉continue;␊ |
1014 | ␉␉␉␉␉}␊ |
1015 | ␉␉␉␉␉if (tableSign(table, "FACP"))␊ |
1016 | ␉␉␉␉␉{␊ |
1017 | ␉␉␉␉␉␉struct acpi_2_fadt *fadt, *fadt_mod;␊ |
1018 | ␉␉␉␉␉␉fadt=(struct acpi_2_fadt *)(uint32_t)xsdt_entries[i];␊ |
1019 | ␉␉␉␉␉␉␊ |
1020 | ␉␉␉␉␉␉DBG("FADT found @%x,%x, Length %d\n",(uint32_t)(xsdt_entries[i]>>32),fadt, ␊ |
1021 | ␉␉␉␉␉␉␉fadt->Length);␊ |
1022 | ␉␉␉␉␉␉␊ |
1023 | ␉␉␉␉␉␉if (!fadt || (uint64_t)xsdt_entries[i] >= 0xffffffff || fadt->Length>0x10000)␊ |
1024 | ␉␉␉␉␉␉{␊ |
1025 | ␉␉␉␉␉␉␉verbose("FADT incorrect or after 4GB. Dropping XSDT\n");␊ |
1026 | ␉␉␉␉␉␉␉goto drop_xsdt;␊ |
1027 | ␉␉␉␉␉␉}␊ |
1028 | ␉␉␉␉␉␉␊ |
1029 | ␉␉␉␉␉␉fadt_mod = patch_fadt(fadt, new_dsdt);␊ |
1030 | ␉␉␉␉␉␉xsdt_entries[i-dropoffset]=(uint32_t)fadt_mod;␊ |
1031 | ␉␉␉␉␉␉␊ |
1032 | ␉␉␉␉␉␉DBG("TABLE %c%c%c%c@%x,",table[0],table[1],table[2],table[3],xsdt_entries[i]);␊ |
1033 | ␉␉␉␉␉␉␊ |
1034 | ␉␉␉␉␉␉// Generate _CST SSDT␊ |
1035 | ␉␉␉␉␉␉if (generate_cstates && (new_ssdt[ssdt_count] = generate_cst_ssdt(fadt_mod))) ␊ |
1036 | ␉␉␉␉␉␉{␊ |
1037 | ␉␉␉␉␉␉␉generate_cstates = false; // Generate SSDT only once!␊ |
1038 | ␉␉␉␉␉␉␉ssdt_count++;␊ |
1039 | ␉␉␉␉␉␉}␊ |
1040 | ␉␉␉␉␉␉␊ |
1041 | ␉␉␉␉␉␉// Generating _PSS SSDT␊ |
1042 | ␉␉␉␉␉␉if (generate_pstates && (new_ssdt[ssdt_count] = generate_pss_ssdt((void*)fadt_mod->DSDT)))␊ |
1043 | ␉␉␉␉␉␉{␊ |
1044 | ␉␉␉␉␉␉␉generate_pstates = false; // Generate SSDT only once!␊ |
1045 | ␉␉␉␉␉␉␉ssdt_count++;␊ |
1046 | ␉␉␉␉␉␉}␊ |
1047 | ␉␉␉␉␉␉␊ |
1048 | ␉␉␉␉␉␉continue;␊ |
1049 | ␉␉␉␉␉}␊ |
1050 | ␉␉␉␉␉␊ |
1051 | ␉␉␉␉␉DBG("TABLE %c%c%c%c@%x,",table[0],table[1],table[2],table[3],xsdt_entries[i]);␊ |
1052 | ␉␉␉␉␉␊ |
1053 | ␉␉␉␉}␊ |
1054 | ␉␉␉␉␊ |
1055 | ␉␉␉␉// Allocate xsdt in Kernel memory area␊ |
1056 | ␉␉␉␉xsdt_mod->Length += 8*ssdt_count - 8*dropoffset;␊ |
1057 | ␉␉␉␉struct acpi_2_xsdt *xsdt_copy = (struct acpi_2_xsdt *)AllocateKernelMemory(xsdt_mod->Length);␊ |
1058 | ␉␉␉␉memcpy(xsdt_copy, xsdt_mod, xsdt_mod->Length);␊ |
1059 | ␉␉␉␉free(xsdt_mod); xsdt_mod = xsdt_copy;␊ |
1060 | ␉␉␉␉rsdp_mod->XsdtAddress=(uint32_t)xsdt_mod;␊ |
1061 | ␉␉␉␉xsdt_entries_num=(xsdt_mod->Length-sizeof(struct acpi_2_xsdt))/8;␊ |
1062 | ␉␉␉␉xsdt_entries=(uint64_t *)(xsdt_mod+1);␊ |
1063 | ␉␉␉␉␊ |
1064 | ␉␉␉␉// Mozodojo: Insert additional SSDTs into XSDT␊ |
1065 | ␉␉␉␉if(ssdt_count>0)␊ |
1066 | ␉␉␉␉{␊ |
1067 | ␉␉␉␉␉int j;␊ |
1068 | ␉␉␉␉␉␊ |
1069 | ␉␉␉␉␉for (j=0; j<ssdt_count; j++)␊ |
1070 | ␉␉␉␉␉␉xsdt_entries[i-dropoffset+j]=(uint32_t)new_ssdt[j];␊ |
1071 | ␉␉␉␉␉␉␊ |
1072 | ␉␉␉␉␉verbose("Added %d SSDT table(s) into XSDT\n", ssdt_count);␊ |
1073 | ␉␉␉␉}␊ |
1074 | ␊ |
1075 | ␉␉␉␉// Correct the checksum of XSDT␊ |
1076 | ␉␉␉␉xsdt_mod->Checksum=0;␊ |
1077 | ␉␉␉␉xsdt_mod->Checksum=256-checksum8(xsdt_mod,xsdt_mod->Length);␊ |
1078 | ␉␉␉}␊ |
1079 | ␉␉␉else␊ |
1080 | ␉␉␉{␊ |
1081 | ␉␉␉drop_xsdt:␊ |
1082 | ␉␉␉␉␊ |
1083 | ␉␉␉␉DBG("About to drop XSDT\n");␊ |
1084 | ␉␉␉␉␊ |
1085 | ␉␉␉␉/*FIXME: Now we just hope that if MacOS doesn't find XSDT it reverts to RSDT. ␊ |
1086 | ␉␉␉␉ * A Better strategy would be to generate␊ |
1087 | ␉␉␉␉ */␊ |
1088 | ␉␉␉␉␊ |
1089 | ␉␉␉␉rsdp_mod->XsdtAddress=0xffffffffffffffffLL;␊ |
1090 | ␉␉␉␉verbose("XSDT not found or XSDT incorrect\n");␊ |
1091 | ␉␉␉}␊ |
1092 | ␉␉}␊ |
1093 | ␉␉␊ |
1094 | ␉␉// Correct the checksum of RSDP ␊ |
1095 | ␉␉␊ |
1096 | ␉␉DBG("RSDP: Original checksum %d, ", rsdp_mod->Checksum);␊ |
1097 | ␉␉␊ |
1098 | ␉␉rsdp_mod->Checksum=0;␊ |
1099 | ␉␉rsdp_mod->Checksum=256-checksum8(rsdp_mod,20);␊ |
1100 | ␉␉␊ |
1101 | ␉␉DBG("New checksum %d\n", rsdp_mod->Checksum);␊ |
1102 | ␉␉␊ |
1103 | ␉␉if (version)␊ |
1104 | ␉␉{␊ |
1105 | ␉␉␉DBG("RSDP: Original extended checksum %d", rsdp_mod->ExtendedChecksum);␊ |
1106 | ␉␉␉␊ |
1107 | ␉␉␉rsdp_mod->ExtendedChecksum=0;␊ |
1108 | ␉␉␉rsdp_mod->ExtendedChecksum=256-checksum8(rsdp_mod,rsdp_mod->Length);␊ |
1109 | ␉␉␉␊ |
1110 | ␉␉␉DBG("New extended checksum %d\n", rsdp_mod->ExtendedChecksum);␊ |
1111 | ␉␉␉␊ |
1112 | ␉␉}␊ |
1113 | ␉␉␊ |
1114 | ␉␉//verbose("Patched ACPI version %d DSDT\n", version+1);␊ |
1115 | ␉␉if (version)␊ |
1116 | ␉␉{␊ |
1117 | ␉␉␉/* XXX aserebln why uint32 cast if pointer is uint64 ? */␊ |
1118 | ␉␉␉acpi20_p = (uint32_t)rsdp_mod;␊ |
1119 | ␉␉␉addConfigurationTable(&gEfiAcpi20TableGuid, &acpi20_p, "ACPI_20");␊ |
1120 | ␉␉}␊ |
1121 | ␉␉else␊ |
1122 | ␉␉{␊ |
1123 | ␉␉␉/* XXX aserebln why uint32 cast if pointer is uint64 ? */␊ |
1124 | ␉␉␉acpi10_p = (uint32_t)rsdp_mod;␊ |
1125 | ␉␉␉addConfigurationTable(&gEfiAcpiTableGuid, &acpi10_p, "ACPI");␊ |
1126 | ␉␉}␊ |
1127 | ␉}␊ |
1128 | #if DEBUG_ACPI␊ |
1129 | ␉printf("Press a key to continue... (DEBUG_ACPI)\n");␊ |
1130 | ␉getchar();␊ |
1131 | #endif␊ |
1132 | ␉return 1;␊ |
1133 | }␊ |
1134 |