Two questions on Flattened Device Tree, newbus and device driver attaching

Matías Perret Cantoni perretcantonim at gmail.com
Sun Aug 3 19:41:26 UTC 2014


Hello everyone!
I'm working with FreeBSD on the Zedboard (ported by Thomas Skibo
<http://www.thomasskibo.com/zedbsd/>). Currently I'm trying to fully
understand how the Flattened Device Tree (FDT) mechanism works and how it
integrates with FreeBSD. What I've already understand (I think) is:

    (1) how to represent devices, memory mapping/ranges, interrupts, etc...
in a Device Tree Source (DTS) file,
    (2) how  the newbus framework works, and
    (3) how the kernel manages resources, devices and drivers.

Although I've read all the documents I could find (and some source code)
there are still two things I don't understand:

*1) The DTS source file and CPUs definition:*

 The DTS file for the zedboard, /release/10.0.0/sys/boot/fdt/dts/zedboard.dts
(here
<https://svnweb.freebsd.org/base/release/10.0.0/sys/boot/fdt/dts/zedboard.dts?revision=260789&view=markup>),
has the CPU definition all commented out:

   ...
   // cpus {
   //      #address-cells = <1>;
   //      #size-cells = <0>;
   //      cpu at 0 {
   //              device-type = "cpu";
   //              model = "ARM Cortex-A9";
   //      };
   // };
   ...

This sounds really strange to me! How can the system tell the CPU it's
running on? I'v found some other DTS files for other boards that *do
define* it's
CPUs. For example:

imx53x.dtsi: (here
<https://svnweb.freebsd.org/base/release/10.0.0/sys/boot/fdt/dts/imx53x.dtsi?view=markup>
)

    ...
    cpus {
            #address-cells = <1>;
            #size-cells = <0>;

            cpu at 0 {
                    device_type = "cpu";
                    compatible = "ARM,MCIMX535";
                   reg = <0x0>;
                   d-cache-line-size = <32>;
                   i-cache-line-size = <32>;
                   d-cache-size = <0x8000>;
                    i-cache-size = <0x8000>;
                    l2-cache-line-size = <32>;
                    l2-cache-line = <0x40000>;
                    timebase-frequency = <0>;
                    bus-frequency = <0>;
                    clock-frequency = <0>;
            };
    ...

or:

p1020rdb.dts (here
<https://svnweb.freebsd.org/base/release/10.0.0/sys/boot/fdt/dts/p1020rdb.dts?view=markup>
)

   ...
   cpus {
          #address-cells = <1>;
           #size-cells = <0>;

           PowerPC,P1020 at 0 {
                   device_type = "cpu";
                   reg = <0x0>;
                   next-level-cache = <&L2>;
           };

           PowerPC,P1020 at 1 {
                   device_type = "cpu";
                   reg = <0x1>;
                   next-level-cache = <&L2>;
           };
   };
   ...

*So my first question is: How can the system tell on wich CPU it running
on? can I add the CPUs definition in my DTS file?*

2) The 'compatible' property of a node, finding the driver and attaching it
to the corresponding newbus node: During autoconfiguration the the .dtb
(device tree blob) file is parsed and for each node of the device three the
autoconfiguration systen will create a new newbus node (with
device_add_child()) and then it will find a suitable driver for it and will
attach it:

*/
* This function is the core of the device autoconfiguration
* system. Its purpose is to select a suitable driver for a device and
* then call that driver to initialise the hardware appropriately. The
* driver is selected by calling the DEVICE_PROBE() method of a set of
* candidate drivers and then choosing the driver which returned the
* best value. This driver is then attached to the device using
* device_attach().
*
* The set of suitable drivers is taken from the list of drivers in
* the parent device's devclass. If the device was originally created
* with a specific class name (see device_add_child()), only drivers
* with that name are probed, otherwise all drivers in the devclass
* are probed. If no drivers return successful probe values in the
* parent devclass, the search continues in the parent of that
* devclass (see devclass_get_parent()) if any.
*
* @param dev the device to initialise
*/

int device_probe(device_t dev)

(I extracted this from here
<https://svnweb.freebsd.org/base/release/10.0.0/sys/kern/subr_bus.c?revision=260789&view=markup>
)

I believe that the autoconfiguration system uses the
fdt_node_check_compatible() function (from fdtlib
<https://svnweb.freebsd.org/base/release/10.0.0/sys/contrib/libfdt/libfdt.h?revision=260789&view=markup>)
to get the "compatible" property out of each node of the .dtb blob and then
it calls device_probe() to find the best driver and attach it to the
corresponding newbus node. (is this correct?).

>From the ePAPR
<https://www.power.org/wp-content/uploads/2012/06/Power_ePAPR_APPROVED_v1.1.pdf>
standard
we have this:

2.3.1 compatible
Property: compatible
Value type: <stringlist>

Description: The compatible property value consists of one or more strings
that define the specific
programming model for the device. This list of strings should be used by a
client program for
device driver selection. The property value consists of a concatenated list
of null terminated
strings, from most specific to most general. They allow a device to express
its compatibility
with a family of similar devices, potentially allowing a single device
driver to match against
several devices.
The recommended format is “manufacturer,model”, where manufacturer is a
string describing the name of the manufacturer (such as a stock ticker
symbol), and model
specifies the model number.

Example:         *compatible=“fsl,mpc8641-uart”, “ns16550";*

 In this example, an operating system would first try to locate a device
driver that supported
fsl,mpc8641-uart. If a driver was not found, it would then try to locate a
driver that supported
the more general ns16550 device type.


*What I don't understand is how the system locates a device driver based on
the compatible property. For example the cpu node's compatible property
("ARM,MCIMX535") of the imx53x.dtsi example. More precisely: How can the
system relate the string "ARM,MCIMX535" with the actual device driver in
the file system.*

I hope my questions are clear enough. Many thanks in advance.

Best regards, Matías.-


More information about the freebsd-arm mailing list