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