3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 Ia32 platform related code to support FtwLite..
28 // MACROs for boot block update
30 #define BOOT_BLOCK_BASE 0xFFFF0000
35 #define LPC_BUS_NUMBER 0x00
36 #define LPC_DEVICE_NUMBER 0x1F
41 #define GEN_STATUS 0xD4
42 #define TOP_SWAP_BIT (1 << 13)
53 Read PCI register value.
57 Offset - Offset of the register
67 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
70 Status
= gBS
->LocateProtocol (&gEfiPciRootBridgeIoProtocolGuid
, NULL
, (VOID
**) &PciRootBridgeIo
);
71 if (EFI_ERROR (Status
)) {
72 DEBUG ((EFI_D_ERROR
, "FtwLite: Locate PCI root bridge io protocol - %r", Status
));
76 Status
= PciRootBridgeIo
->Pci
.Read (
79 EFI_PCI_ADDRESS (LPC_BUS_NUMBER
,
86 ASSERT_EFI_ERROR (Status
);
94 IN EFI_FTW_LITE_DEVICE
*FtwLiteDevice
,
95 OUT BOOLEAN
*SwapState
105 FtwLiteDevice - Calling context
106 SwapState - Swap state
110 EFI_SUCCESS - State successfully got
115 // Top swap status is 13 bit
117 *SwapState
= (BOOLEAN
) ((ReadPciRegister (GEN_STATUS
) & TOP_SWAP_BIT
) != 0);
125 IN EFI_FTW_LITE_DEVICE
*FtwLiteDevice
,
134 FtwLiteDevice - Indicates a pointer to the calling context.
135 TopSwap - New swap state
138 EFI_SUCCESS - The function completed successfully
141 the Top-Swap bit (bit 13, D31: F0, Offset D4h). Note that
142 software will not be able to clear the Top-Swap bit until the system is
143 rebooted without GNT[A]# being pulled down.
148 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
152 // Top-Swap bit (bit 13, D31: F0, Offset D4h)
154 GenStatus
= ReadPciRegister (GEN_STATUS
);
157 // Set 13 bit, according to input NewSwapState
160 GenStatus
|= TOP_SWAP_BIT
;
162 GenStatus
&= ~TOP_SWAP_BIT
;
165 Status
= gBS
->LocateProtocol (&gEfiPciRootBridgeIoProtocolGuid
, NULL
, (VOID
**) &PciRootBridgeIo
);
166 if (EFI_ERROR (Status
)) {
167 DEBUG ((EFI_D_ERROR
, "FtwLite: Locate PCI root bridge io protocol - %r", Status
));
171 // Write back the GenStatus register
173 Status
= PciRootBridgeIo
->Pci
.Write (
188 DEBUG ((EFI_D_ERROR
, "SAR: Set top swap\n"));
190 DEBUG ((EFI_D_ERROR
, "SAR: Clear top swap\n"));
199 EFI_FTW_LITE_DEVICE
*FtwLiteDevice
,
200 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL
*FvBlock
,
207 Check whether the block is a boot block.
211 FtwLiteDevice - Calling context
212 FvBlock - Fvb protocol instance
217 Is a boot block or not
222 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL
*BootFvb
;
224 Status
= GetFvbByAddress (BOOT_BLOCK_BASE
, &BootFvb
);
225 if (EFI_ERROR (Status
)) {
231 return (BOOLEAN
) (FvBlock
== BootFvb
);
235 FlushSpareBlockToBootBlock (
236 EFI_FTW_LITE_DEVICE
*FtwLiteDevice
241 Copy the content of spare block to a boot block. Size is FTW_BLOCK_SIZE.
242 Spare block is accessed by FTW backup FVB protocol interface. LBA is
243 FtwLiteDevice->FtwSpareLba.
244 Boot block is accessed by BootFvb protocol interface. LBA is 0.
247 FtwLiteDevice - The private data of FTW_LITE driver
250 EFI_SUCCESS - Spare block content is copied to boot block
251 EFI_INVALID_PARAMETER - Input parameter error
252 EFI_OUT_OF_RESOURCES - Allocate memory error
253 EFI_ABORTED - The function could not complete successfully
256 FTW will do extra work on boot block update.
257 FTW should depend on a protocol of EFI_ADDRESS_RANGE_SWAP_PROTOCOL,
258 which is produced by a chipset driver.
260 FTW updating boot block steps:
261 1. Erase top swap block (0xFFFE-0xFFFEFFFF) and write data to it ready
262 2. Read data from top swap block to memory buffer
263 3. SetSwapState(EFI_SWAPPED)
264 4. Erasing boot block (0xFFFF-0xFFFFFFFF)
265 5. Programming boot block until the boot block is ok.
266 6. SetSwapState(UNSWAPPED)
269 1. Since the SwapState bit is saved in CMOS, FTW can restore and continue
270 even in the scenario of power failure.
271 2. FTW shall not allow to update boot block when battery state is error.
282 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL
*BootFvb
;
286 // Allocate a memory buffer
288 Length
= FtwLiteDevice
->SpareAreaLength
;
289 Buffer
= AllocatePool (Length
);
290 if (Buffer
== NULL
) {
293 // Get TopSwap bit state
295 Status
= GetSwapState (FtwLiteDevice
, &TopSwap
);
296 if (EFI_ERROR (Status
)) {
297 DEBUG ((EFI_D_ERROR
, "FtwLite: Get Top Swapped status - %r\n", Status
));
298 gBS
->FreePool (Buffer
);
304 // Get FVB of current boot block
306 Status
= GetFvbByAddress (FtwLiteDevice
->SpareAreaAddress
+ FTW_BLOCK_SIZE
, &BootFvb
);
307 if (EFI_ERROR (Status
)) {
308 gBS
->FreePool (Buffer
);
312 // Read data from current boot block
316 for (Index
= 0; Index
< FtwLiteDevice
->NumberOfSpareBlock
; Index
+= 1) {
317 Count
= FtwLiteDevice
->SizeOfSpareBlock
;
318 Status
= BootFvb
->Read (
325 if (EFI_ERROR (Status
)) {
326 gBS
->FreePool (Buffer
);
335 // Read data from spare block
338 for (Index
= 0; Index
< FtwLiteDevice
->NumberOfSpareBlock
; Index
+= 1) {
339 Count
= FtwLiteDevice
->SizeOfSpareBlock
;
340 Status
= FtwLiteDevice
->FtwBackupFvb
->Read (
341 FtwLiteDevice
->FtwBackupFvb
,
342 FtwLiteDevice
->FtwSpareLba
+ Index
,
347 if (EFI_ERROR (Status
)) {
348 gBS
->FreePool (Buffer
);
357 Status
= SetSwapState (FtwLiteDevice
, TRUE
);
358 DEBUG ((EFI_D_ERROR
, "FtwLite: Set Swap State - %r\n", Status
));
359 ASSERT_EFI_ERROR (Status
);
362 // Erase boot block. After setting TopSwap bit, it's spare block now!
364 Status
= FtwEraseSpareBlock (FtwLiteDevice
);
365 if (EFI_ERROR (Status
)) {
366 gBS
->FreePool (Buffer
);
370 // Write memory buffer to currenet spare block
373 for (Index
= 0; Index
< FtwLiteDevice
->NumberOfSpareBlock
; Index
+= 1) {
374 Count
= FtwLiteDevice
->SizeOfSpareBlock
;
375 Status
= FtwLiteDevice
->FtwBackupFvb
->Write (
376 FtwLiteDevice
->FtwBackupFvb
,
377 FtwLiteDevice
->FtwSpareLba
+ Index
,
382 if (EFI_ERROR (Status
)) {
383 DEBUG ((EFI_D_FTW_LITE
, "FtwLite: FVB Write boot block - %r\n", Status
));
384 gBS
->FreePool (Buffer
);
391 gBS
->FreePool (Buffer
);
396 Status
= SetSwapState (FtwLiteDevice
, FALSE
);
397 DEBUG ((EFI_D_ERROR
, "FtwLite: Clear Swap State - %r\n", Status
));
398 ASSERT_EFI_ERROR (Status
);