/** @file This driver handle msdm OA data between variable and SPI ROM ;****************************************************************************** ;* Copyright (c) 2021, Insyde Software Corporation. All Rights Reserved. ;* ;* You may not reproduce, distribute, publish, display, perform, modify, adapt, ;* transmit, broadcast, present, recite, release, license or otherwise exploit ;* any part of this publication in any form, by any means, without the prior ;* written permission of Insyde Software Corporation. ;* ;****************************************************************************** */ #include #include #include #include #include #include #include static EFI_GUID gMsdmAddressGuid = MEMORY_ADDRESS_FOR_MSDM_GUID; EFI_SMM_FW_BLOCK_SERVICE_PROTOCOL *mSmmFwBlockService = NULL; EFI_SMM_VARIABLE_PROTOCOL *mSmmVariable = NULL; UINTN mRomBaseAddress; UINTN mMsdmDataSize; /** Erasing MSDM OA data from SPI ROM NvStorageMsdmData region. **/ VOID OA30EraseFromRom ( VOID ) { EFI_STATUS Status; Status = mSmmFwBlockService->EraseBlocks ( mSmmFwBlockService, mRomBaseAddress, &mMsdmDataSize ); if (!EFI_ERROR (Status)) { // // Delete MsdmErase variable. // Status = mSmmVariable->SmmSetVariable ( L"MsdmErase", &gMsdmAddressGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, 0, NULL ); if (!EFI_ERROR (Status)) { return; } else { DEBUG ((DEBUG_WARN, "Erasing Msdm data from NvStorageMsdmData Success, but MsdmErase Variable did NOT been removed. Status : %r\n", Status)); } } else { DEBUG ((DEBUG_WARN, "NvStorageMsdmData Erasing Failed. Status : %r\n", Status)); } return; } /** Writing MSDM OA data from Variable to SPI ROM NvStorageMsdmData region. **/ VOID OA30UpdateToRom ( IN UINT8 *MsdmData ) { EFI_STATUS Status; Status = mSmmFwBlockService->EraseBlocks ( mSmmFwBlockService, mRomBaseAddress, &mMsdmDataSize ); if (!EFI_ERROR(Status)) { Status = mSmmFwBlockService->Write ( mSmmFwBlockService, mRomBaseAddress, &mMsdmDataSize, MsdmData ); if (!EFI_ERROR (Status)) { // // Delete MsdmUpdate variable. // Status = mSmmVariable->SmmSetVariable ( L"MsdmUpdate", &gMsdmAddressGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, 0, NULL ); if (!EFI_ERROR (Status)) { return; } else { DEBUG ((DEBUG_WARN, "Update Msdm to ROM Success but MsdmUpdate Variable did NOT been removed. Status : %r\n", Status)); } } else { DEBUG ((DEBUG_WARN, "Update Msdm to ROM Failed. Status : %r\n", Status)); } } else { DEBUG ((DEBUG_WARN, "NvStorageMsdmData Erasing Failed. Status : %r\n", Status)); } return; } /** Handle msdm OA data between variable and SPI ROM @param[in] ImageHandle Image handle of this driver. @param[in] SystemTable Pointer to standard EFI system table. @retval EFI_SUCCESS Msdm Data was updated to ROM or removed form ROM Successful. @retval !EFI_SUCCESS Fail or NoNeed to update. **/ EFI_STATUS EFIAPI UpdateMsdmSmmEntry ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; UINT8 Erase; UINTN DataSize; UINT8 *MsdmData; Status = EFI_SUCCESS; Erase = 0; DataSize = 0; MsdmData = NULL; mRomBaseAddress = (UINTN) FixedPcdGet32 (PcdFlashNvStorageMsdmDataBase); mMsdmDataSize = (UINTN) FixedPcdGet32 (PcdFlashNvStorageMsdmDataSize); Status = gSmst->SmmLocateProtocol ( &gEfiSmmFwBlockServiceProtocolGuid, NULL, &mSmmFwBlockService ); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_WARN, "FW Block Service Protocol Locate Failed. Status : %r\n", Status)); return Status; } // // Locate SMM Variable Protocol // Status = gSmst->SmmLocateProtocol ( &gEfiSmmVariableProtocolGuid, NULL, (VOID **) &mSmmVariable ); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_WARN, "Smm Variable Protocol Locate Failed. Status : %r\n", Status)); return Status; } // // Erase Msdm Data. // DataSize = sizeof (UINT8); Status = mSmmVariable->SmmGetVariable ( L"MsdmErase", &gMsdmAddressGuid, NULL, &DataSize, (UINTN*) &Erase ); if (!EFI_ERROR (Status)) { OA30EraseFromRom (); } // // Update Msdm data. // Status = gSmst->SmmAllocatePool ( EfiRuntimeServicesData, mMsdmDataSize, &MsdmData ); DEBUG ((DEBUG_INFO, "Allocate pool for MSDM Data Status : %r\n", Status)); if (!EFI_ERROR (Status)) { Status = mSmmVariable->SmmGetVariable ( L"MsdmUpdate", &gMsdmAddressGuid, NULL, &mMsdmDataSize, MsdmData ); if (!EFI_ERROR (Status)) { OA30UpdateToRom (MsdmData); } } if (MsdmData != NULL) { gSmst->SmmFreePool (MsdmData); } return Status; }