blob: e49fb789eb614c4aa57335bfe21a96b5267b421d [file] [log] [blame]
Marc Jones9ef6e522016-09-20 20:16:20 -06001/* $NoKeywords:$ */
2/**
3 * @file
4 *
5 * PSP Base Library
6 *
7 * Contains interface to the PSP library
8 *
9 * @xrefitem bom "File Content Label" "Release Content"
10 * @e project: AGESA
11 * @e sub-project: PSP
Marshall Dawsona0400652016-10-15 09:20:43 -060012 * @e \$Revision$ @e \$Date$
Marc Jones9ef6e522016-09-20 20:16:20 -060013 *
14 */
15 /*****************************************************************************
16 *
Marshall Dawsona0400652016-10-15 09:20:43 -060017 * Copyright (c) 2008 - 2016, Advanced Micro Devices, Inc.
Marc Jones9ef6e522016-09-20 20:16:20 -060018 * All rights reserved.
19 *
20 * Redistribution and use in source and binary forms, with or without
21 * modification, are permitted provided that the following conditions are met:
22 * * Redistributions of source code must retain the above copyright
23 * notice, this list of conditions and the following disclaimer.
24 * * Redistributions in binary form must reproduce the above copyright
25 * notice, this list of conditions and the following disclaimer in the
26 * documentation and/or other materials provided with the distribution.
27 * * Neither the name of Advanced Micro Devices, Inc. nor the names of
28 * its contributors may be used to endorse or promote products derived
29 * from this software without specific prior written permission.
30 *
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
32 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
33 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
34 * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
35 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
36 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
38 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
40 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 *
42 ***************************************************************************/
43
44
45/*----------------------------------------------------------------------------------------
46 * M O D U L E S U S E D
47 *----------------------------------------------------------------------------------------
48 */
49#include "AGESA.h"
50#include "Filecode.h"
Marshall Dawsona0400652016-10-15 09:20:43 -060051#include "Fch.h"
Marc Jones9ef6e522016-09-20 20:16:20 -060052#include "PspBaseLib.h"
53
54#define FILECODE PROC_PSP_PSPBASELIB_PSPBASELIB_FILECODE
Marshall Dawsona0400652016-10-15 09:20:43 -060055#define PSP_BAR_TMP_BASE 0xFEA00000ul
Marc Jones9ef6e522016-09-20 20:16:20 -060056
57#define GET_PCI_BUS(Reg) (((UINT32) Reg >> 16) & 0xFF)
58#define GET_PCI_DEV(Reg) (((UINT32) Reg >> 11) & 0x1F)
59#define GET_PCI_FUNC(Reg) (((UINT32) Reg >> 8) & 0x7)
60#define GET_PCI_OFFSET(Reg) ((UINT32)Reg & 0xFF)
61
62#define PCI_CONFIG_SMU_INDIRECT_INDEX 0xB8 ///< Gnb Offset index for SMU mbox
63#define PCI_CONFIG_SMU_INDIRECT_DATA 0xBC ///< Gnb Offset data for SMU mbox
64
65#define SMU_CC_PSP_FUSES_STATUS 0xC0018000ul ///< offset in GNB to find PSP fusing
66#define SMU_CC_PSP_FUSES_SECURE BIT0 ///< BIT0
67#define SMU_CC_PSP_FUSES_FRA_ENABLE BIT1 ///< BIT1
68#define SMU_CC_PSP_FUSES_PROTO BIT2 ///< BIT2
69#define PLATFORM_SECURE_BOOT_EN BIT4 ///< BIT4
70
71
72#define PSP_BLANK_PART 0 ///< Blank part
73#define PSP_PROTO_PART SMU_CC_PSP_FUSES_PROTO ///< Proto Part
74#define PSP_NON_SECURE_PART (SMU_CC_PSP_FUSES_PROTO + SMU_CC_PSP_FUSES_PCPU_DIS) ///< Non Secure Part
75#define PSP_SECURE_PART (SMU_CC_PSP_FUSES_PROTO + SMU_CC_PSP_FUSES_SECURE) ///< Secure Part
76#define PSP_FRA_MODE (SMU_CC_PSP_FUSES_FRA_ENABLE + SMU_CC_PSP_FUSES_PROTO + SMU_CC_PSP_FUSES_SECURE) ///< FRA Part
77
Marshall Dawsona0400652016-10-15 09:20:43 -060078#define PSP_MUTEX_REG0_OFFSET (24 * 4) ///< PSP Mutex0 register offset
79#define PSP_MUTEX_REG1_OFFSET (25 * 4) ///< PSP Mutex1 register offset
80
81#ifndef OFFSET_OF
82#define OFFSET_OF(TYPE, Field) ((UINTN) &(((TYPE *)0)->Field))
83#endif
84
Marc Jones9ef6e522016-09-20 20:16:20 -060085/*----------------------------------------------------------------------------------------
86 * D E F I N I T I O N S A N D M A C R O S
87 *----------------------------------------------------------------------------------------
88 */
89
90
91/*----------------------------------------------------------------------------------------
92 * T Y P E D E F S A N D S T R U C T U R E S
93 *----------------------------------------------------------------------------------------
94 */
95
96
97/*----------------------------------------------------------------------------------------
98 * P R O T O T Y P E S O F L O C A L F U N C T I O N S
99 *----------------------------------------------------------------------------------------
100 */
101
102
103
104UINT32
105PspLibPciReadConfig (
106 IN UINT32 Register
107 )
108{
109 UINT32 Value;
110 PCI_ADDR PciAddr;
111
112 Value = 0;
113 PciAddr.AddressValue = MAKE_SBDFO (0, GET_PCI_BUS (Register), GET_PCI_DEV (Register), GET_PCI_FUNC (Register), GET_PCI_OFFSET (Register));
114
115 LibAmdPciRead (AccessWidth32, PciAddr, &Value, NULL);
116
117 return Value;
118}
119
120VOID
121PspLibPciWriteConfig (
122 IN UINT32 Register,
123 IN UINT32 Value
124 )
125{
126 PCI_ADDR PciAddr;
127 PciAddr.AddressValue = MAKE_SBDFO (0, GET_PCI_BUS (Register), GET_PCI_DEV (Register), GET_PCI_FUNC (Register), GET_PCI_OFFSET (Register));
128
129 LibAmdPciWrite (AccessWidth32, PciAddr, &Value, NULL);
130
131}
132
133UINT32
134PspLibPciReadPspConfig (
135 IN UINT16 Offset
136 )
137{
138 return (PspLibPciReadConfig ((UINT32) (PSP_PCI_BDA + Offset)));
139}
140
141VOID
142PspLibPciWritePspConfig (
143 IN UINT16 Offset,
144 IN UINT32 Value
145 )
146{
147 PspLibPciWriteConfig ((UINT32) (PSP_PCI_BDA + Offset), Value);
148}
149
Marshall Dawsona0400652016-10-15 09:20:43 -0600150/// Structure for Program ID
151typedef enum {
152 CZ_PROGRAM = 0x00, ///< Program ID for CZ
153 BR_PROGRAM = 0x01, ///< Program ID for BR
154 ST_PROGRAM = 0x02, ///< Program ID for ST
155 UNSUPPORTED_PROGRAM = 0xFF, ///< Program ID for unsupported
156} PROGRAM_ID;
157
Marshall Dawsonf3093882016-10-15 09:45:44 -0600158static PROGRAM_ID
Marshall Dawsona0400652016-10-15 09:20:43 -0600159PspGetProgarmId (
160 VOID
161 )
162{
163 CPUID_DATA Cpuid;
164
165 LibAmdCpuidRead (0x00000001, &Cpuid, NULL);
166 //Stoney CPUID 0x00670F00 or 0x00670F01
167 if ((Cpuid.EAX_Reg >> 16) == 0x67) {
168 return ST_PROGRAM;
169 } else if ((Cpuid.EAX_Reg >> 16) == 0x66) {
170 if ((Cpuid.EAX_Reg & 0xF0) == 0x50) {
171 //Bristol CPUID 0x00660F51
172 return BR_PROGRAM;
173 } else if ((Cpuid.EAX_Reg & 0xF0) == 0x00) {
174 //Carrizo CPUID 0x00660F00 or 0x00660F01
175 return CZ_PROGRAM;
176 }
177 }
178 return UNSUPPORTED_PROGRAM;
179}
180
Marc Jones9ef6e522016-09-20 20:16:20 -0600181BOOLEAN
182GetPspDirBase (
183 IN OUT UINT32 *Address
184 )
185{
186 UINTN i;
187 FIRMWARE_ENTRY_TABLE *FirmwareTableBase;
Marshall Dawsona0400652016-10-15 09:20:43 -0600188 PROGRAM_ID ProgramId;
Marc Jones9ef6e522016-09-20 20:16:20 -0600189 CONST UINT32 RomSigAddrTable[] =
190 {
191 0xFFFA0000, // --> 512KB base
192 0xFFF20000, // --> 1MB base
193 0xFFE20000, // --> 2MB base
194 0xFFC20000, // --> 4MB base
195 0xFF820000, // --> 8MB base
196 0xFF020000 // --> 16MB base
197 };
198
Marshall Dawsona0400652016-10-15 09:20:43 -0600199 ProgramId = PspGetProgarmId ();
200
Marc Jones9ef6e522016-09-20 20:16:20 -0600201 for (i = 0; i < sizeof (RomSigAddrTable) / sizeof (UINT32); i++) {
202 FirmwareTableBase = (FIRMWARE_ENTRY_TABLE *) (UINTN) RomSigAddrTable[i];
203 // Search flash for unique signature 0x55AA55AA
204 if (FirmwareTableBase->Signature == FIRMWARE_TABLE_SIGNATURE) {
Marshall Dawsona0400652016-10-15 09:20:43 -0600205 switch (ProgramId) {
206 case BR_PROGRAM:
207 case CZ_PROGRAM:
208 *Address = FirmwareTableBase->PspDirBase;
209 break;
210 case ST_PROGRAM:
211 *Address = FirmwareTableBase->NewPspDirBase;
212 break;
213 default:
214 *Address = FirmwareTableBase->PspDirBase;
215 break;
216 }
Marc Jones9ef6e522016-09-20 20:16:20 -0600217 return TRUE;
218 }
219 }
Marc Jones9ef6e522016-09-20 20:16:20 -0600220 return (FALSE);
221}
222
Marshall Dawsona0400652016-10-15 09:20:43 -0600223/**
224 * Get specific PSP Entry information, this routine will auto detect the processor for loading
225 * correct PSP Directory
226 *
227 *
228 *
229 * @param[in] EntryType PSP DIR Entry Type
230 * @param[in,out] EntryAddress Address of the specific PSP Entry
231 * @param[in,out] EntrySize Size of the specific PSP Entry
232 */
233
Marc Jones9ef6e522016-09-20 20:16:20 -0600234BOOLEAN
235PSPEntryInfo (
236 IN PSP_DIRECTORY_ENTRY_TYPE EntryType,
237 IN OUT UINT64 *EntryAddress,
Marshall Dawsona0400652016-10-15 09:20:43 -0600238 IN OUT UINT32 *EntrySize
Marc Jones9ef6e522016-09-20 20:16:20 -0600239 )
240{
241 PSP_DIRECTORY *PspDir;
242 UINTN i;
Marshall Dawsona0400652016-10-15 09:20:43 -0600243 PROGRAM_ID ProgramId;
Marc Jones9ef6e522016-09-20 20:16:20 -0600244
Marshall Dawsona0400652016-10-15 09:20:43 -0600245 PspDir = NULL;
Marc Jones9ef6e522016-09-20 20:16:20 -0600246 if (GetPspDirBase ((UINT32 *)&PspDir ) != TRUE) {
247 return FALSE;
248 }
249
Marshall Dawsona0400652016-10-15 09:20:43 -0600250 ProgramId = PspGetProgarmId ();
251 //Append BR Program ID
252 if ((ProgramId == BR_PROGRAM) &&
253 ((EntryType == SMU_OFFCHIP_FW) ||
254 (EntryType == SMU_OFF_CHIP_FW_2) ||
255 (EntryType == AMD_SCS_BINARY))) {
256 EntryType |= (PSP_ENTRY_BR_PROGRAM_ID << 8);
257 }
258
Marc Jones9ef6e522016-09-20 20:16:20 -0600259 for (i = 0; i < PspDir->Header.TotalEntries; i++) {
260 if (PspDir->PspEntry[i].Type == EntryType) {
261 *EntryAddress = PspDir->PspEntry[i].Location;
262 *EntrySize = PspDir->PspEntry[i].Size;
263 return (TRUE);
264 }
265 }
266
267 return (FALSE);
268}
269
Marshall Dawsona0400652016-10-15 09:20:43 -0600270BOOLEAN
271PspSoftWareFuseInfo (
272 IN OUT UINTN *FuseSpiAddress,
273 IN OUT UINT64 *FuseValue
274 )
275{
276 PSP_DIRECTORY *PspDir;
277 UINTN i;
278
279 PspDir = NULL;
280 if (GetPspDirBase ((UINT32 *)&PspDir ) != TRUE) {
281 return FALSE;
282 }
283
284 for (i = 0; i < PspDir->Header.TotalEntries; i++) {
285 if (PspDir->PspEntry[i].Type == AMD_SOFT_FUSE_CHAIN_01) {
286 *FuseSpiAddress = (UINT32) (UINTN) &PspDir->PspEntry[i].Location;
287 *FuseValue = PspDir->PspEntry[i].Location;
288 return (TRUE);
289 }
290 }
291 return (FALSE);
292}
293
Marshall Dawsonf3093882016-10-15 09:45:44 -0600294static UINT32 Fletcher32 (
Marshall Dawsona0400652016-10-15 09:20:43 -0600295 IN OUT UINT16 *data,
296 IN UINTN words
297 )
298{
299 UINT32 sum1;
300 UINT32 sum2;
301 UINTN tlen;
302
303 sum1 = 0xffff;
304 sum2 = 0xffff;
305
306 while (words) {
307 tlen = words >= 359 ? 359 : words;
308 words -= tlen;
309 do {
310 sum2 += sum1 += *data++;
311 } while (--tlen);
312 sum1 = (sum1 & 0xffff) + (sum1 >> 16);
313 sum2 = (sum2 & 0xffff) + (sum2 >> 16);
314 }
315 // Second reduction step to reduce sums to 16 bits
316 sum1 = (sum1 & 0xffff) + (sum1 >> 16);
317 sum2 = (sum2 & 0xffff) + (sum2 >> 16);
318 return sum2 << 16 | sum1;
319}
320
321VOID
322UpdataPspDirCheckSum (
323 IN OUT PSP_DIRECTORY *PspDir
324 )
325{
326 PspDir->Header.Checksum = Fletcher32 ((UINT16 *) &PspDir->Header.TotalEntries, \
327 (sizeof (PSP_DIRECTORY_HEADER) - OFFSET_OF (PSP_DIRECTORY_HEADER, TotalEntries) + PspDir->Header.TotalEntries * sizeof (PSP_DIRECTORY_ENTRY)) / 2);
328}
329
Marc Jones9ef6e522016-09-20 20:16:20 -0600330/**
331 Check if PSP device is present
332
333 @retval BOOLEAN 0: PSP Disabled, 1: PSP Enabled
334
335**/
336BOOLEAN
337CheckPspDevicePresent (
338 VOID
339 )
340{
341 UINT32 SecureFuseReg;
342 PspLibPciWriteConfig ( (UINT32)PCI_CONFIG_SMU_INDIRECT_INDEX, (UINT32)SMU_CC_PSP_FUSES_STATUS);
343 SecureFuseReg = PspLibPciReadConfig ( (UINT32)PCI_CONFIG_SMU_INDIRECT_DATA);
344
345 if (SecureFuseReg &= SMU_CC_PSP_FUSES_PROTO) {
346 return (TRUE);
347 }
348 return (FALSE);
349}
350
351/**
352 Check PSP Platform Seucre Enable State
353 HVB & Secure S3 (Resume vector set to Dram, & core content will restore by uCode)
354 will be applied if Psp Plaform Secure is enabled
355
356 @retval BOOLEAN 0: PSP Platform Secure Disabled, 1: PSP Platform Secure Enabled
357
358**/
359BOOLEAN
360CheckPspPlatformSecureEnable (
361 VOID
362 )
363{
364 UINT32 SecureFuseReg;
365 PspLibPciWriteConfig ( (UINT32)PCI_CONFIG_SMU_INDIRECT_INDEX, (UINT32)SMU_CC_PSP_FUSES_STATUS);
366 SecureFuseReg = PspLibPciReadConfig ( (UINT32)PCI_CONFIG_SMU_INDIRECT_DATA);
367
368 if (SecureFuseReg &= PLATFORM_SECURE_BOOT_EN) {
369 return (TRUE);
370 }
371 return (FALSE);
372}
373
374/**
375 Check PSP Recovery Flag
376 Target will set Recovery flag if some PSP entry point by PSP directory has been corrupted.
377
378 @retval BOOLEAN 0: Recovery Flag is cleared, 1: Recovery Flag has been set
379
380**/
381BOOLEAN
382CheckPspRecoveryFlag (
383 VOID
384 )
385{
386 MBOX_STATUS *MboxStatus;
387
388 //Init PSP MMIO
389 PspBarInitEarly ();
390
391 GetPspMboxStatus (&MboxStatus);
392
393 return (BOOLEAN) (MboxStatus->Recovery);
394}
395
396/**
397 Return the PspMbox MMIO location
398
399
400 @retval BOOLEAN FALSE: ERROR, TRUE: SUCCEED
401
402**/
403BOOLEAN
404GetPspMboxStatus (
405 IN OUT MBOX_STATUS **MboxStatus
406 )
407{
408 UINT32 PspMmio;
409
Marshall Dawsona0400652016-10-15 09:20:43 -0600410 if (GetPspBar3Addr (&PspMmio) == FALSE) {
Marc Jones9ef6e522016-09-20 20:16:20 -0600411 return (FALSE);
412 }
413
414 *MboxStatus = (MBOX_STATUS *)( (UINTN)PspMmio + PSP_MAILBOX_BASE + PSP_MAILBOX_STATUS_OFFSET); // PSPMbox base is at offset CP2MSG_28 ie. offset 28*4 = 0x70
415
416 return (TRUE);
417}
418
419BOOLEAN
Marshall Dawsona0400652016-10-15 09:20:43 -0600420PspBarInitEarly ()
Marc Jones9ef6e522016-09-20 20:16:20 -0600421{
422 UINT32 PspMmioSize;
423 UINT32 Value32;
424
425 if (PspLibPciReadPspConfig (PSP_PCI_DEVID_REG) == 0xffffffff) {
426 return (FALSE);
427 }
428
429 //Check if PSP BAR has been assigned, if not do the PSP BAR initialation
Marshall Dawsona0400652016-10-15 09:20:43 -0600430 if (PspLibPciReadPspConfig (PSP_PCI_BAR3_REG) == 0) {
Marc Jones9ef6e522016-09-20 20:16:20 -0600431 /// Get PSP BAR1 Size
Marshall Dawsona0400652016-10-15 09:20:43 -0600432 PspLibPciWritePspConfig (PSP_PCI_BAR3_REG, 0xFFFFFFFF);
433 PspMmioSize = PspLibPciReadPspConfig (PSP_PCI_BAR3_REG);
Marc Jones9ef6e522016-09-20 20:16:20 -0600434 PspMmioSize = ~PspMmioSize + 1;
Marshall Dawsona0400652016-10-15 09:20:43 -0600435 /// Assign BAR3 Temporary Address
436 PspLibPciWritePspConfig (PSP_PCI_BAR3_REG, PSP_BAR_TMP_BASE);
Marc Jones9ef6e522016-09-20 20:16:20 -0600437 PspLibPciWritePspConfig ( PSP_PCI_CMD_REG, 0x06);
438
439 /// Enable GNB redirection to this space @todo use equate & also find proper fix
Marshall Dawsona0400652016-10-15 09:20:43 -0600440 PspLibPciWriteConfig ( ( (0x18 << 11) + (1 << 8) + 0xBC), ((PSP_BAR_TMP_BASE + PspMmioSize -1) >> 8) & ~0xFF);
441 PspLibPciWriteConfig ( ( (0x18 << 11) + (1 << 8) + 0xB8), (PSP_BAR_TMP_BASE >> 8) | 3);
Marc Jones9ef6e522016-09-20 20:16:20 -0600442 /// Enable MsixBarEn, Bar1En, Bar3En
443 PspLibPciWritePspConfig ( PSP_PCI_EXTRAPCIHDR_REG, 0x34);
444 /// Capability chain update
445 Value32 = PspLibPciReadPspConfig (PSP_PCI_MIRRORCTRL1_REG);
446 Value32 &= ~D8F0x44_PmNxtPtrW_MASK;
447 Value32 |= 0xA4;
448 PspLibPciWritePspConfig (PSP_PCI_MIRRORCTRL1_REG, Value32);
449 }
450
451 return (TRUE);
452}
453
454/**
455 Return the PspMMIO MMIO location
456
457 @param[in] PspMmio Pointer to Psp MMIO address
458
459 @retval BOOLEAN 0: Error, 1 Success
460**/
461BOOLEAN
462GetPspBar1Addr (
463 IN OUT UINT32 *PspMmio
464 )
465{
466 if (CheckPspDevicePresent () == FALSE) {
467 return (FALSE);
468 }
469
470 *PspMmio = PspLibPciReadPspConfig (PSP_PCI_BAR1_REG);
471
472 if ((*PspMmio) == 0xffffffff) {
473 return (FALSE);
474 }
475
476 return (TRUE);
477}
478
479/**
480 Return the PspMMIO MMIO location
481
482 @param[in] PspMmio Pointer to Psp MMIO address
483
484 @retval BOOLEAN 0: Error, 1 Success
485**/
486BOOLEAN
487GetPspBar3Addr (
488 IN OUT UINT32 *PspMmio
489 )
490{
Marshall Dawsona0400652016-10-15 09:20:43 -0600491 UINT32 PciReg48;
492 UINT64 MsrPspAddr;
493
Marc Jones9ef6e522016-09-20 20:16:20 -0600494 if (CheckPspDevicePresent () == FALSE) {
495 return (FALSE);
496 }
497
Marshall Dawsona0400652016-10-15 09:20:43 -0600498 PciReg48 = PspLibPciReadPspConfig (PSP_PCI_EXTRAPCIHDR_REG);
499 if (PciReg48 & BIT12) {
500 // D8F0x48[12] Bar3Hide
501 LibAmdMsrRead (PSP_MSR_PRIVATE_BLOCK_BAR, &MsrPspAddr, NULL);
502 *PspMmio = (UINT32)MsrPspAddr;
503 } else {
504 *PspMmio = PspLibPciReadPspConfig (PSP_PCI_BAR3_REG) & 0xFFF00000;
505 }
Marc Jones9ef6e522016-09-20 20:16:20 -0600506
507 if ((*PspMmio) == 0xffffffff) {
508 return (FALSE);
509 }
510
511 return (TRUE);
512}
Marshall Dawsona0400652016-10-15 09:20:43 -0600513/**
514 * Acquire the Mutex for access PSP,X86 co-accessed register
515 * Call this routine before access SMIx98 & SMIxA8
516 *
517 */
518VOID
519AcquirePspSmiRegMutex (
520 VOID
521 )
522{
523 UINT32 PspBarAddr;
524 UINT32 MutexReg0;
525 UINT32 MutexReg1;
526
527 PspBarAddr = 0;
528 if (GetPspBar3Addr (&PspBarAddr)) {
529 MutexReg0 = PspBarAddr + PSP_MUTEX_REG0_OFFSET;
530 MutexReg1 = PspBarAddr + PSP_MUTEX_REG1_OFFSET;
531 *(volatile UINT32*)(UINTN)(MutexReg0) |= BIT0;
532 *(volatile UINT32*)(UINTN)(MutexReg1) |= BIT0;
533 //Wait till PSP FW release the mutex
534 while ((*(volatile UINT32*)(UINTN)(MutexReg0)& BIT1) && (*(volatile UINT32*)(UINTN)(MutexReg1) & BIT0)) {
535 ;
536 }
537 }
538}
539/**
540 * Release the Mutex for access PSP,X86 co-accessed register
541 * Call this routine after access SMIx98 & SMIxA8
542 *
543 */
544VOID
545ReleasePspSmiRegMutex (
546 VOID
547 )
548{
549 UINT32 PspBarAddr;
550 UINT32 MutexReg0;
551
552 PspBarAddr = 0;
553 if (GetPspBar3Addr (&PspBarAddr)) {
554 MutexReg0 = PspBarAddr + PSP_MUTEX_REG0_OFFSET;
555 *(volatile UINT32*)(UINTN)(MutexReg0) &= ~BIT0;
556 }
557}
Marc Jones9ef6e522016-09-20 20:16:20 -0600558
559/*---------------------------------------------------------------------------------------*/
560/**
561 * Returns the access width mask for the processor
562 *
563 *
564 * @param[in] AccessWidth Access width
565 * @retval Width in number of bytes
566 */
567
568
569UINT8
Marshall Dawsonf3093882016-10-15 09:45:44 -0600570static PspLibAccessWidth (
Marc Jones9ef6e522016-09-20 20:16:20 -0600571 IN ACCESS_WIDTH AccessWidth
572 )
573{
574 UINT8 Width;
575
576 switch (AccessWidth) {
577 case AccessWidth8:
578 case AccessS3SaveWidth8:
579 Width = 1;
580 break;
581 case AccessWidth16:
582 case AccessS3SaveWidth16:
583 Width = 2;
584 break;
585 case AccessWidth32:
586 case AccessS3SaveWidth32:
587 Width = 4;
588 break;
589 case AccessWidth64:
590 case AccessS3SaveWidth64:
591 Width = 8;
592 break;
593 default:
594 Width = 0;
595 }
596 return Width;
597}
598
599/*----------------------------------------------------------------------------------------*/
600/**
601 * Read GNB indirect registers
602 *
603 *
604 *
605 * @param[in] Address PCI address of indirect register
606 * @param[in] IndirectAddress Offset of indirect register
607 * @param[in] Width Width
608 * @param[out] Value Pointer to value
609 */
610VOID
611PspLibPciIndirectRead (
612 IN PCI_ADDR Address,
613 IN UINT32 IndirectAddress,
614 IN ACCESS_WIDTH Width,
615 OUT VOID *Value
616 )
617{
618 UINT32 IndexOffset;
619
620 IndexOffset = PspLibAccessWidth (Width);
621 LibAmdPciWrite (Width, Address, &IndirectAddress, NULL);
622 Address.AddressValue += IndexOffset;
623 LibAmdPciRead (Width, Address, Value, NULL);
624}
625
626/*----------------------------------------------------------------------------------------*/
627/**
628 * Write GNB indirect registers
629 *
630 *
631 *
632 * @param[in] Address PCI address of indirect register
633 * @param[in] IndirectAddress Offset of indirect register
634 * @param[in] Width Width
635 * @param[in] Value Pointer to value
636 */
637VOID
638PspLibPciIndirectWrite (
639 IN PCI_ADDR Address,
640 IN UINT32 IndirectAddress,
641 IN ACCESS_WIDTH Width,
642 IN VOID *Value
643 )
644{
645 UINT32 IndexOffset;
646
647 IndexOffset = PspLibAccessWidth (Width);
648 LibAmdPciWrite (Width, Address, &IndirectAddress, NULL);
649 Address.AddressValue += IndexOffset;
650 LibAmdPciWrite (Width, Address, Value, NULL);
651}
652
Marshall Dawsona0400652016-10-15 09:20:43 -0600653BOOLEAN
654IsS3Resume (
655 )
656{
657 UINT16 AcpiPm1CntBlk;
658 UINT16 SleepType;
659 UINT8 PmioAddr;
660
661 AcpiPm1CntBlk = 0;
662 //Get AcpiPm1CntBlk address
663 //PMIO register can only allow 8bits access
664 PmioAddr = PMIO_REG62;
665 LibAmdIoWrite (AccessWidth8, PMIO_INDEX_PORT, &PmioAddr, NULL);
666 LibAmdIoRead (AccessWidth8, PMIO_DATA_PORT, &AcpiPm1CntBlk, NULL);
667
668 PmioAddr++;
669 LibAmdIoWrite (AccessWidth8, PMIO_INDEX_PORT, &PmioAddr, NULL);
670 LibAmdIoRead (AccessWidth8, PMIO_DATA_PORT, ((UINT8 *) &AcpiPm1CntBlk) + 1, NULL);
671
672 //Get Sleep type
673 LibAmdIoRead (AccessWidth16, AcpiPm1CntBlk, &SleepType, NULL);
674 SleepType = SleepType & 0x1C00;
675 SleepType = ((SleepType >> 10) & 7);
676
677 return ((SleepType == 3) ? TRUE : FALSE);
678}
Marc Jones9ef6e522016-09-20 20:16:20 -0600679