diff --git a/src/mainboard/google/slippy/acpi_tables.c b/src/mainboard/google/slippy/acpi_tables.c index 51b230c58d..7a3ccea50c 100644 --- a/src/mainboard/google/slippy/acpi_tables.c +++ b/src/mainboard/google/slippy/acpi_tables.c @@ -279,6 +279,13 @@ unsigned long write_acpi_tables(unsigned long start) acpi_add_table(rsdp, ssdt); ALIGN_CURRENT; + printk(BIOS_DEBUG, "ACPI: * SSDT2\n"); + ssdt = (acpi_header_t *)current; + acpi_create_serialio_ssdt(ssdt); + current += ssdt->length; + acpi_add_table(rsdp, ssdt); + ALIGN_CURRENT; + printk(BIOS_DEBUG, "current = %lx\n", current); printk(BIOS_INFO, "ACPI: done.\n"); return current; diff --git a/src/southbridge/intel/lynxpoint/acpi.c b/src/southbridge/intel/lynxpoint/acpi.c index 4118b9df6d..ccf43231e2 100644 --- a/src/southbridge/intel/lynxpoint/acpi.c +++ b/src/southbridge/intel/lynxpoint/acpi.c @@ -18,9 +18,13 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include +#include +#include #include #include #include "pch.h" +#include "nvs.h" void acpi_create_intel_hpet(acpi_hpet_t * hpet) { @@ -53,3 +57,41 @@ void acpi_create_intel_hpet(acpi_hpet_t * hpet) acpi_checksum((void *) hpet, sizeof(acpi_hpet_t)); } +static int acpi_create_serialio_ssdt_entry(int id, global_nvs_t *gnvs) +{ + char sio_name[5] = {}; + sprintf(sio_name, "S%1uEN", id); + return acpigen_write_name_byte(sio_name, gnvs->s0b[id] ? 1 : 0); +} + +void acpi_create_serialio_ssdt(acpi_header_t *ssdt) +{ + unsigned long current = (unsigned long)ssdt + sizeof(acpi_header_t); + global_nvs_t *gnvs = cbmem_find(CBMEM_ID_ACPI_GNVS); + int id, len = 0; + + if (!gnvs) + return; + + /* Fill the SSDT header */ + memset((void *)ssdt, 0, sizeof(acpi_header_t)); + memcpy(&ssdt->signature, "SSDT", 4); + ssdt->revision = 2; + memcpy(&ssdt->oem_id, OEM_ID, 6); + memcpy(&ssdt->oem_table_id, ACPI_TABLE_CREATOR, 8); + ssdt->oem_revision = 42; + memcpy(&ssdt->asl_compiler_id, ASLC, 4); + ssdt->asl_compiler_revision = 42; + ssdt->length = sizeof(acpi_header_t); + acpigen_set_current((char *) current); + + /* Fill the SSDT with an entry for each SerialIO device */ + for (id = 0; id < 8; id++) + len += acpi_create_serialio_ssdt_entry(id, gnvs); + acpigen_patch_len(len-1); + + /* (Re)calculate length and checksum. */ + current = (unsigned long)acpigen_get_current(); + ssdt->length = current - (unsigned long)ssdt; + ssdt->checksum = acpi_checksum((void *)ssdt, ssdt->length); +} diff --git a/src/southbridge/intel/lynxpoint/acpi/serialio.asl b/src/southbridge/intel/lynxpoint/acpi/serialio.asl index 03f6974a38..4c0d36bcc6 100644 --- a/src/southbridge/intel/lynxpoint/acpi/serialio.asl +++ b/src/southbridge/intel/lynxpoint/acpi/serialio.asl @@ -24,6 +24,17 @@ // Serial IO Device BAR0 and BAR1 is 4KB #define SIO_BAR_LEN 0x1000 +// This is defined in SSDT2 which is generated at boot based +// on whether or not the device is enabled in ACPI mode. +External(\S0EN) +External(\S1EN) +External(\S2EN) +External(\S3EN) +External(\S4EN) +External(\S5EN) +External(\S6EN) +External(\S7EN) + // Serial IO Resource Consumption for BAR1 Device (SIOR) { @@ -143,7 +154,7 @@ Device (SDMA) Method (_STA, 0, NotSerialized) { - If (LEqual (\S0B0, 0)) { + If (LEqual (\S0EN, 0)) { Return (0x0) } Else { Return (0xF) @@ -194,7 +205,7 @@ Device (I2C0) Method (_STA, 0, NotSerialized) { - If (LEqual (\S1B0, 0)) { + If (LEqual (\S1EN, 0)) { Return (0x0) } Else { Return (0xF) @@ -245,7 +256,7 @@ Device (I2C1) Method (_STA, 0, NotSerialized) { - If (LEqual (\S2B0, 0)) { + If (LEqual (\S2EN, 0)) { Return (0x0) } Else { Return (0xF) @@ -283,7 +294,7 @@ Device (SPI0) Method (_STA, 0, NotSerialized) { - If (LEqual (\S3B0, 0)) { + If (LEqual (\S3EN, 0)) { Return (0x0) } Else { Return (0xF) @@ -334,7 +345,7 @@ Device (SPI1) Method (_STA, 0, NotSerialized) { - If (LEqual (\S4B0, 0)) { + If (LEqual (\S4EN, 0)) { Return (0x0) } Else { Return (0xF) @@ -385,7 +396,7 @@ Device (UAR0) Method (_STA, 0, NotSerialized) { - If (LEqual (\S5B0, 0)) { + If (LEqual (\S5EN, 0)) { Return (0x0) } Else { Return (0xF) @@ -423,7 +434,7 @@ Device (UAR1) Method (_STA, 0, NotSerialized) { - If (LEqual (\S6B0, 0)) { + If (LEqual (\S6EN, 0)) { Return (0x0) } Else { Return (0xF) @@ -461,7 +472,7 @@ Device (SDIO) Method (_STA, 0, NotSerialized) { - If (LEqual (\S7B0, 0)) { + If (LEqual (\S7EN, 0)) { Return (0x0) } Else { Return (0xF) diff --git a/src/southbridge/intel/lynxpoint/pch.h b/src/southbridge/intel/lynxpoint/pch.h index 58b07d16cc..ca1d8b1b68 100644 --- a/src/southbridge/intel/lynxpoint/pch.h +++ b/src/southbridge/intel/lynxpoint/pch.h @@ -167,6 +167,7 @@ void pch_iobp_update(u32 address, u32 andvalue, u32 orvalue); void pch_log_state(void); #endif void acpi_create_intel_hpet(acpi_hpet_t * hpet); +void acpi_create_serialio_ssdt(acpi_header_t *ssdt); /* These helpers are for performing SMM relocation. */ void southbridge_trigger_smi(void);