WEBVTT

00:00.000 --> 00:15.000
All right, the next talk is a lot of words about how devices modelled in Linux, but please.

00:15.000 --> 00:29.000
Hi, so I review mostly driver code and I realize that sometimes there seems to be some confusion on what different types of firmware notes are and what they are at all.

00:29.000 --> 00:38.000
So I decided to deliver this talk, I'm going to do a short recap of the driver model, how we discussed how we did things in the past and how we're doing them now.

00:38.000 --> 00:45.000
I work for Qualcomm and I maintain a couple of things in the Linux and my work revolves mostly on my own.

00:45.000 --> 00:55.000
So the driver model, the driver model was created to abstract the code that is common to all device drivers and Linux, and we have three principles or actors.

00:55.000 --> 00:59.000
We have the device, we have the driver and bus.

00:59.000 --> 01:08.000
So devices represented in the kernel by struct, by structure called struct device, and this is the logical representation of a hardware component.

01:08.000 --> 01:14.000
Not necessarily one to one, we can have multiple struct devices representing a single component or the other way around.

01:14.000 --> 01:21.000
We can have logical struct devices for where there are no real actual discrete hardware components.

01:21.000 --> 01:28.000
We have the driver driver is a set of instructions telling Linux how to deal and how to control a device.

01:28.000 --> 01:38.000
And finally we have the bus, and bus is the entity whose task is to manage, matching and attaching devices to drivers.

01:38.000 --> 01:52.000
A driver always has to have a bus type assigned, and a bus can actually be a device driver that exports a bus that manages a different type of device drivers.

01:52.000 --> 01:59.000
How does Qualcomm practice? So we have a bus and it contains two lists and maintains a device list and a driver list.

01:59.000 --> 02:11.000
And when a driver appears, so let's populate the driver list with some drivers, this is equivalent to registering your driver in a kernel module, and then a device appears.

02:11.000 --> 02:17.000
So what the bus will try to do, it will try to match the device, the new device with every driver.

02:17.000 --> 02:23.000
So let's try driver zero, didn't match, let's try the second one, okay, this one match.

02:23.000 --> 02:27.000
So that means that this driver can actually control this device.

02:27.000 --> 02:33.000
So the next step is attaching the device to the driver. So we do something that we refer to as probing.

02:33.000 --> 02:37.000
We try to attach the device to the driver and it works.

02:37.000 --> 02:45.000
So that means that this driver and this device can work together. So we consider now the driver, the device to be bound to the driver.

02:45.000 --> 02:48.000
So let's consider another device that appears on the bus.

02:48.000 --> 02:54.000
We try again, we try to match it. It doesn't match. Try to match it with a second driver. Okay, now it matches.

02:54.000 --> 03:04.000
Let's try to probe it. Oh, no, it doesn't work. Probably for what does mean? This means that this driver, this device and this driver can work together, but there's something missing some resource.

03:04.000 --> 03:10.000
So we put it into a queue and we wait for more devices to appear. Okay, we have another device.

03:10.000 --> 03:20.000
This one matches, this one probes. And now we can try to reprobe the device that was previously different.

03:20.000 --> 03:26.000
Okay, now it works. So something provided by device number two was needed by device number one.

03:26.000 --> 03:34.000
And if we add another driver, what we do will do, we will just go through the list of existing devices and try to match them.

03:34.000 --> 03:44.000
Okay, so how are devices that don't just automatically appear on the bus can be discovered and instantiate in the Linux kernel?

03:44.000 --> 03:52.000
So for that we use something called the platform bus and also some other more exotic buses, but that's for another.

03:52.000 --> 03:59.000
That's that's not really for another talk. So what is the platform bus? The platform devices are the devices that you cannot really discover.

03:59.000 --> 04:06.000
You need to describe them in the firmware. And this will be typically the low level devices on your system.

04:06.000 --> 04:16.000
And why do they need to be described? Because let's imagine that you have the same device used in different on different boards and they are wire differently.

04:16.000 --> 04:23.000
Or even you have the same IT you reused in different SOCs, but they are implemented in a bit different way.

04:23.000 --> 04:31.000
So Linux needs to know what register range to map for a device or which clock to enable or which regulator GPI or what not.

04:31.000 --> 04:39.000
And the platform driver just says not me this or give me this and able this.

04:39.000 --> 04:45.000
And it wouldn't be very portable if that driver tries to actually access the system registers. So we abstract that away.

04:45.000 --> 04:52.000
Because there is no problem in computer science that cannot be fixed with another layer of abstraction.

04:52.000 --> 04:59.000
So how do you reuse the same platform driver, the same device that just wired a bit differently on a different system.

04:59.000 --> 05:07.000
So we do along with the device driver, sorry, along with the device, we also need to pass some information describing it to the driver.

05:07.000 --> 05:10.000
How did we do that historically?

05:11.000 --> 05:15.000
Before we had a thing called device 3 we used to use board files.

05:15.000 --> 05:25.000
Of course there were other ways, but I have an ARM BIAS and X86 faultful probably remember different mechanisms.

05:25.000 --> 05:36.000
So this is your typical ARM board file. And what you do, you have some resources, you have some platform data, you have the definition of the device and then you register it in code.

05:36.000 --> 05:43.000
But this comes with a lot of problems. So when you do that in C code, you have strict ordering, no parallelization.

05:43.000 --> 05:52.000
You mix harder description with functional logic and you have a lot of hand coded dependencies, random callbacks all over the place.

05:52.000 --> 05:58.000
Adding anything new, sometimes requires reordering, debugging and whatnot.

05:59.000 --> 06:08.000
And while some things were done right and an example is the track resource which exists has existed for decades and still exists and is still used.

06:08.000 --> 06:15.000
Some things didn't age very well among them platform data. So how did it work?

06:15.000 --> 06:25.000
Each platform driver would define its own custom structure and board files would fill that structure in and pass it to along on the device to the driver.

06:25.000 --> 06:29.000
And that would be quite repetitive. You would have hundreds of different platform data structures.

06:29.000 --> 06:41.000
But what they store are typically integers and strings and possibly also pointers to callbacks that would be defined in the board files and would be responsible for setting up clock regulators and whatnot.

06:41.000 --> 06:47.000
So the latter, that has mostly been abstracted away into driver substance subsistence nowadays.

06:47.000 --> 06:53.000
And if what you're left with is mostly integers and strings, then it probably can be done better.

06:53.000 --> 06:55.000
And third device three.

06:55.000 --> 07:02.000
So device three is called a device three because the device a cyclic directed graph wasn't a very sexy name.

07:02.000 --> 07:08.000
This is a data structure that has both text and binary format and this platform's hardware.

07:08.000 --> 07:14.000
And we have a compiler dedicated called device to compiler DTC that is used to translate between the two formats.

07:14.000 --> 07:21.000
And notes in device three are ordered in a parent child fashion and also talking from a root.

07:21.000 --> 07:27.000
And we also can reference notes from other notes using what we call p handles.

07:27.000 --> 07:31.000
This is just a bit of a device three in text format.

07:31.000 --> 07:35.000
You have your properties. You have your references to other notes.

07:35.000 --> 07:43.000
You can use the so-called hash properties to define, for instance, number of expected p handle arguments.

07:43.000 --> 07:51.000
You have your child notes. And there are also some more advanced concepts like drafts and whatnot.

07:51.000 --> 07:58.000
But in Linux, in general, all upstream device resources should conform with.

07:58.000 --> 08:05.000
With device three bindings, which are YAML documents that define expected properties, their format meaning and whatnot.

08:05.000 --> 08:17.000
And Linux, at boot, it parses the binary form of device three and creates a tree in memory or a cyclic directed graph in memory of structures called device notes.

08:17.000 --> 08:25.000
And also exposes a set of interfaces for accessing this data from drivers.

08:25.000 --> 08:38.000
So when you have the example that we had before, you can use the functions in the kernel that use the OS prefix for accessing the data strings, integers, lists, p handles.

08:38.000 --> 08:41.000
And you can iterate over child notes.

08:41.000 --> 08:52.000
So now this is not the only data format that uses notes and concepts like children references to other notes and whatnot.

08:52.000 --> 09:05.000
So we have this, but we also have a CPI, which isn't the same, but can we use a certain number of concepts.

09:05.000 --> 09:09.000
And we have software notes about which I'm going to be talking in a minute.

09:09.000 --> 09:15.000
So they're powered by their power combined. We created something that is called the firmer note interface.

09:15.000 --> 09:20.000
So this is just a generalization of this firmer description.

09:20.000 --> 09:29.000
And if you want to generalize your off-centric system to firmer notes, your device note will become an FW note handle.

09:29.000 --> 09:33.000
P handles become references, graphs from graphs and graphs.

09:33.000 --> 09:39.000
And users drivers can freely translate between the two using the provided interfaces.

09:39.000 --> 09:54.000
So if we go back to our example, instead of using the OS interfaces, if we translate our device note to the firmer note, we now can use the FW note properties to, for most parts do all the same operations.

09:54.000 --> 10:04.000
They are not one to one, and there's some functionality in firmer note that is missing from, sorry, in of OS notes that is missing from the firmer notes, but for most part they can be used.

10:04.000 --> 10:12.000
What are software notes? So some devices don't have real firmer notes associated with them or they are incomplete.

10:12.000 --> 10:17.000
So this is where you can fill in those gaps in software.

10:17.000 --> 10:27.000
Software notes are basically C structure that are defined statically and they are registered at runtime, and they also have a parent shot relationship.

10:27.000 --> 10:29.000
You can also reference other notes.

10:29.000 --> 10:45.000
And if you look at that and you tell to yourself, well, this is just platform data with extra steps, then you are right, but also with this, we have the abstraction that allows drivers to use the same code to access data defined in firmer and in software.

10:45.000 --> 11:07.000
And can we have both, can we mix the two OF notes or ACPI notes and software notes? Yes, we have a concept called secondary firmer notes where a firmer note can have an additional reference to, to a software note from which we can complete its information about the device.

11:07.000 --> 11:19.000
So so far, we've been talking about mostly about the parent shot relationship, but we also have to talk more about sibling relationships or other maybe supplier consumer.

11:19.000 --> 11:29.000
So let's imagine that we have a system where we have a Mac and this Mac needs to function and say phi and a clock.

11:29.000 --> 11:39.000
So the Mac and the clock are the children of the SOC and the clock we can consider the supplier to the internet Mac and same phi.

11:39.000 --> 11:47.000
But the thing is that if the phi and the clock is not there, then there is no reason to even try to probe the Mac.

11:47.000 --> 12:12.000
That's why we have a thing where from the firmer information like device 3, we can infer what the relationships between the device are, who is supplier of whom and we can actually make sure that we don't pass that we don't try to probe the Mac before we have successfully probe the phi and the clock.

12:12.000 --> 12:31.000
So if you look at all those interfaces that we have, like to give you an example, there is this thing called recurrent laryngeal nerve in our bodies which is a nerve that controls the larynx, the speech and it goes from your brain all the way under the hour time and then all the way back.

12:31.000 --> 12:39.000
And if you consider an animal like giraffe with a very long neck, it actually does go all the way down and all the way up.

12:39.000 --> 12:46.000
This is the result of evolution which is just good enough and it isn't an intelligent design.

12:46.000 --> 12:59.000
So it's the same with the kernel. The interfaces have evolved, evolved over many, many years and through many iterations and not all of them were done perfectly from the get go.

12:59.000 --> 13:14.000
So this is why we have so many different interfaces. If we did it from the start now, we would probably have ended up with a single firmer note interface, but we have all these other interfaces as well that we mix.

13:14.000 --> 13:25.000
So to explain why the kernel is a bit like a giraffe programming guide. If you're writing a kernel driver, which interfaces do use.

13:25.000 --> 13:43.000
If you have a struck device and you don't need to do anything complex like resolving references to other notes use the interfaces that start with device underscore they go to the firmer note and they are the highest fraction layer for retreating information for devices.

13:43.000 --> 13:55.000
If you take the example from before, this is what interfaces you can use to retrieve the information from that piece of device to use firmer note APIs.

13:55.000 --> 14:08.000
If you need to, if your device note has children that carry important information, you may need to iterate over the child firmer note.

14:08.000 --> 14:21.000
This is where you start using the FW note API. Also you may need to extract information from a note that is not associated with an actual device doesn't exist yet.

14:22.000 --> 14:34.000
When to use the very low level API like the OF functions, you may need to iterate over all the properties of a firmer note that's not possible or not possible yet.

14:35.000 --> 14:50.000
And also you may need, if you may need to set up software notes, for software notes you need to set them up before you register up here register them.

14:50.000 --> 14:55.000
Before you register them, you refer to them as software notes using their low level APIs.

14:55.000 --> 15:00.000
If the register they become full firmer notes and this is where you should switch to the higher level API.

15:00.000 --> 15:10.000
So this is like something like this device underscore, it's better than FW note than FW note or FW note and ACPI so the low level APIs.

15:10.000 --> 15:20.000
Yeah, that's it. Sorry, I have to bring really fast because I wanted to fit into their hands.

15:22.000 --> 15:27.000
All right, questions.

15:27.000 --> 15:56.000
So since there are some drivers that needs to take information from software as a firmer note, is that possible that more drivers have to adopt the firmer note, the conventional instead of

15:56.000 --> 16:24.000
the OF note or the ACPI note, if for example in some devices, can run ACPI have ACPI and the device tree, for example, is it possible to transform the drivers to use either ACPI and what is the situation now in the kernel for those drivers.

16:24.000 --> 16:36.000
So if you are writing a new driver, there's no reason to use OF interfaces. You should use either the device or as a second option, the firmer note interface.

16:36.000 --> 16:43.000
If you're writing a new driver, even if it's OF only for now, there's no reason to not use the firmer note abstraction.

16:43.000 --> 16:50.000
And if you need to enable firmer note abstraction and an OF centric driver, then yeah, that's the way to do it.

16:55.000 --> 17:01.000
Maybe a bit a little out of topic, but is support for MacFise really there?

17:01.000 --> 17:12.000
Because it was a new example, but I thought all week with a FI driver for another FI, not probing before it's consumer, so the Mac.

17:12.000 --> 17:18.000
I saw something on the lore about this leveling, not really working for MacFise.

17:18.000 --> 17:21.000
Oh, I don't have an answer, but I will find out.

17:24.000 --> 17:41.000
Hi, God. So good presentation. I like that you made it eventually.

17:41.000 --> 17:47.000
Not really the equation, but one additional information maybe to audience and to you as well.

17:47.000 --> 17:59.000
There is an activity for this big devices like DSAs and PCAx extension cards with full computer on them.

17:59.000 --> 18:05.000
That week could run on ASAP by the system, so actually we could run device three overways.

18:05.000 --> 18:13.000
And when you say about or have specific APIs, in some cases it's used even in ACP enabled systems.

18:13.000 --> 18:19.000
So it's really interesting case to maybe mention.

18:19.000 --> 18:26.000
I will update the talkifier, we do it.

18:26.000 --> 18:30.000
Possibly a last question, thank you.

18:30.000 --> 18:37.000
Based on what you mentioned, I understand that the FW interface can do anything that the OS is not anything.

18:37.000 --> 18:40.000
I mentioned there are a couple of things that they cannot do.

18:40.000 --> 18:41.000
It can do no.

18:41.000 --> 18:42.000
It can do no.

18:42.000 --> 18:49.000
So does this mean the OS one would eventually be replaced by the other entirely?

18:49.000 --> 18:56.000
So I don't think so, but for most use cases it probably could.

18:56.000 --> 18:59.000
But there's no chance of deprecating the other one.

18:59.000 --> 19:09.000
Well, there are still things that we do like device three overways dynamic or F notes and what not that we'll probably have to keep it around.

19:09.000 --> 19:19.000
I think but I don't think we can entirely get rid of it, but probably we can use FW note interface.

19:19.000 --> 19:25.000
In most use cases, normal use cases not doing anything over the complex.

19:25.000 --> 19:28.000
All right, thank you very much.

