[PATCH v3 27/57] x86: acpi: Add PCT and PTC tables

Simon Glass
2020-09-06T21:43:35Z

These are needed for the CPU tables. Add them into an x86-specific file
since we do not support them on sandbox, or include tests.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

(no changes since v1)

Changes in v1:
- Split PCT and PTC tables into a separate patch

arch/x86/include/asm/acpigen.h | 35 +++++++++++++
arch/x86/lib/Makefile | 2 +-
arch/x86/lib/acpigen.c | 96 ++++++++++++++++++++++++++++++++++
3 files changed, 132 insertions(+), 1 deletion(-)
create mode 100644 arch/x86/include/asm/acpigen.h
create mode 100644 arch/x86/lib/acpigen.c

diff --git a/arch/x86/include/asm/acpigen.h b/arch/x86/include/asm/acpigen.h
new file mode 100644
index 00000000000..c531dd61d53
--- /dev/null
+++ b/arch/x86/include/asm/acpigen.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Generation of x86-specific ACPI tables
+ *
+ * Copyright 2020 Google LLC
+ */
+
+#ifndef __ASM_ACPIGEN_H__
+#define __ASM_ACPIGEN_H__
+
+struct acpi_ctx;
+
+/**
+ * acpigen_write_empty_pct() - Write an empty PCT
+ *
+ * See ACPI v6.3 section 8.4.6.1: _PCT (Performance Control)
+ *
+ * This writes an empty table so that CPU performance works as expected
+ *
+ * @ctx: ACPI context pointer
+ */
+void acpigen_write_empty_pct(struct acpi_ctx *ctx);
+
+/**
+ * acpigen_write_empty_ptc() - Write an empty PTC
+ *
+ * See ACPI v6.3 section 8.4.5.1: _PTC (Processor Throttling Control)
+ *
+ * This writes an empty table so that CPU performance works as expected
+ *
+ * @ctx: ACPI context pointer
+ */
+void acpigen_write_empty_ptc(struct acpi_ctx *ctx);
+
+#endif /* __ASM_ACPI_H__ */
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index 1185a88c27c..f04d275dd9a 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -38,7 +38,7 @@ obj-y += sfi.o
obj-y += acpi.o
obj-$(CONFIG_HAVE_ACPI_RESUME) += acpi_s3.o
ifndef CONFIG_QEMU
-obj-$(CONFIG_GENERATE_ACPI_TABLE) += acpi_table.o
+obj-$(CONFIG_GENERATE_ACPI_TABLE) += acpi_table.o acpigen.o
endif
obj-y += tables.o
ifndef CONFIG_SPL_BUILD
diff --git a/arch/x86/lib/acpigen.c b/arch/x86/lib/acpigen.c
new file mode 100644
index 00000000000..ea2ec2a9083
--- /dev/null
+++ b/arch/x86/lib/acpigen.c
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Google LLC
+ */
+
+#include <common.h>
+#include <acpi/acpigen.h>
+#include <acpi/acpi_table.h>
+#include <asm/acpigen.h>
+
+void acpigen_write_empty_pct(struct acpi_ctx *ctx)
+{
+ /*
+ * Name (_PCT, Package (0x02)
+ * {
+ * ResourceTemplate ()
+ * {
+ * Register (FFixedHW,
+ * 0x00, // Bit Width
+ * 0x00, // Bit Offset
+ * 0x0000000000000000, // Address
+ * ,)
+ * },
+ *
+ * ResourceTemplate ()
+ * {
+ * Register (FFixedHW,
+ * 0x00, // Bit Width
+ * 0x00, // Bit Offset
+ * 0x0000000000000000, // Address
+ * ,)
+ * }
+ * })
+ */
+ static char stream[] = {
+ /* 00000030 "0._PCT.," */
+ 0x08, 0x5f, 0x50, 0x43, 0x54, 0x12, 0x2c,
+ /* 00000038 "........" */
+ 0x02, 0x11, 0x14, 0x0a, 0x11, 0x82, 0x0c, 0x00,
+ /* 00000040 "........" */
+ 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* 00000048 "....y..." */
+ 0x00, 0x00, 0x00, 0x00, 0x79, 0x00, 0x11, 0x14,
+ /* 00000050 "........" */
+ 0x0a, 0x11, 0x82, 0x0c, 0x00, 0x7f, 0x00, 0x00,
+ /* 00000058 "........" */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x79, 0x00
+ };
+ acpigen_emit_stream(ctx, stream, ARRAY_SIZE(stream));
+}
+
+void acpigen_write_empty_ptc(struct acpi_ctx *ctx)
+{
+ /*
+ * Name (_PTC, Package (0x02)
+ * {
+ * ResourceTemplate ()
+ * {
+ * Register (FFixedHW,
+ * 0x00, // Bit Width
+ * 0x00, // Bit Offset
+ * 0x0000000000000000, // Address
+ * ,)
+ * },
+ *
+ * ResourceTemplate ()
+ * {
+ * Register (FFixedHW,
+ * 0x00, // Bit Width
+ * 0x00, // Bit Offset
+ * 0x0000000000000000, // Address
+ * ,)
+ * }
+ * })
+ */
+ struct acpi_gen_regaddr addr = {
+ .space_id = ACPI_ADDRESS_SPACE_FIXED,
+ .bit_width = 0,
+ .bit_offset = 0,
+ .access_size = 0,
+ .addrl = 0,
+ .addrh = 0,
+ };
+
+ acpigen_write_name(ctx, "_PTC");
+ acpigen_write_package(ctx, 2);
+
+ /* ControlRegister */
+ acpigen_write_register_resource(ctx, &addr);
+
+ /* StatusRegister */
+ acpigen_write_register_resource(ctx, &addr);
+
+ acpigen_pop_len(ctx);
+}
--
2.28.0.526.ge36021eeef-goog