blob: 11ff3cc58f5a603525dbf313c0f15e8d9e0afaa9 [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)
Harry Liebela960f282013-12-12 16:03:44 +0000164. C Library
Achin Gupta4f6ad662013-10-25 09:08:21 +010017
18- - - - - - - - - - - - - - - - - -
19
201. Introduction
21----------------
22
23Porting the ARM Trusted Firmware to a new platform involves making some
24mandatory and optional modifications for both the cold and warm boot paths.
25Modifications consist of:
26
27* Implementing a platform-specific function or variable,
28* Setting up the execution context in a certain way, or
29* Defining certain constants (for example #defines).
30
31The firmware provides a default implementation of variables and functions to
32fulfill the optional requirements. These implementations are all weakly defined;
33they are provided to ease the porting effort. Each platform port can override
34them with its own implementation if the default implementation is inadequate.
35
36Some modifications are common to all Boot Loader (BL) stages. Section 2
37discusses these in detail. The subsequent sections discuss the remaining
38modifications for each BL stage in detail.
39
40This document should be read in conjunction with the ARM Trusted Firmware
41[User Guide].
42
43
442. Common modifications
45------------------------
46
47This section covers the modifications that should be made by the platform for
48each BL stage to correctly port the firmware stack. They are categorized as
49either mandatory or optional.
50
51
522.1 Common mandatory modifications
53----------------------------------
54A platform port must enable the Memory Management Unit (MMU) with identity
55mapped page tables, and enable both the instruction and data caches for each BL
56stage. In the ARM FVP port, each BL stage configures the MMU in its platform-
57specific architecture setup function, for example `blX_plat_arch_setup()`.
58
59Each platform must allocate a block of identity mapped secure memory with
60Device-nGnRE attributes aligned to page boundary (4K) for each BL stage. This
61memory is identified by the section name `tzfw_coherent_mem` so that its
62possible for the firmware to place variables in it using the following C code
63directive:
64
65 __attribute__ ((section("tzfw_coherent_mem")))
66
67Or alternatively the following assembler code directive:
68
69 .section tzfw_coherent_mem
70
71The `tzfw_coherent_mem` section is used to allocate any data structures that are
72accessed both when a CPU is executing with its MMU and caches enabled, and when
73it's running with its MMU and caches disabled. Examples are given below.
74
75The following variables, functions and constants must be defined by the platform
76for the firmware to work correctly.
77
78
79### File : platform.h [mandatory]
80
81Each platform must export a header file of this name with the following
82constants defined. In the ARM FVP port, this file is found in
83[../plat/fvp/platform.h].
84
James Morrisseyba3155b2013-10-29 10:56:46 +000085* **#define : PLATFORM_LINKER_FORMAT**
Achin Gupta4f6ad662013-10-25 09:08:21 +010086
87 Defines the linker format used by the platform, for example
88 `elf64-littleaarch64` used by the FVP.
89
James Morrisseyba3155b2013-10-29 10:56:46 +000090* **#define : PLATFORM_LINKER_ARCH**
Achin Gupta4f6ad662013-10-25 09:08:21 +010091
92 Defines the processor architecture for the linker by the platform, for
93 example `aarch64` used by the FVP.
94
James Morrisseyba3155b2013-10-29 10:56:46 +000095* **#define : PLATFORM_STACK_SIZE**
Achin Gupta4f6ad662013-10-25 09:08:21 +010096
97 Defines the normal stack memory available to each CPU. This constant is used
98 by `platform_set_stack()`.
99
James Morrisseyba3155b2013-10-29 10:56:46 +0000100* **#define : FIRMWARE_WELCOME_STR**
Achin Gupta4f6ad662013-10-25 09:08:21 +0100101
102 Defines the character string printed by BL1 upon entry into the `bl1_main()`
103 function.
104
James Morrisseyba3155b2013-10-29 10:56:46 +0000105* **#define : BL2_IMAGE_NAME**
Achin Gupta4f6ad662013-10-25 09:08:21 +0100106
107 Name of the BL2 binary image on the host file-system. This name is used by
108 BL1 to load BL2 into secure memory using semi-hosting.
109
James Morrisseyba3155b2013-10-29 10:56:46 +0000110* **#define : PLATFORM_CACHE_LINE_SIZE**
Achin Gupta4f6ad662013-10-25 09:08:21 +0100111
112 Defines the size (in bytes) of the largest cache line across all the cache
113 levels in the platform.
114
James Morrisseyba3155b2013-10-29 10:56:46 +0000115* **#define : PLATFORM_CLUSTER_COUNT**
Achin Gupta4f6ad662013-10-25 09:08:21 +0100116
117 Defines the total number of clusters implemented by the platform in the
118 system.
119
James Morrisseyba3155b2013-10-29 10:56:46 +0000120* **#define : PLATFORM_CORE_COUNT**
Achin Gupta4f6ad662013-10-25 09:08:21 +0100121
122 Defines the total number of CPUs implemented by the platform across all
123 clusters in the system.
124
James Morrisseyba3155b2013-10-29 10:56:46 +0000125* **#define : PLATFORM_MAX_CPUS_PER_CLUSTER**
Achin Gupta4f6ad662013-10-25 09:08:21 +0100126
127 Defines the maximum number of CPUs that can be implemented within a cluster
128 on the platform.
129
James Morrisseyba3155b2013-10-29 10:56:46 +0000130* **#define : PRIMARY_CPU**
Achin Gupta4f6ad662013-10-25 09:08:21 +0100131
132 Defines the `MPIDR` of the primary CPU on the platform. This value is used
133 after a cold boot to distinguish between primary and secondary CPUs.
134
James Morrisseyba3155b2013-10-29 10:56:46 +0000135* **#define : TZROM_BASE**
Achin Gupta4f6ad662013-10-25 09:08:21 +0100136
137 Defines the base address of secure ROM on the platform, where the BL1 binary
138 is loaded. This constant is used by the linker scripts to ensure that the
139 BL1 image fits into the available memory.
140
James Morrisseyba3155b2013-10-29 10:56:46 +0000141* **#define : TZROM_SIZE**
Achin Gupta4f6ad662013-10-25 09:08:21 +0100142
143 Defines the size of secure ROM on the platform. This constant is used by the
144 linker scripts to ensure that the BL1 image fits into the available memory.
145
James Morrisseyba3155b2013-10-29 10:56:46 +0000146* **#define : TZRAM_BASE**
Achin Gupta4f6ad662013-10-25 09:08:21 +0100147
148 Defines the base address of the secure RAM on platform, where the data
149 section of the BL1 binary is loaded. The BL2 and BL3-1 images are also
150 loaded in this secure RAM region. This constant is used by the linker
151 scripts to ensure that the BL1 data section and BL2/BL3-1 binary images fit
152 into the available memory.
153
James Morrisseyba3155b2013-10-29 10:56:46 +0000154* **#define : TZRAM_SIZE**
Achin Gupta4f6ad662013-10-25 09:08:21 +0100155
156 Defines the size of the secure RAM on the platform. This constant is used by
157 the linker scripts to ensure that the BL1 data section and BL2/BL3-1 binary
158 images fit into the available memory.
159
James Morrisseyba3155b2013-10-29 10:56:46 +0000160* **#define : SYS_CNTCTL_BASE**
Achin Gupta4f6ad662013-10-25 09:08:21 +0100161
162 Defines the base address of the `CNTCTLBase` frame of the memory mapped
163 counter and timer in the system level implementation of the generic timer.
164
James Morrisseyba3155b2013-10-29 10:56:46 +0000165* **#define : BL2_BASE**
Achin Gupta4f6ad662013-10-25 09:08:21 +0100166
167 Defines the base address in secure RAM where BL1 loads the BL2 binary image.
Sandrine Bailleuxcd29b0a2013-11-27 10:32:17 +0000168 Must be aligned on a page-size boundary.
Achin Gupta4f6ad662013-10-25 09:08:21 +0100169
James Morrisseyba3155b2013-10-29 10:56:46 +0000170* **#define : BL31_BASE**
Achin Gupta4f6ad662013-10-25 09:08:21 +0100171
172 Defines the base address in secure RAM where BL2 loads the BL3-1 binary
Sandrine Bailleuxcd29b0a2013-11-27 10:32:17 +0000173 image. Must be aligned on a page-size boundary.
Achin Gupta4f6ad662013-10-25 09:08:21 +0100174
175
176### Other mandatory modifications
177
James Morrisseyba3155b2013-10-29 10:56:46 +0000178The following mandatory modifications may be implemented in any file
Achin Gupta4f6ad662013-10-25 09:08:21 +0100179the implementer chooses. In the ARM FVP port, they are implemented in
180[../plat/fvp/aarch64/fvp_common.c].
181
James Morrisseyba3155b2013-10-29 10:56:46 +0000182* **Variable : unsigned char platform_normal_stacks[X][Y]**
Achin Gupta4f6ad662013-10-25 09:08:21 +0100183
184 where X = PLATFORM_STACK_SIZE
185 and Y = PLATFORM_CORE_COUNT
186
187 Each platform must allocate a block of memory with Normal Cacheable, Write
188 back, Write allocate and Inner Shareable attributes aligned to the size (in
189 bytes) of the largest cache line amongst all caches implemented in the
190 system. A pointer to this memory should be exported with the name
191 `platform_normal_stacks`. This pointer is used by the common platform helper
Achin Guptac8afc782013-11-25 18:45:02 +0000192 functions `platform_set_stack()` (to allocate a stack for each CPU in the
193 platform) & `platform_get_stack()` (to return the base address of that
194 stack) (see [../plat/common/aarch64/platform_helpers.S]).
Achin Gupta4f6ad662013-10-25 09:08:21 +0100195
196
1972.2 Common optional modifications
198---------------------------------
199
200The following are helper functions implemented by the firmware that perform
201common platform-specific tasks. A platform may choose to override these
202definitions.
203
204
205### Function : platform_get_core_pos()
206
207 Argument : unsigned long
208 Return : int
209
210A platform may need to convert the `MPIDR` of a CPU to an absolute number, which
211can be used as a CPU-specific linear index into blocks of memory (for example
212while allocating per-CPU stacks). This routine contains a simple mechanism
213to perform this conversion, using the assumption that each cluster contains a
214maximum of 4 CPUs:
215
216 linear index = cpu_id + (cluster_id * 4)
217
218 cpu_id = 8-bit value in MPIDR at affinity level 0
219 cluster_id = 8-bit value in MPIDR at affinity level 1
220
221
222### Function : platform_set_coherent_stack()
223
224 Argument : unsigned long
225 Return : void
226
227A platform may need stack memory that is coherent with main memory to perform
228certain operations like:
229
230* Turning the MMU on, or
231* Flushing caches prior to powering down a CPU or cluster.
232
233Each BL stage allocates this coherent stack memory for each CPU in the
234`tzfw_coherent_mem` section. A pointer to this memory (`pcpu_dv_mem_stack`) is
235used by this function to allocate a coherent stack for each CPU. A CPU is
236identified by its `MPIDR`, which is passed as an argument to this function.
237
238The size of the stack allocated to each CPU is specified by the constant
239`PCPU_DV_MEM_STACK_SIZE`.
240
241
242### Function : platform_is_primary_cpu()
243
244 Argument : unsigned long
245 Return : unsigned int
246
247This function identifies a CPU by its `MPIDR`, which is passed as the argument,
248to determine whether this CPU is the primary CPU or a secondary CPU. A return
249value of zero indicates that the CPU is not the primary CPU, while a non-zero
250return value indicates that the CPU is the primary CPU.
251
252
253### Function : platform_set_stack()
254
255 Argument : unsigned long
256 Return : void
257
258This function uses the `platform_normal_stacks` pointer variable to allocate
259stacks to each CPU. Further details are given in the description of the
260`platform_normal_stacks` variable below. A CPU is identified by its `MPIDR`,
261which is passed as the argument.
262
263The size of the stack allocated to each CPU is specified by the platform defined
264constant `PLATFORM_STACK_SIZE`.
265
266
Achin Guptac8afc782013-11-25 18:45:02 +0000267### Function : platform_get_stack()
268
269 Argument : unsigned long
270 Return : unsigned long
271
272This function uses the `platform_normal_stacks` pointer variable to return the
273base address of the stack memory reserved for a CPU. Further details are given
274in the description of the `platform_normal_stacks` variable below. A CPU is
275identified by its `MPIDR`, which is passed as the argument.
276
277The size of the stack allocated to each CPU is specified by the platform defined
278constant `PLATFORM_STACK_SIZE`.
279
280
Achin Gupta4f6ad662013-10-25 09:08:21 +0100281### Function : plat_report_exception()
282
283 Argument : unsigned int
284 Return : void
285
286A platform may need to report various information about its status when an
287exception is taken, for example the current exception level, the CPU security
288state (secure/non-secure), the exception type, and so on. This function is
289called in the following circumstances:
290
291* In BL1, whenever an exception is taken.
292* In BL2, whenever an exception is taken.
293* In BL3-1, whenever an asynchronous exception or a synchronous exception
294 other than an SMC32/SMC64 exception is taken.
295
296The default implementation doesn't do anything, to avoid making assumptions
297about the way the platform displays its status information.
298
299This function receives the exception type as its argument. Possible values for
300exceptions types are listed in the [../include/runtime_svc.h] header file. Note
301that these constants are not related to any architectural exception code; they
302are just an ARM Trusted Firmware convention.
303
304
3053. Modifications specific to a Boot Loader stage
306-------------------------------------------------
307
3083.1 Boot Loader Stage 1 (BL1)
309-----------------------------
310
311BL1 implements the reset vector where execution starts from after a cold or
312warm boot. For each CPU, BL1 is responsible for the following tasks:
313
3141. Distinguishing between a cold boot and a warm boot.
315
3162. In the case of a cold boot and the CPU being the primary CPU, ensuring that
317 only this CPU executes the remaining BL1 code, including loading and passing
318 control to the BL2 stage.
319
3203. In the case of a cold boot and the CPU being a secondary CPU, ensuring that
321 the CPU is placed in a platform-specific state until the primary CPU
322 performs the necessary steps to remove it from this state.
323
3244. In the case of a warm boot, ensuring that the CPU jumps to a platform-
325 specific address in the BL3-1 image in the same processor mode as it was
326 when released from reset.
327
3285. Loading the BL2 image in secure memory using semi-hosting at the
329 address specified by the platform defined constant `BL2_BASE`.
330
3316. Populating a `meminfo` structure with the following information in memory,
332 accessible by BL2 immediately upon entry.
333
334 meminfo.total_base = Base address of secure RAM visible to BL2
335 meminfo.total_size = Size of secure RAM visible to BL2
336 meminfo.free_base = Base address of secure RAM available for
337 allocation to BL2
338 meminfo.free_size = Size of secure RAM available for allocation to BL2
339
340 BL1 places this `meminfo` structure at the beginning of the free memory
341 available for its use. Since BL1 cannot allocate memory dynamically at the
342 moment, its free memory will be available for BL2's use as-is. However, this
343 means that BL2 must read the `meminfo` structure before it starts using its
344 free memory (this is discussed in Section 3.2).
345
346 In future releases of the ARM Trusted Firmware it will be possible for
347 the platform to decide where it wants to place the `meminfo` structure for
348 BL2.
349
350 BL1 implements the `init_bl2_mem_layout()` function to populate the
351 BL2 `meminfo` structure. The platform may override this implementation, for
352 example if the platform wants to restrict the amount of memory visible to
353 BL2. Details of how to do this are given below.
354
355The following functions need to be implemented by the platform port to enable
356BL1 to perform the above tasks.
357
358
359### Function : platform_get_entrypoint() [mandatory]
360
361 Argument : unsigned long
362 Return : unsigned int
363
364This function is called with the `SCTLR.M` and `SCTLR.C` bits disabled. The CPU
365is identified by its `MPIDR`, which is passed as the argument. The function is
366responsible for distinguishing between a warm and cold reset using platform-
367specific means. If it's a warm reset then it returns the entrypoint into the
368BL3-1 image that the CPU must jump to. If it's a cold reset then this function
369must return zero.
370
371This function is also responsible for implementing a platform-specific mechanism
372to handle the condition where the CPU has been warm reset but there is no
373entrypoint to jump to.
374
375This function does not follow the Procedure Call Standard used by the
376Application Binary Interface for the ARM 64-bit architecture. The caller should
377not assume that callee saved registers are preserved across a call to this
378function.
379
380This function fulfills requirement 1 listed above.
381
382
383### Function : plat_secondary_cold_boot_setup() [mandatory]
384
385 Argument : void
386 Return : void
387
388This function is called with the MMU and data caches disabled. It is responsible
389for placing the executing secondary CPU in a platform-specific state until the
390primary CPU performs the necessary actions to bring it out of that state and
391allow entry into the OS.
392
393In the ARM FVP port, each secondary CPU powers itself off. The primary CPU is
394responsible for powering up the secondary CPU when normal world software
395requires them.
396
397This function fulfills requirement 3 above.
398
399
400### Function : platform_cold_boot_init() [mandatory]
401
402 Argument : unsigned long
403 Return : unsigned int
404
405This function executes with the MMU and data caches disabled. It is only called
406by the primary CPU. The argument to this function is the address of the
407`bl1_main()` routine where the generic BL1-specific actions are performed.
408This function performs any platform-specific and architectural setup that the
409platform requires to make execution of `bl1_main()` possible.
410
411The platform must enable the MMU with identity mapped page tables and enable
412caches by setting the `SCTLR.I` and `SCTLR.C` bits.
413
414Platform-specific setup might include configuration of memory controllers,
415configuration of the interconnect to allow the cluster to service cache snoop
416requests from another cluster, zeroing of the ZI section, and so on.
417
418In the ARM FVP port, this function enables CCI snoops into the cluster that the
419primary CPU is part of. It also enables the MMU and initializes the ZI section
420in the BL1 image through the use of linker defined symbols.
421
422This function helps fulfill requirement 2 above.
423
424
425### Function : bl1_platform_setup() [mandatory]
426
427 Argument : void
428 Return : void
429
430This function executes with the MMU and data caches enabled. It is responsible
431for performing any remaining platform-specific setup that can occur after the
432MMU and data cache have been enabled.
433
434In the ARM FVP port, it zeros out the ZI section, enables the system level
435implementation of the generic timer counter and initializes the console.
436
437This function helps fulfill requirement 5 above.
438
439
Sandrine Bailleuxee12f6f2013-11-28 14:55:58 +0000440### Function : bl1_plat_sec_mem_layout() [mandatory]
Achin Gupta4f6ad662013-10-25 09:08:21 +0100441
442 Argument : void
Sandrine Bailleuxee12f6f2013-11-28 14:55:58 +0000443 Return : meminfo *
Achin Gupta4f6ad662013-10-25 09:08:21 +0100444
Sandrine Bailleuxee12f6f2013-11-28 14:55:58 +0000445This function should only be called on the cold boot path. It executes with the
446MMU and data caches enabled. The pointer returned by this function must point to
447a `meminfo` structure containing the extents and availability of secure RAM for
448the BL1 stage.
Achin Gupta4f6ad662013-10-25 09:08:21 +0100449
450 meminfo.total_base = Base address of secure RAM visible to BL1
451 meminfo.total_size = Size of secure RAM visible to BL1
452 meminfo.free_base = Base address of secure RAM available for allocation
453 to BL1
454 meminfo.free_size = Size of secure RAM available for allocation to BL1
455
456This information is used by BL1 to load the BL2 image in secure RAM. BL1 also
457populates a similar structure to tell BL2 the extents of memory available for
458its own use.
459
460This function helps fulfill requirement 5 above.
461
462
463### Function : init_bl2_mem_layout() [optional]
464
465 Argument : meminfo *, meminfo *, unsigned int, unsigned long
466 Return : void
467
468Each BL stage needs to tell the next stage the amount of secure RAM available
469for it to use. For example, as part of handing control to BL2, BL1 informs BL2
470of the extents of secure RAM available for BL2 to use. BL2 must do the same when
471passing control to BL3-1. This information is populated in a `meminfo`
472structure.
473
474Depending upon where BL2 has been loaded in secure RAM (determined by
475`BL2_BASE`), BL1 calculates the amount of free memory available for BL2 to use.
476BL1 also ensures that its data sections resident in secure RAM are not visible
477to BL2. An illustration of how this is done in the ARM FVP port is given in the
478[User Guide], in the Section "Memory layout on Base FVP".
479
480
4813.2 Boot Loader Stage 2 (BL2)
482-----------------------------
483
484The BL2 stage is executed only by the primary CPU, which is determined in BL1
485using the `platform_is_primary_cpu()` function. BL1 passed control to BL2 at
486`BL2_BASE`. BL2 executes in Secure EL1 and is responsible for:
487
4881. Loading the BL3-1 binary image in secure RAM using semi-hosting. To load the
489 BL3-1 image, BL2 makes use of the `meminfo` structure passed to it by BL1.
490 This structure allows BL2 to calculate how much secure RAM is available for
491 its use. The platform also defines the address in secure RAM where BL3-1 is
492 loaded through the constant `BL31_BASE`. BL2 uses this information to
493 determine if there is enough memory to load the BL3-1 image.
494
4952. Arranging to pass control to a normal world BL image that has been
496 pre-loaded at a platform-specific address. This address is determined using
497 the `plat_get_ns_image_entrypoint()` function described below.
498
499 BL2 populates an `el_change_info` structure in memory provided by the
500 platform with information about how BL3-1 should pass control to the normal
501 world BL image.
502
5033. Populating a `meminfo` structure with the following information in
504 memory that is accessible by BL3-1 immediately upon entry.
505
506 meminfo.total_base = Base address of secure RAM visible to BL3-1
507 meminfo.total_size = Size of secure RAM visible to BL3-1
508 meminfo.free_base = Base address of secure RAM available for allocation
509 to BL3-1
510 meminfo.free_size = Size of secure RAM available for allocation to
511 BL3-1
512
513 BL2 places this `meminfo` structure in memory provided by the
514 platform (`bl2_el_change_mem_ptr`). BL2 implements the
515 `init_bl31_mem_layout()` function to populate the BL3-1 meminfo structure
516 described above. The platform may override this implementation, for example
517 if the platform wants to restrict the amount of memory visible to BL3-1.
518 Details of this function are given below.
519
520The following functions must be implemented by the platform port to enable BL2
521to perform the above tasks.
522
523
524### Function : bl2_early_platform_setup() [mandatory]
525
526 Argument : meminfo *, void *
527 Return : void
528
529This function executes with the MMU and data caches disabled. It is only called
530by the primary CPU. The arguments to this function are:
531
532* The address of the `meminfo` structure populated by BL1
533* An opaque pointer that the platform may use as needed.
534
535The platform must copy the contents of the `meminfo` structure into a private
536variable as the original memory may be subsequently overwritten by BL2. The
537copied structure is made available to all BL2 code through the
Sandrine Bailleuxee12f6f2013-11-28 14:55:58 +0000538`bl2_plat_sec_mem_layout()` function.
Achin Gupta4f6ad662013-10-25 09:08:21 +0100539
540
541### Function : bl2_plat_arch_setup() [mandatory]
542
543 Argument : void
544 Return : void
545
546This function executes with the MMU and data caches disabled. It is only called
547by the primary CPU.
548
549The purpose of this function is to perform any architectural initialization
550that varies across platforms, for example enabling the MMU (since the memory
551map differs across platforms).
552
553
554### Function : bl2_platform_setup() [mandatory]
555
556 Argument : void
557 Return : void
558
559This function may execute with the MMU and data caches enabled if the platform
560port does the necessary initialization in `bl2_plat_arch_setup()`. It is only
561called by the primary CPU.
562
563The purpose of this function is to perform any platform initialization specific
564to BL2. This function must initialize a pointer to memory
565(`bl2_el_change_mem_ptr`), which can then be used to populate an
566`el_change_info` structure. The underlying requirement is that the platform must
567initialize this pointer before the `get_el_change_mem_ptr()` function
568accesses it in `bl2_main()`.
569
570The ARM FVP port initializes this pointer to the base address of Secure DRAM
571(`0x06000000`).
572
573
574### Variable : unsigned char bl2_el_change_mem_ptr[EL_CHANGE_MEM_SIZE] [mandatory]
575
576As mentioned in the description of `bl2_platform_setup()`, this pointer is
577initialized by the platform to point to memory where an `el_change_info`
578structure can be populated.
579
580
Sandrine Bailleuxee12f6f2013-11-28 14:55:58 +0000581### Function : bl2_plat_sec_mem_layout() [mandatory]
Achin Gupta4f6ad662013-10-25 09:08:21 +0100582
583 Argument : void
Sandrine Bailleuxee12f6f2013-11-28 14:55:58 +0000584 Return : meminfo *
Achin Gupta4f6ad662013-10-25 09:08:21 +0100585
Sandrine Bailleuxee12f6f2013-11-28 14:55:58 +0000586This function should only be called on the cold boot path. It may execute with
587the MMU and data caches enabled if the platform port does the necessary
588initialization in `bl2_plat_arch_setup()`. It is only called by the primary CPU.
Achin Gupta4f6ad662013-10-25 09:08:21 +0100589
Sandrine Bailleuxee12f6f2013-11-28 14:55:58 +0000590The purpose of this function is to return a pointer to a `meminfo` structure
591populated with the extents of secure RAM available for BL2 to use. See
Achin Gupta4f6ad662013-10-25 09:08:21 +0100592`bl2_early_platform_setup()` above.
593
594
595### Function : init_bl31_mem_layout() [optional]
596
597 Argument : meminfo *, meminfo *, unsigned int
598 Return : void
599
600Each BL stage needs to tell the next stage the amount of secure RAM that is
601available for it to use. For example, as part of handing control to BL2, BL1
602must inform BL2 about the extents of secure RAM that is available for BL2 to
603use. BL2 must do the same when passing control to BL3-1. This information is
604populated in a `meminfo` structure.
605
606Depending upon where BL3-1 has been loaded in secure RAM (determined by
607`BL31_BASE`), BL2 calculates the amount of free memory available for BL3-1 to
608use. BL2 also ensures that BL3-1 is able reclaim memory occupied by BL2. This
609is done because BL2 never executes again after passing control to BL3-1.
610An illustration of how this is done in the ARM FVP port is given in the
611[User Guide], in the section "Memory layout on Base FVP".
612
613
614### Function : plat_get_ns_image_entrypoint() [mandatory]
615
616 Argument : void
617 Return : unsigned long
618
619As previously described, BL2 is responsible for arranging for control to be
620passed to a normal world BL image through BL3-1. This function returns the
621entrypoint of that image, which BL3-1 uses to jump to it.
622
623The ARM FVP port assumes that flash memory has been pre-loaded with the UEFI
624image, and so returns the base address of flash memory.
625
626
6273.2 Boot Loader Stage 3-1 (BL3-1)
628---------------------------------
629
630During cold boot, the BL3-1 stage is executed only by the primary CPU. This is
631determined in BL1 using the `platform_is_primary_cpu()` function. BL1 passes
632control to BL3-1 at `BL31_BASE`. During warm boot, BL3-1 is executed by all
633CPUs. BL3-1 executes at EL3 and is responsible for:
634
6351. Re-initializing all architectural and platform state. Although BL1 performs
636 some of this initialization, BL3-1 remains resident in EL3 and must ensure
637 that EL3 architectural and platform state is completely initialized. It
638 should make no assumptions about the system state when it receives control.
639
6402. Passing control to a normal world BL image, pre-loaded at a platform-
641 specific address by BL2. BL3-1 uses the `el_change_info` structure that BL2
642 populated in memory to do this.
643
6443. Providing runtime firmware services. Currently, BL3-1 only implements a
645 subset of the Power State Coordination Interface (PSCI) API as a runtime
646 service. See Section 3.3 below for details of porting the PSCI
647 implementation.
648
649The following functions must be implemented by the platform port to enable BL3-1
650to perform the above tasks.
651
652
653### Function : bl31_early_platform_setup() [mandatory]
654
655 Argument : meminfo *, void *, unsigned long
656 Return : void
657
658This function executes with the MMU and data caches disabled. It is only called
659by the primary CPU. The arguments to this function are:
660
661* The address of the `meminfo` structure populated by BL2.
662* An opaque pointer that the platform may use as needed.
663* The `MPIDR` of the primary CPU.
664
665The platform must copy the contents of the `meminfo` structure into a private
666variable as the original memory may be subsequently overwritten by BL3-1. The
667copied structure is made available to all BL3-1 code through the
Sandrine Bailleuxee12f6f2013-11-28 14:55:58 +0000668`bl31_plat_sec_mem_layout()` function.
Achin Gupta4f6ad662013-10-25 09:08:21 +0100669
670
671### Function : bl31_plat_arch_setup() [mandatory]
672
673 Argument : void
674 Return : void
675
676This function executes with the MMU and data caches disabled. It is only called
677by the primary CPU.
678
679The purpose of this function is to perform any architectural initialization
680that varies across platforms, for example enabling the MMU (since the memory
681map differs across platforms).
682
683
684### Function : bl31_platform_setup() [mandatory]
685
686 Argument : void
687 Return : void
688
689This function may execute with the MMU and data caches enabled if the platform
690port does the necessary initialization in `bl31_plat_arch_setup()`. It is only
691called by the primary CPU.
692
693The purpose of this function is to complete platform initialization so that both
694BL3-1 runtime services and normal world software can function correctly.
695
696The ARM FVP port does the following:
697* Initializes the generic interrupt controller.
698* Configures the CLCD controller.
699* Grants access to the system counter timer module
700* Initializes the FVP power controller device
701* Detects the system topology.
702
703
704### Function : bl31_get_next_image_info() [mandatory]
705
706 Argument : unsigned long
707 Return : el_change_info *
708
709This function may execute with the MMU and data caches enabled if the platform
710port does the necessary initializations in `bl31_plat_arch_setup()`.
711
712This function is called by `bl31_main()` to retrieve information provided by
713BL2, so that BL3-1 can pass control to the normal world software image. This
714function must return a pointer to the `el_change_info` structure (that was
715copied during `bl31_early_platform_setup()`).
716
717
Sandrine Bailleuxee12f6f2013-11-28 14:55:58 +0000718### Function : bl31_plat_sec_mem_layout() [mandatory]
Achin Gupta4f6ad662013-10-25 09:08:21 +0100719
720 Argument : void
Sandrine Bailleuxee12f6f2013-11-28 14:55:58 +0000721 Return : meminfo *
Achin Gupta4f6ad662013-10-25 09:08:21 +0100722
Sandrine Bailleuxee12f6f2013-11-28 14:55:58 +0000723This function should only be called on the cold boot path. This function may
724execute with the MMU and data caches enabled if the platform port does the
725necessary initializations in `bl31_plat_arch_setup()`. It is only called by the
726primary CPU.
Achin Gupta4f6ad662013-10-25 09:08:21 +0100727
Sandrine Bailleuxee12f6f2013-11-28 14:55:58 +0000728The purpose of this function is to return a pointer to a `meminfo` structure
729populated with the extents of secure RAM available for BL3-1 to use. See
Achin Gupta4f6ad662013-10-25 09:08:21 +0100730`bl31_early_platform_setup()` above.
731
732
7333.3 Power State Coordination Interface (in BL3-1)
734------------------------------------------------
735
736The ARM Trusted Firmware's implementation of the PSCI API is based around the
737concept of an _affinity instance_. Each _affinity instance_ can be uniquely
738identified in a system by a CPU ID (the processor `MPIDR` is used in the PSCI
739interface) and an _affinity level_. A processing element (for example, a
740CPU) is at level 0. If the CPUs in the system are described in a tree where the
741node above a CPU is a logical grouping of CPUs that share some state, then
742affinity level 1 is that group of CPUs (for example, a cluster), and affinity
743level 2 is a group of clusters (for example, the system). The implementation
744assumes that the affinity level 1 ID can be computed from the affinity level 0
745ID (for example, a unique cluster ID can be computed from the CPU ID). The
746current implementation computes this on the basis of the recommended use of
747`MPIDR` affinity fields in the ARM Architecture Reference Manual.
748
749BL3-1's platform initialization code exports a pointer to the platform-specific
750power management operations required for the PSCI implementation to function
751correctly. This information is populated in the `plat_pm_ops` structure. The
752PSCI implementation calls members of the `plat_pm_ops` structure for performing
753power management operations for each affinity instance. For example, the target
754CPU is specified by its `MPIDR` in a PSCI `CPU_ON` call. The `affinst_on()`
755handler (if present) is called for each affinity instance as the PSCI
756implementation powers up each affinity level implemented in the `MPIDR` (for
757example, CPU, cluster and system).
758
759The following functions must be implemented to initialize PSCI functionality in
760the ARM Trusted Firmware.
761
762
763### Function : plat_get_aff_count() [mandatory]
764
765 Argument : unsigned int, unsigned long
766 Return : unsigned int
767
768This function may execute with the MMU and data caches enabled if the platform
769port does the necessary initializations in `bl31_plat_arch_setup()`. It is only
770called by the primary CPU.
771
772This function is called by the PSCI initialization code to detect the system
773topology. Its purpose is to return the number of affinity instances implemented
774at a given `affinity level` (specified by the first argument) and a given
775`MPIDR` (specified by the second argument). For example, on a dual-cluster
776system where first cluster implements 2 CPUs and the second cluster implements 4
777CPUs, a call to this function with an `MPIDR` corresponding to the first cluster
778(`0x0`) and affinity level 0, would return 2. A call to this function with an
779`MPIDR` corresponding to the second cluster (`0x100`) and affinity level 0,
780would return 4.
781
782
783### Function : plat_get_aff_state() [mandatory]
784
785 Argument : unsigned int, unsigned long
786 Return : unsigned int
787
788This function may execute with the MMU and data caches enabled if the platform
789port does the necessary initializations in `bl31_plat_arch_setup()`. It is only
790called by the primary CPU.
791
792This function is called by the PSCI initialization code. Its purpose is to
793return the state of an affinity instance. The affinity instance is determined by
794the affinity ID at a given `affinity level` (specified by the first argument)
795and an `MPIDR` (specified by the second argument). The state can be one of
796`PSCI_AFF_PRESENT` or `PSCI_AFF_ABSENT`. The latter state is used to cater for
797system topologies where certain affinity instances are unimplemented. For
798example, consider a platform that implements a single cluster with 4 CPUs and
799another CPU implemented directly on the interconnect with the cluster. The
800`MPIDR`s of the cluster would range from `0x0-0x3`. The `MPIDR` of the single
801CPU would be 0x100 to indicate that it does not belong to cluster 0. Cluster 1
802is missing but needs to be accounted for to reach this single CPU in the
803topology tree. Hence it is marked as `PSCI_AFF_ABSENT`.
804
805
806### Function : plat_get_max_afflvl() [mandatory]
807
808 Argument : void
809 Return : int
810
811This function may execute with the MMU and data caches enabled if the platform
812port does the necessary initializations in `bl31_plat_arch_setup()`. It is only
813called by the primary CPU.
814
815This function is called by the PSCI implementation both during cold and warm
816boot, to determine the maximum affinity level that the power management
James Morrisseyba3155b2013-10-29 10:56:46 +0000817operations should apply to. ARMv8-A has support for 4 affinity levels. It is
Achin Gupta4f6ad662013-10-25 09:08:21 +0100818likely that hardware will implement fewer affinity levels. This function allows
819the PSCI implementation to consider only those affinity levels in the system
820that the platform implements. For example, the Base AEM FVP implements two
821clusters with a configurable number of CPUs. It reports the maximum affinity
822level as 1, resulting in PSCI power control up to the cluster level.
823
824
825### Function : platform_setup_pm() [mandatory]
826
827 Argument : plat_pm_ops **
828 Return : int
829
830This function may execute with the MMU and data caches enabled if the platform
831port does the necessary initializations in `bl31_plat_arch_setup()`. It is only
832called by the primary CPU.
833
834This function is called by PSCI initialization code. Its purpose is to export
835handler routines for platform-specific power management actions by populating
836the passed pointer with a pointer to BL3-1's private `plat_pm_ops` structure.
837
838A description of each member of this structure is given below. Please refer to
839the ARM FVP specific implementation of these handlers in [../plat/fvp/fvp_pm.c]
840as an example. A platform port may choose not implement some of the power
841management operations. For example, the ARM FVP port does not implement the
842`affinst_standby()` function.
843
844#### plat_pm_ops.affinst_standby()
845
846Perform the platform-specific setup to enter the standby state indicated by the
847passed argument.
848
849#### plat_pm_ops.affinst_on()
850
851Perform the platform specific setup to power on an affinity instance, specified
852by the `MPIDR` (first argument) and `affinity level` (fourth argument). The
853`state` (fifth argument) contains the current state of that affinity instance
854(ON or OFF). This is useful to determine whether any action must be taken. For
855example, while powering on a CPU, the cluster that contains this CPU might
856already be in the ON state. The platform decides what actions must be taken to
857transition from the current state to the target state (indicated by the power
858management operation).
859
860#### plat_pm_ops.affinst_off()
861
862Perform the platform specific setup to power off an affinity instance in the
863`MPIDR` of the calling CPU. It is called by the PSCI `CPU_OFF` API
864implementation.
865
866The `MPIDR` (first argument), `affinity level` (second argument) and `state`
867(third argument) have a similar meaning as described in the `affinst_on()`
868operation. They are used to identify the affinity instance on which the call
869is made and its current state. This gives the platform port an indication of the
870state transition it must make to perform the requested action. For example, if
871the calling CPU is the last powered on CPU in the cluster, after powering down
872affinity level 0 (CPU), the platform port should power down affinity level 1
873(the cluster) as well.
874
875This function is called with coherent stacks. This allows the PSCI
876implementation to flush caches at a given affinity level without running into
James Morrisseyba3155b2013-10-29 10:56:46 +0000877stale stack state after turning off the caches. On ARMv8-A cache hits do not
878occur after the cache has been turned off.
Achin Gupta4f6ad662013-10-25 09:08:21 +0100879
880#### plat_pm_ops.affinst_suspend()
881
882Perform the platform specific setup to power off an affinity instance in the
883`MPIDR` of the calling CPU. It is called by the PSCI `CPU_SUSPEND` API
884implementation.
885
886The `MPIDR` (first argument), `affinity level` (third argument) and `state`
887(fifth argument) have a similar meaning as described in the `affinst_on()`
888operation. They are used to identify the affinity instance on which the call
889is made and its current state. This gives the platform port an indication of the
890state transition it must make to perform the requested action. For example, if
891the calling CPU is the last powered on CPU in the cluster, after powering down
892affinity level 0 (CPU), the platform port should power down affinity level 1
893(the cluster) as well.
894
895The difference between turning an affinity instance off versus suspending it
896is that in the former case, the affinity instance is expected to re-initialize
897its state when its next powered on (see `affinst_on_finish()`). In the latter
898case, the affinity instance is expected to save enough state so that it can
899resume execution by restoring this state when its powered on (see
900`affinst_suspend_finish()`).
901
902This function is called with coherent stacks. This allows the PSCI
903implementation to flush caches at a given affinity level without running into
James Morrisseyba3155b2013-10-29 10:56:46 +0000904stale stack state after turning off the caches. On ARMv8-A cache hits do not
905occur after the cache has been turned off.
Achin Gupta4f6ad662013-10-25 09:08:21 +0100906
907#### plat_pm_ops.affinst_on_finish()
908
909This function is called by the PSCI implementation after the calling CPU is
910powered on and released from reset in response to an earlier PSCI `CPU_ON` call.
911It performs the platform-specific setup required to initialize enough state for
912this CPU to enter the normal world and also provide secure runtime firmware
913services.
914
915The `MPIDR` (first argument), `affinity level` (second argument) and `state`
916(third argument) have a similar meaning as described in the previous operations.
917
918This function is called with coherent stacks. This allows the PSCI
919implementation to flush caches at a given affinity level without running into
James Morrisseyba3155b2013-10-29 10:56:46 +0000920stale stack state after turning off the caches. On ARMv8-A cache hits do not
921occur after the cache has been turned off.
Achin Gupta4f6ad662013-10-25 09:08:21 +0100922
923#### plat_pm_ops.affinst_on_suspend()
924
925This function is called by the PSCI implementation after the calling CPU is
926powered on and released from reset in response to an asynchronous wakeup
927event, for example a timer interrupt that was programmed by the CPU during the
928`CPU_SUSPEND` call. It performs the platform-specific setup required to
929restore the saved state for this CPU to resume execution in the normal world
930and also provide secure runtime firmware services.
931
932The `MPIDR` (first argument), `affinity level` (second argument) and `state`
933(third argument) have a similar meaning as described in the previous operations.
934
935This function is called with coherent stacks. This allows the PSCI
936implementation to flush caches at a given affinity level without running into
James Morrisseyba3155b2013-10-29 10:56:46 +0000937stale stack state after turning off the caches. On ARMv8-A cache hits do not
938occur after the cache has been turned off.
Achin Gupta4f6ad662013-10-25 09:08:21 +0100939
940BL3-1 platform initialization code must also detect the system topology and
941the state of each affinity instance in the topology. This information is
942critical for the PSCI runtime service to function correctly. More details are
943provided in the description of the `plat_get_aff_count()` and
944`plat_get_aff_state()` functions above.
945
946
Harry Liebela960f282013-12-12 16:03:44 +00009474. C Library
948-------------
949
950To avoid subtle toolchain behavioral dependencies, the header files provided
951by the compiler are not used. The software is built with the `-nostdinc` flag
952to ensure no headers are included from the toolchain inadvertently. Instead the
953required headers are included in the ARM Trusted Firmware source tree. The
954library only contains those C library definitions required by the local
955implementation. If more functionality is required, the needed library functions
956will need to be added to the local implementation.
957
958Versions of [FreeBSD] headers can be found in `include/stdlib`. Some of these
959headers have been cut down in order to simplify the implementation. In order to
960minimize changes to the header files, the [FreeBSD] layout has been maintained.
961The generic C library definitions can be found in `include/stdlib` with more
962system and machine specific declarations in `include/stdlib/sys` and
963`include/stdlib/machine`.
964
965The local C library implementations can be found in `lib/stdlib`. In order to
966extend the C library these files may need to be modified. It is recommended to
967use a release version of [FreeBSD] as a starting point.
968
969The C library header files in the [FreeBSD] source tree are located in the
970`include` and `sys/sys` directories. [FreeBSD] machine specific definitions
971can be found in the `sys/<machine-type>` directories. These files define things
972like 'the size of a pointer' and 'the range of an integer'. Since an AArch64
973port for [FreeBSD] does not yet exist, the machine specific definitions are
974based on existing machine types with similar properties (for example SPARC64).
975
976Where possible, C library function implementations were taken from [FreeBSD]
977as found in the `lib/libc` directory.
978
979A copy of the [FreeBSD] sources can be downloaded with `git`.
980
981 git clone git://github.com/freebsd/freebsd.git -b origin/release/9.2.0
982
983
Achin Gupta4f6ad662013-10-25 09:08:21 +0100984- - - - - - - - - - - - - - - - - - - - - - - - - -
985
Dan Handleyab2d31e2013-12-02 19:25:12 +0000986_Copyright (c) 2013, ARM Limited and Contributors. All rights reserved._
Achin Gupta4f6ad662013-10-25 09:08:21 +0100987
988
989[User Guide]: user-guide.md
Harry Liebela960f282013-12-12 16:03:44 +0000990[FreeBSD]: http://www.freebsd.org
Achin Gupta4f6ad662013-10-25 09:08:21 +0100991
992[../plat/common/aarch64/platform_helpers.S]: ../plat/common/aarch64/platform_helpers.S
993[../plat/fvp/platform.h]: ../plat/fvp/platform.h
994[../plat/fvp/aarch64/fvp_common.c]: ../plat/fvp/aarch64/fvp_common.c
995[../plat/fvp/fvp_pm.c]: ../plat/fvp/fvp_pm.c
996[../include/runtime_svc.h]: ../include/runtime_svc.h