• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2 *
3 *  Copyright (c) 2015-2016, Linaro Ltd. All rights reserved.
4 *  Copyright (c) 2015-2016, Hisilicon Ltd. 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 #include <Library/BaseMemoryLib.h>
17 #include <Library/BdsLib.h>
18 #include <Library/CacheMaintenanceLib.h>
19 #include <Library/DevicePathLib.h>
20 #include <Library/MemoryAllocationLib.h>
21 #include <Library/UefiBootServicesTableLib.h>
22 #include <Library/UefiLib.h>
23 #include <Library/UefiRuntimeServicesTableLib.h>
24 
25 #include <Guid/HiKeyVariable.h>
26 
27 #include <Protocol/BlockIo.h>
28 #include <Protocol/DwUsb.h>
29 
30 #include "HiKeyDxeInternal.h"
31 
32 #define SERIAL_NUMBER_LENGTH        17
33 #define SERIAL_NUMBER_LBA           1024
34 #define SERIAL_NUMBER_BLOCK_SIZE    512
35 #define RANDOM_MAGIC                0x9a4dbeaf
36 
37 struct RandomSerialNo {
38   UINTN              Magic;
39   UINTN              Data;
40   CHAR8              SerialNo[32];
41 };
42 
43 STATIC CHAR16 mSerialNo[17];
44 
45 STATIC
46 UINTN
47 EFIAPI
HiKeyInitSerialNo(IN VOID)48 HiKeyInitSerialNo (
49   IN   VOID
50   )
51 {
52   EFI_STATUS                      Status;
53   UINTN                           VariableSize;
54   EFI_DEVICE_PATH_PROTOCOL        *BlockDevicePath;
55   EFI_BLOCK_IO_PROTOCOL           *BlockIoProtocol;
56   EFI_HANDLE                      Handle;
57   VOID                            *DataPtr;
58   struct RandomSerialNo           *Random;
59   CHAR16                          DefaultSerialNo[] = L"0123456789abcdef";
60   CHAR16                          SerialNoUnicode[32], DataUnicode[32];
61 
62   BlockDevicePath = ConvertTextToDevicePath ((CHAR16*)FixedPcdGetPtr (PcdAndroidFastbootNvmDevicePath));
63   Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &BlockDevicePath, &Handle);
64   if (EFI_ERROR (Status)) {
65     DEBUG ((EFI_D_ERROR, "Warning: Couldn't locate block device (status: %r)\n", Status));
66     return EFI_INVALID_PARAMETER;
67   }
68   Status = gBS->OpenProtocol (
69 		      Handle,
70                       &gEfiBlockIoProtocolGuid,
71 		      (VOID **) &BlockIoProtocol,
72                       gImageHandle,
73                       NULL,
74                       EFI_OPEN_PROTOCOL_GET_PROTOCOL
75                       );
76   if (EFI_ERROR (Status)) {
77     DEBUG ((EFI_D_ERROR, "Warning: Couldn't open block device (status: %r)\n", Status));
78     return EFI_DEVICE_ERROR;
79   }
80   DataPtr = AllocateZeroPool (SERIAL_NUMBER_BLOCK_SIZE);
81   WriteBackDataCacheRange (DataPtr, SERIAL_NUMBER_BLOCK_SIZE);
82   Status = BlockIoProtocol->ReadBlocks (BlockIoProtocol, BlockIoProtocol->Media->MediaId,
83                                         SERIAL_NUMBER_LBA, SERIAL_NUMBER_BLOCK_SIZE,
84                                         DataPtr);
85   if (EFI_ERROR (Status)) {
86     DEBUG ((EFI_D_ERROR, "Warning: failed on reading blocks.\n"));
87     goto exit;
88   }
89   InvalidateDataCacheRange (DataPtr, SERIAL_NUMBER_BLOCK_SIZE);
90   Random = (struct RandomSerialNo *)DataPtr;
91   if (Random->Magic != RANDOM_MAGIC) {
92     VariableSize = SERIAL_NUMBER_LENGTH * sizeof (CHAR16);
93     Status = gRT->GetVariable (
94                     (CHAR16 *)L"SerialNo",
95                     &gHiKeyVariableGuid,
96                     NULL,
97                     &VariableSize,
98                     &DefaultSerialNo
99                     );
100     if (Status == EFI_NOT_FOUND) {
101       Status = gRT->SetVariable (
102                       (CHAR16*)L"SerialNo",
103                       &gHiKeyVariableGuid,
104                       EFI_VARIABLE_NON_VOLATILE       |
105                       EFI_VARIABLE_BOOTSERVICE_ACCESS |
106                       EFI_VARIABLE_RUNTIME_ACCESS,
107                       VariableSize,
108                       DefaultSerialNo
109                       );
110     }
111     CopyMem (mSerialNo, DefaultSerialNo, sizeof (DefaultSerialNo));
112   } else {
113     ZeroMem (DataUnicode, 32 * sizeof(CHAR16));
114     ZeroMem (SerialNoUnicode, 32 * sizeof(CHAR16));
115     AsciiStrToUnicodeStr (Random->SerialNo, SerialNoUnicode);
116     VariableSize = SERIAL_NUMBER_LENGTH * sizeof (CHAR16);
117     Status = gRT->GetVariable (
118                     (CHAR16 *)L"SerialNo",
119                     &gHiKeyVariableGuid,
120                     NULL,
121                     &VariableSize,
122                     &DataUnicode
123                     );
124     if ((Status == EFI_NOT_FOUND) || StrCmp (DataUnicode, SerialNoUnicode)) {
125       Status = gRT->SetVariable (
126                       (CHAR16*)L"SerialNo",
127                       &gHiKeyVariableGuid,
128                       EFI_VARIABLE_NON_VOLATILE       |
129                       EFI_VARIABLE_BOOTSERVICE_ACCESS |
130                       EFI_VARIABLE_RUNTIME_ACCESS,
131                       VariableSize,
132                       SerialNoUnicode
133                       );
134     }
135     CopyMem (mSerialNo, SerialNoUnicode, VariableSize);
136   }
137 exit:
138   FreePool (DataPtr);
139   return Status;
140 }
141 
142 EFI_STATUS
143 EFIAPI
GetSerialNo(OUT CHAR16 * SerialNo,OUT UINT8 * Length)144 GetSerialNo (
145   OUT CHAR16            *SerialNo,
146   OUT UINT8             *Length
147   )
148 {
149   EFI_STATUS             Status;
150   UINTN                  VariableSize;
151   CHAR16                 DataUnicode[32];
152 
153   if (SerialNo == NULL)
154     return EFI_INVALID_PARAMETER;
155   VariableSize = SERIAL_NUMBER_LENGTH * sizeof (CHAR16);
156   ZeroMem (DataUnicode, 32 * sizeof(CHAR16));
157   Status = gRT->GetVariable (
158                   (CHAR16 *)L"SerialNo",
159                   &gHiKeyVariableGuid,
160                   NULL,
161                   &VariableSize,
162                   &DataUnicode
163                   );
164   if (EFI_ERROR (Status)) {
165     return Status;
166   }
167   CopyMem (SerialNo, DataUnicode, VariableSize);
168   *Length = VariableSize;
169   return EFI_SUCCESS;
170 }
171 
172 EFI_STATUS
173 EFIAPI
UsbPhyInit(IN UINT8 Mode)174 UsbPhyInit (
175   IN UINT8     Mode
176   )
177 {
178   return HiKeyUsbPhyInit (Mode);
179 }
180 
181 DW_USB_PROTOCOL mDwUsbDevice = {
182   GetSerialNo,
183   UsbPhyInit
184 };
185 
186 EFI_STATUS
187 EFIAPI
HiKeyEntryPoint(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)188 HiKeyEntryPoint (
189   IN EFI_HANDLE         ImageHandle,
190   IN EFI_SYSTEM_TABLE   *SystemTable
191   )
192 {
193   EFI_STATUS           Status;
194 
195   Status = gBS->InstallProtocolInterface (
196 		  &ImageHandle,
197 		  &gDwUsbProtocolGuid,
198 		  EFI_NATIVE_INTERFACE,
199 		  &mDwUsbDevice
200 		  );
201   if (EFI_ERROR (Status)) {
202     return Status;
203   }
204 
205   HiKeyInitSerialNo ();
206   HiKeyInitPeripherals ();
207 
208   Status = HiKeyBootMenuInstall ();
209 
210   return Status;
211 }
212