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