1 /** @file
2 Firmware volume block driver for SPI device
3 
4 Copyright (c) 2013-2015 Intel Corporation.
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 #ifndef _FW_BLOCK_SERVICE_H
18 #define _FW_BLOCK_SERVICE_H
19 
20 
21 #include "SpiFlashDevice.h"
22 
23 //
24 // Statements that include other header files
25 
26 #include <Library/IoLib.h>
27 #include <Library/HobLib.h>
28 #include <Library/PcdLib.h>
29 #include <Library/UefiLib.h>
30 #include <Library/DebugLib.h>
31 #include <Library/BaseMemoryLib.h>
32 #include <Library/DevicePathLib.h>
33 #include <Library/UefiRuntimeLib.h>
34 #include <Library/UefiDriverEntryPoint.h>
35 #include <Library/UefiBootServicesTableLib.h>
36 #include <Library/UefiRuntimeServicesTableLib.h>
37 #include <Library/DxeServicesTableLib.h>
38 #include <Library/MemoryAllocationLib.h>
39 
40 #include <Guid/EventGroup.h>
41 #include <Guid/HobList.h>
42 #include <Guid/FirmwareFileSystem2.h>
43 #include <Guid/SystemNvDataGuid.h>
44 
45 #include <Protocol/SmmBase2.h>
46 #include <Protocol/LoadedImage.h>
47 #include <Protocol/PlatformSmmSpiReady.h>
48 
49 //
50 // Define two helper macro to extract the Capability field or Status field in FVB
51 // bit fields
52 //
53 #define EFI_FVB2_CAPABILITIES (EFI_FVB2_READ_DISABLED_CAP | \
54                               EFI_FVB2_READ_ENABLED_CAP | \
55                               EFI_FVB2_WRITE_DISABLED_CAP | \
56                               EFI_FVB2_WRITE_ENABLED_CAP | \
57                               EFI_FVB2_LOCK_CAP \
58                               )
59 
60 #define EFI_FVB2_STATUS (EFI_FVB2_READ_STATUS | EFI_FVB2_WRITE_STATUS | EFI_FVB2_LOCK_STATUS)
61 
62 #define EFI_INTERNAL_POINTER  0x00000004
63 #define FVB_PHYSICAL  0
64 #define FVB_VIRTUAL   1
65 
66 typedef struct {
67   EFI_LOCK                    FvbDevLock;
68   UINTN                       FvBase[2];
69   UINTN                       FvWriteBase[2];
70   UINTN                       NumOfBlocks;
71   BOOLEAN                     WriteEnabled;
72   EFI_FIRMWARE_VOLUME_HEADER  VolumeHeader;
73 } EFI_FW_VOL_INSTANCE;
74 
75 typedef struct {
76   UINT32                NumFv;
77   EFI_FW_VOL_INSTANCE   *FvInstance[2];
78   UINT8                 *FvbScratchSpace[2];
79   EFI_SPI_PROTOCOL      *SpiProtocol;
80   EFI_SPI_PROTOCOL      *SmmSpiProtocol;
81 } ESAL_FWB_GLOBAL;
82 
83 //
84 // SPI default opcode slots
85 //
86 #define SPI_OPCODE_JEDEC_ID_INDEX        0
87 #define SPI_OPCODE_READ_ID_INDEX         1
88 #define SPI_OPCODE_WRITE_S_INDEX         2
89 #define SPI_OPCODE_WRITE_INDEX           3
90 #define SPI_OPCODE_READ_INDEX            4
91 #define SPI_OPCODE_ERASE_INDEX           5
92 #define SPI_OPCODE_READ_S_INDEX          6
93 #define SPI_OPCODE_CHIP_ERASE_INDEX      7
94 
95 #define SPI_ERASE_SECTOR_SIZE            SIZE_4KB  //This is the chipset requirement
96 
97 //
98 // Fvb Protocol instance data
99 //
100 #define FVB_DEVICE_FROM_THIS(a)         CR (a, EFI_FW_VOL_BLOCK_DEVICE, FwVolBlockInstance, FVB_DEVICE_SIGNATURE)
101 #define FVB_EXTEND_DEVICE_FROM_THIS(a)  CR (a, EFI_FW_VOL_BLOCK_DEVICE, FvbExtension, FVB_DEVICE_SIGNATURE)
102 #define FVB_DEVICE_SIGNATURE            SIGNATURE_32 ('F', 'V', 'B', 'C')
103 //
104 // Device Path
105 //
106 #define EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE    0xff
107 #define EfiDevicePathType(a)                  (((a)->Type) & 0x7f)
108 #define EfiIsDevicePathEndType(a)             (EfiDevicePathType (a) == 0x7f)
109 #define EfiIsDevicePathEndSubType(a)          ((a)->SubType == EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE)
110 #define EfiIsDevicePathEnd(a)                 (EfiIsDevicePathEndType (a) && EfiIsDevicePathEndSubType (a))
111 
112 typedef struct {
113   MEMMAP_DEVICE_PATH        MemMapDevPath;
114   EFI_DEVICE_PATH_PROTOCOL  EndDevPath;
115 } FV_DEVICE_PATH;
116 
117 //
118 // UEFI Specification define FV device path format if FV provide name GUID in extension header
119 //
120 typedef struct {
121   MEDIA_FW_VOL_DEVICE_PATH    FvDevPath;
122   EFI_DEVICE_PATH_PROTOCOL    EndDevPath;
123 } UEFI_FV_DEVICE_PATH;
124 
125 typedef struct {
126   UINTN                               Signature;
127   FV_DEVICE_PATH                      FvDevicePath;
128   UEFI_FV_DEVICE_PATH                 UefiFvDevicePath;
129   UINTN                               Instance;
130   EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  FwVolBlockInstance;
131 } EFI_FW_VOL_BLOCK_DEVICE;
132 
133 typedef struct {
134   EFI_PHYSICAL_ADDRESS        BaseAddress;
135   EFI_FIRMWARE_VOLUME_HEADER  FvbInfo;
136   //
137   // EFI_FV_BLOCK_MAP_ENTRY                ExtraBlockMap[n];//n=0
138   //
139   EFI_FV_BLOCK_MAP_ENTRY      End[1];
140 } EFI_FVB_MEDIA_INFO;
141 
142 VOID
143 FvbVirtualddressChangeEvent (
144   IN EFI_EVENT        Event,
145   IN VOID             *Context
146   );
147 
148 EFI_STATUS
149 GetFvbInfo (
150   IN  EFI_PHYSICAL_ADDRESS              FvBaseAddress,
151   OUT EFI_FIRMWARE_VOLUME_HEADER        **FvbInfo
152   );
153 
154 BOOLEAN
155 SetPlatformFvbLock (
156   IN UINTN                              LbaAddress
157   );
158 
159 EFI_STATUS
160 FvbReadBlock (
161   IN UINTN                              Instance,
162   IN EFI_LBA                            Lba,
163   IN UINTN                              BlockOffset,
164   IN OUT UINTN                          *NumBytes,
165   IN UINT8                              *Buffer,
166   IN ESAL_FWB_GLOBAL                    *Global,
167   IN BOOLEAN                            Virtual
168   );
169 
170 EFI_STATUS
171 FvbWriteBlock (
172   IN UINTN                              Instance,
173   IN EFI_LBA                            Lba,
174   IN UINTN                              BlockOffset,
175   IN OUT UINTN                          *NumBytes,
176   IN UINT8                              *Buffer,
177   IN ESAL_FWB_GLOBAL                    *Global,
178   IN BOOLEAN                            Virtual
179   );
180 
181 EFI_STATUS
182 FvbEraseBlock (
183   IN UINTN                              Instance,
184   IN EFI_LBA                            Lba,
185   IN ESAL_FWB_GLOBAL                    *Global,
186   IN BOOLEAN                            Virtual
187   );
188 
189 EFI_STATUS
190 FvbSetVolumeAttributes (
191   IN UINTN                              Instance,
192   IN OUT EFI_FVB_ATTRIBUTES_2             *Attributes,
193   IN ESAL_FWB_GLOBAL                    *Global,
194   IN BOOLEAN                            Virtual
195   );
196 
197 EFI_STATUS
198 FvbGetVolumeAttributes (
199   IN UINTN                              Instance,
200   OUT EFI_FVB_ATTRIBUTES_2                *Attributes,
201   IN ESAL_FWB_GLOBAL                    *Global,
202   IN BOOLEAN                            Virtual
203   );
204 
205 EFI_STATUS
206 FvbGetPhysicalAddress (
207   IN UINTN                              Instance,
208   OUT EFI_PHYSICAL_ADDRESS              *Address,
209   IN ESAL_FWB_GLOBAL                    *Global,
210   IN BOOLEAN                            Virtual
211   );
212 
213 EFI_STATUS
214 FvbInitialize (
215   IN EFI_HANDLE                         ImageHandle,
216   IN EFI_SYSTEM_TABLE                   *SystemTable
217   );
218 
219 VOID
220 FvbClassAddressChangeEvent (
221   IN EFI_EVENT                          Event,
222   IN VOID                               *Context
223   );
224 
225 EFI_STATUS
226 FvbSpecificInitialize (
227   IN  ESAL_FWB_GLOBAL                   *mFvbModuleGlobal
228   );
229 
230 EFI_STATUS
231 FvbGetLbaAddress (
232   IN  UINTN                             Instance,
233   IN  EFI_LBA                           Lba,
234   OUT UINTN                             *LbaAddress,
235   OUT UINTN                             *LbaWriteAddress,
236   OUT UINTN                             *LbaLength,
237   OUT UINTN                             *NumOfBlocks,
238   IN  ESAL_FWB_GLOBAL                   *Global,
239   IN  BOOLEAN                           Virtual
240   );
241 
242 EFI_STATUS
243 FvbEraseCustomBlockRange (
244   IN UINTN                              Instance,
245   IN EFI_LBA                            StartLba,
246   IN UINTN                              OffsetStartLba,
247   IN EFI_LBA                            LastLba,
248   IN UINTN                              OffsetLastLba,
249   IN ESAL_FWB_GLOBAL                    *Global,
250   IN BOOLEAN                            Virtual
251   );
252 
253 //
254 // Protocol APIs
255 //
256 EFI_STATUS
257 EFIAPI
258 FvbProtocolGetAttributes (
259   IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
260   OUT EFI_FVB_ATTRIBUTES_2                *Attributes
261   );
262 
263 EFI_STATUS
264 EFIAPI
265 FvbProtocolSetAttributes (
266   IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
267   IN OUT EFI_FVB_ATTRIBUTES_2             *Attributes
268   );
269 
270 EFI_STATUS
271 EFIAPI
272 FvbProtocolGetPhysicalAddress (
273   IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
274   OUT EFI_PHYSICAL_ADDRESS              *Address
275   );
276 
277 EFI_STATUS
278 FvbProtocolGetBlockSize (
279   IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
280   IN  EFI_LBA                           Lba,
281   OUT UINTN                             *BlockSize,
282   OUT UINTN                             *NumOfBlocks
283   );
284 
285 EFI_STATUS
286 EFIAPI
287 FvbProtocolRead (
288   IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
289   IN EFI_LBA                            Lba,
290   IN UINTN                              Offset,
291   IN OUT UINTN                          *NumBytes,
292   IN UINT8                              *Buffer
293   );
294 
295 EFI_STATUS
296 EFIAPI
297 FvbProtocolWrite (
298   IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
299   IN EFI_LBA                            Lba,
300   IN UINTN                              Offset,
301   IN OUT UINTN                          *NumBytes,
302   IN UINT8                              *Buffer
303   );
304 
305 EFI_STATUS
306 EFIAPI
307 FvbProtocolEraseBlocks (
308   IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL         *This,
309   ...
310   );
311 
312 extern SPI_INIT_TABLE   mSpiInitTable[];
313 
314 #endif
315