[coreboot-gerrit] Change in coreboot[master]: arch/x86/acpigen: add methods for cppc

Matt Delco (Code Review) gerrit at coreboot.org
Mon Aug 13 23:04:47 CEST 2018


Matt Delco has uploaded this change for review. ( https://review.coreboot.org/28066


Change subject: arch/x86/acpigen: add methods for cppc
......................................................................

arch/x86/acpigen: add methods for cppc

This change adds 2 methods for Conginuous Performance Control that was
added in ACPI 5.0 and expanded twice in later versions.  One function
will create a global table based on a provided struct, while the other
function is used to add a _CPC method in each processor object.

Change-Id: I8798a4c72c681b960087ed65668f01b2ca77d2ce
Signed-off-by: Matt Delco <delco at chromium.org>
---
M src/arch/x86/acpigen.c
M src/arch/x86/include/arch/acpigen.h
2 files changed, 107 insertions(+), 0 deletions(-)



  git pull ssh://review.coreboot.org:29418/coreboot refs/changes/66/28066/1

diff --git a/src/arch/x86/acpigen.c b/src/arch/x86/acpigen.c
index a614efb..06702ce 100644
--- a/src/arch/x86/acpigen.c
+++ b/src/arch/x86/acpigen.c
@@ -1339,6 +1339,54 @@
 	acpigen_pop_len();	/* Method _DSM */
 }
 
+#define CPPC_PACKAGE_NAME "\\GCPC"
+
+void acpigen_write_CPPC_package(const struct cppc_config *config)
+{
+	u32 i;
+	u32 max;
+	switch (config->version) {
+	case 1:
+		max = CPPC_MAX_FIELDS_VER_1;
+		break;
+	case 2:
+		max = CPPC_MAX_FIELDS_VER_2;
+		break;
+	case 3:
+		max = CPPC_MAX_FIELDS_VER_3;
+		break;
+	default:
+		printk(BIOS_ERR, "ERROR: CPPC version %u is not implemented\n",
+		       config->version);
+		return;
+	}
+	acpigen_write_name(CPPC_PACKAGE_NAME);
+	acpigen_write_package(max);
+
+	acpigen_write_dword(max);
+	acpigen_write_byte(config->version);
+
+	for (i = 0; i < max; ++i) {
+		const acpi_addr_t *reg = &(config->regs[i]);
+		if (reg->space_id == ACPI_ADDRESS_SPACE_MEMORY &&
+		    reg->bit_width == 32 && reg->access_size == 0) {
+			acpigen_write_dword(reg->addrl);
+		} else {
+			acpigen_write_register_resource(reg);
+		}
+	}
+	acpigen_pop_len();
+}
+
+void acpigen_write_CPPC_method(void)
+{
+	acpigen_write_method("_CPC", 0);
+	acpigen_emit_byte(RETURN_OP);
+	acpigen_emit_namestring(CPPC_PACKAGE_NAME);
+	acpigen_pop_len();
+}
+
+
 /*
  * Generate ACPI AML code for _ROM method.
  * This function takes as input ROM data and ROM length.
diff --git a/src/arch/x86/include/arch/acpigen.h b/src/arch/x86/include/arch/acpigen.h
index 042c797..775339a 100644
--- a/src/arch/x86/include/arch/acpigen.h
+++ b/src/arch/x86/include/arch/acpigen.h
@@ -167,6 +167,56 @@
 	void *arg;
 };
 
+/*version 1 has 15 fields, version 2 has 19, and version 3 has 21 */
+enum cppc_fields {
+	CPPC_HIGHEST_PERF, /* can be DWORD */
+	CPPC_NOMINAL_PERF, /* can be DWORD */
+	CPPC_LOWEST_NONL_PERF, /* can be DWORD */
+	CPPC_LOWEST_PERF, /* can be DWORD */
+	CPPC_GUARANTEED_PERF,
+	CPPC_DESIRED_PERF,
+	CPPC_MIN_PERF,
+	CPPC_MAX_PERF,
+	CPPC_PERF_REDUCE_TOLERANCE,
+	CPPC_TIME_WINDOW,
+	CPPC_COUNTER_WRAP, /* can be DWORD */
+	CPPC_REF_PERF_COUNTER,
+	CPPC_DELIVERED_PERF_COUNTER,
+	CPPC_PERF_LIMITED,
+	CPPC_ENABLE, /* can be System I/O */
+	CPPC_MAX_FIELDS_VER_1,
+	CPPC_AUTO_SELECT = /* can be DWORD */
+		CPPC_MAX_FIELDS_VER_1,
+	CPPC_AUTO_ACTIVITY_WINDOW,
+	CPPC_PERF_PREF,
+	CPPC_REF_PERF, /* can be DWORD */
+	CPPC_MAX_FIELDS_VER_2,
+	CPPC_LOWEST_FREQ = /* can be DWORD */
+		CPPC_MAX_FIELDS_VER_2,
+	CPPC_NOMINAL_FREQ, /* can be DWORD */
+	CPPC_MAX_FIELDS_VER_3,
+};
+
+struct cppc_config {
+	u32 version; /* must be 1, 2, or 3 */
+	/*
+	 * The generic acpi_addr_t structure is being used, though
+	 * anything besides PPC or FFIXED generally requires checking
+	 * if the OS has advertised support for it (via _OSC).
+	 *
+	 * NOTE: some fields permit DWORDs to be used.  If you
+	 * provide a System Memory register with all zeros (which
+	 * represents unsupported) then this will be used as-is.
+	 * Otherwise, a System Memory register with a 32-bit
+	 * width will be converted into a DWORD field (the value
+	 * of which will be the value of 'addrl'.  Any other use
+	 * of System Memory register is currently undefined.
+	 * (i.e., if you have an actual need for System Memory
+	 * then you'll need to adjust this kludge).
+	 */
+	acpi_addr_t regs[CPPC_MAX_FIELDS_VER_3];
+};
+
 void acpigen_write_return_integer(uint64_t arg);
 void acpigen_write_return_string(const char *arg);
 void acpigen_write_len_f(void);
@@ -269,6 +319,15 @@
 void acpigen_write_dsm_uuid_arr(struct dsm_uuid *ids, size_t count);
 
 /*
+ * Generate ACPI AML code for _CPC (Continuous Perfmance Control).
+ * Execute the package function once to create a global table, then
+ * execute the method function within each processor object to
+ * create a method that points to the global table.
+ */
+void acpigen_write_CPPC_package(const struct cppc_config *config);
+void acpigen_write_CPPC_method(void);
+
+/*
  * Generate ACPI AML code for _ROM method.
  * This function takes as input ROM data and ROM length.
  * The ROM length has to be multiple of 4096 and has to be less

-- 
To view, visit https://review.coreboot.org/28066
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I8798a4c72c681b960087ed65668f01b2ca77d2ce
Gerrit-Change-Number: 28066
Gerrit-PatchSet: 1
Gerrit-Owner: Matt Delco <delco at chromium.org>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.coreboot.org/pipermail/coreboot-gerrit/attachments/20180813/a7b02041/attachment-0001.html>


More information about the coreboot-gerrit mailing list