blob: ba9b9aaf83bacfdbb6a9cc94d3e00c635e807e80 [file] [log] [blame]
Paul Beesleyec7988c2019-10-24 11:57:00 +00001Porting Guide
2=============
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +02003
4Introduction
5------------
6
7Please note that this document is incomplete.
8
9Porting the TF-A Tests to a new platform involves making some mandatory and
10optional modifications for both the cold and warm boot paths. Modifications
11consist of:
12
13* Implementing a platform-specific function or variable,
14* Setting up the execution context in a certain way, or
15* Defining certain constants (for example #defines).
16
17The platform-specific functions and variables are all declared in
18``include/plat/common/platform.h``. The framework provides a default
19implementation of variables and functions to fulfill the optional requirements.
20These implementations are all weakly defined; they are provided to ease the
21porting effort. Each platform port can override them with its own implementation
22if the default implementation is inadequate.
23
24Platform requirements
25---------------------
26
27The TF-A Tests rely on the following features to be present on the platform and
28accessible from Normal World.
29
30- Watchdog
31- Non-Volatile Memory
32- System Timer
33
34This also means that a platform port of the TF-A Tests must include software
35drivers for those features.
36
37Mandatory modifications
38-----------------------
39
40File : platform_def.h [mandatory]
41`````````````````````````````````
42
43Each platform must ensure that a header file of this name is in the system
44include path with the following constants defined. This may require updating the
45list of ``PLAT_INCLUDES`` in the ``platform.mk`` file. In the ARM FVP port, this
46file is found in ``plat/arm/board/fvp/include/platform_def.h``.
47
48- **#define : PLATFORM_LINKER_FORMAT**
49
50 Defines the linker format used by the platform, for example
51 `elf64-littleaarch64` used by the FVP.
52
53- **#define : PLATFORM_LINKER_ARCH**
54
55 Defines the processor architecture for the linker by the platform, for
56 example `aarch64` used by the FVP.
57
58- **#define : PLATFORM_STACK_SIZE**
59
60 Defines the stack memory available to each CPU. This constant is used by
61 ``plat/common/aarch64/platform_mp_stack.S``.
62
63- **#define : PLATFORM_CLUSTER_COUNT**
64
65 Defines the total number of clusters implemented by the platform in the
66 system.
67
68- **#define : PLATFORM_CORE_COUNT**
69
70 Defines the total number of CPUs implemented by the platform across all
71 clusters in the system.
72
73- **#define : PLATFORM_NUM_AFFS**
74
75 Defines the total number of nodes in the affinity hierarchy at all affinity
76 levels used by the platform.
77
78- **#define : PLATFORM_MAX_AFFLVL**
79
80 Defines the maximum number of affinity levels in the system that the platform
81 implements. ARMv8-A has support for 4 affinity levels. It is likely that
82 hardware will implement fewer affinity levels. For example, the Base AEM FVP
83 implements two clusters with a configurable number of CPUs. It reports the
84 maximum affinity level as 1.
85
86- **#define : PLAT_MAX_SPI_OFFSET_ID**
87
88 Defines the offset of the last Shared Peripheral Interrupt supported by the
89 TF-A Tests on this platform. SPI numbers are mapped onto GIC interrupt IDs,
90 starting from interrupt ID 32. In other words, this offset ID corresponds to
91 the last SPI number, to which 32 must be added to get the corresponding last
92 GIC IRQ ID.
93
94 E.g. If ``PLAT_MAX_SPI_OFFSET_ID`` is 10, this means that IRQ #42 is the last
95 SPI.
96
97- **#define : PLAT_LOCAL_PSTATE_WIDTH**
98
99 Defines the bit-field width of the local state in State-ID field of the
100 power-state parameter. This macro will be used to compose the State-ID field
101 given the local power state at different affinity levels.
102
103- **#define : PLAT_MAX_PWR_STATES_PER_LVL**
104
105 Defines the maximum number of power states at a power domain level for the
106 platform. This macro will be used by the ``PSCI_STAT_COUNT/RESIDENCY`` tests
107 to determine the size of the array to allocate for storing the statistics.
108
109- **#define : TFTF_BASE**
110
111 Defines the base address of the TFTF binary in DRAM. Used by the linker
112 script to link the image at the right address. Must be aligned on a page-size
113 boundary.
114
115- **#define : IRQ_PCPU_NS_TIMER**
116
117 Defines the IRQ ID of the per-CPU Non-Secure timer of the platform.
118
119- **#define : IRQ_CNTPSIRQ1**
120
121 Defines the IRQ ID of the System timer of the platform.
122
123- **#define : TFTF_NVM_OFFSET**
124
125 The TFTF needs some Non-Volatile Memory to store persistent data. This
126 defines the offset from the beginning of this memory that the TFTF can use.
127
128- **#define : TFTF_NVM_SIZE**
129
130 Defines the size of the Non-Volatile Memory allocated for TFTF usage.
131
132If the platform port uses the ARM Watchdog Module (`SP805`_) peripheral, the
133following constant needs to be defined:
134
135- **#define : SP805_WDOG_BASE**
136
137 Defines the base address of the `SP805`_ watchdog peripheral.
138
139If the platform port uses the IO storage framework, the following constants
140must also be defined:
141
142- **#define : MAX_IO_DEVICES**
143
144 Defines the maximum number of registered IO devices. Attempting to register
145 more devices than this value using ``io_register_device()`` will fail with
146 ``IO_RESOURCES_EXHAUSTED``.
147
148- **#define : MAX_IO_HANDLES**
149
150 Defines the maximum number of open IO handles. Attempting to open more IO
151 entities than this value using ``io_open()`` will fail with
152 ``IO_RESOURCES_EXHAUSTED``.
153
154If the platform port uses the VExpress NOR flash driver (see
155``drivers/io/vexpress_nor/``), the following constants must also be defined:
156
157- **#define : NOR_FLASH_BLOCK_SIZE**
158
159 Defines the largest block size as seen by the software while writing to NOR
160 flash.
161
162Function : tftf_plat_arch_setup() [mandatory]
163`````````````````````````````````````````````
164::
165
166 Argument : void
167 Return : void
168
169This function performs any platform-specific and architectural setup that the
170platform requires.
171
172In both the ARM FVP and Juno ports, this function configures and enables the
173MMU.
174
175Function : tftf_early_platform_setup() [mandatory]
176``````````````````````````````````````````````````
177
178::
179
180 Argument : void
181 Return : void
182
183This function executes with the MMU and data caches disabled. It is only called
184by the primary CPU. It is used to perform platform-specific actions very early
185in the boot.
186
187In both the ARM FVP and Juno ports, this function configures the console.
188
189Function : tftf_platform_setup() [mandatory]
190````````````````````````````````````````````
191
192::
193
194 Argument : void
195 Return : void
196
197This function executes with the MMU and data caches enabled. It is responsible
198for performing any remaining platform-specific setup that can occur after the
199MMU and data cache have been enabled.
200
201This function is also responsible for initializing the storage abstraction layer
202used to access non-volatile memory for permanent storage of test results. It
203also initialises the GIC and detects the platform topology using
204platform-specific means.
205
206Function : plat_get_nvm_handle() [mandatory]
207````````````````````````````````````````````
208
209::
210
211 Argument : uintptr_t *
212 Return : void
213
214It is needed if the platform port uses IO storage framework. This function is
215responsible for getting the pointer to the initialised non-volatile memory
216entity.
217
218Function : tftf_plat_get_pwr_domain_tree_desc() [mandatory]
219```````````````````````````````````````````````````````````
220
221::
222
223 Argument : void
224 Return : const unsigned char *
225
226This function returns the platform topology description array in a suitable
227format as expected by TFTF. The size of the array is expected to be
228``PLATFORM_NUM_AFFS - PLATFORM_CORE_COUNT + 1``. The format used to describe
229this array is :
230
2311. The first entry in the array specifies the number of power domains at the
232 highest power level implemented in the platform. This caters for platforms
233 where the power domain tree does not have a single root node e.g. the FVP
234 which has two cluster power domains at the highest level (that is, 1).
235
2362. Each subsequent entry corresponds to a power domain and contains the number
237 of power domains that are its direct children.
238
239The array format is the same as the one used by Trusted Firmware-A and more
240details of its description can be found in the Trusted Firmware-A documentation:
241`docs/psci-pd-tree.rst`_.
242
243Function : tftf_plat_get_mpidr() [mandatory]
244````````````````````````````````````````````
245
246::
247
248 Argument : unsigned int
249 Return : uint64_t
250
251This function converts a given `core_pos` into a valid MPIDR if the CPU is
252present in the platform. The `core_pos` is a unique number less than the
253``PLATFORM_CORE_COUNT`` returned by ``platform_get_core_pos()`` for a given
254CPU. This API is used by the topology framework in TFTF to query the presence of
255a CPU and, if present, returns the corresponding MPIDR for it. If the CPU
256referred to by the `core_pos` is absent, then this function returns
257``INVALID_MPID``.
258
259Function : plat_get_state_prop() [mandatory]
260````````````````````````````````````````````
261
262::
263
264 Argument : unsigned int
265 Return : const plat_state_prop_t *
266
267This functions returns the ``plat_state_prop_t`` array for all the valid low
268power states from platform for a specified affinity level and returns ``NULL``
269for an invalid affinity level. The array is expected to be NULL-terminated.
270This function is expected to be used by tests that need to compose the power
271state parameter for use in ``PSCI_CPU_SUSPEND`` API or ``PSCI_STAT/RESIDENCY``
272API.
273
274Function : plat_fwu_io_setup() [mandatory]
275``````````````````````````````````````````
276
277::
278
279 Argument : void
280 Return : void
281
282This function initializes the IO system used by the firmware update.
283
284Function : plat_arm_gic_init() [mandatory]
285``````````````````````````````````````````
286
287::
288
289 Argument : void
290 Return : void
291
292This function initializes the ARM Generic Interrupt Controller (GIC).
293
Antonio Nino Diaz1cf45c92018-10-15 09:03:43 +0100294Function : platform_get_core_pos() [mandatory]
295``````````````````````````````````````````````
296
297::
298
299 Argument : u_register_t
300 Return : unsigned int
301
302This function returns a linear core ID from a MPID.
303
304Function : plat_crash_console_init() [mandatory]
305````````````````````````````````````````````````
306
307::
308
309 Argument : void
310 Return : int
311
312This function initializes a platform-specific console for crash reporting.
313
314Function : plat_crash_console_putc() [mandatory]
315````````````````````````````````````````````````
316
317::
318
319 Argument : int
320 Return : int
321
322This function prints a character on the platform-specific crash console.
323
324Function : plat_crash_console_flush() [mandatory]
325`````````````````````````````````````````````````
326
327::
328
329 Argument : void
330 Return : int
331
332This function waits until all the characters of the platform-specific crash
333console have been actually printed.
334
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200335Optional modifications
336----------------------
337
338The following are helper functions implemented by the test framework that
339perform common platform-specific tasks. A platform may choose to override these
340definitions.
341
342Function : platform_get_stack()
343```````````````````````````````
344
345::
346
347 Argument : unsigned long
348 Return : unsigned long
349
350This function returns the base address of the memory stack that has been
351allocated for the CPU specified by MPIDR. The size of the stack allocated to
352each CPU is specified by the platform defined constant ``PLATFORM_STACK_SIZE``.
353
354Common implementation of this function is provided in
355``plat/common/aarch64/platform_mp_stack.S``.
356
357Function : tftf_platform_end()
358``````````````````````````````
359
360::
361
362 Argument : void
363 Return : void
364
365This function performs any operation required by the platform to properly finish
366the test session.
367
368The default implementation sends an EOT (End Of Transmission) character on the
369UART. This can be used to automatically shutdown the FVP models. When running on
370real hardware, the UART output may be parsed by an external tool looking for
371this character and rebooting the platform for example.
372
373Function : tftf_plat_reset()
374````````````````````````````
375
376::
377
378 Argument : void
379 Return : void
380
381This function resets the platform.
382
383The default implementation uses the ARM watchdog peripheral (`SP805`_) to
384generate a watchdog timeout interrupt. This interrupt remains deliberately
385unserviced, which eventually asserts the reset signal.
386
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200387Storage abstraction layer
388-------------------------
389
390In order to improve platform independence and portability a storage abstraction
391layer is used to store test results to non-volatile platform storage.
392
393Each platform should register devices and their drivers via the Storage layer.
394These drivers then need to be initialized in ``tftf_platform_setup()`` function.
395
396It is mandatory to implement at least one storage driver. For the FVP and Juno
397platforms the NOR Flash driver is provided as the default means to store test
398results to storage. The storage layer is described in the header file
399``include/lib/io_storage.h``. The implementation of the common library is in
400``drivers/io/io_storage.c`` and the driver files are located in ``drivers/io/``.
401
402
403Build Flags
404-----------
405
406- **PLAT_TESTS_SKIP_LIST**
407
408This build flag can be defined by the platform to control exclusion of some
409testcases from the default test plan for a platform. If used this needs to
410point to a text file which follows the following criteria:
411
412 - Contain a list of tests to skip for this platform.
413
414 - Specify 1 test per line, using the following format:
415
416 ::
417
418 testsuite_name/testcase_name
419
420 where ``testsuite_name`` and ``testcase_name`` are the names that appear in
421 the XML tests file.
422
423 - Alternatively, it is possible to disable a test suite entirely, which will
424 disable all test cases part of this test suite. To do so, only specify the
425 test suite name, omitting the ``/testcase_name`` part.
426
427--------------
428
Antonio Nino Diaz2f13f422019-03-13 13:57:39 +0000429*Copyright (c) 2018-2019, Arm Limited. All rights reserved.*
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200430
Sandrine Bailleuxb308d012019-04-10 09:30:10 +0200431.. _docs/psci-pd-tree.rst: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/about/docs/psci-pd-tree.rst
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200432.. _SP805: https://static.docs.arm.com/ddi0270/b/DDI0270.pdf