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