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