1 /** @file
2 This file contains functions that read the SPD data for each DIMM slot over
3 the SMBus interface.
4 This file is SampleCode for Intel SA PEI Policy initialization.
5
6 Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
7
8 SPDX-License-Identifier: BSD-2-Clause-Patent
9 **/
10
11 #include "PeiSaPolicyLibrary.h"
12 #include "MrcInterface.h"
13
14 #define RTC_INDEX_REGISTER (0x70)
15 #define RTC_TARGET_REGISTER (0x71)
16
17 #define RTC_INDEX_MASK (0x7F)
18 #define RTC_BANK_SIZE (0x80)
19
20 #define RTC_SECONDS (0x00)
21 #define RTC_MINUTES (0x02)
22 #define RTC_HOURS (0x04)
main(int argc,char * argv[])23 #define RTC_DAY_OF_MONTH (0x07)
24 #define RTC_MONTH (0x08)
25 #define RTC_YEAR (0x09)
26 #define CMOS_REGA (0x0A)
27 #define CMOS_REGB (0x0B)
28 #define CMOS_REGC (0x0C)
29 #define CMOS_REGD (0x0D)
30
31 #define RTC_UPDATE_IN_PROGRESS (0x80)
32 #define RTC_HOLD (0x80)
33 #define RTC_MODE_24HOUR (0x02)
34 #define RTC_CLOCK_DIVIDER (0x20)
35 #define RTC_RATE_SELECT (0x06)
36
37 #define BCD2BINARY(A) (((((A) >> 4) & 0xF) * 10) + ((A) & 0xF))
38 #define CENTURY_OFFSET (2000)
39
40 /**
41 Read the SPD data over the SMBus, at the given SmBus SPD address and copy the data to the data structure.
42 The SPD data locations read is controlled by the current boot mode.
43
44 @param[in] BootMode - The current MRC boot mode.
45 @param[in] Address - SPD SmBus address offset.
46 @param[in] Buffer - Buffer that contains the data read from the SPD.
47 @param[in] SpdDdr3Table - Indicates which SPD bytes to read.
48 @param[in] SpdDdr3TableSize - Size of SpdDdr3Table in bytes.
49 @param[in] SpdDdr4Table - Indicates which SPD bytes to read.
50 @param[in] SpdDdr4TableSize - Size of SpdDdr4Table in bytes.
51 @param[in] SpdLpddrTable - Indicates which SPD bytes to read.
52 @param[in] SpdLpddrTableSize - Size of SpdLpddrTable in bytes.
53
54 @retval TRUE if the read is successful, otherwise FALSE on error.
55 **/
56 BOOLEAN
57 GetSpdData (
58 IN SPD_BOOT_MODE BootMode,
59 IN UINT8 Address,
60 IN OUT UINT8 *Buffer,
61 IN UINT8 *SpdDdr3Table,
62 IN UINT32 SpdDdr3TableSize,
63 IN UINT8 *SpdDdr4Table,
64 IN UINT32 SpdDdr4TableSize,
65 IN UINT8 *SpdLpddrTable,
66 IN UINT32 SpdLpddrTableSize
67 );
68
69 /**
70 Output a string to the debug stream/device.
71
72 @param[in] String - The string to output.
73 **/
74 VOID
75 SaDebugPrint (
76 VOID *String
77 );
78
79 /**
80 Calculate the PCI device address for the given Bus/Device/Function/Offset.
81
82 @param[in] Bus - PCI bus
83 @param[in] Device - PCI device
84 @param[in] Function - PCI function
85 @param[in] Offset - Offset
86
87 @retval The PCI device address.
88 **/
89 UINT32
90 GetPciDeviceAddress (
91 IN const UINT8 Bus,
92 IN const UINT8 Device,
93 IN const UINT8 Function,
94 IN const UINT8 Offset
95 );
96
97 /**
98 Calculate the PCIE device address for the given Bus/Device/Function/Offset.
99
100 @param[in] Bus - PCI bus
101 @param[in] Device - PCI device
102 @param[in] Function - PCI function
103 @param[in] Offset - Offset
104
105 The PCIE device address.
106
107 @retval The PCIe device address
108 **/
109 UINT32
110 GetPcieDeviceAddress (
111 IN const UINT8 Bus,
112 IN const UINT8 Device,
113 IN const UINT8 Function,
114 IN const UINT8 Offset
115 );
116
117 /**
118 Read specific RTC/CMOS RAM
119
120 @param[in] Location Point to RTC/CMOS RAM offset for read
121
122 @retval The data of specific location in RTC/CMOS RAM.
123 **/
124 UINT8
125 PeiRtcRead (
126 IN const UINT8 Location
127 );
128
129 /**
130 Returns the current time, as determined by reading the Real Time Clock (RTC) on the platform.
131 Since RTC time is stored in BCD, convert each value to binary.
132
133 @param[out] Seconds - The current second (0-59).
134 @param[out] Minutes - The current minute (0-59).
135 @param[out] Hours - The current hour (0-23).
136 @param[out] DayOfMonth - The current day of the month (1-31).
137 @param[out] Month - The current month (1-12).
138 @param[out] Year - The current year (2000-2099).
139 **/
140 VOID
141 GetRtcTime (
142 OUT UINT8 *const Seconds,
143 OUT UINT8 *const Minutes,
144 OUT UINT8 *const Hours,
145 OUT UINT8 *const DayOfMonth,
146 OUT UINT8 *const Month,
147 OUT UINT16 *const Year
148 );
149
150 /**
151 Gets CPU current time.
152
153 @param[in] GlobalData - Pointer to global MRC data struct.
154
155 @retval The current CPU time in milliseconds.
156 **/
157 UINT64
158 GetCpuTime (
159 IN VOID *GlobalData
160 );
161
162 /**
163 Sets the specified number of memory words, a word at a time, at the
164 specified destination.
165
166 @param[in, out] Dest - Destination pointer.
167 @param[in] NumWords - The number of dwords to set.
168 @param[in] Value - The value to set.
169
170 @retval Pointer to the buffer.
171 **/
172 VOID *
173 SetMemWord (
174 IN OUT VOID *Dest,
175 IN UINTN NumWords,
176 IN const UINT16 Value
177 );
178
179 /**
180 Sets the specified number of memory dwords, a dword at a time, at the
181 specified destination.
182
183 @param[in, out] Dest - Destination pointer.
184 @param[in] NumDwords - The number of dwords to set.
185 @param[in] Value - The value to set.
186
187 @retval Pointer to the buffer.
188 **/
189 VOID *
190 SetMemDword (
191 IN OUT VOID *Dest,
192 IN UINT32 NumDwords,
193 IN const UINT32 Value
194 );
195
196 /**
197 Read 64 bits from the Memory Mapped I/O space.
198 Use MMX instruction for atomic access, because some MC registers have side effect.
199
200 @param[in] Address - Memory mapped I/O address.
201 **/
202 UINT64
203 SaMmioRead64 (
204 IN UINTN Address
205 );
206
207 /**
208 Write 64 bits to the Memory Mapped I/O space.
209 Use MMX instruction for atomic access, because some MC registers have side effect.
210
211 @param[in] Address - Memory mapped I/O address.
212 @param[in] Value - The value to write.
213 **/
214 UINT64
215 SaMmioWrite64 (
216 IN UINTN Address,
217 IN UINT64 Value
218 );
219
220 /**
221 Intel Silicon View Technology check point interface based on IO port reading
222
223 @param CheckPoint Check point AH value.
224 AH = 0x10: End of MRC State
225 AH = 0x20: End of DXE State
226 AH = 0x30: Ready to boot before INT-19h or UEFI boot
227 AH = 0x40: After OS booting, need a timer SMI trigger to implement (TBD)
228
229 @param PortReading IO port reading address used for breakpoints
230 **/
231 VOID
232 EFIAPI
233 IsvtCheckPoint (
234 IN UINT32 CheckPoint,
235 IN UINT32 PortReading
236 );
237
238 /**
239 Gets the current memory voltage (VDD).
240
241 @param[in] GlobalData - Pointer to global MRC data struct.
242 @param[in] DefaultVdd - Default Vdd for the given platform.
243
244 @retval The current memory voltage (VDD), in millivolts. 0 means platform default.
245 **/
246 UINT32
247 GetMemoryVdd (
248 IN VOID *GlobalData,
249 IN UINT32 DefaultVdd
250 );
251
252 /**
253 Sets the memory voltage (VDD) to the specified value.
254
255 @param[in] GlobalData - Pointer to global MRC data struct.
256 @param[in] DefaultVdd - Default Vdd for the given platform.
257 @param[in] Voltage - The new memory voltage to set.
258
259 @retval The actual memory voltage (VDD), in millivolts, that is closest to what the caller passed in.
260 **/
261 UINT32
262 SetMemoryVdd (
263 IN VOID *GlobalData,
264 IN UINT32 DefaultVdd,
265 IN UINT32 Voltage
266 );
267
268 /**
269 Check point that is called at various points in the MRC.
270
271 @param[in] GlobalData - MRC global data.
272 @param[in] Command - OEM command.
273 @param[in] Pointer - Command specific data.
274
275 @retval MrcStatus value.
276 **/
277 UINT32
278 CheckPoint (
279 VOID *GlobalData,
280 UINT32 Command,
281 VOID *Pointer
282 );
283
284 /**
285 Typically used to display to the I/O port 80h.
286
287 @param[in] GlobalData - Mrc Global Data
288 @param[in] DisplayDebugNumber - the number to display on port 80.
289
290 @retval Nothing.
291 **/
292 VOID
293 DebugHook (
294 VOID *GlobalData,
295 UINT16 DisplayDebugNumber
296 );
297
298 /**
299 Hook to take any action after returning from MrcStartMemoryConfiguration()
300 and prior to taking any action regarding MrcStatus. Pre-populated with issuing
301 Intel Silicon View Technology (ISVT) checkpoint 0x01.
302
303 @param[in] GlobalData - Mrc Global Data
304 @param[in] MrcStatus - Mrc status variable
305 **/
306 VOID
307 ReturnFromSmc (
308 VOID *GlobalData,
309 UINT32 MrcStatus
310 );
311
312 /**
313 Assert or deassert DRAM_RESET# pin; this is used in JEDEC Reset.
314
315 @param[in] PciEBaseAddress - PCI express base address.
316 @param[in] ResetValue - desired value of DRAM_RESET#. 1 - reset deasserted, 0 - reset asserted.
317 **/
318 VOID
319 SaDramReset (
320 IN UINT32 PciEBaseAddress,
321 IN UINT32 ResetValue
322 );
323
324