/** @file * * Copyright (c) 2015, Hisilicon Limited. All rights reserved. * Copyright (c) 2015, Linaro Limited. All rights reserved. * * This program and the accompanying materials * are licensed and made available under the terms and conditions of the BSD License * which accompanies this distribution. The full text of the license may be found at * http://opensource.org/licenses/bsd-license.php * * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. * **/ #include #include #include #include #include #include #include #include #include #include #include STATIC EFI_STATUS InstallFdtIntoConfigurationTable ( IN VOID* FdtBlob, IN UINTN FdtSize ) { EFI_STATUS Status; // Check the FDT header is valid. We only make this check in DEBUG mode in case the FDT header change on // production device and this ASSERT() becomes not valid. if(!(fdt_check_header (FdtBlob) == 0)) { DEBUG ((EFI_D_ERROR,"can not find FdtBlob \n")); return EFI_INVALID_PARAMETER; } // Ensure the Size of the Device Tree is smaller than the size of the read file if(!((UINTN)fdt_totalsize (FdtBlob) <= FdtSize)) { DEBUG ((EFI_D_ERROR,"FdtBlob <= FdtSize \n")); return EFI_INVALID_PARAMETER; } // Install the FDT into the Configuration Table Status = gBS->InstallConfigurationTable (&gFdtTableGuid, FdtBlob); return Status; } EFI_STATUS SetNvramSpace (VOID) { EFI_STATUS Status; EFI_GCD_MEMORY_SPACE_DESCRIPTOR desp = {0}; if (PcdGet64(PcdReservedNvramSize) == 0) { return EFI_SUCCESS; } Status = gDS->GetMemorySpaceDescriptor(PcdGet64(PcdReservedNvramBase),&desp); if(EFI_ERROR(Status)){ DEBUG ((EFI_D_ERROR,"get memory space error:--------- \n")); return Status; } desp.Attributes |= EFI_MEMORY_RUNTIME | EFI_MEMORY_WB; Status = gDS->SetMemorySpaceAttributes(PcdGet64(PcdReservedNvramBase),PcdGet64(PcdReservedNvramSize), desp.Attributes); if(EFI_ERROR(Status)){ DEBUG ((EFI_D_ERROR,"set memory space error:--------- \n")); return Status; } return EFI_SUCCESS; } EFI_STATUS EFIAPI UpdateFdt ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable) { INTN Error; VOID* Fdt; UINT32 Size; UINTN NewFdtBlobSize; UINTN NewFdtBlobBase; EFI_STATUS Status = EFI_SUCCESS; UINT32 Index = 0; UINTN FDTConfigTable; (VOID) SetNvramSpace (); Fdt = (VOID*)(PcdGet64(FdtFileAddress)); Error = fdt_check_header ((VOID*)(PcdGet64(FdtFileAddress))); DEBUG ((EFI_D_ERROR,"fdtfileaddress:--------- 0x%lx\n",PcdGet64(FdtFileAddress))); if (Error != 0) { DEBUG ((EFI_D_ERROR,"ERROR: Device Tree header not valid (%a)\n", fdt_strerror(Error))); return EFI_INVALID_PARAMETER; } Size = (UINTN)fdt_totalsize ((VOID*)(PcdGet64(FdtFileAddress))); NewFdtBlobSize = Size + ADD_FILE_LENGTH; Status = gBS->AllocatePages (AllocateAnyPages, EfiRuntimeServicesData, EFI_SIZE_TO_PAGES(NewFdtBlobSize), &NewFdtBlobBase); if (EFI_ERROR (Status)) { return EFI_OUT_OF_RESOURCES; } (VOID) CopyMem((VOID*)NewFdtBlobBase, Fdt, Size); Status = EFIFdtUpdate(NewFdtBlobBase); if (EFI_ERROR (Status)) { DEBUG((EFI_D_ERROR, "%a(%d):EFIFdtUpdate Fail!\n", __FUNCTION__,__LINE__)); goto EXIT; } Status = InstallFdtIntoConfigurationTable ((VOID*)(UINTN)NewFdtBlobBase, NewFdtBlobSize); DEBUG ((EFI_D_ERROR, "NewFdtBlobBase: 0x%lx NewFdtBlobSize:0x%lx\n",NewFdtBlobBase,NewFdtBlobSize)); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "installfdtconfiguration table fail():\n")); goto EXIT; } for (Index = 0; Index < gST->NumberOfTableEntries; Index ++) { if (CompareGuid (&gFdtTableGuid, &(gST->ConfigurationTable[Index].VendorGuid))) { FDTConfigTable = (UINTN)gST->ConfigurationTable[Index].VendorTable; DEBUG ((EFI_D_ERROR, "FDTConfigTable Address: 0x%lx\n",FDTConfigTable)); break; } } return Status; EXIT: gBS->FreePages(NewFdtBlobBase,EFI_SIZE_TO_PAGES(NewFdtBlobSize)); return Status; }