diff options
Diffstat (limited to 'docs/firmware-design.md')
-rw-r--r-- | docs/firmware-design.md | 798 |
1 files changed, 798 insertions, 0 deletions
diff --git a/docs/firmware-design.md b/docs/firmware-design.md new file mode 100644 index 0000000..89dd45f --- /dev/null +++ b/docs/firmware-design.md @@ -0,0 +1,798 @@ +ARM Trusted Firmware Design +=========================== + +Contents : + +1. Introduction +2. Cold Boot +3. Memory layout on FVP platforms +4. Firmware Image Package (FIP) +5. Code Structure +6. References + + +1. Introduction +---------------- + +The ARM Trusted Firmware implements a subset of the Trusted Board Boot +Requirements (TBBR) Platform Design Document (PDD) [1] for ARM reference +platforms. The TBB sequence starts when the platform is powered on and runs up +to the stage where it hands-off control to firmware running in the normal +world in DRAM. This is the cold boot path. + +The ARM Trusted Firmware also implements the Power State Coordination Interface +([PSCI]) PDD [2] as a runtime service. PSCI is the interface from normal world +software to firmware implementing power management use-cases (for example, +secondary CPU boot, hotplug and idle). Normal world software can access ARM +Trusted Firmware runtime services via the ARM SMC (Secure Monitor Call) +instruction. The SMC instruction must be used as mandated by the [SMC Calling +Convention PDD][SMCCC] [3]. + + +2. Cold Boot +------------- + +The cold boot path starts when the platform is physically turned on. One of +the CPUs released from reset is chosen as the primary CPU, and the remaining +CPUs are considered secondary CPUs. The primary CPU is chosen through +platform-specific means. The cold boot path is mainly executed by the primary +CPU, other than essential CPU initialization executed by all CPUs. The +secondary CPUs are kept in a safe platform-specific state until the primary +CPU has performed enough initialization to boot them. + +The cold boot path in this implementation of the ARM Trusted Firmware is divided +into three stages (in order of execution): + +* Boot Loader stage 1 (BL1) +* Boot Loader stage 2 (BL2) +* Boot Loader stage 3 (BL3-1). The '1' distinguishes this from other 3rd level + boot loader stages. + +The ARM Fixed Virtual Platforms (FVPs) provide trusted ROM, trusted SRAM and +trusted DRAM regions. Each boot loader stage uses one or more of these +memories for its code and data. + + +### BL1 + +This stage begins execution from the platform's reset vector in trusted ROM at +EL3. BL1 code starts at `0x00000000` (trusted ROM) in the FVP memory map. The +BL1 data section is placed at the start of trusted SRAM, `0x04000000`. The +functionality implemented by this stage is as follows. + +#### Determination of boot path + +Whenever a CPU is released from reset, BL1 needs to distinguish between a warm +boot and a cold boot. This is done using a platform-specific mechanism. The +ARM FVPs implement a simple power controller at `0x1c100000`. The `PSYS` +register (`0x10`) is used to distinguish between a cold and warm boot. This +information is contained in the `PSYS.WK[25:24]` field. Additionally, a +per-CPU mailbox is maintained in trusted DRAM (`0x00600000`), to which BL1 +writes an entrypoint. Each CPU jumps to this entrypoint upon warm boot. During +cold boot, BL1 places the secondary CPUs in a safe platform-specific state while +the primary CPU executes the remaining cold boot path as described in the +following sections. + +#### Architectural initialization + +BL1 performs minimal architectural initialization as follows. + +* Exception vectors + + BL1 sets up simple exception vectors for both synchronous and asynchronous + exceptions. The default behavior upon receiving an exception is to set a + status code. In the case of the FVP this code is written to the Versatile + Express System LED register in the following format: + + SYS_LED[0] - Security state (Secure=0/Non-Secure=1) + SYS_LED[2:1] - Exception Level (EL3=0x3, EL2=0x2, EL1=0x1, EL0=0x0) + SYS_LED[7:3] - Exception Class (Sync/Async & origin). The values for + each exception class are: + + 0x0 : Synchronous exception from Current EL with SP_EL0 + 0x1 : IRQ exception from Current EL with SP_EL0 + 0x2 : FIQ exception from Current EL with SP_EL0 + 0x3 : System Error exception from Current EL with SP_EL0 + 0x4 : Synchronous exception from Current EL with SP_ELx + 0x5 : IRQ exception from Current EL with SP_ELx + 0x6 : FIQ exception from Current EL with SP_ELx + 0x7 : System Error exception from Current EL with SP_ELx + 0x8 : Synchronous exception from Lower EL using aarch64 + 0x9 : IRQ exception from Lower EL using aarch64 + 0xa : FIQ exception from Lower EL using aarch64 + 0xb : System Error exception from Lower EL using aarch64 + 0xc : Synchronous exception from Lower EL using aarch32 + 0xd : IRQ exception from Lower EL using aarch32 + 0xe : FIQ exception from Lower EL using aarch32 + 0xf : System Error exception from Lower EL using aarch32 + + A write to the LED register reflects in the System LEDs (S6LED0..7) in the + CLCD window of the FVP. This behavior is because this boot loader stage + does not expect to receive any exceptions other than the SMC exception. + For the latter, BL1 installs a simple stub. The stub expects to receive + only a single type of SMC (determined by its function ID in the general + purpose register `X0`). This SMC is raised by BL2 to make BL1 pass control + to BL3-1 (loaded by BL2) at EL3. Any other SMC leads to an assertion + failure. + +* MMU setup + + BL1 sets up EL3 memory translation by creating page tables to cover the + first 4GB of physical address space. This covers all the memories and + peripherals needed by BL1. + +* Control register setup + - `SCTLR_EL3`. Instruction cache is enabled by setting the `SCTLR_EL3.I` + bit. Alignment and stack alignment checking is enabled by setting the + `SCTLR_EL3.A` and `SCTLR_EL3.SA` bits. Exception endianness is set to + little-endian by clearing the `SCTLR_EL3.EE` bit. + + - `CPUECTLR`. When the FVP includes a model of a specific ARM processor + implementation (for example A57 or A53), then intra-cluster coherency is + enabled by setting the `CPUECTLR.SMPEN` bit. The AEMv8 Base FVP is + inherently coherent so does not implement `CPUECTLR`. + + - `SCR`. Use of the HVC instruction from EL1 is enabled by setting the + `SCR.HCE` bit. FIQ exceptions are configured to be taken in EL3 by + setting the `SCR.FIQ` bit. The register width of the next lower + exception level is set to AArch64 by setting the `SCR.RW` bit. External + Aborts and SError Interrupts are configured to be taken in EL3 by + setting the `SCR.EA` bit. + + - `CPTR_EL3`. Accesses to the `CPACR_EL1` register from EL1 or EL2, or the + `CPTR_EL2` register from EL2 are configured to not trap to EL3 by + clearing the `CPTR_EL3.TCPAC` bit. Access to the trace functionality is + configured not to trap to EL3 by clearing the `CPTR_EL3.TTA` bit. + Instructions that access the registers associated with Floating Point + and Advanced SIMD execution are configured to not trap to EL3 by + clearing the `CPTR_EL3.TFP` bit. + + - `CNTFRQ_EL0`. The `CNTFRQ_EL0` register is programmed with the base + frequency of the system counter, which is retrieved from the first entry + in the frequency modes table. + + - Generic Timer. The system level implementation of the generic timer is + enabled through the memory mapped interface. + +#### Platform initialization + +BL1 enables issuing of snoop and DVM (Distributed Virtual Memory) requests from +the CCI-400 slave interface corresponding to the cluster that includes the +primary CPU. BL1 also initializes UART0 (PL011 console), which enables access to +the `printf` family of functions. + +#### BL2 image load and execution + +BL1 execution continues as follows: + +1. BL1 determines the amount of free trusted SRAM memory available by + calculating the extent of its own data section, which also resides in + trusted SRAM. BL1 loads a BL2 raw binary image from platform storage, at a + platform-specific base address. The filename of the BL2 raw binary image + must be `bl2.bin`. If the BL2 image file is not present or if there is not + enough free trusted SRAM the following error message is printed: + + "Failed to load boot loader stage 2 (BL2) firmware." + + If the load is successful, BL1 updates the limits of the remaining free + trusted SRAM. It also populates information about the amount of trusted + SRAM used by the BL2 image. The exact load location of the image is + provided as a base address in the platform header. Further description of + the memory layout can be found later in this document. + +2. BL1 prints the following string from the primary CPU to indicate successful + execution of the BL1 stage: + + "Booting trusted firmware boot loader stage 1" + +3. BL1 passes control to the BL2 image at Secure EL1, starting from its load + address. + +4. BL1 also passes information about the amount of trusted SRAM used and + available for use. This information is populated at a platform-specific + memory address. + + +### BL2 + +BL1 loads and passes control to BL2 at Secure EL1. BL2 is linked against and +loaded at a platform-specific base address (more information can be found later +in this document). The functionality implemented by BL2 is as follows. + +#### Architectural initialization + +BL2 performs minimal architectural initialization required for subsequent +stages of the ARM Trusted Firmware and normal world software. It sets up +Secure EL1 memory translation by creating page tables to address the first 4GB +of the physical address space in a similar way to BL1. EL1 and EL0 are given +access to Floating Point & Advanced SIMD registers by clearing the `CPACR.FPEN` +bits. + +#### Platform initialization + +BL2 does not perform any platform initialization that affects subsequent +stages of the ARM Trusted Firmware or normal world software. It copies the +information regarding the trusted SRAM populated by BL1 using a +platform-specific mechanism. It calculates the limits of DRAM (main memory) +to determine whether there is enough space to load the normal world software +images. A platform defined base address is used to specify the load address for +the BL3-1 image. It also defines the extents of memory available for use by the +BL3-2 image. + +#### Normal world image load + +BL2 loads the normal world firmware image (e.g. UEFI). BL2 relies on BL3-1 to +pass control to the normal world software image it loads. Hence, BL2 populates +a platform-specific area of memory with the entrypoint and Current Program +Status Register (`CPSR`) of the normal world software image. The entrypoint is +the load address of the normal world software image. The `CPSR` is determined as +specified in Section 5.13 of the [PSCI PDD] [PSCI]. This information is passed +to BL3-1. + +#### BL3-2 (Secure Payload) image load + +BL2 loads the optional BL3-2 image. The image executes in the secure world. BL2 +relies on BL3-1 to pass control to the BL3-2 image, if present. Hence, BL2 +populates a platform- specific area of memory with the entrypoint and Current +Program Status Register (`CPSR`) of the BL3-2 image. The entrypoint is the load +address of the BL3-2 image. The `CPSR` is initialized with Secure EL1 and Stack +pointer set to SP_EL1 (EL1h) as the mode, exception bits disabled (DAIF bits) +and AArch64 execution state. This information is passed to BL3-1. + +##### UEFI firmware load + +BL2 loads the BL3-3 (UEFI) image into non-secure memory as defined by the +platform (`0x88000000` for FVPs), and arranges for BL3-1 to pass control to that +location. As mentioned earlier, BL2 populates platform-specific memory with the +entrypoint and `CPSR` of the BL3-3 image. + +#### BL3-1 image load and execution + +BL2 execution continues as follows: + +1. BL2 loads the BL3-1 image into a platform-specific address in trusted SRAM + and the BL3-3 image into a platform specific address in non-secure DRAM. + The images are identified by the files `bl31.bin` and `bl33.bin` in + platform storage. If there is not enough memory to load the images or the + images are missing it leads to an assertion failure. If the BL3-1 image + loads successfully, BL1 updates the amount of trusted SRAM used and + available for use by BL3-1. This information is populated at a + platform-specific memory address. + +2. BL2 passes control back to BL1 by raising an SMC, providing BL1 with the + BL3-1 entrypoint. The exception is handled by the SMC exception handler + installed by BL1. + +3. BL1 turns off the MMU and flushes the caches. It clears the + `SCTLR_EL3.M/I/C` bits, flushes the data cache to the point of coherency + and invalidates the TLBs. + +4. BL1 passes control to BL3-1 at the specified entrypoint at EL3. + + +### BL3-1 + +The image for this stage is loaded by BL2 and BL1 passes control to BL3-1 at +EL3. BL3-1 executes solely in trusted SRAM. BL3-1 is linked against and +loaded at a platform-specific base address (more information can be found later +in this document). The functionality implemented by BL3-1 is as follows. + +#### Architectural initialization + +Currently, BL3-1 performs a similar architectural initialization to BL1 as +far as system register settings are concerned. Since BL1 code resides in ROM, +architectural initialization in BL3-1 allows override of any previous +initialization done by BL1. BL3-1 creates page tables to address the first +4GB of physical address space and initializes the MMU accordingly. It replaces +the exception vectors populated by BL1 with its own. BL3-1 exception vectors +signal error conditions in the same way as BL1 does if an unexpected +exception is raised. They implement more elaborate support for handling SMCs +since this is the only mechanism to access the runtime services implemented by +BL3-1 (PSCI for example). BL3-1 checks each SMC for validity as specified by +the [SMC calling convention PDD][SMCCC] before passing control to the required +SMC handler routine. + +#### Platform initialization + +BL3-1 performs detailed platform initialization, which enables normal world +software to function correctly. It also retrieves entrypoint information for +the normal world software image loaded by BL2 from the platform defined +memory address populated by BL2. + +* GICv2 initialization: + + - Enable group0 interrupts in the GIC CPU interface. + - Configure group0 interrupts to be asserted as FIQs. + - Disable the legacy interrupt bypass mechanism. + - Configure the priority mask register to allow interrupts of all + priorities to be signaled to the CPU interface. + - Mark SGIs 8-15, the secure physical timer interrupt (#29) and the + trusted watchdog interrupt (#56) as group0 (secure). + - Target the trusted watchdog interrupt to CPU0. + - Enable these group0 interrupts in the GIC distributor. + - Configure all other interrupts as group1 (non-secure). + - Enable signaling of group0 interrupts in the GIC distributor. + +* GICv3 initialization: + + If a GICv3 implementation is available in the platform, BL3-1 initializes + the GICv3 in GICv2 emulation mode with settings as described for GICv2 + above. + +* Power management initialization: + + BL3-1 implements a state machine to track CPU and cluster state. The state + can be one of `OFF`, `ON_PENDING`, `SUSPEND` or `ON`. All secondary CPUs are + initially in the `OFF` state. The cluster that the primary CPU belongs to is + `ON`; any other cluster is `OFF`. BL3-1 initializes the data structures that + implement the state machine, including the locks that protect them. BL3-1 + accesses the state of a CPU or cluster immediately after reset and before + the MMU is enabled in the warm boot path. It is not currently possible to + use 'exclusive' based spinlocks, therefore BL3-1 uses locks based on + Lamport's Bakery algorithm instead. BL3-1 allocates these locks in device + memory. They are accessible irrespective of MMU state. + +* Runtime services initialization: + + The only runtime service implemented by BL3-1 is PSCI. The complete PSCI API + is not yet implemented. The following functions are currently implemented: + + - `PSCI_VERSION` + - `CPU_OFF` + - `CPU_ON` + - `CPU_SUSPEND` + - `AFFINITY_INFO` + + The `CPU_ON`, `CPU_OFF` and `CPU_SUSPEND` functions implement the warm boot + path in ARM Trusted Firmware. `CPU_ON` and `CPU_OFF` have undergone testing + on all the supported FVPs. `CPU_SUSPEND` & `AFFINITY_INFO` have undergone + testing only on the AEM v8 Base FVP. Support for `AFFINITY_INFO` is still + experimental. Support for `CPU_SUSPEND` is stable for entry into power down + states. Standby states are currently not supported. `PSCI_VERSION` is + present but completely untested in this version of the software. + + Unsupported PSCI functions can be divided into ones that can return + execution to the caller and ones that cannot. The following functions + return with a error code as documented in the [Power State Coordination + Interface PDD] [PSCI]. + + - `MIGRATE` : -1 (NOT_SUPPORTED) + - `MIGRATE_INFO_TYPE` : 2 (Trusted OS is either not present or does not + require migration) + - `MIGRATE_INFO_UP_CPU` : 0 (Return value is UNDEFINED) + + The following unsupported functions do not return and signal an assertion + failure if invoked. + + - `SYSTEM_OFF` + - `SYSTEM_RESET` + + BL3-1 returns the error code `-1` if an SMC is raised for any other runtime + service. This behavior is mandated by the [SMC calling convention PDD] + [SMCCC]. + + +### BL3-2 (Secure Payload) image initialization + +BL2 is responsible for loading a BL3-2 image in memory specified by the platform. +BL3-1 provides an api that uses the entrypoint and memory layout information for +the BL3-2 image provided by BL2 to initialise BL3-2 in S-EL1. + + +### Normal world software execution + +BL3-1 uses the entrypoint information provided by BL2 to jump to the normal +world software image (BL3-3) at the highest available Exception Level (EL2 if +available, otherwise EL1). + + +3. Memory layout on FVP platforms +---------------------------------- + +On FVP platforms, we use the Trusted ROM and Trusted SRAM to store the trusted +firmware binaries. BL1 is originally sitting in the Trusted ROM. Its read-write +data are relocated at the base of the Trusted SRAM at runtime. BL1 loads BL2 +image near the top of the the trusted SRAM. BL2 loads BL3-1 image between BL1 +and BL2. This memory layout is illustrated by the following diagram. + + Trusted SRAM + +----------+ 0x04040000 + | | + |----------| + | BL2 | + |----------| + | | + |----------| + | BL31 | + |----------| + | | + |----------| + | BL1 (rw) | + +----------+ 0x04000000 + + Trusted ROM + +----------+ 0x04000000 + | BL1 (ro) | + +----------+ 0x00000000 + +Each bootloader stage image layout is described by its own linker script. The +linker scripts export some symbols into the program symbol table. Their values +correspond to particular addresses. The trusted firmware code can refer to these +symbols to figure out the image memory layout. + +Linker symbols follow the following naming convention in the trusted firmware. + +* `__<SECTION>_START__` + + Start address of a given section named `<SECTION>`. + +* `__<SECTION>_END__` + + End address of a given section named `<SECTION>`. If there is an alignment + constraint on the section's end address then `__<SECTION>_END__` corresponds + to the end address of the section's actual contents, rounded up to the right + boundary. Refer to the value of `__<SECTION>_UNALIGNED_END__` to know the + actual end address of the section's contents. + +* `__<SECTION>_UNALIGNED_END__` + + End address of a given section named `<SECTION>` without any padding or + rounding up due to some alignment constraint. + +* `__<SECTION>_SIZE__` + + Size (in bytes) of a given section named `<SECTION>`. If there is an + alignment constraint on the section's end address then `__<SECTION>_SIZE__` + corresponds to the size of the section's actual contents, rounded up to the + right boundary. In other words, `__<SECTION>_SIZE__ = __<SECTION>_END__ - + _<SECTION>_START__`. Refer to the value of `__<SECTION>_UNALIGNED_SIZE__` + to know the actual size of the section's contents. + +* `__<SECTION>_UNALIGNED_SIZE__` + + Size (in bytes) of a given section named `<SECTION>` without any padding or + rounding up due to some alignment constraint. In other words, + `__<SECTION>_UNALIGNED_SIZE__ = __<SECTION>_UNALIGNED_END__ - + __<SECTION>_START__`. + +Some of the linker symbols are mandatory as the trusted firmware code relies on +them to be defined. They are listed in the following subsections. Some of them +must be provided for each bootloader stage and some are specific to a given +bootloader stage. + +The linker scripts define some extra, optional symbols. They are not actually +used by any code but they help in understanding the bootloader images' memory +layout as they are easy to spot in the link map files. + +### Common linker symbols + +Early setup code needs to know the extents of the BSS section to zero-initialise +it before executing any C code. The following linker symbols are defined for +this purpose: + +* `__BSS_START__` This address must be aligned on a 16-byte boundary. +* `__BSS_SIZE__` + +Similarly, the coherent memory section must be zero-initialised. Also, the MMU +setup code needs to know the extents of this section to set the right memory +attributes for it. The following linker symbols are defined for this purpose: + +* `__COHERENT_RAM_START__` This address must be aligned on a page-size boundary. +* `__COHERENT_RAM_END__` This address must be aligned on a page-size boundary. +* `__COHERENT_RAM_UNALIGNED_SIZE__` + +### BL1's linker symbols + +BL1's early setup code needs to know the extents of the .data section to +relocate it from ROM to RAM before executing any C code. The following linker +symbols are defined for this purpose: + +* `__DATA_ROM_START__` This address must be aligned on a 16-byte boundary. +* `__DATA_RAM_START__` This address must be aligned on a 16-byte boundary. +* `__DATA_SIZE__` + +BL1's platform setup code needs to know the extents of its read-write data +region to figure out its memory layout. The following linker symbols are defined +for this purpose: + +* `__BL1_RAM_START__` This is the start address of BL1 RW data. +* `__BL1_RAM_END__` This is the end address of BL1 RW data. + +### BL2's and BL3-1's linker symbols + +Both BL2 and BL3-1 need to know the extents of their read-only section to set +the right memory attributes for this memory region in their MMU setup code. The +following linker symbols are defined for this purpose: + +* `__RO_START__` +* `__RO_END__` + +### How to choose the right base address for each bootloader stage image + +The current implementation of the image loader has some limitations. It is +designed to load images dynamically, at a load address chosen to minimize memory +fragmentation. The chosen image location can be either at the top or the bottom +of free memory. However, until this feature is fully functional, the code also +contains support for loading images at a link-time fixed address. + +BL1 is always loaded at address `0x0`. BL2 and BL3-1 are loaded at specified +locations in Trusted SRAM. The lack of dynamic image loader support means these +load addresses must currently be adjusted as the code grows. The individual +images must be linked against their ultimate runtime locations. + +BL2 is loaded near the top of the Trusted SRAM. BL3-1 is loaded between BL1 +and BL2. All three images are resident concurrently in Trusted RAM during boot +so overlaps are not permitted. + +The image end addresses can be determined from the link map files of the +different images. These are the `build/<platform>/<build-type>/bl<x>/bl<x>.map` +files, with `<x>` the stage bootloader. + +* `bl1.map` link map file provides `__BL1_RAM_END__` address. +* `bl2.map` link map file provides `__BL2_END__` address. +* `bl31.map` link map file provides `__BL31_END__` address. + +To prevent images from overlapping each other, the following constraints must be +enforced: + +1. `__BL1_RAM_END__ <= BL31_BASE` +2. `__BL31_END__ <= BL2_BASE` +3. `__BL2_END__ <= (<Top of Trusted SRAM>)` + +This is illustrated by the following memory layout diagram: + + +----------+ 0x04040000 + | | + |----------| __BL2_END__ + | BL2 | + |----------| BL2_BASE + | | + |----------| __BL31_END__ + | BL31 | + |----------| BL31_BASE + | | + |----------| __BL1_RAM_END__ + | BL1 (rw) | + +----------+ 0x04000000 + +Overlaps are detected during image linking as follows. + +Constraint 1 is enforced by BL1's linker script. If it is violated then the +linker will report an error while building BL1 to indicate that it doesn't +fit: + + aarch64-none-elf-ld: BL31 image overlaps BL1 image. + +This error means that the BL3-1 base address needs to be incremented. Ensure +that the new memory layout still obeys all constraints. + +Constraint 2 is enforced by BL3-1's linker script. If it is violated then the +linker will report an error while building BL3-1 to indicate that it doesn't +fit: + + aarch64-none-elf-ld: BL31 image overlaps BL2 image. + +This error can either mean that the BL3-1 base address needs to be decremented +or that BL2 base address needs to be incremented. Ensure that the new memory +layout still obeys all constraints. + +Constraint 3 is enforced by BL2's linker script. If it is violated then the +linker will report an error while building BL2 to indicate that it doesn't +fit. For example: + + aarch64-none-elf-ld: address 0x40400c8 of bl2.elf section `.bss' is not + within region `RAM' + +This error means that the BL2 base address needs to be decremented. Ensure that +the new memory layout still obeys all constraints. + +Since constraint checks are scattered across linker scripts, it is required to +`make clean` prior to building to ensure that all possible overlapping scenarios +are checked. + +The current implementation of the image loader can result in wasted space +because of the simplified data structure used to represent the extents of free +memory. For example, to load BL2 at address `0x0402D000`, the resulting memory +layout should be as follows: + + ------------ 0x04040000 + | | <- Free space (1) + |----------| + | BL2 | + |----------| BL2_BASE (0x0402D000) + | | <- Free space (2) + |----------| + | BL1 | + ------------ 0x04000000 + +In the current implementation, we need to specify whether BL2 is loaded at the +top or bottom of the free memory. BL2 is top-loaded so in the example above, +the free space (1) above BL2 is hidden, resulting in the following view of +memory: + + ------------ 0x04040000 + | | + | | + | BL2 | + |----------| BL2_BASE (0x0402D000) + | | <- Free space (2) + |----------| + | BL1 | + ------------ 0x04000000 + +BL3-1 is bottom-loaded above BL1. For example, if BL3-1 is bottom-loaded at +`0x0400E000`, the memory layout should look like this: + + ------------ 0x04040000 + | | + | | + | BL2 | + |----------| BL2_BASE (0x0402D000) + | | <- Free space (2) + | | + |----------| + | | + | BL31 | + |----------| BL31_BASE (0x0400E000) + | | <- Free space (3) + |----------| + | BL1 | + ------------ 0x04000000 + +But the free space (3) between BL1 and BL3-1 is wasted, resulting in the +following view: + + ------------ 0x04040000 + | | + | | + | BL2 | + |----------| BL2_BASE (0x0402D000) + | | <- Free space (2) + | | + |----------| + | | + | | + | BL31 | BL31_BASE (0x0400E000) + | | + |----------| + | BL1 | + ------------ 0x04000000 + + +4. Firmware Image Package (FIP) +-------------------------------- + +Using a Firmware Image Package (FIP) allows for packing bootloader images (and +potentially other payloads) into a single archive that can be loaded by the ARM +Trusted Firmware from non-volatile platform storage. A driver to load images +from a FIP has been added to the storage layer and allows a package to be read +from supported platform storage. A tool to create Firmware Image Packages is +also provided and described below. + +### Firmware Image Package layout + +The FIP layout consists of a table of contents (ToC) followed by payload data. +The ToC itself has a header followed by one or more table entries. The ToC is +terminated by an end marker entry. All ToC entries describe some payload data +that has been appended to the end of the binary package. With the information +provided in the ToC entry the corresponding payload data can be retrieved. + + ------------------ + | ToC Header | + |----------------| + | ToC Entry 0 | + |----------------| + | ToC Entry 1 | + |----------------| + | ToC End Marker | + |----------------| + | | + | Data 0 | + | | + |----------------| + | | + | Data 1 | + | | + ------------------ + +The ToC header and entry formats are described in the header file +`include/firmware_image_package.h`. This file is used by both the tool and the +ARM Trusted firmware. + +The ToC header has the following fields: + `name`: The name of the ToC. This is currently used to validate the header. + `serial_number`: A non-zero number provided by the creation tool + `flags`: Flags associated with this data. None are yet defined. + +A ToC entry has the following fields: + `uuid`: All files are referred to by a pre-defined Universally Unique + IDentifier [UUID] . The UUIDs are defined in + `include/firmware_image_package`. The platform translates the requested + image name into the corresponding UUID when accessing the package. + `offset_address`: The offset address at which the corresponding payload data + can be found. The offset is calculated from the ToC base address. + `size`: The size of the corresponding payload data in bytes. + `flags`: Flags associated with this entry. Non are yet defined. + +### Firmware Image Package creation tool + +The FIP creation tool can be used to pack specified images into a binary package +that can be loaded by the ARM Trusted Firmware from platform storage. The tool +currently only supports packing bootloader images. Additional image definitions +can be added to the tool as required. + +The tool can be found in `tools/fip_create`. + +### Loading from a Firmware Image Package (FIP) + +The Firmware Image Package (FIP) driver can load images from a binary package on +non-volatile platform storage. For the FVPs this currently NOR FLASH. For +information on how to load a FIP into FVP NOR FLASH see the "Running the +software" section. + +Bootloader images are loaded according to the platform policy as specified in +`plat/<platform>/plat_io_storage.c`. For the FVPs this means the platform will +attempt to load images from a Firmware Image Package located at the start of NOR +FLASH0. + +Currently the FVPs policy only allows for loading of known images. The platform +policy can be modified to add additional images. + + +5. Code Structure +------------------ + +Trusted Firmware code is logically divided between the three boot loader +stages mentioned in the previous sections. The code is also divided into the +following categories (present as directories in the source code): + +* **Architecture specific.** This could be AArch32 or AArch64. +* **Platform specific.** Choice of architecture specific code depends upon + the platform. +* **Common code.** This is platform and architecture agnostic code. +* **Library code.** This code comprises of functionality commonly used by all + other code. +* **Stage specific.** Code specific to a boot stage. +* **Drivers.** + +Each boot loader stage uses code from one or more of the above mentioned +categories. Based upon the above, the code layout looks like this: + + Directory Used by BL1? Used by BL2? Used by BL3? + bl1 Yes No No + bl2 No Yes No + bl31 No No Yes + arch Yes Yes Yes + plat Yes Yes Yes + drivers Yes No Yes + common Yes Yes Yes + lib Yes Yes Yes + +All assembler files have the `.S` extension. The linker source files for each +boot stage have the extension `.ld.S`. These are processed by GCC to create the +linker scripts which have the extension `.ld`. + +FDTs provide a description of the hardware platform and are used by the Linux +kernel at boot time. These can be found in the `fdts` directory. + + +6. References +-------------- + +1. Trusted Board Boot Requirements CLIENT PDD (ARM DEN 0006B-5). Available + under NDA through your ARM account representative. + +2. [Power State Coordination Interface PDD (ARM DEN 0022B.b)][PSCI]. + +3. [SMC Calling Convention PDD (ARM DEN 0028A)][SMCCC]. + + + +- - - - - - - - - - - - - - - - - - - - - - - - - - + +_Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved._ + + +[PSCI]: http://infocenter.arm.com/help/topic/com.arm.doc.den0022b/index.html "Power State Coordination Interface PDD (ARM DEN 0022B.b)" +[SMCCC]: http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html "SMC Calling Convention PDD (ARM DEN 0028A)" +[UUID]: https://tools.ietf.org/rfc/rfc4122.txt "A Universally Unique IDentifier (UUID) URN Namespace" |