ARM Trusted Firmware - liuyq/android-issues GitHub Wiki

  1. source link like here: https://android-kvm.googlesource.com/trusted-firmware-a
  2. ./out/buildroot/host/bin/aarch64-linux-objdump -m aarch64 -b binary -D qemu/kvm/bl1.bin |less
    qemu/kvm/bl1.bin:     file format binary
    
    
    Disassembly of section .data:
    
    0000000000000000 <.data>:
           0:       d2810600        mov     x0, #0x830                      // #2096
           4:       f2a618a0        movk    x0, #0x30c5, lsl #16
           8:       d51e1000        msr     sctlr_el3, x0
           c:       d5033fdf        isb
           ...
    
  3. source files
    • trusted-firmware-a/Makefile
    ...
    ifeq (${NEED_BL1},yes)
    include bl1/bl1.mk
    endif
    ...
    # Expand build macros for the different images
    ifeq (${NEED_BL1},yes)
    BL1_SOURCES := $(sort ${BL1_SOURCES})
    
    $(eval $(call MAKE_BL,bl1))
    endif
    ...
    
    • trusted-firmware-a/bl1/bl1.mk
    ...
    BL1_SOURCES     +=  bl1/${ARCH}/bl1_arch_setup.c        \
                    bl1/${ARCH}/bl1_context_mgmt.c      \
                    bl1/${ARCH}/bl1_entrypoint.S        \
                    bl1/${ARCH}/bl1_exceptions.S        \
                    bl1/bl1_main.c              \
                    lib/cpus/${ARCH}/cpu_helpers.S      \
                    lib/cpus/errata_report.c        \
                    lib/el3_runtime/${ARCH}/context_mgmt.c  \
                    plat/common/plat_bl1_common.c       \
                    plat/common/${ARCH}/platform_up_stack.S \
                    ${MBEDTLS_SOURCES}
    
    ifeq (${DISABLE_MTPMU},1)
    BL1_SOURCES     +=  lib/extensions/mtpmu/${ARCH}/mtpmu.S
    endif
    
    ifeq (${ARCH},aarch64)
    BL1_SOURCES     +=  lib/cpus/aarch64/dsu_helpers.S      \
                    lib/el3_runtime/aarch64/context.S
    endif
    
    ifeq (${TRUSTED_BOARD_BOOT},1)
    BL1_SOURCES     +=  bl1/bl1_fwu.c
    endif
    
    BL1_LINKERFILE      :=  bl1/bl1.ld.S
    ...
    
    • trusted-firmware-a/bl1/bl1.ld.S
    ...
    OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT)
    OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
    ENTRY(bl1_entrypoint)
    
    MEMORY {
        ROM (rx): ORIGIN = BL1_RO_BASE, LENGTH = BL1_RO_LIMIT - BL1_RO_BASE
        RAM (rwx): ORIGIN = BL1_RW_BASE, LENGTH = BL1_RW_LIMIT - BL1_RW_BASE
    }
    
    SECTIONS
    {
    ...
    
    • trusted-firmware-a/bl1/aarch64/bl1_entrypoint.S
    ...
        /* -----------------------------------------------------
         * bl1_entrypoint() is the entry point into the trusted
         * firmware code when a cpu is released from warm or
         * cold reset.
         * -----------------------------------------------------
         */
    
    func bl1_entrypoint
        /* ---------------------------------------------------------------------
         * If the reset address is programmable then bl1_entrypoint() is
         * executed only on the cold boot path. Therefore, we can skip the warm
         * boot mailbox mechanism.
         * ---------------------------------------------------------------------
         */
        el3_entrypoint_common                   \
            _init_sctlr=1                   \
            _warm_boot_mailbox=!PROGRAMMABLE_RESET_ADDRESS  \
            _secondary_cold_boot=!COLD_BOOT_SINGLE_CPU  \
            _init_memory=1                  \
            _init_c_runtime=1               \
            _exception_vectors=bl1_exceptions       \
            _pie_fixup_size=0
    
        /* --------------------------------------------------------------------
         * Perform BL1 setup
         * --------------------------------------------------------------------
         */
        bl  bl1_setup
    
    ...
    
    • trusted-firmware-a/bl1/bl1_main.c
    ...
    /*******************************************************************************
     * Setup function for BL1.
     ******************************************************************************/
    void bl1_setup(void)
    {
        /* Perform early platform-specific setup */
        bl1_early_platform_setup();
    
        /* Perform late platform-specific setup */
        bl1_plat_arch_setup();
    
    #if CTX_INCLUDE_PAUTH_REGS
        /*
         * Assert that the ARMv8.3-PAuth registers are present or an access
         * fault will be triggered when they are being saved or restored.
         */
        assert(is_armv8_3_pauth_present());
    #endif /* CTX_INCLUDE_PAUTH_REGS */
    }
    
    /*******************************************************************************
     * Function to perform late architectural and platform specific initialization.
     * It also queries the platform to load and run next BL image. Only called
     * by the primary cpu after a cold boot.
     ******************************************************************************/
    void bl1_main(void)
    {
        unsigned int image_id;
    
        /* Announce our arrival */
        NOTICE(FIRMWARE_WELCOME_STR);
        NOTICE("BL1: %s\n", version_string);
        NOTICE("BL1: %s\n", build_message);
    
        INFO("BL1: RAM %p - %p\n", (void *)BL1_RAM_BASE, (void *)BL1_RAM_LIMIT);
    
        print_errata_status();
    ...
    
    • trusted-firmware-a/include/arch/aarch64/el3_common_macros.S
    ...
    .macro el3_entrypoint_common                    \
         _init_sctlr, _warm_boot_mailbox, _secondary_cold_boot,  \
         _init_memory, _init_c_runtime, _exception_vectors,  \
         _pie_fixup_size
    
     .if \_init_sctlr
         /* -------------------------------------------------------------
          * This is the initialisation of SCTLR_EL3 and so must ensure
          * that all fields are explicitly set rather than relying on hw.
          * Some fields reset to an IMPLEMENTATION DEFINED value and
          * others are architecturally UNKNOWN on reset.
          *
          * SCTLR.EE: Set the CPU endianness before doing anything that
          *  might involve memory reads or writes. Set to zero to select
          *  Little Endian.
          *
          * SCTLR_EL3.WXN: For the EL3 translation regime, this field can
          *  force all memory regions that are writeable to be treated as
          *  XN (Execute-never). Set to zero so that this control has no
          *  effect on memory access permissions.
          *
          * SCTLR_EL3.SA: Set to zero to disable Stack Alignment check.
          *
          * SCTLR_EL3.A: Set to zero to disable Alignment fault checking.
          *
          * SCTLR.DSSBS: Set to zero to disable speculation store bypass
          *  safe behaviour upon exception entry to EL3.
          * -------------------------------------------------------------
          */
         mov_imm x0, (SCTLR_RESET_VAL & ~(SCTLR_EE_BIT | SCTLR_WXN_BIT \
                 | SCTLR_SA_BIT | SCTLR_A_BIT | SCTLR_DSSBS_BIT))
         msr sctlr_el3, x0
         isb
     .endif /* _init_sctlr */
    ...
    
    • trusted-firmware-a/include/arch/aarch64/asm_macros.S
    ...
     /*
      * Helper macro to generate the best mov/movk combinations according
      * the value to be moved. The 16 bits from '_shift' are tested and
      * if not zero, they are moved into '_reg' without affecting
      * other bits.
      */
     .macro _mov_imm16 _reg, _val, _shift
         .if (\_val >> \_shift) & 0xffff
             .if (\_val & (1 << \_shift - 1)) 
                 movk    \_reg, (\_val >> \_shift) & 0xffff, LSL \_shift
             .else
                 mov \_reg, \_val & (0xffff << \_shift)
             .endif
         .endif
     .endm
    
     /*
      * Helper macro to load arbitrary values into 32 or 64-bit registers
      * which generates the best mov/movk combinations. Many base addresses
      * are 64KB aligned the macro will eliminate updating bits 15:0 in
      * that case
      */
     .macro mov_imm _reg, _val
         .if (\_val) == 0
             mov \_reg, #0
         .else
             _mov_imm16  \_reg, (\_val), 0
             _mov_imm16  \_reg, (\_val), 16
             _mov_imm16  \_reg, (\_val), 32
             _mov_imm16  \_reg, (\_val), 48
         .endif
     .endm
    ...
    
    • trusted-firmware-a/include/arch/aarch64/arch.h
    ...
    
    #define SCTLR_EL3_RES1  ((U(1) << 29) | (U(1) << 28) | (U(1) << 23) | \
             (U(1) << 22) | (U(1) << 18) | (U(1) << 16) | \
             (U(1) << 11) | (U(1) << 5) | (U(1) << 4))  # 00110000 11000101 00001000 00110000 
    ...
    #define SCTLR_A_BIT     (ULL(1) << 1)      # 00000000 00000000 00000000 00000010
    ...
    #define SCTLR_SA_BIT        (ULL(1) << 3)  # 00000000 00000000 00000000 00001000
    ...
    #define SCTLR_WXN_BIT       (ULL(1) << 19) # 00000000 00001000 00000000 00000000
    ...   
    #define SCTLR_EE_BIT        (ULL(1) << 25) # 00000010 00000000 00000000 00000000
    ...   
    #define SCTLR_DSSBS_SHIFT   U(44)
    #define SCTLR_DSSBS_BIT     (ULL(1) << SCTLR_DSSBS_SHIFT)
    ...
    #define SCTLR_RESET_VAL		SCTLR_EL3_RES1 # 00110000 10000101 00001000 00110000
    ...
    
    # 00000000 00000000 00010000 00000000 00000000 00000000 00000000 00000000
    # 00000000 00000000 00010000 00000000 00000010 00001000 00000000 00001010
    # 11111111 11111111 11101111 11111111 11111101 11110111 11111111 11110101
                                        # 00110000 10000101 00001000 00110000
    # 00000000 00000000 00000000 00000000 00110000 11000101 00001000 00110000
    #                                        3   0    c   5    0   8    3   0 #0x30c50830
    ...
    
⚠️ **GitHub.com Fallback** ⚠️