]> git.proxmox.com Git - mirror_edk2.git/blob - UefiPayloadPkg/Library/SpiFlashLib/SpiFlashLib.c
UefiPayloadPkg: Add SpiFlashLib
[mirror_edk2.git] / UefiPayloadPkg / Library / SpiFlashLib / SpiFlashLib.c
1 /** @file
2 Generic driver using Hardware Sequencing registers.
3
4 Copyright (c) 2017-2021, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8 #include "SpiCommon.h"
9
10 SPI_INSTANCE *mSpiInstance = NULL;
11
12 /**
13 Get SPI Instance from library global data..
14
15 @retval SpiInstance Return SPI instance
16 **/
17 SPI_INSTANCE *
18 GetSpiInstance (
19 VOID
20 )
21 {
22 if (mSpiInstance == NULL) {
23 mSpiInstance = AllocatePool (sizeof(SPI_INSTANCE));
24 if (mSpiInstance == NULL) {
25 return NULL;
26 }
27 ZeroMem (mSpiInstance, sizeof(SPI_INSTANCE));
28 }
29
30 return mSpiInstance;
31 }
32
33
34 /**
35 Initialize an SPI library.
36
37 @retval EFI_SUCCESS The protocol instance was properly initialized
38 @retval EFI_NOT_FOUND The expected SPI info could not be found
39 **/
40 EFI_STATUS
41 EFIAPI
42 SpiConstructor (
43 VOID
44 )
45 {
46 UINT32 ScSpiBar0;
47 UINT8 Comp0Density;
48 SPI_INSTANCE *SpiInstance;
49 EFI_HOB_GUID_TYPE *GuidHob;
50 SPI_FLASH_INFO *SpiFlashInfo;
51
52 //
53 // Find SPI flash hob
54 //
55 GuidHob = GetFirstGuidHob (&gSpiFlashInfoGuid);
56 if (GuidHob == NULL) {
57 ASSERT (FALSE);
58 return EFI_NOT_FOUND;
59 }
60 SpiFlashInfo = (SPI_FLASH_INFO *) GET_GUID_HOB_DATA (GuidHob);
61
62 //
63 // Initialize the SPI instance
64 //
65 SpiInstance = GetSpiInstance ();
66 if (SpiInstance == NULL) {
67 return EFI_NOT_FOUND;
68 }
69 DEBUG ((DEBUG_INFO, "SpiInstance = %08X\n", SpiInstance));
70
71 SpiInstance->Signature = SC_SPI_PRIVATE_DATA_SIGNATURE;
72 SpiInstance->Handle = NULL;
73
74 //
75 // Check the SPI address
76 //
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"));
82 }
83 SpiInstance->PchSpiBase = (UINT32)(UINTN)SpiFlashInfo->SpiAddress.Address;
84 SpiInstance->Flags = SpiFlashInfo->Flags;
85 DEBUG ((DEBUG_INFO, "PchSpiBase at 0x%x\n", SpiInstance->PchSpiBase));
86
87 ScSpiBar0 = AcquireSpiBar0 (SpiInstance->PchSpiBase);
88 DEBUG ((DEBUG_INFO, "ScSpiBar0 at 0x%08X\n", ScSpiBar0));
89
90 if (ScSpiBar0 == 0) {
91 ASSERT (FALSE);
92 }
93
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"));
96 ASSERT (FALSE);
97 }
98
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);
103
104 //
105 // Select to Flash Map 0 Register to get the number of flash Component
106 //
107 MmioAndThenOr32 (
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)
111 );
112
113 //
114 // Copy Zero based Number Of Components
115 //
116 SpiInstance->NumberOfComponents = (UINT8) ((MmioRead16 (ScSpiBar0 + R_SPI_FDOD) & B_SPI_FDBAR_NC) >> N_SPI_FDBAR_NC);
117
118 MmioAndThenOr32 (
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)
122 );
123
124 //
125 // Copy Component 0 Density
126 //
127 Comp0Density = (UINT8) MmioRead32 (ScSpiBar0 + R_SPI_FDOD) & B_SPI_FLCOMP_COMP1_MASK;
128 SpiInstance->Component1StartAddr = (UINT32) (SIZE_512KB << Comp0Density);
129
130 //
131 // Select FLASH_MAP1 to get Flash SC Strap Base Address
132 //
133 MmioAndThenOr32 (
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)
137 );
138
139 SpiInstance->StrapBaseAddress = MmioRead32 (ScSpiBar0 + R_SPI_FDOD) & B_SPI_FDBAR_FPSBA;
140
141 //
142 // Align FPSBA with address bits for the SC Strap portion of flash descriptor
143 //
144 SpiInstance->StrapBaseAddress &= B_SPI_FDBAR_FPSBA;
145
146 return EFI_SUCCESS;
147 }
148
149
150 /**
151 Read data from the flash part.
152
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.
158
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.
162 **/
163 EFI_STATUS
164 EFIAPI
165 SpiFlashRead (
166 IN FLASH_REGION_TYPE FlashRegionType,
167 IN UINT32 Address,
168 IN UINT32 ByteCount,
169 OUT UINT8 *Buffer
170 )
171 {
172 EFI_STATUS Status;
173
174 Status = SendSpiCmd (FlashRegionType, FlashCycleRead, Address, ByteCount, Buffer);
175 return Status;
176 }
177
178 /**
179 Write data to the flash part.
180
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.
185
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.
189 **/
190 EFI_STATUS
191 EFIAPI
192 SpiFlashWrite (
193 IN FLASH_REGION_TYPE FlashRegionType,
194 IN UINT32 Address,
195 IN UINT32 ByteCount,
196 IN UINT8 *Buffer
197 )
198 {
199 EFI_STATUS Status;
200
201 Status = SendSpiCmd (FlashRegionType, FlashCycleWrite, Address, ByteCount, Buffer);
202 return Status;
203 }
204
205 /**
206 Erase some area on the flash part.
207
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.
211
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.
215 **/
216 EFI_STATUS
217 EFIAPI
218 SpiFlashErase (
219 IN FLASH_REGION_TYPE FlashRegionType,
220 IN UINT32 Address,
221 IN UINT32 ByteCount
222 )
223 {
224 EFI_STATUS Status;
225
226 Status = SendSpiCmd (FlashRegionType, FlashCycleErase, Address, ByteCount, NULL);
227 return Status;
228 }
229
230 /**
231 Read SFDP data from the flash part.
232
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.
237
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.
241 **/
242 EFI_STATUS
243 EFIAPI
244 SpiFlashReadSfdp (
245 IN UINT8 ComponentNumber,
246 IN UINT32 ByteCount,
247 OUT UINT8 *SfdpData
248 )
249 {
250 EFI_STATUS Status;
251 UINT32 Address;
252 SPI_INSTANCE *SpiInstance;
253
254 SpiInstance = GetSpiInstance ();
255 if (SpiInstance == NULL) {
256 return EFI_DEVICE_ERROR;
257 }
258
259 if ((ByteCount > 64) || (ComponentNumber > SpiInstance->NumberOfComponents)) {
260 ASSERT (FALSE);
261 return EFI_INVALID_PARAMETER;
262 }
263
264 Address = 0;
265 if (ComponentNumber == FlashComponent1) {
266 Address = SpiInstance->Component1StartAddr;
267 }
268
269 Status = SendSpiCmd (0, FlashCycleReadSfdp, Address, ByteCount, SfdpData);
270 return Status;
271 }
272
273 /**
274 Read Jedec Id from the flash part.
275
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.
280
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.
284 **/
285 EFI_STATUS
286 EFIAPI
287 SpiFlashReadJedecId (
288 IN UINT8 ComponentNumber,
289 IN UINT32 ByteCount,
290 OUT UINT8 *JedecId
291 )
292 {
293 EFI_STATUS Status;
294 UINT32 Address;
295 SPI_INSTANCE *SpiInstance;
296
297 SpiInstance = GetSpiInstance ();
298 if (SpiInstance == NULL) {
299 return EFI_DEVICE_ERROR;
300 }
301
302 if (ComponentNumber > SpiInstance->NumberOfComponents) {
303 ASSERT (FALSE);
304 return EFI_INVALID_PARAMETER;
305 }
306
307 Address = 0;
308 if (ComponentNumber == FlashComponent1) {
309 Address = SpiInstance->Component1StartAddr;
310 }
311
312 Status = SendSpiCmd (0, FlashCycleReadJedecId, Address, ByteCount, JedecId);
313 return Status;
314 }
315
316 /**
317 Write the status register in the flash part.
318
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
321
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.
325 **/
326 EFI_STATUS
327 EFIAPI
328 SpiFlashWriteStatus (
329 IN UINT32 ByteCount,
330 IN UINT8 *StatusValue
331 )
332 {
333 EFI_STATUS Status;
334
335 Status = SendSpiCmd (0, FlashCycleWriteStatus, 0, ByteCount, StatusValue);
336 return Status;
337 }
338
339 /**
340 Read status register in the flash part.
341
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.
344
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.
348 **/
349 EFI_STATUS
350 EFIAPI
351 SpiFlashReadStatus (
352 IN UINT32 ByteCount,
353 OUT UINT8 *StatusValue
354 )
355 {
356 EFI_STATUS Status;
357
358 Status = SendSpiCmd (0, FlashCycleReadStatus, 0, ByteCount, StatusValue);
359 return Status;
360 }
361
362 /**
363 Read SC Soft Strap Values
364
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.
369
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.
373 **/
374 EFI_STATUS
375 EFIAPI
376 SpiReadPchSoftStrap (
377 IN UINT32 SoftStrapAddr,
378 IN UINT32 ByteCount,
379 OUT UINT8 *SoftStrapValue
380 )
381 {
382 UINT32 StrapFlashAddr;
383 EFI_STATUS Status;
384 SPI_INSTANCE *SpiInstance;
385
386 SpiInstance = GetSpiInstance ();
387 if (SpiInstance == NULL) {
388 return EFI_DEVICE_ERROR;
389 }
390
391 ASSERT (SpiInstance->StrapBaseAddress != 0);
392 //
393 // SC Strap Flash Address = FPSBA + RamAddr
394 //
395 StrapFlashAddr = SpiInstance->StrapBaseAddress + SoftStrapAddr;
396
397 Status = SendSpiCmd (FlashRegionDescriptor, FlashCycleRead, StrapFlashAddr, ByteCount, SoftStrapValue);
398 return Status;
399 }
400
401 /**
402 This function sends the programmed SPI command to the slave device.
403
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.
409
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.
414 **/
415 EFI_STATUS
416 SendSpiCmd (
417 IN FLASH_REGION_TYPE FlashRegionType,
418 IN FLASH_CYCLE_TYPE FlashCycleType,
419 IN UINT32 Address,
420 IN UINT32 ByteCount,
421 IN OUT UINT8 *Buffer
422 )
423 {
424 EFI_STATUS Status;
425 UINT32 Index;
426 UINTN SpiBaseAddress;
427 UINT32 ScSpiBar0;
428 UINT32 LimitAddress;
429 UINT32 HardwareSpiAddr;
430 UINT16 PermissionBit;
431 UINT32 SpiDataCount;
432 UINT32 FlashCycle;
433 UINT8 BiosCtlSave;
434 SPI_INSTANCE *SpiInstance;
435 UINT32 Data32;
436
437 SpiInstance = GetSpiInstance ();
438 if (SpiInstance == NULL) {
439 return EFI_DEVICE_ERROR;
440 }
441
442 Status = EFI_SUCCESS;
443 SpiBaseAddress = SpiInstance->PchSpiBase;
444 ScSpiBar0 = AcquireSpiBar0 (SpiBaseAddress);
445 BiosCtlSave = 0;
446 SpiInstance->RegionPermission = MmioRead16 (ScSpiBar0 + R_SPI_FRAP);
447
448 //
449 // If it's write cycle, disable Prefetching, Caching and disable BIOS Write Protect
450 //
451 if ((FlashCycleType == FlashCycleWrite) || (FlashCycleType == FlashCycleErase)) {
452 Status = DisableBiosWriteProtect (SpiBaseAddress, mSpiInstance->Flags & FLAGS_SPI_DISABLE_SMM_WRITE_PROTECT);
453 if (EFI_ERROR (Status)) {
454 goto SendSpiCmdEnd;
455 }
456 BiosCtlSave = SaveAndDisableSpiPrefetchCache (SpiBaseAddress);
457 }
458
459 //
460 // Make sure it's safe to program the command.
461 //
462 if (!WaitForSpiCycleComplete (ScSpiBar0, FALSE)) {
463 Status = EFI_DEVICE_ERROR;
464 goto SendSpiCmdEnd;
465 }
466
467 HardwareSpiAddr = Address;
468 if ((FlashCycleType == FlashCycleRead) ||
469 (FlashCycleType == FlashCycleWrite) ||
470 (FlashCycleType == FlashCycleErase)) {
471
472 switch (FlashRegionType) {
473 case FlashRegionDescriptor:
474 if (FlashCycleType == FlashCycleRead) {
475 PermissionBit = B_SPI_FRAP_BRRA_FLASHD;
476 } else {
477 PermissionBit = B_SPI_FRAP_BRWA_FLASHD;
478 }
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;
482 break;
483
484 case FlashRegionBios:
485 if (FlashCycleType == FlashCycleRead) {
486 PermissionBit = B_SPI_FRAP_BRRA_BIOS;
487 } else {
488 PermissionBit = B_SPI_FRAP_BRWA_BIOS;
489 }
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;
493 break;
494
495 case FlashRegionMe:
496 if (FlashCycleType == FlashCycleRead) {
497 PermissionBit = B_SPI_FRAP_BRRA_SEC;
498 } else {
499 PermissionBit = B_SPI_FRAP_BRWA_SEC;
500 }
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;
504 break;
505
506 case FlashRegionGbE:
507 if (FlashCycleType == FlashCycleRead) {
508 PermissionBit = B_SPI_FRAP_BRRA_GBE;
509 } else {
510 PermissionBit = B_SPI_FRAP_BRWA_GBE;
511 }
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;
515 break;
516
517 case FlashRegionPlatformData:
518 if (FlashCycleType == FlashCycleRead) {
519 PermissionBit = B_SPI_FRAP_BRRA_PLATFORM;
520 } else {
521 PermissionBit = B_SPI_FRAP_BRWA_PLATFORM;
522 }
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;
526 break;
527
528 case FlashRegionAll:
529 //
530 // FlashRegionAll indicates address is relative to flash device
531 // No error checking for this case
532 //
533 LimitAddress = 0;
534 PermissionBit = 0;
535 break;
536
537 default:
538 Status = EFI_UNSUPPORTED;
539 goto SendSpiCmdEnd;
540 }
541
542 if ((LimitAddress != 0) && (Address > LimitAddress)) {
543 Status = EFI_INVALID_PARAMETER;
544 goto SendSpiCmdEnd;
545 }
546
547 //
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.
550 //
551 if ((PermissionBit != 0) && ((SpiInstance->RegionPermission & PermissionBit) == 0)) {
552 Status = EFI_ACCESS_DENIED;
553 goto SendSpiCmdEnd;
554 }
555 }
556
557 //
558 // Check for SC SPI hardware sequencing required commands
559 //
560 FlashCycle = 0;
561 switch (FlashCycleType) {
562 case FlashCycleRead:
563 FlashCycle = (UINT32) (V_SPI_HSFS_CYCLE_READ << N_SPI_HSFS_CYCLE);
564 break;
565
566 case FlashCycleWrite:
567 FlashCycle = (UINT32) (V_SPI_HSFS_CYCLE_WRITE << N_SPI_HSFS_CYCLE);
568 break;
569
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"));
573 ASSERT (FALSE);
574 Status = EFI_INVALID_PARAMETER;
575 goto SendSpiCmdEnd;
576 }
577 break;
578
579 case FlashCycleReadSfdp:
580 FlashCycle = (UINT32) (V_SPI_HSFS_CYCLE_READ_SFDP << N_SPI_HSFS_CYCLE);
581 break;
582
583 case FlashCycleReadJedecId:
584 FlashCycle = (UINT32) (V_SPI_HSFS_CYCLE_READ_JEDEC_ID << N_SPI_HSFS_CYCLE);
585 break;
586
587 case FlashCycleWriteStatus:
588 FlashCycle = (UINT32) (V_SPI_HSFS_CYCLE_WRITE_STATUS << N_SPI_HSFS_CYCLE);
589 break;
590
591 case FlashCycleReadStatus:
592 FlashCycle = (UINT32) (V_SPI_HSFS_CYCLE_READ_STATUS << N_SPI_HSFS_CYCLE);
593 break;
594
595 default:
596 //
597 // Unrecognized Operation
598 //
599 ASSERT (FALSE);
600 Status = EFI_INVALID_PARAMETER;
601 goto SendSpiCmdEnd;
602 break;
603 }
604
605 do {
606 SpiDataCount = ByteCount;
607 if ((FlashCycleType == FlashCycleRead) || (FlashCycleType == FlashCycleWrite)) {
608 //
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
613 // per operation
614 //
615 if (HardwareSpiAddr + ByteCount > ((HardwareSpiAddr + BIT8) &~(BIT8 - 1))) {
616 SpiDataCount = (((UINT32) (HardwareSpiAddr) + BIT8) &~(BIT8 - 1)) - (UINT32) (HardwareSpiAddr);
617 }
618 //
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
622 //
623 if (SpiDataCount >= 64) {
624 SpiDataCount = 64;
625 } else if ((SpiDataCount &~0x07) != 0) {
626 SpiDataCount = SpiDataCount &~0x07;
627 }
628 }
629
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) {
635 //
636 // Check whether Component0 support 64k Erase
637 //
638 if ((SpiInstance->SfdpVscc0Value & B_SPI_LVSCC_EO_64K) != 0) {
639 SpiDataCount = SIZE_64KB;
640 } else {
641 SpiDataCount = SIZE_4KB;
642 }
643 } else {
644 //
645 // Check whether Component1 support 64k Erase
646 //
647 if ((SpiInstance->SfdpVscc1Value & B_SPI_LVSCC_EO_64K) != 0) {
648 SpiDataCount = SIZE_64KB;
649 } else {
650 SpiDataCount = SIZE_4KB;
651 }
652 }
653 } else {
654 SpiDataCount = SIZE_4KB;
655 }
656 if (SpiDataCount == SIZE_4KB) {
657 FlashCycle = (UINT32) (V_SPI_HSFS_CYCLE_4K_ERASE << N_SPI_HSFS_CYCLE);
658 } else {
659 FlashCycle = (UINT32) (V_SPI_HSFS_CYCLE_64K_ERASE << N_SPI_HSFS_CYCLE);
660 }
661 }
662
663 //
664 // If it's write cycle, load data into the SPI data buffer.
665 //
666 if ((FlashCycleType == FlashCycleWrite) || (FlashCycleType == FlashCycleWriteStatus)) {
667 if ((SpiDataCount & 0x07) != 0) {
668 //
669 // Use Byte write if Data Count is 0, 1, 2, 3, 4, 5, 6, 7
670 //
671 for (Index = 0; Index < SpiDataCount; Index++) {
672 MmioWrite8 (ScSpiBar0 + R_SPI_FDATA00 + Index, Buffer[Index]);
673 }
674 } else {
675 //
676 // Use Dword write if Data Count is 8, 16, 24, 32, 40, 48, 56, 64
677 //
678 for (Index = 0; Index < SpiDataCount; Index += sizeof (UINT32)) {
679 MmioWrite32 (ScSpiBar0 + R_SPI_FDATA00 + Index, *(UINT32 *) (Buffer + Index));
680 }
681 }
682 }
683
684 //
685 // Set the Flash Address
686 //
687 MmioWrite32 (ScSpiBar0 + R_SPI_FADDR, (UINT32) (HardwareSpiAddr & B_SPI_FADDR_MASK));
688
689 //
690 // Set Data count, Flash cycle, and Set Go bit to start a cycle
691 //
692 MmioAndThenOr32 (
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)
696 );
697
698 //
699 // Wait for command execution complete.
700 //
701 if (!WaitForSpiCycleComplete (ScSpiBar0, TRUE)) {
702 Status = EFI_DEVICE_ERROR;
703 goto SendSpiCmdEnd;
704 }
705
706 //
707 // If it's read cycle, load data into the caller's buffer.
708 //
709 if ((FlashCycleType == FlashCycleRead) ||
710 (FlashCycleType == FlashCycleReadSfdp) ||
711 (FlashCycleType == FlashCycleReadJedecId) ||
712 (FlashCycleType == FlashCycleReadStatus)) {
713 if ((SpiDataCount & 0x07) != 0) {
714 //
715 // Use Byte read if Data Count is 0, 1, 2, 3, 4, 5, 6, 7
716 //
717 for (Index = 0; Index < SpiDataCount; Index++) {
718 Buffer[Index] = MmioRead8 (ScSpiBar0 + R_SPI_FDATA00 + Index);
719 }
720 } else {
721 //
722 // Use Dword read if Data Count is 8, 16, 24, 32, 40, 48, 56, 64
723 //
724 for (Index = 0; Index < SpiDataCount; Index += sizeof (UINT32)) {
725 *(UINT32 *) (Buffer + Index) = MmioRead32 (ScSpiBar0 + R_SPI_FDATA00 + Index);
726 }
727 }
728 }
729
730 HardwareSpiAddr += SpiDataCount;
731 Buffer += SpiDataCount;
732 ByteCount -= SpiDataCount;
733 } while (ByteCount > 0);
734
735 SendSpiCmdEnd:
736 ///
737 /// Restore the settings for SPI Prefetching and Caching and enable BIOS Write Protect
738 ///
739 if ((FlashCycleType == FlashCycleWrite) || (FlashCycleType == FlashCycleErase)) {
740 EnableBiosWriteProtect (SpiBaseAddress, mSpiInstance->Flags & FLAGS_SPI_DISABLE_SMM_WRITE_PROTECT);
741 SetSpiBiosControlRegister (SpiBaseAddress, BiosCtlSave);
742 }
743
744 ReleaseSpiBar0 (SpiBaseAddress);
745
746 return Status;
747 }
748
749 /**
750 Wait execution cycle to complete on the SPI interface.
751
752 @param[in] ScSpiBar0 Spi MMIO base address
753 @param[in] ErrorCheck TRUE if the SpiCycle needs to do the error check
754
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.
758 **/
759 BOOLEAN
760 WaitForSpiCycleComplete (
761 IN UINT32 ScSpiBar0,
762 IN BOOLEAN ErrorCheck
763 )
764 {
765 UINT64 WaitTicks;
766 UINT64 WaitCount;
767 UINT32 Data32;
768
769 //
770 // Convert the wait period allowed into to tick count
771 //
772 WaitCount = WAIT_TIME / WAIT_PERIOD;
773 //
774 // Wait for the SPI cycle to complete.
775 //
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) {
781 return FALSE;
782 } else {
783 return TRUE;
784 }
785 }
786 MicroSecondDelay ( WAIT_PERIOD);
787 }
788 return FALSE;
789 }
790
791 /**
792 Get the SPI region base and size, based on the enum type
793
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'
797
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
801 **/
802 EFI_STATUS
803 EFIAPI
804 SpiGetRegionAddress (
805 IN FLASH_REGION_TYPE FlashRegionType,
806 OUT UINT32 *BaseAddress, OPTIONAL
807 OUT UINT32 *RegionSize OPTIONAL
808 )
809 {
810 UINT32 ScSpiBar0;
811 UINT32 ReadValue;
812 UINT32 Base;
813 SPI_INSTANCE *SpiInstance;
814
815 if (FlashRegionType >= FlashRegionMax) {
816 return EFI_INVALID_PARAMETER;
817 }
818
819 SpiInstance = GetSpiInstance();
820 if (SpiInstance == NULL) {
821 return EFI_DEVICE_ERROR;
822 }
823
824 if (FlashRegionType == FlashRegionAll) {
825 if (BaseAddress != NULL) {
826 *BaseAddress = 0;
827 }
828 if (RegionSize != NULL) {
829 *RegionSize = SpiInstance->Component1StartAddr;
830 }
831 return EFI_SUCCESS;
832 }
833
834 ScSpiBar0 = AcquireSpiBar0 (SpiInstance->PchSpiBase);
835 ReadValue = MmioRead32 (ScSpiBar0 + R_SPI_FREG0_FLASHD + S_SPI_FREGX * (UINT32) FlashRegionType);
836 ReleaseSpiBar0 (SpiInstance->PchSpiBase);
837
838 //
839 // If the region is not used, the Region Base is 7FFFh and Region Limit is 0000h
840 //
841 if (ReadValue == B_SPI_FREGX_BASE_MASK) {
842 return EFI_DEVICE_ERROR;
843 }
844
845 Base = (ReadValue & B_SPI_FREG1_BASE_MASK) << N_SPI_FREG1_BASE;
846 if (BaseAddress != NULL) {
847 *BaseAddress = Base;
848 }
849
850 if (RegionSize != NULL) {
851 *RegionSize = ((((ReadValue & B_SPI_FREGX_LIMIT_MASK) >> N_SPI_FREGX_LIMIT) + 1) <<
852 N_SPI_FREGX_LIMIT_REPR) - Base;
853 }
854
855 return EFI_SUCCESS;
856 }
857