3 Ia32 platform related code to support FtwLite.
5 Copyright (c) 2006 - 2008, Intel Corporation
6 All rights reserved. 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
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.
20 // MACROs for boot block update
22 #define BOOT_BLOCK_BASE 0xFFFF0000
27 #define LPC_BUS_NUMBER 0x00
28 #define LPC_DEVICE_NUMBER 0x1F
33 #define GEN_STATUS 0xD4
34 #define TOP_SWAP_BIT (1 << 13)
45 Read PCI register value.
49 Offset - Offset of the register
59 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
62 Status
= gBS
->LocateProtocol (&gEfiPciRootBridgeIoProtocolGuid
, NULL
, (VOID
**) &PciRootBridgeIo
);
63 if (EFI_ERROR (Status
)) {
64 DEBUG ((EFI_D_ERROR
, "FtwLite: Locate PCI root bridge io protocol - %r", Status
));
68 Status
= PciRootBridgeIo
->Pci
.Read (
80 ASSERT_EFI_ERROR (Status
);
88 IN EFI_FTW_LITE_DEVICE
*FtwLiteDevice
,
89 OUT BOOLEAN
*SwapState
99 FtwLiteDevice - Calling context
100 SwapState - Swap state
104 EFI_SUCCESS - State successfully got
109 // Top swap status is 13 bit
111 *SwapState
= (BOOLEAN
) ((ReadPciRegister (GEN_STATUS
) & TOP_SWAP_BIT
) != 0);
119 IN EFI_FTW_LITE_DEVICE
*FtwLiteDevice
,
128 FtwLiteDevice - Indicates a pointer to the calling context.
129 TopSwap - New swap state
132 EFI_SUCCESS - The function completed successfully
135 the Top-Swap bit (bit 13, D31: F0, Offset D4h). Note that
136 software will not be able to clear the Top-Swap bit until the system is
137 rebooted without GNT[A]# being pulled down.
142 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
146 // Top-Swap bit (bit 13, D31: F0, Offset D4h)
148 GenStatus
= ReadPciRegister (GEN_STATUS
);
151 // Set 13 bit, according to input NewSwapState
154 GenStatus
|= TOP_SWAP_BIT
;
156 GenStatus
&= ~TOP_SWAP_BIT
;
159 Status
= gBS
->LocateProtocol (&gEfiPciRootBridgeIoProtocolGuid
, NULL
, (VOID
**) &PciRootBridgeIo
);
160 if (EFI_ERROR (Status
)) {
161 DEBUG ((EFI_D_ERROR
, "FtwLite: Locate PCI root bridge io protocol - %r", Status
));
165 // Write back the GenStatus register
167 Status
= PciRootBridgeIo
->Pci
.Write (
182 DEBUG ((EFI_D_ERROR
, "SAR: Set top swap\n"));
184 DEBUG ((EFI_D_ERROR
, "SAR: Clear top swap\n"));
193 EFI_FTW_LITE_DEVICE
*FtwLiteDevice
,
194 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL
*FvBlock
,
201 Check whether the block is a boot block.
205 FtwLiteDevice - Calling context
206 FvBlock - Fvb protocol instance
211 Is a boot block or not
216 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL
*BootFvb
;
218 Status
= GetFvbByAddress (BOOT_BLOCK_BASE
, &BootFvb
);
219 if (EFI_ERROR (Status
)) {
225 return (BOOLEAN
) (FvBlock
== BootFvb
);
229 FlushSpareBlockToBootBlock (
230 EFI_FTW_LITE_DEVICE
*FtwLiteDevice
235 Copy the content of spare block to a boot block. Size is FTW_BLOCK_SIZE.
236 Spare block is accessed by FTW backup FVB protocol interface. LBA is
237 FtwLiteDevice->FtwSpareLba.
238 Boot block is accessed by BootFvb protocol interface. LBA is 0.
241 FtwLiteDevice - The private data of FTW_LITE driver
244 EFI_SUCCESS - Spare block content is copied to boot block
245 EFI_INVALID_PARAMETER - Input parameter error
246 EFI_OUT_OF_RESOURCES - Allocate memory error
247 EFI_ABORTED - The function could not complete successfully
250 FTW will do extra work on boot block update.
251 FTW should depend on a protocol of EFI_ADDRESS_RANGE_SWAP_PROTOCOL,
252 which is produced by a chipset driver.
254 FTW updating boot block steps:
255 1. Erase top swap block (0xFFFE-0xFFFEFFFF) and write data to it ready
256 2. Read data from top swap block to memory buffer
257 3. SetSwapState(EFI_SWAPPED)
258 4. Erasing boot block (0xFFFF-0xFFFFFFFF)
259 5. Programming boot block until the boot block is ok.
260 6. SetSwapState(UNSWAPPED)
263 1. Since the SwapState bit is saved in CMOS, FTW can restore and continue
264 even in the scenario of power failure.
265 2. FTW shall not allow to update boot block when battery state is error.
276 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL
*BootFvb
;
280 // Allocate a memory buffer
282 Length
= FtwLiteDevice
->SpareAreaLength
;
283 Buffer
= AllocatePool (Length
);
284 if (Buffer
== NULL
) {
287 // Get TopSwap bit state
289 Status
= GetSwapState (FtwLiteDevice
, &TopSwap
);
290 if (EFI_ERROR (Status
)) {
291 DEBUG ((EFI_D_ERROR
, "FtwLite: Get Top Swapped status - %r\n", Status
));
298 // Get FVB of current boot block
300 Status
= GetFvbByAddress (FtwLiteDevice
->SpareAreaAddress
+ FTW_BLOCK_SIZE
, &BootFvb
);
301 if (EFI_ERROR (Status
)) {
306 // Read data from current boot block
310 for (Index
= 0; Index
< FtwLiteDevice
->NumberOfSpareBlock
; Index
+= 1) {
311 Count
= FtwLiteDevice
->SizeOfSpareBlock
;
312 Status
= BootFvb
->Read (
319 if (EFI_ERROR (Status
)) {
329 // Read data from spare block
332 for (Index
= 0; Index
< FtwLiteDevice
->NumberOfSpareBlock
; Index
+= 1) {
333 Count
= FtwLiteDevice
->SizeOfSpareBlock
;
334 Status
= FtwLiteDevice
->FtwBackupFvb
->Read (
335 FtwLiteDevice
->FtwBackupFvb
,
336 FtwLiteDevice
->FtwSpareLba
+ Index
,
341 if (EFI_ERROR (Status
)) {
351 Status
= SetSwapState (FtwLiteDevice
, TRUE
);
352 DEBUG ((EFI_D_ERROR
, "FtwLite: Set Swap State - %r\n", Status
));
353 ASSERT_EFI_ERROR (Status
);
356 // Erase boot block. After setting TopSwap bit, it's spare block now!
358 Status
= FtwEraseSpareBlock (FtwLiteDevice
);
359 if (EFI_ERROR (Status
)) {
364 // Write memory buffer to currenet spare block
367 for (Index
= 0; Index
< FtwLiteDevice
->NumberOfSpareBlock
; Index
+= 1) {
368 Count
= FtwLiteDevice
->SizeOfSpareBlock
;
369 Status
= FtwLiteDevice
->FtwBackupFvb
->Write (
370 FtwLiteDevice
->FtwBackupFvb
,
371 FtwLiteDevice
->FtwSpareLba
+ Index
,
376 if (EFI_ERROR (Status
)) {
377 DEBUG ((EFI_D_FTW_LITE
, "FtwLite: FVB Write boot block - %r\n", Status
));
390 Status
= SetSwapState (FtwLiteDevice
, FALSE
);
391 DEBUG ((EFI_D_ERROR
, "FtwLite: Clear Swap State - %r\n", Status
));
392 ASSERT_EFI_ERROR (Status
);