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