WEBVTT

00:00.000 --> 00:10.280
Okay, let's start the next talk.

00:10.280 --> 00:18.240
My name is Marigwasheur, and today is going to be slightly different, kind of hot, hot on a

00:18.240 --> 00:20.240
sec.

00:20.240 --> 00:21.240
Better.

00:21.240 --> 00:24.600
It will be slightly different kind of talk, because I'll be talking about not you

00:24.600 --> 00:32.840
good, but I'm SAP firmware-porting this time, and just out of curiosity how many of you

00:32.840 --> 00:38.280
do know what the SAP firmware is all about, very few people, excellent.

00:38.280 --> 00:44.880
So I have a motivational slide to give you some sort of a context what this is even all

00:44.880 --> 00:48.320
about before I plant into the porting part.

00:48.320 --> 00:55.800
Hey, so contemporary embedded SOCs, they do no longer have only an A-core, which is running

00:55.800 --> 00:58.560
Linux, but they also have M cores.

00:58.560 --> 01:07.440
The M cores are running some sort of an RTOS, and the issue is, all these cores share resources,

01:07.440 --> 01:13.560
clock, pin controller, and traditionally there was no arbitration, or there was some sort

01:13.560 --> 01:19.000
of an arbitration in hardware, which was done using hardware spin logs, this kind of stuff,

01:19.000 --> 01:27.280
but the original idea was that everyone is well behaved, the articles is well behaved, the Linux

01:27.280 --> 01:32.320
is well behaved, and they cooperate not to mess up the system state.

01:32.320 --> 01:39.320
Nowadays with push towards security and isolation and so on, we can no longer depend on

01:39.320 --> 01:43.480
that, so we need some sort of an proper arbitration.

01:43.480 --> 01:50.320
So the policies of which govern whether one of the cores or the other core should be able

01:50.320 --> 01:55.360
to do some action with the system, they are increasingly more complex, so there has to be

01:55.360 --> 01:59.640
some more capable arbitrar.

01:59.640 --> 02:07.080
And this more capable arbitrar is called an SAP on newer SOCs, and it's nothing really

02:07.080 --> 02:12.520
special, it's yet another core, which is usually called the XAM, or Cortex R, it's running

02:12.560 --> 02:16.800
some sort of althinbar, and it exposes interfaces.

02:16.800 --> 02:22.800
Today, a cores, today, M cores, or whatever other CPU cores you have on your system.

02:22.800 --> 02:32.520
The arbitric core, the SAP is responsible for managing those cook, the pin moops, potentially

02:32.520 --> 02:37.720
regulators, whatever it has access to this hardware, and all the other cores, the A cores

02:37.720 --> 02:45.120
running Linux, the M cores running RTO, as they talk to this SAP, Arbitric core, and ask

02:45.120 --> 02:48.200
requests via some sort of a protocol.

02:48.200 --> 02:54.400
The other cores, they technically can manipulate with the hardware as well, but it's usually

02:54.400 --> 03:02.320
blocked by trust zone for security reasons, so they can't mess up the system state.

03:02.320 --> 03:05.680
And they have to go through the, this Arbitric.

03:05.680 --> 03:12.360
So the Arbitric core, SAP exposes some sort of interface to what all the cores, there is

03:12.360 --> 03:18.120
usually some bidirectional communication channel, based on mailbox and shared memory, although

03:18.120 --> 03:22.920
it can be something else, it's traditionally that.

03:22.920 --> 03:29.560
It works in such a way that the A cores of the M cores and commands to the Arbitric, and the

03:29.560 --> 03:36.920
Arbitric response, with some sort of a response, or the Arbitric, which is the SAP, can

03:36.920 --> 03:42.000
send notifications to the A cores to the M cores that something happened, and the A cores

03:42.000 --> 03:45.080
and M cores, acknowledge it.

03:45.080 --> 03:51.400
The commands are used for things like, okay, I'm an A core, I want the Arbitric to enable

03:51.400 --> 03:57.080
some cook, or I want the Arbitric to turn on the regulator or whatever.

03:57.080 --> 04:02.040
The Arbitric in response says, yeah, okay, action happened, or no action didn't happen

04:02.040 --> 04:04.960
denied because you cannot do this.

04:04.960 --> 04:11.040
The notifications go the other way from the SAP to the A cores M cores, and this is used

04:11.040 --> 04:14.680
for example, for shutdown notifications.

04:14.680 --> 04:20.280
So when the system is shutting down, for some reason, maybe it overheated, it sends a notification

04:20.280 --> 04:27.240
to all the cores, which says, hey, I'm going down, shutdown is happening, do your thing.

04:27.240 --> 04:31.720
On the Linux site, for example, this is handled internally, then it triggers some sort of

04:31.720 --> 04:38.200
stuff in user space, system de-us, it's own shutdown thing, and then the kernel says, okay,

04:38.200 --> 04:39.200
it's shutdown.

04:39.200 --> 04:42.240
That's why the notifications are there for them.

04:42.240 --> 04:46.800
Now, the protocol that's running on top of this, be directional channel between the

04:46.800 --> 04:55.240
SAP and the A cores and M cores is usually STMI, system control, and management interface,

04:55.240 --> 05:01.360
it's defined in arms specification, if you download the slides, you can get the latest version

05:01.360 --> 05:07.840
of the specification as of today, and it's actually not a single protocol, the SCMI,

05:07.840 --> 05:11.360
it's a collection of protocols.

05:11.360 --> 05:16.640
And it's always going to be one protocol in the SCMI, which is the base protocol, and

05:16.640 --> 05:23.240
the base protocol then allows the Linux on the A cores or the RT was on the M cores to discover

05:23.240 --> 05:27.520
what actually is supported by the SCP.

05:27.520 --> 05:35.280
The base protocol reports things like version of the SCP provider, sorry, SCMI provider,

05:35.280 --> 05:42.360
it reports the vendor of the SCMI provider, which can be used, for example, to apply

05:42.360 --> 05:48.560
for X, Linux uses this to apply for X, in case the implementation of the SCMI protocol provider

05:48.560 --> 05:54.440
is broken in some width way, but it also gives you the information which other protocols

05:54.440 --> 05:58.560
are supported by the SCMI implementation.

05:58.560 --> 06:03.680
The other protocols which can be supported by the SCMI implementation are clock protocol,

06:03.760 --> 06:12.200
regulators, sensors, power domains, all kinds of these things, there is like 15 of them.

06:12.200 --> 06:16.560
You can find the complete list in the specification.

06:16.560 --> 06:20.280
The communication with every one of these protocols is command based, so there is a bunch

06:20.280 --> 06:27.600
of commands and every one of these protocols, and this is something which every client

06:27.600 --> 06:35.760
that means Linux on the A core, RT on the M cores can invoke.

06:35.760 --> 06:47.080
All right, let's talk about the other side of it, that is the SCMI protocol provider,

06:47.080 --> 06:53.800
which is an SCP firmware that's running on the SCP control processor.

06:54.800 --> 07:02.040
Sorry, now the SCP firmware unfortunately on most of the SCC will find nowadays is

07:02.040 --> 07:07.160
not going to be open, it's some sort of a closed source stuff which is written by the vendors.

07:07.160 --> 07:13.960
Some vendors did open it, but it's their own handwritten custom code, but increasingly

07:13.960 --> 07:21.600
there is a push to make it properly open, and there is actually already an existing project

07:21.600 --> 07:27.720
from ARM, which is called ARM SCP firmware, and this is BSD3 calls, and we'll talk about

07:27.720 --> 07:33.680
this one because we do not care about the non-free and close source implementations.

07:33.680 --> 07:38.480
Keep in mind that if something is non-free and it's close source it will usually be very

07:38.480 --> 07:41.680
buggy, so just you don't want that.

07:41.680 --> 07:46.200
I guess I don't have to spell it out to this audience.

07:47.160 --> 07:50.400
So let's talk about ARM SCP firmware, what is this?

07:50.400 --> 07:56.720
It's a project which is actually hosted by ARM, it's BSD3, recalls license, it's very

07:56.720 --> 08:03.960
much self-contained, all you need to compile it is valid, cross compiler, toolchain, it only

08:03.960 --> 08:12.160
depends on new lip nano, lip gcc and STD lip, which means if you have some valid ARM

08:12.240 --> 08:20.040
on the heavy toolchain, you can just compile this and get a valid executable out of it.

08:20.040 --> 08:26.040
The ARM SCP firmware can actually run on more than just Cortex M, it can also run

08:26.040 --> 08:33.680
on R64, but in general, the Cortex M is the prime target for this.

08:33.680 --> 08:39.880
The base code is super simple, it's effectively two functions which call itself until

08:39.880 --> 08:45.640
the rich as main loop, so it's really easy to understand what's going on in there, everything

08:45.640 --> 08:51.560
else in the ARM SCP firmware is then extended by adding modules, so pretty much everything

08:51.560 --> 08:55.320
in the SCP firmware is some sort of a self-contained module, which you can include in the

08:55.320 --> 09:00.800
build or not include in the build, there's a lot of modules which are part of the SCP firmware

09:00.800 --> 09:07.200
code base, which is convenient because a lot of them are generic, some of them implement

09:08.000 --> 09:13.920
the SCMI protocol base, some of them implement the additional SCMI protocols which follow

09:13.920 --> 09:17.680
the standard, so you don't have to implement this yourself and you don't have to reinvent

09:17.680 --> 09:26.560
the real, which is convenient, and there are actually two ways how to port the SCP, I'll

09:26.560 --> 09:33.200
choose the easier way, one of the ways is that you can have the SCP actually do the full

09:33.200 --> 09:39.280
platform initialization, that means it acts as a bootloader as a BL2, this is the more complex

09:39.280 --> 09:45.760
way, the SCP will then compile two binaries, one of them which is really the full bootloader

09:45.760 --> 09:52.160
which thus the platform initialization, pin moves initialization, drum initialization, all

09:52.160 --> 10:02.000
the stuff, and then the second stage will actually run S, the SCP and handle the request on

10:02.000 --> 10:06.720
the SCMI protocol and response is and so on, but since bootloader is generally

10:06.720 --> 10:11.920
do better job at bootloader ink, we can skip the first part and only focus on the second

10:11.920 --> 10:18.880
part that means only port the SCP and let bootloader actually initialize the platform

10:18.880 --> 10:25.440
and start the SCP on the SCP core, this is additional benefit because by the time we start

10:25.520 --> 10:33.440
the SCP firmware, we will have UART initialized so if we need to start doing some printkader

10:33.440 --> 10:38.640
bugging which is or print of the bugging which is awesome, which is can because we can start

10:38.640 --> 10:42.800
writing into the UART FIFO and we will start getting characters right out of out of the UART

10:45.440 --> 10:54.560
so yeah I'll opt for the for the simpler option which is only port the SCP and before we go into

10:54.560 --> 11:01.360
that I still want to go through some terminology, if you start porting a SCP, basically the documentation

11:01.360 --> 11:07.920
the documentation is very short, very concise, it's a very good idea to read at least that

11:07.920 --> 11:12.880
because it gives you the overall concept how this whole codebase structure and how it looks

11:13.600 --> 11:18.880
and it gives you about these five keywords which are being used in this documentation which

11:18.960 --> 11:28.640
define the core keywords in the SCP codebase, the important ones are framework which is essentially

11:28.640 --> 11:35.360
the whole codebase then that is module, a module is a self contained piece of code which does

11:35.360 --> 11:42.160
something it can be a driver, it can be some sort of a service provider like an SCMI protocol,

11:42.160 --> 11:50.960
a SCMI cloud protocol implementation and element is an instance of module that means if you have

11:50.960 --> 11:56.960
say a UART driver which is a module the element would be an instance of this module which has some sort

11:56.960 --> 12:04.480
of an instance specific data attached to it say it's the UART driver which is attached to your

12:04.560 --> 12:12.960
specific UART IP at address blah blah blah that's what the element is it has it's like in terms

12:12.960 --> 12:20.640
of Linux kernel module would be the driver the element would be the driver instance that's what it is

12:22.560 --> 12:28.960
internally the SCP does message passing so there are events and notifications events are messages

12:29.040 --> 12:35.120
which can be exchanged between two elements notifications are the same thing by the broadcast

12:36.720 --> 12:42.960
and that's pretty much all you need to know to grow what's going on in the SCP internally

12:43.760 --> 12:51.760
now porting the SCP firmware itself is also actually super easy because all you have to do is

12:51.840 --> 12:57.840
comb the sources look into the product directory there is a bunch of example products already

12:57.840 --> 13:03.040
find one which is similar to what you have in your SCE what core you have in there

13:04.240 --> 13:12.800
duplicated rename it make a comment then once you have this compile the result and verify that you

13:12.800 --> 13:19.680
can actually get a binary out of it if you have a binary at this point then you effectively have

13:19.760 --> 13:26.320
some sort of an executable which you can't still run on your hardware but you know that you

13:26.320 --> 13:31.520
at least manage to fork a platform and you can compile something you get a valid result

13:32.320 --> 13:39.520
the next step is to actually figure out whether this binary could even potentially run on your hardware

13:39.520 --> 13:46.320
at all that means grab the binary run into object dumb disassembled the binary and have a look

13:46.400 --> 13:52.240
at the entry point address then look into your documentation and do your data sheet

13:52.800 --> 13:59.760
and figure out whether your cortex m which you will use as an SCP has this matching entry point

13:59.760 --> 14:06.160
address if it doesn't then look into the forked product directory there is a bunch of headers

14:06.160 --> 14:12.240
which allow you to refine the entry point address change it, recompile it and verify again

14:13.200 --> 14:20.480
at this point you will have a binary which is most likely going to be executable on your hardware

14:20.480 --> 14:27.280
because it has the right memory map now once you have that you need to figure out how to start

14:27.280 --> 14:34.480
it on your platform this unfortunately is for specific or sox specific so this is something you

14:34.480 --> 14:41.520
need to figure out based on your sox documentation if you have k-tech access that's excellent

14:41.600 --> 14:46.400
you can load it into memory and start going to core directly whatever came out of the build

14:46.400 --> 14:50.640
if you don't have k-tech access you'll probably have to write this binary somewhere into storage into

14:50.640 --> 14:59.760
flash and then somehow start it on the SCP core this is yeah sox specific so this you need to figure out

15:00.480 --> 15:06.880
but once you figure this out then the next step is to validate that there are any signs of life

15:07.680 --> 15:14.240
and to get this information whether your code is actually executing you need to know where to put

15:14.240 --> 15:21.440
some sort of a marker to get these signs of life and for that you should look into the init code

15:21.440 --> 15:29.360
or init process for the SCP the init process for the SCP is in fact super simple because

15:30.320 --> 15:40.960
what it does is it enters yeah it enters main function in the arc main.c right after

15:41.680 --> 15:48.800
serant time has been configured the main function runs through it's super short function it calls

15:48.800 --> 15:56.480
advocate advocate in it that one runs through and then ultimately it calls advocate on main loop

15:57.280 --> 16:05.520
and this is the main loop which is then the runtime of the SCP it's literally these two functions

16:05.520 --> 16:10.080
which you need to analyze and figure out where you are running code in that or not

16:11.520 --> 16:16.400
the best thing you can do is put some sort of a marker at the very beginning of the main function

16:17.280 --> 16:25.520
and what kind of marker would that be well the easiest you can do is make use of the fact that

16:25.680 --> 16:32.560
a bootloader has now initialized your system including a UR so you should be able to write

16:32.560 --> 16:38.800
characters into UR before the simplest marker to denote some sort of a signs of life from the

16:38.800 --> 16:45.120
SCP is basically to write a character into the UR before and wait for it to appear on your serial

16:45.120 --> 16:51.760
console and if you can do whatever plain and simple memory write somewhere at the beginning of the

16:51.840 --> 16:58.960
main function just like that of course if you have a j tag access then that's much easier because

16:58.960 --> 17:03.680
with j tag access you can stop the core and figure out where it's like so you think if you don't have

17:03.680 --> 17:11.600
j tag access then this is the next best thing now once you have this printing primitive you can

17:12.720 --> 17:19.040
add more of these simple outputs throughout the main function throughout the arc unit function

17:19.120 --> 17:25.840
until you reach the main loop and you're going to effectively debug the whole unit process using

17:25.840 --> 17:34.800
simple print markers since the unit process is not complex it's doable now once you actually

17:34.800 --> 17:42.240
reach the main loop we probably need to formalize somehow the UR driver and this is done by

17:42.240 --> 17:51.440
wrapping in into a module of type driver so a module is defined in the following way there is a

17:51.440 --> 17:57.920
structure which is called FWK under SCOR module which is a bunch of callbacks it has to be type driver

17:57.920 --> 18:04.000
it has two callbacks at the very beginning which are relevant to us one of them is in it one of the

18:04.000 --> 18:11.600
other one is element in it the difference is that when the system is going through the unit process

18:11.760 --> 18:17.440
it initializes the module itself using the unit callback and then every module instances initialized

18:17.440 --> 18:26.560
using the element unit callback now the module has an iO adapter which is optional for the

18:26.560 --> 18:32.640
UR we will make use of it and we will fill in the iO functions into the iO adapter so that

18:33.360 --> 18:39.040
when any sort of printing happens within the SCP it goes into the iO adapter and then out of your

18:39.120 --> 18:51.920
UR the functions are very simplistic open putc close you will be interested in the putc function

18:52.720 --> 18:59.280
where this where you will get a character from the intern also the SCP which are supposed to

18:59.280 --> 19:07.600
put on the UR so this is where you will do exactly the same right has happened before in the

19:07.680 --> 19:11.360
simple debugging function but now you will do it in a more formal way within the module

19:13.120 --> 19:22.160
in the putc function now this is not all of it because at this point you have a module but

19:22.160 --> 19:28.800
you need to instantiate it the middle and element this is done by including the module in the

19:29.360 --> 19:39.120
build and yeah this is done by including the module in the build by patching a bunch of

19:39.120 --> 19:45.840
CMake files but this is still not all of it because in the product directory you have to

19:45.840 --> 19:55.840
refine the element private data this stuff the element private data they are used to parameterize

19:55.840 --> 20:04.640
the module instances that means the elements in case of UR it could be for example the UR

20:04.640 --> 20:18.400
base address about rate of the of this UR instance that you now once you have these things in place

20:19.280 --> 20:27.680
it's important to test the UR module and the instance of it now the SCP has a print buffer

20:27.680 --> 20:33.600
internally that means whenever you some sort of a printing within the SCP and this may be surprising

20:33.600 --> 20:40.880
it goes actually into a print buffer internally and after the main loop does one sort of a

20:40.880 --> 20:48.080
round that only then the print buffer gets printed out which is not very practical when testing

20:48.080 --> 20:54.240
UR driver because you'll do some sort of printing and suddenly it's not going anywhere it's

20:54.240 --> 21:03.120
not appearing on the UR at all so you can actually circumvent it by calling the FWKIO putc which will

21:03.120 --> 21:10.800
go directly into the UR output it will skip the print buffer for that all you have to do

21:10.880 --> 21:19.360
is prepare some sort of a local string which you then feed into the UR print buffer now we've that

21:20.400 --> 21:27.920
finished what are the next steps let's summarize this what we did now is we effectively

21:29.440 --> 21:37.200
did a port of the SCP which is running on the SCP core it has some sort of printing facility and

21:37.280 --> 21:43.280
it's running in the main loop so you have module you have element which is instance of the module

21:43.280 --> 21:50.720
and it's running on the SCP core the next steps are to add in a similar way a mailbox module

21:50.720 --> 21:57.360
which will allow you to communicate with the other course through the mailbox and schmem and then

21:57.360 --> 22:05.600
on top of that it's all generic then the SCMI module then on top of that SCMI clock protocol module

22:06.160 --> 22:12.800
with the clock protocol module reset modules there is one other detail which you need to be aware of

22:12.800 --> 22:19.440
because if you are adding SCMI clock protocol module this is generic but you need a matching module

22:19.440 --> 22:26.640
which is a clock driver specific for your platform and this has to expose an API to which the

22:26.640 --> 22:34.400
SCMI clock protocol module binds in the documentation you will find how this API binding is described

22:34.480 --> 22:44.320
but there is also a bunch of examples within the SCP code base itself board of caution when you

22:44.320 --> 22:52.560
are adding clock protocol and for bindings keep in mind that what you are defining is an

22:52.560 --> 22:59.200
API which is facing your users it's an API that's facing Linux it's a BI facing your RTO SS

23:00.000 --> 23:05.440
and this API has to be immutable you cannot change it so when you are defining this be

23:05.440 --> 23:12.160
very careful how you are defining this very good way to do this is to add it incrementally that

23:12.160 --> 23:20.160
means when you define some sort of an SCMI clock define only the minimum subset and verify that

23:20.160 --> 23:25.360
Linux can use them successfully verify that RTO SS are happy with them and only then add them

23:26.000 --> 23:30.640
into your SCP and expose them to users do not expose everything at once because you will make

23:30.640 --> 23:36.400
mistakes and they will be hard to correct so add things gradually as you test them

23:37.680 --> 23:46.080
right with that but summarized this it is possible to have an open SCP implementation

23:47.360 --> 23:54.720
the code which is currently available is PSD 3 calls so it's open and yeah

23:54.800 --> 24:02.320
the port can be implemented incrementally and when you do so be very mindful of the API which you

24:02.320 --> 24:11.680
are exposing to the Linux kernel and your RTO SS and so on with that thank you for your attention

24:11.680 --> 24:32.960
and you have any questions thank you do you have TFA doing like SCMI processing or to

24:32.960 --> 24:41.120
speak SCMI directly to the co-processor that's actually a good good question so the question was

24:41.120 --> 24:47.600
whether I'm talking to TFA and then TFA talks to SCB or whether I directly talk to SCB from all

24:47.600 --> 24:53.600
the clients right so on the platform that I'm working on which is the upcoming SLC from

24:53.600 --> 25:04.240
Renesas this is all the clients directly talk to SCB that means TFA talks to SCB you would talk

25:04.240 --> 25:14.160
to SCB Linux talks to SCB the RTO SS talk to SCB and the SCB is the manager of the overall platform

25:14.160 --> 25:19.760
policy thank you

