图表

_DSD

_DSD(设备特定数据)[dsd-guide] 是一个预定义的 ACPI 设备配置对象,可用于传递 ACPI 规范 [acpi] 未明确涵盖的硬件功能信息。 有两个与图表相关的 _DSD 扩展:属性 [dsd-guide] 和分层数据扩展。 属性扩展提供通用的键值对,而分层数据扩展支持具有对其他节点的引用的节点,从而形成一个树。 树中的节点可能包含属性扩展定义的属性。 这两个扩展共同提供了一个树状结构,树中的每个节点都有零个或多个属性(键值对)。

可以使用 include/linux/fwnode.h 中定义的 device_* 和 fwnode_* 函数在运行时访问数据结构。

Fwnode 表示一个通用的固件节点对象。它独立于固件类型。在 ACPI 中,fwnode 是 _DSD 分层数据扩展对象。设备的 _DSD 对象由 fwnode 表示。

通过使用对设备本身的硬引用以及对每个深度的分层数据扩展数组的索引,可以在 ACPI 表中的其他位置引用数据结构。

端口和端点

端口和端点概念与设备树 [devicetree, graph-bindings] 中的概念非常相似。端口表示设备中的一个接口,而端点表示与该接口的连接。另请参见 [data-node-ref] 以获取通用数据节点引用。

所有端口节点都位于分层数据扩展树中设备的“_DSD”节点下。与每个端口节点相关的数据扩展必须以“port”开头,后跟“@”字符和端口号作为其键。它引用的目标对象应称为“PRTX”,其中“X”是端口号。这样的包的示例是

Package() { "port@4", "PRT4" }

此外,端点位于端口节点下。端点节点的分层数据扩展键必须以“endpoint”开头,后跟“@”字符和端点号。它引用的对象应称为“EPXY”,其中“X”是端口号,“Y”是端点号。这样的包的示例是

Package() { "endpoint@0", "EP40" }

每个端口节点都包含一个属性扩展键“port”,其值是端口号。每个端点都以类似的方式编号,属性扩展键为“reg”,其值是端点号。端口号在设备中必须是唯一的,并且端点号在端口中必须是唯一的。如果设备对象只有一个端口,则该端口的编号应为零。同样,如果一个端口只能有一个端点,则该端点的编号应为零。

端点引用使用属性扩展,属性名称为“remote-endpoint”,后跟同一包中的引用。此类引用由远程设备引用、设备下端口数据扩展引用的第一个包条目以及最后端口下端点数据扩展引用的第一个包条目组成。因此,单个引用显示为

Package() { device, "port@X", "endpoint@Y" }

在上面的示例中,“X”是端口号,“Y”是端点号。

必须始终以双向方式完成对端点的引用,即引用到远程端点,然后再从被引用的远程端点节点返回。

下面显示了一个简单的示例

Scope (\_SB.PCI0.I2C2)
{
    Device (CAM0)
    {
        Name (_DSD, Package () {
            ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
            Package () {
                Package () { "compatible", Package () { "nokia,smia" } },
            },
            ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
            Package () {
                Package () { "port@0", "PRT0" },
            }
        })
        Name (PRT0, Package() {
            ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
            Package () {
                Package () { "reg", 0 },
            },
            ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
            Package () {
                Package () { "endpoint@0", "EP00" },
            }
        })
        Name (EP00, Package() {
            ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
            Package () {
                Package () { "reg", 0 },
                Package () { "remote-endpoint", Package() { \_SB.PCI0.ISP, "port@4", "endpoint@0" } },
            }
        })
    }
}

Scope (\_SB.PCI0)
{
    Device (ISP)
    {
        Name (_DSD, Package () {
            ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
            Package () {
                Package () { "port@4", "PRT4" },
            }
        })

        Name (PRT4, Package() {
            ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
            Package () {
                Package () { "reg", 4 }, /* CSI-2 port number */
            },
            ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
            Package () {
                Package () { "endpoint@0", "EP40" },
            }
        })

        Name (EP40, Package() {
            ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
            Package () {
                Package () { "reg", 0 },
                Package () { "remote-endpoint", Package () { \_SB.PCI0.I2C2.CAM0, "port@0", "endpoint@0" } },
            }
        })
    }
}

在这里,“CAM0”设备的端口 0 连接到“ISP”设备的端口 4,反之亦然。

参考资料

[acpi] 高级配置和电源接口规范。

https://uefi.org/specifications/ACPI/6.4/,引用日期:2021-11-30。

[data-node-ref] 引用分层数据节点

[devicetree] 设备树。 https://www.devicetree.org,引用日期:2016-10-03。

[dsd-guide] DSD 指南。

https://github.com/UEFI/DSD-Guide/blob/main/dsd-guide.adoc,引用日期:2021-11-30。

[dsd-rules] _DSD 设备属性使用规则。

_DSD 设备属性使用规则

[graph-bindings] 设备图的通用绑定(设备树)。

https://github.com/devicetree-org/dt-schema/blob/main/schemas/graph.yaml,引用日期:2021-11-30。