X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=OvmfPkg%2FSec%2FSecMain.c;h=670ad8d763aab0dc3a5f8215ee57c96a3cf7c6dd;hb=a781f7099bc2584fd065f1947bedd49adfea0fa5;hp=6e238fe3370160e95a6ce65405025905767fd348;hpb=4b4b783dbe49102e5acaa9852e737820a645a559;p=mirror_edk2.git diff --git a/OvmfPkg/Sec/SecMain.c b/OvmfPkg/Sec/SecMain.c index 6e238fe337..670ad8d763 100644 --- a/OvmfPkg/Sec/SecMain.c +++ b/OvmfPkg/Sec/SecMain.c @@ -311,7 +311,7 @@ FindFfsFileAndSection ( Locates the compressed main firmware volume and decompresses it. @param[in,out] Fv On input, the firmware volume to search - On output, the decompressed main FV + On output, the decompressed BOOT/PEI FV @retval EFI_SUCCESS The file and section was found @retval EFI_NOT_FOUND The file and section was not found @@ -319,7 +319,7 @@ FindFfsFileAndSection ( **/ EFI_STATUS -DecompressGuidedFv ( +DecompressMemFvs ( IN OUT EFI_FIRMWARE_VOLUME_HEADER **Fv ) { @@ -331,10 +331,11 @@ DecompressGuidedFv ( UINT32 AuthenticationStatus; VOID *OutputBuffer; VOID *ScratchBuffer; - EFI_FIRMWARE_VOLUME_IMAGE_SECTION *NewFvSection; - EFI_FIRMWARE_VOLUME_HEADER *NewFv; + EFI_FIRMWARE_VOLUME_IMAGE_SECTION *FvSection; + EFI_FIRMWARE_VOLUME_HEADER *PeiMemFv; + EFI_FIRMWARE_VOLUME_HEADER *DxeMemFv; - NewFvSection = (EFI_FIRMWARE_VOLUME_IMAGE_SECTION*) NULL; + FvSection = (EFI_FIRMWARE_VOLUME_IMAGE_SECTION*) NULL; Status = FindFfsFileAndSection ( *Fv, @@ -358,8 +359,7 @@ DecompressGuidedFv ( return Status; } - //PcdGet32 (PcdOvmfMemFvBase), PcdGet32 (PcdOvmfMemFvSize) - OutputBuffer = (VOID*) ((UINT8*)(UINTN) PcdGet32 (PcdOvmfMemFvBase) + SIZE_1MB); + OutputBuffer = (VOID*) ((UINT8*)(UINTN) PcdGet32 (PcdOvmfDxeMemFvBase) + SIZE_1MB); ScratchBuffer = ALIGN_POINTER ((UINT8*) OutputBuffer + OutputBufferSize, SIZE_1MB); Status = ExtractGuidedSectionDecode ( Section, @@ -372,27 +372,57 @@ DecompressGuidedFv ( return Status; } - Status = FindFfsSectionInSections ( + Status = FindFfsSectionInstance ( OutputBuffer, OutputBufferSize, EFI_SECTION_FIRMWARE_VOLUME_IMAGE, - (EFI_COMMON_SECTION_HEADER**) &NewFvSection + 0, + (EFI_COMMON_SECTION_HEADER**) &FvSection ); if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "Unable to find FV image in extracted data\n")); + DEBUG ((EFI_D_ERROR, "Unable to find PEI FV section\n")); return Status; } - NewFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32 (PcdOvmfMemFvBase); - CopyMem (NewFv, (VOID*) (NewFvSection + 1), PcdGet32 (PcdOvmfMemFvSize)); + ASSERT (SECTION_SIZE (FvSection) == + (PcdGet32 (PcdOvmfPeiMemFvSize) + sizeof (*FvSection))); + ASSERT (FvSection->Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE); - if (NewFv->Signature != EFI_FVH_SIGNATURE) { - DEBUG ((EFI_D_ERROR, "Extracted FV at %p does not have FV header signature\n", NewFv)); + PeiMemFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32 (PcdOvmfPeiMemFvBase); + CopyMem (PeiMemFv, (VOID*) (FvSection + 1), PcdGet32 (PcdOvmfPeiMemFvSize)); + + if (PeiMemFv->Signature != EFI_FVH_SIGNATURE) { + DEBUG ((EFI_D_ERROR, "Extracted FV at %p does not have FV header signature\n", PeiMemFv)); + CpuDeadLoop (); + return EFI_VOLUME_CORRUPTED; + } + + Status = FindFfsSectionInstance ( + OutputBuffer, + OutputBufferSize, + EFI_SECTION_FIRMWARE_VOLUME_IMAGE, + 1, + (EFI_COMMON_SECTION_HEADER**) &FvSection + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Unable to find DXE FV section\n")); + return Status; + } + + ASSERT (FvSection->Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE); + ASSERT (SECTION_SIZE (FvSection) == + (PcdGet32 (PcdOvmfDxeMemFvSize) + sizeof (*FvSection))); + + DxeMemFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32 (PcdOvmfDxeMemFvBase); + CopyMem (DxeMemFv, (VOID*) (FvSection + 1), PcdGet32 (PcdOvmfDxeMemFvSize)); + + if (DxeMemFv->Signature != EFI_FVH_SIGNATURE) { + DEBUG ((EFI_D_ERROR, "Extracted FV at %p does not have FV header signature\n", DxeMemFv)); CpuDeadLoop (); return EFI_VOLUME_CORRUPTED; } - *Fv = NewFv; + *Fv = PeiMemFv; return EFI_SUCCESS; } @@ -439,6 +469,50 @@ FindPeiCoreImageBaseInFv ( return EFI_SUCCESS; } + +/** + Reads 8-bits of CMOS data. + + Reads the 8-bits of CMOS data at the location specified by Index. + The 8-bit read value is returned. + + @param Index The CMOS location to read. + + @return The value read. + +**/ +STATIC +UINT8 +CmosRead8 ( + IN UINTN Index + ) +{ + IoWrite8 (0x70, (UINT8) Index); + return IoRead8 (0x71); +} + + +STATIC +BOOLEAN +IsS3Resume ( + VOID + ) +{ + return (CmosRead8 (0xF) == 0xFE); +} + + +STATIC +EFI_STATUS +GetS3ResumePeiFv ( + IN OUT EFI_FIRMWARE_VOLUME_HEADER **PeiFv + ) +{ + *PeiFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32 (PcdOvmfPeiMemFvBase); + return EFI_SUCCESS; +} + + /** Locates the PEI Core entry point address @@ -458,9 +532,15 @@ FindPeiCoreImageBase ( { *PeiCoreImageBase = 0; - FindMainFv (BootFv); + if (IsS3Resume ()) { + DEBUG ((EFI_D_VERBOSE, "SEC: S3 resume\n")); + GetS3ResumePeiFv (BootFv); + } else { + DEBUG ((EFI_D_VERBOSE, "SEC: Normal boot\n")); + FindMainFv (BootFv); - DecompressGuidedFv (BootFv); + DecompressMemFvs (BootFv); + } FindPeiCoreImageBaseInFv (*BootFv, PeiCoreImageBase); }