Commit ef48a8ce authored by Corey Minyard's avatar Corey Minyard
Browse files

acpi: Add i2c serial bus CRS handling



This will be required for getting IPMI SSIF (SMBus interface) into
the ACPI tables.

Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: default avatarCorey Minyard <cminyard@mvista.com>
parent 38033052
Loading
Loading
Loading
Loading
+40 −0
Original line number Diff line number Diff line
@@ -1874,3 +1874,43 @@ build_hdr:
    build_header(linker, tbl, (void *)(tbl->data + fadt_start),
                 "FACP", tbl->len - fadt_start, f->rev, oem_id, oem_table_id);
}

/* ACPI 5.0: 6.4.3.8.2 Serial Bus Connection Descriptors */
static Aml *aml_serial_bus_device(uint8_t serial_bus_type, uint8_t flags,
                                  uint16_t type_flags,
                                  uint8_t revid, uint16_t data_length,
                                  uint16_t resource_source_len)
{
    Aml *var = aml_alloc();
    uint16_t length = data_length + resource_source_len + 9;

    build_append_byte(var->buf, 0x8e); /* Serial Bus Connection Descriptor */
    build_append_int_noprefix(var->buf, length, sizeof(length));
    build_append_byte(var->buf, 1);    /* Revision ID */
    build_append_byte(var->buf, 0);    /* Resource Source Index */
    build_append_byte(var->buf, serial_bus_type); /* Serial Bus Type */
    build_append_byte(var->buf, flags); /* General Flags */
    build_append_int_noprefix(var->buf, type_flags, /* Type Specific Flags */
                              sizeof(type_flags));
    build_append_byte(var->buf, revid); /* Type Specification Revision ID */
    build_append_int_noprefix(var->buf, data_length, sizeof(data_length));

    return var;
}

/* ACPI 5.0: 6.4.3.8.2.1 I2C Serial Bus Connection Resource Descriptor */
Aml *aml_i2c_serial_bus_device(uint16_t address, const char *resource_source)
{
    uint16_t resource_source_len = strlen(resource_source) + 1;
    Aml *var = aml_serial_bus_device(AML_SERIAL_BUS_TYPE_I2C, 0, 0, 1,
                                     6, resource_source_len);

    /* Connection Speed.  Just set to 100K for now, it doesn't really matter. */
    build_append_int_noprefix(var->buf, 100000, 4);
    build_append_int_noprefix(var->buf, address, sizeof(address));

    /* This is a string, not a name, so just copy it directly in. */
    g_array_append_vals(var->buf, resource_source, resource_source_len);

    return var;
}
+18 −0
Original line number Diff line number Diff line
@@ -223,6 +223,23 @@ struct AcpiBuildTables {
    BIOSLinker *linker;
} AcpiBuildTables;

/*
 * ACPI 5.0: 6.4.3.8.2 Serial Bus Connection Descriptors
 * Serial Bus Type
 */
#define AML_SERIAL_BUS_TYPE_I2C  1
#define AML_SERIAL_BUS_TYPE_SPI  2
#define AML_SERIAL_BUS_TYPE_UART 3

/*
 * ACPI 5.0: 6.4.3.8.2 Serial Bus Connection Descriptors
 * General Flags
 */
/* Slave Mode */
#define AML_SERIAL_BUS_FLAG_MASTER_DEVICE       (1 << 0)
/* Consumer/Producer */
#define AML_SERIAL_BUS_FLAG_CONSUME_ONLY        (1 << 1)

/**
 * init_aml_allocator:
 *
@@ -347,6 +364,7 @@ Aml *aml_qword_memory(AmlDecode dec, AmlMinFixed min_fixed,
Aml *aml_dma(AmlDmaType typ, AmlDmaBusMaster bm, AmlTransferSize sz,
             uint8_t channel);
Aml *aml_sleep(uint64_t msec);
Aml *aml_i2c_serial_bus_device(uint16_t address, const char *resource_source);

/* Block AML object primitives */
Aml *aml_scope(const char *name_format, ...) GCC_FMT_ATTR(1, 2);