Hi all,
I am bringing the System Device Tree discussion to the mailing list so that we can dig deeper into the details. Let's start by providing the background and reference material from previous discussions. Below is a transcript of the slides and diagram I showed during the calls.
The notes and recording from the last meeting are here: https://github.com/OpenAMP/open-amp/wiki/System-DT-Meeting-Notes-2020#202012...
The paragraphs below up until "Interconnect Bindings" describe the bus-firewall proposal.
Last time the general agreement was that interconnects and bus-firewalls are different enough that reusing the interconnects bindings for bus-firewalls doesn't seem to be the best way forward.
The possibility of reusing IOMMU bindings for bus-firewalls was discussed toward the end of the meeting. However, IOMMU bindings currently do not have a way to to describe the slave side, which is covered by the "firewall" property in the bus-firewall proposal. (bus-master-is is similar to the iommu property.)
Cheers,
Stefano
# Background
See "Figure 4: at https://www.xilinx.com/support/documentation/architecture-manuals/am011-vers... for a diagram representing bus-firewalls, see XMPU and XPPU and how they differ from interconnects.
See the existing interconnect binding at Documentation/devicetree/bindings/interconnect/interconnect.txt
# Bus-Firewalls in Device Tree: Goals
- describe firewall controllers - describe which device is protected by which controller - describe a new ID space to configure the firewalls - describe domains-based firewall configurations in system device tree
# Firewall Controllers
Nodes describing the programmable controllers. There can be multiple controllers in a system. We thought of using a #firewall-cells property for firewall-specific extra information. It could be zero.
Each device protected by a firewall has a firewall property to link to the controller that protects accesses *to the device MMIO regions*.
Example: ctrl0: firewall@5c007000 { compatible = "st,stm32-etzpc"; reg = <0x5c007000 0x400>; #firewall-cells = <2>; status = "okay"; }; /* ctrl0 protects accesses to foo */ foo: foo@0 { firewall-names = "default", "setting1"; firewall = <&ctrl0 1 2>; };
# Bus Master IDs
Bus mastering devices are identified by firewalls using IDs. Their transactions are marked with a device ID. These IDs are used to configure bus-firewalls.
Let's call these IDs "Bus Master IDs" and advertise them on device tree using a new property: bus-master-id. They could be different per firewall controller.
Example:
foo: foo@0 { bus-master-id = <&ctrl0 0x12>;
# System Device Tree Hardware Description Example
amba_xppu: indirect-bus@1 { compatible = "indirect-bus"; #address-cells = <0x2>; #size-cells = <0x2>;
lpd_xppu: xppu@ff990000 { compatible = "xlnx,xppu" #firewall-cells = <0x0>; reg = <0x0 0xff990000 0x0 0x1000>; };
pmc_xppu: xppu@f1310000 { compatible = "xlnx,xppu" #firewall-cells = <0x0>; reg = <0x0 0xf1310000 0x0 0x1000>; }; };
cpus_r5: cpus-cluster@0 { #address-cells = <0x1>; #size-cells = <0x0>; #cpus-mask-cells = <0x1>; compatible = "cpus,cluster";
bus-master-id = <&lpd_xppu 0x0 &pmc_xppu 0x0 &lpd_xppu 0x1 &pmc_xppu 0x1>; };
amba { ethernet0: ethernet@ff0c0000 { bus-master-id = <&lpd_xppu 0x234 &pmc_xppu 0x234>; firewall = <&lpd_xppu>; };
can0: can@ff060000 { firewall = <&lpd_xppu>; };
mmc0: sdhci@f1050000 { bus-master-id = <&lpd_xppu 0x243 &pmc_xppu 0x243>; firewall = <&pmc_xppu>; };
serial0: serial@ff000000 { firewall = <&lpd_xppu>; }; };
# Interconnect Bindings
From Documentation/devicetree/bindings/interconnect/interconnect.txt:
snoc: interconnect@580000 { compatible = "qcom,msm8916-snoc"; #interconnect-cells = <1>; reg = <0x580000 0x14000>; clock-names = "bus_clk", "bus_a_clk"; clocks = <&rpmcc RPM_SMD_SNOC_CLK>, <&rpmcc RPM_SMD_SNOC_A_CLK>; };
sdhci@7864000 { ... interconnects = <&pnoc MASTER_SDCC_1 &bimc SLAVE_EBI_CH0>; interconnect-names = "sdhc-mem"; };
# Interconnect Bindings vs Firewall Bindings
- Similar concepts
- Firewall controller and Interconnect controller are separate hardware blocks - how to distinguish between the two controllers? - QoS and firewalls are configured independently
- Using Interconnect Bindings for Firewalls - the firewall property is *missing* - there is no distinction between a device as bus master or as slave - we need a way to describe firewall interactions as master and as slave
Bus firewalls description example using the interconnect bindings:
amba_xppu: indirect-bus@1 { compatible = "indirect-bus"; #address-cells = <0x2>; #size-cells = <0x2>;
lpd_xppu: xppu@ff990000 { compatible = "xlnx,xppu" #interconnect-cells = <0x0>; reg = <0x0 0xff990000 0x0 0x1000>; };
pmc_xppu: xppu@f1310000 { compatible = "xlnx,xppu" #interconnect-cells = <0x0>; reg = <0x0 0xf1310000 0x0 0x1000>; }; };
amba { ethernet0: ethernet@ff0c0000 { interconnects = <&lpd_xppu 0x234 &pmc_xppu 0x234>; firewall = <&lpd_xppu>; // XXX };
can0: can@ff060000 { firewall = <&lpd_xppu>; // XXX };
mmc0: sdhci@f1050000 { interconnects = <&lpd_xppu 0x243 &pmc_xppu 0x243>; firewall = <&pmc_xppu>; // XXX };
serial0: serial@ff000000 { firewall = <&lpd_xppu>; // XXX }; };
# Interconnect Bindings for Bus Firewalls
- Reuse the same controller for both QoS and Firewall configurations
- Add two new consumer properties - interconnects-master (and #interconnect-master-cells) - interconnects-slave (and #interconnect-slave-cells)
- Specify both master and slave firewall interactions
- Keep the QoS data and Firewall data separately
Example:
amba_xppu: indirect-bus@1 { compatible = "indirect-bus"; #address-cells = <0x2>; #size-cells = <0x2>;
lpd_xppu: xppu@ff990000 { compatible = "xlnx,xppu" #interconnect-cells = <0x1>; #interconnect-master-cells = <0x1>; #interconnect-slave-cells = <0x0>; reg = <0x0 0xff990000 0x0 0x1000>; };
pmc_xppu: xppu@f1310000 { compatible = "xlnx,xppu" #interconnect-cells = <0x1>; #interconnect-master-cells = <0x1>; #interconnect-slave-cells = <0x0>; reg = <0x0 0xf1310000 0x0 0x1000>; }; };
amba { ethernet0: ethernet@ff0c0000 { interconnects = <&lpd_xppu QOS &pmc_xppu QOS>; interconnects-master = <&lpd_xppu 0x234 &pmc_xppu 0x234>; interconnects-slave = <&lpd_xppu>; };
can0: can@ff060000 { interconnects-slave = <&lpd_xppu>; };
mmc0: sdhci@f1050000 { interconnects-master = <&lpd_xppu 0x243 &pmc_xppu 0x243>; interconnects-slave = <&pmc_xppu>; };
serial0: serial@ff000000 { interconnects-slave = <&lpd_xppu>; }; };
# Interconnect Bindings for Bus Firewalls: Alternative
- Reuse the same controller for both QoS and Firewall configurations - Specify both master and slave firewall interactions - Distinguish between master/slave using interconnect-names - Mix QoS data and Firewall data
Example:
amba_xppu: indirect-bus@1 { compatible = "indirect-bus"; #address-cells = <0x2>; #size-cells = <0x2>;
lpd_xppu: xppu@ff990000 { compatible = "xlnx,xppu" #interconnect-cells = <0x1>; reg = <0x0 0xff990000 0x0 0x1000>; };
pmc_xppu: xppu@f1310000 { compatible = "xlnx,xppu" #interconnect-cells = <0x1>; reg = <0x0 0xf1310000 0x0 0x1000>; }; };
amba { ethernet0: ethernet@ff0c0000 { interconnects = <&lpd_xppu 0x234 &pmc_xppu 0x234 &lpd_xppu 0x0 &qos_controller QOS>; interconnects-names = "master", "master", "slave", "qos"; };
can0: can@ff060000 { interconnects = <&lpd_xppu>; interconnects-names = "slave"; };
mmc0: sdhci@f1050000 { interconnects = <&lpd_xppu 0x243 &pmc_xppu 0x243 &pmc_xppu 0x0>; interconnect-names = "master", "master", "slave"; };
serial0: serial@ff000000 { interconnects = <&lpd_xppu>; interconnects-names = "slave"; }; };