blob: a3ef99e8af73318320166fa51c0382b8c3d62e37 [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
191 function `platform_set_stack()` to allocate a stack to each CPU in the
192 platform (see [../plat/common/aarch64/platform_helpers.S]).
193
194
1952.2 Common optional modifications
196---------------------------------
197
198The following are helper functions implemented by the firmware that perform
199common platform-specific tasks. A platform may choose to override these
200definitions.
201
202
203### Function : platform_get_core_pos()
204
205 Argument : unsigned long
206 Return : int
207
208A platform may need to convert the `MPIDR` of a CPU to an absolute number, which
209can be used as a CPU-specific linear index into blocks of memory (for example
210while allocating per-CPU stacks). This routine contains a simple mechanism
211to perform this conversion, using the assumption that each cluster contains a
212maximum of 4 CPUs:
213
214 linear index = cpu_id + (cluster_id * 4)
215
216 cpu_id = 8-bit value in MPIDR at affinity level 0
217 cluster_id = 8-bit value in MPIDR at affinity level 1
218
219
220### Function : platform_set_coherent_stack()
221
222 Argument : unsigned long
223 Return : void
224
225A platform may need stack memory that is coherent with main memory to perform
226certain operations like:
227
228* Turning the MMU on, or
229* Flushing caches prior to powering down a CPU or cluster.
230
231Each BL stage allocates this coherent stack memory for each CPU in the
232`tzfw_coherent_mem` section. A pointer to this memory (`pcpu_dv_mem_stack`) is
233used by this function to allocate a coherent stack for each CPU. A CPU is
234identified by its `MPIDR`, which is passed as an argument to this function.
235
236The size of the stack allocated to each CPU is specified by the constant
237`PCPU_DV_MEM_STACK_SIZE`.
238
239
240### Function : platform_is_primary_cpu()
241
242 Argument : unsigned long
243 Return : unsigned int
244
245This function identifies a CPU by its `MPIDR`, which is passed as the argument,
246to determine whether this CPU is the primary CPU or a secondary CPU. A return
247value of zero indicates that the CPU is not the primary CPU, while a non-zero
248return value indicates that the CPU is the primary CPU.
249
250
251### Function : platform_set_stack()
252
253 Argument : unsigned long
254 Return : void
255
256This function uses the `platform_normal_stacks` pointer variable to allocate
257stacks to each CPU. Further details are given in the description of the
258`platform_normal_stacks` variable below. A CPU is identified by its `MPIDR`,
259which is passed as the argument.
260
261The size of the stack allocated to each CPU is specified by the platform defined
262constant `PLATFORM_STACK_SIZE`.
263
264
265### Function : plat_report_exception()
266
267 Argument : unsigned int
268 Return : void
269
270A platform may need to report various information about its status when an
271exception is taken, for example the current exception level, the CPU security
272state (secure/non-secure), the exception type, and so on. This function is
273called in the following circumstances:
274
275* In BL1, whenever an exception is taken.
276* In BL2, whenever an exception is taken.
277* In BL3-1, whenever an asynchronous exception or a synchronous exception
278 other than an SMC32/SMC64 exception is taken.
279
280The default implementation doesn't do anything, to avoid making assumptions
281about the way the platform displays its status information.
282
283This function receives the exception type as its argument. Possible values for
284exceptions types are listed in the [../include/runtime_svc.h] header file. Note
285that these constants are not related to any architectural exception code; they
286are just an ARM Trusted Firmware convention.
287
288
2893. Modifications specific to a Boot Loader stage
290-------------------------------------------------
291
2923.1 Boot Loader Stage 1 (BL1)
293-----------------------------
294
295BL1 implements the reset vector where execution starts from after a cold or
296warm boot. For each CPU, BL1 is responsible for the following tasks:
297
2981. Distinguishing between a cold boot and a warm boot.
299
3002. In the case of a cold boot and the CPU being the primary CPU, ensuring that
301 only this CPU executes the remaining BL1 code, including loading and passing
302 control to the BL2 stage.
303
3043. In the case of a cold boot and the CPU being a secondary CPU, ensuring that
305 the CPU is placed in a platform-specific state until the primary CPU
306 performs the necessary steps to remove it from this state.
307
3084. In the case of a warm boot, ensuring that the CPU jumps to a platform-
309 specific address in the BL3-1 image in the same processor mode as it was
310 when released from reset.
311
3125. Loading the BL2 image in secure memory using semi-hosting at the
313 address specified by the platform defined constant `BL2_BASE`.
314
3156. Populating a `meminfo` structure with the following information in memory,
316 accessible by BL2 immediately upon entry.
317
318 meminfo.total_base = Base address of secure RAM visible to BL2
319 meminfo.total_size = Size of secure RAM visible to BL2
320 meminfo.free_base = Base address of secure RAM available for
321 allocation to BL2
322 meminfo.free_size = Size of secure RAM available for allocation to BL2
323
324 BL1 places this `meminfo` structure at the beginning of the free memory
325 available for its use. Since BL1 cannot allocate memory dynamically at the
326 moment, its free memory will be available for BL2's use as-is. However, this
327 means that BL2 must read the `meminfo` structure before it starts using its
328 free memory (this is discussed in Section 3.2).
329
330 In future releases of the ARM Trusted Firmware it will be possible for
331 the platform to decide where it wants to place the `meminfo` structure for
332 BL2.
333
334 BL1 implements the `init_bl2_mem_layout()` function to populate the
335 BL2 `meminfo` structure. The platform may override this implementation, for
336 example if the platform wants to restrict the amount of memory visible to
337 BL2. Details of how to do this are given below.
338
339The following functions need to be implemented by the platform port to enable
340BL1 to perform the above tasks.
341
342
343### Function : platform_get_entrypoint() [mandatory]
344
345 Argument : unsigned long
346 Return : unsigned int
347
348This function is called with the `SCTLR.M` and `SCTLR.C` bits disabled. The CPU
349is identified by its `MPIDR`, which is passed as the argument. The function is
350responsible for distinguishing between a warm and cold reset using platform-
351specific means. If it's a warm reset then it returns the entrypoint into the
352BL3-1 image that the CPU must jump to. If it's a cold reset then this function
353must return zero.
354
355This function is also responsible for implementing a platform-specific mechanism
356to handle the condition where the CPU has been warm reset but there is no
357entrypoint to jump to.
358
359This function does not follow the Procedure Call Standard used by the
360Application Binary Interface for the ARM 64-bit architecture. The caller should
361not assume that callee saved registers are preserved across a call to this
362function.
363
364This function fulfills requirement 1 listed above.
365
366
367### Function : plat_secondary_cold_boot_setup() [mandatory]
368
369 Argument : void
370 Return : void
371
372This function is called with the MMU and data caches disabled. It is responsible
373for placing the executing secondary CPU in a platform-specific state until the
374primary CPU performs the necessary actions to bring it out of that state and
375allow entry into the OS.
376
377In the ARM FVP port, each secondary CPU powers itself off. The primary CPU is
378responsible for powering up the secondary CPU when normal world software
379requires them.
380
381This function fulfills requirement 3 above.
382
383
384### Function : platform_cold_boot_init() [mandatory]
385
386 Argument : unsigned long
387 Return : unsigned int
388
389This function executes with the MMU and data caches disabled. It is only called
390by the primary CPU. The argument to this function is the address of the
391`bl1_main()` routine where the generic BL1-specific actions are performed.
392This function performs any platform-specific and architectural setup that the
393platform requires to make execution of `bl1_main()` possible.
394
395The platform must enable the MMU with identity mapped page tables and enable
396caches by setting the `SCTLR.I` and `SCTLR.C` bits.
397
398Platform-specific setup might include configuration of memory controllers,
399configuration of the interconnect to allow the cluster to service cache snoop
400requests from another cluster, zeroing of the ZI section, and so on.
401
402In the ARM FVP port, this function enables CCI snoops into the cluster that the
403primary CPU is part of. It also enables the MMU and initializes the ZI section
404in the BL1 image through the use of linker defined symbols.
405
406This function helps fulfill requirement 2 above.
407
408
409### Function : bl1_platform_setup() [mandatory]
410
411 Argument : void
412 Return : void
413
414This function executes with the MMU and data caches enabled. It is responsible
415for performing any remaining platform-specific setup that can occur after the
416MMU and data cache have been enabled.
417
418In the ARM FVP port, it zeros out the ZI section, enables the system level
419implementation of the generic timer counter and initializes the console.
420
421This function helps fulfill requirement 5 above.
422
423
424### Function : bl1_get_sec_mem_layout() [mandatory]
425
426 Argument : void
427 Return : meminfo
428
429This function executes with the MMU and data caches enabled. The `meminfo`
430structure returned by this function must contain the extents and availability of
431secure RAM for the BL1 stage.
432
433 meminfo.total_base = Base address of secure RAM visible to BL1
434 meminfo.total_size = Size of secure RAM visible to BL1
435 meminfo.free_base = Base address of secure RAM available for allocation
436 to BL1
437 meminfo.free_size = Size of secure RAM available for allocation to BL1
438
439This information is used by BL1 to load the BL2 image in secure RAM. BL1 also
440populates a similar structure to tell BL2 the extents of memory available for
441its own use.
442
443This function helps fulfill requirement 5 above.
444
445
446### Function : init_bl2_mem_layout() [optional]
447
448 Argument : meminfo *, meminfo *, unsigned int, unsigned long
449 Return : void
450
451Each BL stage needs to tell the next stage the amount of secure RAM available
452for it to use. For example, as part of handing control to BL2, BL1 informs BL2
453of the extents of secure RAM available for BL2 to use. BL2 must do the same when
454passing control to BL3-1. This information is populated in a `meminfo`
455structure.
456
457Depending upon where BL2 has been loaded in secure RAM (determined by
458`BL2_BASE`), BL1 calculates the amount of free memory available for BL2 to use.
459BL1 also ensures that its data sections resident in secure RAM are not visible
460to BL2. An illustration of how this is done in the ARM FVP port is given in the
461[User Guide], in the Section "Memory layout on Base FVP".
462
463
4643.2 Boot Loader Stage 2 (BL2)
465-----------------------------
466
467The BL2 stage is executed only by the primary CPU, which is determined in BL1
468using the `platform_is_primary_cpu()` function. BL1 passed control to BL2 at
469`BL2_BASE`. BL2 executes in Secure EL1 and is responsible for:
470
4711. Loading the BL3-1 binary image in secure RAM using semi-hosting. To load the
472 BL3-1 image, BL2 makes use of the `meminfo` structure passed to it by BL1.
473 This structure allows BL2 to calculate how much secure RAM is available for
474 its use. The platform also defines the address in secure RAM where BL3-1 is
475 loaded through the constant `BL31_BASE`. BL2 uses this information to
476 determine if there is enough memory to load the BL3-1 image.
477
4782. Arranging to pass control to a normal world BL image that has been
479 pre-loaded at a platform-specific address. This address is determined using
480 the `plat_get_ns_image_entrypoint()` function described below.
481
482 BL2 populates an `el_change_info` structure in memory provided by the
483 platform with information about how BL3-1 should pass control to the normal
484 world BL image.
485
4863. Populating a `meminfo` structure with the following information in
487 memory that is accessible by BL3-1 immediately upon entry.
488
489 meminfo.total_base = Base address of secure RAM visible to BL3-1
490 meminfo.total_size = Size of secure RAM visible to BL3-1
491 meminfo.free_base = Base address of secure RAM available for allocation
492 to BL3-1
493 meminfo.free_size = Size of secure RAM available for allocation to
494 BL3-1
495
496 BL2 places this `meminfo` structure in memory provided by the
497 platform (`bl2_el_change_mem_ptr`). BL2 implements the
498 `init_bl31_mem_layout()` function to populate the BL3-1 meminfo structure
499 described above. The platform may override this implementation, for example
500 if the platform wants to restrict the amount of memory visible to BL3-1.
501 Details of this function are given below.
502
503The following functions must be implemented by the platform port to enable BL2
504to perform the above tasks.
505
506
507### Function : bl2_early_platform_setup() [mandatory]
508
509 Argument : meminfo *, void *
510 Return : void
511
512This function executes with the MMU and data caches disabled. It is only called
513by the primary CPU. The arguments to this function are:
514
515* The address of the `meminfo` structure populated by BL1
516* An opaque pointer that the platform may use as needed.
517
518The platform must copy the contents of the `meminfo` structure into a private
519variable as the original memory may be subsequently overwritten by BL2. The
520copied structure is made available to all BL2 code through the
521`bl2_get_sec_mem_layout()` function.
522
523
524### Function : bl2_plat_arch_setup() [mandatory]
525
526 Argument : void
527 Return : void
528
529This function executes with the MMU and data caches disabled. It is only called
530by the primary CPU.
531
532The purpose of this function is to perform any architectural initialization
533that varies across platforms, for example enabling the MMU (since the memory
534map differs across platforms).
535
536
537### Function : bl2_platform_setup() [mandatory]
538
539 Argument : void
540 Return : void
541
542This function may execute with the MMU and data caches enabled if the platform
543port does the necessary initialization in `bl2_plat_arch_setup()`. It is only
544called by the primary CPU.
545
546The purpose of this function is to perform any platform initialization specific
547to BL2. This function must initialize a pointer to memory
548(`bl2_el_change_mem_ptr`), which can then be used to populate an
549`el_change_info` structure. The underlying requirement is that the platform must
550initialize this pointer before the `get_el_change_mem_ptr()` function
551accesses it in `bl2_main()`.
552
553The ARM FVP port initializes this pointer to the base address of Secure DRAM
554(`0x06000000`).
555
556
557### Variable : unsigned char bl2_el_change_mem_ptr[EL_CHANGE_MEM_SIZE] [mandatory]
558
559As mentioned in the description of `bl2_platform_setup()`, this pointer is
560initialized by the platform to point to memory where an `el_change_info`
561structure can be populated.
562
563
564### Function : bl2_get_sec_mem_layout() [mandatory]
565
566 Argument : void
567 Return : meminfo
568
569This function may execute with the MMU and data caches enabled if the platform
570port does the necessary initialization in `bl2_plat_arch_setup()`. It is only
571called by the primary CPU.
572
573The purpose of this function is to return a `meminfo` structure populated with
574the extents of secure RAM available for BL2 to use. See
575`bl2_early_platform_setup()` above.
576
577
578### Function : init_bl31_mem_layout() [optional]
579
580 Argument : meminfo *, meminfo *, unsigned int
581 Return : void
582
583Each BL stage needs to tell the next stage the amount of secure RAM that is
584available for it to use. For example, as part of handing control to BL2, BL1
585must inform BL2 about the extents of secure RAM that is available for BL2 to
586use. BL2 must do the same when passing control to BL3-1. This information is
587populated in a `meminfo` structure.
588
589Depending upon where BL3-1 has been loaded in secure RAM (determined by
590`BL31_BASE`), BL2 calculates the amount of free memory available for BL3-1 to
591use. BL2 also ensures that BL3-1 is able reclaim memory occupied by BL2. This
592is done because BL2 never executes again after passing control to BL3-1.
593An illustration of how this is done in the ARM FVP port is given in the
594[User Guide], in the section "Memory layout on Base FVP".
595
596
597### Function : plat_get_ns_image_entrypoint() [mandatory]
598
599 Argument : void
600 Return : unsigned long
601
602As previously described, BL2 is responsible for arranging for control to be
603passed to a normal world BL image through BL3-1. This function returns the
604entrypoint of that image, which BL3-1 uses to jump to it.
605
606The ARM FVP port assumes that flash memory has been pre-loaded with the UEFI
607image, and so returns the base address of flash memory.
608
609
6103.2 Boot Loader Stage 3-1 (BL3-1)
611---------------------------------
612
613During cold boot, the BL3-1 stage is executed only by the primary CPU. This is
614determined in BL1 using the `platform_is_primary_cpu()` function. BL1 passes
615control to BL3-1 at `BL31_BASE`. During warm boot, BL3-1 is executed by all
616CPUs. BL3-1 executes at EL3 and is responsible for:
617
6181. Re-initializing all architectural and platform state. Although BL1 performs
619 some of this initialization, BL3-1 remains resident in EL3 and must ensure
620 that EL3 architectural and platform state is completely initialized. It
621 should make no assumptions about the system state when it receives control.
622
6232. Passing control to a normal world BL image, pre-loaded at a platform-
624 specific address by BL2. BL3-1 uses the `el_change_info` structure that BL2
625 populated in memory to do this.
626
6273. Providing runtime firmware services. Currently, BL3-1 only implements a
628 subset of the Power State Coordination Interface (PSCI) API as a runtime
629 service. See Section 3.3 below for details of porting the PSCI
630 implementation.
631
632The following functions must be implemented by the platform port to enable BL3-1
633to perform the above tasks.
634
635
636### Function : bl31_early_platform_setup() [mandatory]
637
638 Argument : meminfo *, void *, unsigned long
639 Return : void
640
641This function executes with the MMU and data caches disabled. It is only called
642by the primary CPU. The arguments to this function are:
643
644* The address of the `meminfo` structure populated by BL2.
645* An opaque pointer that the platform may use as needed.
646* The `MPIDR` of the primary CPU.
647
648The platform must copy the contents of the `meminfo` structure into a private
649variable as the original memory may be subsequently overwritten by BL3-1. The
650copied structure is made available to all BL3-1 code through the
651`bl31_get_sec_mem_layout()` function.
652
653
654### Function : bl31_plat_arch_setup() [mandatory]
655
656 Argument : void
657 Return : void
658
659This function executes with the MMU and data caches disabled. It is only called
660by the primary CPU.
661
662The purpose of this function is to perform any architectural initialization
663that varies across platforms, for example enabling the MMU (since the memory
664map differs across platforms).
665
666
667### Function : bl31_platform_setup() [mandatory]
668
669 Argument : void
670 Return : void
671
672This function may execute with the MMU and data caches enabled if the platform
673port does the necessary initialization in `bl31_plat_arch_setup()`. It is only
674called by the primary CPU.
675
676The purpose of this function is to complete platform initialization so that both
677BL3-1 runtime services and normal world software can function correctly.
678
679The ARM FVP port does the following:
680* Initializes the generic interrupt controller.
681* Configures the CLCD controller.
682* Grants access to the system counter timer module
683* Initializes the FVP power controller device
684* Detects the system topology.
685
686
687### Function : bl31_get_next_image_info() [mandatory]
688
689 Argument : unsigned long
690 Return : el_change_info *
691
692This function may execute with the MMU and data caches enabled if the platform
693port does the necessary initializations in `bl31_plat_arch_setup()`.
694
695This function is called by `bl31_main()` to retrieve information provided by
696BL2, so that BL3-1 can pass control to the normal world software image. This
697function must return a pointer to the `el_change_info` structure (that was
698copied during `bl31_early_platform_setup()`).
699
700
701### Function : bl31_get_sec_mem_layout() [mandatory]
702
703 Argument : void
704 Return : meminfo
705
706This function may execute with the MMU and data caches enabled if the platform
707port does the necessary initializations in `bl31_plat_arch_setup()`. It is only
708called by the primary CPU.
709
710The purpose of this function is to return a `meminfo` structure populated with
711the extents of secure RAM available for BL3-1 to use. See
712`bl31_early_platform_setup()` above.
713
714
7153.3 Power State Coordination Interface (in BL3-1)
716------------------------------------------------
717
718The ARM Trusted Firmware's implementation of the PSCI API is based around the
719concept of an _affinity instance_. Each _affinity instance_ can be uniquely
720identified in a system by a CPU ID (the processor `MPIDR` is used in the PSCI
721interface) and an _affinity level_. A processing element (for example, a
722CPU) is at level 0. If the CPUs in the system are described in a tree where the
723node above a CPU is a logical grouping of CPUs that share some state, then
724affinity level 1 is that group of CPUs (for example, a cluster), and affinity
725level 2 is a group of clusters (for example, the system). The implementation
726assumes that the affinity level 1 ID can be computed from the affinity level 0
727ID (for example, a unique cluster ID can be computed from the CPU ID). The
728current implementation computes this on the basis of the recommended use of
729`MPIDR` affinity fields in the ARM Architecture Reference Manual.
730
731BL3-1's platform initialization code exports a pointer to the platform-specific
732power management operations required for the PSCI implementation to function
733correctly. This information is populated in the `plat_pm_ops` structure. The
734PSCI implementation calls members of the `plat_pm_ops` structure for performing
735power management operations for each affinity instance. For example, the target
736CPU is specified by its `MPIDR` in a PSCI `CPU_ON` call. The `affinst_on()`
737handler (if present) is called for each affinity instance as the PSCI
738implementation powers up each affinity level implemented in the `MPIDR` (for
739example, CPU, cluster and system).
740
741The following functions must be implemented to initialize PSCI functionality in
742the ARM Trusted Firmware.
743
744
745### Function : plat_get_aff_count() [mandatory]
746
747 Argument : unsigned int, unsigned long
748 Return : unsigned int
749
750This function may execute with the MMU and data caches enabled if the platform
751port does the necessary initializations in `bl31_plat_arch_setup()`. It is only
752called by the primary CPU.
753
754This function is called by the PSCI initialization code to detect the system
755topology. Its purpose is to return the number of affinity instances implemented
756at a given `affinity level` (specified by the first argument) and a given
757`MPIDR` (specified by the second argument). For example, on a dual-cluster
758system where first cluster implements 2 CPUs and the second cluster implements 4
759CPUs, a call to this function with an `MPIDR` corresponding to the first cluster
760(`0x0`) and affinity level 0, would return 2. A call to this function with an
761`MPIDR` corresponding to the second cluster (`0x100`) and affinity level 0,
762would return 4.
763
764
765### Function : plat_get_aff_state() [mandatory]
766
767 Argument : unsigned int, unsigned long
768 Return : unsigned int
769
770This function may execute with the MMU and data caches enabled if the platform
771port does the necessary initializations in `bl31_plat_arch_setup()`. It is only
772called by the primary CPU.
773
774This function is called by the PSCI initialization code. Its purpose is to
775return the state of an affinity instance. The affinity instance is determined by
776the affinity ID at a given `affinity level` (specified by the first argument)
777and an `MPIDR` (specified by the second argument). The state can be one of
778`PSCI_AFF_PRESENT` or `PSCI_AFF_ABSENT`. The latter state is used to cater for
779system topologies where certain affinity instances are unimplemented. For
780example, consider a platform that implements a single cluster with 4 CPUs and
781another CPU implemented directly on the interconnect with the cluster. The
782`MPIDR`s of the cluster would range from `0x0-0x3`. The `MPIDR` of the single
783CPU would be 0x100 to indicate that it does not belong to cluster 0. Cluster 1
784is missing but needs to be accounted for to reach this single CPU in the
785topology tree. Hence it is marked as `PSCI_AFF_ABSENT`.
786
787
788### Function : plat_get_max_afflvl() [mandatory]
789
790 Argument : void
791 Return : int
792
793This function may execute with the MMU and data caches enabled if the platform
794port does the necessary initializations in `bl31_plat_arch_setup()`. It is only
795called by the primary CPU.
796
797This function is called by the PSCI implementation both during cold and warm
798boot, to determine the maximum affinity level that the power management
James Morrisseyba3155b2013-10-29 10:56:46 +0000799operations should apply to. ARMv8-A has support for 4 affinity levels. It is
Achin Gupta4f6ad662013-10-25 09:08:21 +0100800likely that hardware will implement fewer affinity levels. This function allows
801the PSCI implementation to consider only those affinity levels in the system
802that the platform implements. For example, the Base AEM FVP implements two
803clusters with a configurable number of CPUs. It reports the maximum affinity
804level as 1, resulting in PSCI power control up to the cluster level.
805
806
807### Function : platform_setup_pm() [mandatory]
808
809 Argument : plat_pm_ops **
810 Return : int
811
812This function may execute with the MMU and data caches enabled if the platform
813port does the necessary initializations in `bl31_plat_arch_setup()`. It is only
814called by the primary CPU.
815
816This function is called by PSCI initialization code. Its purpose is to export
817handler routines for platform-specific power management actions by populating
818the passed pointer with a pointer to BL3-1's private `plat_pm_ops` structure.
819
820A description of each member of this structure is given below. Please refer to
821the ARM FVP specific implementation of these handlers in [../plat/fvp/fvp_pm.c]
822as an example. A platform port may choose not implement some of the power
823management operations. For example, the ARM FVP port does not implement the
824`affinst_standby()` function.
825
826#### plat_pm_ops.affinst_standby()
827
828Perform the platform-specific setup to enter the standby state indicated by the
829passed argument.
830
831#### plat_pm_ops.affinst_on()
832
833Perform the platform specific setup to power on an affinity instance, specified
834by the `MPIDR` (first argument) and `affinity level` (fourth argument). The
835`state` (fifth argument) contains the current state of that affinity instance
836(ON or OFF). This is useful to determine whether any action must be taken. For
837example, while powering on a CPU, the cluster that contains this CPU might
838already be in the ON state. The platform decides what actions must be taken to
839transition from the current state to the target state (indicated by the power
840management operation).
841
842#### plat_pm_ops.affinst_off()
843
844Perform the platform specific setup to power off an affinity instance in the
845`MPIDR` of the calling CPU. It is called by the PSCI `CPU_OFF` API
846implementation.
847
848The `MPIDR` (first argument), `affinity level` (second argument) and `state`
849(third argument) have a similar meaning as described in the `affinst_on()`
850operation. They are used to identify the affinity instance on which the call
851is made and its current state. This gives the platform port an indication of the
852state transition it must make to perform the requested action. For example, if
853the calling CPU is the last powered on CPU in the cluster, after powering down
854affinity level 0 (CPU), the platform port should power down affinity level 1
855(the cluster) as well.
856
857This function is called with coherent stacks. This allows the PSCI
858implementation to flush caches at a given affinity level without running into
James Morrisseyba3155b2013-10-29 10:56:46 +0000859stale stack state after turning off the caches. On ARMv8-A cache hits do not
860occur after the cache has been turned off.
Achin Gupta4f6ad662013-10-25 09:08:21 +0100861
862#### plat_pm_ops.affinst_suspend()
863
864Perform the platform specific setup to power off an affinity instance in the
865`MPIDR` of the calling CPU. It is called by the PSCI `CPU_SUSPEND` API
866implementation.
867
868The `MPIDR` (first argument), `affinity level` (third argument) and `state`
869(fifth argument) have a similar meaning as described in the `affinst_on()`
870operation. They are used to identify the affinity instance on which the call
871is made and its current state. This gives the platform port an indication of the
872state transition it must make to perform the requested action. For example, if
873the calling CPU is the last powered on CPU in the cluster, after powering down
874affinity level 0 (CPU), the platform port should power down affinity level 1
875(the cluster) as well.
876
877The difference between turning an affinity instance off versus suspending it
878is that in the former case, the affinity instance is expected to re-initialize
879its state when its next powered on (see `affinst_on_finish()`). In the latter
880case, the affinity instance is expected to save enough state so that it can
881resume execution by restoring this state when its powered on (see
882`affinst_suspend_finish()`).
883
884This function is called with coherent stacks. This allows the PSCI
885implementation to flush caches at a given affinity level without running into
James Morrisseyba3155b2013-10-29 10:56:46 +0000886stale stack state after turning off the caches. On ARMv8-A cache hits do not
887occur after the cache has been turned off.
Achin Gupta4f6ad662013-10-25 09:08:21 +0100888
889#### plat_pm_ops.affinst_on_finish()
890
891This function is called by the PSCI implementation after the calling CPU is
892powered on and released from reset in response to an earlier PSCI `CPU_ON` call.
893It performs the platform-specific setup required to initialize enough state for
894this CPU to enter the normal world and also provide secure runtime firmware
895services.
896
897The `MPIDR` (first argument), `affinity level` (second argument) and `state`
898(third argument) have a similar meaning as described in the previous operations.
899
900This function is called with coherent stacks. This allows the PSCI
901implementation to flush caches at a given affinity level without running into
James Morrisseyba3155b2013-10-29 10:56:46 +0000902stale stack state after turning off the caches. On ARMv8-A cache hits do not
903occur after the cache has been turned off.
Achin Gupta4f6ad662013-10-25 09:08:21 +0100904
905#### plat_pm_ops.affinst_on_suspend()
906
907This function is called by the PSCI implementation after the calling CPU is
908powered on and released from reset in response to an asynchronous wakeup
909event, for example a timer interrupt that was programmed by the CPU during the
910`CPU_SUSPEND` call. It performs the platform-specific setup required to
911restore the saved state for this CPU to resume execution in the normal world
912and also provide secure runtime firmware services.
913
914The `MPIDR` (first argument), `affinity level` (second argument) and `state`
915(third argument) have a similar meaning as described in the previous operations.
916
917This function is called with coherent stacks. This allows the PSCI
918implementation to flush caches at a given affinity level without running into
James Morrisseyba3155b2013-10-29 10:56:46 +0000919stale stack state after turning off the caches. On ARMv8-A cache hits do not
920occur after the cache has been turned off.
Achin Gupta4f6ad662013-10-25 09:08:21 +0100921
922BL3-1 platform initialization code must also detect the system topology and
923the state of each affinity instance in the topology. This information is
924critical for the PSCI runtime service to function correctly. More details are
925provided in the description of the `plat_get_aff_count()` and
926`plat_get_aff_state()` functions above.
927
928
929- - - - - - - - - - - - - - - - - - - - - - - - - -
930
931_Copyright (c) 2013 ARM Ltd. All rights reserved._
932
933
934[User Guide]: user-guide.md
935
936[../plat/common/aarch64/platform_helpers.S]: ../plat/common/aarch64/platform_helpers.S
937[../plat/fvp/platform.h]: ../plat/fvp/platform.h
938[../plat/fvp/aarch64/fvp_common.c]: ../plat/fvp/aarch64/fvp_common.c
939[../plat/fvp/fvp_pm.c]: ../plat/fvp/fvp_pm.c
940[../include/runtime_svc.h]: ../include/runtime_svc.h