Пример #1
0
void aml_append(Aml *parent_ctx, Aml *child)
{
    GArray *buf = build_alloc_array();
    build_append_array(buf, child->buf);

    switch (child->block_flags) {
    case AML_OPCODE:
        build_append_byte(parent_ctx->buf, child->op);
        break;
    case AML_EXT_PACKAGE:
        build_extop_package(buf, child->op);
        break;
    case AML_PACKAGE:
        build_package(buf, child->op);
        break;
    case AML_RES_TEMPLATE:
        build_append_byte(buf, 0x79); /* EndTag */
        /*
         * checksum operations are treated as succeeded if checksum
         * field is zero. [ACPI Spec 1.0b, 6.4.2.8 End Tag]
         */
        build_append_byte(buf, 0);
        /* fall through, to pack resources in buffer */
    case AML_BUFFER:
        build_buffer(buf, child->op);
        break;
    case AML_NO_OPCODE:
        break;
    default:
        assert(0);
        break;
    }
    build_append_array(parent_ctx->buf, buf);
    build_free_array(buf);
}
Пример #2
0
/* ACPI 1.0b: 16.2.6.3 Debug Objects Encoding: DebugObj */
Aml *aml_debug(void)
{
    Aml *var = aml_alloc();
    build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
    build_append_byte(var->buf, 0x31); /* DebugOp */
    return var;
}
static void build_append_value(GArray *table, uint32_t value, int size)
{
    uint8_t prefix;
    int i;

    switch (size) {
    case 1:
        prefix = 0x0A; /* BytePrefix */
        break;
    case 2:
        prefix = 0x0B; /* WordPrefix */
        break;
    case 4:
        prefix = 0x0C; /* DWordPrefix */
        break;
    default:
        assert(0);
        return;
    }
    build_append_byte(table, prefix);
    for (i = 0; i < size; ++i) {
        build_append_byte(table, value & 0xFF);
        value = value >> 8;
    }
}
Пример #4
0
/*
 * ACPI 5.0: 6.4.3.6 Extended Interrupt Descriptor
 * Type 1, Large Item Name 0x9
 */
Aml *aml_interrupt(AmlConsumerAndProducer con_and_pro,
                   AmlLevelAndEdge level_and_edge,
                   AmlActiveHighAndLow high_and_low, AmlShared shared,
                   uint32_t *irq_list, uint8_t irq_count)
{
    int i;
    Aml *var = aml_alloc();
    uint8_t irq_flags = con_and_pro | (level_and_edge << 1)
                        | (high_and_low << 2) | (shared << 3);
    const int header_bytes_in_len = 2;
    uint16_t len = header_bytes_in_len + irq_count * sizeof(uint32_t);

    assert(irq_count > 0);

    build_append_byte(var->buf, 0x89); /* Extended irq descriptor */
    build_append_byte(var->buf, len & 0xFF); /* Length, bits[7:0] */
    build_append_byte(var->buf, len >> 8); /* Length, bits[15:8] */
    build_append_byte(var->buf, irq_flags); /* Interrupt Vector Information. */
    build_append_byte(var->buf, irq_count);   /* Interrupt table length */

    /* Interrupt Number List */
    for (i = 0; i < irq_count; i++) {
        build_append_int_noprefix(var->buf, irq_list[i], 4);
    }
    return var;
}
Пример #5
0
/* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefSleep */
Aml *aml_sleep(uint64_t msec)
{
    Aml *var = aml_alloc();
    build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
    build_append_byte(var->buf, 0x22); /* SleepOp */
    aml_append(var, aml_int(msec));
    return var;
}
Пример #6
0
/* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefRelease */
Aml *aml_release(Aml *mutex)
{
    Aml *var = aml_alloc();
    build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
    build_append_byte(var->buf, 0x27); /* ReleaseOp */
    aml_append(var, mutex);
    return var;
}
Пример #7
0
/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefAcquire */
Aml *aml_acquire(Aml *mutex, uint16_t timeout)
{
    Aml *var = aml_alloc();
    build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
    build_append_byte(var->buf, 0x23); /* AcquireOp */
    aml_append(var, mutex);
    build_append_int_noprefix(var->buf, timeout, sizeof(timeout));
    return var;
}
Пример #8
0
/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefMutex */
Aml *aml_mutex(const char *name, uint8_t sync_level)
{
    Aml *var = aml_alloc();
    build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
    build_append_byte(var->buf, 0x01); /* MutexOp */
    build_append_namestring(var->buf, "%s", name);
    assert(!(sync_level & 0xF0));
    build_append_byte(var->buf, sync_level);
    return var;
}
Пример #9
0
/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefCreateField */
Aml *aml_create_field(Aml *srcbuf, Aml *bit_index, Aml *num_bits,
                      const char *name)
{
    Aml *var = aml_alloc();
    build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
    build_append_byte(var->buf, 0x13); /* CreateFieldOp */
    aml_append(var, srcbuf);
    aml_append(var, bit_index);
    aml_append(var, num_bits);
    build_append_namestring(var->buf, "%s", name);
    return var;
}
Пример #10
0
/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefOpRegion */
Aml *aml_operation_region(const char *name, AmlRegionSpace rs,
                          Aml *offset, uint32_t len)
{
    Aml *var = aml_alloc();
    build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
    build_append_byte(var->buf, 0x80); /* OpRegionOp */
    build_append_namestring(var->buf, "%s", name);
    build_append_byte(var->buf, rs);
    aml_append(var, offset);
    build_append_int(var->buf, len);
    return var;
}
Пример #11
0
/* ACPI 1.0b: 6.4.2.2 DMA Format/6.4.2.2.1 ASL Macro for DMA Descriptor */
Aml *aml_dma(AmlDmaType typ, AmlDmaBusMaster bm, AmlTransferSize sz,
             uint8_t channel)
{
    Aml *var = aml_alloc();
    uint8_t flags = sz | bm << 2 | typ << 5;

    assert(channel < 8);
    build_append_byte(var->buf, 0x2A);    /* Byte 0: DMA Descriptor */
    build_append_byte(var->buf, 1U << channel); /* Byte 1: _DMA - DmaChannel */
    build_append_byte(var->buf, flags);   /* Byte 2 */
    return var;
}
Пример #12
0
/* ACPI 1.0b: 6.4.3.5.5 Word Address Space Descriptor: bytes 3-5 */
static Aml *aml_as_desc_header(AmlResourceType type, AmlMinFixed min_fixed,
                               AmlMaxFixed max_fixed, AmlDecode dec,
                               uint8_t type_flags)
{
    uint8_t flags = max_fixed | min_fixed | dec;
    Aml *var = aml_alloc();

    build_append_byte(var->buf, type);
    build_append_byte(var->buf, flags);
    build_append_byte(var->buf, type_flags); /* Type Specific Flags */
    return var;
}
Пример #13
0
/*
 * ACPI 1.0b: 6.4.2.1.1 ASL Macro for IRQ Descriptor
 *
 * More verbose description at:
 * ACPI 5.0: 19.5.64 IRQNoFlags (Interrupt Resource Descriptor Macro)
 *           6.4.2.1 IRQ Descriptor
 */
Aml *aml_irq_no_flags(uint8_t irq)
{
    uint16_t irq_mask;
    Aml *var = aml_alloc();

    assert(irq < 16);
    build_append_byte(var->buf, 0x22); /* IRQ descriptor 2 byte form */

    irq_mask = 1U << irq;
    build_append_byte(var->buf, irq_mask & 0xFF); /* IRQ mask bits[7:0] */
    build_append_byte(var->buf, irq_mask >> 8); /* IRQ mask bits[15:8] */
    return var;
}
Пример #14
0
/*
 * ACPI 2.0b: 16.2.3.6.4.3  Unicode Macro (Convert Ascii String To Unicode)
 */
Aml *aml_unicode(const char *str)
{
    int i = 0;
    Aml *var = aml_bundle(0x11 /* BufferOp */, AML_BUFFER);

    do {
        build_append_byte(var->buf, str[i]);
        build_append_byte(var->buf, 0);
        i++;
    } while (i <= strlen(str));

    return var;
}
Пример #15
0
/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefProcessor */
Aml *aml_processor(uint8_t proc_id, uint32_t pblk_addr, uint8_t pblk_len,
                   const char *name_format, ...)
{
    va_list ap;
    Aml *var = aml_bundle(0x83 /* ProcessorOp */, AML_EXT_PACKAGE);
    va_start(ap, name_format);
    build_append_namestringv(var->buf, name_format, ap);
    va_end(ap);
    build_append_byte(var->buf, proc_id); /* ProcID */
    build_append_int_noprefix(var->buf, pblk_addr, sizeof(pblk_addr));
    build_append_byte(var->buf, pblk_len); /* PblkLen */
    return var;
}
static void build_append_int(GArray *table, uint32_t value)
{
    if (value == 0x00) {
        build_append_byte(table, 0x00); /* ZeroOp */
    } else if (value == 0x01) {
        build_append_byte(table, 0x01); /* OneOp */
    } else if (value <= 0xFF) {
        build_append_value(table, value, 1);
    } else if (value <= 0xFFFFF) {
        build_append_value(table, value, 2);
    } else {
        build_append_value(table, value, 4);
    }
}
Пример #17
0
/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefBuffer
 * Pass byte_list as NULL to request uninitialized buffer to reserve space.
 */
Aml *aml_buffer(int buffer_size, uint8_t *byte_list)
{
    int i;
    Aml *var = aml_bundle(0x11 /* BufferOp */, AML_BUFFER);

    for (i = 0; i < buffer_size; i++) {
        if (byte_list == NULL) {
            build_append_byte(var->buf, 0x0);
        } else {
            build_append_byte(var->buf, byte_list[i]);
        }
    }

    return var;
}
Пример #18
0
/* ACPI 2.0a: 17.2.4.4 Type 2 Opcodes Encoding: DefToInteger */
Aml *aml_to_integer(Aml *arg)
{
    Aml *var = aml_opcode(0x99 /* ToIntegerOp */);
    aml_append(var, arg);
    build_append_byte(var->buf, 0x00 /* NullNameOp */);
    return var;
}
Пример #19
0
/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefField */
Aml *aml_field(const char *name, AmlFieldFlags flags)
{
    Aml *var = aml_bundle(0x81 /* FieldOp */, AML_EXT_PACKAGE);
    build_append_namestring(var->buf, "%s", name);
    build_append_byte(var->buf, flags);
    return var;
}
Пример #20
0
/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefMethod */
Aml *aml_method(const char *name, int arg_count)
{
    Aml *var = aml_bundle(0x14 /* MethodOp */, AML_PACKAGE);
    build_append_namestring(var->buf, "%s", name);
    build_append_byte(var->buf, arg_count); /* MethodFlags: ArgCount */
    return var;
}
Пример #21
0
/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: ReservedField */
Aml *aml_reserved_field(unsigned length)
{
    Aml *var = aml_alloc();
    /* ReservedField  := 0x00 PkgLength */
    build_append_byte(var->buf, 0x00);
    build_append_pkg_length(var->buf, length, false);
    return var;
}
Пример #22
0
/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefAnd */
Aml *aml_and(Aml *arg1, Aml *arg2)
{
    Aml *var = aml_opcode(0x7B /* AndOp */);
    aml_append(var, arg1);
    aml_append(var, arg2);
    build_append_byte(var->buf, 0x00 /* NullNameOp */);
    return var;
}
static GArray *build_alloc_method(const char *name, uint8_t arg_count)
{
    GArray *method = build_alloc_array();

    build_append_nameseg(method, "%s", name);
    build_append_byte(method, arg_count); /* MethodFlags: ArgCount */

    return method;
}
Пример #24
0
/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLGreaterEqual */
Aml *aml_lgreater_equal(Aml *arg1, Aml *arg2)
{
    /* LGreaterEqualOp := LNotOp LLessOp */
    Aml *var = aml_opcode(0x92 /* LNotOp */);
    build_append_byte(var->buf, 0x95 /* LLessOp */);
    aml_append(var, arg1);
    aml_append(var, arg2);
    return var;
}
Пример #25
0
void build_append_int_noprefix(GArray *table, uint64_t value, int size)
{
    int i;

    for (i = 0; i < size; ++i) {
        build_append_byte(table, value & 0xFF);
        value = value >> 8;
    }
}
Пример #26
0
/*
 * Build NAME(XXXX, 0x00000000) where 0x00000000 is encoded as a dword,
 * and return the offset to 0x00000000 for runtime patching.
 *
 * Warning: runtime patching is best avoided. Only use this as
 * a replacement for DataTableRegion (for guests that don't
 * support it).
 */
int
build_append_named_dword(GArray *array, const char *name_format, ...)
{
    int offset;
    va_list ap;

    build_append_byte(array, 0x08); /* NameOp */
    va_start(ap, name_format);
    build_append_namestringv(array, name_format, ap);
    va_end(ap);

    build_append_byte(array, 0x0C); /* DWordPrefix */

    offset = array->len;
    build_append_int_noprefix(array, 0x00000000, 4);
    assert(array->len == offset + 4);

    return offset;
}
Пример #27
0
/* ACPI 2.0a: 17.2.4.4 Type 2 Opcodes Encoding: DefToBuffer */
Aml *aml_to_buffer(Aml *src, Aml *dst)
{
    Aml *var = aml_opcode(0x96 /* ToBufferOp */);
    aml_append(var, src);
    if (dst) {
        aml_append(var, dst);
    } else {
        build_append_byte(var->buf, 0x00 /* NullNameOp */);
    }
    return var;
}
Пример #28
0
/* ACPI 2.0a: 17.2.4.4 Type 2 Opcodes Encoding: DefToHexString */
Aml *aml_to_hexstring(Aml *src, Aml *dst)
{
    Aml *var = aml_opcode(0x98 /* ToHexStringOp */);
    aml_append(var, src);
    if (dst) {
        aml_append(var, dst);
    } else {
        build_append_byte(var->buf, 0x00 /* NullNameOp */);
    }
    return var;
}
Пример #29
0
/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefField */
Aml *aml_field(const char *name, AmlAccessType type, AmlLockRule lock,
               AmlUpdateRule rule)
{
    Aml *var = aml_bundle(0x81 /* FieldOp */, AML_EXT_PACKAGE);
    uint8_t flags = rule << 5 | type;

    flags |= lock << 4; /* LockRule at 4 bit offset */

    build_append_namestring(var->buf, "%s", name);
    build_append_byte(var->buf, flags);
    return var;
}
static void build_append_notify_target_ifequal(GArray *method,
                                               GArray *target_name,
                                               uint32_t value, int size)
{
    GArray *notify = build_alloc_array();
    uint8_t op = 0xA0; /* IfOp */

    build_append_byte(notify, 0x93); /* LEqualOp */
    build_append_byte(notify, 0x68); /* Arg0Op */
    build_append_value(notify, value, size);
    build_append_byte(notify, 0x86); /* NotifyOp */
    build_append_array(notify, target_name);
    build_append_byte(notify, 0x69); /* Arg1Op */

    /* Pack it up */
    build_package(notify, op, 1);

    build_append_array(method, notify);

    build_free_array(notify);
}