예제 #1
0
/*******************************************************************************
 * This function programs EL3 registers and performs other setup to enable entry
 * into the next image after BL31 at the next ERET.
 ******************************************************************************/
void bl31_prepare_next_image_entry()
{
	el_change_info_t *next_image_info;
	uint32_t scr, image_type;

	/* Determine which image to execute next */
	image_type = bl31_get_next_image_type();

	/*
	 * Setup minimal architectural state of the next highest EL to
	 * allow execution in it immediately upon entering it.
	 */
	bl31_next_el_arch_setup(image_type);

	/* Program EL3 registers to enable entry into the next EL */
	next_image_info = bl31_get_next_image_info(image_type);
	assert(next_image_info);

	scr = read_scr();
	if (image_type == NON_SECURE)
		scr |= SCR_NS_BIT;

	/*
	 * Tell the context mgmt. library to ensure that SP_EL3 points to
	 * the right context to exit from EL3 correctly.
	 */
	cm_set_el3_eret_context(next_image_info->security_state,
			next_image_info->entrypoint,
			next_image_info->spsr,
			scr);

	/* Finally set the next context */
	cm_set_next_eret_context(next_image_info->security_state);
}
예제 #2
0
/*******************************************************************************
 * BL31 is responsible for setting up the runtime services for the primary cpu
 * before passing control to the bootloader (UEFI) or Linux. This function calls
 * runtime_svc_init() which initializes all registered runtime services. The run
 * time services would setup enough context for the core to swtich to the next
 * exception level. When this function returns, the core will switch to the
 * programmed exception level via. an ERET.
 ******************************************************************************/
void bl31_main(void)
{
	el_change_info *next_image_info;
	uint32_t scr;

	/* Perform remaining generic architectural setup from EL3 */
	bl31_arch_setup();

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

#if defined (__GNUC__)
	printf("BL31 Built : %s, %s\n\r", __TIME__, __DATE__);
#endif
	/* Initialise helper libraries */
	bl31_lib_init();

	/* Initialize the runtime services e.g. psci */
	runtime_svc_init();

	/* Clean caches before re-entering normal world */
	dcsw_op_all(DCCSW);

	/*
	 * Setup minimal architectural state of the next highest EL to
	 * allow execution in it immediately upon entering it.
	 */
	bl31_arch_next_el_setup();

	/* Program EL3 registers to enable entry into the next EL */
	next_image_info = bl31_get_next_image_info();
	scr = read_scr();
	if (next_image_info->security_state == NON_SECURE)
		scr |= SCR_NS_BIT;

	/*
	 * Tell the context mgmt. library to ensure that SP_EL3 points to
	 * the right context to exit from EL3 correctly.
	 */
	cm_set_el3_eret_context(next_image_info->security_state,
			next_image_info->entrypoint,
			next_image_info->spsr,
			scr);

	/* Finally set the next context */
	cm_set_next_eret_context(next_image_info->security_state);
}
예제 #3
0
//*******************************************************************************
// Configure tbase and EL3 registers for intial entry 
static void tbase_init_eret( uint64_t entrypoint, uint32_t rw ) {
  uint32_t scr = read_scr();
  uint32_t spsr = TBASE_INIT_SPSR;
  
  assert(rw == TBASE_AARCH32);

  // Set the right security state and register width for the SP
  scr &= ~SCR_NS_BIT; 
  scr &= ~SCR_RW_BIT; 
  // Also IRQ and FIQ handled in secure state
  scr &= ~(SCR_FIQ_BIT|SCR_IRQ_BIT); 
  // No execution from Non-secure memory
  scr |= SCR_SIF_BIT; 
  
  cm_set_el3_eret_context(SECURE, entrypoint, spsr, scr);
  entry_point_info_t *image_info = bl31_plat_get_next_image_ep_info(SECURE);
  assert(image_info);
  image_info->spsr = spsr;

}
예제 #4
0
/*******************************************************************************
 * This function programs EL3 registers and performs other setup to enable entry
 * into the next image after BL31 at the next ERET.
 ******************************************************************************/
void bl31_prepare_next_image_entry()
{
	entry_point_info_t *next_image_info;
	uint32_t scr, image_type;
	cpu_context_t *ctx;
	gp_regs_t *gp_regs;

	/* Determine which image to execute next */
	image_type = bl31_get_next_image_type();

	/*
	 * Setup minimal architectural state of the next highest EL to
	 * allow execution in it immediately upon entering it.
	 */
	bl31_next_el_arch_setup(image_type);

	/* Program EL3 registers to enable entry into the next EL */
	next_image_info = bl31_plat_get_next_image_ep_info(image_type);
	assert(next_image_info);
	assert(image_type == GET_SECURITY_STATE(next_image_info->h.attr));

	scr = read_scr();
	scr &= ~SCR_NS_BIT;
	if (image_type == NON_SECURE)
		scr |= SCR_NS_BIT;

	scr &= ~SCR_RW_BIT;
	if ((next_image_info->spsr & (1 << MODE_RW_SHIFT)) ==
				(MODE_RW_64 << MODE_RW_SHIFT))
	{
		scr |= SCR_RW_BIT;
		scr |= SCR_HCE_BIT;
	}
	else
	{
		scr &= ~(SCR_HCE_BIT);
	}

	/*
	 * FIXME: Need a configurable flag when we have hypervisor installed
	 * This is for PSCI CPU_UP api to work correctly
	 * PSCI uses scr.hce to determine the target CPU of CPU_UP
	 * returns to NS world with HYP mode(HCE is set) or SVC mode(HCE is not set)
	 * (refer to psci_set_ns_entry_info() in psci_common.c)
	 * since we don't have hypervisor installed for now, we need to
	 * enter linux with SVC mode.
	 */
	// FIXME: For 64bit kernel, we need return to normal world with EL2
	// Temporary comment out this to enable 64bit kernel smp.
	// Need a method to configure this for 32bit/64bit kernel
	//scr &= ~(SCR_HCE_BIT);

	/*
	 * Tell the context mgmt. library to ensure that SP_EL3 points to
	 * the right context to exit from EL3 correctly.
	 */
	cm_set_el3_eret_context(image_type,
			next_image_info->pc,
			next_image_info->spsr,
			scr);

	/*
	 * Save the args generated in BL2 for the image in the right context
	 * used on its entry
	 */
	ctx = cm_get_context(read_mpidr(), image_type);
	gp_regs = get_gpregs_ctx(ctx);
	memcpy(gp_regs, (void *)&next_image_info->args, sizeof(aapcs64_params_t));

	/* Finally set the next context */
	cm_set_next_eret_context(image_type);
}
예제 #5
0
void bl31_prepare_k64_entry(void)
{
	entry_point_info_t *next_image_info;
	uint32_t scr, image_type;
	cpu_context_t *ctx;
	gp_regs_t *gp_regs;

	/* Determine which image to execute next */
	image_type = NON_SECURE; //bl31_get_next_image_type();

	/*
	 * Setup minimal architectural state of the next highest EL to
	 * allow execution in it immediately upon entering it.
	 */
	bl31_next_el_arch_setup(image_type);

	/* Program EL3 registers to enable entry into the next EL */
	next_image_info = bl31_plat_get_next_kernel_ep_info(image_type);


	assert(next_image_info);
	assert(image_type == GET_SECURITY_STATE(next_image_info->h.attr));


    /* check is set 64bit kernel*/
    printf("next_image_info->spsr = 0x%llx\n", next_image_info->spsr);

	scr = read_scr();
	scr &= ~SCR_NS_BIT;
	if (image_type == NON_SECURE)
		scr |= SCR_NS_BIT;

	scr &= ~SCR_RW_BIT;
	if ((next_image_info->spsr & (1 << MODE_RW_SHIFT)) ==
				(MODE_RW_64 << MODE_RW_SHIFT))
    {
		scr |= SCR_RW_BIT;

        printf("spsr is 64 bit\n");
    }

	scr |= SCR_HCE_BIT;

	/*
	 * Tell the context mgmt. library to ensure that SP_EL3 points to
	 * the right context to exit from EL3 correctly.
	 */
	cm_set_el3_eret_context(image_type,
			next_image_info->pc,
			next_image_info->spsr,
			scr);

	/*
	 * Save the args generated in BL2 for the image in the right context
	 * used on its entry
	 */
	ctx = cm_get_context(read_mpidr(), image_type);
	gp_regs = get_gpregs_ctx(ctx);
	memcpy(gp_regs, (void *)&next_image_info->args, sizeof(aapcs64_params_t));

    printf("Finally set the next context\n");

	/* Finally set the next context */
	cm_set_next_eret_context(image_type);
}