Message ID | 20220831081603.3415-11-rrichter@amd.com |
---|---|
State | Superseded |
Delegated to: | Dan Williams |
Headers | show |
Series | cxl: Add support for Restricted CXL hosts (RCD mode) | expand |
On Wed, 31 Aug 2022 10:15:58 +0200 Robert Richter <rrichter@amd.com> wrote: > The downstream and upstream port Root Complex Register Blocks (RCRBs) > are needed to control the ports and CXL devices connected to it. It > also includes the location of the RCH/RCD downstream and upstream port > component registers in MEMBAR0. Extract the RCRB from the host's CEDT > entry. > > Signed-off-by: Robert Richter <rrichter@amd.com> Hi Robert, One trivial comment inline. Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> > --- > drivers/cxl/acpi.c | 43 +++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 43 insertions(+) > > diff --git a/drivers/cxl/acpi.c b/drivers/cxl/acpi.c > index b3146b7ae922..439df9df2741 100644 > --- a/drivers/cxl/acpi.c > +++ b/drivers/cxl/acpi.c > @@ -365,11 +365,48 @@ struct pci_host_bridge *cxl_find_next_rch(struct pci_host_bridge *host) > return NULL; > } > > +static int __cxl_get_rcrb(union acpi_subtable_headers *header, void *arg, > + const unsigned long end) > +{ > + struct cxl_chbs_context *ctx = arg; > + struct acpi_cedt_chbs *chbs; > + > + if (ctx->chbcr) > + return 0; > + > + chbs = (struct acpi_cedt_chbs *)header; > + > + if (ctx->uid != chbs->uid) > + return 0; > + > + if (chbs->cxl_version != ACPI_CEDT_CHBS_VERSION_CXL11) > + return 0; > + > + if (chbs->length != SZ_8K) > + return 0; > + > + ctx->chbcr = chbs->base; > + > + return 0; > +} > + > +static resource_size_t cxl_get_rcrb(u32 uid) > +{ > + struct cxl_chbs_context ctx = { > + .uid = uid, > + }; > + > + acpi_table_parse_cedt(ACPI_CEDT_TYPE_CHBS, __cxl_get_rcrb, &ctx); > + > + return ctx.chbcr; > +} > + > static int __init cxl_restricted_host_probe(struct platform_device *pdev) > { > struct pci_host_bridge *host = NULL; > struct acpi_device *adev; > unsigned long long uid = ~0; > + resource_size_t rcrb; Some of these could be made local to the while loop to reduce their scope. > > while ((host = cxl_find_next_rch(host)) != NULL) { > adev = ACPI_COMPANION(&host->dev); > @@ -382,6 +419,12 @@ static int __init cxl_restricted_host_probe(struct platform_device *pdev) > if (uid > U32_MAX) > continue; > > + rcrb = cxl_get_rcrb(uid); > + if (!rcrb) > + continue; > + > + dev_dbg(&host->dev, "RCRB found: 0x%08llx\n", (u64)rcrb); > + > dev_info(&host->dev, "host supports CXL\n"); > } >
On 31.08.22 12:09:09, Jonathan Cameron wrote: > On Wed, 31 Aug 2022 10:15:58 +0200 > Robert Richter <rrichter@amd.com> wrote: > > static int __init cxl_restricted_host_probe(struct platform_device *pdev) > > { > > struct pci_host_bridge *host = NULL; > > struct acpi_device *adev; > > unsigned long long uid = ~0; > > + resource_size_t rcrb; > > Some of these could be made local to the while loop to reduce their scope. I would need to move most of the vars into the loop then. So I rather want to keep it as it is. I also remember a compiler or code checker complaining about block declaration, though it is in the c standard. -Robert > > > > while ((host = cxl_find_next_rch(host)) != NULL) { > > adev = ACPI_COMPANION(&host->dev); > > @@ -382,6 +419,12 @@ static int __init cxl_restricted_host_probe(struct platform_device *pdev) > > if (uid > U32_MAX) > > continue; > > > > + rcrb = cxl_get_rcrb(uid); > > + if (!rcrb) > > + continue; > > + > > + dev_dbg(&host->dev, "RCRB found: 0x%08llx\n", (u64)rcrb); > > + > > dev_info(&host->dev, "host supports CXL\n"); > > } > > >
diff --git a/drivers/cxl/acpi.c b/drivers/cxl/acpi.c index b3146b7ae922..439df9df2741 100644 --- a/drivers/cxl/acpi.c +++ b/drivers/cxl/acpi.c @@ -365,11 +365,48 @@ struct pci_host_bridge *cxl_find_next_rch(struct pci_host_bridge *host) return NULL; } +static int __cxl_get_rcrb(union acpi_subtable_headers *header, void *arg, + const unsigned long end) +{ + struct cxl_chbs_context *ctx = arg; + struct acpi_cedt_chbs *chbs; + + if (ctx->chbcr) + return 0; + + chbs = (struct acpi_cedt_chbs *)header; + + if (ctx->uid != chbs->uid) + return 0; + + if (chbs->cxl_version != ACPI_CEDT_CHBS_VERSION_CXL11) + return 0; + + if (chbs->length != SZ_8K) + return 0; + + ctx->chbcr = chbs->base; + + return 0; +} + +static resource_size_t cxl_get_rcrb(u32 uid) +{ + struct cxl_chbs_context ctx = { + .uid = uid, + }; + + acpi_table_parse_cedt(ACPI_CEDT_TYPE_CHBS, __cxl_get_rcrb, &ctx); + + return ctx.chbcr; +} + static int __init cxl_restricted_host_probe(struct platform_device *pdev) { struct pci_host_bridge *host = NULL; struct acpi_device *adev; unsigned long long uid = ~0; + resource_size_t rcrb; while ((host = cxl_find_next_rch(host)) != NULL) { adev = ACPI_COMPANION(&host->dev); @@ -382,6 +419,12 @@ static int __init cxl_restricted_host_probe(struct platform_device *pdev) if (uid > U32_MAX) continue; + rcrb = cxl_get_rcrb(uid); + if (!rcrb) + continue; + + dev_dbg(&host->dev, "RCRB found: 0x%08llx\n", (u64)rcrb); + dev_info(&host->dev, "host supports CXL\n"); }
The downstream and upstream port Root Complex Register Blocks (RCRBs) are needed to control the ports and CXL devices connected to it. It also includes the location of the RCH/RCD downstream and upstream port component registers in MEMBAR0. Extract the RCRB from the host's CEDT entry. Signed-off-by: Robert Richter <rrichter@amd.com> --- drivers/cxl/acpi.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+)