2 Generic driver using Hardware Sequencing registers.
4 Copyright (c) 2017-2021, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
10 SPI_INSTANCE
*mSpiInstance
= NULL
;
13 Get SPI Instance from library global data..
15 @retval SpiInstance Return SPI instance
22 if (mSpiInstance
== NULL
) {
23 mSpiInstance
= AllocatePool (sizeof(SPI_INSTANCE
));
24 if (mSpiInstance
== NULL
) {
27 ZeroMem (mSpiInstance
, sizeof(SPI_INSTANCE
));
35 Initialize an SPI library.
37 @retval EFI_SUCCESS The protocol instance was properly initialized
38 @retval EFI_NOT_FOUND The expected SPI info could not be found
48 SPI_INSTANCE
*SpiInstance
;
49 EFI_HOB_GUID_TYPE
*GuidHob
;
50 SPI_FLASH_INFO
*SpiFlashInfo
;
55 GuidHob
= GetFirstGuidHob (&gSpiFlashInfoGuid
);
56 if (GuidHob
== NULL
) {
60 SpiFlashInfo
= (SPI_FLASH_INFO
*) GET_GUID_HOB_DATA (GuidHob
);
63 // Initialize the SPI instance
65 SpiInstance
= GetSpiInstance ();
66 if (SpiInstance
== NULL
) {
69 DEBUG ((DEBUG_INFO
, "SpiInstance = %08X\n", SpiInstance
));
71 SpiInstance
->Signature
= SC_SPI_PRIVATE_DATA_SIGNATURE
;
72 SpiInstance
->Handle
= NULL
;
75 // Check the SPI address
77 if ((SpiFlashInfo
->SpiAddress
.AddressSpaceId
!= EFI_ACPI_3_0_PCI_CONFIGURATION_SPACE
) ||
78 (SpiFlashInfo
->SpiAddress
.RegisterBitWidth
!= 32) ||
79 (SpiFlashInfo
->SpiAddress
.RegisterBitOffset
!= 0) ||
80 (SpiFlashInfo
->SpiAddress
.AccessSize
!= EFI_ACPI_3_0_DWORD
)){
81 DEBUG ((DEBUG_ERROR
, "SPI FLASH HOB is not expected. need check the hob or enhance SPI flash driver.\n"));
83 SpiInstance
->PchSpiBase
= (UINT32
)(UINTN
)SpiFlashInfo
->SpiAddress
.Address
;
84 SpiInstance
->Flags
= SpiFlashInfo
->Flags
;
85 DEBUG ((DEBUG_INFO
, "PchSpiBase at 0x%x\n", SpiInstance
->PchSpiBase
));
87 ScSpiBar0
= AcquireSpiBar0 (SpiInstance
->PchSpiBase
);
88 DEBUG ((DEBUG_INFO
, "ScSpiBar0 at 0x%08X\n", ScSpiBar0
));
94 if ((MmioRead32 (ScSpiBar0
+ R_SPI_HSFS
) & B_SPI_HSFS_FDV
) == 0) {
95 DEBUG ((DEBUG_ERROR
, "SPI Flash descriptor invalid, cannot use Hardware Sequencing registers!\n"));
99 MmioOr32 (SpiInstance
->PchSpiBase
+ PCI_COMMAND_OFFSET
, EFI_PCI_COMMAND_MEMORY_SPACE
);
100 SpiInstance
->RegionPermission
= MmioRead16 (ScSpiBar0
+ R_SPI_FRAP
);
101 SpiInstance
->SfdpVscc0Value
= MmioRead32 (ScSpiBar0
+ R_SPI_LVSCC
);
102 SpiInstance
->SfdpVscc1Value
= MmioRead32 (ScSpiBar0
+ R_SPI_UVSCC
);
105 // Select to Flash Map 0 Register to get the number of flash Component
108 ScSpiBar0
+ R_SPI_FDOC
,
109 (UINT32
) (~(B_SPI_FDOC_FDSS_MASK
| B_SPI_FDOC_FDSI_MASK
)),
110 (UINT32
) (V_SPI_FDOC_FDSS_FSDM
| R_SPI_FDBAR_FLASH_MAP0
)
114 // Copy Zero based Number Of Components
116 SpiInstance
->NumberOfComponents
= (UINT8
) ((MmioRead16 (ScSpiBar0
+ R_SPI_FDOD
) & B_SPI_FDBAR_NC
) >> N_SPI_FDBAR_NC
);
119 ScSpiBar0
+ R_SPI_FDOC
,
120 (UINT32
) (~(B_SPI_FDOC_FDSS_MASK
| B_SPI_FDOC_FDSI_MASK
)),
121 (UINT32
) (V_SPI_FDOC_FDSS_COMP
| R_SPI_FCBA_FLCOMP
)
125 // Copy Component 0 Density
127 Comp0Density
= (UINT8
) MmioRead32 (ScSpiBar0
+ R_SPI_FDOD
) & B_SPI_FLCOMP_COMP1_MASK
;
128 SpiInstance
->Component1StartAddr
= (UINT32
) (SIZE_512KB
<< Comp0Density
);
131 // Select FLASH_MAP1 to get Flash SC Strap Base Address
134 (ScSpiBar0
+ R_SPI_FDOC
),
135 (UINT32
) (~(B_SPI_FDOC_FDSS_MASK
| B_SPI_FDOC_FDSI_MASK
)),
136 (UINT32
) (V_SPI_FDOC_FDSS_FSDM
| R_SPI_FDBAR_FLASH_MAP1
)
139 SpiInstance
->StrapBaseAddress
= MmioRead32 (ScSpiBar0
+ R_SPI_FDOD
) & B_SPI_FDBAR_FPSBA
;
142 // Align FPSBA with address bits for the SC Strap portion of flash descriptor
144 SpiInstance
->StrapBaseAddress
&= B_SPI_FDBAR_FPSBA
;
151 Read data from the flash part.
153 @param[in] FlashRegionType The Flash Region type for flash cycle which is listed in the Descriptor.
154 @param[in] Address The Flash Linear Address must fall within a region for which BIOS has access permissions.
155 @param[in] ByteCount Number of bytes in the data portion of the SPI cycle.
156 @param[out] Buffer The Pointer to caller-allocated buffer containing the data received.
157 It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
159 @retval EFI_SUCCESS Command succeed.
160 @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
161 @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
166 IN FLASH_REGION_TYPE FlashRegionType
,
174 Status
= SendSpiCmd (FlashRegionType
, FlashCycleRead
, Address
, ByteCount
, Buffer
);
179 Write data to the flash part.
181 @param[in] FlashRegionType The Flash Region type for flash cycle which is listed in the Descriptor.
182 @param[in] Address The Flash Linear Address must fall within a region for which BIOS has access permissions.
183 @param[in] ByteCount Number of bytes in the data portion of the SPI cycle.
184 @param[in] Buffer Pointer to caller-allocated buffer containing the data sent during the SPI cycle.
186 @retval EFI_SUCCESS Command succeed.
187 @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
188 @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
193 IN FLASH_REGION_TYPE FlashRegionType
,
201 Status
= SendSpiCmd (FlashRegionType
, FlashCycleWrite
, Address
, ByteCount
, Buffer
);
206 Erase some area on the flash part.
208 @param[in] FlashRegionType The Flash Region type for flash cycle which is listed in the Descriptor.
209 @param[in] Address The Flash Linear Address must fall within a region for which BIOS has access permissions.
210 @param[in] ByteCount Number of bytes in the data portion of the SPI cycle.
212 @retval EFI_SUCCESS Command succeed.
213 @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
214 @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
219 IN FLASH_REGION_TYPE FlashRegionType
,
226 Status
= SendSpiCmd (FlashRegionType
, FlashCycleErase
, Address
, ByteCount
, NULL
);
231 Read SFDP data from the flash part.
233 @param[in] ComponentNumber The Component Number for chip select
234 @param[in] ByteCount Number of bytes in SFDP data portion of the SPI cycle, the max number is 64
235 @param[out] SfdpData The Pointer to caller-allocated buffer containing the SFDP data received
236 It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
238 @retval EFI_SUCCESS Command succeed.
239 @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
240 @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
245 IN UINT8 ComponentNumber
,
252 SPI_INSTANCE
*SpiInstance
;
254 SpiInstance
= GetSpiInstance ();
255 if (SpiInstance
== NULL
) {
256 return EFI_DEVICE_ERROR
;
259 if ((ByteCount
> 64) || (ComponentNumber
> SpiInstance
->NumberOfComponents
)) {
261 return EFI_INVALID_PARAMETER
;
265 if (ComponentNumber
== FlashComponent1
) {
266 Address
= SpiInstance
->Component1StartAddr
;
269 Status
= SendSpiCmd (0, FlashCycleReadSfdp
, Address
, ByteCount
, SfdpData
);
274 Read Jedec Id from the flash part.
276 @param[in] ComponentNumber The Component Number for chip select
277 @param[in] ByteCount Number of bytes in JedecId data portion of the SPI cycle, the data size is 3 typically
278 @param[out] JedecId The Pointer to caller-allocated buffer containing JEDEC ID received
279 It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
281 @retval EFI_SUCCESS Command succeed.
282 @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
283 @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
287 SpiFlashReadJedecId (
288 IN UINT8 ComponentNumber
,
295 SPI_INSTANCE
*SpiInstance
;
297 SpiInstance
= GetSpiInstance ();
298 if (SpiInstance
== NULL
) {
299 return EFI_DEVICE_ERROR
;
302 if (ComponentNumber
> SpiInstance
->NumberOfComponents
) {
304 return EFI_INVALID_PARAMETER
;
308 if (ComponentNumber
== FlashComponent1
) {
309 Address
= SpiInstance
->Component1StartAddr
;
312 Status
= SendSpiCmd (0, FlashCycleReadJedecId
, Address
, ByteCount
, JedecId
);
317 Write the status register in the flash part.
319 @param[in] ByteCount Number of bytes in Status data portion of the SPI cycle, the data size is 1 typically
320 @param[in] StatusValue The Pointer to caller-allocated buffer containing the value of Status register writing
322 @retval EFI_SUCCESS Command succeed.
323 @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
324 @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
328 SpiFlashWriteStatus (
330 IN UINT8
*StatusValue
335 Status
= SendSpiCmd (0, FlashCycleWriteStatus
, 0, ByteCount
, StatusValue
);
340 Read status register in the flash part.
342 @param[in] ByteCount Number of bytes in Status data portion of the SPI cycle, the data size is 1 typically
343 @param[out] StatusValue The Pointer to caller-allocated buffer containing the value of Status register received.
345 @retval EFI_SUCCESS Command succeed.
346 @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
347 @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
353 OUT UINT8
*StatusValue
358 Status
= SendSpiCmd (0, FlashCycleReadStatus
, 0, ByteCount
, StatusValue
);
363 Read SC Soft Strap Values
365 @param[in] SoftStrapAddr SC Soft Strap address offset from FPSBA.
366 @param[in] ByteCount Number of bytes in SoftStrap data portion of the SPI cycle
367 @param[out] SoftStrapValue The Pointer to caller-allocated buffer containing SC Soft Strap Value.
368 It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
370 @retval EFI_SUCCESS Command succeed.
371 @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
372 @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
376 SpiReadPchSoftStrap (
377 IN UINT32 SoftStrapAddr
,
379 OUT UINT8
*SoftStrapValue
382 UINT32 StrapFlashAddr
;
384 SPI_INSTANCE
*SpiInstance
;
386 SpiInstance
= GetSpiInstance ();
387 if (SpiInstance
== NULL
) {
388 return EFI_DEVICE_ERROR
;
391 ASSERT (SpiInstance
->StrapBaseAddress
!= 0);
393 // SC Strap Flash Address = FPSBA + RamAddr
395 StrapFlashAddr
= SpiInstance
->StrapBaseAddress
+ SoftStrapAddr
;
397 Status
= SendSpiCmd (FlashRegionDescriptor
, FlashCycleRead
, StrapFlashAddr
, ByteCount
, SoftStrapValue
);
402 This function sends the programmed SPI command to the slave device.
404 @param[in] FlashRegionType The SPI Region type for flash cycle which is listed in the Descriptor
405 @param[in] FlashCycleType The Flash SPI cycle type list in HSFC (Hardware Sequencing Flash Control Register) register
406 @param[in] Address The Flash Linear Address must fall within a region for which BIOS has access permissions.
407 @param[in] ByteCount Number of bytes in the data portion of the SPI cycle.
408 @param[in,out] Buffer Pointer to caller-allocated buffer containing the data received or sent during the SPI cycle.
410 @retval EFI_SUCCESS SPI command completes successfully.
411 @retval EFI_DEVICE_ERROR Device error, the command aborts abnormally.
412 @retval EFI_ACCESS_DENIED Some unrecognized command encountered in hardware sequencing mode
413 @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
417 IN FLASH_REGION_TYPE FlashRegionType
,
418 IN FLASH_CYCLE_TYPE FlashCycleType
,
426 UINTN SpiBaseAddress
;
429 UINT32 HardwareSpiAddr
;
430 UINT16 PermissionBit
;
434 SPI_INSTANCE
*SpiInstance
;
437 SpiInstance
= GetSpiInstance ();
438 if (SpiInstance
== NULL
) {
439 return EFI_DEVICE_ERROR
;
442 Status
= EFI_SUCCESS
;
443 SpiBaseAddress
= SpiInstance
->PchSpiBase
;
444 ScSpiBar0
= AcquireSpiBar0 (SpiBaseAddress
);
446 SpiInstance
->RegionPermission
= MmioRead16 (ScSpiBar0
+ R_SPI_FRAP
);
449 // If it's write cycle, disable Prefetching, Caching and disable BIOS Write Protect
451 if ((FlashCycleType
== FlashCycleWrite
) || (FlashCycleType
== FlashCycleErase
)) {
452 Status
= DisableBiosWriteProtect (SpiBaseAddress
, mSpiInstance
->Flags
& FLAGS_SPI_DISABLE_SMM_WRITE_PROTECT
);
453 if (EFI_ERROR (Status
)) {
456 BiosCtlSave
= SaveAndDisableSpiPrefetchCache (SpiBaseAddress
);
460 // Make sure it's safe to program the command.
462 if (!WaitForSpiCycleComplete (ScSpiBar0
, FALSE
)) {
463 Status
= EFI_DEVICE_ERROR
;
467 HardwareSpiAddr
= Address
;
468 if ((FlashCycleType
== FlashCycleRead
) ||
469 (FlashCycleType
== FlashCycleWrite
) ||
470 (FlashCycleType
== FlashCycleErase
)) {
472 switch (FlashRegionType
) {
473 case FlashRegionDescriptor
:
474 if (FlashCycleType
== FlashCycleRead
) {
475 PermissionBit
= B_SPI_FRAP_BRRA_FLASHD
;
477 PermissionBit
= B_SPI_FRAP_BRWA_FLASHD
;
479 Data32
= MmioRead32 (ScSpiBar0
+ R_SPI_FREG0_FLASHD
);
480 HardwareSpiAddr
+= (Data32
& B_SPI_FREG0_BASE_MASK
) << N_SPI_FREG0_BASE
;
481 LimitAddress
= (Data32
& B_SPI_FREG0_LIMIT_MASK
) >> N_SPI_FREG0_LIMIT
;
484 case FlashRegionBios
:
485 if (FlashCycleType
== FlashCycleRead
) {
486 PermissionBit
= B_SPI_FRAP_BRRA_BIOS
;
488 PermissionBit
= B_SPI_FRAP_BRWA_BIOS
;
490 Data32
= MmioRead32 (ScSpiBar0
+ R_SPI_FREG1_BIOS
);
491 HardwareSpiAddr
+= (Data32
& B_SPI_FREG1_BASE_MASK
) << N_SPI_FREG1_BASE
;
492 LimitAddress
= (Data32
& B_SPI_FREG1_LIMIT_MASK
) >> N_SPI_FREG1_LIMIT
;
496 if (FlashCycleType
== FlashCycleRead
) {
497 PermissionBit
= B_SPI_FRAP_BRRA_SEC
;
499 PermissionBit
= B_SPI_FRAP_BRWA_SEC
;
501 Data32
= MmioRead32 (ScSpiBar0
+ R_SPI_FREG2_SEC
);
502 HardwareSpiAddr
+= (Data32
& B_SPI_FREG2_BASE_MASK
) << N_SPI_FREG2_BASE
;
503 LimitAddress
= (Data32
& B_SPI_FREG2_LIMIT_MASK
) >> N_SPI_FREG2_LIMIT
;
507 if (FlashCycleType
== FlashCycleRead
) {
508 PermissionBit
= B_SPI_FRAP_BRRA_GBE
;
510 PermissionBit
= B_SPI_FRAP_BRWA_GBE
;
512 Data32
= MmioRead32 (ScSpiBar0
+ R_SPI_FREG3_GBE
);
513 HardwareSpiAddr
+= (Data32
& B_SPI_FREG3_BASE_MASK
) << N_SPI_FREG3_BASE
;
514 LimitAddress
= (Data32
& B_SPI_FREG3_LIMIT_MASK
) >> N_SPI_FREG3_LIMIT
;
517 case FlashRegionPlatformData
:
518 if (FlashCycleType
== FlashCycleRead
) {
519 PermissionBit
= B_SPI_FRAP_BRRA_PLATFORM
;
521 PermissionBit
= B_SPI_FRAP_BRWA_PLATFORM
;
523 Data32
= MmioRead32 (ScSpiBar0
+ R_SPI_FREG4_PLATFORM_DATA
);
524 HardwareSpiAddr
+= (Data32
& B_SPI_FREG4_BASE_MASK
) << N_SPI_FREG4_BASE
;
525 LimitAddress
= (Data32
& B_SPI_FREG4_LIMIT_MASK
) >> N_SPI_FREG4_LIMIT
;
530 // FlashRegionAll indicates address is relative to flash device
531 // No error checking for this case
538 Status
= EFI_UNSUPPORTED
;
542 if ((LimitAddress
!= 0) && (Address
> LimitAddress
)) {
543 Status
= EFI_INVALID_PARAMETER
;
548 // If the operation is read, but the region attribute is not read allowed, return error.
549 // If the operation is write, but the region attribute is not write allowed, return error.
551 if ((PermissionBit
!= 0) && ((SpiInstance
->RegionPermission
& PermissionBit
) == 0)) {
552 Status
= EFI_ACCESS_DENIED
;
558 // Check for SC SPI hardware sequencing required commands
561 switch (FlashCycleType
) {
563 FlashCycle
= (UINT32
) (V_SPI_HSFS_CYCLE_READ
<< N_SPI_HSFS_CYCLE
);
566 case FlashCycleWrite
:
567 FlashCycle
= (UINT32
) (V_SPI_HSFS_CYCLE_WRITE
<< N_SPI_HSFS_CYCLE
);
570 case FlashCycleErase
:
571 if (((ByteCount
% SIZE_4KB
) != 0) || ((HardwareSpiAddr
% SIZE_4KB
) != 0)) {
572 DEBUG ((DEBUG_ERROR
, "Erase and erase size must be 4KB aligned. \n"));
574 Status
= EFI_INVALID_PARAMETER
;
579 case FlashCycleReadSfdp
:
580 FlashCycle
= (UINT32
) (V_SPI_HSFS_CYCLE_READ_SFDP
<< N_SPI_HSFS_CYCLE
);
583 case FlashCycleReadJedecId
:
584 FlashCycle
= (UINT32
) (V_SPI_HSFS_CYCLE_READ_JEDEC_ID
<< N_SPI_HSFS_CYCLE
);
587 case FlashCycleWriteStatus
:
588 FlashCycle
= (UINT32
) (V_SPI_HSFS_CYCLE_WRITE_STATUS
<< N_SPI_HSFS_CYCLE
);
591 case FlashCycleReadStatus
:
592 FlashCycle
= (UINT32
) (V_SPI_HSFS_CYCLE_READ_STATUS
<< N_SPI_HSFS_CYCLE
);
597 // Unrecognized Operation
600 Status
= EFI_INVALID_PARAMETER
;
606 SpiDataCount
= ByteCount
;
607 if ((FlashCycleType
== FlashCycleRead
) || (FlashCycleType
== FlashCycleWrite
)) {
609 // Trim at 256 byte boundary per operation,
610 // - SC SPI controller requires trimming at 4KB boundary
611 // - Some SPI chips require trimming at 256 byte boundary for write operation
612 // - Trimming has limited performance impact as we can read / write at most 64 byte
615 if (HardwareSpiAddr
+ ByteCount
> ((HardwareSpiAddr
+ BIT8
) &~(BIT8
- 1))) {
616 SpiDataCount
= (((UINT32
) (HardwareSpiAddr
) + BIT8
) &~(BIT8
- 1)) - (UINT32
) (HardwareSpiAddr
);
619 // Calculate the number of bytes to shift in/out during the SPI data cycle.
620 // Valid settings for the number of bytes during each data portion of the
621 // SC SPI cycles are: 0, 1, 2, 3, 4, 5, 6, 7, 8, 16, 24, 32, 40, 48, 56, 64
623 if (SpiDataCount
>= 64) {
625 } else if ((SpiDataCount
&~0x07) != 0) {
626 SpiDataCount
= SpiDataCount
&~0x07;
630 if (FlashCycleType
== FlashCycleErase
) {
631 if (((ByteCount
/ SIZE_64KB
) != 0) &&
632 ((ByteCount
% SIZE_64KB
) == 0) &&
633 ((HardwareSpiAddr
% SIZE_64KB
) == 0)) {
634 if (HardwareSpiAddr
< SpiInstance
->Component1StartAddr
) {
636 // Check whether Component0 support 64k Erase
638 if ((SpiInstance
->SfdpVscc0Value
& B_SPI_LVSCC_EO_64K
) != 0) {
639 SpiDataCount
= SIZE_64KB
;
641 SpiDataCount
= SIZE_4KB
;
645 // Check whether Component1 support 64k Erase
647 if ((SpiInstance
->SfdpVscc1Value
& B_SPI_LVSCC_EO_64K
) != 0) {
648 SpiDataCount
= SIZE_64KB
;
650 SpiDataCount
= SIZE_4KB
;
654 SpiDataCount
= SIZE_4KB
;
656 if (SpiDataCount
== SIZE_4KB
) {
657 FlashCycle
= (UINT32
) (V_SPI_HSFS_CYCLE_4K_ERASE
<< N_SPI_HSFS_CYCLE
);
659 FlashCycle
= (UINT32
) (V_SPI_HSFS_CYCLE_64K_ERASE
<< N_SPI_HSFS_CYCLE
);
664 // If it's write cycle, load data into the SPI data buffer.
666 if ((FlashCycleType
== FlashCycleWrite
) || (FlashCycleType
== FlashCycleWriteStatus
)) {
667 if ((SpiDataCount
& 0x07) != 0) {
669 // Use Byte write if Data Count is 0, 1, 2, 3, 4, 5, 6, 7
671 for (Index
= 0; Index
< SpiDataCount
; Index
++) {
672 MmioWrite8 (ScSpiBar0
+ R_SPI_FDATA00
+ Index
, Buffer
[Index
]);
676 // Use Dword write if Data Count is 8, 16, 24, 32, 40, 48, 56, 64
678 for (Index
= 0; Index
< SpiDataCount
; Index
+= sizeof (UINT32
)) {
679 MmioWrite32 (ScSpiBar0
+ R_SPI_FDATA00
+ Index
, *(UINT32
*) (Buffer
+ Index
));
685 // Set the Flash Address
687 MmioWrite32 (ScSpiBar0
+ R_SPI_FADDR
, (UINT32
) (HardwareSpiAddr
& B_SPI_FADDR_MASK
));
690 // Set Data count, Flash cycle, and Set Go bit to start a cycle
693 ScSpiBar0
+ R_SPI_HSFS
,
694 (UINT32
) (~(B_SPI_HSFS_FDBC_MASK
| B_SPI_HSFS_CYCLE_MASK
)),
695 (UINT32
) (((SpiDataCount
- 1) << N_SPI_HSFS_FDBC
) | FlashCycle
| B_SPI_HSFS_CYCLE_FGO
)
699 // Wait for command execution complete.
701 if (!WaitForSpiCycleComplete (ScSpiBar0
, TRUE
)) {
702 Status
= EFI_DEVICE_ERROR
;
707 // If it's read cycle, load data into the caller's buffer.
709 if ((FlashCycleType
== FlashCycleRead
) ||
710 (FlashCycleType
== FlashCycleReadSfdp
) ||
711 (FlashCycleType
== FlashCycleReadJedecId
) ||
712 (FlashCycleType
== FlashCycleReadStatus
)) {
713 if ((SpiDataCount
& 0x07) != 0) {
715 // Use Byte read if Data Count is 0, 1, 2, 3, 4, 5, 6, 7
717 for (Index
= 0; Index
< SpiDataCount
; Index
++) {
718 Buffer
[Index
] = MmioRead8 (ScSpiBar0
+ R_SPI_FDATA00
+ Index
);
722 // Use Dword read if Data Count is 8, 16, 24, 32, 40, 48, 56, 64
724 for (Index
= 0; Index
< SpiDataCount
; Index
+= sizeof (UINT32
)) {
725 *(UINT32
*) (Buffer
+ Index
) = MmioRead32 (ScSpiBar0
+ R_SPI_FDATA00
+ Index
);
730 HardwareSpiAddr
+= SpiDataCount
;
731 Buffer
+= SpiDataCount
;
732 ByteCount
-= SpiDataCount
;
733 } while (ByteCount
> 0);
737 /// Restore the settings for SPI Prefetching and Caching and enable BIOS Write Protect
739 if ((FlashCycleType
== FlashCycleWrite
) || (FlashCycleType
== FlashCycleErase
)) {
740 EnableBiosWriteProtect (SpiBaseAddress
, mSpiInstance
->Flags
& FLAGS_SPI_DISABLE_SMM_WRITE_PROTECT
);
741 SetSpiBiosControlRegister (SpiBaseAddress
, BiosCtlSave
);
744 ReleaseSpiBar0 (SpiBaseAddress
);
750 Wait execution cycle to complete on the SPI interface.
752 @param[in] ScSpiBar0 Spi MMIO base address
753 @param[in] ErrorCheck TRUE if the SpiCycle needs to do the error check
755 @retval TRUE SPI cycle completed on the interface.
756 @retval FALSE Time out while waiting the SPI cycle to complete.
757 It's not safe to program the next command on the SPI interface.
760 WaitForSpiCycleComplete (
762 IN BOOLEAN ErrorCheck
770 // Convert the wait period allowed into to tick count
772 WaitCount
= WAIT_TIME
/ WAIT_PERIOD
;
774 // Wait for the SPI cycle to complete.
776 for (WaitTicks
= 0; WaitTicks
< WaitCount
; WaitTicks
++) {
777 Data32
= MmioRead32 (ScSpiBar0
+ R_SPI_HSFS
);
778 if ((Data32
& B_SPI_HSFS_SCIP
) == 0) {
779 MmioWrite32 (ScSpiBar0
+ R_SPI_HSFS
, B_SPI_HSFS_FCERR
| B_SPI_HSFS_FDONE
);
780 if (((Data32
& B_SPI_HSFS_FCERR
) != 0) && ErrorCheck
) {
786 MicroSecondDelay ( WAIT_PERIOD
);
792 Get the SPI region base and size, based on the enum type
794 @param[in] FlashRegionType The Flash Region type for for the base address which is listed in the Descriptor.
795 @param[out] BaseAddress The Flash Linear Address for the Region 'n' Base
796 @param[out] RegionSize The size for the Region 'n'
798 @retval EFI_SUCCESS Read success
799 @retval EFI_INVALID_PARAMETER Invalid region type given
800 @retval EFI_DEVICE_ERROR The region is not used
804 SpiGetRegionAddress (
805 IN FLASH_REGION_TYPE FlashRegionType
,
806 OUT UINT32
*BaseAddress
, OPTIONAL
807 OUT UINT32
*RegionSize OPTIONAL
813 SPI_INSTANCE
*SpiInstance
;
815 if (FlashRegionType
>= FlashRegionMax
) {
816 return EFI_INVALID_PARAMETER
;
819 SpiInstance
= GetSpiInstance();
820 if (SpiInstance
== NULL
) {
821 return EFI_DEVICE_ERROR
;
824 if (FlashRegionType
== FlashRegionAll
) {
825 if (BaseAddress
!= NULL
) {
828 if (RegionSize
!= NULL
) {
829 *RegionSize
= SpiInstance
->Component1StartAddr
;
834 ScSpiBar0
= AcquireSpiBar0 (SpiInstance
->PchSpiBase
);
835 ReadValue
= MmioRead32 (ScSpiBar0
+ R_SPI_FREG0_FLASHD
+ S_SPI_FREGX
* (UINT32
) FlashRegionType
);
836 ReleaseSpiBar0 (SpiInstance
->PchSpiBase
);
839 // If the region is not used, the Region Base is 7FFFh and Region Limit is 0000h
841 if (ReadValue
== B_SPI_FREGX_BASE_MASK
) {
842 return EFI_DEVICE_ERROR
;
845 Base
= (ReadValue
& B_SPI_FREG1_BASE_MASK
) << N_SPI_FREG1_BASE
;
846 if (BaseAddress
!= NULL
) {
850 if (RegionSize
!= NULL
) {
851 *RegionSize
= ((((ReadValue
& B_SPI_FREGX_LIMIT_MASK
) >> N_SPI_FREGX_LIMIT
) + 1) <<
852 N_SPI_FREGX_LIMIT_REPR
) - Base
;