blob: 418c74cadafbe478652d162d2b947e8045797ff4 [file] [log] [blame]
/* $NoKeywords:$ */
/**
* @file
*
* ACPI S3 support definitions.
*
* @xrefitem bom "File Content Label" "Release Content"
* @e project: AGESA
* @e sub-project: CPU
* @e \$Revision: 34897 $ @e \$Date: 2010-07-14 10:07:10 +0800 (Wed, 14 Jul 2010) $
*
*/
/*
*****************************************************************************
*
* Copyright (c) 2011, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Advanced Micro Devices, Inc. nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ***************************************************************************
*
*/
#ifndef _S3_H_
#define _S3_H_
/*---------------------------------------------------------------------------------------
* M I X E D (Definitions And Macros / Typedefs, Structures, Enums)
*---------------------------------------------------------------------------------------
*/
/*---------------------------------------------------------------------------------------
* D E F I N I T I O N S A N D M A C R O S
*---------------------------------------------------------------------------------------
*/
/*---------------------------------------------------------------------------------------
* T Y P E D E F S, S T R U C T U R E S, E N U M S
*---------------------------------------------------------------------------------------
*/
/* Device related definitions */
/// Header at the beginning of a context save buffer.
typedef struct {
UINT16 Version; ///< Version of header
UINT16 NumDevices; ///< Number of devices in the list
UINT16 RelativeOrMaskOffset; ///< Size of device list + header
} DEVICE_BLOCK_HEADER;
/// S3 device types
typedef enum {
DEV_TYPE_PCI_PRE_ESR, ///< PCI device before exiting self-refresh
DEV_TYPE_PCI, ///< PCI device after exiting self-refresh
DEV_TYPE_CPCI_PRE_ESR, ///< 'conditional' PCI device before exiting self-refresh
DEV_TYPE_CPCI, ///< 'conditional' PCI device after exiting self-refresh
DEV_TYPE_MSR_PRE_ESR, ///< MSR device before exiting self-refresh
DEV_TYPE_MSR, ///< MSR device after exiting self-refresh
DEV_TYPE_CMSR_PRE_ESR, ///< 'conditional' MSR device before exiting self-refresh
DEV_TYPE_CMSR ///< 'conditional' MSR device after exiting self-refresh
} S3_DEVICE_TYPES;
/// S3 restoration call points
typedef enum {
INIT_RESUME, ///< AMD_INIT_RESUME
S3_LATE_RESTORE ///< AMD_S3LATE_RESTORE
} CALL_POINTS;
/// S3 device common header
typedef struct {
UINT32 RegisterListID; ///< Unique ID of this device
UINT8 Type; ///< Appropriate S3_DEVICE_TYPES type
} DEVICE_DESCRIPTOR;
/// S3 PCI device header
typedef struct {
UINT32 RegisterListID; ///< Unique ID of this device
UINT8 Type; ///< DEV_TYPE_PCI / DEV_TYPE_PCI_PRE_ESR
UINT8 Node; ///< Zero-based node number
} PCI_DEVICE_DESCRIPTOR;
/// S3 'conditional' PCI device header
typedef struct {
UINT32 RegisterListID; ///< Unique ID of this device
UINT8 Type; ///< DEV_TYPE_CPCI / DEV_TYPE_CPCI_PRE_ESR
UINT8 Node; ///< Zero-based node number
UINT8 Mask1; ///< Conditional mask 1
UINT8 Mask2; ///< Conditional mask 2
} CONDITIONAL_PCI_DEVICE_DESCRIPTOR;
/// S3 MSR device header
typedef struct {
UINT32 RegisterListID; ///< Unique ID of this device
UINT8 Type; ///< DEV_TYPE_MSR / DEV_TYPE_MSR_PRE_ESR
} MSR_DEVICE_DESCRIPTOR;
/// S3 'conditional' MSR device header
typedef struct {
UINT32 RegisterListID; ///< Unique ID of this device
UINT8 Type; ///< DEV_TYPE_CMSR / DEV_TYPE_CMSR_PRE_ESR
UINT8 Mask1; ///< Conditional mask 1
UINT8 Mask2; ///< Conditional mask 2
} CONDITIONAL_MSR_DEVICE_DESCRIPTOR;
/* Special case related definitions */
/**
* PCI special case save handler
*
* @param[in] AccessWidth 8, 16, or 32 bit wide access
* @param[in] Address full PCI address of the register to save
* @param[out] Value Value read from the register
* @param[in] ConfigPtr AMD standard header config parameter
*
*/
typedef VOID (*PF_S3_SPECIAL_PCI_SAVE) (
IN ACCESS_WIDTH AccessWidth,
IN PCI_ADDR Address,
OUT VOID *Value,
IN VOID *ConfigPtr
);
/**
* PCI special case restore handler
*
* @param[in] AccessWidth 8, 16, or 32 bit wide access
* @param[in] Address full PCI address of the register to save
* @param[in] Value Value to write to the register
* @param[in] ConfigPtr AMD standard header config parameter
*
*/
typedef VOID (*PF_S3_SPECIAL_PCI_RESTORE) (
IN ACCESS_WIDTH AccessWidth,
IN PCI_ADDR PciAddress,
IN VOID *Value,
IN VOID *StdHeader
);
/**
* MSR special case save handler
*
* @param[in] MsrAddress Address of model specific register to save
* @param[out] Value Value read from the register
* @param[in] ConfigPtr AMD standard header config parameter
*
*/
typedef VOID (*PF_S3_SPECIAL_MSR_SAVE) (
IN UINT32 MsrAddress,
OUT UINT64 *Value,
IN VOID *StdHeader
);
/**
* MSR special case restore handler
*
* @param[in] MsrAddress Address of model specific register to restore
* @param[in] Value Value to write to the register
* @param[in] ConfigPtr AMD standard header config parameter
*
*/
typedef VOID (*PF_S3_SPECIAL_MSR_RESTORE) (
IN UINT32 MsrAddress,
IN UINT64 *Value,
IN VOID *StdHeader
);
/// PCI special case save/restore structure.
typedef struct {
PF_S3_SPECIAL_PCI_SAVE Save; ///< Save routine
PF_S3_SPECIAL_PCI_RESTORE Restore; ///< Restore routine
} PCI_SPECIAL_CASE;
/// MSR special case save/restore structure.
typedef struct {
PF_S3_SPECIAL_MSR_SAVE Save; ///< Save routine
PF_S3_SPECIAL_MSR_RESTORE Restore; ///< Restore routine
} MSR_SPECIAL_CASE;
/* Register related definitions */
/// S3 register type bit fields
typedef struct {
UINT8 SpecialCaseIndex:4; ///< Special Case array index
UINT8 RegisterSize:3; ///< For PCI, 1 = byte, 2 = word, else = dword.
///< For MSR, don't care
UINT8 SpecialCaseFlag:1; ///< Indicates special case
} S3_REGISTER_TYPE;
/// S3 PCI register descriptor.
typedef struct {
S3_REGISTER_TYPE Type; ///< Type[7] = special case flag,
///< Type[6:3] = register size in bytes,
///< Type[2:0] = special case index
UINT8 Function; ///< PCI function of the register
UINT16 Offset; ///< PCI offset of the register
UINT32 AndMask; ///< AND mask to be applied to the value before saving
} PCI_REG_DESCRIPTOR;
/// S3 'conditional' PCI register descriptor.
typedef struct {
S3_REGISTER_TYPE Type; ///< Type[7] = special case flag,
///< Type[6:3] = register size in bytes,
///< Type[2:0] = special case index
UINT8 Function; ///< PCI function of the register
UINT16 Offset; ///< PCI offset of the register
UINT32 AndMask; ///< AND mask to be applied to the value before saving
UINT8 Mask1; ///< conditional mask 1
UINT8 Mask2; ///< conditional mask 2
} CONDITIONAL_PCI_REG_DESCRIPTOR;
/// S3 MSR register descriptor.
typedef struct {
S3_REGISTER_TYPE Type; ///< Type[7] = special case flag,
///< Type[6:3] = reserved,
///< Type[2:0] = special case index
UINT32 Address; ///< MSR address
UINT64 AndMask; ///< AND mask to be applied to the value before saving
} MSR_REG_DESCRIPTOR;
/// S3 'conditional' MSR register descriptor.
typedef struct {
S3_REGISTER_TYPE Type; ///< Type[7] = special case flag,
///< Type[6:3] = reserved,
///< Type[2:0] = special case index
UINT32 Address; ///< MSR address
UINT64 AndMask; ///< AND mask to be applied to the value before saving
UINT8 Mask1; ///< conditional mask 1
UINT8 Mask2; ///< conditional mask 2
} CONDITIONAL_MSR_REG_DESCRIPTOR;
/// Common header at the beginning of an S3 register list.
typedef struct {
UINT16 Version; ///< Version of header
UINT16 NumRegisters; ///< Number of registers in the list
} REGISTER_BLOCK_HEADER;
/// S3 PCI register list header.
typedef struct {
UINT16 Version; ///< Version of header
UINT16 NumRegisters; ///< Number of registers in the list
PCI_REG_DESCRIPTOR *RegisterList; ///< Pointer to the first register descriptor
PCI_SPECIAL_CASE *SpecialCases; ///< Pointer to array of special case handlers
} PCI_REGISTER_BLOCK_HEADER;
/// S3 'conditional' PCI register list header.
typedef struct {
UINT16 Version; ///< Version of header
UINT16 NumRegisters; ///< Number of registers in the list
CONDITIONAL_PCI_REG_DESCRIPTOR *RegisterList; ///< Pointer to the first register descriptor
PCI_SPECIAL_CASE *SpecialCases; ///< Pointer to array of special case handlers
} CPCI_REGISTER_BLOCK_HEADER;
/// S3 MSR register list header.
typedef struct {
UINT16 Version; ///< Version of header
UINT16 NumRegisters; ///< Number of registers in the list
MSR_REG_DESCRIPTOR *RegisterList; ///< Pointer to the first register descriptor
MSR_SPECIAL_CASE *SpecialCases; ///< Pointer to array of special case handlers
} MSR_REGISTER_BLOCK_HEADER;
/// S3 'conditional' MSR register list header.
typedef struct {
UINT16 Version; ///< Version of header
UINT16 NumRegisters; ///< Number of registers in the list
CONDITIONAL_MSR_REG_DESCRIPTOR *RegisterList; ///< Pointer to the first register descriptor
MSR_SPECIAL_CASE *SpecialCases; ///< Pointer to array of special case handlers
} CMSR_REGISTER_BLOCK_HEADER;
/// S3 device descriptor pointers for ease of proper pointer advancement.
typedef union {
DEVICE_DESCRIPTOR *CommonDeviceHeader; ///< Common header
PCI_DEVICE_DESCRIPTOR *PciDevice; ///< PCI header
CONDITIONAL_PCI_DEVICE_DESCRIPTOR *CPciDevice; ///< 'conditional' PCI header
MSR_DEVICE_DESCRIPTOR *MsrDevice; ///< MSR header
CONDITIONAL_MSR_DEVICE_DESCRIPTOR *CMsrDevice; ///< 'conditional' MSR header
} DEVICE_DESCRIPTORS;
/// S3 register list header pointers for ease of proper pointer advancement.
typedef union {
DEVICE_DESCRIPTOR *CommonDeviceHeader; ///< Common header
PCI_REGISTER_BLOCK_HEADER *PciRegisters; ///< PCI header
CPCI_REGISTER_BLOCK_HEADER *CPciRegisters; ///< 'conditional' PCI header
MSR_REGISTER_BLOCK_HEADER *MsrRegisters; ///< MSR header
CMSR_REGISTER_BLOCK_HEADER *CMsrRegisters; ///< 'conditional' MSR header
} REGISTER_BLOCK_HEADERS;
/// S3 Volatile Storage Header
typedef struct {
UINT32 HeapOffset; ///< Offset to beginning of heap data
UINT32 HeapSize; ///< Size of the heap data
UINT32 RegisterDataOffset; ///< Offset to beginning of raw save data
UINT32 RegisterDataSize; ///< Size of raw save data
} S3_VOLATILE_STORAGE_HEADER;
/*---------------------------------------------------------------------------------------
* F U N C T I O N P R O T O T Y P E
*---------------------------------------------------------------------------------------
*/
UINT32
GetWorstCaseContextSize (
IN DEVICE_BLOCK_HEADER *DeviceList,
IN CALL_POINTS CallPoint,
IN AMD_CONFIG_PARAMS *StdHeader
);
VOID
SaveDeviceListContext (
IN DEVICE_BLOCK_HEADER *DeviceList,
IN VOID *Storage,
IN CALL_POINTS CallPoint,
OUT UINT32 *ActualBufferSize,
IN AMD_CONFIG_PARAMS *StdHeader
);
VOID
RestorePreESRContext (
OUT VOID **OrMaskPtr,
IN VOID *Storage,
IN CALL_POINTS CallPoint,
IN AMD_CONFIG_PARAMS *StdHeader
);
VOID
RestorePostESRContext (
IN VOID *OrMaskPtr,
IN VOID *Storage,
IN CALL_POINTS CallPoint,
IN AMD_CONFIG_PARAMS *StdHeader
);
VOID
AmdS3ParamsInitializer (
OUT AMD_S3_PARAMS *S3Params
);
VOID
GetNonMemoryRelatedDeviceList (
OUT DEVICE_BLOCK_HEADER **NonMemoryRelatedDeviceList,
IN AMD_CONFIG_PARAMS *StdHeader
);
AGESA_STATUS
S3GetPciDeviceRegisterList (
IN PCI_DEVICE_DESCRIPTOR *Device,
OUT PCI_REGISTER_BLOCK_HEADER **RegisterHdr,
IN AMD_CONFIG_PARAMS *StdHeader
);
AGESA_STATUS
S3GetCPciDeviceRegisterList (
IN CONDITIONAL_PCI_DEVICE_DESCRIPTOR *Device,
OUT CPCI_REGISTER_BLOCK_HEADER **RegisterHdr,
IN AMD_CONFIG_PARAMS *StdHeader
);
AGESA_STATUS
S3GetMsrDeviceRegisterList (
IN MSR_DEVICE_DESCRIPTOR *Device,
OUT MSR_REGISTER_BLOCK_HEADER **RegisterHdr,
IN AMD_CONFIG_PARAMS *StdHeader
);
AGESA_STATUS
S3GetCMsrDeviceRegisterList (
IN CONDITIONAL_MSR_DEVICE_DESCRIPTOR *Device,
OUT CMSR_REGISTER_BLOCK_HEADER **RegisterHdr,
IN AMD_CONFIG_PARAMS *StdHeader
);
#endif // _S3_H_