Patrick Rudolph has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/37639 )
Change subject: superio/common/conf_mode: Add op to write SSDT ......................................................................
superio/common/conf_mode: Add op to write SSDT
Add functions to write ACPI SSDT code for entering and leaving the config mode. To be used by ACPI generators.
Change-Id: I14b55b885f1c384536bafafed39ad399639868e4 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com --- M src/device/pnp_device.c M src/include/device/pnp.h M src/superio/common/conf_mode.c 3 files changed, 153 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/39/37639/1
diff --git a/src/device/pnp_device.c b/src/device/pnp_device.c index 28a45d0..4216a0d 100644 --- a/src/device/pnp_device.c +++ b/src/device/pnp_device.c @@ -32,6 +32,17 @@ dev->ops->ops_pnp_mode->exit_conf_mode(dev); }
+void pnp_ssdt_enter_conf_mode(struct device *dev, const char *idx, const char *data) +{ + if (dev->ops->ops_pnp_mode && dev->ops->ops_pnp_mode->ssdt_enter_conf_mode) + dev->ops->ops_pnp_mode->ssdt_enter_conf_mode(dev, idx, data); +} +void pnp_ssdt_exit_conf_mode(struct device *dev, const char *idx, const char *data) +{ + if (dev->ops->ops_pnp_mode && dev->ops->ops_pnp_mode->ssdt_exit_conf_mode) + dev->ops->ops_pnp_mode->ssdt_exit_conf_mode(dev, idx, data); +} + /* PNP fundamental operations */
void pnp_write_config(struct device *dev, u8 reg, u8 value) diff --git a/src/include/device/pnp.h b/src/include/device/pnp.h index 69a06674..29e6195 100644 --- a/src/include/device/pnp.h +++ b/src/include/device/pnp.h @@ -66,12 +66,17 @@ void pnp_enable_devices(struct device *dev, struct device_operations *ops, unsigned int functions, struct pnp_info *info);
+ struct pnp_mode_ops { void (*enter_conf_mode)(struct device *dev); void (*exit_conf_mode)(struct device *dev); + void (*ssdt_enter_conf_mode)(struct device *dev, const char *idx, const char *data); + void (*ssdt_exit_conf_mode)(struct device *dev, const char *idx, const char *data); }; void pnp_enter_conf_mode(struct device *dev); void pnp_exit_conf_mode(struct device *dev); +void pnp_ssdt_enter_conf_mode(struct device *dev, const char *idx, const char *data); +void pnp_ssdt_exit_conf_mode(struct device *dev, const char *idx, const char *data);
/* PNP indexed I/O operations */
diff --git a/src/superio/common/conf_mode.c b/src/superio/common/conf_mode.c index 8ba1cdd..ad69d22 100644 --- a/src/superio/common/conf_mode.c +++ b/src/superio/common/conf_mode.c @@ -17,6 +17,7 @@ #include <arch/io.h> #include <device/device.h> #include <superio/conf_mode.h> +#include <arch/acpigen.h>
/* Common enter/exit implementations */
@@ -77,38 +78,174 @@ pnp_write_config(dev, 0x02, (1 << 1)); }
+/* Functions for ACPI */ +#if CONFIG(HAVE_ACPI_TABLES) +static void pnp_ssdt_enter_conf_mode_55(struct device *dev, const char *idx, const char *data) +{ + acpigen_write_store(); + acpigen_write_byte(0x55); + acpigen_emit_namestring(idx); + +} + +static void pnp_ssdt_enter_conf_mode_6767(struct device *dev, const char *idx, const char *data) +{ + acpigen_write_store(); + acpigen_write_byte(0x67); + acpigen_emit_namestring(idx); + + acpigen_write_store(); + acpigen_write_byte(0x67); + acpigen_emit_namestring(idx); +} + +static void pnp_ssdt_enter_conf_mode_7777(struct device *dev, const char *idx, const char *data) +{ + acpigen_write_store(); + acpigen_write_byte(0x77); + acpigen_emit_namestring(idx); + + acpigen_write_store(); + acpigen_write_byte(0x77); + acpigen_emit_namestring(idx); +} + +static void pnp_ssdt_enter_conf_mode_8787(struct device *dev, const char *idx, const char *data) +{ + acpigen_write_store(); + acpigen_write_byte(0x87); + acpigen_emit_namestring(idx); + + acpigen_write_store(); + acpigen_write_byte(0x87); + acpigen_emit_namestring(idx); +} + +static void pnp_ssdt_enter_conf_mode_a0a0(struct device *dev, const char *idx, const char *data) +{ + acpigen_write_store(); + acpigen_write_byte(0xa0); + acpigen_emit_namestring(idx); + + acpigen_write_store(); + acpigen_write_byte(0xa0); + acpigen_emit_namestring(idx); + +} + +static void pnp_ssdt_enter_conf_mode_a5a5(struct device *dev, const char *idx, const char *data) +{ + acpigen_write_store(); + acpigen_write_byte(0xa5); + acpigen_emit_namestring(idx); + + acpigen_write_store(); + acpigen_write_byte(0xa5); + acpigen_emit_namestring(idx); +} + +static void pnp_ssdt_enter_conf_mode_870155aa(struct device *dev, + const char *idx, const char *data) +{ + acpigen_write_store(); + acpigen_write_byte(0x87); + acpigen_emit_namestring(idx); + + acpigen_write_store(); + acpigen_write_byte(0x01); + acpigen_emit_namestring(idx); + + acpigen_write_store(); + acpigen_write_byte(0x55); + acpigen_emit_namestring(idx); + + acpigen_write_store(); + if (dev->path.pnp.port == 0x4e) + acpigen_write_byte(0xaa); + else + acpigen_write_byte(0x55); + acpigen_emit_namestring(idx); +} + +static void pnp_ssdt_exit_conf_mode_aa(struct device *dev, const char *idx, const char *data) +{ + acpigen_write_store(); + acpigen_write_byte(0xaa); + acpigen_emit_namestring(idx); +} + +static void pnp_ssdt_exit_conf_mode_0202(struct device *dev, const char *idx, const char *data) +{ + + acpigen_write_store(); + acpigen_write_byte(2); + acpigen_emit_namestring(idx); + + acpigen_write_store(); + acpigen_write_byte(2); + acpigen_emit_namestring(data); +} +#endif
const struct pnp_mode_ops pnp_conf_mode_55_aa = { .enter_conf_mode = pnp_enter_conf_mode_55, .exit_conf_mode = pnp_exit_conf_mode_aa, +#if CONFIG(HAVE_ACPI_TABLES) + .ssdt_enter_conf_mode = pnp_ssdt_enter_conf_mode_55, + .ssdt_exit_conf_mode = pnp_ssdt_exit_conf_mode_aa, +#endif };
const struct pnp_mode_ops pnp_conf_mode_6767_aa = { .enter_conf_mode = pnp_enter_conf_mode_6767, .exit_conf_mode = pnp_exit_conf_mode_aa, +#if CONFIG(HAVE_ACPI_TABLES) + .ssdt_enter_conf_mode = pnp_ssdt_enter_conf_mode_6767, + .ssdt_exit_conf_mode = pnp_ssdt_exit_conf_mode_aa, +#endif };
const struct pnp_mode_ops pnp_conf_mode_7777_aa = { .enter_conf_mode = pnp_enter_conf_mode_7777, .exit_conf_mode = pnp_exit_conf_mode_aa, +#if CONFIG(HAVE_ACPI_TABLES) + .ssdt_enter_conf_mode = pnp_ssdt_enter_conf_mode_7777, + .ssdt_exit_conf_mode = pnp_ssdt_exit_conf_mode_aa, +#endif };
const struct pnp_mode_ops pnp_conf_mode_8787_aa = { .enter_conf_mode = pnp_enter_conf_mode_8787, .exit_conf_mode = pnp_exit_conf_mode_aa, +#if CONFIG(HAVE_ACPI_TABLES) + .ssdt_enter_conf_mode = pnp_ssdt_enter_conf_mode_8787, + .ssdt_exit_conf_mode = pnp_ssdt_exit_conf_mode_aa, +#endif };
const struct pnp_mode_ops pnp_conf_mode_a0a0_aa = { .enter_conf_mode = pnp_enter_conf_mode_a0a0, .exit_conf_mode = pnp_exit_conf_mode_aa, +#if CONFIG(HAVE_ACPI_TABLES) + .ssdt_enter_conf_mode = pnp_ssdt_enter_conf_mode_a0a0, + .ssdt_exit_conf_mode = pnp_ssdt_exit_conf_mode_aa, +#endif };
const struct pnp_mode_ops pnp_conf_mode_a5a5_aa = { .enter_conf_mode = pnp_enter_conf_mode_a5a5, .exit_conf_mode = pnp_exit_conf_mode_aa, +#if CONFIG(HAVE_ACPI_TABLES) + .ssdt_enter_conf_mode = pnp_ssdt_enter_conf_mode_a5a5, + .ssdt_exit_conf_mode = pnp_ssdt_exit_conf_mode_aa, +#endif };
const struct pnp_mode_ops pnp_conf_mode_870155_aa = { .enter_conf_mode = pnp_enter_conf_mode_870155aa, .exit_conf_mode = pnp_exit_conf_mode_0202, +#if CONFIG(HAVE_ACPI_TABLES) + .ssdt_enter_conf_mode = pnp_ssdt_enter_conf_mode_870155aa, + .ssdt_exit_conf_mode = pnp_ssdt_exit_conf_mode_0202, +#endif };