diff --git a/plat/imx/common/imx8_helpers.S b/plat/imx/common/imx8_helpers.S new file mode 100644 index 0000000..b89d346 --- /dev/null +++ b/plat/imx/common/imx8_helpers.S @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + + .globl plat_is_my_cpu_primary + .globl plat_my_core_pos + .globl plat_calc_core_pos + .globl plat_reset_handler + .globl plat_get_my_entrypoint + .globl plat_secondary_cold_boot_setup + .globl plat_crash_console_init + .globl plat_crash_console_putc + .globl platform_mem_init + .globl imx_mailbox_init + + /* -------------------------------------------------------------------- + * Helper macro that reads the part number of the current CPU and jumps + * to the given label if it matches the CPU MIDR provided. + * + * Clobbers x0. + * -------------------------------------------------------------------- + */ + .macro jump_if_cpu_midr _cpu_midr, _label + + mrs x0, midr_el1 + ubfx x0, x0, MIDR_PN_SHIFT, #12 + cmp w0, #((\_cpu_midr >> MIDR_PN_SHIFT) & MIDR_PN_MASK) + b.eq \_label + + .endm + + /* ---------------------------------------------- + * The mailbox_base is used to distinguish warm/cold + * reset. The mailbox_base is in the data section, not + * in .bss, this allows function to start using this + * variable before the runtime memory is initialized. + * ---------------------------------------------- + */ + .section .data.mailbox_base + .align 3 + mailbox_base: .quad 0x0 + + /* ---------------------------------------------- + * unsigned int plat_is_my_cpu_primary(void); + * This function checks if this is the primary CPU + * ---------------------------------------------- + */ +func plat_is_my_cpu_primary + mrs x0, mpidr_el1 + and x0, x0, #(MPIDR_CPU_MASK) + cmp x0, #PLAT_PRIMARY_CPU + cset x0, eq + ret +endfunc plat_is_my_cpu_primary + + /* ---------------------------------------------- + * unsigned int plat_my_core_pos(void) + * This Function uses the plat_calc_core_pos() + * to get the index of the calling CPU. + * ---------------------------------------------- + */ +func plat_my_core_pos + mrs x0, mpidr_el1 + and x1, x0, #MPIDR_CPU_MASK + and x0, x0, #MPIDR_CLUSTER_MASK + add x0, x1, x0, LSR #6 + ret +endfunc plat_my_core_pos + + /* + * unsigned int plat_calc_core_pos(uint64_t mpidr) + * helper function to calculate the core position. + * With this function. + */ +func plat_calc_core_pos + and x1, x0, #MPIDR_CPU_MASK + and x0, x0, #MPIDR_CLUSTER_MASK + add x0, x1, x0, LSR #6 + ret +endfunc plat_calc_core_pos + + /* --------------------------------------------- + * function to get the entrypoint. + * --------------------------------------------- + */ +func plat_get_my_entrypoint + adrp x1, mailbox_base + ldr x0, [x1, :lo12:mailbox_base] + ret +endfunc plat_get_my_entrypoint + +func imx_mailbox_init + adrp x1, mailbox_base + str x0, [x1, :lo12:mailbox_base] + ret +endfunc imx_mailbox_init + +func plat_secondary_cold_boot_setup + b . +endfunc plat_secondary_cold_boot_setup + +func plat_crash_console_init + ret +endfunc plat_crash_console_init + +func plat_crash_console_putc + ret +endfunc plat_crash_console_putc + +func platform_mem_init + ret +endfunc platform_mem_init diff --git a/plat/imx/common/imx8_topology.c b/plat/imx/common/imx8_topology.c new file mode 100644 index 0000000..bcb7d59 --- /dev/null +++ b/plat/imx/common/imx8_topology.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +const unsigned char imx_power_domain_tree_desc[] = { + PWR_DOMAIN_AT_MAX_LVL, + PLATFORM_CLUSTER_COUNT, + PLATFORM_CORE_COUNT, +}; + +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + return imx_power_domain_tree_desc; +} + +int plat_core_pos_by_mpidr(u_register_t mpidr) +{ + unsigned int cluster_id, cpu_id; + + mpidr &= MPIDR_AFFINITY_MASK; + + if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) + return -1; + + cluster_id = MPIDR_AFFLVL1_VAL(mpidr); + cpu_id = MPIDR_AFFLVL0_VAL(mpidr); + + if (cluster_id > PLATFORM_CLUSTER_COUNT || + cpu_id > PLATFORM_MAX_CPU_PER_CLUSTER) + return -1; + + return (cpu_id + (cluster_id * 4)); +} diff --git a/plat/imx/common/include/plat_imx8.h b/plat/imx/common/include/plat_imx8.h new file mode 100644 index 0000000..27d4c37 --- /dev/null +++ b/plat/imx/common/include/plat_imx8.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __PLAT_IMX8_H__ +#define __PLAT_IMX8_H__ + +#include + +unsigned int plat_calc_core_pos(uint64_t mpidr); +void imx_mailbox_init(uintptr_t base_addr); +void plat_gic_driver_init(void); +void plat_gic_init(void); +void plat_gic_cpuif_enable(void); +void plat_gic_cpuif_disable(void); +void plat_gic_pcpu_init(void); + +#endif /*__PLAT_IMX8_H__ */ diff --git a/plat/imx/common/include/plat_macros.S b/plat/imx/common/include/plat_macros.S new file mode 100644 index 0000000..30cce0a --- /dev/null +++ b/plat/imx/common/include/plat_macros.S @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * the below macros print out relevant GIC + * registers whenever an unhandled exception is + * taken in BL3-1 + */ +.macro plat_print_gic_regs + /* TODO */ +.endm + +/* + * the below macros print out relevant interconnect + * registers whenever an unhandled exception is + * taken in BL3-1 + */ +.macro plat_print_interconnect_regs + /* TODO */ +.endm + +/* --------------------------------------------- + * The below required platform porting macro + * prints out relevant platform registers + * whenever an unhandled exception is taken in + * BL31. + * --------------------------------------------- + */ +.macro plat_crash_print_regs + /* TODO */ +.endm diff --git a/plat/imx/common/plat_imx8_gic.c b/plat/imx/common/plat_imx8_gic.c new file mode 100644 index 0000000..242e31b --- /dev/null +++ b/plat/imx/common/plat_imx8_gic.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include + +/* the GICv3 driver only needs to be initialized in EL3 */ +uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT]; + +/* array of Group1 secure interrupts to be configured by the gic driver */ +const unsigned int g1s_interrupt_array[] = { 6 }; + +/* array of Group0 interrupts to be configured by the gic driver */ +const unsigned int g0_interrupt_array[] = { 7 }; + +static unsigned int plat_imx_mpidr_to_core_pos(unsigned long mpidr) +{ + return (unsigned int)plat_core_pos_by_mpidr(mpidr); +} + +const gicv3_driver_data_t arm_gic_data = { + .gicd_base = PLAT_GICD_BASE, + .gicr_base = PLAT_GICR_BASE, + .g0_interrupt_num = ARRAY_SIZE(g0_interrupt_array), + .g1s_interrupt_num = ARRAY_SIZE(g1s_interrupt_array), + .g0_interrupt_array = g0_interrupt_array, + .g1s_interrupt_array = g1s_interrupt_array, + .rdistif_num = PLATFORM_CORE_COUNT, + .rdistif_base_addrs = rdistif_base_addrs, + .mpidr_to_core_pos = plat_imx_mpidr_to_core_pos, +}; + +void plat_gic_driver_init(void) +{ + /* + * the GICv3 driver is initialized in EL3 and does not need + * to be initialized again in S-EL1. This is because the S-EL1 + * can use GIC system registers to manage interrupts and does + * not need GIC interface base addresses to be configured. + */ +#if IMAGE_BL31 + gicv3_driver_init(&arm_gic_data); +#endif +} + +void plat_gic_init(void) +{ + gicv3_distif_init(); + gicv3_rdistif_init(plat_my_core_pos()); + gicv3_cpuif_enable(plat_my_core_pos()); +} + +void plat_gic_cpuif_enable(void) +{ + gicv3_cpuif_enable(plat_my_core_pos()); +} + +void plat_gic_cpuif_disable(void) +{ + gicv3_cpuif_disable(plat_my_core_pos()); +} + +void plat_gic_pcpu_init(void) +{ + gicv3_rdistif_init(plat_my_core_pos()); +}