[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <Z8sLznxBkJHWeTvQ@gourry-fedora-PF4VCD3F>
Date: Fri, 7 Mar 2025 10:07:58 -0500
From: Gregory Price <gourry@...rry.net>
To: "Zhijian Li (Fujitsu)" <lizhijian@...itsu.com>
Cc: "lsf-pc@...ts.linux-foundation.org" <lsf-pc@...ts.linux-foundation.org>,
"linux-mm@...ck.org" <linux-mm@...ck.org>,
"linux-cxl@...r.kernel.org" <linux-cxl@...r.kernel.org>,
"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>
Subject: Re: CXL Boot to Bash - Section 2a (Drivers): CXL Decoder Programming
On Fri, Mar 07, 2025 at 12:57:18AM +0000, Zhijian Li (Fujitsu) wrote:
> > In section 2, I referenced a simple device-to-decoder mapping:
> >
> > root --- decoder0.0 -- Root Port Decoder
> > | |
> > port1 --- decoder1.0 -- Host Bridge Decoder
> > | |
> > endpoint0 --- decoder2.0 -- Endpoint Decoder
>
> Here, I noticed something that differs slightly from my understanding:
> "root --- decoder0.0 -- Root Port Decoder."
>
> From the perspective of the Linux Driver, decoder0.0 usually refers to
> associated a CFMWs. Moreover, according to Spec r3.1 Table 8-22 CXL HDM Decoder Capability,
> the CXL Root Port (also known as R in the table) is not permitted to implement
> the HDM decoder.
>
> If I have misunderstood something, please let me know.
You're indeed right that in the spec it says root ports do not have
decoder capability. What we have here may be some jumbling of CXL
spec languange and Linux CXL driver language.
The decoder0.0 is a `root decoder`.
The `root_port` is a logical construct belonging to the CXL root
struct cxl_root {
struct cxl_port port; <--- root_port
}
A root_decoder is added to the CXL drivers `root_port` when
we parse the cfmws:
static int __cxl_parse_cfmws(struct acpi_cedt_cfmws *cfmws,
struct cxl_cfmws_context *ctx)
{
...
struct cxl_root_decoder *cxlrd __free(put_cxlrd) =
cxl_root_decoder_alloc(root_port, ways);
...
}
And the `root_port` is a port with downstream ports - which are
presumably the host bridges
static int cxl_acpi_probe(struct platform_device *pdev)
{
cxl_root = devm_cxl_add_root(host, &acpi_root_ops);
^^^^^^^^ - Create "The CXL Root"
root_port = &cxl_root->port;
^^^^^^^^^ - The Root's "Port"
rc = bus_for_each_dev(adev->dev.bus, NULL, root_port,
add_host_bridge_dport);
^^^^^^^^^ - Add host bridges "downstream" of The Root's "Port"
...
ctx = (struct cxl_cfmws_context) {
.dev = host,
.root_port = root_port,
.cxl_res = cxl_res,
};
rc = acpi_table_parse_cedt(ACPI_CEDT_TYPE_CFMWS, cxl_parse_cfmws, &ctx);
^^^^^^^^^ - Add "root decoders" to The Root's "Port"
}
If we look at what a root decoder is defined as in cxl/cxl.h:
* struct cxl_root_decoder - Static platform CXL address decoder
So this is just some semantic confusion - and the reality is the driver
simply refers to the first device in the fabric as "The Root", and every
device has "A Port", and so the "Root Port" just means it's the Root's
"Port" not a "CXL Specification Root Port".
Whatever the case, from the snippets above, you can see the CFMWS adds 1
"root decoder" per CFMWS - which makes sense, as a CFMWS can describe
multi-host-bridge interleave - i.e. whatever the actual root device is
must be upstream of the host bridges themselves.
~Gregory
Powered by blists - more mailing lists