/******************************************************************************* * MTK_platform handler called when an affinity instance is about to be turned on. The * level and mpidr determine the affinity instance. ******************************************************************************/ int mt_affinst_on(unsigned long mpidr, unsigned long sec_entrypoint, unsigned long ns_entrypoint, unsigned int afflvl, unsigned int state) { int rc = PSCI_E_SUCCESS; unsigned long linear_id; mailbox_t *mt_mboxes; /* * It's possible to turn on only affinity level 0 i.e. a cpu * on the MTK_platform. Ignore any other affinity level. */ if (afflvl != MPIDR_AFFLVL0) goto exit; linear_id = platform_get_core_pos(mpidr); mt_mboxes = (mailbox_t *) (MBOX_OFF); mt_mboxes[linear_id].value = sec_entrypoint; flush_dcache_range((unsigned long) &mt_mboxes[linear_id], sizeof(unsigned long)); extern void bl31_on_entrypoint(void); if (linear_id >= 4) { mmio_write_32(MP1_MISC_CONFIG_BOOT_ADDR(linear_id-4), (unsigned long)bl31_on_entrypoint); printf("mt_on, entry %x\n", mmio_read_32(MP1_MISC_CONFIG_BOOT_ADDR(linear_id-4))); } else { /* set secondary CPUs to AArch64 */ mmio_write_32(MP0_MISC_CONFIG3, mmio_read_32(MP0_MISC_CONFIG3) | 0x0000E000); mmio_write_32(MP0_MISC_CONFIG_BOOT_ADDR(linear_id), (unsigned long)bl31_on_entrypoint); printf("mt_on, entry %x\n", mmio_read_32(MP0_MISC_CONFIG_BOOT_ADDR(linear_id))); } exit: return rc; }
/******************************************************************************* * FVP handler called when an affinity instance is about to be turned on. The * level and mpidr determine the affinity instance. ******************************************************************************/ int plat_affinst_on(unsigned long mpidr, unsigned long sec_entrypoint, unsigned long ns_entrypoint, unsigned int afflvl, unsigned int state) { int rc = PSCI_E_SUCCESS; unsigned long linear_id; /* * It's possible to turn on only affinity level 0 i.e. a cpu * on the FVP. Ignore any other affinity level. */ if (afflvl != MPIDR_AFFLVL0) return rc; /* * Ensure that we do not cancel an inflight power off request * for the target cpu. That would leave it in a zombie wfi. * Wait for it to power off, program the jump address for the * target cpu and then program the power controller to turn * that cpu on */ // do { // psysr = plat_pwrc_read_psysr(mpidr); // } while (psysr & PSYSR_AFF_L0); plat_program_mailbox(mpidr, sec_entrypoint); // plat_pwrc_write_pponr(mpidr); linear_id = platform_get_core_pos(mpidr); extern void bl31_on_entrypoint(void); if (linear_id >= 4) { mmio_write_32(MP1_MISC_CONFIG_BOOT_ADDR(linear_id-4), (unsigned long)bl31_on_entrypoint); printf("mt_on_1, entry %x\n", mmio_read_32(MP1_MISC_CONFIG_BOOT_ADDR(linear_id-4))); } else { /* set secondary CPUs to AArch64 */ mmio_write_32(MP0_MISC_CONFIG3, mmio_read_32(MP0_MISC_CONFIG3) | 0x0000E000); mmio_write_32(MP0_MISC_CONFIG_BOOT_ADDR(linear_id), (unsigned long)bl31_on_entrypoint); printf("mt_on_0, entry %x\n", mmio_read_32(MP1_MISC_CONFIG_BOOT_ADDR(linear_id))); } return rc; }
void bl31_early_platform_setup(bl31_params_t *from_bl2, void *plat_params_from_bl2) { unsigned long long normal_base; unsigned long long atf_base; config_L2_size(); atf_arg_t_ptr teearg = (atf_arg_t_ptr)(uintptr_t)TEE_BOOT_INFO_ADDR; // overwrite core0 reset address, to avoid overwrite tee boot argument mmio_write_32(MP0_MISC_CONFIG_BOOT_ADDR(0), (unsigned long)bl31_on_entrypoint); normal_base = 0; /* in ATF boot time, tiemr for cntpct_el0 is not initialized * so it will not count now. */ atf_base = read_cntpct_el0(); atf_sched_clock_init(normal_base, atf_base); /* Initialize the console to provide early debug support */ // console_init(UART0_BASE); // without boot argument console_init(teearg->atf_log_port); printf("LK boot argument location=0x%x\n\r", BOOT_ARGUMENT_LOCATION); printf("KL boot argument size=0x%x\n\r", BOOT_ARGUMENT_SIZE); printf("atf_magic=0x%x\n\r", teearg->atf_magic); printf("tee_support=0x%x\n\r", teearg->tee_support); printf("tee_entry=0x%x\n\r", teearg->tee_entry); printf("tee_boot_arg_addr=0x%x\n\r", teearg->tee_boot_arg_addr); printf("atf_log_port=0x%x\n\r", teearg->atf_log_port); printf("atf_log_baudrate=0x%x\n\r", teearg->atf_log_baudrate); printf("atf_log_buf_start=0x%x\n\r", teearg->atf_log_buf_start); printf("atf_log_buf_size=0x%x\n\r", teearg->atf_log_buf_size); printf("atf_aee_debug_buf_start=0x%x\n\r", teearg->atf_aee_debug_buf_start); printf("atf_aee_debug_buf_size=0x%x\n\r", teearg->atf_aee_debug_buf_size); printf("atf_irq_num=%d\n\r", teearg->atf_irq_num); printf("BL33_START_ADDRESS=0x%x\n\r", BL33_START_ADDRESS); /* Initialize the platform config for future decision making */ mt_config_setup(); printf("bl31_setup\n\r"); #if RESET_TO_BL31 /* There are no parameters from BL2 if BL31 is a reset vector */ assert(from_bl2 == NULL); assert(plat_params_from_bl2 == NULL); printf("RESET_TO_BL31\n\r"); /* * Do initial security configuration to allow DRAM/device access. On * Base MTK_platform only DRAM security is programmable (via TrustZone), but * other platforms might have more programmable security devices * present. */ //FIXME, do not set TZC400 now //mt_security_setup(); #else /* Check params passed from BL2 should not be NULL, * We are not checking plat_params_from_bl2 as NULL as we are not * using it on MTK_platform */ printf("not RESET_TO_BL31\n"); assert(from_bl2 != NULL); assert(from_bl2->h.type == PARAM_BL31); assert(from_bl2->h.version >= VERSION_1); bl2_to_bl31_params = from_bl2; assert(((unsigned long)plat_params_from_bl2) == MT_BL31_PLAT_PARAM_VAL); #endif /*If no TEE, initial devapc in ATF*/ if(! (teearg->tee_support)) start_devapc(); }