/** * DOC: Xe Boot Survivability * * Boot Survivability is a software based workflow for recovering a system in a failed boot state * Here system recoverability is concerned with recovering the firmware responsible for boot. * * This is implemented by loading the driver with bare minimum (no drm card) to allow the firmware * to be flashed through mei and collect telemetry. The driver's probe flow is modified * such that it enters survivability mode when pcode initialization is incomplete and boot status * denotes a failure. * * Survivability mode can also be entered manually using the survivability mode attribute available * through configfs which is beneficial in several usecases. It can be used to address scenarios * where pcode does not detect failure or for validation purposes. It can also be used in * In-Field-Repair (IFR) to repair a single card without impacting the other cards in a node. * * Use below command enable survivability mode manually:: * * # echo 1 > /sys/kernel/config/xe/0000:03:00.0/survivability_mode * * It is the responsibility of the user to clear the mode once firmware flash is complete. * * Refer :ref:`xe_configfs` for more details on how to use configfs * * Survivability mode is indicated by the below admin-only readable sysfs which provides additional * debug information:: * * /sys/bus/pci/devices/<device>/surivability_mode * * Capability Information: * Provides boot status * Postcode Information: * Provides information about the failure * Overflow Information * Provides history of previous failures * Auxiliary Information * Certain failures may have information in addition to postcode information
*/
/* create survivability mode sysfs */
ret = sysfs_create_file(&dev->kobj, &dev_attr_survivability_mode.attr); if (ret) {
dev_warn(dev, "Failed to create survivability sysfs files\n"); return ret;
}
ret = devm_add_action_or_reset(xe->drm.dev,
xe_survivability_mode_fini, xe); if (ret) return ret;
/* Make sure xe_heci_gsc_init() knows about survivability mode */
survivability->mode = true;
ret = xe_heci_gsc_init(xe); if (ret) goto err;
xe_vsec_init(xe);
ret = xe_i2c_probe(xe); if (ret) goto err;
dev_err(dev, "In Survivability Mode\n");
return 0;
err:
survivability->mode = false; return ret;
}
/** * xe_survivability_mode_is_enabled - check if survivability mode is enabled * @xe: xe device instance * * Returns true if in survivability mode, false otherwise
*/ bool xe_survivability_mode_is_enabled(struct xe_device *xe)
{ return xe->survivability.mode;
}
/** * xe_survivability_mode_is_requested - check if it's possible to enable survivability * mode that was requested by firmware or userspace * @xe: xe device instance * * This function reads configfs and boot status from Pcode. * * Return: true if platform support is available and boot status indicates * failure or if survivability mode is requested, false otherwise.
*/ bool xe_survivability_mode_is_requested(struct xe_device *xe)
{ struct xe_survivability *survivability = &xe->survivability; struct xe_mmio *mmio = xe_root_tile_mmio(xe); struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
u32 data; bool survivability_mode;
if (xe->info.platform < XE_BATTLEMAGE) { if (survivability_mode) {
dev_err(&pdev->dev, "Survivability Mode is not supported on this card\n");
xe_configfs_clear_survivability_mode(pdev);
} returnfalse;
}
/* Enable survivability mode if set via configfs */ if (survivability_mode) returntrue;
data = xe_mmio_read32(mmio, PCODE_SCRATCH(0));
survivability->boot_status = REG_FIELD_GET(BOOT_STATUS, data);
/** * xe_survivability_mode_enable - Initialize and enable the survivability mode * @xe: xe device instance * * Initialize survivability information and enable survivability mode * * Return: 0 if survivability mode is enabled or not requested; negative error * code otherwise.
*/ int xe_survivability_mode_enable(struct xe_device *xe)
{ struct xe_survivability *survivability = &xe->survivability; struct xe_survivability_info *info; struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
if (!xe_survivability_mode_is_requested(xe)) return 0;
survivability->size = MAX_SCRATCH_MMIO;
info = devm_kcalloc(xe->drm.dev, survivability->size, sizeof(*info),
GFP_KERNEL); if (!info) return -ENOMEM;
survivability->info = info;
populate_survivability_info(xe);
/* Only log debug information and exit if it is a critical failure */ if (survivability->boot_status == CRITICAL_FAILURE) {
log_survivability_info(pdev); return -ENXIO;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.