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