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 };
Hello Felix Held, build bot (Jenkins),
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/37639
to look at the new patch set (#2).
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.
Tested on Linux 5.2 using the Aspeed SSDT generator.
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/2
Felix Held has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/37639 )
Change subject: superio/common/conf_mode: Add op to write SSDT ......................................................................
Patch Set 2:
(3 comments)
https://review.coreboot.org/c/coreboot/+/37639/2/src/include/device/pnp.h File src/include/device/pnp.h:
https://review.coreboot.org/c/coreboot/+/37639/2/src/include/device/pnp.h@73 PS2, Line 73: 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); should this be guarded by #if CONFIG(HAVE_ACPI_TABLES) to be consistent with device_operations in device.h? without having looked into the details i wonder though, why some members of other structs are only present when HAVE_ACPI_TABLES is set.
https://review.coreboot.org/c/coreboot/+/37639/2/src/include/device/pnp.h@78 PS2, Line 78: const char *idx, const char *data maybe add a comment that those two parameters correspond to the index and data register of the sio config register pair; wasn't obvious to me before having a look at the actual implementation
https://review.coreboot.org/c/coreboot/+/37639/2/src/superio/common/conf_mod... File src/superio/common/conf_mode.c:
https://review.coreboot.org/c/coreboot/+/37639/2/src/superio/common/conf_mod... PS2, Line 181: 2 0x02 would be more consistent here; same thing a few lines below
Hello Felix Held, build bot (Jenkins),
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/37639
to look at the new patch set (#3).
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.
Tested on Linux 5.2 using the Aspeed SSDT generator.
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, 171 insertions(+), 1 deletion(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/39/37639/3
Patrick Rudolph has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/37639 )
Change subject: superio/common/conf_mode: Add op to write SSDT ......................................................................
Patch Set 3:
(3 comments)
https://review.coreboot.org/c/coreboot/+/37639/2/src/include/device/pnp.h File src/include/device/pnp.h:
https://review.coreboot.org/c/coreboot/+/37639/2/src/include/device/pnp.h@73 PS2, Line 73: 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);
should this be guarded by #if CONFIG(HAVE_ACPI_TABLES) to be consistent with device_operations in de […]
Done
https://review.coreboot.org/c/coreboot/+/37639/2/src/include/device/pnp.h@78 PS2, Line 78: const char *idx, const char *data
maybe add a comment that those two parameters correspond to the index and data register of the sio c […]
Done
https://review.coreboot.org/c/coreboot/+/37639/2/src/superio/common/conf_mod... File src/superio/common/conf_mode.c:
https://review.coreboot.org/c/coreboot/+/37639/2/src/superio/common/conf_mod... PS2, Line 181: 2
0x02 would be more consistent here; same thing a few lines below
Done
Felix Held has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/37639 )
Change subject: superio/common/conf_mode: Add op to write SSDT ......................................................................
Patch Set 3: Code-Review+2
Felix Held has submitted this change. ( 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.
Tested on Linux 5.2 using the Aspeed SSDT generator.
Change-Id: I14b55b885f1c384536bafafed39ad399639868e4 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com Reviewed-on: https://review.coreboot.org/c/coreboot/+/37639 Tested-by: build bot (Jenkins) no-reply@coreboot.org Reviewed-by: Felix Held felix-coreboot@felixheld.de --- M src/device/pnp_device.c M src/include/device/pnp.h M src/superio/common/conf_mode.c 3 files changed, 171 insertions(+), 1 deletion(-)
Approvals: build bot (Jenkins): Verified Felix Held: Looks good to me, approved
diff --git a/src/device/pnp_device.c b/src/device/pnp_device.c index c58b375..81aa889 100644 --- a/src/device/pnp_device.c +++ b/src/device/pnp_device.c @@ -31,6 +31,19 @@ dev->ops->ops_pnp_mode->exit_conf_mode(dev); }
+#if CONFIG(HAVE_ACPI_TABLES) +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); +} +#endif + /* 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 d459fd2..800bcc0 100644 --- a/src/include/device/pnp.h +++ b/src/include/device/pnp.h @@ -67,13 +67,34 @@ 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); +#if CONFIG(HAVE_ACPI_TABLES) + /* + * Generates ASL code to enter/exit config mode. + * + * @param idx The ACPI name of the SuperIO index port register. eg. 'INDX'. + * @param data The ACPI name of the SuperIO data port register. eg. 'DATA'. + */ + 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); +#endif }; void pnp_enter_conf_mode(struct device *dev); void pnp_exit_conf_mode(struct device *dev); - +#if CONFIG(HAVE_ACPI_TABLES) +/* + * Generates ASL code to enter/exit config mode if supported. + * The calling code has to place this within an ASL MethodOP. + * + * @param idx The ACPI name of the SuperIO index port register. eg. 'INDX'. + * @param data The ACPI name of the SuperIO data port register. eg. 'DATA'. + */ +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); +#endif /* PNP indexed I/O operations */
/* diff --git a/src/superio/common/conf_mode.c b/src/superio/common/conf_mode.c index 8ba1cdd..1e62285 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,173 @@ 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(0x02); + acpigen_emit_namestring(idx); + + acpigen_write_store(); + acpigen_write_byte(0x02); + 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 };