Esempio n. 1
0
static void init_primary_helper(uint32_t pageable_part, uint32_t nsec_entry)
{
	/*
	 * Mask asynchronous exceptions before switch to the thread vector
	 * as the thread handler requires those to be masked while
	 * executing with the temporary stack. The thread subsystem also
	 * asserts that IRQ is blocked when using most if its functions.
	 */
	thread_set_exceptions(THREAD_EXCP_ALL);
	init_vfp_sec();

	init_runtime(pageable_part);

	IMSG("Initializing (%s)\n", core_v_str);

	thread_init_primary(generic_boot_get_handlers());
	thread_init_per_cpu();
	init_sec_mon(nsec_entry);


	main_init_gic();
	init_vfp_nsec();

	if (init_teecore() != TEE_SUCCESS)
		panic();
	DMSG("Primary CPU switching to normal world boot\n");
}
Esempio n. 2
0
static void main_init_helper(bool is_primary, size_t pos, uint32_t nsec_entry)
{
	/*
	 * Mask external Abort, IRQ and FIQ before switch to the thread
	 * vector as the thread handler requires externl Abort, IRQ and FIQ
	 * to be masked while executing with the temporary stack. The
	 * thread subsystem also asserts that IRQ is blocked when using
	 * most if its functions.
	 */
	write_cpsr(read_cpsr() | CPSR_FIA);

	if (is_primary) {
		uintptr_t bss_start = (uintptr_t)&__bss_start;
		uintptr_t bss_end = (uintptr_t)&__bss_end;
		size_t n;

		/* Initialize uart with physical address */
		uart_init(CONSOLE_UART_BASE);

		/*
		 * Zero BSS area. Note that globals that would normally
		 * would go into BSS which are used before this has to be
		 * put into .nozi.* to avoid getting overwritten.
		 */
		memset((void *)bss_start, 0, bss_end - bss_start);

		DMSG("TEE initializing\n");

		/* Initialize canaries around the stacks */
		init_canaries();

		/* Assign the thread stacks */
		for (n = 0; n < NUM_THREADS; n++) {
			if (!thread_init_stack(n, GET_STACK(stack_thread[n])))
				panic();
		}
	}

	if (!thread_init_stack(THREAD_TMP_STACK, GET_STACK(stack_tmp[pos])))
		panic();
	if (!thread_init_stack(THREAD_ABT_STACK, GET_STACK(stack_abt[pos])))
		panic();

	thread_init_handlers(&handlers);

	main_init_sec_mon(pos, nsec_entry);

	if (is_primary) {
		main_init_gic();
		if (init_teecore() != TEE_SUCCESS)
			panic();
		DMSG("Primary CPU switching to normal world boot\n");
	} else {
		DMSG("Secondary CPU Switching to normal world boot\n");
	}
}
Esempio n. 3
0
int imx7d_lowpower_idle(uint32_t power_state __unused,
			uintptr_t entry __unused,
			uint32_t context_id __unused,
			struct sm_nsec_ctx *nsec)
{
	struct imx7_pm_info *p;
	uint32_t cpuidle_ocram_base;
	static uint32_t gic_inited;
	int ret;

	uint32_t cpu_id __maybe_unused = get_core_pos();
	uint32_t type = (power_state & PSCI_POWER_STATE_TYPE_MASK) >>
		PSCI_POWER_STATE_TYPE_SHIFT;
	uint32_t cpu = get_core_pos();

	cpuidle_ocram_base = core_mmu_get_va(TRUSTZONE_OCRAM_START +
					     LOWPOWER_IDLE_OCRAM_OFFSET,
					     MEM_AREA_TEE_COHERENT);
	p = (struct imx7_pm_info *)cpuidle_ocram_base;

	imx_pen_lock(cpu);

	if (!lowpoweridle_init) {
		imx7d_cpuidle_init();
		lowpoweridle_init = 1;
	}

	if (type != PSCI_POWER_STATE_TYPE_POWER_DOWN)
		panic();

	p->num_online_cpus = get_online_cpus();
	p->num_lpi_cpus++;

	sm_save_unbanked_regs(&nsec->ub_regs);

	ret = sm_pm_cpu_suspend((uint32_t)p, (int (*)(uint32_t))
				(cpuidle_ocram_base + sizeof(*p)));

	/*
	 * Sometimes cpu_suspend may not really suspended, we need to check
	 * it's return value to restore reg or not
	 */
	if (ret < 0) {
		p->num_lpi_cpus--;
		imx_pen_unlock(cpu);
		DMSG("=== Not suspended, GPC IRQ Pending === %d\n", cpu_id);
		return 0;
	}

	/*
	 * Restore register of different mode in secure world
	 * When cpu powers up, after ROM init, cpu in secure SVC
	 * mode, we first need to restore monitor regs.
	 */
	sm_restore_unbanked_regs(&nsec->ub_regs);

	p->num_lpi_cpus--;
	/* Back to Linux */
	nsec->mon_lr = (uint32_t)entry;

	if (gic_inited == 0) {
		/*
		 * TODO: Call the Wakeup Late function to restore some
		 * HW configuration (e.g. TZASC)
		 */
		plat_cpu_reset_late();

		main_init_gic();
		gic_inited = 1;
		DMSG("=== Back from Suspended ===\n");
	} else {
		main_secondary_init_gic();
		gic_inited = 0;
	}

	imx_pen_unlock(cpu);

	return 0;
}