summaryrefslogtreecommitdiff
path: root/src/southbridge/intel
diff options
context:
space:
mode:
Diffstat (limited to 'src/southbridge/intel')
-rw-r--r--src/southbridge/intel/lynxpoint/acpi.c42
-rw-r--r--src/southbridge/intel/lynxpoint/acpi/serialio.asl27
-rw-r--r--src/southbridge/intel/lynxpoint/pch.h1
3 files changed, 62 insertions, 8 deletions
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 <arch/acpi.h>
+#include <arch/acpigen.h>
+#include <cbmem.h>
#include <types.h>
#include <string.h>
#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);