1ARM Trusted Firmware Porting Guide 2================================== 3 4Contents 5-------- 6 71. [Introduction](#1--introduction) 82. [Common Modifications](#2--common-modifications) 9 * [Common mandatory modifications](#21-common-mandatory-modifications) 10 * [Handling reset](#22-handling-reset) 11 * [Common optional modifications](#23-common-optional-modifications) 123. [Boot Loader stage specific modifications](#3--modifications-specific-to-a-boot-loader-stage) 13 * [Boot Loader stage 1 (BL1)](#31-boot-loader-stage-1-bl1) 14 * [Boot Loader stage 2 (BL2)](#32-boot-loader-stage-2-bl2) 15 * [Boot Loader stage 3-1 (BL3-1)](#32-boot-loader-stage-3-1-bl3-1) 16 * [PSCI implementation (in BL3-1)](#33-power-state-coordination-interface-in-bl3-1) 17 * [Interrupt Management framework (in BL3-1)](#34--interrupt-management-framework-in-bl3-1) 18 * [Crash Reporting mechanism (in BL3-1)](#35--crash-reporting-mechanism-in-bl3-1) 194. [Build flags](#4--build-flags) 205. [C Library](#5--c-library) 216. [Storage abstraction layer](#6--storage-abstraction-layer) 22 23- - - - - - - - - - - - - - - - - - 24 251. Introduction 26---------------- 27 28Porting the ARM Trusted Firmware to a new platform involves making some 29mandatory and optional modifications for both the cold and warm boot paths. 30Modifications consist of: 31 32* Implementing a platform-specific function or variable, 33* Setting up the execution context in a certain way, or 34* Defining certain constants (for example #defines). 35 36The platform-specific functions and variables are all declared in 37[include/plat/common/platform.h]. The firmware provides a default implementation 38of variables and functions to fulfill the optional requirements. These 39implementations are all weakly defined; they are provided to ease the porting 40effort. Each platform port can override them with its own implementation if the 41default implementation is inadequate. 42 43Some modifications are common to all Boot Loader (BL) stages. Section 2 44discusses these in detail. The subsequent sections discuss the remaining 45modifications for each BL stage in detail. 46 47This document should be read in conjunction with the ARM Trusted Firmware 48[User Guide]. 49 50 512. Common modifications 52------------------------ 53 54This section covers the modifications that should be made by the platform for 55each BL stage to correctly port the firmware stack. They are categorized as 56either mandatory or optional. 57 58 592.1 Common mandatory modifications 60---------------------------------- 61A platform port must enable the Memory Management Unit (MMU) with identity 62mapped page tables, and enable both the instruction and data caches for each BL 63stage. In the ARM FVP port, each BL stage configures the MMU in its platform- 64specific architecture setup function, for example `blX_plat_arch_setup()`. 65 66If the build option `USE_COHERENT_MEM` is enabled, each platform must allocate a 67block of identity mapped secure memory with Device-nGnRE attributes aligned to 68page boundary (4K) for each BL stage. This memory is identified by the section 69name `tzfw_coherent_mem` so that its possible for the firmware to place 70variables in it using the following C code directive: 71 72 __attribute__ ((section("tzfw_coherent_mem"))) 73 74Or alternatively the following assembler code directive: 75 76 .section tzfw_coherent_mem 77 78The `tzfw_coherent_mem` section is used to allocate any data structures that are 79accessed both when a CPU is executing with its MMU and caches enabled, and when 80it's running with its MMU and caches disabled. Examples are given below. 81 82The following variables, functions and constants must be defined by the platform 83for the firmware to work correctly. 84 85 86### File : platform_def.h [mandatory] 87 88Each platform must ensure that a header file of this name is in the system 89include path with the following constants defined. This may require updating the 90list of `PLAT_INCLUDES` in the `platform.mk` file. In the ARM FVP port, this 91file is found in [plat/fvp/include/platform_def.h]. 92 93* **#define : PLATFORM_LINKER_FORMAT** 94 95 Defines the linker format used by the platform, for example 96 `elf64-littleaarch64` used by the FVP. 97 98* **#define : PLATFORM_LINKER_ARCH** 99 100 Defines the processor architecture for the linker by the platform, for 101 example `aarch64` used by the FVP. 102 103* **#define : PLATFORM_STACK_SIZE** 104 105 Defines the normal stack memory available to each CPU. This constant is used 106 by [plat/common/aarch64/platform_mp_stack.S] and 107 [plat/common/aarch64/platform_up_stack.S]. 108 109* **#define : FIRMWARE_WELCOME_STR** 110 111 Defines the character string printed by BL1 upon entry into the `bl1_main()` 112 function. 113 114* **#define : BL2_IMAGE_NAME** 115 116 Name of the BL2 binary image on the host file-system. This name is used by 117 BL1 to load BL2 into secure memory from non-volatile storage. 118 119* **#define : BL31_IMAGE_NAME** 120 121 Name of the BL3-1 binary image on the host file-system. This name is used by 122 BL2 to load BL3-1 into secure memory from platform storage. 123 124* **#define : BL33_IMAGE_NAME** 125 126 Name of the BL3-3 binary image on the host file-system. This name is used by 127 BL2 to load BL3-3 into non-secure memory from platform storage. 128 129* **#define : BL2_CERT_NAME** 130 131 Name of the BL2 content certificate on the host file-system (mandatory when 132 Trusted Board Boot is enabled). 133 134* **#define : TRUSTED_KEY_CERT_NAME** 135 136 Name of the Trusted Key certificate on the host file-system (mandatory when 137 Trusted Board Boot is enabled). 138 139* **#define : BL31_KEY_CERT_NAME** 140 141 Name of the BL3-1 Key certificate on the host file-system (mandatory when 142 Trusted Board Boot is enabled). 143 144* **#define : BL31_CERT_NAME** 145 146 Name of the BL3-1 Content certificate on the host file-system (mandatory 147 when Trusted Board Boot is enabled). 148 149* **#define : BL33_KEY_CERT_NAME** 150 151 Name of the BL3-3 Key certificate on the host file-system (mandatory when 152 Trusted Board Boot is enabled). 153 154* **#define : BL33_CERT_NAME** 155 156 Name of the BL3-3 Content certificate on the host file-system (mandatory 157 when Trusted Board Boot is enabled). 158 159* **#define : PLATFORM_CACHE_LINE_SIZE** 160 161 Defines the size (in bytes) of the largest cache line across all the cache 162 levels in the platform. 163 164* **#define : PLATFORM_CLUSTER_COUNT** 165 166 Defines the total number of clusters implemented by the platform in the 167 system. 168 169* **#define : PLATFORM_CORE_COUNT** 170 171 Defines the total number of CPUs implemented by the platform across all 172 clusters in the system. 173 174* **#define : PLATFORM_MAX_CPUS_PER_CLUSTER** 175 176 Defines the maximum number of CPUs that can be implemented within a cluster 177 on the platform. 178 179* **#define : PLATFORM_NUM_AFFS** 180 181 Defines the total number of nodes in the affinity heirarchy at all affinity 182 levels used by the platform. 183 184* **#define : BL1_RO_BASE** 185 186 Defines the base address in secure ROM where BL1 originally lives. Must be 187 aligned on a page-size boundary. 188 189* **#define : BL1_RO_LIMIT** 190 191 Defines the maximum address in secure ROM that BL1's actual content (i.e. 192 excluding any data section allocated at runtime) can occupy. 193 194* **#define : BL1_RW_BASE** 195 196 Defines the base address in secure RAM where BL1's read-write data will live 197 at runtime. Must be aligned on a page-size boundary. 198 199* **#define : BL1_RW_LIMIT** 200 201 Defines the maximum address in secure RAM that BL1's read-write data can 202 occupy at runtime. 203 204* **#define : BL2_BASE** 205 206 Defines the base address in secure RAM where BL1 loads the BL2 binary image. 207 Must be aligned on a page-size boundary. 208 209* **#define : BL2_LIMIT** 210 211 Defines the maximum address in secure RAM that the BL2 image can occupy. 212 213* **#define : BL31_BASE** 214 215 Defines the base address in secure RAM where BL2 loads the BL3-1 binary 216 image. Must be aligned on a page-size boundary. 217 218* **#define : BL31_LIMIT** 219 220 Defines the maximum address in secure RAM that the BL3-1 image can occupy. 221 222* **#define : NS_IMAGE_OFFSET** 223 224 Defines the base address in non-secure DRAM where BL2 loads the BL3-3 binary 225 image. Must be aligned on a page-size boundary. 226 227If a BL3-0 image is supported by the platform, the following constants must 228also be defined: 229 230* **#define : BL30_IMAGE_NAME** 231 232 Name of the BL3-0 binary image on the host file-system. This name is used by 233 BL2 to load BL3-0 into secure memory from platform storage before being 234 transfered to the SCP. 235 236* **#define : BL30_KEY_CERT_NAME** 237 238 Name of the BL3-0 Key certificate on the host file-system (mandatory when 239 Trusted Board Boot is enabled). 240 241* **#define : BL30_CERT_NAME** 242 243 Name of the BL3-0 Content certificate on the host file-system (mandatory 244 when Trusted Board Boot is enabled). 245 246If a BL3-2 image is supported by the platform, the following constants must 247also be defined: 248 249* **#define : BL32_IMAGE_NAME** 250 251 Name of the BL3-2 binary image on the host file-system. This name is used by 252 BL2 to load BL3-2 into secure memory from platform storage. 253 254* **#define : BL32_KEY_CERT_NAME** 255 256 Name of the BL3-2 Key certificate on the host file-system (mandatory when 257 Trusted Board Boot is enabled). 258 259* **#define : BL32_CERT_NAME** 260 261 Name of the BL3-2 Content certificate on the host file-system (mandatory 262 when Trusted Board Boot is enabled). 263 264* **#define : BL32_BASE** 265 266 Defines the base address in secure memory where BL2 loads the BL3-2 binary 267 image. Must be aligned on a page-size boundary. 268 269* **#define : BL32_LIMIT** 270 271 Defines the maximum address that the BL3-2 image can occupy. 272 273If the Test Secure-EL1 Payload (TSP) instantiation of BL3-2 is supported by the 274platform, the following constants must also be defined: 275 276* **#define : TSP_SEC_MEM_BASE** 277 278 Defines the base address of the secure memory used by the TSP image on the 279 platform. This must be at the same address or below `BL32_BASE`. 280 281* **#define : TSP_SEC_MEM_SIZE** 282 283 Defines the size of the secure memory used by the BL3-2 image on the 284 platform. `TSP_SEC_MEM_BASE` and `TSP_SEC_MEM_SIZE` must fully accomodate 285 the memory required by the BL3-2 image, defined by `BL32_BASE` and 286 `BL32_LIMIT`. 287 288* **#define : TSP_IRQ_SEC_PHY_TIMER** 289 290 Defines the ID of the secure physical generic timer interrupt used by the 291 TSP's interrupt handling code. 292 293If the platform port uses the IO storage framework, the following constants 294must also be defined: 295 296* **#define : MAX_IO_DEVICES** 297 298 Defines the maximum number of registered IO devices. Attempting to register 299 more devices than this value using `io_register_device()` will fail with 300 IO_RESOURCES_EXHAUSTED. 301 302* **#define : MAX_IO_HANDLES** 303 304 Defines the maximum number of open IO handles. Attempting to open more IO 305 entities than this value using `io_open()` will fail with 306 IO_RESOURCES_EXHAUSTED. 307 308If the platform needs to allocate data within the per-cpu data framework in 309BL3-1, it should define the following macro. Currently this is only required if 310the platform decides not to use the coherent memory section by undefining the 311USE_COHERENT_MEM build flag. In this case, the framework allocates the required 312memory within the the per-cpu data to minimize wastage. 313 314* **#define : PLAT_PCPU_DATA_SIZE** 315 316 Defines the memory (in bytes) to be reserved within the per-cpu data 317 structure for use by the platform layer. 318 319The following constants are optional. They should be defined when the platform 320memory layout implies some image overlaying like on FVP. 321 322* **#define : BL31_PROGBITS_LIMIT** 323 324 Defines the maximum address in secure RAM that the BL3-1's progbits sections 325 can occupy. 326 327* **#define : TSP_PROGBITS_LIMIT** 328 329 Defines the maximum address that the TSP's progbits sections can occupy. 330 331### File : plat_macros.S [mandatory] 332 333Each platform must ensure a file of this name is in the system include path with 334the following macro defined. In the ARM FVP port, this file is found in 335[plat/fvp/include/plat_macros.S]. 336 337* **Macro : plat_print_gic_regs** 338 339 This macro allows the crash reporting routine to print GIC registers 340 in case of an unhandled exception in BL3-1. This aids in debugging and 341 this macro can be defined to be empty in case GIC register reporting is 342 not desired. 343 344* **Macro : plat_print_interconnect_regs** 345 346 This macro allows the crash reporting routine to print interconnect registers 347 in case of an unhandled exception in BL3-1. This aids in debugging and 348 this macro can be defined to be empty in case interconnect register reporting 349 is not desired. In the ARM FVP port, the CCI snoop control registers are 350 reported. 351 352### Other mandatory modifications 353 354The following mandatory modifications may be implemented in any file 355the implementer chooses. In the ARM FVP port, they are implemented in 356[plat/fvp/aarch64/plat_common.c]. 357 358* **Function : uint64_t plat_get_syscnt_freq(void)** 359 360 This function is used by the architecture setup code to retrieve the 361 counter frequency for the CPU's generic timer. This value will be 362 programmed into the `CNTFRQ_EL0` register. 363 In the ARM FVP port, it returns the base frequency of the system counter, 364 which is retrieved from the first entry in the frequency modes table. 365 366 3672.2 Handling Reset 368------------------ 369 370BL1 by default implements the reset vector where execution starts from a cold 371or warm boot. BL3-1 can be optionally set as a reset vector using the 372RESET_TO_BL31 make variable. 373 374For each CPU, the reset vector code is responsible for the following tasks: 375 3761. Distinguishing between a cold boot and a warm boot. 377 3782. In the case of a cold boot and the CPU being a secondary CPU, ensuring that 379 the CPU is placed in a platform-specific state until the primary CPU 380 performs the necessary steps to remove it from this state. 381 3823. In the case of a warm boot, ensuring that the CPU jumps to a platform- 383 specific address in the BL3-1 image in the same processor mode as it was 384 when released from reset. 385 386The following functions need to be implemented by the platform port to enable 387reset vector code to perform the above tasks. 388 389 390### Function : platform_get_entrypoint() [mandatory] 391 392 Argument : unsigned long 393 Return : unsigned int 394 395This function is called with the `SCTLR.M` and `SCTLR.C` bits disabled. The CPU 396is identified by its `MPIDR`, which is passed as the argument. The function is 397responsible for distinguishing between a warm and cold reset using platform- 398specific means. If it's a warm reset then it returns the entrypoint into the 399BL3-1 image that the CPU must jump to. If it's a cold reset then this function 400must return zero. 401 402This function is also responsible for implementing a platform-specific mechanism 403to handle the condition where the CPU has been warm reset but there is no 404entrypoint to jump to. 405 406This function does not follow the Procedure Call Standard used by the 407Application Binary Interface for the ARM 64-bit architecture. The caller should 408not assume that callee saved registers are preserved across a call to this 409function. 410 411This function fulfills requirement 1 and 3 listed above. 412 413 414### Function : plat_secondary_cold_boot_setup() [mandatory] 415 416 Argument : void 417 Return : void 418 419This function is called with the MMU and data caches disabled. It is responsible 420for placing the executing secondary CPU in a platform-specific state until the 421primary CPU performs the necessary actions to bring it out of that state and 422allow entry into the OS. 423 424In the ARM FVP port, each secondary CPU powers itself off. The primary CPU is 425responsible for powering up the secondary CPU when normal world software 426requires them. 427 428This function fulfills requirement 2 above. 429 430 431### Function : platform_is_primary_cpu() [mandatory] 432 433 Argument : unsigned long 434 Return : unsigned int 435 436This function identifies a CPU by its `MPIDR`, which is passed as the argument, 437to determine whether this CPU is the primary CPU or a secondary CPU. A return 438value of zero indicates that the CPU is not the primary CPU, while a non-zero 439return value indicates that the CPU is the primary CPU. 440 441 442### Function : platform_mem_init() [mandatory] 443 444 Argument : void 445 Return : void 446 447This function is called before any access to data is made by the firmware, in 448order to carry out any essential memory initialization. 449 450The ARM FVP port uses this function to initialize the mailbox memory used for 451providing the warm-boot entry-point addresses. 452 453 454### Function: plat_match_rotpk() 455 456 Argument : const unsigned char *, unsigned int 457 Return : int 458 459This function is mandatory when Trusted Board Boot is enabled. It receives a 460pointer to a buffer containing a signing key and its size as parameters and 461returns 0 (success) if that key matches the ROT (Root Of Trust) key stored in 462the platform. Any other return value means a mismatch. 463 464 465 4662.3 Common optional modifications 467--------------------------------- 468 469The following are helper functions implemented by the firmware that perform 470common platform-specific tasks. A platform may choose to override these 471definitions. 472 473 474### Function : platform_get_core_pos() 475 476 Argument : unsigned long 477 Return : int 478 479A platform may need to convert the `MPIDR` of a CPU to an absolute number, which 480can be used as a CPU-specific linear index into blocks of memory (for example 481while allocating per-CPU stacks). This routine contains a simple mechanism 482to perform this conversion, using the assumption that each cluster contains a 483maximum of 4 CPUs: 484 485 linear index = cpu_id + (cluster_id * 4) 486 487 cpu_id = 8-bit value in MPIDR at affinity level 0 488 cluster_id = 8-bit value in MPIDR at affinity level 1 489 490 491### Function : platform_set_stack() 492 493 Argument : unsigned long 494 Return : void 495 496This function sets the current stack pointer to the normal memory stack that 497has been allocated for the CPU specificed by MPIDR. For BL images that only 498require a stack for the primary CPU the parameter is ignored. The size of 499the stack allocated to each CPU is specified by the platform defined constant 500`PLATFORM_STACK_SIZE`. 501 502Common implementations of this function for the UP and MP BL images are 503provided in [plat/common/aarch64/platform_up_stack.S] and 504[plat/common/aarch64/platform_mp_stack.S] 505 506 507### Function : platform_get_stack() 508 509 Argument : unsigned long 510 Return : unsigned long 511 512This function returns the base address of the normal memory stack that 513has been allocated for the CPU specificed by MPIDR. For BL images that only 514require a stack for the primary CPU the parameter is ignored. The size of 515the stack allocated to each CPU is specified by the platform defined constant 516`PLATFORM_STACK_SIZE`. 517 518Common implementations of this function for the UP and MP BL images are 519provided in [plat/common/aarch64/platform_up_stack.S] and 520[plat/common/aarch64/platform_mp_stack.S] 521 522 523### Function : plat_report_exception() 524 525 Argument : unsigned int 526 Return : void 527 528A platform may need to report various information about its status when an 529exception is taken, for example the current exception level, the CPU security 530state (secure/non-secure), the exception type, and so on. This function is 531called in the following circumstances: 532 533* In BL1, whenever an exception is taken. 534* In BL2, whenever an exception is taken. 535 536The default implementation doesn't do anything, to avoid making assumptions 537about the way the platform displays its status information. 538 539This function receives the exception type as its argument. Possible values for 540exceptions types are listed in the [include/runtime_svc.h] header file. Note 541that these constants are not related to any architectural exception code; they 542are just an ARM Trusted Firmware convention. 543 544 545### Function : plat_reset_handler() 546 547 Argument : void 548 Return : void 549 550A platform may need to do additional initialization after reset. This function 551allows the platform to do the platform specific intializations. Platform 552specific errata workarounds could also be implemented here. The api should 553preserve the values of callee saved registers x19 to x29. 554 555The default implementation doesn't do anything. If a platform needs to override 556the default implementation, refer to the [Firmware Design Guide] for general 557guidelines regarding placement of code in a reset handler. 558 559### Function : plat_disable_acp() 560 561 Argument : void 562 Return : void 563 564This api allows a platform to disable the Accelerator Coherency Port (if 565present) during a cluster power down sequence. The default weak implementation 566doesn't do anything. Since this api is called during the power down sequence, 567it has restrictions for stack usage and it can use the registers x0 - x17 as 568scratch registers. It should preserve the value in x18 register as it is used 569by the caller to store the return address. 570 571 5723. Modifications specific to a Boot Loader stage 573------------------------------------------------- 574 5753.1 Boot Loader Stage 1 (BL1) 576----------------------------- 577 578BL1 implements the reset vector where execution starts from after a cold or 579warm boot. For each CPU, BL1 is responsible for the following tasks: 580 5811. Handling the reset as described in section 2.2 582 5832. In the case of a cold boot and the CPU being the primary CPU, ensuring that 584 only this CPU executes the remaining BL1 code, including loading and passing 585 control to the BL2 stage. 586 5873. Loading the BL2 image from non-volatile storage into secure memory at the 588 address specified by the platform defined constant `BL2_BASE`. 589 5904. Populating a `meminfo` structure with the following information in memory, 591 accessible by BL2 immediately upon entry. 592 593 meminfo.total_base = Base address of secure RAM visible to BL2 594 meminfo.total_size = Size of secure RAM visible to BL2 595 meminfo.free_base = Base address of secure RAM available for 596 allocation to BL2 597 meminfo.free_size = Size of secure RAM available for allocation to BL2 598 599 BL1 places this `meminfo` structure at the beginning of the free memory 600 available for its use. Since BL1 cannot allocate memory dynamically at the 601 moment, its free memory will be available for BL2's use as-is. However, this 602 means that BL2 must read the `meminfo` structure before it starts using its 603 free memory (this is discussed in Section 3.2). 604 605 In future releases of the ARM Trusted Firmware it will be possible for 606 the platform to decide where it wants to place the `meminfo` structure for 607 BL2. 608 609 BL1 implements the `bl1_init_bl2_mem_layout()` function to populate the 610 BL2 `meminfo` structure. The platform may override this implementation, for 611 example if the platform wants to restrict the amount of memory visible to 612 BL2. Details of how to do this are given below. 613 614The following functions need to be implemented by the platform port to enable 615BL1 to perform the above tasks. 616 617 618### Function : bl1_plat_arch_setup() [mandatory] 619 620 Argument : void 621 Return : void 622 623This function performs any platform-specific and architectural setup that the 624platform requires. Platform-specific setup might include configuration of 625memory controllers, configuration of the interconnect to allow the cluster 626to service cache snoop requests from another cluster, and so on. 627 628In the ARM FVP port, this function enables CCI snoops into the cluster that the 629primary CPU is part of. It also enables the MMU. 630 631This function helps fulfill requirement 2 above. 632 633 634### Function : bl1_platform_setup() [mandatory] 635 636 Argument : void 637 Return : void 638 639This function executes with the MMU and data caches enabled. It is responsible 640for performing any remaining platform-specific setup that can occur after the 641MMU and data cache have been enabled. 642 643This function is also responsible for initializing the storage abstraction layer 644which is used to load further bootloader images. 645 646This function helps fulfill requirement 3 above. 647 648 649### Function : bl1_plat_sec_mem_layout() [mandatory] 650 651 Argument : void 652 Return : meminfo * 653 654This function should only be called on the cold boot path. It executes with the 655MMU and data caches enabled. The pointer returned by this function must point to 656a `meminfo` structure containing the extents and availability of secure RAM for 657the BL1 stage. 658 659 meminfo.total_base = Base address of secure RAM visible to BL1 660 meminfo.total_size = Size of secure RAM visible to BL1 661 meminfo.free_base = Base address of secure RAM available for allocation 662 to BL1 663 meminfo.free_size = Size of secure RAM available for allocation to BL1 664 665This information is used by BL1 to load the BL2 image in secure RAM. BL1 also 666populates a similar structure to tell BL2 the extents of memory available for 667its own use. 668 669This function helps fulfill requirement 3 above. 670 671 672### Function : bl1_init_bl2_mem_layout() [optional] 673 674 Argument : meminfo *, meminfo *, unsigned int, unsigned long 675 Return : void 676 677BL1 needs to tell the next stage the amount of secure RAM available 678for it to use. This information is populated in a `meminfo` 679structure. 680 681Depending upon where BL2 has been loaded in secure RAM (determined by 682`BL2_BASE`), BL1 calculates the amount of free memory available for BL2 to use. 683BL1 also ensures that its data sections resident in secure RAM are not visible 684to BL2. An illustration of how this is done in the ARM FVP port is given in the 685[User Guide], in the Section "Memory layout on Base FVP". 686 687 688### Function : bl1_plat_set_bl2_ep_info() [mandatory] 689 690 Argument : image_info *, entry_point_info * 691 Return : void 692 693This function is called after loading BL2 image and it can be used to overwrite 694the entry point set by loader and also set the security state and SPSR which 695represents the entry point system state for BL2. 696 697On FVP, we are setting the security state and the SPSR for the BL2 entrypoint 698 699 7003.2 Boot Loader Stage 2 (BL2) 701----------------------------- 702 703The BL2 stage is executed only by the primary CPU, which is determined in BL1 704using the `platform_is_primary_cpu()` function. BL1 passed control to BL2 at 705`BL2_BASE`. BL2 executes in Secure EL1 and is responsible for: 706 7071. (Optional) Loading the BL3-0 binary image (if present) from platform 708 provided non-volatile storage. To load the BL3-0 image, BL2 makes use of 709 the `meminfo` returned by the `bl2_plat_get_bl30_meminfo()` function. 710 The platform also defines the address in memory where BL3-0 is loaded 711 through the optional constant `BL30_BASE`. BL2 uses this information 712 to determine if there is enough memory to load the BL3-0 image. 713 Subsequent handling of the BL3-0 image is platform-specific and is 714 implemented in the `bl2_plat_handle_bl30()` function. 715 If `BL30_BASE` is not defined then this step is not performed. 716 7172. Loading the BL3-1 binary image into secure RAM from non-volatile storage. To 718 load the BL3-1 image, BL2 makes use of the `meminfo` structure passed to it 719 by BL1. This structure allows BL2 to calculate how much secure RAM is 720 available for its use. The platform also defines the address in secure RAM 721 where BL3-1 is loaded through the constant `BL31_BASE`. BL2 uses this 722 information to determine if there is enough memory to load the BL3-1 image. 723 7243. (Optional) Loading the BL3-2 binary image (if present) from platform 725 provided non-volatile storage. To load the BL3-2 image, BL2 makes use of 726 the `meminfo` returned by the `bl2_plat_get_bl32_meminfo()` function. 727 The platform also defines the address in memory where BL3-2 is loaded 728 through the optional constant `BL32_BASE`. BL2 uses this information 729 to determine if there is enough memory to load the BL3-2 image. 730 If `BL32_BASE` is not defined then this and the next step is not performed. 731 7324. (Optional) Arranging to pass control to the BL3-2 image (if present) that 733 has been pre-loaded at `BL32_BASE`. BL2 populates an `entry_point_info` 734 structure in memory provided by the platform with information about how 735 BL3-1 should pass control to the BL3-2 image. 736 7375. Loading the normal world BL3-3 binary image into non-secure DRAM from 738 platform storage and arranging for BL3-1 to pass control to this image. This 739 address is determined using the `plat_get_ns_image_entrypoint()` function 740 described below. 741 7426. BL2 populates an `entry_point_info` structure in memory provided by the 743 platform with information about how BL3-1 should pass control to the 744 other BL images. 745 746The following functions must be implemented by the platform port to enable BL2 747to perform the above tasks. 748 749 750### Function : bl2_early_platform_setup() [mandatory] 751 752 Argument : meminfo * 753 Return : void 754 755This function executes with the MMU and data caches disabled. It is only called 756by the primary CPU. The arguments to this function is the address of the 757`meminfo` structure populated by BL1. 758 759The platform must copy the contents of the `meminfo` structure into a private 760variable as the original memory may be subsequently overwritten by BL2. The 761copied structure is made available to all BL2 code through the 762`bl2_plat_sec_mem_layout()` function. 763 764 765### Function : bl2_plat_arch_setup() [mandatory] 766 767 Argument : void 768 Return : void 769 770This function executes with the MMU and data caches disabled. It is only called 771by the primary CPU. 772 773The purpose of this function is to perform any architectural initialization 774that varies across platforms, for example enabling the MMU (since the memory 775map differs across platforms). 776 777 778### Function : bl2_platform_setup() [mandatory] 779 780 Argument : void 781 Return : void 782 783This function may execute with the MMU and data caches enabled if the platform 784port does the necessary initialization in `bl2_plat_arch_setup()`. It is only 785called by the primary CPU. 786 787The purpose of this function is to perform any platform initialization 788specific to BL2. Platform security components are configured if required. 789For the Base FVP the TZC-400 TrustZone controller is configured to only 790grant non-secure access to DRAM. This avoids aliasing between secure and 791non-secure accesses in the TLB and cache - secure execution states can use 792the NS attributes in the MMU translation tables to access the DRAM. 793 794This function is also responsible for initializing the storage abstraction layer 795which is used to load further bootloader images. 796 797 798### Function : bl2_plat_sec_mem_layout() [mandatory] 799 800 Argument : void 801 Return : meminfo * 802 803This function should only be called on the cold boot path. It may execute with 804the MMU and data caches enabled if the platform port does the necessary 805initialization in `bl2_plat_arch_setup()`. It is only called by the primary CPU. 806 807The purpose of this function is to return a pointer to a `meminfo` structure 808populated with the extents of secure RAM available for BL2 to use. See 809`bl2_early_platform_setup()` above. 810 811 812### Function : bl2_plat_get_bl30_meminfo() [mandatory] 813 814 Argument : meminfo * 815 Return : void 816 817This function is used to get the memory limits where BL2 can load the 818BL3-0 image. The meminfo provided by this is used by load_image() to 819validate whether the BL3-0 image can be loaded within the given 820memory from the given base. 821 822 823### Function : bl2_plat_handle_bl30() [mandatory] 824 825 Argument : image_info * 826 Return : int 827 828This function is called after loading BL3-0 image and it is used to perform any 829platform-specific actions required to handle the SCP firmware. Typically it 830transfers the image into SCP memory using a platform-specific protocol and waits 831until SCP executes it and signals to the Application Processor (AP) for BL2 832execution to continue. 833 834This function returns 0 on success, a negative error code otherwise. 835 836 837### Function : bl2_plat_get_bl31_params() [mandatory] 838 839 Argument : void 840 Return : bl31_params * 841 842BL2 platform code needs to return a pointer to a `bl31_params` structure it 843will use for passing information to BL3-1. The `bl31_params` structure carries 844the following information. 845 - Header describing the version information for interpreting the bl31_param 846 structure 847 - Information about executing the BL3-3 image in the `bl33_ep_info` field 848 - Information about executing the BL3-2 image in the `bl32_ep_info` field 849 - Information about the type and extents of BL3-1 image in the 850 `bl31_image_info` field 851 - Information about the type and extents of BL3-2 image in the 852 `bl32_image_info` field 853 - Information about the type and extents of BL3-3 image in the 854 `bl33_image_info` field 855 856The memory pointed by this structure and its sub-structures should be 857accessible from BL3-1 initialisation code. BL3-1 might choose to copy the 858necessary content, or maintain the structures until BL3-3 is initialised. 859 860 861### Funtion : bl2_plat_get_bl31_ep_info() [mandatory] 862 863 Argument : void 864 Return : entry_point_info * 865 866BL2 platform code returns a pointer which is used to populate the entry point 867information for BL3-1 entry point. The location pointed by it should be 868accessible from BL1 while processing the synchronous exception to run to BL3-1. 869 870On FVP this is allocated inside an bl2_to_bl31_params_mem structure which 871is allocated at an address pointed by PARAMS_BASE. 872 873 874### Function : bl2_plat_set_bl31_ep_info() [mandatory] 875 876 Argument : image_info *, entry_point_info * 877 Return : void 878 879This function is called after loading BL3-1 image and it can be used to 880overwrite the entry point set by loader and also set the security state 881and SPSR which represents the entry point system state for BL3-1. 882 883On FVP, we are setting the security state and the SPSR for the BL3-1 884entrypoint. 885 886### Function : bl2_plat_set_bl32_ep_info() [mandatory] 887 888 Argument : image_info *, entry_point_info * 889 Return : void 890 891This function is called after loading BL3-2 image and it can be used to 892overwrite the entry point set by loader and also set the security state 893and SPSR which represents the entry point system state for BL3-2. 894 895On FVP, we are setting the security state and the SPSR for the BL3-2 896entrypoint 897 898### Function : bl2_plat_set_bl33_ep_info() [mandatory] 899 900 Argument : image_info *, entry_point_info * 901 Return : void 902 903This function is called after loading BL3-3 image and it can be used to 904overwrite the entry point set by loader and also set the security state 905and SPSR which represents the entry point system state for BL3-3. 906 907On FVP, we are setting the security state and the SPSR for the BL3-3 908entrypoint 909 910### Function : bl2_plat_get_bl32_meminfo() [mandatory] 911 912 Argument : meminfo * 913 Return : void 914 915This function is used to get the memory limits where BL2 can load the 916BL3-2 image. The meminfo provided by this is used by load_image() to 917validate whether the BL3-2 image can be loaded with in the given 918memory from the given base. 919 920### Function : bl2_plat_get_bl33_meminfo() [mandatory] 921 922 Argument : meminfo * 923 Return : void 924 925This function is used to get the memory limits where BL2 can load the 926BL3-3 image. The meminfo provided by this is used by load_image() to 927validate whether the BL3-3 image can be loaded with in the given 928memory from the given base. 929 930### Function : bl2_plat_flush_bl31_params() [mandatory] 931 932 Argument : void 933 Return : void 934 935Once BL2 has populated all the structures that needs to be read by BL1 936and BL3-1 including the bl31_params structures and its sub-structures, 937the bl31_ep_info structure and any platform specific data. It flushes 938all these data to the main memory so that it is available when we jump to 939later Bootloader stages with MMU off 940 941### Function : plat_get_ns_image_entrypoint() [mandatory] 942 943 Argument : void 944 Return : unsigned long 945 946As previously described, BL2 is responsible for arranging for control to be 947passed to a normal world BL image through BL3-1. This function returns the 948entrypoint of that image, which BL3-1 uses to jump to it. 949 950BL2 is responsible for loading the normal world BL3-3 image (e.g. UEFI). 951 952 9533.2 Boot Loader Stage 3-1 (BL3-1) 954--------------------------------- 955 956During cold boot, the BL3-1 stage is executed only by the primary CPU. This is 957determined in BL1 using the `platform_is_primary_cpu()` function. BL1 passes 958control to BL3-1 at `BL31_BASE`. During warm boot, BL3-1 is executed by all 959CPUs. BL3-1 executes at EL3 and is responsible for: 960 9611. Re-initializing all architectural and platform state. Although BL1 performs 962 some of this initialization, BL3-1 remains resident in EL3 and must ensure 963 that EL3 architectural and platform state is completely initialized. It 964 should make no assumptions about the system state when it receives control. 965 9662. Passing control to a normal world BL image, pre-loaded at a platform- 967 specific address by BL2. BL3-1 uses the `entry_point_info` structure that BL2 968 populated in memory to do this. 969 9703. Providing runtime firmware services. Currently, BL3-1 only implements a 971 subset of the Power State Coordination Interface (PSCI) API as a runtime 972 service. See Section 3.3 below for details of porting the PSCI 973 implementation. 974 9754. Optionally passing control to the BL3-2 image, pre-loaded at a platform- 976 specific address by BL2. BL3-1 exports a set of apis that allow runtime 977 services to specify the security state in which the next image should be 978 executed and run the corresponding image. BL3-1 uses the `entry_point_info` 979 structure populated by BL2 to do this. 980 981If BL3-1 is a reset vector, It also needs to handle the reset as specified in 982section 2.2 before the tasks described above. 983 984The following functions must be implemented by the platform port to enable BL3-1 985to perform the above tasks. 986 987 988### Function : bl31_early_platform_setup() [mandatory] 989 990 Argument : bl31_params *, void * 991 Return : void 992 993This function executes with the MMU and data caches disabled. It is only called 994by the primary CPU. The arguments to this function are: 995 996* The address of the `bl31_params` structure populated by BL2. 997* An opaque pointer that the platform may use as needed. 998 999The platform can copy the contents of the `bl31_params` structure and its 1000sub-structures into private variables if the original memory may be 1001subsequently overwritten by BL3-1 and similarly the `void *` pointing 1002to the platform data also needs to be saved. 1003 1004On the ARM FVP port, BL2 passes a pointer to a `bl31_params` structure populated 1005in the secure DRAM at address `0x6000000` in the bl31_params * argument and it 1006does not use opaque pointer mentioned earlier. BL3-1 does not copy this 1007information to internal data structures as it guarantees that the secure 1008DRAM memory will not be overwritten. It maintains an internal reference to this 1009information in the `bl2_to_bl31_params` variable. 1010 1011### Function : bl31_plat_arch_setup() [mandatory] 1012 1013 Argument : void 1014 Return : void 1015 1016This function executes with the MMU and data caches disabled. It is only called 1017by the primary CPU. 1018 1019The purpose of this function is to perform any architectural initialization 1020that varies across platforms, for example enabling the MMU (since the memory 1021map differs across platforms). 1022 1023 1024### Function : bl31_platform_setup() [mandatory] 1025 1026 Argument : void 1027 Return : void 1028 1029This function may execute with the MMU and data caches enabled if the platform 1030port does the necessary initialization in `bl31_plat_arch_setup()`. It is only 1031called by the primary CPU. 1032 1033The purpose of this function is to complete platform initialization so that both 1034BL3-1 runtime services and normal world software can function correctly. 1035 1036The ARM FVP port does the following: 1037* Initializes the generic interrupt controller. 1038* Configures the CLCD controller. 1039* Enables system-level implementation of the generic timer counter. 1040* Grants access to the system counter timer module 1041* Initializes the FVP power controller device 1042* Detects the system topology. 1043 1044 1045### Function : bl31_get_next_image_info() [mandatory] 1046 1047 Argument : unsigned int 1048 Return : entry_point_info * 1049 1050This function may execute with the MMU and data caches enabled if the platform 1051port does the necessary initializations in `bl31_plat_arch_setup()`. 1052 1053This function is called by `bl31_main()` to retrieve information provided by 1054BL2 for the next image in the security state specified by the argument. BL3-1 1055uses this information to pass control to that image in the specified security 1056state. This function must return a pointer to the `entry_point_info` structure 1057(that was copied during `bl31_early_platform_setup()`) if the image exists. It 1058should return NULL otherwise. 1059 1060 10613.3 Power State Coordination Interface (in BL3-1) 1062------------------------------------------------ 1063 1064The ARM Trusted Firmware's implementation of the PSCI API is based around the 1065concept of an _affinity instance_. Each _affinity instance_ can be uniquely 1066identified in a system by a CPU ID (the processor `MPIDR` is used in the PSCI 1067interface) and an _affinity level_. A processing element (for example, a 1068CPU) is at level 0. If the CPUs in the system are described in a tree where the 1069node above a CPU is a logical grouping of CPUs that share some state, then 1070affinity level 1 is that group of CPUs (for example, a cluster), and affinity 1071level 2 is a group of clusters (for example, the system). The implementation 1072assumes that the affinity level 1 ID can be computed from the affinity level 0 1073ID (for example, a unique cluster ID can be computed from the CPU ID). The 1074current implementation computes this on the basis of the recommended use of 1075`MPIDR` affinity fields in the ARM Architecture Reference Manual. 1076 1077BL3-1's platform initialization code exports a pointer to the platform-specific 1078power management operations required for the PSCI implementation to function 1079correctly. This information is populated in the `plat_pm_ops` structure. The 1080PSCI implementation calls members of the `plat_pm_ops` structure for performing 1081power management operations for each affinity instance. For example, the target 1082CPU is specified by its `MPIDR` in a PSCI `CPU_ON` call. The `affinst_on()` 1083handler (if present) is called for each affinity instance as the PSCI 1084implementation powers up each affinity level implemented in the `MPIDR` (for 1085example, CPU, cluster and system). 1086 1087The following functions must be implemented to initialize PSCI functionality in 1088the ARM Trusted Firmware. 1089 1090 1091### Function : plat_get_aff_count() [mandatory] 1092 1093 Argument : unsigned int, unsigned long 1094 Return : unsigned int 1095 1096This function may execute with the MMU and data caches enabled if the platform 1097port does the necessary initializations in `bl31_plat_arch_setup()`. It is only 1098called by the primary CPU. 1099 1100This function is called by the PSCI initialization code to detect the system 1101topology. Its purpose is to return the number of affinity instances implemented 1102at a given `affinity level` (specified by the first argument) and a given 1103`MPIDR` (specified by the second argument). For example, on a dual-cluster 1104system where first cluster implements 2 CPUs and the second cluster implements 4 1105CPUs, a call to this function with an `MPIDR` corresponding to the first cluster 1106(`0x0`) and affinity level 0, would return 2. A call to this function with an 1107`MPIDR` corresponding to the second cluster (`0x100`) and affinity level 0, 1108would return 4. 1109 1110 1111### Function : plat_get_aff_state() [mandatory] 1112 1113 Argument : unsigned int, unsigned long 1114 Return : unsigned int 1115 1116This function may execute with the MMU and data caches enabled if the platform 1117port does the necessary initializations in `bl31_plat_arch_setup()`. It is only 1118called by the primary CPU. 1119 1120This function is called by the PSCI initialization code. Its purpose is to 1121return the state of an affinity instance. The affinity instance is determined by 1122the affinity ID at a given `affinity level` (specified by the first argument) 1123and an `MPIDR` (specified by the second argument). The state can be one of 1124`PSCI_AFF_PRESENT` or `PSCI_AFF_ABSENT`. The latter state is used to cater for 1125system topologies where certain affinity instances are unimplemented. For 1126example, consider a platform that implements a single cluster with 4 CPUs and 1127another CPU implemented directly on the interconnect with the cluster. The 1128`MPIDR`s of the cluster would range from `0x0-0x3`. The `MPIDR` of the single 1129CPU would be 0x100 to indicate that it does not belong to cluster 0. Cluster 1 1130is missing but needs to be accounted for to reach this single CPU in the 1131topology tree. Hence it is marked as `PSCI_AFF_ABSENT`. 1132 1133 1134### Function : plat_get_max_afflvl() [mandatory] 1135 1136 Argument : void 1137 Return : int 1138 1139This function may execute with the MMU and data caches enabled if the platform 1140port does the necessary initializations in `bl31_plat_arch_setup()`. It is only 1141called by the primary CPU. 1142 1143This function is called by the PSCI implementation both during cold and warm 1144boot, to determine the maximum affinity level that the power management 1145operations should apply to. ARMv8-A has support for 4 affinity levels. It is 1146likely that hardware will implement fewer affinity levels. This function allows 1147the PSCI implementation to consider only those affinity levels in the system 1148that the platform implements. For example, the Base AEM FVP implements two 1149clusters with a configurable number of CPUs. It reports the maximum affinity 1150level as 1, resulting in PSCI power control up to the cluster level. 1151 1152 1153### Function : platform_setup_pm() [mandatory] 1154 1155 Argument : const plat_pm_ops ** 1156 Return : int 1157 1158This function may execute with the MMU and data caches enabled if the platform 1159port does the necessary initializations in `bl31_plat_arch_setup()`. It is only 1160called by the primary CPU. 1161 1162This function is called by PSCI initialization code. Its purpose is to export 1163handler routines for platform-specific power management actions by populating 1164the passed pointer with a pointer to BL3-1's private `plat_pm_ops` structure. 1165 1166A description of each member of this structure is given below. Please refer to 1167the ARM FVP specific implementation of these handlers in [plat/fvp/fvp_pm.c] 1168as an example. A platform port is expected to implement these handlers if the 1169corresponding PSCI operation is to be supported and these handlers are expected 1170to succeed if the return type is `void`. 1171 1172#### plat_pm_ops.affinst_standby() 1173 1174Perform the platform-specific setup to enter the standby state indicated by the 1175passed argument. The generic code expects the handler to succeed. 1176 1177#### plat_pm_ops.affinst_on() 1178 1179Perform the platform specific setup to power on an affinity instance, specified 1180by the `MPIDR` (first argument) and `affinity level` (third argument). The 1181`state` (fourth argument) contains the current state of that affinity instance 1182(ON or OFF). This is useful to determine whether any action must be taken. For 1183example, while powering on a CPU, the cluster that contains this CPU might 1184already be in the ON state. The platform decides what actions must be taken to 1185transition from the current state to the target state (indicated by the power 1186management operation). The generic code expects the platform to return 1187E_SUCCESS on success or E_INTERN_FAIL for any failure. 1188 1189#### plat_pm_ops.affinst_off() 1190 1191Perform the platform specific setup to power off an affinity instance of the 1192calling CPU. It is called by the PSCI `CPU_OFF` API implementation. 1193 1194The `affinity level` (first argument) and `state` (second argument) have 1195a similar meaning as described in the `affinst_on()` operation. They are 1196used to identify the affinity instance on which the call is made and its 1197current state. This gives the platform port an indication of the 1198state transition it must make to perform the requested action. For example, if 1199the calling CPU is the last powered on CPU in the cluster, after powering down 1200affinity level 0 (CPU), the platform port should power down affinity level 1 1201(the cluster) as well. The generic code expects the handler to succeed. 1202 1203#### plat_pm_ops.affinst_suspend() 1204 1205Perform the platform specific setup to power off an affinity instance of the 1206calling CPU. It is called by the PSCI `CPU_SUSPEND` API and `SYSTEM_SUSPEND` 1207API implementation 1208 1209The `affinity level` (second argument) and `state` (third argument) have a 1210similar meaning as described in the `affinst_on()` operation. They are used to 1211identify the affinity instance on which the call is made and its current state. 1212This gives the platform port an indication of the state transition it must 1213make to perform the requested action. For example, if the calling CPU is the 1214last powered on CPU in the cluster, after powering down affinity level 0 (CPU), 1215the platform port should power down affinity level 1 (the cluster) as well. 1216 1217The difference between turning an affinity instance off versus suspending it 1218is that in the former case, the affinity instance is expected to re-initialize 1219its state when its next powered on (see `affinst_on_finish()`). In the latter 1220case, the affinity instance is expected to save enough state so that it can 1221resume execution by restoring this state when its powered on (see 1222`affinst_suspend_finish()`).The generic code expects the handler to succeed. 1223 1224#### plat_pm_ops.affinst_on_finish() 1225 1226This function is called by the PSCI implementation after the calling CPU is 1227powered on and released from reset in response to an earlier PSCI `CPU_ON` call. 1228It performs the platform-specific setup required to initialize enough state for 1229this CPU to enter the normal world and also provide secure runtime firmware 1230services. 1231 1232The `affinity level` (first argument) and `state` (second argument) have a 1233similar meaning as described in the previous operations. The generic code 1234expects the handler to succeed. 1235 1236#### plat_pm_ops.affinst_suspend_finish() 1237 1238This function is called by the PSCI implementation after the calling CPU is 1239powered on and released from reset in response to an asynchronous wakeup 1240event, for example a timer interrupt that was programmed by the CPU during the 1241`CPU_SUSPEND` call or `SYSTEM_SUSPEND` call. It performs the platform-specific 1242setup required to restore the saved state for this CPU to resume execution 1243in the normal world and also provide secure runtime firmware services. 1244 1245The `affinity level` (first argument) and `state` (second argument) have a 1246similar meaning as described in the previous operations. The generic code 1247expects the platform to succeed. 1248 1249#### plat_pm_ops.validate_power_state() 1250 1251This function is called by the PSCI implementation during the `CPU_SUSPEND` 1252call to validate the `power_state` parameter of the PSCI API. If the 1253`power_state` is known to be invalid, the platform must return 1254PSCI_E_INVALID_PARAMS as error, which is propagated back to the normal 1255world PSCI client. 1256 1257#### plat_pm_ops.validate_ns_entrypoint() 1258 1259This function is called by the PSCI implementation during the `CPU_SUSPEND`, 1260`SYSTEM_SUSPEND` and `CPU_ON` calls to validate the non-secure `entry_point` 1261parameter passed by the normal world. If the `entry_point` is known to be 1262invalid, the platform must return PSCI_E_INVALID_PARAMS as error, which is 1263propagated back to the normal world PSCI client. 1264 1265#### plat_pm_ops.get_sys_suspend_power_state() 1266 1267This function is called by the PSCI implementation during the `SYSTEM_SUSPEND` 1268call to return the `power_state` parameter. This allows the platform to encode 1269the appropriate State-ID field within the `power_state` parameter which can be 1270utilized in `affinst_suspend()` to suspend to system affinity level. The 1271`power_state` parameter should be in the same format as specified by the 1272PSCI specification for the CPU_SUSPEND API. 1273 1274BL3-1 platform initialization code must also detect the system topology and 1275the state of each affinity instance in the topology. This information is 1276critical for the PSCI runtime service to function correctly. More details are 1277provided in the description of the `plat_get_aff_count()` and 1278`plat_get_aff_state()` functions above. 1279 12803.4 Interrupt Management framework (in BL3-1) 1281---------------------------------------------- 1282BL3-1 implements an Interrupt Management Framework (IMF) to manage interrupts 1283generated in either security state and targeted to EL1 or EL2 in the non-secure 1284state or EL3/S-EL1 in the secure state. The design of this framework is 1285described in the [IMF Design Guide] 1286 1287A platform should export the following APIs to support the IMF. The following 1288text briefly describes each api and its implementation on the FVP port. The API 1289implementation depends upon the type of interrupt controller present in the 1290platform. The FVP implements an ARM Generic Interrupt Controller (ARM GIC) as 1291per the version 2.0 of the [ARM GIC Architecture Specification] 1292 1293### Function : plat_interrupt_type_to_line() [mandatory] 1294 1295 Argument : uint32_t, uint32_t 1296 Return : uint32_t 1297 1298The ARM processor signals an interrupt exception either through the IRQ or FIQ 1299interrupt line. The specific line that is signaled depends on how the interrupt 1300controller (IC) reports different interrupt types from an execution context in 1301either security state. The IMF uses this API to determine which interrupt line 1302the platform IC uses to signal each type of interrupt supported by the framework 1303from a given security state. 1304 1305The first parameter will be one of the `INTR_TYPE_*` values (see [IMF Design 1306Guide]) indicating the target type of the interrupt, the second parameter is the 1307security state of the originating execution context. The return result is the 1308bit position in the `SCR_EL3` register of the respective interrupt trap: IRQ=1, 1309FIQ=2. 1310 1311The FVP port configures the ARM GIC to signal S-EL1 interrupts as FIQs and 1312Non-secure interrupts as IRQs from either security state. 1313 1314 1315### Function : plat_ic_get_pending_interrupt_type() [mandatory] 1316 1317 Argument : void 1318 Return : uint32_t 1319 1320This API returns the type of the highest priority pending interrupt at the 1321platform IC. The IMF uses the interrupt type to retrieve the corresponding 1322handler function. `INTR_TYPE_INVAL` is returned when there is no interrupt 1323pending. The valid interrupt types that can be returned are `INTR_TYPE_EL3`, 1324`INTR_TYPE_S_EL1` and `INTR_TYPE_NS`. 1325 1326The FVP port reads the _Highest Priority Pending Interrupt Register_ 1327(`GICC_HPPIR`) to determine the id of the pending interrupt. The type of interrupt 1328depends upon the id value as follows. 1329 13301. id < 1022 is reported as a S-EL1 interrupt 13312. id = 1022 is reported as a Non-secure interrupt. 13323. id = 1023 is reported as an invalid interrupt type. 1333 1334 1335### Function : plat_ic_get_pending_interrupt_id() [mandatory] 1336 1337 Argument : void 1338 Return : uint32_t 1339 1340This API returns the id of the highest priority pending interrupt at the 1341platform IC. The IMF passes the id returned by this API to the registered 1342handler for the pending interrupt if the `IMF_READ_INTERRUPT_ID` build time flag 1343is set. INTR_ID_UNAVAILABLE is returned when there is no interrupt pending. 1344 1345The FVP port reads the _Highest Priority Pending Interrupt Register_ 1346(`GICC_HPPIR`) to determine the id of the pending interrupt. The id that is 1347returned by API depends upon the value of the id read from the interrupt 1348controller as follows. 1349 13501. id < 1022. id is returned as is. 13512. id = 1022. The _Aliased Highest Priority Pending Interrupt Register_ 1352 (`GICC_AHPPIR`) is read to determine the id of the non-secure interrupt. This 1353 id is returned by the API. 13543. id = 1023. `INTR_ID_UNAVAILABLE` is returned. 1355 1356 1357### Function : plat_ic_acknowledge_interrupt() [mandatory] 1358 1359 Argument : void 1360 Return : uint32_t 1361 1362This API is used by the CPU to indicate to the platform IC that processing of 1363the highest pending interrupt has begun. It should return the id of the 1364interrupt which is being processed. 1365 1366The FVP port reads the _Interrupt Acknowledge Register_ (`GICC_IAR`). This 1367changes the state of the highest priority pending interrupt from pending to 1368active in the interrupt controller. It returns the value read from the 1369`GICC_IAR`. This value is the id of the interrupt whose state has been changed. 1370 1371The TSP uses this API to start processing of the secure physical timer 1372interrupt. 1373 1374 1375### Function : plat_ic_end_of_interrupt() [mandatory] 1376 1377 Argument : uint32_t 1378 Return : void 1379 1380This API is used by the CPU to indicate to the platform IC that processing of 1381the interrupt corresponding to the id (passed as the parameter) has 1382finished. The id should be the same as the id returned by the 1383`plat_ic_acknowledge_interrupt()` API. 1384 1385The FVP port writes the id to the _End of Interrupt Register_ 1386(`GICC_EOIR`). This deactivates the corresponding interrupt in the interrupt 1387controller. 1388 1389The TSP uses this API to finish processing of the secure physical timer 1390interrupt. 1391 1392 1393### Function : plat_ic_get_interrupt_type() [mandatory] 1394 1395 Argument : uint32_t 1396 Return : uint32_t 1397 1398This API returns the type of the interrupt id passed as the parameter. 1399`INTR_TYPE_INVAL` is returned if the id is invalid. If the id is valid, a valid 1400interrupt type (one of `INTR_TYPE_EL3`, `INTR_TYPE_S_EL1` and `INTR_TYPE_NS`) is 1401returned depending upon how the interrupt has been configured by the platform 1402IC. 1403 1404The FVP port configures S-EL1 interrupts as Group0 interrupts and Non-secure 1405interrupts as Group1 interrupts. It reads the group value corresponding to the 1406interrupt id from the relevant _Interrupt Group Register_ (`GICD_IGROUPRn`). It 1407uses the group value to determine the type of interrupt. 1408 14093.5 Crash Reporting mechanism (in BL3-1) 1410---------------------------------------------- 1411BL3-1 implements a crash reporting mechanism which prints the various registers 1412of the CPU to enable quick crash analysis and debugging. It requires that a 1413console is designated as the crash console by the platform which will be used to 1414print the register dump. 1415 1416The following functions must be implemented by the platform if it wants crash 1417reporting mechanism in BL3-1. The functions are implemented in assembly so that 1418they can be invoked without a C Runtime stack. 1419 1420### Function : plat_crash_console_init 1421 1422 Argument : void 1423 Return : int 1424 1425This API is used by the crash reporting mechanism to initialize the crash 1426console. It should only use the general purpose registers x0 to x2 to do the 1427initialization and returns 1 on success. 1428 1429The FVP port designates the `PL011_UART0` as the crash console and calls the 1430console_core_init() to initialize the console. 1431 1432### Function : plat_crash_console_putc 1433 1434 Argument : int 1435 Return : int 1436 1437This API is used by the crash reporting mechanism to print a character on the 1438designated crash console. It should only use general purpose registers x1 and 1439x2 to do its work. The parameter and the return value are in general purpose 1440register x0. 1441 1442The FVP port designates the `PL011_UART0` as the crash console and calls the 1443console_core_putc() to print the character on the console. 1444 14454. Build flags 1446--------------- 1447 1448There are some build flags which can be defined by the platform to control 1449inclusion or exclusion of certain BL stages from the FIP image. These flags 1450need to be defined in the platform makefile which will get included by the 1451build system. 1452 1453* **NEED_BL30** 1454 This flag if defined by the platform mandates that a BL3-0 binary should 1455 be included in the FIP image. The path to the BL3-0 binary can be specified 1456 by the `BL30` build option (see build options in the [User Guide]). 1457 1458* **NEED_BL33** 1459 By default, this flag is defined `yes` by the build system and `BL33` 1460 build option should be supplied as a build option. The platform has the option 1461 of excluding the BL3-3 image in the `fip` image by defining this flag to 1462 `no`. 1463 14645. C Library 1465------------- 1466 1467To avoid subtle toolchain behavioral dependencies, the header files provided 1468by the compiler are not used. The software is built with the `-nostdinc` flag 1469to ensure no headers are included from the toolchain inadvertently. Instead the 1470required headers are included in the ARM Trusted Firmware source tree. The 1471library only contains those C library definitions required by the local 1472implementation. If more functionality is required, the needed library functions 1473will need to be added to the local implementation. 1474 1475Versions of [FreeBSD] headers can be found in `include/stdlib`. Some of these 1476headers have been cut down in order to simplify the implementation. In order to 1477minimize changes to the header files, the [FreeBSD] layout has been maintained. 1478The generic C library definitions can be found in `include/stdlib` with more 1479system and machine specific declarations in `include/stdlib/sys` and 1480`include/stdlib/machine`. 1481 1482The local C library implementations can be found in `lib/stdlib`. In order to 1483extend the C library these files may need to be modified. It is recommended to 1484use a release version of [FreeBSD] as a starting point. 1485 1486The C library header files in the [FreeBSD] source tree are located in the 1487`include` and `sys/sys` directories. [FreeBSD] machine specific definitions 1488can be found in the `sys/<machine-type>` directories. These files define things 1489like 'the size of a pointer' and 'the range of an integer'. Since an AArch64 1490port for [FreeBSD] does not yet exist, the machine specific definitions are 1491based on existing machine types with similar properties (for example SPARC64). 1492 1493Where possible, C library function implementations were taken from [FreeBSD] 1494as found in the `lib/libc` directory. 1495 1496A copy of the [FreeBSD] sources can be downloaded with `git`. 1497 1498 git clone git://github.com/freebsd/freebsd.git -b origin/release/9.2.0 1499 1500 15016. Storage abstraction layer 1502----------------------------- 1503 1504In order to improve platform independence and portability an storage abstraction 1505layer is used to load data from non-volatile platform storage. 1506 1507Each platform should register devices and their drivers via the Storage layer. 1508These drivers then need to be initialized by bootloader phases as 1509required in their respective `blx_platform_setup()` functions. Currently 1510storage access is only required by BL1 and BL2 phases. The `load_image()` 1511function uses the storage layer to access non-volatile platform storage. 1512 1513It is mandatory to implement at least one storage driver. For the FVP the 1514Firmware Image Package(FIP) driver is provided as the default means to load data 1515from storage (see the "Firmware Image Package" section in the [User Guide]). 1516The storage layer is described in the header file 1517`include/drivers/io/io_storage.h`. The implementation of the common library 1518is in `drivers/io/io_storage.c` and the driver files are located in 1519`drivers/io/`. 1520 1521Each IO driver must provide `io_dev_*` structures, as described in 1522`drivers/io/io_driver.h`. These are returned via a mandatory registration 1523function that is called on platform initialization. The semi-hosting driver 1524implementation in `io_semihosting.c` can be used as an example. 1525 1526The Storage layer provides mechanisms to initialize storage devices before 1527IO operations are called. The basic operations supported by the layer 1528include `open()`, `close()`, `read()`, `write()`, `size()` and `seek()`. 1529Drivers do not have to implement all operations, but each platform must 1530provide at least one driver for a device capable of supporting generic 1531operations such as loading a bootloader image. 1532 1533The current implementation only allows for known images to be loaded by the 1534firmware. These images are specified by using their names, as defined in 1535[include/plat/common/platform.h]. The platform layer (`plat_get_image_source()`) 1536then returns a reference to a device and a driver-specific `spec` which will be 1537understood by the driver to allow access to the image data. 1538 1539The layer is designed in such a way that is it possible to chain drivers with 1540other drivers. For example, file-system drivers may be implemented on top of 1541physical block devices, both represented by IO devices with corresponding 1542drivers. In such a case, the file-system "binding" with the block device may 1543be deferred until the file-system device is initialised. 1544 1545The abstraction currently depends on structures being statically allocated 1546by the drivers and callers, as the system does not yet provide a means of 1547dynamically allocating memory. This may also have the affect of limiting the 1548amount of open resources per driver. 1549 1550 1551- - - - - - - - - - - - - - - - - - - - - - - - - - 1552 1553_Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved._ 1554 1555 1556[ARM GIC Architecture Specification]: http://arminfo.emea.arm.com/help/topic/com.arm.doc.ihi0048b/IHI0048B_gic_architecture_specification.pdf 1557[IMF Design Guide]: interrupt-framework-design.md 1558[User Guide]: user-guide.md 1559[FreeBSD]: http://www.freebsd.org 1560[Firmware Design Guide]: firmware-design.md 1561 1562[plat/common/aarch64/platform_mp_stack.S]: ../plat/common/aarch64/platform_mp_stack.S 1563[plat/common/aarch64/platform_up_stack.S]: ../plat/common/aarch64/platform_up_stack.S 1564[plat/fvp/include/platform_def.h]: ../plat/fvp/include/platform_def.h 1565[plat/fvp/include/plat_macros.S]: ../plat/fvp/include/plat_macros.S 1566[plat/fvp/aarch64/plat_common.c]: ../plat/fvp/aarch64/plat_common.c 1567[plat/fvp/plat_pm.c]: ../plat/fvp/plat_pm.c 1568[include/runtime_svc.h]: ../include/runtime_svc.h 1569[include/plat/common/platform.h]: ../include/plat/common/platform.h 1570