WEBVTT

00:00.000 --> 00:13.120
Okay, good. Hello. My name is Patrick Woolowiv and I'm working at my

00:13.120 --> 00:20.400
elements and last year I got the chance to work on U-Boot and actually getting

00:20.400 --> 00:32.080
paid for it. So let's get started. So I got a task. The task was to enable the

00:32.080 --> 00:39.600
SPSA on Raspberry Pi 4 within U-Boot and yeah that's what my daughter is about

00:39.600 --> 00:46.240
about the journey that was necessary to get this done. So the ARM SPSA is a

00:46.240 --> 00:55.360
specification released by ARM. It's intended for server platforms for 64 bit

00:55.360 --> 01:02.720
server platforms and the specification points to the BBR that's the base boot

01:02.720 --> 01:10.240
requirements specification for such servers. And I use this specification to

01:10.240 --> 01:17.760
implement the changes in U-Boot to get it working. Okay, so let's have a look at

01:17.760 --> 01:29.200
the specification. It mandates several items. Some of those were already implemented.

01:29.200 --> 01:35.680
So UFI support and the PSCI support were already done in U-Boot so I don't

01:35.680 --> 01:44.160
had to work on this. It also mandates ACPI support and yeah that's what I implemented.

01:44.160 --> 01:52.080
It also mandates SMBIOS. That's something I did not look at. It's currently not implemented.

01:52.080 --> 01:58.800
Ever it's not required to boot an operating system. It works without SMBIOS.

01:59.760 --> 02:05.520
Yeah, first of all let's have a look at the device three. It's usually used on

02:05.520 --> 02:12.480
embedded platforms like the Raspberry Pi 4 and it's typically not used on server platforms.

02:13.600 --> 02:18.000
While the specification, the SPSA is especially for server platforms.

02:19.280 --> 02:25.360
The device describes what your hat looks like and it allows an operating system or a boot

02:25.440 --> 02:36.640
loader to identify components. One-year computer to load drivers and yeah it allows to reuse

02:36.640 --> 02:42.160
drivers across various computers. So you don't have to know what computer you run on you just

02:42.160 --> 02:48.080
need a device. It tells you everything you need to know. And on the other hand there's ACPI

02:48.880 --> 02:57.840
and it was a replacement for the BIOS. Back in the days you had no chance to know

02:57.840 --> 03:05.120
what hardware you running on or you could do it's called into the BIOS. It was 16-bit code.

03:05.120 --> 03:13.120
It was very slow, very buggy, Windows Pacific and just the pain to deal with. That's why ACPI

03:13.120 --> 03:20.320
was invented. Again, it just describes the hardware. There's the binary representation.

03:22.160 --> 03:29.760
So you compile your ACPI source code into a binary code but it's lossless so you can convert it back

03:29.760 --> 03:40.240
if you want basically disassemble it. On ACPI you have two different kinds of code. You have

03:41.200 --> 03:47.760
tables and you have AML byte code and the AML byte code requires an interpreter in

03:47.760 --> 03:54.400
the US or the boot loader. So that's kind of different compared to the device tree. The device tree

03:54.400 --> 04:00.000
is just a data structure. You don't need an interpreter. Of course you need to understand the data

04:01.680 --> 04:09.200
but ACPI is more complex but on the other hand allows you to give you more control over your computer.

04:10.880 --> 04:17.360
ACPI tables need to be loaded into the DRAM. Usually that's a standby firmware or the boot loader.

04:20.560 --> 04:24.960
Just a short explanation about ACPI so there are multiple tables in your DRAM.

04:26.640 --> 04:34.960
For example the RSTP it just points to another table inside the table multiple pointers to

04:34.960 --> 04:42.240
again different ACPI tables because you can have multiple inner system. Some of those are

04:42.800 --> 04:49.680
like the FADT, the DSTT which contains the byte code I talked about.

04:50.960 --> 05:01.600
But we're look kind of different. So we have a specific name that can be chosen by the

05:02.560 --> 05:11.920
firmware vendor or the manufacturer. We have an identifier that identifies the hardware. In this

05:11.920 --> 05:23.360
case it's an PLO11uart. We have a property that describes where to find this. A specific hardware

05:23.440 --> 05:34.320
here it's a memory mapped at address and has a fixed length and in the end there's also

05:34.320 --> 05:41.840
a status or field that says it's actually enabled and working in your computer.

05:41.840 --> 05:54.880
What can we do to patch the device free? Usually device free is loaded from the spy flash

05:54.880 --> 06:03.280
or provided by early stage boot loader and then you have to modify it to add user specific settings,

06:03.280 --> 06:14.240
port specific settings, change the boot order or the command line. You can do it in line or

06:15.520 --> 06:23.040
unflatten the whole binary device free. Do modifications and then pick it again that means converted

06:23.120 --> 06:30.880
into a binary representation and an example that is given here is used in a huboot.

06:35.440 --> 06:41.920
On the other hand we have the ACPI byte code. Again this can be in line patched.

06:42.720 --> 06:50.000
However currently there's no firmware that allows to parse it, modify it and generate a

06:50.000 --> 06:58.560
amount of byte code of it. What's supported is just generating it at runtime that's usually done in

06:58.560 --> 07:03.680
C. Here's an example how the inline patching is done.

07:07.920 --> 07:16.800
Okay so we look at the computer, the two shows, the other firmware solutions that exist

07:16.880 --> 07:26.880
like QMO, UFI or cobbled that are able to generate ACPI on ARM64.

07:29.120 --> 07:37.040
So the simplest solution is use kernel. It generates ACPI code for your run your virtual machine.

07:38.160 --> 07:45.040
It's just copied into the virtual machine and it allows to you to run your kernel directly.

07:46.000 --> 07:52.480
So that's not an example for us because there's basically no firmware and waft it just works.

07:54.000 --> 08:01.040
Then there are firmware-based solutions so you can run fobbled, EDK2 or Uboot in your virtual machine.

08:02.160 --> 08:10.720
But again it just uses an MMI origin to copy the ACPI tables into the DRAM of the virtual machine.

08:11.680 --> 08:21.760
So even though it's using a firmware, it's not a good example. But it has murking ACPI support on ARM64.

08:29.280 --> 08:40.000
Yeah so UFI. UFI usually has all their ACPI tables in flash. It just loads them from flash places it in DRAM.

08:41.360 --> 08:45.680
And then it's modified in DRAM or in place.

08:48.000 --> 08:53.440
UFI does not use a device tree just hard codes defines them the DCFi.

08:54.400 --> 09:03.200
Similar our cobbled is able to load the STT from flash, place the table in DRAM and all other tables

09:03.200 --> 09:10.320
generated at run time using C code. It does not use a device tree. It has something similar

09:10.400 --> 09:16.800
called device tree.cb but that actually converted into a C file when you build cobbled.

09:18.320 --> 09:26.720
It's possible to generate a STT code as seen here in the example so you call tons of C functions

09:26.720 --> 09:34.000
that generate a MMI byte code. At this point I want to thank Simon Glass.

09:34.960 --> 09:43.040
He started the ACPI enablement on Raspberry Pi 4 back in 2021 and he did a lot of reviewing

09:43.920 --> 09:51.920
and the whole process of upstreaming. And also I want to thank my colleague Max. He picked up Simon's

09:52.000 --> 10:02.800
work, polished the code, moved everything into come folders and then we just call the come code.

10:04.080 --> 10:11.280
I took that over last year July, polished it for upstreaming, sent it upstream and it was denied.

10:11.280 --> 10:18.080
So let's look why. So there were several dues and owns by the maintainers and here at DRAM.

10:18.800 --> 10:23.840
So they said we need an emulated mainboard first so the Raspberry Pi is not an emulated mainboard.

10:25.040 --> 10:31.200
It's not a good example. Start with something else. Because we need to make sure it works

10:31.200 --> 10:38.320
for everybody we can use the CI to run the new code and it allows everybody to confirm the change of

10:38.320 --> 10:46.560
stuff. And they also said device refers to. So not using C code but everything need to be defined

10:46.560 --> 11:00.080
in the device tree. So the issue is this is an ACPI only platform. I will show that in next slide.

11:00.800 --> 11:07.360
And they also said you would drive us should take care of the ACPI code generation by just reading

11:07.360 --> 11:15.760
the device tree. So don'ts are no static, the STTAML code and no static, basically I tables and

11:15.760 --> 11:25.840
C code that are just placed in DRAM. So I added support for the kernel SPSA ref platform that's designed

11:26.800 --> 11:32.960
around the specification by ARM. It provides a minimum of the device tree and nothing else.

11:32.960 --> 11:38.640
It doesn't provide ACPI tables, it doesn't have sort of a config interface. It just gives you a

11:38.640 --> 11:47.200
very, very small device tree and that's it. So what I had to do is add a property-wise T because

11:47.200 --> 11:55.120
that was mandated by your boot developers. And what we do is currently on that platform we merge

11:55.200 --> 12:00.560
the device tree. So there's one that's included into the U-bit binary. There's one that's given by

12:00.560 --> 12:07.280
QMO. Both emerged and then we got a complete device tree for that specific virtual machine.

12:10.480 --> 12:17.840
So the U-bit drivers then match against the compatible string. See here in this example.

12:18.720 --> 12:26.000
And every U-bit driver has something in-board specific or sox-specific C code that generates

12:26.000 --> 12:34.640
those tables. But the ultimate goal is to have just U-bit drivers to generate every ACPI table

12:34.640 --> 12:42.320
in your system by just reading device tree notes. So the Upspinning status,

12:42.480 --> 12:52.160
it was quite a lot of work, much more than expected. I added two boards, the QMO SPSA ref board,

12:52.960 --> 12:58.800
a virtual machine. And the Raspberry Pi 4, with ACPI enabled.

13:00.240 --> 13:07.040
Upspinning completed in 2024. You can check out the release tag that has all the patches included.

13:07.680 --> 13:20.480
So let's review the original task. So I had a basic ACPI support. It works on the Raspberry Pi 4

13:20.480 --> 13:28.640
virtual machine boots on real hardware, but it's not SPSA compliant. Just because the hardware

13:28.720 --> 13:39.520
itself is an embedded platform. It doesn't fulfill this specification. This sox support is also

13:41.760 --> 13:50.160
let's say experimental. It doesn't implement org works. Not all Linux drivers will load or work

13:50.160 --> 14:01.040
correctly, just because it's a very special platform and if lots of special road-con drivers

14:01.040 --> 14:08.000
that needs to be adapted to work with the ACPI. There's an official EDK2 firmware that you can use

14:08.000 --> 14:18.080
on Raspberry Pi 4 that has proper ACPI support. And here's some future plans. So the

14:18.080 --> 14:27.920
adheres to the grid of all the STTAML code, the grid of all the table generation and mainboard code

14:27.920 --> 14:34.480
and subcode and just have your boot drivers to write out tables by powerling the device through.

14:35.760 --> 14:40.480
Also to enable more boards, because currently it's just the Raspberry Pi 4 and the

14:40.480 --> 14:48.240
emulated platform. That's it for my side. Do you have any questions?

14:55.840 --> 15:01.120
Yeah. In two questions, does Hubode still pass the device to binary to the kernel

15:01.680 --> 15:08.800
and how do you deal with overlays in the case of ACPI? So the first question is does Hubode pass the

15:08.800 --> 15:14.880
device through to the kernel? No. So the ideas that only ACPI tables are passed to the kernel,

15:14.880 --> 15:19.360
no device free is provided. And the second question was,

15:26.640 --> 15:37.600
So the device free overlays, I'm not sure if the device free overlays are used within Hubode,

15:38.560 --> 15:45.520
on Raspberry Pi 4. Because currently Hubode is not the first firmware that runs,

15:45.520 --> 15:53.520
there are several other firmware or boot loaders that start before Hubode actually runs. And in the end,

15:53.520 --> 16:02.560
Hubode just gets a complete device free, something that's assembled already and ready for proper use.

16:02.560 --> 16:10.320
That's it, answer your question? Okay, let's go. Next question.

16:32.560 --> 16:36.880
How did you know that Hubode has denied the device that they are not in the board? Because then they

16:36.880 --> 16:43.680
can push all the clock so power the main skeleton to the ACPI, to the ML, etc. Then forget about that.

16:45.920 --> 16:50.400
Isn't possible if you are approached to do that? Isn't possible if you are approached to do that?

16:55.200 --> 16:57.200
Yeah.

16:57.200 --> 17:21.760
Yes, it's possible. So you have to write drivers for everything to generate proper ACPI code for

17:21.760 --> 17:31.600
power domains for clock domains, but it shouldn't be, it should be status and power states for

17:31.600 --> 17:39.440
the device. That's the point. Yeah, I guess you can read this. Yeah, sorry, nice.

