Beispiel #1
0
/*
 * vb2_check_recovery_request looks up different components to identify if there
 * is a recovery request and returns appropriate reason code:
 * 1. Checks if recovery mode is initiated by EC. If yes, returns
 * VB2_RECOVERY_RO_MANUAL.
 * 2. Checks if recovery request is present in VBNV and returns the code read
 * from it.
 * 3. Checks recovery request in handoff for stages post-cbmem.
 * 4. For non-CBMEM stages, check if vboot verification is done and look-up
 * selected region to identify if vboot_refence library has requested recovery
 * path. If yes, return the reason code from shared data.
 * 5. If nothing applies, return 0 indicating no recovery request.
 */
int vboot_check_recovery_request(void)
{
	int reason = 0;

	/* EC-initiated recovery. */
	if (get_recovery_mode_switch())
		return VB2_RECOVERY_RO_MANUAL;

	/* Recovery request in VBNV. */
	if ((reason = get_recovery_mode_from_vbnv()) != 0)
		return reason;

	/*
	 * Check recovery flag in vboot_handoff for stages post CBMEM coming
	 * online. Since for some stages there is no way to know if cbmem has
	 * already come online, try looking up handoff anyways. If it fails,
	 * flow will fallback to looking up shared data.
	 */
	if (cbmem_possibly_online() &&
	    ((reason = vboot_handoff_get_recovery_reason()) != 0))
		return reason;

	/*
	 * For stages where CBMEM might not be online, identify if vboot
	 * verification is already complete and no slot was selected
	 * i.e. recovery path was requested.
	 */
	if (vboot_possibly_executed() && vb2_logic_executed() &&
	    !vb2_is_slot_selected())
		return vb2_get_recovery_reason_shared_data();

	return 0;
}
Beispiel #2
0
void elog_add_boot_reason(void)
{
	if (developer_mode_enabled()) {
		elog_add_event(ELOG_TYPE_CROS_DEVELOPER_MODE);
		printk(BIOS_DEBUG, "%s: Logged dev mode boot\n", __func__);
	} else if (recovery_mode_enabled()) {
		u8 reason = 0;
#if CONFIG_VBOOT_VERIFY_FIRMWARE
		struct vboot_handoff *vbho = cbmem_find(CBMEM_ID_VBOOT_HANDOFF);

		reason = get_recovery_mode_from_vbnv();
		if (vbho && !reason) {
			VbSharedDataHeader *sd = (VbSharedDataHeader *)
				vbho->shared_data;
			reason = sd->recovery_reason;
		}
#endif

		elog_add_event_byte(ELOG_TYPE_CROS_RECOVERY_MODE,
			reason ? reason : ELOG_CROS_RECOVERY_MODE_BUTTON);
		printk(BIOS_DEBUG, "%s: Logged recovery mode boot, "
				"reason: 0x%02x\n", __func__, reason);
	} else {
		printk(BIOS_DEBUG, "%s: Normal mode boot, nothing "
					"interesting to log\n", __func__);
	}
}
Beispiel #3
0
/*
 * This is called in multiple places and has to detect
 * recovery mode triggered from the EC and via shared
 * recovery reason set with crossystem.
 *
 * If shared recovery reason is set:
 * - before VbInit then get_recovery_mode_from_vbnv() is true
 * - after VbInit then vboot_enable_recovery() is true
 *
 * Otherwise the mainboard handler for get_recovery_mode_switch()
 * will detect recovery mode initiated by the EC.
 */
int recovery_mode_enabled(void)
{
	if (get_recovery_mode_switch())
		return 1;
#if CONFIG_CHROMEOS
	if (get_recovery_mode_from_vbnv())
		return 1;
#endif
#if CONFIG_VBOOT_VERIFY_FIRMWARE
	if (vboot_enable_recovery())
		return 1;
#endif
	return 0;
}
Beispiel #4
0
int recovery_mode_enabled(void)
{
	/*
	 * This is called in multiple places and has to detect
	 * recovery mode triggered from the EC and via shared
	 * recovery reason set with crossystem.
	 *
	 * If shared recovery reason is set:
	 * - before VbInit then get_recovery_mode_from_vbnv() is true
	 * - after VbInit then vboot_enable_recovery() is true
	 *
	 * Otherwise the mainboard handler for get_recovery_mode_switch()
	 * will detect recovery mode initiated by the EC.
	 */
	return get_recovery_mode_switch() || get_recovery_mode_from_vbnv() ||
		vboot_enable_recovery();
}