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