/*
 * Copyright (c) 2013, ARM Limited. All rights reserved.
 *
 * 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 <stdio.h>
#include <string.h>
#include <assert.h>
#include <arch_helpers.h>
#include <console.h>
#include <platform.h>
#include <semihosting.h>
#include <bl_common.h>
#include <bl2.h>

/*******************************************************************************
 * The only thing to do in BL2 is to load further images and pass control to
 * BL31. The memory occupied by BL2 will be reclaimed by BL3_x stages. BL2 runs
 * entirely in S-EL1. Since arm standard c libraries are not PIC, printf et al
 * are not available. We rely on assertions to signal error conditions
 ******************************************************************************/
void bl2_main(void)
{
	meminfo bl2_tzram_layout, *bl31_tzram_layout;
	el_change_info *ns_image_info;
	unsigned long bl31_base, el_status;
	unsigned int bl2_load, bl31_load, mode;

	/* Perform remaining generic architectural setup in S-El1 */
	bl2_arch_setup();

	/* Perform platform setup in BL1 */
	bl2_platform_setup();

#if defined (__GNUC__)
	printf("BL2 Built : %s, %s\n\r", __TIME__, __DATE__);
#endif

	/* Find out how much free trusted ram remains after BL2 load */
	bl2_tzram_layout = bl2_get_sec_mem_layout();

	/*
	 * Load BL31. BL1 tells BL2 whether it has been TOP or BOTTOM loaded.
	 * To avoid fragmentation of trusted SRAM memory, BL31 is always
	 * loaded opposite to BL2. This allows BL31 to reclaim BL2 memory
	 * while maintaining its free space in one contiguous chunk.
	 */
	bl2_load = bl2_tzram_layout.attr & LOAD_MASK;
	assert((bl2_load == TOP_LOAD) || (bl2_load == BOT_LOAD));
	bl31_load = (bl2_load == TOP_LOAD) ? BOT_LOAD : TOP_LOAD;
	bl31_base = load_image(&bl2_tzram_layout, BL31_IMAGE_NAME,
	                       bl31_load, BL31_BASE);

	/* Assert if it has not been possible to load BL31 */
	assert(bl31_base != 0);

	/*
	 * Create a new layout of memory for BL31 as seen by BL2. This
	 * will gobble up all the BL2 memory.
	 */
	bl31_tzram_layout = (meminfo *) get_el_change_mem_ptr();
	init_bl31_mem_layout(&bl2_tzram_layout, bl31_tzram_layout, bl31_load);

	/*
	 * BL2 also needs to tell BL31 where the non-trusted software image
	 * has been loaded. Place this info right after the BL31 memory layout
	 */
	ns_image_info = (el_change_info *) ((unsigned char *) bl31_tzram_layout
					      + sizeof(meminfo));

	/*
	 * Assume that the non-secure bootloader has already been
	 * loaded to its platform-specific location.
	 */
	ns_image_info->entrypoint = plat_get_ns_image_entrypoint();

	/* Figure out what mode we enter the non-secure world in */
	el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
	el_status &= ID_AA64PFR0_ELX_MASK;

	if (el_status)
		mode = MODE_EL2;
	else
		mode = MODE_EL1;

	ns_image_info->spsr = make_spsr(mode, MODE_SP_ELX, MODE_RW_64);
	ns_image_info->security_state = NON_SECURE;
	flush_dcache_range((unsigned long) ns_image_info,
			   sizeof(el_change_info));

	/*
	 * Run BL31 via an SMC to BL1. Information on how to pass control to
	 * the non-trusted software image will be passed to BL31 in x2.
	 */
	if (bl31_base)
		run_image(bl31_base,
			  make_spsr(MODE_EL3, MODE_SP_ELX, MODE_RW_64),
			  SECURE,
			  bl31_tzram_layout,
			  (void *) ns_image_info);

	/* There is no valid reason for run_image() to return */
	assert(0);
}

/*******************************************************************************
 * BL1 has this function to print the fact that BL2 has done its job and BL31 is
 * about to be loaded. Since BL2 re-uses BL1's exception table, it needs to
 * define this function as well.
 * TODO: Remove this function from BL2.
 ******************************************************************************/
void display_boot_progress(unsigned long entrypoint,
			   unsigned long spsr,
			   unsigned long mem_layout,
			   unsigned long ns_image_info)
{
	return;
}
