/* * 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; }
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__); } }
/* * 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; }
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(); }