acpi: Add SSDT pstate helper functions

Add new generic helper functions for PSS, PCT, XPSS, objects.

BUG=b:155307433
TEST=Boot Morphius and dump SSDT. Confirm PSS and PCT objects appear
as expected and conform to ACPI_6_3_May16.pdf ACPI specification.
Check XPSS against Microsoft "Extended PSS ACPI Method Specification"
XPSS_spec.doc April 2, 2007.
BRANCH=Zork

Change-Id: I1ea218bcee33093481e82390550ff96d9d2cb8b5
Signed-off-by: Jason Glenesk <jason.glenesk@amd.corp-partner.google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/45437
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Furquan Shaikh <furquan@google.com>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
diff --git a/src/acpi/acpigen.c b/src/acpi/acpigen.c
index 7910cbc..5b45ebd 100644
--- a/src/acpi/acpigen.c
+++ b/src/acpi/acpigen.c
@@ -832,6 +832,23 @@
 	       coreFreq, power, control, status);
 }
 
+void acpigen_write_pss_object(const struct acpi_sw_pstate *pstate_values, size_t nentries)
+{
+	size_t pstate;
+
+	acpigen_write_name("_PSS");
+	acpigen_write_package(nentries);
+	for (pstate = 0; pstate < nentries; pstate++) {
+		acpigen_write_PSS_package(
+			pstate_values->core_freq, pstate_values->power,
+			pstate_values->transition_latency, pstate_values->bus_master_latency,
+			pstate_values->control_value, pstate_values->status_value);
+		pstate_values++;
+	}
+
+	acpigen_pop_len();
+}
+
 void acpigen_write_PSD_package(u32 domain, u32 numprocs, PSD_coord coordtype)
 {
 	acpigen_write_name("_PSD");
@@ -2002,3 +2019,43 @@
 {
 	_create_field(CREATE_QWORD_OP, op, byte_offset, name);
 }
+
+void acpigen_write_pct_package(const acpi_addr_t *perf_ctrl, const acpi_addr_t *perf_sts)
+{
+	acpigen_write_name("_PCT");
+	acpigen_write_package(0x02);
+	acpigen_write_register_resource(perf_ctrl);
+	acpigen_write_register_resource(perf_sts);
+
+	acpigen_pop_len();
+}
+
+void acpigen_write_xpss_package(const struct acpi_xpss_sw_pstate *pstate_value)
+{
+	acpigen_write_package(0x08);
+	acpigen_write_dword(pstate_value->core_freq);
+	acpigen_write_dword(pstate_value->power);
+	acpigen_write_dword(pstate_value->transition_latency);
+	acpigen_write_dword(pstate_value->bus_master_latency);
+
+	acpigen_write_byte_buffer((uint8_t *)&pstate_value->control_value, sizeof(uint64_t));
+	acpigen_write_byte_buffer((uint8_t *)&pstate_value->status_value, sizeof(uint64_t));
+	acpigen_write_byte_buffer((uint8_t *)&pstate_value->control_mask, sizeof(uint64_t));
+	acpigen_write_byte_buffer((uint8_t *)&pstate_value->status_mask, sizeof(uint64_t));
+
+	acpigen_pop_len();
+}
+
+void acpigen_write_xpss_object(const struct acpi_xpss_sw_pstate *pstate_values, size_t nentries)
+{
+	size_t pstate;
+
+	acpigen_write_name("XPSS");
+	acpigen_write_package(nentries);
+	for (pstate = 0; pstate < nentries; pstate++) {
+		acpigen_write_xpss_package(pstate_values);
+		pstate_values++;
+	}
+
+	acpigen_pop_len();
+}