• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* $NoKeywords:$ */
2 /**
3  * @file
4  *
5  * FCH IMC lib
6  *
7  *
8  *
9  * @xrefitem bom "File Content Label" "Release Content"
10  * @e project:     AGESA
11  * @e sub-project: FCH
12  * @e \$Revision: 87213 $   @e \$Date: 2013-01-30 15:37:54 -0600 (Wed, 30 Jan 2013) $
13  *
14  */
15 /*
16 *****************************************************************************
17 *
18  * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc.
19  * All rights reserved.
20  *
21  * Redistribution and use in source and binary forms, with or without
22  * modification, are permitted provided that the following conditions are met:
23  *     * Redistributions of source code must retain the above copyright
24  *       notice, this list of conditions and the following disclaimer.
25  *     * Redistributions in binary form must reproduce the above copyright
26  *       notice, this list of conditions and the following disclaimer in the
27  *       documentation and/or other materials provided with the distribution.
28  *     * Neither the name of Advanced Micro Devices, Inc. nor the names of
29  *       its contributors may be used to endorse or promote products derived
30  *       from this software without specific prior written permission.
31  *
32  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
33  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
34  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
35  * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
36  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
38  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
39  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
41  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 ****************************************************************************
43 */
44 #include "FchPlatform.h"
45 #include "Filecode.h"
46 #define FILECODE PROC_FCH_IMC_IMCLIB_FILECODE
47 
48 /**
49  * WriteECmsg
50  *
51  *
52  *
53  * @param[in]  Address    - Address
54  * @param[in]  OpFlag     - Access width
55  * @param[in]  *Value     - Out Value pointer
56  * @param[in]  StdHeader
57  *
58  */
59 VOID
WriteECmsg(IN UINT8 Address,IN UINT8 OpFlag,IN VOID * Value,IN AMD_CONFIG_PARAMS * StdHeader)60 WriteECmsg (
61   IN       UINT8     Address,
62   IN       UINT8     OpFlag,
63   IN       VOID      *Value,
64   IN       AMD_CONFIG_PARAMS *StdHeader
65   )
66 {
67   UINT8   Index;
68 
69   ASSERT (OpFlag < AccessWidth64); /* TODO: Add the assertion to make it not crash for now. */
70   OpFlag = (OpFlag & 0x7f) - 1;
71   if (OpFlag == 0x02) {
72     OpFlag = 0x03;
73   }
74 
75   for (Index = 0; Index <= OpFlag; Index++) {
76     /// EC_LDN9_MAILBOX_BASE_ADDRESS
77     LibAmdIoWrite (AccessWidth8, MailBoxPort, &Address, StdHeader);
78     Address++;
79     /// EC_LDN9_MAILBOX_BASE_ADDRESS
80     LibAmdIoWrite (AccessWidth8, MailBoxPort + 1, (UINT8 *)Value + Index, StdHeader);
81   }
82 }
83 
84 /**
85  * ReadECmsg
86  *
87  *
88  *
89  * @param[in]  Address    - Address
90  * @param[in]  OpFlag     - Access width
91  * @param[out] *Value     - Out Value pointer
92  * @param[in]  StdHeader
93  *
94  */
95 VOID
ReadECmsg(IN UINT8 Address,IN UINT8 OpFlag,OUT VOID * Value,IN AMD_CONFIG_PARAMS * StdHeader)96 ReadECmsg (
97   IN       UINT8     Address,
98   IN       UINT8     OpFlag,
99      OUT   VOID      *Value,
100   IN       AMD_CONFIG_PARAMS *StdHeader
101   )
102 {
103   UINT8 Index;
104 
105   ASSERT (OpFlag < AccessWidth64); /* TODO: Add the assertion to make it not crash for now. */
106   OpFlag = (OpFlag & 0x7f) - 1;
107   if (OpFlag == 0x02) {
108     OpFlag = 0x03;
109   }
110 
111   for (Index = 0; Index <= OpFlag; Index++) {
112     /// EC_LDN9_MAILBOX_BASE_ADDRESS
113     LibAmdIoWrite (AccessWidth8, MailBoxPort, &Address, StdHeader);
114     Address++;
115     /// EC_LDN9_MAILBOX_BASE_ADDRESS
116     LibAmdIoRead (AccessWidth8, MailBoxPort + 1, (UINT8 *)Value + Index, StdHeader);
117   }
118 }
119 
120 /**
121  * WaitForEcLDN9MailboxCmdAck
122  *
123  *
124  * @param[in] StdHeader
125  *
126  */
127 VOID
WaitForEcLDN9MailboxCmdAck(IN AMD_CONFIG_PARAMS * StdHeader)128 WaitForEcLDN9MailboxCmdAck (
129   IN AMD_CONFIG_PARAMS  *StdHeader
130   )
131 {
132   UINT8    Msgdata;
133   UINT16   Delaytime;
134 
135   Msgdata = 0;
136 
137   for (Delaytime = 0; Delaytime < 0xFFFF; Delaytime++) {
138     ReadECmsg (MSG_REG0, AccessWidth8, &Msgdata, StdHeader);
139     if ( Msgdata == 0xfa) {
140       break;
141     }
142 
143     FchStall (5, StdHeader);                            /// Wait for 1ms
144   }
145 }
146 
147 /**
148  * ImcSleep - IMC Sleep.
149  *
150  *
151  * @param[in] FchDataPtr Fch configuration structure pointer.
152  *
153  */
154 VOID
ImcSleep(IN VOID * FchDataPtr)155 ImcSleep (
156   IN  VOID     *FchDataPtr
157   )
158 {
159   UINT8        Msgdata;
160   FCH_DATA_BLOCK         *LocalCfgPtr;
161   AMD_CONFIG_PARAMS      *StdHeader;
162 
163   LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr;
164   StdHeader = LocalCfgPtr->StdHeader;
165 
166   if (!(IsImcEnabled (StdHeader)) ) {
167     return;                                                ///IMC is not enabled
168   }
169 
170   Msgdata = 0x00;
171   WriteECmsg (MSG_REG0, AccessWidth8, &Msgdata, StdHeader);
172   Msgdata = 0xB4;
173   WriteECmsg (MSG_REG1, AccessWidth8, &Msgdata, StdHeader);
174   Msgdata = 0x00;
175   WriteECmsg (MSG_REG2, AccessWidth8, &Msgdata, StdHeader);
176   Msgdata = 0x96;
177   WriteECmsg (MSG_SYS_TO_IMC, AccessWidth8, &Msgdata, StdHeader);
178   WaitForEcLDN9MailboxCmdAck (StdHeader);
179 }
180 
181 /**
182  * SoftwareDisableImc - Software disable IMC strap
183  *
184  *
185  * @param[in] FchDataPtr Fch configuration structure pointer.
186  *
187  */
188 VOID
SoftwareDisableImc(IN VOID * FchDataPtr)189 SoftwareDisableImc (
190   IN  VOID     *FchDataPtr
191   )
192 {
193   UINT8    ValueByte;
194   UINT8    PortStatusByte;
195   UINT32   AbValue;
196   UINT32   ABStrapOverrideReg;
197   AMD_CONFIG_PARAMS     *StdHeader;
198 
199   StdHeader = ((FCH_DATA_BLOCK *) FchDataPtr)->StdHeader;
200   GetChipSysMode (&PortStatusByte, StdHeader);
201 
202   RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGC8 + 3, AccessWidth8, 0x7F, BIT7, StdHeader);
203   ReadPmio (0xBF, AccessWidth8, &ValueByte, StdHeader);
204 
205   ReadMem ((ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG80), AccessWidth32, &AbValue);
206   ABStrapOverrideReg = AbValue;
207   ABStrapOverrideReg &= ~BIT2;                           // bit2=0 EcEnableStrap
208   WriteMem ((ACPI_MMIO_BASE + MISC_BASE + 0x84), AccessWidth32, &ABStrapOverrideReg);
209 
210   ReadPmio (FCH_PMIOA_REGD7, AccessWidth8, &ValueByte, StdHeader);
211   ValueByte |= BIT1;
212   WritePmio (FCH_PMIOA_REGD7, AccessWidth8, &ValueByte, StdHeader);
213 
214   ValueByte = 06;
215   LibAmdIoWrite (AccessWidth8, 0xcf9, &ValueByte, StdHeader);
216   FchStall (0xffffffff, StdHeader);
217 }
218 
219 /**
220  * ImcDisableSurebootTimer - IMC Disable Sureboot Timer.
221  *
222  *
223  * @param[in] FchDataPtr Fch configuration structure pointer.
224  *
225  */
226 VOID
ImcDisableSurebootTimer(IN VOID * FchDataPtr)227 ImcDisableSurebootTimer (
228   IN  VOID     *FchDataPtr
229   )
230 {
231   UINT8   Msgdata;
232   AMD_CONFIG_PARAMS      *StdHeader;
233 
234   StdHeader = ((FCH_DATA_BLOCK *) FchDataPtr)->StdHeader;
235 
236   if (!(IsImcEnabled (StdHeader)) ) {
237     return;                                      ///IMC is not enabled
238   }
239 
240   ImcWakeup (FchDataPtr);
241   Msgdata = 0x00;
242   WriteECmsg (MSG_REG0, AccessWidth8, &Msgdata, StdHeader);
243   Msgdata = 0x01;
244   WriteECmsg (MSG_REG1, AccessWidth8, &Msgdata, StdHeader);
245   Msgdata = 0x00;
246   WriteECmsg (MSG_REG2, AccessWidth8, &Msgdata, StdHeader);
247   Msgdata = 0x94;
248   WriteECmsg (MSG_SYS_TO_IMC, AccessWidth8, &Msgdata, StdHeader);
249   WaitForEcLDN9MailboxCmdAck (StdHeader);
250   ImcSleep (FchDataPtr);
251 }
252 
253 /**
254  * ImcWakeup - IMC Wakeup.
255  *
256  *
257  * @param[in] FchDataPtr Fch configuration structure pointer.
258  *
259  */
260 VOID
ImcWakeup(IN VOID * FchDataPtr)261 ImcWakeup (
262   IN  VOID     *FchDataPtr
263   )
264 {
265   UINT8   Msgdata;
266   AMD_CONFIG_PARAMS     *StdHeader;
267 
268   StdHeader = ((FCH_DATA_BLOCK *) FchDataPtr)->StdHeader;
269   if (!(IsImcEnabled (StdHeader)) ) {
270     return;                                      ///IMC is not enabled
271   }
272 
273   Msgdata = 0x00;
274   WriteECmsg (MSG_REG0, AccessWidth8, &Msgdata, StdHeader);
275   Msgdata = 0xB5;
276   WriteECmsg (MSG_REG1, AccessWidth8, &Msgdata, StdHeader);
277   Msgdata = 0x00;
278   WriteECmsg (MSG_REG2, AccessWidth8, &Msgdata, StdHeader);
279   Msgdata = 0x96;
280   WriteECmsg (MSG_SYS_TO_IMC, AccessWidth8, &Msgdata, StdHeader);
281   WaitForEcLDN9MailboxCmdAck (StdHeader);
282 }
283 
284 /**
285  * ImcIdle - IMC Idle.
286  *
287  *
288  * @param[in] FchDataPtr Fch configuration structure pointer.
289  *
290  */
291 VOID
ImcIdle(IN VOID * FchDataPtr)292 ImcIdle (
293   IN  VOID     *FchDataPtr
294   )
295 {
296   UINT8   Msgdata;
297   AMD_CONFIG_PARAMS     *StdHeader;
298 
299   StdHeader = ((FCH_DATA_BLOCK *) FchDataPtr)->StdHeader;
300 
301   if (!(IsImcEnabled (StdHeader)) ) {
302     return;                                      ///IMC is not enabled
303   }
304 
305   Msgdata = 0x00;
306   WriteECmsg (MSG_REG0, AccessWidth8, &Msgdata, StdHeader);
307   Msgdata = 0x01;
308   WriteECmsg (MSG_REG1, AccessWidth8, &Msgdata, StdHeader);
309   Msgdata = 0x00;
310   WriteECmsg (MSG_REG2, AccessWidth8, &Msgdata, StdHeader);
311   Msgdata = 0x98;
312   WriteECmsg (MSG_SYS_TO_IMC, AccessWidth8, &Msgdata, StdHeader);
313   WaitForEcLDN9MailboxCmdAck (StdHeader);
314 }
315