<p>Matt Delco has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/28066">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">arch/x86/acpigen: add methods for cppc<br><br>This change adds 2 methods for Conginuous Performance Control that was<br>added in ACPI 5.0 and expanded twice in later versions.  One function<br>will create a global table based on a provided struct, while the other<br>function is used to add a _CPC method in each processor object.<br><br>Change-Id: I8798a4c72c681b960087ed65668f01b2ca77d2ce<br>Signed-off-by: Matt Delco <delco@chromium.org><br>---<br>M src/arch/x86/acpigen.c<br>M src/arch/x86/include/arch/acpigen.h<br>2 files changed, 107 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/66/28066/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/arch/x86/acpigen.c b/src/arch/x86/acpigen.c</span><br><span>index a614efb..06702ce 100644</span><br><span>--- a/src/arch/x86/acpigen.c</span><br><span>+++ b/src/arch/x86/acpigen.c</span><br><span>@@ -1339,6 +1339,54 @@</span><br><span>    acpigen_pop_len();      /* Method _DSM */</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#define CPPC_PACKAGE_NAME "\\GCPC"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void acpigen_write_CPPC_package(const struct cppc_config *config)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      u32 i;</span><br><span style="color: hsl(120, 100%, 40%);">+        u32 max;</span><br><span style="color: hsl(120, 100%, 40%);">+      switch (config->version) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case 1:</span><br><span style="color: hsl(120, 100%, 40%);">+               max = CPPC_MAX_FIELDS_VER_1;</span><br><span style="color: hsl(120, 100%, 40%);">+          break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case 2:</span><br><span style="color: hsl(120, 100%, 40%);">+               max = CPPC_MAX_FIELDS_VER_2;</span><br><span style="color: hsl(120, 100%, 40%);">+          break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case 3:</span><br><span style="color: hsl(120, 100%, 40%);">+               max = CPPC_MAX_FIELDS_VER_3;</span><br><span style="color: hsl(120, 100%, 40%);">+          break;</span><br><span style="color: hsl(120, 100%, 40%);">+        default:</span><br><span style="color: hsl(120, 100%, 40%);">+              printk(BIOS_ERR, "ERROR: CPPC version %u is not implemented\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                    config->version);</span><br><span style="color: hsl(120, 100%, 40%);">+           return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+     acpigen_write_name(CPPC_PACKAGE_NAME);</span><br><span style="color: hsl(120, 100%, 40%);">+        acpigen_write_package(max);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ acpigen_write_dword(max);</span><br><span style="color: hsl(120, 100%, 40%);">+     acpigen_write_byte(config->version);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     for (i = 0; i < max; ++i) {</span><br><span style="color: hsl(120, 100%, 40%);">+                const acpi_addr_t *reg = &(config->regs[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+           if (reg->space_id == ACPI_ADDRESS_SPACE_MEMORY &&</span><br><span style="color: hsl(120, 100%, 40%);">+              reg->bit_width == 32 && reg->access_size == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    acpigen_write_dword(reg->addrl);</span><br><span style="color: hsl(120, 100%, 40%);">+           } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                      acpigen_write_register_resource(reg);</span><br><span style="color: hsl(120, 100%, 40%);">+         }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     acpigen_pop_len();</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void acpigen_write_CPPC_method(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      acpigen_write_method("_CPC", 0);</span><br><span style="color: hsl(120, 100%, 40%);">+    acpigen_emit_byte(RETURN_OP);</span><br><span style="color: hsl(120, 100%, 40%);">+ acpigen_emit_namestring(CPPC_PACKAGE_NAME);</span><br><span style="color: hsl(120, 100%, 40%);">+   acpigen_pop_len();</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*</span><br><span>  * Generate ACPI AML code for _ROM method.</span><br><span>  * This function takes as input ROM data and ROM length.</span><br><span>diff --git a/src/arch/x86/include/arch/acpigen.h b/src/arch/x86/include/arch/acpigen.h</span><br><span>index 042c797..775339a 100644</span><br><span>--- a/src/arch/x86/include/arch/acpigen.h</span><br><span>+++ b/src/arch/x86/include/arch/acpigen.h</span><br><span>@@ -167,6 +167,56 @@</span><br><span>    void *arg;</span><br><span> };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*version 1 has 15 fields, version 2 has 19, and version 3 has 21 */</span><br><span style="color: hsl(120, 100%, 40%);">+enum cppc_fields {</span><br><span style="color: hsl(120, 100%, 40%);">+        CPPC_HIGHEST_PERF, /* can be DWORD */</span><br><span style="color: hsl(120, 100%, 40%);">+ CPPC_NOMINAL_PERF, /* can be DWORD */</span><br><span style="color: hsl(120, 100%, 40%);">+ CPPC_LOWEST_NONL_PERF, /* can be DWORD */</span><br><span style="color: hsl(120, 100%, 40%);">+     CPPC_LOWEST_PERF, /* can be DWORD */</span><br><span style="color: hsl(120, 100%, 40%);">+  CPPC_GUARANTEED_PERF,</span><br><span style="color: hsl(120, 100%, 40%);">+ CPPC_DESIRED_PERF,</span><br><span style="color: hsl(120, 100%, 40%);">+    CPPC_MIN_PERF,</span><br><span style="color: hsl(120, 100%, 40%);">+        CPPC_MAX_PERF,</span><br><span style="color: hsl(120, 100%, 40%);">+        CPPC_PERF_REDUCE_TOLERANCE,</span><br><span style="color: hsl(120, 100%, 40%);">+   CPPC_TIME_WINDOW,</span><br><span style="color: hsl(120, 100%, 40%);">+     CPPC_COUNTER_WRAP, /* can be DWORD */</span><br><span style="color: hsl(120, 100%, 40%);">+ CPPC_REF_PERF_COUNTER,</span><br><span style="color: hsl(120, 100%, 40%);">+        CPPC_DELIVERED_PERF_COUNTER,</span><br><span style="color: hsl(120, 100%, 40%);">+  CPPC_PERF_LIMITED,</span><br><span style="color: hsl(120, 100%, 40%);">+    CPPC_ENABLE, /* can be System I/O */</span><br><span style="color: hsl(120, 100%, 40%);">+  CPPC_MAX_FIELDS_VER_1,</span><br><span style="color: hsl(120, 100%, 40%);">+        CPPC_AUTO_SELECT = /* can be DWORD */</span><br><span style="color: hsl(120, 100%, 40%);">+         CPPC_MAX_FIELDS_VER_1,</span><br><span style="color: hsl(120, 100%, 40%);">+        CPPC_AUTO_ACTIVITY_WINDOW,</span><br><span style="color: hsl(120, 100%, 40%);">+    CPPC_PERF_PREF,</span><br><span style="color: hsl(120, 100%, 40%);">+       CPPC_REF_PERF, /* can be DWORD */</span><br><span style="color: hsl(120, 100%, 40%);">+     CPPC_MAX_FIELDS_VER_2,</span><br><span style="color: hsl(120, 100%, 40%);">+        CPPC_LOWEST_FREQ = /* can be DWORD */</span><br><span style="color: hsl(120, 100%, 40%);">+         CPPC_MAX_FIELDS_VER_2,</span><br><span style="color: hsl(120, 100%, 40%);">+        CPPC_NOMINAL_FREQ, /* can be DWORD */</span><br><span style="color: hsl(120, 100%, 40%);">+ CPPC_MAX_FIELDS_VER_3,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct cppc_config {</span><br><span style="color: hsl(120, 100%, 40%);">+    u32 version; /* must be 1, 2, or 3 */</span><br><span style="color: hsl(120, 100%, 40%);">+ /*</span><br><span style="color: hsl(120, 100%, 40%);">+     * The generic acpi_addr_t structure is being used, though</span><br><span style="color: hsl(120, 100%, 40%);">+     * anything besides PPC or FFIXED generally requires checking</span><br><span style="color: hsl(120, 100%, 40%);">+  * if the OS has advertised support for it (via _OSC).</span><br><span style="color: hsl(120, 100%, 40%);">+         *</span><br><span style="color: hsl(120, 100%, 40%);">+     * NOTE: some fields permit DWORDs to be used.  If you</span><br><span style="color: hsl(120, 100%, 40%);">+         * provide a System Memory register with all zeros (which</span><br><span style="color: hsl(120, 100%, 40%);">+      * represents unsupported) then this will be used as-is.</span><br><span style="color: hsl(120, 100%, 40%);">+       * Otherwise, a System Memory register with a 32-bit</span><br><span style="color: hsl(120, 100%, 40%);">+   * width will be converted into a DWORD field (the value</span><br><span style="color: hsl(120, 100%, 40%);">+       * of which will be the value of 'addrl'.  Any other use</span><br><span style="color: hsl(120, 100%, 40%);">+       * of System Memory register is currently undefined.</span><br><span style="color: hsl(120, 100%, 40%);">+   * (i.e., if you have an actual need for System Memory</span><br><span style="color: hsl(120, 100%, 40%);">+         * then you'll need to adjust this kludge).</span><br><span style="color: hsl(120, 100%, 40%);">+        */</span><br><span style="color: hsl(120, 100%, 40%);">+   acpi_addr_t regs[CPPC_MAX_FIELDS_VER_3];</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> void acpigen_write_return_integer(uint64_t arg);</span><br><span> void acpigen_write_return_string(const char *arg);</span><br><span> void acpigen_write_len_f(void);</span><br><span>@@ -269,6 +319,15 @@</span><br><span> void acpigen_write_dsm_uuid_arr(struct dsm_uuid *ids, size_t count);</span><br><span> </span><br><span> /*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Generate ACPI AML code for _CPC (Continuous Perfmance Control).</span><br><span style="color: hsl(120, 100%, 40%);">+ * Execute the package function once to create a global table, then</span><br><span style="color: hsl(120, 100%, 40%);">+ * execute the method function within each processor object to</span><br><span style="color: hsl(120, 100%, 40%);">+ * create a method that points to the global table.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void acpigen_write_CPPC_package(const struct cppc_config *config);</span><br><span style="color: hsl(120, 100%, 40%);">+void acpigen_write_CPPC_method(void);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span>  * Generate ACPI AML code for _ROM method.</span><br><span>  * This function takes as input ROM data and ROM length.</span><br><span>  * The ROM length has to be multiple of 4096 and has to be less</span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/28066">change 28066</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/28066"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I8798a4c72c681b960087ed65668f01b2ca77d2ce </div>
<div style="display:none"> Gerrit-Change-Number: 28066 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Matt Delco <delco@chromium.org> </div>