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(struct aml_chunk* parent, struct 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 isn't supports child nodes!");␊ |
25 | ␉␉␉␉return false;␊ |
26 | ␉␉␉case AML_CHUNK_NAME:␊ |
27 | ␉␉␉␉if (parent->First) ␊ |
28 | ␉␉␉␉{␊ |
29 | ␉␉␉␉␉verbose("aml_add_to_parent: Name node could have only one child node!");␊ |
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 | struct aml_chunk* aml_create_node(struct aml_chunk* parent)␊ |
53 | {␊ |
54 | ␉struct aml_chunk* node = (struct aml_chunk*)malloc(sizeof(struct aml_chunk));␊ |
55 | ␉␊ |
56 | ␉aml_add_to_parent(parent, node);␊ |
57 | ␉␊ |
58 | ␉return node;␊ |
59 | }␊ |
60 | ␊ |
61 | void aml_destroy_node(struct aml_chunk* node)␊ |
62 | {␊ |
63 | ␉// Delete child nodes␊ |
64 | ␉struct aml_chunk* child = node->First;␊ |
65 | ␉␊ |
66 | ␉while (child) ␊ |
67 | ␉{␊ |
68 | ␉␉struct 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 | struct aml_chunk* aml_add_buffer(struct aml_chunk* parent, const char* buffer, unsigned int size)␊ |
86 | {␊ |
87 | ␉struct aml_chunk* node = aml_create_node(parent);␊ |
88 | ␉␊ |
89 | ␉if (node) ␊ |
90 | ␉{␊ |
91 | ␉␉node->Type = AML_CHUNK_NONE;␊ |
92 | ␉␉node->Length = size;␊ |
93 | ␉␉node->Buffer = malloc(node->Length);␊ |
94 | ␉␉memcpy(node->Buffer, buffer, node->Length);␊ |
95 | ␉}␊ |
96 | ␉␊ |
97 | ␉return node;␊ |
98 | }␊ |
99 | ␊ |
100 | struct aml_chunk* aml_add_byte(struct aml_chunk* parent, unsigned char value)␊ |
101 | {␊ |
102 | ␉struct 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 | struct aml_chunk* aml_add_word(struct aml_chunk* parent, unsigned int value)␊ |
117 | {␊ |
118 | ␉struct 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 | struct aml_chunk* aml_add_dword(struct aml_chunk* parent, unsigned long value)␊ |
133 | {␊ |
134 | ␉struct 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 | struct aml_chunk* aml_add_qword(struct aml_chunk* parent, unsigned long long value)␊ |
151 | {␊ |
152 | ␉struct 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 | unsigned int 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", name);␊ |
177 | ␉␉return 0;␊ |
178 | ␉}␊ |
179 | ␉␊ |
180 | ␉memcpy(buffer, name, 4);␊ |
181 | ␉return 4;␊ |
182 | }␊ |
183 | ␊ |
184 | unsigned int aml_fill_name(struct aml_chunk* node, const char* name)␊ |
185 | {␊ |
186 | ␉if (!node) ␊ |
187 | ␉␉return 0;␊ |
188 | ␉␊ |
189 | ␉int len = strlen(name), offset = 0, count = len / 4;␊ |
190 | ␉␊ |
191 | ␉if ((len % 4) > 1 || count == 0) ␊ |
192 | ␉{␊ |
193 | ␉␉verbose("aml_fill_name: pathname %s has incorrect length! Must be 4, 8, 12, 16 etc.", name);␊ |
194 | ␉␉return 0;␊ |
195 | ␉}␊ |
196 | ␉␊ |
197 | ␉unsigned int root = 0;␊ |
198 | ␉␊ |
199 | ␉if ((len % 4) == 1 && name[0] == '\\')␊ |
200 | ␉␉root++;␊ |
201 | ␉␉␉␊ |
202 | ␉if (count == 1) ␊ |
203 | ␉{␊ |
204 | ␉␉node->Length = 4 + root;␊ |
205 | ␉␉node->Buffer = malloc(node->Length);␊ |
206 | ␉␉memcpy(node->Buffer, name, 4 + root);␊ |
207 | ␉␉return node->Length;␊ |
208 | ␉}␊ |
209 | ␉␊ |
210 | ␉if (count == 2) ␊ |
211 | ␉{␊ |
212 | ␉␉node->Length = 2 + 8;␊ |
213 | ␉␉node->Buffer = malloc(node->Length);␊ |
214 | ␉␉node->Buffer[offset++] = 0x5c; // Root Char␊ |
215 | ␉␉node->Buffer[offset++] = 0x2e; // Double name␊ |
216 | ␉␉memcpy(node->Buffer+offset, name + root, 8);␊ |
217 | ␉␉return node->Length;␊ |
218 | ␉}␊ |
219 | ␉␊ |
220 | ␉node->Length = 3 + count*4;␊ |
221 | ␉node->Buffer = malloc(node->Length);␊ |
222 | ␉node->Buffer[offset++] = 0x5c; // Root Char␊ |
223 | ␉node->Buffer[offset++] = 0x2f; // Multi name␊ |
224 | ␉node->Buffer[offset++] = count; // Names count␊ |
225 | ␉memcpy(node->Buffer+offset, name + root, count*4);␊ |
226 | ␉␊ |
227 | ␉return node->Length;␊ |
228 | }␊ |
229 | ␊ |
230 | struct aml_chunk* aml_add_scope(struct aml_chunk* parent, const char* name)␊ |
231 | {␊ |
232 | ␉struct aml_chunk* node = aml_create_node(parent);␊ |
233 | ␉␊ |
234 | ␉if (node)␊ |
235 | ␉{␊ |
236 | ␉␉node->Type = AML_CHUNK_SCOPE;␊ |
237 | ␉␉␊ |
238 | ␉␉aml_fill_name(node, name);␊ |
239 | ␉}␊ |
240 | ␉␊ |
241 | ␉return node;␊ |
242 | }␊ |
243 | ␊ |
244 | struct aml_chunk* aml_add_name(struct aml_chunk* parent, const char* name)␊ |
245 | {␊ |
246 | ␉struct aml_chunk* node = aml_create_node(parent);␊ |
247 | ␉␊ |
248 | ␉if (node)␊ |
249 | ␉{␊ |
250 | ␉␉node->Type = AML_CHUNK_NAME;␊ |
251 | ␉␉␊ |
252 | ␉␉aml_fill_name(node, name);␊ |
253 | ␉}␊ |
254 | ␉␊ |
255 | ␉return node;␊ |
256 | }␊ |
257 | ␊ |
258 | struct aml_chunk* aml_add_package(struct aml_chunk* parent)␊ |
259 | {␊ |
260 | ␉struct aml_chunk* node = aml_create_node(parent);␊ |
261 | ␉␊ |
262 | ␉if (node)␊ |
263 | ␉{␊ |
264 | ␉␉node->Type = AML_CHUNK_PACKAGE;␊ |
265 | ␉␉␊ |
266 | ␉␉node->Length = 1;␊ |
267 | ␉␉node->Buffer = malloc(node->Length);␊ |
268 | ␉}␊ |
269 | ␉␊ |
270 | ␉return node;␊ |
271 | }␊ |
272 | ␊ |
273 | struct aml_chunk* aml_add_package_with_value(struct aml_chunk* parent, uint64_t *lst, int num)␊ |
274 | {␊ |
275 | ␉struct aml_chunk* node = aml_create_node(parent);␊ |
276 | ␉␊ |
277 | ␉if (node)␊ |
278 | ␉{␊ |
279 | ␉␉node->Type = AML_CHUNK_PACKAGE;␉␉␊ |
280 | ␉␉node->Length = 1;␊ |
281 | ␉␉node->Buffer = malloc(node->Length);␊ |
282 | ␉␉aml_add_multiple_value(node,lst,num);␊ |
283 | ␉␉␊ |
284 | ␉}␊ |
285 | ␉␊ |
286 | ␉return node;␊ |
287 | }␊ |
288 | ␊ |
289 | void aml_add_value(struct aml_chunk* parent, uint64_t val)␊ |
290 | {␉␊ |
291 | ␉if (parent)␊ |
292 | ␉{␉␉␉␊ |
293 | ␉␉if (val > 0xffffffff)␊ |
294 | ␉␉␉aml_add_qword(parent,val);␊ |
295 | ␉␉else if (val > 0xffff)␊ |
296 | ␉␉␉aml_add_dword(parent,val);␊ |
297 | ␉␉else if (val > 0xff)␊ |
298 | ␉␉␉aml_add_word(parent,val);␊ |
299 | ␉␉else if (val >= 0)␊ |
300 | ␉␉␉aml_add_byte(parent, val);␉␉␉␉␉␊ |
301 | ␉}␊ |
302 | ␉␊ |
303 | }␊ |
304 | ␊ |
305 | void aml_add_multiple_value(struct aml_chunk* parent, uint64_t *lst, int num)␊ |
306 | {␉␊ |
307 | ␉if (parent)␊ |
308 | ␉{␉␉␉␉␊ |
309 | ␉␉int i;␉␉␊ |
310 | ␉␉for (i=0; i<(num / 8); i++) {␉␉␉␊ |
311 | ␉␉␉␊ |
312 | ␉␉␉aml_add_value(parent, lst[i]);␊ |
313 | ␉␉}␊ |
314 | ␉}␊ |
315 | ␉␊ |
316 | }␊ |
317 | ␊ |
318 | struct aml_chunk* aml_add_alias(struct aml_chunk* parent, const char* name1, const char* name2)␊ |
319 | {␊ |
320 | ␉struct aml_chunk* node = aml_create_node(parent);␊ |
321 | ␉␊ |
322 | ␉if (node)␊ |
323 | ␉{␊ |
324 | ␉␉node->Type = AML_CHUNK_ALIAS;␊ |
325 | ␉␉␊ |
326 | ␉␉node->Length = 8;␊ |
327 | ␉␉node->Buffer = malloc(node->Length);␊ |
328 | ␉␉aml_fill_simple_name(node->Buffer, name1);␊ |
329 | ␉␉aml_fill_simple_name(node->Buffer+4, name2);␊ |
330 | ␉}␊ |
331 | ␉␊ |
332 | ␉return node;␊ |
333 | }␊ |
334 | ␊ |
335 | unsigned char aml_get_size_length(unsigned int size)␊ |
336 | {␊ |
337 | ␉if (size + 1 <= 0x3f)␊ |
338 | ␉␉return 1;␊ |
339 | ␉else if (size + 2 <= 0x3fff)␊ |
340 | ␉␉return 2;␊ |
341 | ␉else if (size + 3 <= 0x3fffff)␊ |
342 | ␉␉return 3;␊ |
343 | ␉␊ |
344 | ␉return 4;␊ |
345 | }␊ |
346 | ␊ |
347 | unsigned int aml_calculate_size(struct aml_chunk* node)␊ |
348 | {␊ |
349 | ␉if (node)␊ |
350 | ␉{␊ |
351 | ␉␉node->Size = 0;␊ |
352 | ␉␉␊ |
353 | ␉␉// Calculate child nodes size␊ |
354 | ␉␉struct aml_chunk* child = node->First;␊ |
355 | ␉␉unsigned char child_count = 0;␊ |
356 | ␉␉␊ |
357 | ␉␉while (child) ␊ |
358 | ␉␉{␊ |
359 | ␉␉␉child_count++;␊ |
360 | ␉␉␉␊ |
361 | ␉␉␉node->Size += aml_calculate_size(child);␊ |
362 | ␉␉␉␊ |
363 | ␉␉␉child = child->Next;␊ |
364 | ␉␉}␊ |
365 | ␉␉␊ |
366 | ␉␉switch (node->Type) ␊ |
367 | ␉␉{␊ |
368 | ␉␉␉case AML_CHUNK_NONE:␊ |
369 | ␉␉␉␉node->Size += node->Length;␊ |
370 | ␉␉␉␉break;␊ |
371 | ␉␉␉case AML_CHUNK_SCOPE:␊ |
372 | ␉␉␉␉node->Size += 1 + node->Length;␊ |
373 | ␉␉␉␉node->Size += aml_get_size_length(node->Size);␊ |
374 | ␉␉␉␉break;␊ |
375 | ␉␉␉case AML_CHUNK_PACKAGE:␊ |
376 | ␉␉␉␉node->Buffer[0] = child_count;␊ |
377 | ␉␉␉␉node->Size += 1 + node->Length;␊ |
378 | ␉␉␉␉node->Size += aml_get_size_length(node->Size);␊ |
379 | ␉␉␉␉break;␊ |
380 | ␉␉␉␉␊ |
381 | ␉␉␉case AML_CHUNK_BYTE:␊ |
382 | ␉␉␉␉if (node->Buffer[0] == 0x0 || node->Buffer[0] == 0x1) ␊ |
383 | ␉␉␉␉{␊ |
384 | ␉␉␉␉␉node->Size += node->Length;␊ |
385 | ␉␉␉␉}␊ |
386 | ␉␉␉␉else ␊ |
387 | ␉␉␉␉{␊ |
388 | ␉␉␉␉␉node->Size += 1 + node->Length;␊ |
389 | ␉␉␉␉}␊ |
390 | ␉␉␉␉␊ |
391 | ␉␉␉␉break;␊ |
392 | ␉␉␉␉␊ |
393 | ␉␉␉case AML_CHUNK_WORD:␊ |
394 | ␉␉␉case AML_CHUNK_DWORD:␊ |
395 | ␉␉␉case AML_CHUNK_QWORD:␊ |
396 | ␉␉␉case AML_CHUNK_ALIAS:␊ |
397 | ␉␉␉case AML_CHUNK_NAME:␊ |
398 | ␉␉␉␉node->Size += 1 + node->Length;␊ |
399 | ␉␉␉␉break;␊ |
400 | ␉␉}␊ |
401 | ␉␉␊ |
402 | ␉␉return node->Size;␊ |
403 | ␉}␊ |
404 | ␉␊ |
405 | ␉return 0;␊ |
406 | }␊ |
407 | ␊ |
408 | unsigned int aml_write_byte(unsigned char value, char* buffer, unsigned int offset)␊ |
409 | {␊ |
410 | ␉buffer[offset++] = value;␊ |
411 | ␉␊ |
412 | ␉return offset;␊ |
413 | }␊ |
414 | ␊ |
415 | unsigned int aml_write_word(unsigned int value, char* buffer, unsigned int offset)␊ |
416 | {␊ |
417 | ␉buffer[offset++] = value & 0xff;␊ |
418 | ␉buffer[offset++] = value >> 8;␊ |
419 | ␉␊ |
420 | ␉return offset;␊ |
421 | }␊ |
422 | ␊ |
423 | unsigned int aml_write_dword(unsigned long value, char* buffer, unsigned int offset)␊ |
424 | {␊ |
425 | ␉buffer[offset++] = value & 0xff;␊ |
426 | ␉buffer[offset++] = (value >> 8) & 0xff;␊ |
427 | ␉buffer[offset++] = (value >> 16) & 0xff;␊ |
428 | ␉buffer[offset++] = (value >> 24) & 0xff;␊ |
429 | ␉␊ |
430 | ␉return offset;␊ |
431 | }␊ |
432 | ␊ |
433 | unsigned int aml_write_qword(unsigned long long value, char* buffer, unsigned int offset)␊ |
434 | {␊ |
435 | ␉buffer[offset++] = value & 0xff;␊ |
436 | ␉buffer[offset++] = (value >> 8) & 0xff;␊ |
437 | ␉buffer[offset++] = (value >> 16) & 0xff;␊ |
438 | ␉buffer[offset++] = (value >> 24) & 0xff;␊ |
439 | ␉buffer[offset++] = (value >> 32) & 0xff;␊ |
440 | ␉buffer[offset++] = (value >> 40) & 0xff;␊ |
441 | ␉buffer[offset++] = (value >> 48) & 0xff;␊ |
442 | ␉buffer[offset++] = (value >> 56) & 0xff;␊ |
443 | ␉␊ |
444 | ␉return offset;␊ |
445 | }␊ |
446 | ␊ |
447 | unsigned int aml_write_buffer(const char* value, unsigned int size, char* buffer, unsigned int offset)␊ |
448 | {␊ |
449 | ␉if (size > 0)␊ |
450 | ␉{␊ |
451 | ␉␉memcpy(buffer + offset, value, size);␊ |
452 | ␉}␊ |
453 | ␉␊ |
454 | ␉return offset + size;␊ |
455 | }␊ |
456 | ␊ |
457 | void aml_add_ressource_t_fxhw(struct aml_chunk* parent, uint64_t *lst)␊ |
458 | {␊ |
459 | ␉if (parent) {␊ |
460 | ␉␉char resource_template[] = ␊ |
461 | ␉␉{␊ |
462 | ␉␉␉0x11, 0x14, 0x0A, 0x11, 0x82, 0x0C, 0x00, 0x7F, ␊ |
463 | ␉␉␉0x01, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, ␊ |
464 | ␉␉␉0x00, 0x00, 0x00, 0x79, 0x00␊ |
465 | ␉␉};␊ |
466 | ␉␉␊ |
467 | ␉␉char *buffer = resource_template;␊ |
468 | ␉␉unsigned int offset = aml_write_byte(lst[0], buffer, 8);␊ |
469 | ␉␉offset = aml_write_byte(lst[1], buffer, offset);␊ |
470 | ␉␉offset = aml_write_byte(lst[2], buffer, offset);␊ |
471 | ␉␉aml_write_qword(lst[3], buffer, offset);␉␉␊ |
472 | ␉␉aml_add_buffer(parent, buffer, sizeof(resource_template));␊ |
473 | ␉}␊ |
474 | }␊ |
475 | ␊ |
476 | unsigned int aml_write_size(unsigned int size, char* buffer, unsigned int offset)␊ |
477 | {␊ |
478 | ␉if (size <= 0x3f)␊ |
479 | ␉{␊ |
480 | ␉␉buffer[offset++] = size;␊ |
481 | ␉}␊ |
482 | ␉else if (size <= 0x3fff) ␊ |
483 | ␉{␊ |
484 | ␉␉buffer[offset++] = 0x40 | (size & 0xf);␊ |
485 | ␉␉buffer[offset++] = (size >> 4) & 0xff;␊ |
486 | ␉}␊ |
487 | ␉else if (size <= 0x3fffff) ␊ |
488 | ␉{␊ |
489 | ␉␉buffer[offset++] = 0x80 | (size & 0xf);␊ |
490 | ␉␉buffer[offset++] = (size >> 4) & 0xff;␊ |
491 | ␉␉buffer[offset++] = (size >> 12) & 0xff;␊ |
492 | ␉}␊ |
493 | else ␊ |
494 | ␉{␊ |
495 | ␉␉buffer[offset++] = 0xc0 | (size & 0xf);␊ |
496 | ␉␉buffer[offset++] = (size >> 4) & 0xff;␊ |
497 | ␉␉buffer[offset++] = (size >> 12) & 0xff;␊ |
498 | ␉␉buffer[offset++] = (size >> 20) & 0xff;␊ |
499 | ␉}␊ |
500 | ␉␊ |
501 | ␉return offset;␊ |
502 | }␊ |
503 | ␊ |
504 | unsigned int aml_write_node(struct aml_chunk* node, char* buffer, unsigned int offset)␊ |
505 | {␊ |
506 | ␉if (node && buffer) ␊ |
507 | ␉{␊ |
508 | ␉␉unsigned int old = offset;␊ |
509 | ␉␉␊ |
510 | ␉␉switch (node->Type) ␊ |
511 | ␉␉{␊ |
512 | ␉␉␉case AML_CHUNK_NONE:␊ |
513 | ␉␉␉␉offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset);␊ |
514 | ␉␉␉␉break;␊ |
515 | ␊ |
516 | ␉␉␉case AML_CHUNK_SCOPE:␊ |
517 | ␉␉␉case AML_CHUNK_PACKAGE:␊ |
518 | ␉␉␉␉offset = aml_write_byte(node->Type, buffer, offset);␊ |
519 | ␉␉␉␉offset = aml_write_size(node->Size-1, buffer, offset);␊ |
520 | ␉␉␉␉offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset);␊ |
521 | ␉␉␉␉break;␊ |
522 | ␉␉␉␉␊ |
523 | ␉␉␉case AML_CHUNK_BYTE:␊ |
524 | ␉␉␉␉if (node->Buffer[0] == 0x0 || node->Buffer[0] == 0x1) ␊ |
525 | ␉␉␉␉{␊ |
526 | ␉␉␉␉␉offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset);␊ |
527 | ␉␉␉␉}␊ |
528 | ␉␉␉␉else ␊ |
529 | ␉␉␉␉{␊ |
530 | ␉␉␉␉␉offset = aml_write_byte(node->Type, buffer, offset);␊ |
531 | ␉␉␉␉␉offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset);␊ |
532 | ␉␉␉␉}␊ |
533 | ␉␉␉␉break;␊ |
534 | ␉␉␉␉␊ |
535 | ␉␉␉case AML_CHUNK_WORD:␊ |
536 | ␉␉␉case AML_CHUNK_DWORD:␊ |
537 | ␉␉␉case AML_CHUNK_QWORD:␊ |
538 | ␉␉␉case AML_CHUNK_ALIAS:␊ |
539 | ␉␉␉case AML_CHUNK_NAME:␊ |
540 | ␉␉␉␉offset = aml_write_byte(node->Type, buffer, offset);␊ |
541 | ␉␉␉␉offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset);␊ |
542 | ␉␉␉␉break;␊ |
543 | ␉␉␉␉␊ |
544 | ␉␉␉default:␊ |
545 | ␉␉␉␉break;␊ |
546 | ␉␉}␊ |
547 | ␊ |
548 | ␉␉struct aml_chunk* child = node->First;␊ |
549 | ␉␉␊ |
550 | ␉␉while (child) ␊ |
551 | ␉␉{␊ |
552 | ␉␉␉offset = aml_write_node(child, buffer, offset);␊ |
553 | ␉␉␉␊ |
554 | ␉␉␉child = child->Next;␊ |
555 | ␉␉}␊ |
556 | ␉␉␊ |
557 | ␉␉if (offset - old != node->Size) ␊ |
558 | ␉␉␉verbose("Node size incorrect: 0x%x\n", node->Type);␊ |
559 | ␉}␊ |
560 | ␉␊ |
561 | ␉return offset;␊ |
562 | } |