Chameleon

Chameleon Commit Details

Date:2010-07-23 18:38:49 (8 years 11 months ago)
Author:mozo
Commit:207
Parents: 206
Message:Latest Chameleon changes. Now using aml_generator for dynamic SSDT generation, should be easier to add changes in the future.
Changes:
M/branches/mozodojo/i386/libsaio/aml_generator.c
M/branches/mozodojo/i386/libsaio/acpi_patcher.c
M/branches/mozodojo/Chameleon.xcodeproj/project.pbxproj
M/branches/mozodojo/i386/libsaio/aml_generator.h
M/branches/mozodojo/i386/libsaio/cpu.c

File differences

branches/mozodojo/Chameleon.xcodeproj/project.pbxproj
166166
167167
168168
169
170169
171170
172171
......
308307
309308
310309
311
312310
313311
314312
B0056D7B11F3868000754B65 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
B0056D7C11F3868000754B65 /* TODO */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = TODO; sourceTree = "<group>"; };
B0056D7D11F3868000754B65 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
B0056D7E11F3868000754B65 /* efisysinst.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = efisysinst.sh; sourceTree = "<group>"; };
B0056D7F11F3868000754B65 /* CREDITS */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CREDITS; sourceTree = "<group>"; };
B0056D8011F3868000754B65 /* coding_standards.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = coding_standards.txt; sourceTree = "<group>"; };
B0056D8111F3868000754B65 /* CHANGES */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CHANGES; sourceTree = "<group>"; };
B0056CD411F3868000754B65 /* sym */,
B0056D7C11F3868000754B65 /* TODO */,
B0056D7D11F3868000754B65 /* Makefile */,
B0056D7E11F3868000754B65 /* efisysinst.sh */,
B0056D7F11F3868000754B65 /* CREDITS */,
B0056D8011F3868000754B65 /* coding_standards.txt */,
B0056D8111F3868000754B65 /* CHANGES */,
branches/mozodojo/i386/libsaio/acpi_patcher.c
189189
190190
191191
192
192
193193
194194
195195
......
212212
213213
214214
215
215
216216
217
217
218218
219
219220
220221
221222
......
236237
237238
238239
239
240
240241
241
242
242
243
244
243245
246
247
248
249
250
244251
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276252
277253
278254
......
286262
287263
288264
289
265
290266
291
292
267
268
269
270
271
272
293273
294
295
296
274
275
276
277
278
279
297280
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
281
282
283
284
285
286
329287
330
331
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
332319
333
334
335
336
337
338
339
340
341
342
343
344
345320
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
321
361322
362
363
323
324
325
326
364327
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
328
385329
386330
387331
388
332
389333
390334
391335
392336
393337
394
338
339
395340
396341
397342
......
409354
410355
411356
412
413
414
415
416
417
418
419
420
421
422
423
424
425357
426358
427359
......
433365
434366
435367
436
368
437369
438370
439371
......
442374
443375
444376
445
446
447
448377
449378
450379
......
455384
456385
457386
387
458388
459389
390
460391
461392
462393
......
569500
570501
571502
572
503
573504
574
505
506
507
508
509
575510
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
511
512
513
514
515
516
517
518
519
520
521
522
523
524
591525
592
593
526
527
528
529
530
594531
595
596
597
598
599
600532
601
602
603
604
605
606
607
608
609
610
611
612
533
613534
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
535
629536
630
631
632
633
634
635
636
537
538
637539
638
540
639541
640542
641543
642
544
545
643546
644547
645548
......
781684
782685
783686
687
688
689
690
784691
785692
786693
uint8_tacpi_cpu_count = 0;
char* acpi_cpu_name[32];
void find_acpi_cpu_names(unsigned char* dsdt, int length)
void get_acpi_cpu_names(unsigned char* dsdt, int length)
{
int i;
}
}
if (add_name && dsdt[offset+5] < 32 )
if (add_name && dsdt[offset+4] < 32 )
{
acpi_cpu_name[acpi_cpu_count] = malloc(5);
acpi_cpu_name[acpi_cpu_count] = malloc(4);
memcpy(acpi_cpu_name[acpi_cpu_count], dsdt+offset, 4);
i = offset + 5;
verbose("Found %c%c%c%c (from DSDT)\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]);
0x31, 0x03, 0x10, 0x20 /* 1.._*/
};
char chunk_name_body[] =
char cstate_resource_template[] =
{
0x5C, 0x5F, 0x50, 0x52, 0x5F, 0x08, 0x43, 0x53, /* \_PR_.CS */
0x54, 0x5F/* T_*/
0x11, 0x14, 0x0A, 0x11, 0x82, 0x0C, 0x00, 0x7F,
0x01, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x79, 0x00
};
if (Platform.CPU.Vendor != 0x756E6547) {
verbose ("Not an Intel platform: C-States will not be generated !!!\n");
return NULL;
}
char chunk_c1[] =
{
0x12, 0x1C, 0x04, 0x11, 0x14, 0x0A, 0x11, 0x82,
0x0C, 0x00, 0x7F, 0x01, 0x02, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0x00,
0x01, 0x01, 0x0B, 0xE8, 0x03
};
char chunk_c2[] =
{
0x12, 0x1E, 0x04, 0x11, 0x14, 0x0A, 0x11, 0x82,
0x0C, 0x00, 0x7F, 0x01, 0x02, 0x01, 0x10, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0x00,
0x0A, 0x02, 0x0A, 0x40, 0x0B, 0xF4, 0x01
};
char chunk_c3[] =
{
0x12, 0x1F, 0x04, 0x11, 0x14, 0x0A, 0x11, 0x82,
0x0C, 0x00, 0x7F, 0x01, 0x02, 0x01, 0x20, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0x00,
0x0A, 0x03, 0x0B, 0x60, 0x03, 0x0B, 0x5E, 0x01
};
char chunk_alias[] =
{
0x10, 0x14, 0x5C, 0x2E, 0x5F, 0x50, 0x52, 0x5F, /* ..\._PR_ */
0x43, 0x50, 0x55, 0x30, 0x06, 0x43, 0x53, 0x54, /* CPU0.CST */
0x5F, 0x5F, 0x43, 0x53, 0x54/* __CST*/
};
if (fadt == NULL) {
verbose ("FACP not exists: C-States not generated !!!\n");
return NULL;
}
if (acpi_cpu_count == 0)
find_acpi_cpu_names((void*)dsdt, dsdt->Length);
get_acpi_cpu_names((void*)dsdt, dsdt->Length);
if (acpi_cpu_count > 0) {
bool c2_enabled = fadt->C2_Latency < 100, c3_enabled = fadt->C3_Latency < 1000;
if (acpi_cpu_count > 0)
{
bool c2_enabled = fadt->C2_Latency < 100;
bool c3_enabled = fadt->C3_Latency < 1000;
unsigned char cstates_count = 1 + (c2_enabled ? 1 : 0) + (c3_enabled ? 1 : 0);
// Setup C2 Latency
if (c2_enabled)
chunk_c2[27] = fadt->C2_Latency & 0xff;
struct aml_chunk* root = aml_create_node(NULL);
aml_add_buffer(root, ssdt_header, sizeof(ssdt_header)); // SSDT header
struct aml_chunk* scop = aml_add_scope(root, "\\_PR_");
struct aml_chunk* name = aml_add_name(scop, "CST_");
struct aml_chunk* pack = aml_add_package(name);
aml_add_byte(pack, cstates_count);
// Setup C3 Latency
if (c3_enabled) {
chunk_c3[27] = fadt->C3_Latency & 0xff;
chunk_c3[28] = (fadt->C3_Latency >> 8) & 0xff;
}
// Generating SSDT
uint32_t package_length =
4 +
sizeof(chunk_c1) +
c2_enabled * sizeof(chunk_c2) +
c3_enabled * sizeof(chunk_c3);
if (package_length > 0x3f)
package_length++;
uint32_t name_length =
1 +
sizeof(chunk_name_body) +
1 + package_length;
if (name_length > 0x3f)
name_length++;
uint32_t ssdt_size =
sizeof(ssdt_header) +
1 + name_length +
acpi_cpu_count * sizeof(chunk_alias);
struct acpi_2_ssdt *ssdt = (void*)AllocateKernelMemory(ssdt_size);
int fd = openmem((char*)ssdt, ssdt_size);
struct aml_chunk* tmpl = aml_add_package(pack);
cstate_resource_template[11] = 0x10; // C1
aml_add_buffer(tmpl, cstate_resource_template, sizeof(cstate_resource_template));
aml_add_byte(tmpl, 0x01); // C1
aml_add_byte(tmpl, 0x01); // Latency
aml_add_word(tmpl, 0x03e8); // Power
// Header
write(fd, ssdt_header, sizeof(ssdt_header));
// C2
if (c2_enabled)
{
tmpl = aml_add_package(pack);
cstate_resource_template[11] = 0x20; // C2
aml_add_buffer(tmpl, cstate_resource_template, sizeof(cstate_resource_template));
aml_add_byte(tmpl, 0x02); // C2
aml_add_byte(tmpl, fadt->C2_Latency);
aml_add_word(tmpl, 0x01f4); // Power
}
// C3
if (c3_enabled)
{
tmpl = aml_add_package(pack);
cstate_resource_template[11] = 0x30; // C3
aml_add_buffer(tmpl, cstate_resource_template, sizeof(cstate_resource_template));
aml_add_byte(tmpl, 0x03); // C3
aml_add_word(tmpl, fadt->C3_Latency);
aml_add_word(tmpl, 0x015e); // Power
}
// Aliaces
int i;
for (i = 0; i < acpi_cpu_count; i++)
{
char name[9];
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]);
scop = aml_add_scope(root, name);
aml_add_alias(scop, "CST_", "_CST");
}
// Scope (\_PR) { Name (CST
writebyte(fd, 0x10); // id
if (name_length > 0x3f)
{
writebyte(fd, 0x40 | (name_length & 0xf)); // lo half-byte
writebyte(fd, name_length >> 4); // hi byte
}
else
{
writebyte(fd, name_length); // length
}
write(fd, chunk_name_body, sizeof(chunk_name_body));
//Package (0x04) { 0x03,
writebyte(fd, 0x12); // id
if (package_length > 0x3f)
{
writebyte(fd, 0x40 | (package_length & 0xf)); // lo half-byte
writebyte(fd, package_length >> 4); // hi byte
}
else
{
writebyte(fd, package_length); // length
}
uint8_t cstates_count = 1 + c2_enabled + c3_enabled;
writebyte(fd, cstates_count + 1);
writebyte(fd, 0x0A); // first entry - number of c-states
writebyte(fd, cstates_count);
aml_calculate_size(root);
// C1
write(fd, chunk_c1, sizeof(chunk_c1));
struct acpi_2_ssdt *ssdt = (struct acpi_2_ssdt *)AllocateKernelMemory(root->Size);
aml_write_node(root, (void*)ssdt, 0);
aml_destroy_node(root);
// C2
if (c2_enabled)
write(fd, chunk_c2, sizeof(chunk_c2));
// C3
if (c3_enabled)
write(fd, chunk_c3, sizeof(chunk_c3));
// Write aliases
int i;
for (i = 0; i < acpi_cpu_count; i++) {
int j;
for (j = 0; j < 4; j++)
chunk_alias[8+j] = acpi_cpu_name[i][j];
write(fd, chunk_alias, sizeof(chunk_alias));
}
close(fd);
ssdt->Length = ssdt_size;
ssdt->Length = root->Size;
ssdt->Checksum = 0;
ssdt->Checksum = 256 - checksum8(ssdt, ssdt->Length);
//dumpPhysAddr("C-States SSDT content: ", ssdt, ssdt_size);
//dumpPhysAddr("C-States SSDT content: ", ssdt, ssdt->Length);
verbose ("SSDT with CPU C-States generated successfully\n");
return ssdt;
}
else {
else
{
verbose ("DSDT CPUs not found: C-States not generated !!!\n");
}
0x31, 0x03, 0x10, 0x20,/* 1.._*/
};
char chunk_name_body[] =
{
0x5C, 0x5F, 0x50, 0x52, 0x5F, 0x08, 0x50, 0x53, /* \_PR_.PS */
0x53, 0x5F/* S_*/
};
char chunk_alias[] =
{
0x10, 0x14, 0x5C, 0x2E, 0x5F, 0x50, 0x52, 0x5F, /* ..\._PR_ */
0x43, 0x50, 0x55, 0x30, 0x06, 0x50, 0x53, 0x53, /* CPU0.PSS */
0x5F, 0x5F, 0x50, 0x53, 0x53/* __PSS*/
};
if (Platform.CPU.Vendor != 0x756E6547) {
verbose ("Not an Intel platform: P-States will not be generated !!!\n");
return NULL;
}
if (acpi_cpu_count == 0)
find_acpi_cpu_names((void*)dsdt, dsdt->Length);
get_acpi_cpu_names((void*)dsdt, dsdt->Length);
if (acpi_cpu_count > 0)
{
uint8_t p_states_count;
// Retrieving P-States, ported from code by superhai (c)
switch (Platform.CPU.Family) {
case 0x06:
{
case 0x1C: // Intel Atom (45nm)
case 0x1A: // Intel Core i7 LGA1366 (45nm)
case 0x1E: // Intel Core i5, i7 LGA1156 (45nm)
case 0x1F:
case 0x25: // Intel Core i3, i5, i7 LGA1156 (32nm)
case 0x2C: // Intel Core i7 LGA1366 (32nm) 6 Core
case 0x2F:
if (rdmsr64(MSR_IA32_EXT_CONFIG) & (1 << 27))
{
wrmsr64(MSR_IA32_EXT_CONFIG, (rdmsr64(MSR_IA32_EXT_CONFIG) | (1 << 28)));
if (p_states_count > 0)
{
uint32_t i, pss_entries_size = 33 * p_states_count, pss_package_length = pss_entries_size + 2;
int i;
if (pss_package_length > 0x3f) pss_package_length++; // for chunks > 0x3f bytes length have 2 bytes encoding
struct aml_chunk* root = aml_create_node(NULL);
aml_add_buffer(root, ssdt_header, sizeof(ssdt_header)); // SSDT header
struct aml_chunk* scop = aml_add_scope(root, "\\_PR_");
struct aml_chunk* name = aml_add_name(scop, "PSS_");
struct aml_chunk* pack = aml_add_package(name);
uint32_t pss_name_length = (1 /* id=0x12 */ + pss_package_length) + (1 + 10);
if (pss_name_length > 0x3f) pss_name_length++;
uint32_t ssdt_size = 36 + (1 /* id=0x10 */ + pss_name_length) + acpi_cpu_count * sizeof(chunk_alias);
struct acpi_2_ssdt *ssdt = (void*)AllocateKernelMemory(ssdt_size);
int fd = openmem((char*)ssdt, ssdt_size);
// write header
write(fd, ssdt_header, sizeof(ssdt_header));
// write Scope (\_PR) {Name (PSS, ...
writebyte(fd, 0x10); // id
if (pss_name_length > 0x3f)
for (i = 0; i < p_states_count; i++)
{
struct aml_chunk* pstt = aml_add_package(pack);
aml_add_dword(pstt, p_states[i].Frequency);
aml_add_dword(pstt, 0x00000000); // Power
aml_add_dword(pstt, 0x0000000A); // Latency
aml_add_dword(pstt, 0x0000000A); // Latency
aml_add_dword(pstt, p_states[i].Control);
aml_add_dword(pstt, i+1); // Status
}
// Add aliaces
for (i = 0; i < acpi_cpu_count; i++)
{
writebyte(fd, 0x40 | (pss_name_length & 0xf)); // lo half-byte
writebyte(fd, pss_name_length >> 4); // hi byte
char name[9];
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]);
scop = aml_add_scope(root, name);
aml_add_alias(scop, "PSS_", "_PSS");
}
else
{
writebyte(fd, pss_name_length); // length
}
write(fd, chunk_name_body, sizeof(chunk_name_body));
// write Package(p_states_count) { ...
writebyte(fd, 0x12); // id
if (pss_package_length > 0x3f)
{
writebyte(fd, 0x40 | (pss_package_length & 0xf)); // lo half-byte
writebyte(fd, pss_package_length >> 4); // hi byte
}
else
{
writebyte(fd, pss_package_length); // length
}
writebyte(fd, p_states_count); // entries
aml_calculate_size(root);
for (i = 0; i < p_states_count; i++)
{
DBG("P-State: Frequency %d MHz, FID 0x%x, VID 0x%x\n", p_states[i].Frequency, p_states[i].FID, p_states[i].VID);
writebyte(fd, 0x12); // chunk id
writebyte(fd, 32); // chunk length without id
writebyte(fd, 6); // entries
writebyte(fd, 0x0C); /* id */ writeint(fd, p_states[i].Frequency); // value
writebyte(fd, 0x0C); /* id */ writeint(fd, 0x00000000); // value
writebyte(fd, 0x0C); /* id */ writeint(fd, 0x0000000A); // value
writebyte(fd, 0x0C); /* id */ writeint(fd, 0x0000000A); // value
writebyte(fd, 0x0C); /* id */ writeint(fd, p_states[i].Control); // value
writebyte(fd, 0x0C); /* id */ writeint(fd, i + 1); // value
}
struct acpi_2_ssdt *ssdt = (struct acpi_2_ssdt *)AllocateKernelMemory(root->Size);
// Write aliases
for (i = 0; i < acpi_cpu_count; i++) {
int j;
for (j = 0; j < 4; j++)
chunk_alias[8+j] = acpi_cpu_name[i][j];
write(fd, chunk_alias, sizeof(chunk_alias));
}
aml_write_node(root, (void*)ssdt, 0);
aml_destroy_node(root);
ssdt->Length = ssdt_size;
ssdt->Length = root->Size;
ssdt->Checksum = 0;
ssdt->Checksum = 256 - checksum8(ssdt, ssdt->Length);
//dumpPhysAddr("P-States SSDT content: ", ssdt, ssdt_size);
//dumpPhysAddr("P-States SSDT content: ", ssdt, ssdt->Length);
verbose ("SSDT with CPU P-States generated successfully\n");
return ssdt;
struct acpi_2_ssdt *new_ssdt[32]; // 30 + 2 additional tables for pss & cst
int ssdt_count=0;
// TEST!
/*if(new_ssdt[ssdt_count] = generate_test_ssdt())
ssdt_count++;*/
// SSDT Options
bool drop_ssdt=false, generate_pstates=false, generate_cstates=false;
branches/mozodojo/i386/libsaio/aml_generator.c
99
1010
1111
12
12
1313
14
15
16
17
18
19
20
21
22
23
2414
2515
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
2638
2739
2840
......
3042
3143
3244
45
46
3347
48
49
3450
3551
3652
3753
38
54
3955
4056
4157
4258
4359
4460
45
61
4662
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
4787
4888
4989
......
5191
5292
5393
54
55
56
94
5795
5896
59
97
6098
6199
62
100
63101
64102
65103
66104
67105
68106
107
69108
70109
71
72
73
74
75
76
77
78
79
110
80111
81112
82
113
83114
84115
85
116
86117
87118
88119
......
93124
94125
95126
96
97
98127
99128
100
129
101130
102131
103
132
104133
105134
106135
......
113142
114143
115144
116
117
118145
119146
120
147
121148
122149
123
150
124151
125152
126153
......
137164
138165
139166
140
141
142167
143168
144
169
145170
146171
147
172
148173
149
150
151
174
152175
153
154
155
156
157
158
159
160
176
177
161178
162179
180
163181
164182
165183
166
184
167185
168186
169
187
170188
171
189
172190
173
191
174192
175
176
177
178
179
180
181
182
183
193
194
184195
185196
186
187
197
188198
189
190
199
200
201
191202
192203
193
204
194205
195
206
196207
197208
198209
......
200211
201212
202213
203
214
204215
216
217
205218
206
207
208
209
210
211
212
213219
214
220
221
222
223
224
225
215226
216
227
228
229
230
231
232
233
234
217235
218
236
219237
220
221
222
223
224
225
226
227
228
229
230
231
238
232239
233240
234
241
235242
236243
237
244
238245
239246
240247
......
243250
244251
245252
253
254
255
256
257
258
259
260
261
262
263
264
246265
247
266
267
248268
249269
250
270
251271
252272
253
273
254274
255275
256276
257277
258278
259
279
260280
261
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
262307
263
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
264358
265359
266
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
267498
#include "aml_generator.h"
unsigned char aml_get_length_size(long length)
bool aml_add_to_parent(struct aml_chunk* parent, struct aml_chunk* node)
{
if (length > 0x3F)
return 2;
else if (length > 0x3FFF)
return 3;
return 1;
}
void aml_add_to_parent(struct aml_chunk* parent, struct aml_chunk* node)
{
if (parent && node)
{
switch (parent->Type)
{
case AML_CHUNK_NONE:
case AML_CHUNK_BYTE:
case AML_CHUNK_WORD:
case AML_CHUNK_DWORD:
case AML_CHUNK_QWORD:
case AML_CHUNK_ALIAS:
verbose("aml_add_to_parent: Node isn't supports child nodes!");
return FALSE;
case AML_CHUNK_NAME:
if (parent->First)
{
verbose("aml_add_to_parent: Name node could have only one child node!");
return FALSE;
}
break;
default:
break;
}
if (!parent->First)
parent->First = node;
parent->Last->Next = node;
parent->Last = node;
return TRUE;
}
return FALSE;
}
struct aml_chunk* aml_create_node(struct aml_chunk* parent)
{
struct aml_chunk* node = (void*)malloc(sizeof(struct aml_chunk));
struct aml_chunk* node = (struct aml_chunk*)malloc(sizeof(struct aml_chunk));
aml_add_to_parent(parent, node);
return node;
}
int aml_add_buffer(struct aml_chunk* parent, const char* buffer, unsigned int size)
void aml_destroy_node(struct aml_chunk* node)
{
// Delete child nodes
struct aml_chunk* child = node->First;
while (child)
{
struct aml_chunk* next = child->Next;
if (child->Buffer)
free(child->Buffer);
free(child);
child = next;
}
// Free node
if (node->Buffer)
free(node->Buffer);
free(node);
}
struct aml_chunk* aml_add_buffer(struct aml_chunk* parent, const char* buffer, unsigned int size)
{
struct aml_chunk* node = aml_create_node(parent);
if (node)
node->Type = AML_CHUNK_NONE;
node->Length = size;
node->Buffer = malloc(node->Length);
memcpy(node->Buffer, buffer, size);
return node->Length;
memcpy(node->Buffer, buffer, node->Length);
}
return -1;
return node;
}
int aml_add_byte(struct aml_chunk* parent, unsigned char value)
struct aml_chunk* aml_add_byte(struct aml_chunk* parent, unsigned char value)
{
struct aml_chunk* node = aml_create_node(parent);
if (node)
{
node->Type = AML_CHUNK_BYTE;
node->Length = 1;
node->Buffer = malloc(node->Length);
if (value == 0)
node->Buffer[0] = 0x00;
else if (value == 1)
node->Buffer[0] = 0x01;
else
node->Buffer[0] = value;
return node->Length;
node->Buffer[0] = value;
}
return -1;
return node;
}
int aml_add_word(struct aml_chunk* parent, unsigned int value)
struct aml_chunk* aml_add_word(struct aml_chunk* parent, unsigned int value)
{
struct aml_chunk* node = aml_create_node(parent);
node->Buffer = malloc(node->Length);
node->Buffer[0] = value & 0xff;
node->Buffer[1] = value >> 8;
return node->Length;
}
return -1;
return node;
}
int aml_add_dword(struct aml_chunk* parent, unsigned long value)
struct aml_chunk* aml_add_dword(struct aml_chunk* parent, unsigned long value)
{
struct aml_chunk* node = aml_create_node(parent);
node->Buffer[1] = (value >> 8) & 0xff;
node->Buffer[2] = (value >> 16) & 0xff;
node->Buffer[3] = (value >> 24) & 0xff;
return node->Length;
}
return -1;
return node;
}
int aml_add_qword(struct aml_chunk* parent, unsigned long long value)
struct aml_chunk* aml_add_qword(struct aml_chunk* parent, unsigned long long value)
{
struct aml_chunk* node = aml_create_node(parent);
node->Buffer[5] = (value >> 40) & 0xff;
node->Buffer[6] = (value >> 48) & 0xff;
node->Buffer[7] = (value >> 56) & 0xff;
return node->Length;
}
return -1;
return node;
}
int aml_fill_simple_name(char* buffer, const char* name)
unsigned int aml_fill_simple_name(char* buffer, const char* name)
{
int i, len = strlen(name), count = 0;
for (i = 0; i < 4; i++)
if (strlen(name) < 4)
{
if (i < len && aml_isvalidchar(name[i]))
{
buffer[count++] = name[i];
}
else
{
buffer[3-i] = '_';
}
verbose("aml_fill_simple_name: simple name %s has incorrect lengh! Must be 4", name);
return 0;
}
memcpy(buffer, name, 4);
return 4;
}
int aml_fill_name(struct aml_chunk* node, const char* name)
unsigned int aml_fill_name(struct aml_chunk* node, const char* name)
{
if (!node)
return -1;
return 0;
int i, len = strlen(name), count = 0;
int len = strlen(name), offset = 0, count = len / 4;
for (i = 0; i < len; i++)
if ((len % 4) > 1 || count == 0)
{
if (name[i] == '.')
{
count++;
}
else if (!aml_isvalidchar(name[i]))
{
len = i;
break;
}
verbose("aml_fill_name: pathname %s has incorrect length! Must be 4, 8, 12, 16 etc.", name);
return 0;
}
if (count == 0 && len > 0)
count++;
unsigned int root = 0;
int offset = 0;
if ((len % 4) == 1 && name[0] == '\\')
root++;
if (count == 1)
{
node->Length = 4;
node->Length = 4 + root;
node->Buffer = malloc(node->Length);
aml_fill_simple_name(node->Buffer, name);
memcpy(node->Buffer, name, 4 + root);
return node->Length;
}
{
node->Length = 2 + 8;
node->Buffer = malloc(node->Length);
node->Buffer[offset++] = '\\'; // Root
node->Buffer[offset++] = 0x5c; // Root Char
node->Buffer[offset++] = 0x2e; // Double name
memcpy(node->Buffer+offset, name + root, 8);
return node->Length;
}
else
{
node->Length = 3 + count*4;
node->Buffer[offset++] = '\\'; // Root
node->Buffer[offset++] = 0x2f; // Multi name
node->Buffer[offset++] = count; // Names count
}
int j = 0;
node->Length = 3 + count*4;
node->Buffer = malloc(node->Length);
node->Buffer[offset++] = 0x5c; // Root Char
node->Buffer[offset++] = 0x2f; // Multi name
node->Buffer[offset++] = count; // Names count
memcpy(node->Buffer+offset, name + root, count*4);
for (i = 0; i < count; i++)
return node->Length;
}
struct aml_chunk* aml_add_scope(struct aml_chunk* parent, const char* name)
{
struct aml_chunk* node = aml_create_node(parent);
if (node)
{
offset += aml_fill_simple_name(node->Buffer + offset, name + j);
node->Type = AML_CHUNK_SCOPE;
while (name[j] != '.')
{
if (j < len)
{
j++;
}
else
{
verbose("aml_fill_name: unexpected end of names path!");
return -1;
}
}
aml_fill_name(node, name);
}
return offset;
return node;
}
int aml_add_name(struct aml_chunk* parent, const char* name, int count, ...)
struct aml_chunk* aml_add_name(struct aml_chunk* parent, const char* name)
{
struct aml_chunk* node = aml_create_node(parent);
node->Type = AML_CHUNK_NAME;
aml_fill_name(node, name);
}
return node;
}
struct aml_chunk* aml_add_package(struct aml_chunk* parent)
{
struct aml_chunk* node = aml_create_node(parent);
if (node)
{
node->Type = AML_CHUNK_PACKAGE;
return node->Length;
node->Length = 1;
node->Buffer = malloc(node->Length);
}
return -1;
return node;
}
int aml_add_scope(struct aml_chunk* parent, const char* name)
struct aml_chunk* aml_add_alias(struct aml_chunk* parent, const char* name1, const char* name2)
{
struct aml_chunk* node = aml_create_node(parent);
if (node)
{
node->Type = AML_CHUNK_SCOPE;
node->Type = AML_CHUNK_ALIAS;
aml_fill_name(node, name);
node->Length = 8;
node->Buffer = malloc(node->Length);
aml_fill_simple_name(node->Buffer, name1);
aml_fill_simple_name(node->Buffer+4, name2);
}
return node;
}
unsigned char aml_get_size_length(unsigned int size)
{
if (size + 1 <= 0x3f)
return 1;
else if (size + 2 <= 0x3fff)
return 2;
else if (size + 3 <= 0x3fffff)
return 3;
return 4;
}
unsigned int aml_calculate_size(struct aml_chunk* node)
{
if (node)
{
node->Size = 0;
return node->Length;
// Calculate child nodes size
struct aml_chunk* child = node->First;
unsigned char child_count = 0;
while (child)
{
child_count++;
node->Size += aml_calculate_size(child);
child = child->Next;
}
switch (node->Type)
{
case AML_CHUNK_NONE:
node->Size += node->Length;
break;
case AML_CHUNK_SCOPE:
node->Size += 1 + node->Length;
node->Size += aml_get_size_length(node->Size);
break;
case AML_CHUNK_PACKAGE:
node->Buffer[0] = child_count;
node->Size += 1 + node->Length;
node->Size += aml_get_size_length(node->Size);
break;
case AML_CHUNK_BYTE:
if (node->Buffer[0] == 0x0 || node->Buffer[0] == 0x1)
{
node->Size += node->Length;
}
else
{
node->Size += 1 + node->Length;
}
break;
case AML_CHUNK_WORD:
case AML_CHUNK_DWORD:
case AML_CHUNK_QWORD:
case AML_CHUNK_ALIAS:
case AML_CHUNK_NAME:
node->Size += 1 + node->Length;
break;
}
return node->Size;
}
return -1;
return 0;
}
unsigned int aml_write_byte(unsigned char value, char* buffer, unsigned int offset)
{
buffer[offset++] = value;
return offset;
}
unsigned int aml_write_word(unsigned int value, char* buffer, unsigned int offset)
{
buffer[offset++] = value & 0xff;
buffer[offset++] = value >> 8;
return offset;
}
unsigned int aml_write_dword(unsigned long value, char* buffer, unsigned int offset)
{
buffer[offset++] = value & 0xff;
buffer[offset++] = (value >> 8) & 0xff;
buffer[offset++] = (value >> 16) & 0xff;
buffer[offset++] = (value >> 24) & 0xff;
return offset;
}
unsigned int aml_write_qword(unsigned long long value, char* buffer, unsigned int offset)
{
buffer[offset++] = value & 0xff;
buffer[offset++] = (value >> 8) & 0xff;
buffer[offset++] = (value >> 16) & 0xff;
buffer[offset++] = (value >> 24) & 0xff;
buffer[offset++] = (value >> 32) & 0xff;
buffer[offset++] = (value >> 40) & 0xff;
buffer[offset++] = (value >> 48) & 0xff;
buffer[offset++] = (value >> 56) & 0xff;
return offset;
}
unsigned int aml_write_buffer(const char* value, unsigned int size, char* buffer, unsigned int offset)
{
if (size > 0)
{
memcpy(buffer + offset, value, size);
}
return offset + size;
}
unsigned int aml_write_size(unsigned int size, char* buffer, unsigned int offset)
{
if (size <= 0x3f)
{
buffer[offset++] = size;
}
else if (size <= 0x3fff)
{
buffer[offset++] = 0x40 | (size & 0xf);
buffer[offset++] = (size >> 4) & 0xff;
}
else if (size <= 0x3fffff)
{
buffer[offset++] = 0x80 | (size & 0xf);
buffer[offset++] = (size >> 4) & 0xff;
buffer[offset++] = (size >> 12) & 0xff;
}
else
{
buffer[offset++] = 0xc0 | (size & 0xf);
buffer[offset++] = (size >> 4) & 0xff;
buffer[offset++] = (size >> 12) & 0xff;
buffer[offset++] = (size >> 20) & 0xff;
}
return offset;
}
unsigned int aml_write_node(struct aml_chunk* node, char* buffer, unsigned int offset)
{
if (node && buffer)
{
unsigned int old = offset;
switch (node->Type)
{
case AML_CHUNK_NONE:
offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset);
break;
case AML_CHUNK_SCOPE:
case AML_CHUNK_PACKAGE:
offset = aml_write_byte(node->Type, buffer, offset);
offset = aml_write_size(node->Size-1, buffer, offset);
offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset);
break;
case AML_CHUNK_BYTE:
if (node->Buffer[0] == 0x0 || node->Buffer[0] == 0x1)
{
offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset);
}
else
{
offset = aml_write_byte(node->Type, buffer, offset);
offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset);
}
break;
case AML_CHUNK_WORD:
case AML_CHUNK_DWORD:
case AML_CHUNK_QWORD:
case AML_CHUNK_ALIAS:
case AML_CHUNK_NAME:
offset = aml_write_byte(node->Type, buffer, offset);
offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset);
break;
default:
break;
}
struct aml_chunk* child = node->First;
while (child)
{
offset = aml_write_node(child, buffer, offset);
child = child->Next;
}
if (offset - old != node->Size)
verbose("Node size incorrect: 0x%x\n", node->Type);
}
return offset;
}
branches/mozodojo/i386/libsaio/aml_generator.h
1212
1313
1414
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
15
16
17
18
19
20
21
22
23
24
25
26
3027
3128
3229
33
34
30
31
3532
33
34
35
3636
3737
3838
......
4343
4444
4545
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
4661
#include "libsaio.h"
enum aml_chunk_type
{
AML_CHUNK_NONE= -1,
AML_CHUNK_ZERO= 0x00,
AML_CHUNK_ONE= 0x01,
AML_CHUNK_ALIAS= 0x06,
AML_CHUNK_NAME= 0x08,
AML_CHUNK_BYTE= 0x0A,
AML_CHUNK_WORD= 0x0B,
AML_CHUNK_DWORD= 0x0C,
AML_CHUNK_STRING= 0x0D,
AML_CHUNK_QWORD= 0x0E,
AML_CHUNK_SCOPE= 0x10,
AML_CHUNK_PACKAGE= 0x12,
};
#defineAML_CHUNK_NONE0xff
#defineAML_CHUNK_ZERO0x00
#defineAML_CHUNK_ONE0x01
#defineAML_CHUNK_ALIAS0x06
#defineAML_CHUNK_NAME0x08
#defineAML_CHUNK_BYTE0x0A
#defineAML_CHUNK_WORD0x0B
#defineAML_CHUNK_DWORD0x0C
#defineAML_CHUNK_STRING0x0D
#defineAML_CHUNK_QWORD0x0E
#defineAML_CHUNK_SCOPE0x10
#defineAML_CHUNK_PACKAGE0x12
struct aml_chunk
{
enum aml_chunk_typeType;
unsigned longLength;
unsigned charType;
unsigned intLength;
char*Buffer;
unsigned intSize;
struct aml_chunk*Next;
struct aml_chunk*First;
struct aml_chunk*Last;
return isupper(c) || isdigit(c) || c == '_';
};
bool aml_add_to_parent(struct aml_chunk* parent, struct aml_chunk* node);
struct aml_chunk* aml_create_node(struct aml_chunk* parent);
void aml_destroy_node(struct aml_chunk* node);
struct aml_chunk* aml_add_buffer(struct aml_chunk* parent, const char* buffer, unsigned int size);
struct aml_chunk* aml_add_byte(struct aml_chunk* parent, unsigned char value);
struct aml_chunk* aml_add_word(struct aml_chunk* parent, unsigned int value);
struct aml_chunk* aml_add_dword(struct aml_chunk* parent, unsigned long value);
struct aml_chunk* aml_add_qword(struct aml_chunk* parent, unsigned long long value);
struct aml_chunk* aml_add_scope(struct aml_chunk* parent, const char* name);
struct aml_chunk* aml_add_name(struct aml_chunk* parent, const char* name);
struct aml_chunk* aml_add_package(struct aml_chunk* parent);
struct aml_chunk* aml_add_alias(struct aml_chunk* parent, const char* name1, const char* name2);
unsigned int aml_calculate_size(struct aml_chunk* node);
unsigned int aml_write_node(struct aml_chunk* node, char* buffer, unsigned int offset);
#endif /* !__LIBSAIO_AML_GENERATOR_H */
branches/mozodojo/i386/libsaio/cpu.c
166166
167167
168168
169
169
170
170171
171172
172173
if ((p->CPU.Vendor == 0x756E6547 /* Intel */) && ((p->CPU.Family == 0x06) || (p->CPU.Family == 0x0f))) {
if ((p->CPU.Family == 0x06 && p->CPU.Model >= 0x0c) || (p->CPU.Family == 0x0f && p->CPU.Model >= 0x03)) {
/* Nehalem CPU model */
if (p->CPU.Family == 0x06 && (p->CPU.Model == 0x1a || p->CPU.Model == 0x1e)) {
if (p->CPU.Family == 0x06 && (p->CPU.Model == 0x1a || p->CPU.Model == 0x1e
|| p->CPU.Model == 0x1f || p->CPU.Model == 0x25 || p->CPU.Model == 0x2c)) {
msr = rdmsr64(MSR_PLATFORM_INFO);
DBG("msr(%d): platform_info %08x\n", __LINE__, msr & 0xffffffff);
currcoef = (msr >> 8) & 0xff;

Archive Download the corresponding diff file

Revision: 207