blob: c0e6acead4f22a0d77f845c2191aca8abb7fecad [file] [log] [blame] [view]
Achin Gupta4f6ad662013-10-25 09:08:21 +01001ARM Trusted Firmware Porting Guide
2==================================
3
4Contents
5--------
6
71. Introduction
82. Common Modifications
9 * Common mandatory modifications
10 * Common optional modifications
113. Boot Loader stage specific modifications
12 * Boot Loader stage 1 (BL1)
13 * Boot Loader stage 2 (BL2)
14 * Boot Loader stage 3-1 (BL3-1)
15 * PSCI implementation (in BL3-1)
16
17- - - - - - - - - - - - - - - - - -
18
191. Introduction
20----------------
21
22Porting the ARM Trusted Firmware to a new platform involves making some
23mandatory and optional modifications for both the cold and warm boot paths.
24Modifications consist of:
25
26* Implementing a platform-specific function or variable,
27* Setting up the execution context in a certain way, or
28* Defining certain constants (for example #defines).
29
30The firmware provides a default implementation of variables and functions to
31fulfill the optional requirements. These implementations are all weakly defined;
32they are provided to ease the porting effort. Each platform port can override
33them with its own implementation if the default implementation is inadequate.
34
35Some modifications are common to all Boot Loader (BL) stages. Section 2
36discusses these in detail. The subsequent sections discuss the remaining
37modifications for each BL stage in detail.
38
39This document should be read in conjunction with the ARM Trusted Firmware
40[User Guide].
41
42
432. Common modifications
44------------------------
45
46This section covers the modifications that should be made by the platform for
47each BL stage to correctly port the firmware stack. They are categorized as
48either mandatory or optional.
49
50
512.1 Common mandatory modifications
52----------------------------------
53A platform port must enable the Memory Management Unit (MMU) with identity
54mapped page tables, and enable both the instruction and data caches for each BL
55stage. In the ARM FVP port, each BL stage configures the MMU in its platform-
56specific architecture setup function, for example `blX_plat_arch_setup()`.
57
58Each platform must allocate a block of identity mapped secure memory with
59Device-nGnRE attributes aligned to page boundary (4K) for each BL stage. This
60memory is identified by the section name `tzfw_coherent_mem` so that its
61possible for the firmware to place variables in it using the following C code
62directive:
63
64 __attribute__ ((section("tzfw_coherent_mem")))
65
66Or alternatively the following assembler code directive:
67
68 .section tzfw_coherent_mem
69
70The `tzfw_coherent_mem` section is used to allocate any data structures that are
71accessed both when a CPU is executing with its MMU and caches enabled, and when
72it's running with its MMU and caches disabled. Examples are given below.
73
74The following variables, functions and constants must be defined by the platform
75for the firmware to work correctly.
76
77
78### File : platform.h [mandatory]
79
80Each platform must export a header file of this name with the following
81constants defined. In the ARM FVP port, this file is found in
82[../plat/fvp/platform.h].
83
James Morrisseyba3155b2013-10-29 10:56:46 +000084* **#define : PLATFORM_LINKER_FORMAT**
Achin Gupta4f6ad662013-10-25 09:08:21 +010085
86 Defines the linker format used by the platform, for example
87 `elf64-littleaarch64` used by the FVP.
88
James Morrisseyba3155b2013-10-29 10:56:46 +000089* **#define : PLATFORM_LINKER_ARCH**
Achin Gupta4f6ad662013-10-25 09:08:21 +010090
91 Defines the processor architecture for the linker by the platform, for
92 example `aarch64` used by the FVP.
93
James Morrisseyba3155b2013-10-29 10:56:46 +000094* **#define : PLATFORM_STACK_SIZE**
Achin Gupta4f6ad662013-10-25 09:08:21 +010095
96 Defines the normal stack memory available to each CPU. This constant is used
97 by `platform_set_stack()`.
98
James Morrisseyba3155b2013-10-29 10:56:46 +000099* **#define : FIRMWARE_WELCOME_STR**
Achin Gupta4f6ad662013-10-25 09:08:21 +0100100
101 Defines the character string printed by BL1 upon entry into the `bl1_main()`
102 function.
103
James Morrisseyba3155b2013-10-29 10:56:46 +0000104* **#define : BL2_IMAGE_NAME**
Achin Gupta4f6ad662013-10-25 09:08:21 +0100105
106 Name of the BL2 binary image on the host file-system. This name is used by
107 BL1 to load BL2 into secure memory using semi-hosting.
108
James Morrisseyba3155b2013-10-29 10:56:46 +0000109* **#define : PLATFORM_CACHE_LINE_SIZE**
Achin Gupta4f6ad662013-10-25 09:08:21 +0100110
111 Defines the size (in bytes) of the largest cache line across all the cache
112 levels in the platform.
113
James Morrisseyba3155b2013-10-29 10:56:46 +0000114* **#define : PLATFORM_CLUSTER_COUNT**
Achin Gupta4f6ad662013-10-25 09:08:21 +0100115
116 Defines the total number of clusters implemented by the platform in the
117 system.
118
James Morrisseyba3155b2013-10-29 10:56:46 +0000119* **#define : PLATFORM_CORE_COUNT**
Achin Gupta4f6ad662013-10-25 09:08:21 +0100120
121 Defines the total number of CPUs implemented by the platform across all
122 clusters in the system.
123
James Morrisseyba3155b2013-10-29 10:56:46 +0000124* **#define : PLATFORM_MAX_CPUS_PER_CLUSTER**
Achin Gupta4f6ad662013-10-25 09:08:21 +0100125
126 Defines the maximum number of CPUs that can be implemented within a cluster
127 on the platform.
128
James Morrisseyba3155b2013-10-29 10:56:46 +0000129* **#define : PRIMARY_CPU**
Achin Gupta4f6ad662013-10-25 09:08:21 +0100130
131 Defines the `MPIDR` of the primary CPU on the platform. This value is used
132 after a cold boot to distinguish between primary and secondary CPUs.
133
James Morrisseyba3155b2013-10-29 10:56:46 +0000134* **#define : TZROM_BASE**
Achin Gupta4f6ad662013-10-25 09:08:21 +0100135
136 Defines the base address of secure ROM on the platform, where the BL1 binary
137 is loaded. This constant is used by the linker scripts to ensure that the
138 BL1 image fits into the available memory.
139
James Morrisseyba3155b2013-10-29 10:56:46 +0000140* **#define : TZROM_SIZE**
Achin Gupta4f6ad662013-10-25 09:08:21 +0100141
142 Defines the size of secure ROM on the platform. This constant is used by the
143 linker scripts to ensure that the BL1 image fits into the available memory.
144
James Morrisseyba3155b2013-10-29 10:56:46 +0000145* **#define : TZRAM_BASE**
Achin Gupta4f6ad662013-10-25 09:08:21 +0100146
147 Defines the base address of the secure RAM on platform, where the data
148 section of the BL1 binary is loaded. The BL2 and BL3-1 images are also
149 loaded in this secure RAM region. This constant is used by the linker
150 scripts to ensure that the BL1 data section and BL2/BL3-1 binary images fit
151 into the available memory.
152
James Morrisseyba3155b2013-10-29 10:56:46 +0000153* **#define : TZRAM_SIZE**
Achin Gupta4f6ad662013-10-25 09:08:21 +0100154
155 Defines the size of the secure RAM on the platform. This constant is used by
156 the linker scripts to ensure that the BL1 data section and BL2/BL3-1 binary
157 images fit into the available memory.
158
James Morrisseyba3155b2013-10-29 10:56:46 +0000159* **#define : SYS_CNTCTL_BASE**
Achin Gupta4f6ad662013-10-25 09:08:21 +0100160
161 Defines the base address of the `CNTCTLBase` frame of the memory mapped
162 counter and timer in the system level implementation of the generic timer.
163
James Morrisseyba3155b2013-10-29 10:56:46 +0000164* **#define : BL2_BASE**
Achin Gupta4f6ad662013-10-25 09:08:21 +0100165
166 Defines the base address in secure RAM where BL1 loads the BL2 binary image.
Sandrine Bailleuxcd29b0a2013-11-27 10:32:17 +0000167 Must be aligned on a page-size boundary.
Achin Gupta4f6ad662013-10-25 09:08:21 +0100168
James Morrisseyba3155b2013-10-29 10:56:46 +0000169* **#define : BL31_BASE**
Achin Gupta4f6ad662013-10-25 09:08:21 +0100170
171 Defines the base address in secure RAM where BL2 loads the BL3-1 binary
Sandrine Bailleuxcd29b0a2013-11-27 10:32:17 +0000172 image. Must be aligned on a page-size boundary.
Achin Gupta4f6ad662013-10-25 09:08:21 +0100173
174
175### Other mandatory modifications
176
James Morrisseyba3155b2013-10-29 10:56:46 +0000177The following mandatory modifications may be implemented in any file
Achin Gupta4f6ad662013-10-25 09:08:21 +0100178the implementer chooses. In the ARM FVP port, they are implemented in
179[../plat/fvp/aarch64/fvp_common.c].
180
James Morrisseyba3155b2013-10-29 10:56:46 +0000181* **Variable : unsigned char platform_normal_stacks[X][Y]**
Achin Gupta4f6ad662013-10-25 09:08:21 +0100182
183 where X = PLATFORM_STACK_SIZE
184 and Y = PLATFORM_CORE_COUNT
185
186 Each platform must allocate a block of memory with Normal Cacheable, Write
187 back, Write allocate and Inner Shareable attributes aligned to the size (in
188 bytes) of the largest cache line amongst all caches implemented in the
189 system. A pointer to this memory should be exported with the name
190 `platform_normal_stacks`. This pointer is used by the common platform helper
Achin Guptac8afc782013-11-25 18:45:02 +0000191 functions `platform_set_stack()` (to allocate a stack for each CPU in the
192 platform) & `platform_get_stack()` (to return the base address of that
193 stack) (see [../plat/common/aarch64/platform_helpers.S]).
Achin Gupta4f6ad662013-10-25 09:08:21 +0100194
195
1962.2 Common optional modifications
197---------------------------------
198
199The following are helper functions implemented by the firmware that perform
200common platform-specific tasks. A platform may choose to override these
201definitions.
202
203
204### Function : platform_get_core_pos()
205
206 Argument : unsigned long
207 Return : int
208
209A platform may need to convert the `MPIDR` of a CPU to an absolute number, which
210can be used as a CPU-specific linear index into blocks of memory (for example
211while allocating per-CPU stacks). This routine contains a simple mechanism
212to perform this conversion, using the assumption that each cluster contains a
213maximum of 4 CPUs:
214
215 linear index = cpu_id + (cluster_id * 4)
216
217 cpu_id = 8-bit value in MPIDR at affinity level 0
218 cluster_id = 8-bit value in MPIDR at affinity level 1
219
220
221### Function : platform_set_coherent_stack()
222
223 Argument : unsigned long
224 Return : void
225
226A platform may need stack memory that is coherent with main memory to perform
227certain operations like:
228
229* Turning the MMU on, or
230* Flushing caches prior to powering down a CPU or cluster.
231
232Each BL stage allocates this coherent stack memory for each CPU in the
233`tzfw_coherent_mem` section. A pointer to this memory (`pcpu_dv_mem_stack`) is
234used by this function to allocate a coherent stack for each CPU. A CPU is
235identified by its `MPIDR`, which is passed as an argument to this function.
236
237The size of the stack allocated to each CPU is specified by the constant
238`PCPU_DV_MEM_STACK_SIZE`.
239
240
241### Function : platform_is_primary_cpu()
242
243 Argument : unsigned long
244 Return : unsigned int
245
246This function identifies a CPU by its `MPIDR`, which is passed as the argument,
247to determine whether this CPU is the primary CPU or a secondary CPU. A return
248value of zero indicates that the CPU is not the primary CPU, while a non-zero
249return value indicates that the CPU is the primary CPU.
250
251
252### Function : platform_set_stack()
253
254 Argument : unsigned long
255 Return : void
256
257This function uses the `platform_normal_stacks` pointer variable to allocate
258stacks to each CPU. Further details are given in the description of the
259`platform_normal_stacks` variable below. A CPU is identified by its `MPIDR`,
260which is passed as the argument.
261
262The size of the stack allocated to each CPU is specified by the platform defined
263constant `PLATFORM_STACK_SIZE`.
264
265
Achin Guptac8afc782013-11-25 18:45:02 +0000266### Function : platform_get_stack()
267
268 Argument : unsigned long
269 Return : unsigned long
270
271This function uses the `platform_normal_stacks` pointer variable to return the
272base address of the stack memory reserved for a CPU. Further details are given
273in the description of the `platform_normal_stacks` variable below. A CPU is
274identified by its `MPIDR`, which is passed as the argument.
275
276The size of the stack allocated to each CPU is specified by the platform defined
277constant `PLATFORM_STACK_SIZE`.
278
279
Achin Gupta4f6ad662013-10-25 09:08:21 +0100280### Function : plat_report_exception()
281
282 Argument : unsigned int
283 Return : void
284
285A platform may need to report various information about its status when an
286exception is taken, for example the current exception level, the CPU security
287state (secure/non-secure), the exception type, and so on. This function is
288called in the following circumstances:
289
290* In BL1, whenever an exception is taken.
291* In BL2, whenever an exception is taken.
292* In BL3-1, whenever an asynchronous exception or a synchronous exception
293 other than an SMC32/SMC64 exception is taken.
294
295The default implementation doesn't do anything, to avoid making assumptions
296about the way the platform displays its status information.
297
298This function receives the exception type as its argument. Possible values for
299exceptions types are listed in the [../include/runtime_svc.h] header file. Note
300that these constants are not related to any architectural exception code; they
301are just an ARM Trusted Firmware convention.
302
303
3043. Modifications specific to a Boot Loader stage
305-------------------------------------------------
306
3073.1 Boot Loader Stage 1 (BL1)
308-----------------------------
309
310BL1 implements the reset vector where execution starts from after a cold or
311warm boot. For each CPU, BL1 is responsible for the following tasks:
312
3131. Distinguishing between a cold boot and a warm boot.
314
3152. In the case of a cold boot and the CPU being the primary CPU, ensuring that
316 only this CPU executes the remaining BL1 code, including loading and passing
317 control to the BL2 stage.
318
3193. In the case of a cold boot and the CPU being a secondary CPU, ensuring that
320 the CPU is placed in a platform-specific state until the primary CPU
321 performs the necessary steps to remove it from this state.
322
3234. In the case of a warm boot, ensuring that the CPU jumps to a platform-
324 specific address in the BL3-1 image in the same processor mode as it was
325 when released from reset.
326
3275. Loading the BL2 image in secure memory using semi-hosting at the
328 address specified by the platform defined constant `BL2_BASE`.
329
3306. Populating a `meminfo` structure with the following information in memory,
331 accessible by BL2 immediately upon entry.
332
333 meminfo.total_base = Base address of secure RAM visible to BL2
334 meminfo.total_size = Size of secure RAM visible to BL2
335 meminfo.free_base = Base address of secure RAM available for
336 allocation to BL2
337 meminfo.free_size = Size of secure RAM available for allocation to BL2
338
339 BL1 places this `meminfo` structure at the beginning of the free memory
340 available for its use. Since BL1 cannot allocate memory dynamically at the
341 moment, its free memory will be available for BL2's use as-is. However, this
342 means that BL2 must read the `meminfo` structure before it starts using its
343 free memory (this is discussed in Section 3.2).
344
345 In future releases of the ARM Trusted Firmware it will be possible for
346 the platform to decide where it wants to place the `meminfo` structure for
347 BL2.
348
349 BL1 implements the `init_bl2_mem_layout()` function to populate the
350 BL2 `meminfo` structure. The platform may override this implementation, for
351 example if the platform wants to restrict the amount of memory visible to
352 BL2. Details of how to do this are given below.
353
354The following functions need to be implemented by the platform port to enable
355BL1 to perform the above tasks.
356
357
358### Function : platform_get_entrypoint() [mandatory]
359
360 Argument : unsigned long
361 Return : unsigned int
362
363This function is called with the `SCTLR.M` and `SCTLR.C` bits disabled. The CPU
364is identified by its `MPIDR`, which is passed as the argument. The function is
365responsible for distinguishing between a warm and cold reset using platform-
366specific means. If it's a warm reset then it returns the entrypoint into the
367BL3-1 image that the CPU must jump to. If it's a cold reset then this function
368must return zero.
369
370This function is also responsible for implementing a platform-specific mechanism
371to handle the condition where the CPU has been warm reset but there is no
372entrypoint to jump to.
373
374This function does not follow the Procedure Call Standard used by the
375Application Binary Interface for the ARM 64-bit architecture. The caller should
376not assume that callee saved registers are preserved across a call to this
377function.
378
379This function fulfills requirement 1 listed above.
380
381
382### Function : plat_secondary_cold_boot_setup() [mandatory]
383
384 Argument : void
385 Return : void
386
387This function is called with the MMU and data caches disabled. It is responsible
388for placing the executing secondary CPU in a platform-specific state until the
389primary CPU performs the necessary actions to bring it out of that state and
390allow entry into the OS.
391
392In the ARM FVP port, each secondary CPU powers itself off. The primary CPU is
393responsible for powering up the secondary CPU when normal world software
394requires them.
395
396This function fulfills requirement 3 above.
397
398
399### Function : platform_cold_boot_init() [mandatory]
400
401 Argument : unsigned long
402 Return : unsigned int
403
404This function executes with the MMU and data caches disabled. It is only called
405by the primary CPU. The argument to this function is the address of the
406`bl1_main()` routine where the generic BL1-specific actions are performed.
407This function performs any platform-specific and architectural setup that the
408platform requires to make execution of `bl1_main()` possible.
409
410The platform must enable the MMU with identity mapped page tables and enable
411caches by setting the `SCTLR.I` and `SCTLR.C` bits.
412
413Platform-specific setup might include configuration of memory controllers,
414configuration of the interconnect to allow the cluster to service cache snoop
415requests from another cluster, zeroing of the ZI section, and so on.
416
417In the ARM FVP port, this function enables CCI snoops into the cluster that the
418primary CPU is part of. It also enables the MMU and initializes the ZI section
419in the BL1 image through the use of linker defined symbols.
420
421This function helps fulfill requirement 2 above.
422
423
424### Function : bl1_platform_setup() [mandatory]
425
426 Argument : void
427 Return : void
428
429This function executes with the MMU and data caches enabled. It is responsible
430for performing any remaining platform-specific setup that can occur after the
431MMU and data cache have been enabled.
432
433In the ARM FVP port, it zeros out the ZI section, enables the system level
434implementation of the generic timer counter and initializes the console.
435
436This function helps fulfill requirement 5 above.
437
438
439### Function : bl1_get_sec_mem_layout() [mandatory]
440
441 Argument : void
442 Return : meminfo
443
444This function executes with the MMU and data caches enabled. The `meminfo`
445structure returned by this function must contain the extents and availability of
446secure RAM for the BL1 stage.
447
448 meminfo.total_base = Base address of secure RAM visible to BL1
449 meminfo.total_size = Size of secure RAM visible to BL1
450 meminfo.free_base = Base address of secure RAM available for allocation
451 to BL1
452 meminfo.free_size = Size of secure RAM available for allocation to BL1
453
454This information is used by BL1 to load the BL2 image in secure RAM. BL1 also
455populates a similar structure to tell BL2 the extents of memory available for
456its own use.
457
458This function helps fulfill requirement 5 above.
459
460
461### Function : init_bl2_mem_layout() [optional]
462
463 Argument : meminfo *, meminfo *, unsigned int, unsigned long
464 Return : void
465
466Each BL stage needs to tell the next stage the amount of secure RAM available
467for it to use. For example, as part of handing control to BL2, BL1 informs BL2
468of the extents of secure RAM available for BL2 to use. BL2 must do the same when
469passing control to BL3-1. This information is populated in a `meminfo`
470structure.
471
472Depending upon where BL2 has been loaded in secure RAM (determined by
473`BL2_BASE`), BL1 calculates the amount of free memory available for BL2 to use.
474BL1 also ensures that its data sections resident in secure RAM are not visible
475to BL2. An illustration of how this is done in the ARM FVP port is given in the
476[User Guide], in the Section "Memory layout on Base FVP".
477
478
4793.2 Boot Loader Stage 2 (BL2)
480-----------------------------
481
482The BL2 stage is executed only by the primary CPU, which is determined in BL1
483using the `platform_is_primary_cpu()` function. BL1 passed control to BL2 at
484`BL2_BASE`. BL2 executes in Secure EL1 and is responsible for:
485
4861. Loading the BL3-1 binary image in secure RAM using semi-hosting. To load the
487 BL3-1 image, BL2 makes use of the `meminfo` structure passed to it by BL1.
488 This structure allows BL2 to calculate how much secure RAM is available for
489 its use. The platform also defines the address in secure RAM where BL3-1 is
490 loaded through the constant `BL31_BASE`. BL2 uses this information to
491 determine if there is enough memory to load the BL3-1 image.
492
4932. Arranging to pass control to a normal world BL image that has been
494 pre-loaded at a platform-specific address. This address is determined using
495 the `plat_get_ns_image_entrypoint()` function described below.
496
497 BL2 populates an `el_change_info` structure in memory provided by the
498 platform with information about how BL3-1 should pass control to the normal
499 world BL image.
500
5013. Populating a `meminfo` structure with the following information in
502 memory that is accessible by BL3-1 immediately upon entry.
503
504 meminfo.total_base = Base address of secure RAM visible to BL3-1
505 meminfo.total_size = Size of secure RAM visible to BL3-1
506 meminfo.free_base = Base address of secure RAM available for allocation
507 to BL3-1
508 meminfo.free_size = Size of secure RAM available for allocation to
509 BL3-1
510
511 BL2 places this `meminfo` structure in memory provided by the
512 platform (`bl2_el_change_mem_ptr`). BL2 implements the
513 `init_bl31_mem_layout()` function to populate the BL3-1 meminfo structure
514 described above. The platform may override this implementation, for example
515 if the platform wants to restrict the amount of memory visible to BL3-1.
516 Details of this function are given below.
517
518The following functions must be implemented by the platform port to enable BL2
519to perform the above tasks.
520
521
522### Function : bl2_early_platform_setup() [mandatory]
523
524 Argument : meminfo *, void *
525 Return : void
526
527This function executes with the MMU and data caches disabled. It is only called
528by the primary CPU. The arguments to this function are:
529
530* The address of the `meminfo` structure populated by BL1
531* An opaque pointer that the platform may use as needed.
532
533The platform must copy the contents of the `meminfo` structure into a private
534variable as the original memory may be subsequently overwritten by BL2. The
535copied structure is made available to all BL2 code through the
536`bl2_get_sec_mem_layout()` function.
537
538
539### Function : bl2_plat_arch_setup() [mandatory]
540
541 Argument : void
542 Return : void
543
544This function executes with the MMU and data caches disabled. It is only called
545by the primary CPU.
546
547The purpose of this function is to perform any architectural initialization
548that varies across platforms, for example enabling the MMU (since the memory
549map differs across platforms).
550
551
552### Function : bl2_platform_setup() [mandatory]
553
554 Argument : void
555 Return : void
556
557This function may execute with the MMU and data caches enabled if the platform
558port does the necessary initialization in `bl2_plat_arch_setup()`. It is only
559called by the primary CPU.
560
561The purpose of this function is to perform any platform initialization specific
562to BL2. This function must initialize a pointer to memory
563(`bl2_el_change_mem_ptr`), which can then be used to populate an
564`el_change_info` structure. The underlying requirement is that the platform must
565initialize this pointer before the `get_el_change_mem_ptr()` function
566accesses it in `bl2_main()`.
567
568The ARM FVP port initializes this pointer to the base address of Secure DRAM
569(`0x06000000`).
570
571
572### Variable : unsigned char bl2_el_change_mem_ptr[EL_CHANGE_MEM_SIZE] [mandatory]
573
574As mentioned in the description of `bl2_platform_setup()`, this pointer is
575initialized by the platform to point to memory where an `el_change_info`
576structure can be populated.
577
578
579### Function : bl2_get_sec_mem_layout() [mandatory]
580
581 Argument : void
582 Return : meminfo
583
584This function may execute with the MMU and data caches enabled if the platform
585port does the necessary initialization in `bl2_plat_arch_setup()`. It is only
586called by the primary CPU.
587
588The purpose of this function is to return a `meminfo` structure populated with
589the extents of secure RAM available for BL2 to use. See
590`bl2_early_platform_setup()` above.
591
592
593### Function : init_bl31_mem_layout() [optional]
594
595 Argument : meminfo *, meminfo *, unsigned int
596 Return : void
597
598Each BL stage needs to tell the next stage the amount of secure RAM that is
599available for it to use. For example, as part of handing control to BL2, BL1
600must inform BL2 about the extents of secure RAM that is available for BL2 to
601use. BL2 must do the same when passing control to BL3-1. This information is
602populated in a `meminfo` structure.
603
604Depending upon where BL3-1 has been loaded in secure RAM (determined by
605`BL31_BASE`), BL2 calculates the amount of free memory available for BL3-1 to
606use. BL2 also ensures that BL3-1 is able reclaim memory occupied by BL2. This
607is done because BL2 never executes again after passing control to BL3-1.
608An illustration of how this is done in the ARM FVP port is given in the
609[User Guide], in the section "Memory layout on Base FVP".
610
611
612### Function : plat_get_ns_image_entrypoint() [mandatory]
613
614 Argument : void
615 Return : unsigned long
616
617As previously described, BL2 is responsible for arranging for control to be
618passed to a normal world BL image through BL3-1. This function returns the
619entrypoint of that image, which BL3-1 uses to jump to it.
620
621The ARM FVP port assumes that flash memory has been pre-loaded with the UEFI
622image, and so returns the base address of flash memory.
623
624
6253.2 Boot Loader Stage 3-1 (BL3-1)
626---------------------------------
627
628During cold boot, the BL3-1 stage is executed only by the primary CPU. This is
629determined in BL1 using the `platform_is_primary_cpu()` function. BL1 passes
630control to BL3-1 at `BL31_BASE`. During warm boot, BL3-1 is executed by all
631CPUs. BL3-1 executes at EL3 and is responsible for:
632
6331. Re-initializing all architectural and platform state. Although BL1 performs
634 some of this initialization, BL3-1 remains resident in EL3 and must ensure
635 that EL3 architectural and platform state is completely initialized. It
636 should make no assumptions about the system state when it receives control.
637
6382. Passing control to a normal world BL image, pre-loaded at a platform-
639 specific address by BL2. BL3-1 uses the `el_change_info` structure that BL2
640 populated in memory to do this.
641
6423. Providing runtime firmware services. Currently, BL3-1 only implements a
643 subset of the Power State Coordination Interface (PSCI) API as a runtime
644 service. See Section 3.3 below for details of porting the PSCI
645 implementation.
646
647The following functions must be implemented by the platform port to enable BL3-1
648to perform the above tasks.
649
650
651### Function : bl31_early_platform_setup() [mandatory]
652
653 Argument : meminfo *, void *, unsigned long
654 Return : void
655
656This function executes with the MMU and data caches disabled. It is only called
657by the primary CPU. The arguments to this function are:
658
659* The address of the `meminfo` structure populated by BL2.
660* An opaque pointer that the platform may use as needed.
661* The `MPIDR` of the primary CPU.
662
663The platform must copy the contents of the `meminfo` structure into a private
664variable as the original memory may be subsequently overwritten by BL3-1. The
665copied structure is made available to all BL3-1 code through the
666`bl31_get_sec_mem_layout()` function.
667
668
669### Function : bl31_plat_arch_setup() [mandatory]
670
671 Argument : void
672 Return : void
673
674This function executes with the MMU and data caches disabled. It is only called
675by the primary CPU.
676
677The purpose of this function is to perform any architectural initialization
678that varies across platforms, for example enabling the MMU (since the memory
679map differs across platforms).
680
681
682### Function : bl31_platform_setup() [mandatory]
683
684 Argument : void
685 Return : void
686
687This function may execute with the MMU and data caches enabled if the platform
688port does the necessary initialization in `bl31_plat_arch_setup()`. It is only
689called by the primary CPU.
690
691The purpose of this function is to complete platform initialization so that both
692BL3-1 runtime services and normal world software can function correctly.
693
694The ARM FVP port does the following:
695* Initializes the generic interrupt controller.
696* Configures the CLCD controller.
697* Grants access to the system counter timer module
698* Initializes the FVP power controller device
699* Detects the system topology.
700
701
702### Function : bl31_get_next_image_info() [mandatory]
703
704 Argument : unsigned long
705 Return : el_change_info *
706
707This function may execute with the MMU and data caches enabled if the platform
708port does the necessary initializations in `bl31_plat_arch_setup()`.
709
710This function is called by `bl31_main()` to retrieve information provided by
711BL2, so that BL3-1 can pass control to the normal world software image. This
712function must return a pointer to the `el_change_info` structure (that was
713copied during `bl31_early_platform_setup()`).
714
715
716### Function : bl31_get_sec_mem_layout() [mandatory]
717
718 Argument : void
719 Return : meminfo
720
721This function may execute with the MMU and data caches enabled if the platform
722port does the necessary initializations in `bl31_plat_arch_setup()`. It is only
723called by the primary CPU.
724
725The purpose of this function is to return a `meminfo` structure populated with
726the extents of secure RAM available for BL3-1 to use. See
727`bl31_early_platform_setup()` above.
728
729
7303.3 Power State Coordination Interface (in BL3-1)
731------------------------------------------------
732
733The ARM Trusted Firmware's implementation of the PSCI API is based around the
734concept of an _affinity instance_. Each _affinity instance_ can be uniquely
735identified in a system by a CPU ID (the processor `MPIDR` is used in the PSCI
736interface) and an _affinity level_. A processing element (for example, a
737CPU) is at level 0. If the CPUs in the system are described in a tree where the
738node above a CPU is a logical grouping of CPUs that share some state, then
739affinity level 1 is that group of CPUs (for example, a cluster), and affinity
740level 2 is a group of clusters (for example, the system). The implementation
741assumes that the affinity level 1 ID can be computed from the affinity level 0
742ID (for example, a unique cluster ID can be computed from the CPU ID). The
743current implementation computes this on the basis of the recommended use of
744`MPIDR` affinity fields in the ARM Architecture Reference Manual.
745
746BL3-1's platform initialization code exports a pointer to the platform-specific
747power management operations required for the PSCI implementation to function
748correctly. This information is populated in the `plat_pm_ops` structure. The
749PSCI implementation calls members of the `plat_pm_ops` structure for performing
750power management operations for each affinity instance. For example, the target
751CPU is specified by its `MPIDR` in a PSCI `CPU_ON` call. The `affinst_on()`
752handler (if present) is called for each affinity instance as the PSCI
753implementation powers up each affinity level implemented in the `MPIDR` (for
754example, CPU, cluster and system).
755
756The following functions must be implemented to initialize PSCI functionality in
757the ARM Trusted Firmware.
758
759
760### Function : plat_get_aff_count() [mandatory]
761
762 Argument : unsigned int, unsigned long
763 Return : unsigned int
764
765This function may execute with the MMU and data caches enabled if the platform
766port does the necessary initializations in `bl31_plat_arch_setup()`. It is only
767called by the primary CPU.
768
769This function is called by the PSCI initialization code to detect the system
770topology. Its purpose is to return the number of affinity instances implemented
771at a given `affinity level` (specified by the first argument) and a given
772`MPIDR` (specified by the second argument). For example, on a dual-cluster
773system where first cluster implements 2 CPUs and the second cluster implements 4
774CPUs, a call to this function with an `MPIDR` corresponding to the first cluster
775(`0x0`) and affinity level 0, would return 2. A call to this function with an
776`MPIDR` corresponding to the second cluster (`0x100`) and affinity level 0,
777would return 4.
778
779
780### Function : plat_get_aff_state() [mandatory]
781
782 Argument : unsigned int, unsigned long
783 Return : unsigned int
784
785This function may execute with the MMU and data caches enabled if the platform
786port does the necessary initializations in `bl31_plat_arch_setup()`. It is only
787called by the primary CPU.
788
789This function is called by the PSCI initialization code. Its purpose is to
790return the state of an affinity instance. The affinity instance is determined by
791the affinity ID at a given `affinity level` (specified by the first argument)
792and an `MPIDR` (specified by the second argument). The state can be one of
793`PSCI_AFF_PRESENT` or `PSCI_AFF_ABSENT`. The latter state is used to cater for
794system topologies where certain affinity instances are unimplemented. For
795example, consider a platform that implements a single cluster with 4 CPUs and
796another CPU implemented directly on the interconnect with the cluster. The
797`MPIDR`s of the cluster would range from `0x0-0x3`. The `MPIDR` of the single
798CPU would be 0x100 to indicate that it does not belong to cluster 0. Cluster 1
799is missing but needs to be accounted for to reach this single CPU in the
800topology tree. Hence it is marked as `PSCI_AFF_ABSENT`.
801
802
803### Function : plat_get_max_afflvl() [mandatory]
804
805 Argument : void
806 Return : int
807
808This function may execute with the MMU and data caches enabled if the platform
809port does the necessary initializations in `bl31_plat_arch_setup()`. It is only
810called by the primary CPU.
811
812This function is called by the PSCI implementation both during cold and warm
813boot, to determine the maximum affinity level that the power management
James Morrisseyba3155b2013-10-29 10:56:46 +0000814operations should apply to. ARMv8-A has support for 4 affinity levels. It is
Achin Gupta4f6ad662013-10-25 09:08:21 +0100815likely that hardware will implement fewer affinity levels. This function allows
816the PSCI implementation to consider only those affinity levels in the system
817that the platform implements. For example, the Base AEM FVP implements two
818clusters with a configurable number of CPUs. It reports the maximum affinity
819level as 1, resulting in PSCI power control up to the cluster level.
820
821
822### Function : platform_setup_pm() [mandatory]
823
824 Argument : plat_pm_ops **
825 Return : int
826
827This function may execute with the MMU and data caches enabled if the platform
828port does the necessary initializations in `bl31_plat_arch_setup()`. It is only
829called by the primary CPU.
830
831This function is called by PSCI initialization code. Its purpose is to export
832handler routines for platform-specific power management actions by populating
833the passed pointer with a pointer to BL3-1's private `plat_pm_ops` structure.
834
835A description of each member of this structure is given below. Please refer to
836the ARM FVP specific implementation of these handlers in [../plat/fvp/fvp_pm.c]
837as an example. A platform port may choose not implement some of the power
838management operations. For example, the ARM FVP port does not implement the
839`affinst_standby()` function.
840
841#### plat_pm_ops.affinst_standby()
842
843Perform the platform-specific setup to enter the standby state indicated by the
844passed argument.
845
846#### plat_pm_ops.affinst_on()
847
848Perform the platform specific setup to power on an affinity instance, specified
849by the `MPIDR` (first argument) and `affinity level` (fourth argument). The
850`state` (fifth argument) contains the current state of that affinity instance
851(ON or OFF). This is useful to determine whether any action must be taken. For
852example, while powering on a CPU, the cluster that contains this CPU might
853already be in the ON state. The platform decides what actions must be taken to
854transition from the current state to the target state (indicated by the power
855management operation).
856
857#### plat_pm_ops.affinst_off()
858
859Perform the platform specific setup to power off an affinity instance in the
860`MPIDR` of the calling CPU. It is called by the PSCI `CPU_OFF` API
861implementation.
862
863The `MPIDR` (first argument), `affinity level` (second argument) and `state`
864(third argument) have a similar meaning as described in the `affinst_on()`
865operation. They are used to identify the affinity instance on which the call
866is made and its current state. This gives the platform port an indication of the
867state transition it must make to perform the requested action. For example, if
868the calling CPU is the last powered on CPU in the cluster, after powering down
869affinity level 0 (CPU), the platform port should power down affinity level 1
870(the cluster) as well.
871
872This function is called with coherent stacks. This allows the PSCI
873implementation to flush caches at a given affinity level without running into
James Morrisseyba3155b2013-10-29 10:56:46 +0000874stale stack state after turning off the caches. On ARMv8-A cache hits do not
875occur after the cache has been turned off.
Achin Gupta4f6ad662013-10-25 09:08:21 +0100876
877#### plat_pm_ops.affinst_suspend()
878
879Perform the platform specific setup to power off an affinity instance in the
880`MPIDR` of the calling CPU. It is called by the PSCI `CPU_SUSPEND` API
881implementation.
882
883The `MPIDR` (first argument), `affinity level` (third argument) and `state`
884(fifth argument) have a similar meaning as described in the `affinst_on()`
885operation. They are used to identify the affinity instance on which the call
886is made and its current state. This gives the platform port an indication of the
887state transition it must make to perform the requested action. For example, if
888the calling CPU is the last powered on CPU in the cluster, after powering down
889affinity level 0 (CPU), the platform port should power down affinity level 1
890(the cluster) as well.
891
892The difference between turning an affinity instance off versus suspending it
893is that in the former case, the affinity instance is expected to re-initialize
894its state when its next powered on (see `affinst_on_finish()`). In the latter
895case, the affinity instance is expected to save enough state so that it can
896resume execution by restoring this state when its powered on (see
897`affinst_suspend_finish()`).
898
899This function is called with coherent stacks. This allows the PSCI
900implementation to flush caches at a given affinity level without running into
James Morrisseyba3155b2013-10-29 10:56:46 +0000901stale stack state after turning off the caches. On ARMv8-A cache hits do not
902occur after the cache has been turned off.
Achin Gupta4f6ad662013-10-25 09:08:21 +0100903
904#### plat_pm_ops.affinst_on_finish()
905
906This function is called by the PSCI implementation after the calling CPU is
907powered on and released from reset in response to an earlier PSCI `CPU_ON` call.
908It performs the platform-specific setup required to initialize enough state for
909this CPU to enter the normal world and also provide secure runtime firmware
910services.
911
912The `MPIDR` (first argument), `affinity level` (second argument) and `state`
913(third argument) have a similar meaning as described in the previous operations.
914
915This function is called with coherent stacks. This allows the PSCI
916implementation to flush caches at a given affinity level without running into
James Morrisseyba3155b2013-10-29 10:56:46 +0000917stale stack state after turning off the caches. On ARMv8-A cache hits do not
918occur after the cache has been turned off.
Achin Gupta4f6ad662013-10-25 09:08:21 +0100919
920#### plat_pm_ops.affinst_on_suspend()
921
922This function is called by the PSCI implementation after the calling CPU is
923powered on and released from reset in response to an asynchronous wakeup
924event, for example a timer interrupt that was programmed by the CPU during the
925`CPU_SUSPEND` call. It performs the platform-specific setup required to
926restore the saved state for this CPU to resume execution in the normal world
927and also provide secure runtime firmware services.
928
929The `MPIDR` (first argument), `affinity level` (second argument) and `state`
930(third argument) have a similar meaning as described in the previous operations.
931
932This function is called with coherent stacks. This allows the PSCI
933implementation to flush caches at a given affinity level without running into
James Morrisseyba3155b2013-10-29 10:56:46 +0000934stale stack state after turning off the caches. On ARMv8-A cache hits do not
935occur after the cache has been turned off.
Achin Gupta4f6ad662013-10-25 09:08:21 +0100936
937BL3-1 platform initialization code must also detect the system topology and
938the state of each affinity instance in the topology. This information is
939critical for the PSCI runtime service to function correctly. More details are
940provided in the description of the `plat_get_aff_count()` and
941`plat_get_aff_state()` functions above.
942
943
944- - - - - - - - - - - - - - - - - - - - - - - - - -
945
Dan Handleyab2d31e2013-12-02 19:25:12 +0000946_Copyright (c) 2013, ARM Limited and Contributors. All rights reserved._
Achin Gupta4f6ad662013-10-25 09:08:21 +0100947
948
949[User Guide]: user-guide.md
950
951[../plat/common/aarch64/platform_helpers.S]: ../plat/common/aarch64/platform_helpers.S
952[../plat/fvp/platform.h]: ../plat/fvp/platform.h
953[../plat/fvp/aarch64/fvp_common.c]: ../plat/fvp/aarch64/fvp_common.c
954[../plat/fvp/fvp_pm.c]: ../plat/fvp/fvp_pm.c
955[../include/runtime_svc.h]: ../include/runtime_svc.h