From 9292d89be84d6abf9257ddb872887d4f53b2a00e Mon Sep 17 00:00:00 2001 From: Kerry Sheh Date: Tue, 31 Jan 2012 20:39:37 +0800 Subject: RD890 Northbridge: AMD RD890/SR56X0 Northbridge CIMX code Change-Id: If9908ffeb5b707a660db38dc44f5118347cbcc06 Signed-off-by: Kerry Sheh Signed-off-by: Kerry Sheh Reviewed-on: http://review.coreboot.org/557 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi --- src/vendorcode/amd/cimx/rd890/nbIommu.h | 326 ++++++++++++++++++++++++++++++++ 1 file changed, 326 insertions(+) create mode 100644 src/vendorcode/amd/cimx/rd890/nbIommu.h (limited to 'src/vendorcode/amd/cimx/rd890/nbIommu.h') diff --git a/src/vendorcode/amd/cimx/rd890/nbIommu.h b/src/vendorcode/amd/cimx/rd890/nbIommu.h new file mode 100644 index 0000000000..7fc2c5c908 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbIommu.h @@ -0,0 +1,326 @@ +/** + * @file + * + * Routines for IOMMU. + * + * Implement the IOMMU init and ACPI feature. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 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. + * + * + ***************************************************************************/ + +// Identifying an IOMMU: +// RD890S - IOMMU present +// all other (including RD890) - IOMMU not present +// Class = System Base Peripheral (08h) +// Subclass = IOMMU (06h) +// Programming Interface Code = 0h +// Must reside on top/root complex PCI hierarchy +// There is always a NB device at bus 0 device 0 function 0 (fcn 2 for IOMMU) - device ID 0x5A23 + +// Inputs: +// From OEM: Get exclusion table +// From OEM: Get text buffer + +// Outputs: +// To OEM: Complete IVRS table for linking + +#ifndef _NBIOMMU_H_ +#define _NBIOMMU_H_ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +AGESA_STATUS +NbIommuInit ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ); + +AGESA_STATUS +NbIommuInitS3 ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ); + +AGESA_STATUS +NbIommuAcpiInit ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ); + +AGESA_STATUS +NbIommuAcpiFixup ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ); + +VOID +NbIommuDisconnectPcieCore ( + IN CORE CoreId, + IN AMD_NB_CONFIG *pConfig + ); + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +// IOMMU Architectural +#define IVRS_BUFFER_SIZE 0x2000 // Default 8KB allocated to table +//#define IVHD_MIN_8BYTE_ALIGNMENT // Align IVHD entries on 8 byte boundary +#define IVHD_SIZE_ALIGNMENT // Align IVHD entries on MOD entry-size boundary +#define IVHD_HPET_SUPPORT // Create HPET entries +#define IVHD_APIC_SUPPORT // Create IOAPIC entries + +// IOMMU Northbridge +#define RD890S_CAP_MISC 0x50 // RD890/S Capabilities Misc Info +#define NB_PCI_DEV 0 // PCI NB device number +#define NB_HOST 0 // Function 0 = NB HOST +#define NB_IOMMU 2 // Function 2 = IOMMU +#define SB_DEV 0x14 // PCI SB device number +#define SB_SMBUS 3 // Function 3 = SMBUS +#define SB_SATA 0x11 // SB SATA +#define SATA_ENABLE_REG 0xAD // Dev. 0x14, Func 0, Reg 0xAD for SATA combined mode +#define SATA_COMBINED_MODE BIT3 // Bit 3 of SB_ENABLE_REG., 1 = Combined mode + +#define IOMMU_CAP_HEADER_OFFSET 0x00 +#define IOMMU_BASE_LOW_OFFSET 0x04 +#define IOMMU_BASE_HIGH_OFFSET 0x08 +#define IOMMU_RANGE_OFFSET 0x0C +#define IOMMU_MISC_OFFSET 0x10 + +#define DEVICEID_NB ((0 << 8) + (NB_PCI_DEV << 3) + NB_HOST) +#define DEVICEID_IOMMU ((0 << 8) + (NB_PCI_DEV << 3) + NB_IOMMU) +#define DEVICEID_GPP1_0 ((0 << 8) + (0x2 << 3) + 0) +#define DEVICEID_GPP1_1 ((0 << 8) + (0x3 << 3) + 0) +#define DEVICEID_GPP2_0 ((0 << 8) + (0xB << 3) + 0) +#define DEVICEID_GPP2_1 ((0 << 8) + (0xC << 3) + 0) +#define DEVICEID_GPP3A_0 ((0 << 8) + (0x4 << 3) + 0) +#define DEVICEID_GPP3A_1 ((0 << 8) + (0x5 << 3) + 0) +#define DEVICEID_GPP3A_2 ((0 << 8) + (0x6 << 3) + 0) +#define DEVICEID_GPP3A_3 ((0 << 8) + (0x7 << 3) + 0) +#define DEVICEID_GPP3A_4 ((0 << 8) + (0x9 << 3) + 0) +#define DEVICEID_GPP3A_5 ((0 << 8) + (0xA << 3) + 0) +#define DEVICEID_GPP3B_0 ((0 << 8) + (0xD << 3) + 0) + +#define DEVICEID_SATA ((0 << 8) + (0x11 << 3) + 0) +#define DEVICEID_IDE ((0 << 8) + (0x14 << 3) + 1) + +#define L1CFG_INDEX 0xF8 +// There is an L1 for each device (6), which is selected by [19:16] of L1CFG_INDEX +// e.g. (LibNbPciIndexRead (Address | L1CFGIND, L1_REG_0C | L1_CFG_SEL, AccessWidth32, &Value, pConfig) +#define L1CFG_SEL_WR_EN 0x80000000 +#define L1CFG_SEL_GPP1 0x00000000 +#define L1CFG_SEL_GPP2 0x00010000 +#define L1CFG_SEL_SB 0x00020000 +#define L1CFG_SEL_GPP3A 0x00030000 +#define L1CFG_SEL_GPP3B 0x00040000 +#define L1CFG_SEL_VC1 0x00050000 +#define L1REG_06 0x6 +#define L1REG_0C 0xC +#define L1REG_0D 0xD +#define L1REG_07 0x7 +#define L1CFG_DATA 0xFC + +#define L2CFG_INDEX 0xF0 +// e.g. (LibNbPciIndexRead (Address | L2CFGIND, L2_REG_0C, AccessWidth16, &Value, pConfig) +#define L2CFG_SEL_WR_EN 0x100 +#define L2REG_06 0x6 +#define L2REG_07 0x7 +#define L2REG_0C 0xC +#define L2REG_10 0x10 +#define L2REG_11 0x11 +#define L2REG_14 0x14 +#define L2REG_15 0x15 +#define L2REG_18 0x18 +#define L2REG_19 0x19 +#define L2REG_1C 0x1C +#define L2REG_1D 0x1D +#define L2REG_46 0x46 +#define L2REG_47 0x47 +#define L2REG_50 0x50 +#define L2REG_51 0x51 +#define L2REG_52 0x52 +#define L2REG_56 0x56 +#define L2REG_30 0x30 +#define L2REG_80 0x80 +#define L2CFG_DATA 0xF4 + +// PCI/PCIe Architectural +#define PCIE_CAPID 0x10 +#define PCIE_PORTMASK 0xF0 // Device cap reg 2 +#define PCIE_PCIE2PCIX 0x70 // Device cap reg 2 +#define PCIE_PHANTOMMASK 0x18 // Device cap reg 4 +#define PCIX_CAPID 0x07 +#define IOMMU_CAPID 0x0F + +#define PCI_DVID 0x00 +#define PCI_INVALID 0xFFFFFFFF +#define PCI_CLASS 0x08 +#define PCI_HEADER 0x0C +#define PCI_MULTIFUNCTION 0x00800000 +#define PCI_BUS 0x18 +#define PCI_SUBMASK 0xFF0000 +#define PCI_SECMASK 0xFF00 +#define PCI_PRIMASK 0xFF +#define PCI_BRIDGE_CLASS 0x0604 + +// IVRS Table Access +#define TYPE_IVHD 0x10 +#define IVINFO_ATSMASK 0x00400000 // [22] = ATS +#define IVINFO_VAMASK 0x003F8000 // [21:15] = Virtual Address Size +#define IVINFO_PAMASK 0x00007F00 // [14:8] = Physical Address Size +#define FLAGS_COHERENT BIT5 +#define FLAGS_IOTLBSUP BIT4 +#define FLAGS_ISOC BIT3 +#define FLAGS_RESPASSPW BIT2 +#define FLAGS_PASSPW BIT1 + +#define TYPE_IVMD_ALL 0x20 +#define TYPE_IVMD_SELECT 0x21 +#define TYPE_IVMD_RANGE 0x22 + +#define DE_PAD4 1 +#define DE_BYTE0 0 +#define DE_BYTE1 1 +#define DE_BYTE2 2 +#define DE_BYTE3 3 +#define DE_SELECT 2 +#define DATA_NOINTS 0 +#define DATA_LINT_EINT_INIT BIT7 + BIT6 + BIT1 + BIT0 +#define DATA_ALLINTS 0xD7 +#define DE_START 3 +#define DE_END 4 +#define DE_PAD8 64 +#define DE_BYTE4 4 +#define DE_BYTE5 5 +#define DE_BYTE6 6 +#define DE_BYTE7 7 +#define DE_ALIASSELECT 66 +#define DE_ALIASSTART 67 +#define DE_SPECIAL 72 +#define VARIETY_IOAPIC 0x1 +#define VARIETY_HPET 0x2 +#define DE_SPECIAL_VARIETY 7 +#define DE_DEVICEID 5 +#define DE_SPECIAL_ID 4 + +// MADT Table Access +#define MADT_APIC_TYPE 0x1 +#define MADT_APIC_ID 0x2 +#define MADT_APIC_BASE 0x4 + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + + +#pragma pack (push, 1) + +/// IVRS header +typedef struct { + UINT32 Signature; ///< see IOMMU specification for details + UINT32 Length; ///< see IOMMU specification for details + UINT8 Revision; ///< see IOMMU specification for details + UINT8 Checksum; ///< see IOMMU specification for details + CHAR8 OemId[6]; ///< see IOMMU specification for details + CHAR8 OemTableId[8]; ///< see IOMMU specification for details + CHAR8 OemRevision[4]; ///< see IOMMU specification for details + CHAR8 CreatorId[4]; ///< see IOMMU specification for details + CHAR8 CreatorRevision[4]; ///< see IOMMU specification for details + UINT32 IvInfo; ///< see IOMMU specification for details + UINT64 Reserved; ///< see IOMMU specification for details +} IOMMU_IVRS_HEADER; + +/// DeviceID +typedef struct { + UINT16 TableLength; ///< length of table + UINT16 Device[]; ///< DeviceID +} IOMMU_DEVICELIST; + +/// PCI Topology Based Settings +typedef struct { +// BOOLEAN PhantomFunction; ///< phantom functions present + UINT8 MaxBus; ///< max bus accumulator + UINT8 MaxDevice; ///< max device accumulator + UINT16 MaxFunction; ///< max function accumulator +} IOMMU_PCI_TOPOLOGY; + +/// IVHD for each hardware definition (i.e. # of northbridges) +typedef struct { + UINT8 Type; ///< see IOMMU specification for details + UINT8 Flags; ///< see IOMMU specification for details + UINT16 Length; ///< see IOMMU specification for details + UINT16 DeviceId; ///< see IOMMU specification for details + UINT16 CapabilityOffset; ///< see IOMMU specification for details + UINT64 BaseAddress; ///< see IOMMU specification for details + UINT16 PciSegment; ///< see IOMMU specification for details + UINT16 IommuInfo; ///< see IOMMU specification for details + UINT32 Reserved; ///< see IOMMU specification for details + UINT32 DeviceEntry[]; ///< see IOMMU specification for details +} IOMMU_IVHD_ENTRY; + +/// IVMD for each memory range +typedef struct { + UINT8 Type; ///< see IOMMU specification for details + UINT8 Flags; ///< see IOMMU specification for details + UINT16 Length; ///< see IOMMU specification for details + UINT16 DeviceId; ///< see IOMMU specification for details + UINT16 AuxData; ///< see IOMMU specification for details + UINT64 Reserved; ///< see IOMMU specification for details + UINT64 BlockStartAddress; ///< see IOMMU specification for details + UINT64 BlockLength; ///< see IOMMU specification for details +} IOMMU_IVMD_ENTRY; + +//#define IVRS_HANDLE 'SRVI' +#define IVRS_HANDLE Int32FromChar ('S', 'R', 'V', 'I') + +#define L2_DTC_CONTROL 0x10 +#define L2_ITC_CONTROL 0x14 +#define L2_PTC_A_CONTROL 0x18 +#define L2_PTC_B_CONTROL 0x1C +#define L2_PDC_CONTROL 0x50 + +#define EXCLUDE_SB_DEVICE_FROM_L2_HASH + +/// L2 cache init +typedef struct { + UINT8 HashControl; ///