/******************************************************************************* * This function sets the pointer to the current 'cpu_context' structure for the * specified security state for the CPU identified by MPIDR ******************************************************************************/ void cm_set_context_by_mpidr(uint64_t mpidr, void *context, uint32_t security_state) { assert(sec_state_is_valid(security_state)); cm_set_context_by_index(platform_get_core_pos(mpidr), context, security_state); }
/******************************************************************************* * This function sets the pointer to the current 'cpu_context' structure for the * specified security state for the CPU identified by CPU index. ******************************************************************************/ void cm_set_context_by_index(unsigned int cpu_idx, void *context, unsigned int security_state) { assert(sec_state_is_valid(security_state)); set_cpu_data_by_index(cpu_idx, cpu_context[security_state], context); }
/******************************************************************************* * This function returns a pointer to the most recent 'cpu_context' structure * for the CPU identified by `cpu_idx` that was set as the context for the * specified security state. NULL is returned if no such structure has been * specified. ******************************************************************************/ void *cm_get_context_by_index(unsigned int cpu_idx, unsigned int security_state) { assert(sec_state_is_valid(security_state)); return get_cpu_data_by_index(cpu_idx, cpu_context[security_state]); }
/* * Return a pointer to the 'entry_point_info' structure of the next image for * the security state specified. BL33 corresponds to the non-secure image type * while BL32 corresponds to the secure image type. A NULL pointer is returned * if the image does not exist. */ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) { assert(sec_state_is_valid(type)); if (type == NON_SECURE) return &bl33_image_ep_info; return &bl32_image_ep_info; }
/******************************************************************************* * This function returns a pointer to the most recent 'cpu_context' structure * for the CPU identified by MPIDR that was set as the context for the specified * security state. NULL is returned if no such structure has been specified. ******************************************************************************/ void *cm_get_context_by_mpidr(uint64_t mpidr, uint32_t security_state) { assert(sec_state_is_valid(security_state)); /* * Suppress deprecated declaration warning in compatibility function */ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" return cm_get_context_by_index(platform_get_core_pos(mpidr), security_state); #pragma GCC diagnostic pop }
void change_security_state(unsigned int target_security_state) { unsigned long scr = read_scr(); assert(sec_state_is_valid(target_security_state)); if (target_security_state == SECURE) scr &= ~SCR_NS_BIT; else scr |= SCR_NS_BIT; write_scr(scr); }
/******************************************************************************* * An ARM processor signals interrupt exceptions through the IRQ and FIQ pins. * The interrupt controller knows which pin/line it uses to signal a type of * interrupt. The platform knows which interrupt controller type is being used * in a particular security state e.g. with an ARM GIC, normal world could use * the GICv2 features while the secure world could use GICv3 features and vice * versa. * This function is exported by the platform to let the interrupt management * framework determine for a type of interrupt and security state, which line * should be used in the SCR_EL3 to control its routing to EL3. The interrupt * line is represented as the bit position of the IRQ or FIQ bit in the SCR_EL3. ******************************************************************************/ uint32_t plat_interrupt_type_to_line(uint32_t type, uint32_t security_state) { assert(type == INTR_TYPE_S_EL1 || type == INTR_TYPE_EL3 || type == INTR_TYPE_NS); assert(sec_state_is_valid(security_state)); /* * We ignore the security state parameter because Juno is GICv2 only * so both normal and secure worlds are using ARM GICv2. */ return gicv2_interrupt_type_to_line(GICC_BASE, type); }
/******************************************************************************* * Return a pointer to the 'entry_point_info' structure of the next image for the * security state specified. BL33 corresponds to the non-secure image type * while BL32 corresponds to the secure image type. A NULL pointer is returned * if the image does not exist. ******************************************************************************/ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) { entry_point_info_t *next_image_info; assert(sec_state_is_valid(type)); next_image_info = (type == NON_SECURE) ? &bl33_image_ep_info : &bl32_image_ep_info; /* * None of the images on the ARM development platforms can have 0x0 * as the entrypoint */ if (next_image_info->pc) return next_image_info; else return NULL; }
/* * An ARM processor signals interrupt exceptions through the IRQ and FIQ pins. * The interrupt controller knows which pin/line it uses to signal a type of * interrupt. It lets the interrupt management framework determine * for a type of interrupt and security state, which line should be used in the * SCR_EL3 to control its routing to EL3. The interrupt line is represented * as the bit position of the IRQ or FIQ bit in the SCR_EL3. */ uint32_t plat_interrupt_type_to_line(uint32_t type, uint32_t security_state) { assert((type == INTR_TYPE_S_EL1) || (type == INTR_TYPE_EL3) || (type == INTR_TYPE_NS)); assert(sec_state_is_valid(security_state)); /* Non-secure interrupts are signaled on the IRQ line always */ if (type == INTR_TYPE_NS) return __builtin_ctz(SCR_IRQ_BIT); /* * Secure interrupts are signaled using the IRQ line if the FIQ is * not enabled else they are signaled using the FIQ line. */ return ((gicv2_is_fiq_enabled() != 0U) ? __builtin_ctz(SCR_FIQ_BIT) : __builtin_ctz(SCR_IRQ_BIT)); }
/******************************************************************************* * An ARM processor signals interrupt exceptions through the IRQ and FIQ pins. * The interrupt controller knows which pin/line it uses to signal a type of * interrupt. This function provides a common implementation of * plat_interrupt_type_to_line() in an ARM GIC environment for optional re-use * across platforms. It lets the interrupt management framework determine * for a type of interrupt and security state, which line should be used in the * SCR_EL3 to control its routing to EL3. The interrupt line is represented as * the bit position of the IRQ or FIQ bit in the SCR_EL3. ******************************************************************************/ uint32_t tegra_gic_interrupt_type_to_line(uint32_t type, uint32_t security_state) { assert(type == INTR_TYPE_S_EL1 || type == INTR_TYPE_EL3 || type == INTR_TYPE_NS); assert(sec_state_is_valid(security_state)); /* * We ignore the security state parameter under the assumption that * both normal and secure worlds are using ARM GICv2. This parameter * will be used when the secure world starts using GICv3. */ #if ARM_GIC_ARCH == 2 return gicv2_interrupt_type_to_line(TEGRA_GICC_BASE, type); #else #error "Invalid ARM GIC architecture version specified for platform port" #endif /* ARM_GIC_ARCH */ }
/* * An ARM processor signals interrupt exceptions through the IRQ and FIQ pins. * The interrupt controller knows which pin/line it uses to signal a type of * interrupt. It lets the interrupt management framework determine for a type of * interrupt and security state, which line should be used in the SCR_EL3 to * control its routing to EL3. The interrupt line is represented as the bit * position of the IRQ or FIQ bit in the SCR_EL3. */ uint32_t plat_interrupt_type_to_line(uint32_t type, uint32_t security_state) { assert(type == INTR_TYPE_S_EL1 || type == INTR_TYPE_EL3 || type == INTR_TYPE_NS); assert(sec_state_is_valid(security_state)); assert(IS_IN_EL3()); switch (type) { case INTR_TYPE_S_EL1: /* * The S-EL1 interrupts are signaled as IRQ in S-EL0/1 contexts * and as FIQ in the NS-EL0/1/2 contexts */ if (security_state == SECURE) return __builtin_ctz(SCR_IRQ_BIT); else return __builtin_ctz(SCR_FIQ_BIT); case INTR_TYPE_NS: /* * The Non secure interrupts will be signaled as FIQ in S-EL0/1 * contexts and as IRQ in the NS-EL0/1/2 contexts. */ if (security_state == SECURE) return __builtin_ctz(SCR_FIQ_BIT); else return __builtin_ctz(SCR_IRQ_BIT); default: assert(0); /* Fall through in the release build */ case INTR_TYPE_EL3: /* * The EL3 interrupts are signaled as FIQ in both S-EL0/1 and * NS-EL0/1/2 contexts */ return __builtin_ctz(SCR_FIQ_BIT); } }
/******************************************************************************* * Accessor functions to help runtime services decide which image should be * executed after BL31. This is BL33 or the non-secure bootloader image by * default but the Secure payload dispatcher could override this by requesting * an entry into BL32 (Secure payload) first. If it does so then it should use * the same API to program an entry into BL33 once BL32 initialisation is * complete. ******************************************************************************/ void bl31_set_next_image_type(uint32_t security_state) { assert(sec_state_is_valid(security_state)); next_image_type = security_state; }