123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397 |
- /*
- * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
- * Copyright (c) 2015-2023, Renesas Electronics Corporation. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
- #include <arch.h>
- #include <asm_macros.S>
- #include <common/bl_common.h>
- #include <common/runtime_svc.h>
- #include <cortex_a57.h>
- #include <platform_def.h>
- #include "rcar_def.h"
- .globl plat_get_my_entrypoint
- .extern plat_set_my_stack
- .globl platform_mem_init
- .globl plat_crash_console_init
- .globl plat_crash_console_putc
- .globl plat_crash_console_flush
- .globl plat_invalidate_icache
- .globl plat_report_exception
- .globl plat_secondary_reset
- .globl plat_reset_handler
- .globl plat_my_core_pos
- .extern rcar_log_init
- .extern console_rcar_init
- .extern console_rcar_putc
- .extern console_rcar_flush
- #if IMAGE_BL2
- #define INT_ID_MASK (0x3ff)
- .extern bl2_interrupt_error_type
- .extern bl2_interrupt_error_id
- .globl bl2_enter_bl31
- .extern gicv2_acknowledge_interrupt
- .extern rcar_swdt_exec
- #endif
- /* -----------------------------------------------------
- * void platform_get_core_pos (mpidr)
- * -----------------------------------------------------
- */
- func platform_get_core_pos
- and x1, x0, #MPIDR_CPU_MASK
- and x0, x0, #MPIDR_CLUSTER_MASK
- add x0, x1, x0, LSR #6
- ret
- endfunc platform_get_core_pos
- /* -----------------------------------------------------
- * void platform_my_core_pos
- * -----------------------------------------------------
- */
- func plat_my_core_pos
- mrs x0, mpidr_el1
- b platform_get_core_pos
- endfunc plat_my_core_pos
- /* -----------------------------------------------------
- * void platform_get_my_entrypoint (unsigned int mpid);
- *
- * Main job of this routine is to distinguish between
- * a cold and warm boot.
- * On a cold boot the secondaries first wait for the
- * platform to be initialized after which they are
- * hotplugged in. The primary proceeds to perform the
- * platform initialization.
- * On a warm boot, each cpu jumps to the address in its
- * mailbox.
- *
- * TODO: Not a good idea to save lr in a temp reg
- * -----------------------------------------------------
- */
- func plat_get_my_entrypoint
- mrs x0, mpidr_el1
- mov x9, x30 /* lr */
- #if defined(IMAGE_BL2)
- /* always cold boot on bl2 */
- mov x0, #0
- ret x9
- #else
- ldr x1, =BOOT_KIND_BASE
- ldr x21, [x1]
- /* Check the reset info */
- and x1, x21, #0x000c
- cmp x1, #0x0008
- beq el3_panic
- cmp x1, #0x000c
- beq el3_panic
- /* Check the boot kind */
- and x1, x21, #0x0003
- cmp x1, #0x0002
- beq el3_panic
- cmp x1, #0x0003
- beq el3_panic
- /* warm boot or cold boot */
- and x1, x21, #1
- cmp x1, #0
- bne warm_reset
- /* Cold boot */
- mov x0, #0
- b exit
- warm_reset:
- /* --------------------------------------------------------------------
- * A per-cpu mailbox is maintained in the trusted SDRAM. Its flushed out
- * of the caches after every update using normal memory so its safe to
- * read it here with SO attributes
- * ---------------------------------------------------------------------
- */
- ldr x10, =MBOX_BASE
- bl platform_get_core_pos
- lsl x0, x0, #CACHE_WRITEBACK_SHIFT
- ldr x0, [x10, x0]
- cbz x0, _panic
- exit:
- ret x9
- _panic:
- b el3_panic
- #endif
- endfunc plat_get_my_entrypoint
- /* ---------------------------------------------
- * plat_secondary_reset
- *
- * ---------------------------------------------
- */
- func plat_secondary_reset
- mrs x0, sctlr_el3
- bic x0, x0, #SCTLR_EE_BIT
- msr sctlr_el3, x0
- isb
- mrs x0, cptr_el3
- bic w0, w0, #TCPAC_BIT
- bic w0, w0, #TTA_BIT
- bic w0, w0, #TFP_BIT
- msr cptr_el3, x0
- mov_imm x0, PARAMS_BASE
- mov_imm x2, BL31_BASE
- ldr x3, =BOOT_KIND_BASE
- mov x1, #0x1
- str x1, [x3]
- br x2 /* jump to BL31 */
- nop
- nop
- nop
- endfunc plat_secondary_reset
- /* ---------------------------------------------
- * plat_enter_bl31
- *
- * ---------------------------------------------
- */
- func bl2_enter_bl31
- mov x20, x0
- /*
- * MMU needs to be disabled because both BL2 and BL31 execute
- * in EL3, and therefore share the same address space.
- * BL31 will initialize the address space according to its
- * own requirement.
- */
- /* Disable mmu and data cache */
- bl disable_mmu_el3
- #if RCAR_BL2_DCACHE == 1
- /* Data cache clean and invalidate */
- mov x0, #DCCISW
- bl dcsw_op_all
- #endif /* RCAR_BL2_DCACHE == 1 */
- /* TLB invalidate all, EL3 */
- tlbi alle3
- bl disable_mmu_icache_el3
- /* Invalidate instruction cache */
- ic iallu
- dsb sy
- isb
- ldp x0, x1, [x20, #ENTRY_POINT_INFO_PC_OFFSET]
- msr elr_el3, x0
- msr spsr_el3, x1
- exception_return
- endfunc bl2_enter_bl31
- /* -----------------------------------------------------
- * void platform_mem_init (void);
- *
- * Zero out the mailbox registers in the shared memory
- * and set the rcar_boot_kind_flag.
- * The mmu is turned off right now and only the primary can
- * ever execute this code. Secondaries will read the
- * mailboxes using SO accesses.
- * -----------------------------------------------------
- */
- func platform_mem_init
- #if !IMAGE_BL2
- ldr x0, =MBOX_BASE
- mov w1, #PLATFORM_CORE_COUNT
- loop:
- str xzr, [x0], #CACHE_WRITEBACK_GRANULE
- subs w1, w1, #1
- b.gt loop
- #endif
- ret
- endfunc platform_mem_init
- /* ---------------------------------------------
- * void plat_report_exception(unsigned int type)
- * Function to report an unhandled exception
- * with platform-specific means.
- * ---------------------------------------------
- */
- func plat_report_exception
- /* Switch to SP_EL0 */
- msr spsel, #0
- #if IMAGE_BL2
- mov w1, #FIQ_SP_EL0
- cmp w0, w1
- beq rep_exec_fiq_elx
- b rep_exec_panic_type
- rep_exec_fiq_elx:
- bl gicv2_acknowledge_interrupt
- mov x2, #INT_ID_MASK
- and x0, x0, x2
- mov x1, #ARM_IRQ_SEC_WDT
- cmp x0, x1
- bne rep_exec_panic_id
- mrs x0, ELR_EL3
- b rcar_swdt_exec
- rep_exec_panic_type:
- /* x0 is interrupt TYPE */
- b bl2_interrupt_error_type
- rep_exec_panic_id:
- /* x0 is interrupt ID */
- b bl2_interrupt_error_id
- rep_exec_end:
- #endif
- ret
- endfunc plat_report_exception
- /* ---------------------------------------------
- * int plat_crash_console_init(void)
- * Function to initialize log area
- * ---------------------------------------------
- */
- func plat_crash_console_init
- #if IMAGE_BL2
- mov x0, #0
- #else
- mov x1, sp
- mov_imm x2, RCAR_CRASH_STACK
- mov sp, x2
- str x1, [sp, #-16]!
- str x30, [sp, #-16]!
- bl console_rcar_init
- ldr x30, [sp], #16
- ldr x1, [sp], #16
- mov sp, x1
- #endif
- ret
- endfunc plat_crash_console_init
- /* ---------------------------------------------
- * int plat_crash_console_putc(int c)
- * Function to store a character to log area
- * ---------------------------------------------
- */
- func plat_crash_console_putc
- mov x1, sp
- mov_imm x2, RCAR_CRASH_STACK
- mov sp, x2
- str x1, [sp, #-16]!
- str x30, [sp, #-16]!
- str x3, [sp, #-16]!
- str x4, [sp, #-16]!
- str x5, [sp, #-16]!
- str x6, [sp, #-16]!
- str x7, [sp, #-16]!
- bl console_rcar_putc
- ldr x7, [sp], #16
- ldr x6, [sp], #16
- ldr x5, [sp], #16
- ldr x4, [sp], #16
- ldr x3, [sp], #16
- ldr x30, [sp], #16
- ldr x1, [sp], #16
- mov sp, x1
- ret
- endfunc plat_crash_console_putc
- /* ---------------------------------------------
- * void plat_crash_console_flush()
- * ---------------------------------------------
- */
- func plat_crash_console_flush
- b console_rcar_flush
- endfunc plat_crash_console_flush
- /* --------------------------------------------------------------------
- * void plat_reset_handler(void);
- *
- * Before adding code in this function, refer to the guidelines in
- * docs/firmware-design.md to determine whether the code should reside
- * within the FIRST_RESET_HANDLER_CALL block or not.
- *
- * For R-Car H3:
- * - Set the L2 Tag RAM latency to 2 (i.e. 3 cycles) for Cortex-A57
- * - Set the L2 Data setup latency to 1 (i.e. 1 cycles) for Cortex-A57
- * - Set the L2 Data RAM latency to 3 (i.e. 4 cycles) for Cortex-A57
- * For R-Car M3/M3N:
- * - Set the L2 Tag RAM latency to 2 (i.e. 3 cycles) for Cortex-A57
- * - Set the L2 Data setup latency to 0 (i.e. 0 cycles) for Cortex-A57
- * - Set the L2 Data RAM latency to 3 (i.e. 4 cycles) for Cortex-A57
- *
- * --------------------------------------------------------------------
- */
- func plat_reset_handler
- /*
- * On R-Car H3 : x2 := 0
- * On R-Car M3/M3N: x2 := 1
- */
- /* read PRR */
- ldr x0, =0xFFF00044
- ldr w0, [x0]
- ubfx w0, w0, 8, 8
- /* H3? */
- cmp w0, #0x4F
- b.eq RCARH3
- /* set R-Car M3/M3N */
- mov x2, #1
- b CHK_A5x
- RCARH3:
- /* set R-Car H3 */
- mov x2, #0
- /* --------------------------------------------------------------------
- * Determine whether this code is executed on a Cortex-A53 or on a
- * Cortex-A57 core.
- * --------------------------------------------------------------------
- */
- CHK_A5x:
- mrs x0, midr_el1
- ubfx x1, x0, MIDR_PN_SHIFT, #12
- cmp w1, #((CORTEX_A57_MIDR >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
- b.eq A57
- ret
- A57:
- /* Get data from CORTEX_A57_L2CTLR_EL1 */
- mrs x0, CORTEX_A57_L2CTLR_EL1
- /*
- * On R-Car H3/M3/M3N
- *
- * L2 Tag RAM latency is bit8-6 of CORTEX_A57_L2CTLR_EL1
- * L2 Data RAM setup is bit5 of CORTEX_A57_L2CTLR_EL1
- * L2 Data RAM latency is bit2-0 of CORTEX_A57_L2CTLR_EL1
- */
- /* clear bit of L2 RAM */
- /* ~(0x1e7) -> x1 */
- mov x1, #0x1e7
- neg x1, x1
- /* clear bit of L2 RAM -> x0 */
- and x0, x0, x1
- /* L2 Tag RAM latency (3 cycles) */
- orr x0, x0, #0x2 << 6
- /* If M3/M3N then L2 RAM setup is 0 */
- cbnz x2, M3_L2
- /* L2 Data RAM setup (1 cycle) */
- orr x0, x0, #0x1 << 5
- M3_L2:
- /* L2 Data RAM latency (4 cycles) */
- orr x0, x0, #0x3
- /* Store data to L2CTLR_EL1 */
- msr CORTEX_A57_L2CTLR_EL1, x0
- apply_l2_ram_latencies:
- ret
- endfunc plat_reset_handler
- /* ---------------------------------------------
- * void plat_invalidate_icache(void)
- * Instruction Cache Invalidate All to PoU
- * ---------------------------------------------
- */
- func plat_invalidate_icache
- ic iallu
- ret
- endfunc plat_invalidate_icache
|