]> git.proxmox.com Git - mirror_edk2.git/blob - UefiPayloadPkg/Library/SpiFlashLib/PchSpi.c
UefiPayloadPkg: Add SpiFlashLib
[mirror_edk2.git] / UefiPayloadPkg / Library / SpiFlashLib / PchSpi.c
1 /** @file
2
3 Copyright (c) 2017-2021, Intel Corporation. All rights reserved.<BR>
4 SPDX-License-Identifier: BSD-2-Clause-Patent
5
6 **/
7 #include "SpiCommon.h"
8
9 /**
10 Acquire SPI MMIO BAR.
11
12 @param[in] PchSpiBase PCH SPI PCI Base Address
13
14 @retval Return SPI BAR Address
15
16 **/
17 UINT32
18 AcquireSpiBar0 (
19 IN UINTN PchSpiBase
20 )
21 {
22 return MmioRead32 (PchSpiBase + R_SPI_BASE) & ~(B_SPI_BAR0_MASK);
23 }
24
25 /**
26 Release SPI MMIO BAR. Do nothing.
27
28 @param[in] PchSpiBase PCH SPI PCI Base Address
29
30 **/
31 VOID
32 ReleaseSpiBar0 (
33 IN UINTN PchSpiBase
34 )
35 {
36 }
37
38
39
40 /**
41 This function is to enable/disable BIOS Write Protect in SMM phase.
42
43 @param[in] EnableSmmSts Flag to Enable/disable Bios write protect
44
45 **/
46 VOID
47 CpuSmmDisableBiosWriteProtect (
48 IN BOOLEAN EnableSmmSts
49 )
50 {
51 UINT32 Data32;
52
53 if(EnableSmmSts){
54 //
55 // Disable BIOS Write Protect in SMM phase.
56 //
57 Data32 = MmioRead32 ((UINTN) (0xFED30880)) | (UINT32) (BIT0);
58 AsmWriteMsr32 (0x000001FE, Data32);
59 } else {
60 //
61 // Enable BIOS Write Protect in SMM phase
62 //
63 Data32 = MmioRead32 ((UINTN) (0xFED30880)) & (UINT32) (~BIT0);
64 AsmWriteMsr32 (0x000001FE, Data32);
65 }
66
67 //
68 // Read FED30880h back to ensure the setting went through.
69 //
70 Data32 = MmioRead32 (0xFED30880);
71 }
72
73
74 /**
75 This function is a hook for Spi to disable BIOS Write Protect.
76
77 @param[in] PchSpiBase PCH SPI PCI Base Address
78 @param[in] CpuSmmBwp Need to disable CPU SMM Bios write protection or not
79
80 @retval EFI_SUCCESS The protocol instance was properly initialized
81 @retval EFI_ACCESS_DENIED The BIOS Region can only be updated in SMM phase
82
83 **/
84 EFI_STATUS
85 EFIAPI
86 DisableBiosWriteProtect (
87 IN UINTN PchSpiBase,
88 IN UINT8 CpuSmmBwp
89 )
90 {
91
92 //
93 // Write clear BC_SYNC_SS prior to change WPD from 0 to 1.
94 //
95 MmioOr8 (PchSpiBase + R_SPI_BCR + 1, (B_SPI_BCR_SYNC_SS >> 8));
96
97 //
98 // Enable the access to the BIOS space for both read and write cycles
99 //
100 MmioOr8 (PchSpiBase + R_SPI_BCR, B_SPI_BCR_BIOSWE);
101
102 if (CpuSmmBwp != 0) {
103 CpuSmmDisableBiosWriteProtect (TRUE);
104 }
105
106 return EFI_SUCCESS;
107 }
108
109 /**
110 This function is a hook for Spi to enable BIOS Write Protect.
111
112 @param[in] PchSpiBase PCH SPI PCI Base Address
113 @param[in] CpuSmmBwp Need to disable CPU SMM Bios write protection or not
114
115 **/
116 VOID
117 EFIAPI
118 EnableBiosWriteProtect (
119 IN UINTN PchSpiBase,
120 IN UINT8 CpuSmmBwp
121 )
122 {
123
124 //
125 // Disable the access to the BIOS space for write cycles
126 //
127 MmioAnd8 (PchSpiBase + R_SPI_BCR, (UINT8) (~B_SPI_BCR_BIOSWE));
128
129 if (CpuSmmBwp != 0) {
130 CpuSmmDisableBiosWriteProtect (FALSE);
131 }
132 }
133
134 /**
135 This function disables SPI Prefetching and caching,
136 and returns previous BIOS Control Register value before disabling.
137
138 @param[in] PchSpiBase PCH SPI PCI Base Address
139
140 @retval Previous BIOS Control Register value
141
142 **/
143 UINT8
144 SaveAndDisableSpiPrefetchCache (
145 IN UINTN PchSpiBase
146 )
147 {
148 UINT8 BiosCtlSave;
149
150 BiosCtlSave = MmioRead8 (PchSpiBase + R_SPI_BCR) & B_SPI_BCR_SRC;
151
152 MmioAndThenOr32 (PchSpiBase + R_SPI_BCR, \
153 (UINT32) (~B_SPI_BCR_SRC), \
154 (UINT32) (V_SPI_BCR_SRC_PREF_DIS_CACHE_DIS << B_SPI_BCR_SRC));
155
156 return BiosCtlSave;
157 }
158
159 /**
160 This function updates BIOS Control Register with the given value.
161
162 @param[in] PchSpiBase PCH SPI PCI Base Address
163 @param[in] BiosCtlValue BIOS Control Register Value to be updated
164
165 **/
166 VOID
167 SetSpiBiosControlRegister (
168 IN UINTN PchSpiBase,
169 IN UINT8 BiosCtlValue
170 )
171 {
172 MmioAndThenOr8 (PchSpiBase + R_SPI_BCR, (UINT8) ~B_SPI_BCR_SRC, BiosCtlValue);
173 }