| /* |
| * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. |
| * Copyright 2017 NXP |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are met: |
| * |
| * Redistributions of source code must retain the above copyright notice, this |
| * list of conditions and the following disclaimer. |
| * |
| * Redistributions in binary form must reproduce the above copyright notice, |
| * this list of conditions and the following disclaimer in the documentation |
| * and/or other materials provided with the distribution. |
| * |
| * Neither the name of ARM nor the names of its contributors may be used |
| * to endorse or promote products derived from this software without specific |
| * prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
| * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| * POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #include <arch_helpers.h> |
| #include <assert.h> |
| #include <bl_common.h> |
| #include <console.h> |
| #include <context.h> |
| #include <context_mgmt.h> |
| #include <debug.h> |
| #include <stdbool.h> |
| #include <mmio.h> |
| #include <platform.h> |
| #include <platform_def.h> |
| #include <plat_imx8.h> |
| #include <xlat_tables.h> |
| #include <soc.h> |
| #include <tzc380.h> |
| |
| /* linker defined symbols */ |
| #if USE_COHERENT_MEM |
| #define BL31_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__) |
| #define BL31_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__) |
| #endif |
| |
| #define BL31_RO_BASE (unsigned long)(&__RO_START__) |
| #define BL31_RO_LIMIT (unsigned long)(&__RO_END__) |
| #define BL31_END (unsigned long)(&__BL31_END__) |
| |
| static entry_point_info_t bl32_image_ep_info; |
| static entry_point_info_t bl33_image_ep_info; |
| |
| /* get SPSR for BL33 entry */ |
| static uint32_t get_spsr_for_bl33_entry(void) |
| { |
| unsigned long el_status; |
| unsigned long mode; |
| uint32_t spsr; |
| |
| /* figure out what mode we enter the non-secure world */ |
| el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT; |
| el_status &= ID_AA64PFR0_ELX_MASK; |
| |
| mode = (el_status) ? MODE_EL2 : MODE_EL1; |
| |
| spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); |
| return spsr; |
| } |
| |
| #define SCTR_BASE_ADDR 0x306c0000 |
| #define CNTFID0_OFF 0x20 |
| #define CNTFID1_OFF 0x24 |
| |
| #define SC_CNTCR_ENABLE (1 << 0) |
| #define SC_CNTCR_HDBG (1 << 1) |
| #define SC_CNTCR_FREQ0 (1 << 8) |
| #define SC_CNTCR_FREQ1 (1 << 9) |
| |
| #define GPR_TZASC_EN (1 << 0) |
| #define GPR_TZASC_EN_LOCK (1 << 16) |
| unsigned int freq; |
| |
| void system_counter_init(void) |
| { |
| int val; |
| |
| /* Update with accurate clock frequency */ |
| freq = mmio_read_32(SCTR_BASE_ADDR + CNTFID0_OFF); |
| |
| val = mmio_read_32(SCTR_BASE_ADDR + CNTCR_OFF); |
| val &= ~(SC_CNTCR_FREQ0 | SC_CNTCR_FREQ1); |
| val |= SC_CNTCR_FREQ0 | SC_CNTCR_ENABLE | SC_CNTCR_HDBG; |
| mmio_write_32(SCTR_BASE_ADDR + CNTCR_OFF, val); |
| } |
| |
| void bl31_tzc380_setup(void) |
| { |
| unsigned int val; |
| |
| val = mmio_read_32(IMX_IOMUX_GPR_BASE + 0x28); |
| if ((val & GPR_TZASC_EN) != GPR_TZASC_EN) |
| return; |
| |
| NOTICE("Configureing TZASC380\n"); |
| |
| tzc380_init(IMX_TZASC_BASE); |
| |
| /* |
| * Need to substact offset 0x40000000 from CPU address when |
| * programming tzasc region for i.mx8mq. |
| */ |
| |
| /* Enable 1G-5G S/NS RW */ |
| tzc380_configure_region(0, 0x00000000, TZC_ATTR_REGION_SIZE(TZC_REGION_SIZE_4G) | TZC_ATTR_REGION_EN_MASK | TZC_ATTR_SP_ALL); |
| /* Enable 0x40000000 - 0x40020000 S RW */ |
| tzc380_configure_region(1, 0x00000000, TZC_ATTR_REGION_SIZE(TZC_REGION_SIZE_128K) | TZC_ATTR_REGION_EN_MASK | TZC_ATTR_SP_S_RW); |
| |
| tzc380_dump_state(); |
| } |
| |
| void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, |
| u_register_t arg2, u_register_t arg3) |
| { |
| int i; |
| /* enable CSU NS access permission */ |
| for (i = 0; i < 64; i++) { |
| mmio_write_32(0x303e0000 + i * 4, 0xffffffff); |
| } |
| |
| mmio_write_32(0x303a00ec, 0x0000ffff); |
| /* Power up VPU, DISP, GPU etc */ |
| mmio_write_32(0x303a00f8, 0x3fef); |
| |
| /* config the AIPSTZ1 */ |
| mmio_write_32(0x301f0000, 0x77777777); |
| mmio_write_32(0x301f0004, 0x77777777); |
| mmio_write_32(0x301f0040, 0x0); |
| mmio_write_32(0x301f0044, 0x0); |
| mmio_write_32(0x301f0048, 0x0); |
| mmio_write_32(0x301f004c, 0x0); |
| mmio_write_32(0x301f0050, 0x0); |
| |
| /* config the AIPSTZ2 */ |
| mmio_write_32(0x305f0000, 0x77777777); |
| mmio_write_32(0x305f0004, 0x77777777); |
| mmio_write_32(0x305f0040, 0x0); |
| mmio_write_32(0x305f0044, 0x0); |
| mmio_write_32(0x305f0048, 0x0); |
| mmio_write_32(0x305f004c, 0x0); |
| mmio_write_32(0x305f0050, 0x0); |
| |
| /* config the AIPSTZ3 */ |
| mmio_write_32(0x309f0000, 0x77777777); |
| mmio_write_32(0x309f0004, 0x77777777); |
| mmio_write_32(0x309f0040, 0x0); |
| mmio_write_32(0x309f0044, 0x0); |
| mmio_write_32(0x309f0048, 0x0); |
| mmio_write_32(0x309f004c, 0x0); |
| mmio_write_32(0x309f0050, 0x0); |
| |
| /* config the AIPSTZ4 */ |
| mmio_write_32(0x32df0000, 0x77777777); |
| mmio_write_32(0x32df0004, 0x77777777); |
| mmio_write_32(0x32df0040, 0x0); |
| mmio_write_32(0x32df0044, 0x0); |
| mmio_write_32(0x32df0048, 0x0); |
| mmio_write_32(0x32df004c, 0x0); |
| mmio_write_32(0x32df0050, 0x0); |
| |
| #if DEBUG_CONSOLE |
| console_init(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ, |
| IMX_CONSOLE_BAUDRATE); |
| #endif |
| /* enable the system counter */ |
| system_counter_init(); |
| |
| /* |
| * tell BL3-1 where the non-secure software image is located |
| * and the entry state information. |
| */ |
| bl33_image_ep_info.pc = PLAT_NS_IMAGE_OFFSET; |
| bl33_image_ep_info.spsr = get_spsr_for_bl33_entry(); |
| SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); |
| |
| bl31_tzc380_setup(); |
| } |
| |
| void bl31_plat_arch_setup(void) |
| { |
| /* add the mmap */ |
| mmap_add_region(BL31_BASE, BL31_BASE, 0x10000, |
| MT_MEMORY | MT_RW); |
| mmap_add_region(BL31_BASE, BL31_BASE, BL31_RO_LIMIT - BL31_RO_BASE, |
| MT_MEMORY | MT_RO); |
| mmap_add_region(IMX_BOOT_UART_BASE, IMX_BOOT_UART_BASE, |
| 0x1000, MT_DEVICE | MT_RW); |
| mmap_add_region(IMX_SRC_BASE, IMX_SRC_BASE, |
| 0x1000, MT_DEVICE | MT_RW); |
| mmap_add_region(IMX_GPC_BASE, IMX_GPC_BASE, 0x1000, MT_DEVICE | MT_RW); |
| mmap_add_region(IMX_WDOG_BASE, IMX_WDOG_BASE, 0x1000, MT_DEVICE | MT_RW); |
| mmap_add_region(IMX_IOMUX_GPR_BASE, IMX_IOMUX_GPR_BASE, 0x1000, MT_DEVICE | MT_RW); |
| mmap_add_region(IMX_ANAMIX_BASE, IMX_ANAMIX_BASE, 0x1000, MT_DEVICE | MT_RW); |
| mmap_add_region(IMX_SNVS_BASE, IMX_SNVS_BASE, 0x1000, MT_DEVICE | MT_RW); |
| mmap_add_region(PLAT_GICD_BASE, PLAT_GICD_BASE, 0x80000, |
| MT_DEVICE | MT_RW); |
| mmap_add_region(PLAT_GICR_BASE, PLAT_GICR_BASE, 0x80000, |
| MT_DEVICE | MT_RW); |
| #if USE_COHERENT_MEM |
| mmap_add_region(BL31_COHERENT_RAM_BASE, BL31_COHERENT_RAM_BASE, |
| BL31_COHERENT_RAM_LIMIT - BL31_COHERENT_RAM_BASE, |
| MT_DEVICE | MT_RW); |
| #endif |
| |
| /* setup xlat table */ |
| init_xlat_tables(); |
| |
| /* enable the MMU */ |
| enable_mmu_el3(0); |
| } |
| |
| void bl31_platform_setup(void) |
| { |
| /* init the GICv3 cpu and distributor interface */ |
| plat_gic_driver_init(); |
| plat_gic_init(); |
| |
| /* gpc init */ |
| imx_gpc_init(); |
| } |
| |
| entry_point_info_t *bl31_plat_get_next_image_ep_info(unsigned int type) |
| { |
| if (type == NON_SECURE) |
| return &bl33_image_ep_info; |
| if (type == SECURE) |
| return &bl32_image_ep_info; |
| |
| return NULL; |
| } |
| |
| unsigned int plat_get_syscnt_freq2(void) |
| { |
| return freq; |
| } |
| |
| void bl31_plat_runtime_setup(void) |
| { |
| return; |
| } |