• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2 *
3 *  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
4 *  Copyright (c) 2015, Linaro Limited. All rights reserved.
5 *
6 *  This program and the accompanying materials
7 *  are licensed and made available under the terms and conditions of the BSD License
8 *  which accompanies this distribution.  The full text of the license may be found at
9 *  http://opensource.org/licenses/bsd-license.php
10 *
11 *  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 *  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 *
14 **/
15 
16 
17 #include <Uefi.h>
18 #include <Pi/PiDxeCis.h>
19 #include <Library/DebugLib.h>
20 #include <libfdt.h>
21 #include <Library/UefiBootServicesTableLib.h>
22 #include <Library/MemoryAllocationLib.h>
23 #include <Library/PrintLib.h>
24 #include <Guid/Fdt.h>
25 #include <Protocol/HisiBoardNicProtocol.h>
26 #include <Library/DxeServicesTableLib.h>
27 #include <Library/FdtUpdateLib.h>
28 
29 STATIC
30 EFI_STATUS
InstallFdtIntoConfigurationTable(IN VOID * FdtBlob,IN UINTN FdtSize)31 InstallFdtIntoConfigurationTable (
32   IN VOID* FdtBlob,
33   IN UINTN FdtSize
34   )
35 {
36   EFI_STATUS Status;
37 
38   // Check the FDT header is valid. We only make this check in DEBUG mode in case the FDT header change on
39   // production device and this ASSERT() becomes not valid.
40   if(!(fdt_check_header (FdtBlob) == 0))
41   {
42       DEBUG ((EFI_D_ERROR,"can not find FdtBlob \n"));
43       return EFI_INVALID_PARAMETER;
44   }
45 
46   // Ensure the Size of the Device Tree is smaller than the size of the read file
47   if(!((UINTN)fdt_totalsize (FdtBlob) <= FdtSize))
48   {
49       DEBUG ((EFI_D_ERROR,"FdtBlob <= FdtSize \n"));
50       return EFI_INVALID_PARAMETER;
51   }
52 
53   // Install the FDT into the Configuration Table
54   Status = gBS->InstallConfigurationTable (&gFdtTableGuid, FdtBlob);
55 
56   return Status;
57 }
58 
59 EFI_STATUS
SetNvramSpace(VOID)60 SetNvramSpace (VOID)
61 {
62     EFI_STATUS          Status;
63     EFI_GCD_MEMORY_SPACE_DESCRIPTOR desp = {0};
64 
65     if (PcdGet64(PcdReservedNvramSize) == 0) {
66       return EFI_SUCCESS;
67     }
68 
69     Status = gDS->GetMemorySpaceDescriptor(PcdGet64(PcdReservedNvramBase),&desp);
70     if(EFI_ERROR(Status)){
71          DEBUG ((EFI_D_ERROR,"get memory space error:--------- \n"));
72         return Status;
73     }
74     desp.Attributes |= EFI_MEMORY_RUNTIME | EFI_MEMORY_WB;
75     Status = gDS->SetMemorySpaceAttributes(PcdGet64(PcdReservedNvramBase),PcdGet64(PcdReservedNvramSize), desp.Attributes);
76     if(EFI_ERROR(Status)){
77         DEBUG ((EFI_D_ERROR,"set memory space error:--------- \n"));
78         return Status;
79     }
80 
81     return EFI_SUCCESS;
82 }
83 
84 
85 EFI_STATUS
UpdateFdt(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)86 EFIAPI UpdateFdt (
87   IN EFI_HANDLE         ImageHandle,
88   IN EFI_SYSTEM_TABLE  *SystemTable)
89 {
90     INTN                Error;
91     VOID*               Fdt;
92     UINT32              Size;
93     UINTN               NewFdtBlobSize;
94     UINTN               NewFdtBlobBase;
95     EFI_STATUS          Status = EFI_SUCCESS;
96     UINT32              Index = 0;
97     UINTN               FDTConfigTable;
98 
99     (VOID) SetNvramSpace ();
100 
101     Fdt = (VOID*)(PcdGet64(FdtFileAddress));
102 
103 
104     Error = fdt_check_header ((VOID*)(PcdGet64(FdtFileAddress)));
105     DEBUG ((EFI_D_ERROR,"fdtfileaddress:--------- 0x%lx\n",PcdGet64(FdtFileAddress)));
106     if (Error != 0)
107     {
108         DEBUG ((EFI_D_ERROR,"ERROR: Device Tree header not valid (%a)\n", fdt_strerror(Error)));
109         return EFI_INVALID_PARAMETER;
110     }
111 
112     Size = (UINTN)fdt_totalsize ((VOID*)(PcdGet64(FdtFileAddress)));
113     NewFdtBlobSize = Size + ADD_FILE_LENGTH;
114 
115     Status = gBS->AllocatePages (AllocateAnyPages, EfiRuntimeServicesData, EFI_SIZE_TO_PAGES(Size), &NewFdtBlobBase);
116     if (EFI_ERROR (Status))
117     {
118         return EFI_OUT_OF_RESOURCES;
119     }
120 
121     (VOID) CopyMem((VOID*)NewFdtBlobBase, Fdt, Size);
122 
123     Status = EFIFdtUpdate(NewFdtBlobBase);
124     if (EFI_ERROR (Status))
125     {
126         DEBUG((EFI_D_ERROR, "%a(%d):EFIFdtUpdate Fail!\n", __FUNCTION__,__LINE__));
127         goto EXIT;
128     }
129 
130 
131     Status = InstallFdtIntoConfigurationTable ((VOID*)(UINTN)NewFdtBlobBase, NewFdtBlobSize);
132     DEBUG ((EFI_D_ERROR, "NewFdtBlobBase: 0x%lx  NewFdtBlobSize:0x%lx\n",NewFdtBlobBase,NewFdtBlobSize));
133     if (EFI_ERROR (Status))
134     {
135         DEBUG ((EFI_D_ERROR, "installfdtconfiguration table fail():\n"));
136         goto EXIT;
137     }
138 
139 
140     for (Index = 0; Index < gST->NumberOfTableEntries; Index ++)
141     {
142         if (CompareGuid (&gFdtTableGuid, &(gST->ConfigurationTable[Index].VendorGuid)))
143         {
144             FDTConfigTable = (UINTN)gST->ConfigurationTable[Index].VendorTable;
145             DEBUG ((EFI_D_ERROR, "FDTConfigTable Address: 0x%lx\n",FDTConfigTable));
146             break;
147         }
148     }
149 
150     return Status;
151 
152     EXIT:
153 
154          gBS->FreePages(NewFdtBlobBase,EFI_SIZE_TO_PAGES(NewFdtBlobSize));
155 
156     return Status;
157 
158 }
159