Home | History | Annotate | Download | only in poplar
      1 /*
      2  * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
      3  *
      4  * SPDX-License-Identifier: BSD-3-Clause
      5  */
      6 
      7 #include <arch_helpers.h>
      8 #include <assert.h>
      9 #include <bl_common.h>
     10 #include <console.h>
     11 #include <debug.h>
     12 #include <errno.h>
     13 #include <generic_delay_timer.h>
     14 #include <mmio.h>
     15 #include <partition/partition.h>
     16 #include <platform.h>
     17 #include <string.h>
     18 #include "hi3798cv200.h"
     19 #include "plat_private.h"
     20 
     21 /* Memory ranges for code and read only data sections */
     22 #define BL2_RO_BASE	(unsigned long)(&__RO_START__)
     23 #define BL2_RO_LIMIT	(unsigned long)(&__RO_END__)
     24 
     25 /* Memory ranges for coherent memory section */
     26 #define BL2_COHERENT_RAM_BASE	(unsigned long)(&__COHERENT_RAM_START__)
     27 #define BL2_COHERENT_RAM_LIMIT	(unsigned long)(&__COHERENT_RAM_END__)
     28 
     29 typedef struct bl2_to_bl31_params_mem {
     30 	bl31_params_t		bl31_params;
     31 	image_info_t		bl31_image_info;
     32 	image_info_t		bl33_image_info;
     33 	entry_point_info_t	bl33_ep_info;
     34 	entry_point_info_t	bl31_ep_info;
     35 } bl2_to_bl31_params_mem_t;
     36 
     37 static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
     38 static bl2_to_bl31_params_mem_t bl31_params_mem;
     39 
     40 meminfo_t *bl2_plat_sec_mem_layout(void)
     41 {
     42 	return &bl2_tzram_layout;
     43 }
     44 
     45 bl31_params_t *bl2_plat_get_bl31_params(void)
     46 {
     47 	bl31_params_t *bl2_to_bl31_params = NULL;
     48 
     49 	/*
     50 	 * Initialise the memory for all the arguments that needs to
     51 	 * be passed to BL3-1
     52 	 */
     53 	memset(&bl31_params_mem, 0, sizeof(bl2_to_bl31_params_mem_t));
     54 
     55 	/* Assign memory for TF related information */
     56 	bl2_to_bl31_params = &bl31_params_mem.bl31_params;
     57 	SET_PARAM_HEAD(bl2_to_bl31_params, PARAM_BL31, VERSION_1, 0);
     58 
     59 	/* Fill BL3-1 related information */
     60 	bl2_to_bl31_params->bl31_image_info = &bl31_params_mem.bl31_image_info;
     61 	SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info,
     62 		       PARAM_IMAGE_BINARY, VERSION_1, 0);
     63 
     64 	/* Fill BL3-3 related information */
     65 	bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem.bl33_ep_info;
     66 	SET_PARAM_HEAD(bl2_to_bl31_params->bl33_ep_info,
     67 		       PARAM_EP, VERSION_1, 0);
     68 
     69 	/* BL3-3 expects to receive the primary CPU MPID (through x0) */
     70 	bl2_to_bl31_params->bl33_ep_info->args.arg0 = 0xffff & read_mpidr();
     71 
     72 	bl2_to_bl31_params->bl33_image_info = &bl31_params_mem.bl33_image_info;
     73 	SET_PARAM_HEAD(bl2_to_bl31_params->bl33_image_info,
     74 		       PARAM_IMAGE_BINARY, VERSION_1, 0);
     75 
     76 	return bl2_to_bl31_params;
     77 }
     78 
     79 struct entry_point_info *bl2_plat_get_bl31_ep_info(void)
     80 {
     81 	return &bl31_params_mem.bl31_ep_info;
     82 }
     83 
     84 void bl2_plat_set_bl31_ep_info(image_info_t *image,
     85 			       entry_point_info_t *bl31_ep_info)
     86 {
     87 	SET_SECURITY_STATE(bl31_ep_info->h.attr, SECURE);
     88 	bl31_ep_info->spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
     89 				     DISABLE_ALL_EXCEPTIONS);
     90 }
     91 
     92 static uint32_t hisi_get_spsr_for_bl33_entry(void)
     93 {
     94 	unsigned long el_status;
     95 	unsigned int mode;
     96 	uint32_t spsr;
     97 
     98 	/* Figure out what mode we enter the non-secure world in */
     99 	el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
    100 	el_status &= ID_AA64PFR0_ELX_MASK;
    101 
    102 	mode = (el_status) ? MODE_EL2 : MODE_EL1;
    103 
    104 	/*
    105 	 * TODO: Consider the possibility of specifying the SPSR in
    106 	 * the FIP ToC and allowing the platform to have a say as
    107 	 * well.
    108 	 */
    109 	spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
    110 	return spsr;
    111 }
    112 
    113 void bl2_plat_set_bl33_ep_info(image_info_t *image,
    114 			       entry_point_info_t *bl33_ep_info)
    115 {
    116 	SET_SECURITY_STATE(bl33_ep_info->h.attr, NON_SECURE);
    117 	bl33_ep_info->spsr = hisi_get_spsr_for_bl33_entry();
    118 	bl33_ep_info->args.arg2 = image->image_size;
    119 }
    120 
    121 void bl2_plat_flush_bl31_params(void)
    122 {
    123 	flush_dcache_range((unsigned long)&bl31_params_mem,
    124 			   sizeof(bl2_to_bl31_params_mem_t));
    125 }
    126 
    127 void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo)
    128 {
    129 	bl33_meminfo->total_base = DDR_BASE;
    130 	bl33_meminfo->total_size = DDR_SIZE;
    131 	bl33_meminfo->free_base  = DDR_BASE;
    132 	bl33_meminfo->free_size  = DDR_SIZE;
    133 }
    134 
    135 void bl2_early_platform_setup(meminfo_t *mem_layout)
    136 {
    137 	console_init(PL011_UART0_BASE, PL011_UART0_CLK_IN_HZ, PL011_BAUDRATE);
    138 
    139 	/* Enable arch timer */
    140 	generic_delay_timer_init();
    141 
    142 	bl2_tzram_layout = *mem_layout;
    143 }
    144 
    145 void bl2_plat_arch_setup(void)
    146 {
    147 	plat_configure_mmu_el1(bl2_tzram_layout.total_base,
    148 			       bl2_tzram_layout.total_size,
    149 			       BL2_RO_BASE,
    150 			       BL2_RO_LIMIT,
    151 			       BL2_COHERENT_RAM_BASE,
    152 			       BL2_COHERENT_RAM_LIMIT);
    153 }
    154 
    155 void bl2_platform_setup(void)
    156 {
    157 	plat_io_setup();
    158 }
    159 
    160 unsigned long plat_get_ns_image_entrypoint(void)
    161 {
    162 	return PLAT_ARM_NS_IMAGE_OFFSET;
    163 }
    164