Chameleon

Chameleon Svn Source Tree

Root/branches/ErmaC/Enoch_Modules/i386/libsaio/aml_generator.c

1/*
2 * aml_generator.c
3 * Chameleon
4 *
5 * Created by Mozodojo on 20/07/10.
6 * Copyright 2010 mozo. All rights reserved.
7 *
8 */
9
10#include "aml_generator.h"
11
12bool aml_add_to_parent(AML_CHUNK* parent, AML_CHUNK* node)
13{
14if (parent && node)
15{
16switch (parent->Type)
17{
18case AML_CHUNK_NONE:
19case AML_CHUNK_BYTE:
20case AML_CHUNK_WORD:
21case AML_CHUNK_DWORD:
22case AML_CHUNK_QWORD:
23case AML_CHUNK_ALIAS:
24verbose("aml_add_to_parent: Node doesn't support child nodes!\n");
25return false;
26case AML_CHUNK_NAME:
27if (parent->First)
28{
29verbose("aml_add_to_parent: Name node supports only one child node!\n");
30return false;
31}
32break;
33
34default:
35break;
36}
37
38if (!parent->First)
39parent->First = node;
40
41if (parent->Last)
42parent->Last->Next = node;
43
44parent->Last = node;
45
46return true;
47}
48
49return false;
50}
51
52AML_CHUNK* aml_create_node(AML_CHUNK* parent)
53{
54AML_CHUNK* node = (AML_CHUNK*)malloc(sizeof(AML_CHUNK));
55
56aml_add_to_parent(parent, node);
57
58return node;
59}
60
61void aml_destroy_node(AML_CHUNK* node)
62{
63// Delete child nodes
64AML_CHUNK* child = node->First;
65
66while (child)
67{
68AML_CHUNK* next = child->Next;
69
70if (child->Buffer)
71free(child->Buffer);
72
73free(child);
74
75child = next;
76}
77
78// Free node
79if (node->Buffer)
80free(node->Buffer);
81
82free(node);
83}
84
85AML_CHUNK* aml_add_buffer(AML_CHUNK* parent, const char* buffer, uint32_t size)
86{
87AML_CHUNK* node = aml_create_node(parent);
88
89if (node)
90{
91node->Type = AML_CHUNK_NONE;
92node->Length = (uint16_t)size;
93node->Buffer = malloc(node->Length);
94memcpy(node->Buffer, buffer, node->Length);
95}
96
97return node;
98}
99
100AML_CHUNK* aml_add_byte(AML_CHUNK* parent, uint8_t value)
101{
102AML_CHUNK* node = aml_create_node(parent);
103
104if (node)
105{
106node->Type = AML_CHUNK_BYTE;
107
108node->Length = 1;
109node->Buffer = malloc(node->Length);
110node->Buffer[0] = value;
111}
112
113return node;
114}
115
116AML_CHUNK* aml_add_word(AML_CHUNK* parent, uint16_t value)
117{
118AML_CHUNK* node = aml_create_node(parent);
119
120if (node)
121{
122node->Type = AML_CHUNK_WORD;
123node->Length = 2;
124node->Buffer = malloc(node->Length);
125node->Buffer[0] = value & 0xff;
126node->Buffer[1] = value >> 8;
127}
128
129return node;
130}
131
132AML_CHUNK* aml_add_dword(AML_CHUNK* parent, uint32_t value)
133{
134AML_CHUNK* node = aml_create_node(parent);
135
136if (node)
137{
138node->Type = AML_CHUNK_DWORD;
139node->Length = 4;
140node->Buffer = malloc(node->Length);
141node->Buffer[0] = value & 0xff;
142node->Buffer[1] = (value >> 8) & 0xff;
143node->Buffer[2] = (value >> 16) & 0xff;
144node->Buffer[3] = (value >> 24) & 0xff;
145}
146
147return node;
148}
149
150AML_CHUNK* aml_add_qword(AML_CHUNK* parent, uint64_t value)
151{
152AML_CHUNK* node = aml_create_node(parent);
153
154if (node)
155{
156node->Type = AML_CHUNK_QWORD;
157node->Length = 8;
158node->Buffer = malloc(node->Length);
159node->Buffer[0] = value & 0xff;
160node->Buffer[1] = (value >> 8) & 0xff;
161node->Buffer[2] = (value >> 16) & 0xff;
162node->Buffer[3] = (value >> 24) & 0xff;
163node->Buffer[4] = (value >> 32) & 0xff;
164node->Buffer[5] = (value >> 40) & 0xff;
165node->Buffer[6] = (value >> 48) & 0xff;
166node->Buffer[7] = (value >> 56) & 0xff;
167}
168
169return node;
170}
171
172uint32_t aml_fill_simple_name(char* buffer, const char* name)
173{
174if (strlen(name) < 4)
175{
176verbose("aml_fill_simple_name: simple name %s has incorrect lengh! Must be 4.\n", name);
177return 0;
178}
179
180memcpy(buffer, name, 4);
181return 4;
182}
183
184uint32_t aml_fill_name(AML_CHUNK* node, const char* name)
185{
186int len, offset, count;
187uint32_t root = 0;
188
189if (!node)
190{
191return 0;
192}
193
194len = strlen(name);
195offset = 0;
196count = len >> 2;
197
198if ((len % 4) > 1 || count == 0)
199{
200verbose("aml_fill_name: pathname %s has incorrect length! Must be 4, 8, 12, 16, etc...\n", name);
201return 0;
202}
203
204if (((len % 4) == 1) && (name[0] == '\\'))
205root++;
206
207if (count == 1)
208{
209node->Length = (uint16_t)(4 + root);
210node->Buffer = malloc(node->Length+4);
211memcpy(node->Buffer, name, 4 + root);
212offset += 4 + root;
213return (uint32_t)offset;
214}
215
216if (count == 2)
217{
218node->Length = 2 + 8;
219node->Buffer = malloc(node->Length+4);
220node->Buffer[offset++] = 0x5c; // Root Char
221node->Buffer[offset++] = 0x2e; // Double name
222memcpy(node->Buffer+offset, name + root, 8);
223offset += 8;
224return (uint32_t)offset;
225}
226
227node->Length = (uint16_t)(3 + (count << 2));
228node->Buffer = malloc(node->Length+4);
229node->Buffer[offset++] = 0x5c; // Root Char
230node->Buffer[offset++] = 0x2f; // Multi name
231node->Buffer[offset++] = (char)count; // Names count
232memcpy(node->Buffer+offset, name + root, count*4);
233offset += count*4;
234return (uint32_t)offset;
235}
236
237AML_CHUNK* aml_add_scope(AML_CHUNK* parent, const char* name)
238{
239AML_CHUNK* node = aml_create_node(parent);
240
241if (node)
242{
243node->Type = AML_CHUNK_SCOPE;
244
245aml_fill_name(node, name);
246}
247
248return node;
249}
250
251AML_CHUNK* aml_add_name(AML_CHUNK* parent, const char* name)
252{
253AML_CHUNK* node = aml_create_node(parent);
254
255if (node)
256{
257node->Type = AML_CHUNK_NAME;
258
259aml_fill_name(node, name);
260}
261
262return node;
263}
264
265AML_CHUNK* aml_add_method(AML_CHUNK* parent, const char* name, uint8_t args)
266{
267AML_CHUNK* node = aml_create_node(parent);
268
269if (node)
270{
271int offset = aml_fill_name(node, name);
272node->Type = AML_CHUNK_METHOD;
273
274node->Length++;
275node->Buffer[offset] = args;
276}
277
278return node;
279}
280
281AML_CHUNK* aml_add_package(AML_CHUNK* parent)
282{
283AML_CHUNK* node = aml_create_node(parent);
284
285if (node)
286{
287node->Type = AML_CHUNK_PACKAGE;
288
289node->Length = 1;
290node->Buffer = malloc(node->Length);
291}
292
293return node;
294}
295
296AML_CHUNK* aml_add_alias(AML_CHUNK* parent, const char* name1, const char* name2)
297{
298AML_CHUNK* node = aml_create_node(parent);
299
300if (node)
301{
302node->Type = AML_CHUNK_ALIAS;
303
304node->Length = 8;
305node->Buffer = malloc(node->Length);
306aml_fill_simple_name(node->Buffer, name1);
307aml_fill_simple_name(node->Buffer+4, name2);
308}
309
310return node;
311}
312
313AML_CHUNK* aml_add_return_name(AML_CHUNK* parent, const char* name)
314{
315AML_CHUNK* node = aml_create_node(parent);
316
317if (node)
318{
319node->Type = AML_CHUNK_RETURN;
320aml_fill_name(node, name);
321}
322
323return node;
324}
325
326AML_CHUNK* aml_add_return_byte(AML_CHUNK* parent, uint8_t value)
327{
328AML_CHUNK* node = aml_create_node(parent);
329
330if (node)
331{
332node->Type = AML_CHUNK_RETURN;
333aml_add_byte(node, value);
334}
335
336return node;
337}
338
339AML_CHUNK* aml_add_device(AML_CHUNK* parent, const char* name)
340{
341AML_CHUNK* node = aml_create_node(parent);
342
343if (node)
344{
345node->Type = AML_CHUNK_DEVICE;
346aml_fill_name(node, name);
347}
348
349return node;
350}
351
352AML_CHUNK* aml_add_local0(AML_CHUNK* parent)
353{
354AML_CHUNK* node = aml_create_node(parent);
355
356if (node)
357{
358node->Type = AML_CHUNK_LOCAL0;
359node->Length = 1;
360}
361
362return node;
363}
364
365AML_CHUNK* aml_add_store(AML_CHUNK* parent)
366{
367AML_CHUNK* node = aml_create_node(parent);
368
369if (node)
370{
371node->Type = AML_STORE_OP;
372node->Length = 1;
373}
374
375return node;
376}
377
378AML_CHUNK* aml_add_byte_buffer(AML_CHUNK* parent, const char* data, uint32_t size)
379{
380AML_CHUNK* node = aml_create_node(parent);
381
382if (node)
383{
384 int offset = 0;
385node->Type = AML_CHUNK_BUFFER;
386node->Length = (uint8_t)(size + 2);
387node->Buffer = malloc (node->Length);
388node->Buffer[offset++] = AML_CHUNK_BYTE;
389node->Buffer[offset++] = (char)size;
390memcpy(node->Buffer+offset,data, node->Length);
391}
392
393return node;
394}
395
396AML_CHUNK* aml_add_string_buffer(AML_CHUNK* parent, const char* string)
397{
398AML_CHUNK* node = aml_create_node(parent);
399
400if (node)
401{
402 unsigned int offset = 0;
403 unsigned int len = strlen(string);
404node->Type = AML_CHUNK_BUFFER;
405node->Length = (uint8_t)(len + 3);
406node->Buffer = malloc (node->Length);
407node->Buffer[offset++] = AML_CHUNK_BYTE;
408node->Buffer[offset++] = (char)len;
409memcpy(node->Buffer+offset,string, len);
410node->Buffer[offset+len] = '\0';
411}
412
413return node;
414}
415
416AML_CHUNK* aml_add_string(AML_CHUNK* parent, const char* string)
417{
418AML_CHUNK* node = aml_create_node(parent);
419
420if (node)
421{
422 int len = strlen(string);
423node->Type = AML_CHUNK_STRING;
424node->Length = (uint8_t)(len + 1);
425node->Buffer = malloc (len);
426memcpy(node->Buffer,string, len);
427node->Buffer[len] = '\0';
428}
429
430return node;
431}
432
433AML_CHUNK* aml_add_return(AML_CHUNK* parent)
434{
435AML_CHUNK* node = aml_create_node(parent);
436
437if (node)
438{
439node->Type = AML_CHUNK_RETURN;
440//aml_add_byte(node, value);
441}
442
443return node;
444}
445
446uint8_t aml_get_size_length(uint32_t size)
447{
448if (size + 1 <= 0x3f)
449return 1;
450else if (size + 2 <= 0xfff) /* Encode in 4 bits and 1 byte */
451return 2;
452else if (size + 3 <= 0xfffff) /* Encode in 4 bits and 2 bytes */
453return 3;
454
455return 4; /* Encode 0xfffffff in 4 bits and 2 bytes */
456}
457
458uint32_t aml_calculate_size(AML_CHUNK* node)
459{
460if (node)
461{
462// Calculate child nodes size
463AML_CHUNK* child = node->First;
464uint8_t child_count = 0;
465
466node->Size = 0;
467while (child)
468{
469child_count++;
470
471node->Size += (uint16_t)aml_calculate_size(child);
472
473child = child->Next;
474}
475
476switch (node->Type)
477{
478case AML_CHUNK_NONE:
479case AML_STORE_OP:
480case AML_CHUNK_LOCAL0:
481node->Size += node->Length;
482break;
483
484case AML_CHUNK_METHOD:
485case AML_CHUNK_SCOPE:
486case AML_CHUNK_BUFFER:
487node->Size += 1 + node->Length;
488node->Size += aml_get_size_length(node->Size);
489break;
490
491case AML_CHUNK_DEVICE:
492node->Size += 2 + node->Length;
493node->Size += aml_get_size_length(node->Size);
494break;
495
496case AML_CHUNK_PACKAGE:
497node->Buffer[0] = child_count;
498node->Size += 1 + node->Length;
499node->Size += aml_get_size_length(node->Size);
500break;
501
502case AML_CHUNK_BYTE:
503if (node->Buffer[0] == 0x0 || node->Buffer[0] == 0x1)
504{
505node->Size += node->Length;
506}
507else
508{
509node->Size += 1 + node->Length;
510}
511
512break;
513
514case AML_CHUNK_WORD:
515case AML_CHUNK_DWORD:
516case AML_CHUNK_QWORD:
517case AML_CHUNK_ALIAS:
518case AML_CHUNK_NAME:
519case AML_CHUNK_RETURN:
520case AML_CHUNK_STRING:
521node->Size += 1 + node->Length;
522break;
523}
524
525return node->Size;
526}
527
528return 0;
529}
530
531uint32_t aml_write_byte(uint8_t value, char* buffer, uint32_t offset)
532{
533buffer[offset++] = value;
534
535return offset;
536}
537
538uint32_t aml_write_word(uint16_t value, char* buffer, uint32_t offset)
539{
540buffer[offset++] = value & 0xff;
541buffer[offset++] = value >> 8;
542
543return offset;
544}
545
546uint32_t aml_write_dword(uint32_t value, char* buffer, uint32_t offset)
547{
548buffer[offset++] = value & 0xff;
549buffer[offset++] = (value >> 8) & 0xff;
550buffer[offset++] = (value >> 16) & 0xff;
551buffer[offset++] = (value >> 24) & 0xff;
552
553return offset;
554}
555
556uint32_t aml_write_qword(uint64_t value, char* buffer, uint32_t offset)
557{
558buffer[offset++] = value & 0xff;
559buffer[offset++] = (value >> 8) & 0xff;
560buffer[offset++] = (value >> 16) & 0xff;
561buffer[offset++] = (value >> 24) & 0xff;
562buffer[offset++] = (value >> 32) & 0xff;
563buffer[offset++] = (value >> 40) & 0xff;
564buffer[offset++] = (value >> 48) & 0xff;
565buffer[offset++] = (value >> 56) & 0xff;
566
567return offset;
568}
569
570uint32_t aml_write_buffer(const char* value, uint32_t size, char* buffer, uint32_t offset)
571{
572if (size > 0)
573{
574memcpy(buffer + offset, value, size);
575}
576
577return offset + size;
578}
579
580uint32_t aml_write_size(uint32_t size, char* buffer, uint32_t offset)
581{
582if (size <= 0x3f) /* simple 1 byte length in 6 bits */
583{
584buffer[offset++] = (char)size;
585}
586else if (size <= 0xfff)
587{
588buffer[offset++] = 0x40 | (size & 0xf); /* 0x40 is type, 0x0X is first nibble of length */
589buffer[offset++] = (size >> 4) & 0xff; /* +1 bytes for rest length */
590}
591else if (size <= 0xfffff)
592{
593buffer[offset++] = 0x80 | (size & 0xf); /* 0x80 is type, 0x0X is first nibble of length */
594buffer[offset++] = (size >> 4) & 0xff; /* +2 bytes for rest length */
595buffer[offset++] = (size >> 12) & 0xff;
596}
597 else
598{
599buffer[offset++] = 0xc0 | (size & 0xf); /* 0xC0 is type, 0x0X is first nibble of length */
600buffer[offset++] = (size >> 4) & 0xff; /* +3 bytes for rest length */
601buffer[offset++] = (size >> 12) & 0xff;
602buffer[offset++] = (size >> 20) & 0xff;
603}
604
605return offset;
606}
607
608uint32_t aml_write_node(AML_CHUNK* node, char* buffer, uint32_t offset)
609{
610if (node && buffer)
611{
612uint32_t old = offset;
613AML_CHUNK* child = node->First;
614
615switch (node->Type)
616{
617case AML_CHUNK_NONE:
618offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset);
619break;
620
621case AML_CHUNK_LOCAL0:
622case AML_STORE_OP:
623offset = aml_write_byte(node->Type, buffer, offset);
624break;
625
626case AML_CHUNK_DEVICE:
627offset = aml_write_byte(AML_CHUNK_OP, buffer, offset);
628offset = aml_write_byte(node->Type, buffer, offset);
629offset = aml_write_size(node->Size-3, buffer, offset);
630offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset);
631break;
632
633case AML_CHUNK_SCOPE:
634case AML_CHUNK_METHOD:
635case AML_CHUNK_PACKAGE:
636case AML_CHUNK_BUFFER:
637offset = aml_write_byte(node->Type, buffer, offset);
638offset = aml_write_size(node->Size-1, buffer, offset);
639offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset);
640break;
641
642case AML_CHUNK_BYTE:
643if (node->Buffer[0] == 0x0 || node->Buffer[0] == 0x1)
644{
645offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset);
646}
647else
648{
649offset = aml_write_byte(node->Type, buffer, offset);
650offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset);
651}
652break;
653
654case AML_CHUNK_WORD:
655case AML_CHUNK_DWORD:
656case AML_CHUNK_QWORD:
657case AML_CHUNK_ALIAS:
658case AML_CHUNK_NAME:
659case AML_CHUNK_RETURN:
660case AML_CHUNK_STRING:
661offset = aml_write_byte(node->Type, buffer, offset);
662offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset);
663break;
664
665default:
666break;
667}
668
669while (child)
670{
671offset = aml_write_node(child, buffer, offset);
672
673child = child->Next;
674}
675
676if (offset - old != node->Size)
677verbose("Node size incorrect: type=0x%x size=%x offset=%x\n",
678node->Type, node->Size, (offset - old));
679}
680
681return offset;
682}
683
684//the procedure can find array char sizeof N inside part of large array "dsdt" size of len
685uint32_t FindBin (uint8_t *dsdt, uint32_t len, char* bin, unsigned int N)
686{
687uint32_t i, j;
688bool eq;
689
690for (i=0; i<len-N; i++) {
691eq = true;
692for (j=0; j<N; j++) {
693if (dsdt[i+j] != bin[j]) {
694eq = false;
695break;
696}
697}
698if (eq) {
699return i;
700}
701}
702return 0;
703}
704
705uint32_t get_size(uint8_t* Buffer, uint32_t adr)
706{
707uint32_t temp;
708
709temp = Buffer[adr] & 0xF0; //keep bits 0x30 to check if this is valid size field
710
711if(temp <= 0x30) // 0
712{
713temp = Buffer[adr];
714}
715else if(temp == 0x40)// 4
716{
717temp = (Buffer[adr] - 0x40) << 0|
718Buffer[adr+1] << 4;
719}
720else if(temp == 0x80)// 8
721{
722temp = (Buffer[adr] - 0x80) << 0|
723Buffer[adr+1] << 4|
724Buffer[adr+2] << 12;
725}
726else if(temp == 0xC0)// C
727{ // C
728temp = (Buffer[adr] - 0xC0) << 0|
729Buffer[adr+1] << 4|
730Buffer[adr+2] << 12|
731Buffer[adr+3] << 20;
732}
733else {
734verbose("wrong pointer to size field at %x\n", adr);
735return 0; //this means wrong pointer to size field
736}
737return temp;
738}
739

Archive Download this file

Revision: 2238