1 /**
2 
3 Copyright (c) 2012  - 2014, Intel Corporation. All rights reserved
4 
5   This program and the accompanying materials are licensed and made available under
6   the terms and conditions of the BSD License that accompanies this distribution.
7   The full text of the license may be found at
8   http://opensource.org/licenses/bsd-license.php.
9 
10   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 
13 
14 
15   @file
16   PchAccess.h
17 
18   @brief
19   Macros that simplify accessing PCH devices's PCI registers.
20 
21   ** NOTE ** these macros assume the PCH device is on BUS 0
22 
23 **/
24 #ifndef _PCH_ACCESS_H_
25 #define _PCH_ACCESS_H_
26 
27 #include "PchRegs.h"
28 #include "PchCommonDefinitions.h"
29 
30 #ifndef STALL_ONE_MICRO_SECOND
31 #define STALL_ONE_MICRO_SECOND 1
32 #endif
33 #ifndef STALL_ONE_SECOND
34 #define STALL_ONE_SECOND 1000000
35 #endif
36 
37 ///
38 /// Memory Mapped PCI Access macros
39 ///
40 ///
41 /// PCI Device MM Base
42 ///
43 #ifndef MmPciAddress
44 #define MmPciAddress(Segment, Bus, Device, Function, Register) \
45   ((UINTN) PatchPcdGet64 (PcdPciExpressBaseAddress) + \
46    (UINTN) (Bus << 20) + \
47    (UINTN) (Device << 15) + \
48    (UINTN) (Function << 12) + \
49    (UINTN) (Register) \
50   )
51 #endif
52 ///
53 /// Pch Controller PCI access macros
54 ///
55 #define PCH_RCRB_BASE ( \
56   MmioRead32 (MmPciAddress (0, \
57   DEFAULT_PCI_BUS_NUMBER_PCH, \
58   PCI_DEVICE_NUMBER_PCH_LPC, \
59   PCI_FUNCTION_NUMBER_PCH_LPC), \
60   R_PCH_LPC_RCBA)) & B_PCH_LPC_RCBA_BAR \
61   )
62 
63 ///
64 /// Device 0x1b, Function 0
65 ///
66 #define PchAzaliaPciCfg32(Register) \
67   MmioRead32 ( \
68   MmPciAddress (0, \
69   DEFAULT_PCI_BUS_NUMBER_PCH, \
70   PCI_DEVICE_NUMBER_PCH_AZALIA, \
71   0, \
72   Register) \
73   )
74 
75 #define PchAzaliaPciCfg32Or(Register, OrData) \
76   MmioOr32 ( \
77   MmPciAddress (0, \
78   DEFAULT_PCI_BUS_NUMBER_PCH, \
79   PCI_DEVICE_NUMBER_PCH_AZALIA, \
80   0, \
81   Register), \
82   OrData \
83   )
84 
85 #define PchAzaliaPciCfg32And(Register, AndData) \
86   MmioAnd32 ( \
87   MmPciAddress (0, \
88   DEFAULT_PCI_BUS_NUMBER_PCH, \
89   PCI_DEVICE_NUMBER_PCH_AZALIA, \
90   0, \
91   Register), \
92   AndData \
93   )
94 
95 #define PchAzaliaPciCfg32AndThenOr(Register, AndData, OrData) \
96   MmioAndThenOr32 ( \
97   MmPciAddress (0, \
98   DEFAULT_PCI_BUS_NUMBER_PCH, \
99   PCI_DEVICE_NUMBER_PCH_AZALIA, \
100   0, \
101   Register), \
102   OrData \
103   )
104 
105 #define PchAzaliaPciCfg16(Register) \
106   MmioRead16 ( \
107   MmPciAddress (0, \
108   DEFAULT_PCI_BUS_NUMBER_PCH, \
109   PCI_DEVICE_NUMBER_PCH_AZALIA, \
110   0, \
111   Register) \
112   )
113 
114 #define PchAzaliaPciCfg16Or(Register, OrData) \
115   MmioOr16 ( \
116   MmPciAddress (0, \
117   DEFAULT_PCI_BUS_NUMBER_PCH, \
118   PCI_DEVICE_NUMBER_PCH_AZALIA, \
119   0, \
120   Register), \
121   OrData \
122   )
123 
124 #define PchAzaliaPciCfg16And(Register, AndData) \
125   MmioAnd16 ( \
126   MmPciAddress (0, \
127   DEFAULT_PCI_BUS_NUMBER_PCH, \
128   PCI_DEVICE_NUMBER_PCH_AZALIA, \
129   0, \
130   Register), \
131   AndData \
132   )
133 
134 #define PchAzaliaPciCfg16AndThenOr(Register, AndData, OrData) \
135   MmioAndThenOr16 ( \
136   MmPciAddress (0, \
137   DEFAULT_PCI_BUS_NUMBER_PCH, \
138   PCI_DEVICE_NUMBER_PCH_AZALIA, \
139   0, \
140   Register), \
141   AndData, \
142   OrData \
143   )
144 
145 #define PchAzaliaPciCfg8(Register)  MmioRead8 (MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_AZALIA, 0, Register))
146 
147 #define PchAzaliaPciCfg8Or(Register, OrData) \
148   MmioOr8 ( \
149   MmPciAddress (0, \
150   DEFAULT_PCI_BUS_NUMBER_PCH, \
151   PCI_DEVICE_NUMBER_PCH_AZALIA, \
152   0, \
153   Register), \
154   OrData \
155   )
156 
157 #define PchAzaliaPciCfg8And(Register, AndData) \
158   MmioAnd8 ( \
159   MmPciAddress (0, \
160   DEFAULT_PCI_BUS_NUMBER_PCH, \
161   PCI_DEVICE_NUMBER_PCH_AZALIA, \
162   0, \
163   Register), \
164   AndData \
165   )
166 
167 #define PchAzaliaPciCfg8AndThenOr(Register, AndData, OrData) \
168   MmioAndThenOr8 ( \
169   MmPciAddress (0, \
170   DEFAULT_PCI_BUS_NUMBER_PCH, \
171   PCI_DEVICE_NUMBER_PCH_AZALIA, \
172   0, \
173   Register), \
174   AndData, \
175   OrData \
176   )
177 
178 ///
179 /// Device 0x1f, Function 0
180 ///
181 #define PchLpcPciCfg32(Register)  MmioRead32 (MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, Register))
182 
183 #define PchLpcMmioOr32 (Register, OrData) \
184   MmioOr32 ( \
185   MmPciAddress (0, \
186   DEFAULT_PCI_BUS_NUMBER_PCH, \
187   PCI_DEVICE_NUMBER_PCH_LPC, \
188   0, \
189   Register), \
190   OrData \
191   )
192 
193 #define PchLpcPciCfg32And(Register, AndData) \
194   MmioAnd32 ( \
195   MmPciAddress (0, \
196   DEFAULT_PCI_BUS_NUMBER_PCH, \
197   PCI_DEVICE_NUMBER_PCH_LPC, \
198   0, \
199   Register), \
200   AndData \
201   )
202 
203 #define PchLpcPciCfg32AndThenOr(Register, AndData, OrData) \
204   MmioAndThenOr32 ( \
205   MmPciAddress (0, \
206   DEFAULT_PCI_BUS_NUMBER_PCH, \
207   PCI_DEVICE_NUMBER_PCH_LPC, \
208   0, \
209   Register), \
210   AndData, \
211   OrData \
212   )
213 
214 #define PchLpcPciCfg16(Register)  MmioRead16 (MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, Register))
215 
216 #define PchLpcPciCfg16Or(Register, OrData) \
217   MmioOr16 ( \
218   MmPciAddress (0, \
219   DEFAULT_PCI_BUS_NUMBER_PCH, \
220   PCI_DEVICE_NUMBER_PCH_LPC, \
221   0, \
222   Register), \
223   OrData \
224   )
225 
226 #define PchLpcPciCfg16And(Register, AndData) \
227   MmioAndThenOr16 ( \
228   MmPciAddress (0, \
229   DEFAULT_PCI_BUS_NUMBER_PCH, \
230   PCI_DEVICE_NUMBER_PCH_LPC, \
231   0, \
232   Register), \
233   AndData \
234   )
235 
236 #define PchLpcPciCfg16AndThenOr(Register, AndData, OrData) \
237   MmioAndThenOr16 ( \
238   MmPciAddress (0, \
239   DEFAULT_PCI_BUS_NUMBER_PCH, \
240   PCI_DEVICE_NUMBER_PCH_LPC, \
241   0, \
242   Register), \
243   AndData, \
244   OrData \
245   )
246 
247 #define PchLpcPciCfg8(Register) MmioRead8 (MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, Register))
248 
249 #define PchLpcPciCfg8Or(Register, OrData) \
250   MmioOr8 ( \
251   MmPciAddress (0, \
252   DEFAULT_PCI_BUS_NUMBER_PCH, \
253   PCI_DEVICE_NUMBER_PCH_LPC, \
254   0, \
255   Register), \
256   OrData \
257   )
258 
259 #define PchLpcPciCfg8And(Register, AndData) \
260   MmioAnd8 ( \
261   MmPciAddress (0, \
262   DEFAULT_PCI_BUS_NUMBER_PCH, \
263   PCI_DEVICE_NUMBER_PCH_LPC, \
264   0, \
265   Register), \
266   AndData \
267   )
268 
269 #define PchLpcPciCfg8AndThenOr(Register, AndData, OrData) \
270   MmioAndThenOr8 ( \
271   MmPciAddress (0, \
272   DEFAULT_PCI_BUS_NUMBER_PCH, \
273   PCI_DEVICE_NUMBER_PCH_LPC, \
274   0, \
275   Register), \
276   AndData, \
277   OrData \
278   )
279 
280 
281 ///
282 /// SATA device 0x13, Function 0
283 ///
284 #define PchSataPciCfg32(Register) MmioRead32 (MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_SATA, PCI_FUNCTION_NUMBER_PCH_SATA, Register))
285 
286 #define PchSataPciCfg32Or(Register, OrData) \
287   MmioOr32 ( \
288   MmPciAddress (0, \
289   DEFAULT_PCI_BUS_NUMBER_PCH, \
290   PCI_DEVICE_NUMBER_PCH_SATA, \
291   PCI_FUNCTION_NUMBER_PCH_SATA, \
292   Register), \
293   OrData \
294   )
295 
296 #define PchSataPciCfg32And(Register, AndData) \
297   MmioAnd32 ( \
298   MmPciAddress (0, \
299   DEFAULT_PCI_BUS_NUMBER_PCH, \
300   PCI_DEVICE_NUMBER_PCH_SATA, \
301   PCI_FUNCTION_NUMBER_PCH_SATA, \
302   Register), \
303   AndData \
304   )
305 
306 #define PchSataPciCfg32AndThenOr(Register, AndData, OrData) \
307   MmioAndThenOr32 ( \
308   MmPciAddress (0, \
309   DEFAULT_PCI_BUS_NUMBER_PCH, \
310   PCI_DEVICE_NUMBER_PCH_SATA, \
311   PCI_FUNCTION_NUMBER_PCH_SATA, \
312   Register), \
313   AndData, \
314   OrData \
315   )
316 
317 #define PchSataPciCfg16(Register) MmioRead16 (MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_SATA, PCI_FUNCTION_NUMBER_PCH_SATA, Register))
318 
319 #define PchSataPciCfg16Or(Register, OrData) \
320   MmioOr16 ( \
321   MmPciAddress (0, \
322   DEFAULT_PCI_BUS_NUMBER_PCH, \
323   PCI_DEVICE_NUMBER_PCH_SATA, \
324   PCI_FUNCTION_NUMBER_PCH_SATA, \
325   Register), \
326   OrData \
327   )
328 
329 #define PchSataPciCfg16And(Register, AndData) \
330   MmioAndThenOr16 ( \
331   MmPciAddress (0, \
332   DEFAULT_PCI_BUS_NUMBER_PCH, \
333   PCI_DEVICE_NUMBER_PCH_SATA, \
334   PCI_FUNCTION_NUMBER_PCH_SATA, \
335   Register), \
336   AndData \
337   )
338 
339 #define PchSataPciCfg16AndThenOr(Register, AndData, OrData) \
340   MmioAndThenOr16 ( \
341   MmPciAddress (0, \
342   DEFAULT_PCI_BUS_NUMBER_PCH, \
343   PCI_DEVICE_NUMBER_PCH_SATA, \
344   PCI_FUNCTION_NUMBER_PCH_SATA, \
345   Register), \
346   AndData, \
347   OrData \
348   )
349 
350 #define PchSataPciCfg8(Register)  MmioRead8 (MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_SATA, PCI_FUNCTION_NUMBER_PCH_SATA, Register))
351 
352 #define PchSataPciCfg8Or(Register, OrData) \
353   MmioOr8 ( \
354   MmPciAddress (0, \
355   DEFAULT_PCI_BUS_NUMBER_PCH, \
356   PCI_DEVICE_NUMBER_PCH_SATA, \
357   PCI_FUNCTION_NUMBER_PCH_SATA, \
358   Register), \
359   OrData \
360   )
361 
362 #define PchSataPciCfg8And(Register, AndData) \
363   MmioAnd8 ( \
364   MmPciAddress (0, \
365   DEFAULT_PCI_BUS_NUMBER_PCH, \
366   PCI_DEVICE_NUMBER_PCH_SATA, \
367   PCI_FUNCTION_NUMBER_PCH_SATA, \
368   Register), \
369   AndData \
370   )
371 
372 #define PchSataPciCfg8AndThenOr(Register, AndData, OrData) \
373   MmioAndThenOr8 ( \
374   MmPciAddress (0, \
375   DEFAULT_PCI_BUS_NUMBER_PCH, \
376   PCI_DEVICE_NUMBER_PCH_SATA, \
377   PCI_FUNCTION_NUMBER_PCH_SATA, \
378   Register), \
379   AndData, \
380   OrData \
381   )
382 
383 
384 ///
385 /// Root Complex Register Block
386 ///
387 #define PchMmRcrb32(Register)                           MmioRead32 (PCH_RCRB_BASE + Register)
388 
389 #define PchMmRcrb32Or(Register, OrData)                 MmioOr32 (PCH_RCRB_BASE + Register, OrData)
390 
391 #define PchMmRcrb32And(Register, AndData)               MmioAnd32 (PCH_RCRB_BASE + Register, AndData)
392 
393 #define PchMmRcrb32AndThenOr(Register, AndData, OrData) MmioAndThenOr32 (PCH_RCRB_BASE + Register, AndData, OrData)
394 
395 #define PchMmRcrb16(Register)                           MmioRead16 (PCH_RCRB_BASE + Register)
396 
397 #define PchMmRcrb16Or(Register, OrData)                 MmioOr16 (PCH_RCRB_BASE + Register, OrData)
398 
399 #define PchMmRcrb16And(Register, AndData)               MmioAnd16 (PCH_RCRB_BASE + Register, AndData)
400 
401 #define PchMmRcrb16AndThenOr(Register, AndData, OrData) MmioAndThenOr16 (PCH_RCRB_BASE + Register, AndData, OrData)
402 
403 #define PchMmRcrb8(Register)                            MmioRead8 (PCH_RCRB_BASE + Register)
404 
405 #define PchMmRcrb8Or(Register, OrData)                  MmioOr8 (PCH_RCRB_BASE + Register, OrData)
406 
407 #define PchMmRcrb8And(Register, AndData)                MmioAnd8 (PCH_RCRB_BASE + Register, AndData)
408 
409 #define PchMmRcrb8AndThenOr(Register, AndData, OrData)  MmioAndThenOr8 (PCH_RCRB_BASE + Register, AndData, OrData)
410 
411 
412 ///
413 /// Message Bus
414 ///
415 
416 ///
417 /// Message Bus Registers
418 ///
419 #define MC_MCR            0x000000D0 // Cunit Message Control Register
420 #define MC_MDR            0x000000D4 // Cunit Message Data Register
421 #define MC_MCRX           0x000000D8 // Cunit Message Control Register Extension
422 
423 ///
424 /// Message Bus API
425 ///
426 #define MSG_BUS_ENABLED   0x000000F0
427 #define MSGBUS_MASKHI     0xFFFFFF00
428 #define MSGBUS_MASKLO     0x000000FF
429 #define MESSAGE_DWORD_EN  BIT4 | BIT5 | BIT6 | BIT7
430 
431 #define PchMsgBusRead32(PortId, Register, Dbuff, ReadOpCode, WriteOpCode) \
432 { \
433   MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCRX), (UINT32) (Register & MSGBUS_MASKHI)); \
434   MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCR ), (UINT32) ((ReadOpCode << 24) | (PortId << 16) | ((Register & MSGBUS_MASKLO) << 8) | MESSAGE_DWORD_EN)); \
435   (Dbuff) = MmioRead32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MDR)); \
436 }
437 
438 #define PchMsgBusAnd32(PortId, Register, Dbuff, AndData, ReadOpCode, WriteOpCode) \
439 { \
440   MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCRX), (UINT32) (Register & MSGBUS_MASKHI)); \
441   MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCR ), (UINT32) ((ReadOpCode << 24) | (PortId << 16) | ((Register & MSGBUS_MASKLO) << 8) | MESSAGE_DWORD_EN)); \
442   (Dbuff) = MmioRead32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MDR)); \
443   MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCRX), (UINT32) (Register & MSGBUS_MASKHI)); \
444   MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MDR ), (UINT32) (Dbuff & AndData)); \
445   MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCR ), (UINT32) ((WriteOpCode << 24) | (PortId << 16) | ((Register & MSGBUS_MASKLO) << 8) | MESSAGE_DWORD_EN)); \
446 }
447 
448 #define PchMsgBusOr32(PortId, Register, Dbuff, OrData, ReadOpCode, WriteOpCode) \
449 { \
450   MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCRX), (UINT32) (Register & MSGBUS_MASKHI)); \
451   MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCR ), (UINT32) ((ReadOpCode << 24) | (PortId << 16) | ((Register & MSGBUS_MASKLO) << 8) | MESSAGE_DWORD_EN)); \
452   (Dbuff) = MmioRead32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MDR)); \
453   MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCRX), (UINT32) (Register & MSGBUS_MASKHI)); \
454   MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MDR ), (UINT32) (Dbuff | OrData)); \
455   MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCR ), (UINT32) ((WriteOpCode << 24) | (PortId << 16) | ((Register & MSGBUS_MASKLO) << 8) | MESSAGE_DWORD_EN)); \
456 }
457 
458 #define PchMsgBusAndThenOr32(PortId, Register, Dbuff, AndData, OrData, ReadOpCode, WriteOpCode) \
459 { \
460   MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCRX), (UINT32) (Register & MSGBUS_MASKHI)); \
461   MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCR ), (UINT32) ((ReadOpCode << 24) | (PortId << 16) | ((Register & MSGBUS_MASKLO) << 8) | MESSAGE_DWORD_EN)); \
462   (Dbuff) = MmioRead32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MDR)); \
463   MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCRX), (UINT32) (Register & MSGBUS_MASKHI)); \
464   MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MDR ), (UINT32) ((Dbuff & AndData) | OrData)); \
465   MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCR ), (UINT32) ((WriteOpCode << 24) | (PortId << 16) | ((Register & MSGBUS_MASKLO) << 8) | MESSAGE_DWORD_EN)); \
466 }
467 
468 typedef struct _PCH_MSG_BUS_TABLE_STRUCT {
469   UINT32      PortId;
470   UINT32      Address;
471   UINT32      AndMask;
472   UINT32      OrMask;
473   UINT32      ReadOpCode;
474   UINT32      WriteOpCode;
475 } PCH_MSG_BUS_TABLE_STRUCT_TABLE_STRUCT;
476 
477 #ifndef _S3SUPPORT_
478 #define _S3SUPPORT_
479 UINTN MCRX;
480 UINTN MCR;
481 //
482 // In S3 execute, we should follow the MSG BUS access procedure to restore the saving data.
483 // To do so, we adopt READ ->> SAVE
484 // Indirect IO access: (According BayTrail-M EDS chapter 3.6)
485 // 1. Write Index port into MSG BUS_MCRX first.
486 // 2. Write content to data register which is called MSG BUS_MDR.
487 // 3. Send "message bus control" to complete the procedure.
488 //
489 #define S3BootScriptSaveMsgBusToMemWrite(PortId, Register, Dbuff, ReadOpCode, WriteOpCode) \
490 { \
491   MCRX = (UINTN) Register & MSGBUS_MASKHI; \
492   MCR = (UINTN) ((ReadOpCode << 24) | (PortId << 16) | ((Register & MSGBUS_MASKLO) << 8) | MESSAGE_DWORD_EN); \
493   MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCRX), (UINT32) MCRX); \
494   S3BootScriptSaveMemWrite(EfiBootScriptWidthUint32, (UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCRX),1, (VOID *) (UINTN) &MCRX); \
495   MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCR ), (UINT32) MCR); \
496   (Dbuff) = (UINT32) MmioRead32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MDR)); \
497   S3BootScriptSaveMemWrite(EfiBootScriptWidthUint32, (UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MDR),1, (VOID *) &Dbuff); \
498   MCR = (UINTN) ((WriteOpCode << 24) | (PortId << 16) | ((Register & MSGBUS_MASKLO) << 8) | MESSAGE_DWORD_EN); \
499   S3BootScriptSaveMemWrite(EfiBootScriptWidthUint32, (UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCR),1, (VOID *) (UINTN) &MCR); \
500 }
501 
502 //
503 // This macro combines two function:  1. PchMsgBusAndThenOr32 ()  2. S3 boot script save
504 //
505 #define PchMsgBusAndThenOr32AddToS3Save(PortId, Register, Dbuff, AndData, OrData, ReadOpCode, WriteOpCode) \
506 { \
507   MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCRX), (UINT32) (Register & MSGBUS_MASKHI)); \
508   MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCR ), (UINT32) ((ReadOpCode << 24) | (PortId << 16) | ((Register & MSGBUS_MASKLO) << 8) | MESSAGE_DWORD_EN)); \
509   (Dbuff) = (UINT32) MmioRead32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MDR)); \
510   MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCRX), (UINT32) (Register & MSGBUS_MASKHI)); \
511   MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MDR ), (UINT32) ((Dbuff & AndData) | OrData)); \
512   MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCR ), (UINT32) ((WriteOpCode << 24) | (PortId << 16) | ((Register & MSGBUS_MASKLO) << 8) | MESSAGE_DWORD_EN)); \
513   MCRX = (UINTN) Register & MSGBUS_MASKHI; \
514   MCR = (UINTN) ((ReadOpCode << 24) | (PortId << 16) | ((Register & MSGBUS_MASKLO) << 8) | MESSAGE_DWORD_EN); \
515   MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCRX), (UINT32) MCRX); \
516   S3BootScriptSaveMemWrite(EfiBootScriptWidthUint32, (UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCRX),1,(VOID *) (UINTN) &MCRX); \
517   MmioWrite32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCR ), (UINT32) MCR); \
518   (Dbuff) = (UINT32) MmioRead32 ((UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MDR)); \
519   S3BootScriptSaveMemWrite(EfiBootScriptWidthUint32, (UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MDR),1,(VOID *) &Dbuff); \
520   MCR = (UINTN) ((WriteOpCode << 24) | (PortId << 16) | ((Register & MSGBUS_MASKLO) << 8) | MESSAGE_DWORD_EN); \
521   S3BootScriptSaveMemWrite(EfiBootScriptWidthUint32, (UINTN) (PatchPcdGet64 (PcdPciExpressBaseAddress) + MC_MCR),1,(VOID *) (UINTN) &MCR); \
522 }
523 
524 #endif
525 
526 #endif
527