Re: [PATCH V2 6/9] PCI/TPH: Retrieve steering tag from ACPI _DSM

From: Bjorn Helgaas
Date: Fri Jun 07 2024 - 14:43:37 EST


On Fri, May 31, 2024 at 04:38:38PM -0500, Wei Huang wrote:
> According to PCI SIG ECN, calling the _DSM firmware method for a given
> CPU_UID returns the steering tags for different types of memory
> (volatile, non-volatile). These tags are supposed to be used in ST
> table entry for optimal results.

Cite PCI Firmware spec if possible. If it hasn't been incorporated
yet, at least include the exact name of the ECN and the date it was
approved.

Say what the patch does in the commit log (in addition to the subject
line).

> +#define MIN_ST_DSM_REV 7

No useful value in this #define. If the value ever changes, code
changes will be required too.

> +#define ST_DSM_FUNC_INDEX 0xf

Move to the list in pci-acpi.h with name similar to others.

> +static bool invoke_dsm(acpi_handle handle, u32 cpu_uid, u8 ph,
> + u8 target_type, bool cache_ref_valid,
> + u64 cache_ref, union st_info *st_out)
> +{

Return 0 or -errno. "invoke_dsm" is not a predicate with an obvious
true/false meaning.

> + union acpi_object in_obj, in_buf[3], *out_obj;
> +
> + in_buf[0].integer.type = ACPI_TYPE_INTEGER;
> + in_buf[0].integer.value = 0; /* 0 => processor cache steering tags */
> +
> + in_buf[1].integer.type = ACPI_TYPE_INTEGER;
> + in_buf[1].integer.value = cpu_uid;
> +
> + in_buf[2].integer.type = ACPI_TYPE_INTEGER;
> + in_buf[2].integer.value = ph & 3;
> + in_buf[2].integer.value |= (target_type & 1) << 2;
> + in_buf[2].integer.value |= (cache_ref_valid & 1) << 3;
> + in_buf[2].integer.value |= (cache_ref << 32);
> +
> + in_obj.type = ACPI_TYPE_PACKAGE;
> + in_obj.package.count = ARRAY_SIZE(in_buf);
> + in_obj.package.elements = in_buf;

Must check whether this _DSM function is implemented first, e.g., see
acpi_enable_dpc().

> + out_obj = acpi_evaluate_dsm(handle, &pci_acpi_dsm_guid, MIN_ST_DSM_REV,
> + ST_DSM_FUNC_INDEX, &in_obj);
> +
> + if (!out_obj)
> + return false;
> +
> + if (out_obj->type != ACPI_TYPE_BUFFER) {
> + pr_err("invalid return type %d from TPH _DSM\n",
> + out_obj->type);
> + ACPI_FREE(out_obj);
> + return false;
> + }
> +
> + st_out->value = *((u64 *)(out_obj->buffer.pointer));
> +
> + ACPI_FREE(out_obj);
> +
> + return true;
> +}