diff options
author | Duncan Laurie <dlaurie@chromium.org> | 2013-05-15 15:03:57 -0700 |
---|---|---|
committer | Stefan Reinauer <stefan.reinauer@coreboot.org> | 2013-11-25 23:28:27 +0100 |
commit | d7cb8d074f4a9e437ed897ac596ca794698b38c9 (patch) | |
tree | 6e940fa98877925ab3f0d52427a3527789ceb753 /src/southbridge/intel/lynxpoint/acpi.c | |
parent | 8d783b84930e2e14e4f70234ea6589acd06557e7 (diff) |
lynxpoint: Change SerialIO device enable reporting to ACPI
In order to report whether coreboot enabled a SerialIO device
in ACPI mode we had been relying on reading NVS in the _STA
method for the SerialIO device.
The ACPI _STA method has restrictions on what it can access
and is unable to access OperationRegions outside its scope
which means it should not be trying to read NVS.
This change adds a new SSDT to the ACPI tables and fills it
with constants that indicate whether or not a device is enabled
in ACPI mode.
The ACPI code is changed to read these variables from the
SSDT and use that instead of trying to query a variable in NVS.
Attempt to use lpt-clk driver to probe the
device clocks for SerialIO devices and see that the kernel
does not complain about accessing the GNVS region.
Change-Id: I8538bee4390daed4ecca679496ab0cb313f174ce
Signed-off-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/51369
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/4170
Tested-by: build bot (Jenkins)
Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
Diffstat (limited to 'src/southbridge/intel/lynxpoint/acpi.c')
-rw-r--r-- | src/southbridge/intel/lynxpoint/acpi.c | 42 |
1 files changed, 42 insertions, 0 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); +} |