1 /* Support for generating ACPI tables and passing them to Guests
3 * Copyright (C) 2015 Red Hat Inc
5 * Author: Michael S. Tsirkin <mst@redhat.com>
6 * Author: Igor Mammedov <imammedo@redhat.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, see <http://www.gnu.org/licenses/>.
27 #include "hw/acpi/aml-build.h"
28 #include "qemu/bswap.h"
30 static GArray
*build_alloc_array(void)
32 return g_array_new(false, true /* clear */, 1);
35 static void build_free_array(GArray
*array
)
37 g_array_free(array
, true);
40 static void build_prepend_byte(GArray
*array
, uint8_t val
)
42 g_array_prepend_val(array
, val
);
45 static void build_append_byte(GArray
*array
, uint8_t val
)
47 g_array_append_val(array
, val
);
50 static void build_append_array(GArray
*array
, GArray
*val
)
52 g_array_append_vals(array
, val
->data
, val
->len
);
55 #define ACPI_NAMESEG_LEN 4
58 build_append_nameseg(GArray
*array
, const char *seg
)
60 /* It would be nicer to use g_string_vprintf but it's only there in 2.22 */
64 assert(len
<= ACPI_NAMESEG_LEN
);
66 g_array_append_vals(array
, seg
, len
);
67 /* Pad up to ACPI_NAMESEG_LEN characters if necessary. */
68 g_array_append_vals(array
, "____", ACPI_NAMESEG_LEN
- len
);
72 build_append_namestringv(GArray
*array
, const char *format
, va_list ap
)
74 /* It would be nicer to use g_string_vprintf but it's only there in 2.22 */
83 len
= vsnprintf(NULL
, 0, format
, va_len
);
86 s
= g_new(typeof(*s
), len
);
88 len
= vsnprintf(s
, len
, format
, ap
);
90 segs
= g_strsplit(s
, ".", 0);
100 * ACPI 5.0 spec: 20.2.2 Name Objects Encoding:
101 * "SegCount can be from 1 to 255"
103 assert(seg_count
> 0 && seg_count
<= 255);
105 /* handle RootPath || PrefixPath */
107 while (*s
== '\\' || *s
== '^') {
108 build_append_byte(array
, *s
);
115 build_append_byte(array
, 0x00); /* NullName */
117 build_append_nameseg(array
, s
);
122 build_append_byte(array
, 0x2E); /* DualNamePrefix */
123 build_append_nameseg(array
, s
);
124 build_append_nameseg(array
, segs
[1]);
127 build_append_byte(array
, 0x2F); /* MultiNamePrefix */
128 build_append_byte(array
, seg_count
);
130 /* handle the 1st segment manually due to prefix/root path */
131 build_append_nameseg(array
, s
);
133 /* add the rest of segments */
134 segs_iter
= segs
+ 1;
136 build_append_nameseg(array
, *segs_iter
);
144 static void build_append_namestring(GArray
*array
, const char *format
, ...)
148 va_start(ap
, format
);
149 build_append_namestringv(array
, format
, ap
);
153 /* 5.4 Definition Block Encoding */
155 PACKAGE_LENGTH_1BYTE_SHIFT
= 6, /* Up to 63 - use extra 2 bits. */
156 PACKAGE_LENGTH_2BYTE_SHIFT
= 4,
157 PACKAGE_LENGTH_3BYTE_SHIFT
= 12,
158 PACKAGE_LENGTH_4BYTE_SHIFT
= 20,
162 build_prepend_package_length(GArray
*package
, unsigned length
, bool incl_self
)
165 unsigned length_bytes
;
167 if (length
+ 1 < (1 << PACKAGE_LENGTH_1BYTE_SHIFT
)) {
169 } else if (length
+ 2 < (1 << PACKAGE_LENGTH_3BYTE_SHIFT
)) {
171 } else if (length
+ 3 < (1 << PACKAGE_LENGTH_4BYTE_SHIFT
)) {
178 * NamedField uses PkgLength encoding but it doesn't include length
179 * of PkgLength itself.
183 * PkgLength is the length of the inclusive length of the data
184 * and PkgLength's length itself when used for terms with
187 length
+= length_bytes
;
190 switch (length_bytes
) {
193 build_prepend_byte(package
, byte
);
196 byte
= length
>> PACKAGE_LENGTH_4BYTE_SHIFT
;
197 build_prepend_byte(package
, byte
);
198 length
&= (1 << PACKAGE_LENGTH_4BYTE_SHIFT
) - 1;
201 byte
= length
>> PACKAGE_LENGTH_3BYTE_SHIFT
;
202 build_prepend_byte(package
, byte
);
203 length
&= (1 << PACKAGE_LENGTH_3BYTE_SHIFT
) - 1;
206 byte
= length
>> PACKAGE_LENGTH_2BYTE_SHIFT
;
207 build_prepend_byte(package
, byte
);
208 length
&= (1 << PACKAGE_LENGTH_2BYTE_SHIFT
) - 1;
212 * Most significant two bits of byte zero indicate how many following bytes
213 * are in PkgLength encoding.
215 byte
= ((length_bytes
- 1) << PACKAGE_LENGTH_1BYTE_SHIFT
) | length
;
216 build_prepend_byte(package
, byte
);
220 build_append_pkg_length(GArray
*array
, unsigned length
, bool incl_self
)
222 GArray
*tmp
= build_alloc_array();
224 build_prepend_package_length(tmp
, length
, incl_self
);
225 build_append_array(array
, tmp
);
226 build_free_array(tmp
);
229 static void build_package(GArray
*package
, uint8_t op
)
231 build_prepend_package_length(package
, package
->len
, true);
232 build_prepend_byte(package
, op
);
235 static void build_extop_package(GArray
*package
, uint8_t op
)
237 build_package(package
, op
);
238 build_prepend_byte(package
, 0x5B); /* ExtOpPrefix */
241 static void build_append_int_noprefix(GArray
*table
, uint64_t value
, int size
)
245 for (i
= 0; i
< size
; ++i
) {
246 build_append_byte(table
, value
& 0xFF);
251 static void build_append_int(GArray
*table
, uint64_t value
)
254 build_append_byte(table
, 0x00); /* ZeroOp */
255 } else if (value
== 0x01) {
256 build_append_byte(table
, 0x01); /* OneOp */
257 } else if (value
<= 0xFF) {
258 build_append_byte(table
, 0x0A); /* BytePrefix */
259 build_append_int_noprefix(table
, value
, 1);
260 } else if (value
<= 0xFFFF) {
261 build_append_byte(table
, 0x0B); /* WordPrefix */
262 build_append_int_noprefix(table
, value
, 2);
263 } else if (value
<= 0xFFFFFFFF) {
264 build_append_byte(table
, 0x0C); /* DWordPrefix */
265 build_append_int_noprefix(table
, value
, 4);
267 build_append_byte(table
, 0x0E); /* QWordPrefix */
268 build_append_int_noprefix(table
, value
, 8);
272 static GPtrArray
*alloc_list
;
274 static Aml
*aml_alloc(void)
276 Aml
*var
= g_new0(typeof(*var
), 1);
278 g_ptr_array_add(alloc_list
, var
);
279 var
->block_flags
= AML_NO_OPCODE
;
280 var
->buf
= build_alloc_array();
284 static Aml
*aml_opcode(uint8_t op
)
286 Aml
*var
= aml_alloc();
289 var
->block_flags
= AML_OPCODE
;
293 static Aml
*aml_bundle(uint8_t op
, AmlBlockFlags flags
)
295 Aml
*var
= aml_alloc();
298 var
->block_flags
= flags
;
302 static void aml_free(gpointer data
, gpointer user_data
)
305 build_free_array(var
->buf
);
308 Aml
*init_aml_allocator(void)
313 alloc_list
= g_ptr_array_new();
318 void free_aml_allocator(void)
320 g_ptr_array_foreach(alloc_list
, aml_free
, NULL
);
321 g_ptr_array_free(alloc_list
, true);
325 /* pack data with DefBuffer encoding */
326 static void build_buffer(GArray
*array
, uint8_t op
)
328 GArray
*data
= build_alloc_array();
330 build_append_int(data
, array
->len
);
331 g_array_prepend_vals(array
, data
->data
, data
->len
);
332 build_free_array(data
);
333 build_package(array
, op
);
336 void aml_append(Aml
*parent_ctx
, Aml
*child
)
338 GArray
*buf
= build_alloc_array();
339 build_append_array(buf
, child
->buf
);
341 switch (child
->block_flags
) {
343 build_append_byte(parent_ctx
->buf
, child
->op
);
345 case AML_EXT_PACKAGE
:
346 build_extop_package(buf
, child
->op
);
349 build_package(buf
, child
->op
);
351 case AML_RES_TEMPLATE
:
352 build_append_byte(buf
, 0x79); /* EndTag */
354 * checksum operations are treated as succeeded if checksum
355 * field is zero. [ACPI Spec 1.0b, 6.4.2.8 End Tag]
357 build_append_byte(buf
, 0);
358 /* fall through, to pack resources in buffer */
360 build_buffer(buf
, child
->op
);
368 build_append_array(parent_ctx
->buf
, buf
);
369 build_free_array(buf
);
372 /* ACPI 1.0b: 16.2.5.1 Namespace Modifier Objects Encoding: DefScope */
373 Aml
*aml_scope(const char *name_format
, ...)
376 Aml
*var
= aml_bundle(0x10 /* ScopeOp */, AML_PACKAGE
);
377 va_start(ap
, name_format
);
378 build_append_namestringv(var
->buf
, name_format
, ap
);
383 /* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefReturn */
384 Aml
*aml_return(Aml
*val
)
386 Aml
*var
= aml_opcode(0xA4 /* ReturnOp */);
387 aml_append(var
, val
);
392 * ACPI 1.0b: 16.2.3 Data Objects Encoding:
393 * encodes: ByteConst, WordConst, DWordConst, QWordConst, ZeroOp, OneOp
395 Aml
*aml_int(const uint64_t val
)
397 Aml
*var
= aml_alloc();
398 build_append_int(var
->buf
, val
);
403 * helper to construct NameString, which returns Aml object
404 * for using with aml_append or other aml_* terms
406 Aml
*aml_name(const char *name_format
, ...)
409 Aml
*var
= aml_alloc();
410 va_start(ap
, name_format
);
411 build_append_namestringv(var
->buf
, name_format
, ap
);
416 /* ACPI 1.0b: 16.2.5.1 Namespace Modifier Objects Encoding: DefName */
417 Aml
*aml_name_decl(const char *name
, Aml
*val
)
419 Aml
*var
= aml_opcode(0x08 /* NameOp */);
420 build_append_namestring(var
->buf
, "%s", name
);
421 aml_append(var
, val
);
425 /* ACPI 1.0b: 16.2.6.1 Arg Objects Encoding */
426 Aml
*aml_arg(int pos
)
429 uint8_t op
= 0x68 /* ARG0 op */ + pos
;
432 var
= aml_opcode(op
);
436 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefStore */
437 Aml
*aml_store(Aml
*val
, Aml
*target
)
439 Aml
*var
= aml_opcode(0x70 /* StoreOp */);
440 aml_append(var
, val
);
441 aml_append(var
, target
);
445 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefAnd */
446 Aml
*aml_and(Aml
*arg1
, Aml
*arg2
)
448 Aml
*var
= aml_opcode(0x7B /* AndOp */);
449 aml_append(var
, arg1
);
450 aml_append(var
, arg2
);
451 build_append_byte(var
->buf
, 0x00 /* NullNameOp */);
455 /* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefNotify */
456 Aml
*aml_notify(Aml
*arg1
, Aml
*arg2
)
458 Aml
*var
= aml_opcode(0x86 /* NotifyOp */);
459 aml_append(var
, arg1
);
460 aml_append(var
, arg2
);
464 /* helper to call method with 1 argument */
465 Aml
*aml_call1(const char *method
, Aml
*arg1
)
467 Aml
*var
= aml_alloc();
468 build_append_namestring(var
->buf
, "%s", method
);
469 aml_append(var
, arg1
);
473 /* helper to call method with 2 arguments */
474 Aml
*aml_call2(const char *method
, Aml
*arg1
, Aml
*arg2
)
476 Aml
*var
= aml_alloc();
477 build_append_namestring(var
->buf
, "%s", method
);
478 aml_append(var
, arg1
);
479 aml_append(var
, arg2
);
483 /* helper to call method with 3 arguments */
484 Aml
*aml_call3(const char *method
, Aml
*arg1
, Aml
*arg2
, Aml
*arg3
)
486 Aml
*var
= aml_alloc();
487 build_append_namestring(var
->buf
, "%s", method
);
488 aml_append(var
, arg1
);
489 aml_append(var
, arg2
);
490 aml_append(var
, arg3
);
494 /* helper to call method with 4 arguments */
495 Aml
*aml_call4(const char *method
, Aml
*arg1
, Aml
*arg2
, Aml
*arg3
, Aml
*arg4
)
497 Aml
*var
= aml_alloc();
498 build_append_namestring(var
->buf
, "%s", method
);
499 aml_append(var
, arg1
);
500 aml_append(var
, arg2
);
501 aml_append(var
, arg3
);
502 aml_append(var
, arg4
);
506 /* ACPI 1.0b: 6.4.2.5 I/O Port Descriptor */
507 Aml
*aml_io(AmlIODecode dec
, uint16_t min_base
, uint16_t max_base
,
508 uint8_t aln
, uint8_t len
)
510 Aml
*var
= aml_alloc();
511 build_append_byte(var
->buf
, 0x47); /* IO port descriptor */
512 build_append_byte(var
->buf
, dec
);
513 build_append_byte(var
->buf
, min_base
& 0xff);
514 build_append_byte(var
->buf
, (min_base
>> 8) & 0xff);
515 build_append_byte(var
->buf
, max_base
& 0xff);
516 build_append_byte(var
->buf
, (max_base
>> 8) & 0xff);
517 build_append_byte(var
->buf
, aln
);
518 build_append_byte(var
->buf
, len
);
523 * ACPI 1.0b: 6.4.2.1.1 ASL Macro for IRQ Descriptor
525 * More verbose description at:
526 * ACPI 5.0: 19.5.64 IRQNoFlags (Interrupt Resource Descriptor Macro)
527 * 6.4.2.1 IRQ Descriptor
529 Aml
*aml_irq_no_flags(uint8_t irq
)
532 Aml
*var
= aml_alloc();
535 build_append_byte(var
->buf
, 0x22); /* IRQ descriptor 2 byte form */
537 irq_mask
= 1U << irq
;
538 build_append_byte(var
->buf
, irq_mask
& 0xFF); /* IRQ mask bits[7:0] */
539 build_append_byte(var
->buf
, irq_mask
>> 8); /* IRQ mask bits[15:8] */
543 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLEqual */
544 Aml
*aml_equal(Aml
*arg1
, Aml
*arg2
)
546 Aml
*var
= aml_opcode(0x93 /* LequalOp */);
547 aml_append(var
, arg1
);
548 aml_append(var
, arg2
);
552 /* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefIfElse */
553 Aml
*aml_if(Aml
*predicate
)
555 Aml
*var
= aml_bundle(0xA0 /* IfOp */, AML_PACKAGE
);
556 aml_append(var
, predicate
);
560 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefMethod */
561 Aml
*aml_method(const char *name
, int arg_count
)
563 Aml
*var
= aml_bundle(0x14 /* MethodOp */, AML_PACKAGE
);
564 build_append_namestring(var
->buf
, "%s", name
);
565 build_append_byte(var
->buf
, arg_count
); /* MethodFlags: ArgCount */
569 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefDevice */
570 Aml
*aml_device(const char *name_format
, ...)
573 Aml
*var
= aml_bundle(0x82 /* DeviceOp */, AML_EXT_PACKAGE
);
574 va_start(ap
, name_format
);
575 build_append_namestringv(var
->buf
, name_format
, ap
);
580 /* ACPI 1.0b: 6.4.1 ASL Macros for Resource Descriptors */
581 Aml
*aml_resource_template(void)
583 /* ResourceTemplate is a buffer of Resources with EndTag at the end */
584 Aml
*var
= aml_bundle(0x11 /* BufferOp */, AML_RES_TEMPLATE
);
588 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefBuffer */
589 Aml
*aml_buffer(void)
591 Aml
*var
= aml_bundle(0x11 /* BufferOp */, AML_BUFFER
);
595 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefPackage */
596 Aml
*aml_package(uint8_t num_elements
)
598 Aml
*var
= aml_bundle(0x12 /* PackageOp */, AML_PACKAGE
);
599 build_append_byte(var
->buf
, num_elements
);
603 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefOpRegion */
604 Aml
*aml_operation_region(const char *name
, AmlRegionSpace rs
,
605 uint32_t offset
, uint32_t len
)
607 Aml
*var
= aml_alloc();
608 build_append_byte(var
->buf
, 0x5B); /* ExtOpPrefix */
609 build_append_byte(var
->buf
, 0x80); /* OpRegionOp */
610 build_append_namestring(var
->buf
, "%s", name
);
611 build_append_byte(var
->buf
, rs
);
612 build_append_int(var
->buf
, offset
);
613 build_append_int(var
->buf
, len
);
617 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: NamedField */
618 Aml
*aml_named_field(const char *name
, unsigned length
)
620 Aml
*var
= aml_alloc();
621 build_append_nameseg(var
->buf
, name
);
622 build_append_pkg_length(var
->buf
, length
, false);
626 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: ReservedField */
627 Aml
*aml_reserved_field(unsigned length
)
629 Aml
*var
= aml_alloc();
630 /* ReservedField := 0x00 PkgLength */
631 build_append_byte(var
->buf
, 0x00);
632 build_append_pkg_length(var
->buf
, length
, false);
636 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefField */
637 Aml
*aml_field(const char *name
, AmlFieldFlags flags
)
639 Aml
*var
= aml_bundle(0x81 /* FieldOp */, AML_EXT_PACKAGE
);
640 build_append_namestring(var
->buf
, "%s", name
);
641 build_append_byte(var
->buf
, flags
);
645 /* ACPI 1.0b: 16.2.3 Data Objects Encoding: String */
646 Aml
*aml_string(const char *name_format
, ...)
648 Aml
*var
= aml_opcode(0x0D /* StringPrefix */);
653 va_start(ap
, name_format
);
655 len
= vsnprintf(NULL
, 0, name_format
, va_len
);
658 s
= g_new0(typeof(*s
), len
);
660 len
= vsnprintf(s
, len
, name_format
, ap
);
663 g_array_append_vals(var
->buf
, s
, len
);
664 build_append_byte(var
->buf
, 0x0); /* NullChar */
670 /* ACPI 1.0b: 16.2.6.2 Local Objects Encoding */
671 Aml
*aml_local(int num
)
674 uint8_t op
= 0x60 /* Local0Op */ + num
;
677 var
= aml_opcode(op
);
681 /* ACPI 2.0a: 17.2.2 Data Objects Encoding: DefVarPackage */
682 Aml
*aml_varpackage(uint32_t num_elements
)
684 Aml
*var
= aml_bundle(0x13 /* VarPackageOp */, AML_PACKAGE
);
685 build_append_int(var
->buf
, num_elements
);
689 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefProcessor */
690 Aml
*aml_processor(uint8_t proc_id
, uint32_t pblk_addr
, uint8_t pblk_len
,
691 const char *name_format
, ...)
694 Aml
*var
= aml_bundle(0x83 /* ProcessorOp */, AML_EXT_PACKAGE
);
695 va_start(ap
, name_format
);
696 build_append_namestringv(var
->buf
, name_format
, ap
);
698 build_append_byte(var
->buf
, proc_id
); /* ProcID */
699 build_append_int_noprefix(var
->buf
, pblk_addr
, sizeof(pblk_addr
));
700 build_append_byte(var
->buf
, pblk_len
); /* PblkLen */
704 static uint8_t Hex2Digit(char c
)
713 /* ACPI 1.0b: 15.2.3.6.4.1 EISAID Macro - Convert EISA ID String To Integer */
714 Aml
*aml_eisaid(const char *str
)
716 Aml
*var
= aml_alloc();
719 g_assert(strlen(str
) == 7);
720 id
= (str
[0] - 0x40) << 26 |
721 (str
[1] - 0x40) << 21 |
722 (str
[2] - 0x40) << 16 |
723 Hex2Digit(str
[3]) << 12 |
724 Hex2Digit(str
[4]) << 8 |
725 Hex2Digit(str
[5]) << 4 |
728 build_append_byte(var
->buf
, 0x0C); /* DWordPrefix */
729 build_append_int_noprefix(var
->buf
, bswap32(id
), sizeof(id
));
733 /* ACPI 1.0b: 6.4.3.5.5 Word Address Space Descriptor: bytes 3-5 */
734 static Aml
*aml_as_desc_header(AmlResourceType type
, AmlMinFixed min_fixed
,
735 AmlMaxFixed max_fixed
, AmlDecode dec
,
738 uint8_t flags
= max_fixed
| min_fixed
| dec
;
739 Aml
*var
= aml_alloc();
741 build_append_byte(var
->buf
, type
);
742 build_append_byte(var
->buf
, flags
);
743 build_append_byte(var
->buf
, type_flags
); /* Type Specific Flags */
747 /* ACPI 1.0b: 6.4.3.5.5 Word Address Space Descriptor */
748 static Aml
*aml_word_as_desc(AmlResourceType type
, AmlMinFixed min_fixed
,
749 AmlMaxFixed max_fixed
, AmlDecode dec
,
750 uint16_t addr_gran
, uint16_t addr_min
,
751 uint16_t addr_max
, uint16_t addr_trans
,
752 uint16_t len
, uint8_t type_flags
)
754 Aml
*var
= aml_alloc();
756 build_append_byte(var
->buf
, 0x88); /* Word Address Space Descriptor */
757 /* minimum length since we do not encode optional fields */
758 build_append_byte(var
->buf
, 0x0D);
759 build_append_byte(var
->buf
, 0x0);
762 aml_as_desc_header(type
, min_fixed
, max_fixed
, dec
, type_flags
));
763 build_append_int_noprefix(var
->buf
, addr_gran
, sizeof(addr_gran
));
764 build_append_int_noprefix(var
->buf
, addr_min
, sizeof(addr_min
));
765 build_append_int_noprefix(var
->buf
, addr_max
, sizeof(addr_max
));
766 build_append_int_noprefix(var
->buf
, addr_trans
, sizeof(addr_trans
));
767 build_append_int_noprefix(var
->buf
, len
, sizeof(len
));
771 /* ACPI 1.0b: 6.4.3.5.3 DWord Address Space Descriptor */
772 static Aml
*aml_dword_as_desc(AmlResourceType type
, AmlMinFixed min_fixed
,
773 AmlMaxFixed max_fixed
, AmlDecode dec
,
774 uint32_t addr_gran
, uint32_t addr_min
,
775 uint32_t addr_max
, uint32_t addr_trans
,
776 uint32_t len
, uint8_t type_flags
)
778 Aml
*var
= aml_alloc();
780 build_append_byte(var
->buf
, 0x87); /* DWord Address Space Descriptor */
781 /* minimum length since we do not encode optional fields */
782 build_append_byte(var
->buf
, 23);
783 build_append_byte(var
->buf
, 0x0);
787 aml_as_desc_header(type
, min_fixed
, max_fixed
, dec
, type_flags
));
788 build_append_int_noprefix(var
->buf
, addr_gran
, sizeof(addr_gran
));
789 build_append_int_noprefix(var
->buf
, addr_min
, sizeof(addr_min
));
790 build_append_int_noprefix(var
->buf
, addr_max
, sizeof(addr_max
));
791 build_append_int_noprefix(var
->buf
, addr_trans
, sizeof(addr_trans
));
792 build_append_int_noprefix(var
->buf
, len
, sizeof(len
));
796 /* ACPI 1.0b: 6.4.3.5.1 QWord Address Space Descriptor */
797 static Aml
*aml_qword_as_desc(AmlResourceType type
, AmlMinFixed min_fixed
,
798 AmlMaxFixed max_fixed
, AmlDecode dec
,
799 uint64_t addr_gran
, uint64_t addr_min
,
800 uint64_t addr_max
, uint64_t addr_trans
,
801 uint64_t len
, uint8_t type_flags
)
803 Aml
*var
= aml_alloc();
805 build_append_byte(var
->buf
, 0x8A); /* QWord Address Space Descriptor */
806 /* minimum length since we do not encode optional fields */
807 build_append_byte(var
->buf
, 0x2B);
808 build_append_byte(var
->buf
, 0x0);
811 aml_as_desc_header(type
, min_fixed
, max_fixed
, dec
, type_flags
));
812 build_append_int_noprefix(var
->buf
, addr_gran
, sizeof(addr_gran
));
813 build_append_int_noprefix(var
->buf
, addr_min
, sizeof(addr_min
));
814 build_append_int_noprefix(var
->buf
, addr_max
, sizeof(addr_max
));
815 build_append_int_noprefix(var
->buf
, addr_trans
, sizeof(addr_trans
));
816 build_append_int_noprefix(var
->buf
, len
, sizeof(len
));
821 * ACPI 1.0b: 6.4.3.5.6 ASL Macros for WORD Address Descriptor
823 * More verbose description at:
824 * ACPI 5.0: 19.5.141 WordBusNumber (Word Bus Number Resource Descriptor Macro)
826 Aml
*aml_word_bus_number(AmlMinFixed min_fixed
, AmlMaxFixed max_fixed
,
827 AmlDecode dec
, uint16_t addr_gran
,
828 uint16_t addr_min
, uint16_t addr_max
,
829 uint16_t addr_trans
, uint16_t len
)
832 return aml_word_as_desc(aml_bus_number_range
, min_fixed
, max_fixed
, dec
,
833 addr_gran
, addr_min
, addr_max
, addr_trans
, len
, 0);
837 * ACPI 1.0b: 6.4.3.5.6 ASL Macros for WORD Address Descriptor
839 * More verbose description at:
840 * ACPI 5.0: 19.5.142 WordIO (Word IO Resource Descriptor Macro)
842 Aml
*aml_word_io(AmlMinFixed min_fixed
, AmlMaxFixed max_fixed
,
843 AmlDecode dec
, AmlISARanges isa_ranges
,
844 uint16_t addr_gran
, uint16_t addr_min
,
845 uint16_t addr_max
, uint16_t addr_trans
,
849 return aml_word_as_desc(aml_io_range
, min_fixed
, max_fixed
, dec
,
850 addr_gran
, addr_min
, addr_max
, addr_trans
, len
,
855 * ACPI 1.0b: 6.4.3.5.4 ASL Macros for DWORD Address Space Descriptor
857 * More verbose description at:
858 * ACPI 5.0: 19.5.34 DWordMemory (DWord Memory Resource Descriptor Macro)
860 Aml
*aml_dword_memory(AmlDecode dec
, AmlMinFixed min_fixed
,
861 AmlMaxFixed max_fixed
, AmlCacheble cacheable
,
862 AmlReadAndWrite read_and_write
,
863 uint32_t addr_gran
, uint32_t addr_min
,
864 uint32_t addr_max
, uint32_t addr_trans
,
867 uint8_t flags
= read_and_write
| (cacheable
<< 1);
869 return aml_dword_as_desc(aml_memory_range
, min_fixed
, max_fixed
,
870 dec
, addr_gran
, addr_min
, addr_max
,
871 addr_trans
, len
, flags
);
875 * ACPI 1.0b: 6.4.3.5.2 ASL Macros for QWORD Address Space Descriptor
877 * More verbose description at:
878 * ACPI 5.0: 19.5.102 QWordMemory (QWord Memory Resource Descriptor Macro)
880 Aml
*aml_qword_memory(AmlDecode dec
, AmlMinFixed min_fixed
,
881 AmlMaxFixed max_fixed
, AmlCacheble cacheable
,
882 AmlReadAndWrite read_and_write
,
883 uint64_t addr_gran
, uint64_t addr_min
,
884 uint64_t addr_max
, uint64_t addr_trans
,
887 uint8_t flags
= read_and_write
| (cacheable
<< 1);
889 return aml_qword_as_desc(aml_memory_range
, min_fixed
, max_fixed
,
890 dec
, addr_gran
, addr_min
, addr_max
,
891 addr_trans
, len
, flags
);