blob: 807a78eb27ae2499e0e8d42a02e867e2fd241a53 [file] [log] [blame]
zbao7d94cf92012-07-02 14:19:14 +08001/* $NoKeywords:$ */
2/**
3 * @file
4 *
5 * PCIe ALIB
6 *
7 *
8 *
9 * @xrefitem bom "File Content Label" "Release Content"
10 * @e project: AGESA
11 * @e sub-project: GNB
12 * @e \$Revision: 64895 $ @e \$Date: 2012-02-02 01:01:48 -0600 (Thu, 02 Feb 2012) $
13 *
14 */
15/*
16*****************************************************************************
17*
Siyuan Wang641f00c2013-06-08 11:50:55 +080018 * Copyright (c) 2008 - 2012, 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.
zbao7d94cf92012-07-02 14:19:14 +080042* ***************************************************************************
43*
44*/
45
46/*----------------------------------------------------------------------------------------
47 * M O D U L E S U S E D
48 *----------------------------------------------------------------------------------------
49 */
50
51
52#include "AGESA.h"
53#include "Ids.h"
54#include "amdlib.h"
55#include "heapManager.h"
56#include "cpuLateInit.h"
57#include "Gnb.h"
58#include "GnbPcie.h"
59#include "GnbIommu.h"
60#include "GnbFamServices.h"
61#include "GnbCommonLib.h"
62#include "GnbIommuIvrs.h"
63#include "GnbIvrsLib.h"
64#include "Filecode.h"
65#define FILECODE PROC_GNB_MODULES_GNBIVRSLIB_GNBIVRSLIB_FILECODE
66/*----------------------------------------------------------------------------------------
67 * D E F I N I T I O N S A N D M A C R O S
68 *----------------------------------------------------------------------------------------
69 */
70
71/*----------------------------------------------------------------------------------------
72 * T Y P E D E F S A N D S T R U C T U R E S
73 *----------------------------------------------------------------------------------------
74 */
75
76/*----------------------------------------------------------------------------------------
77 * 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
78 *----------------------------------------------------------------------------------------
79 */
80
81/*----------------------------------------------------------------------------------------*/
82/**
83 * Create IVHDR entry for device range
84 *
85 *
86 * @param[in] StartRange Address of start range
87 * @param[in] EndRange Address of end range
88 * @param[in] DataSetting Data setting
89 * @param[in] Ivhd Pointer to IVHD entry
90 * @param[in] StdHeader Standard configuration header
91 *
92 */
93VOID
94GnbIvhdAddDeviceRangeEntry (
95 IN PCI_ADDR StartRange,
96 IN PCI_ADDR EndRange,
97 IN UINT8 DataSetting,
98 IN IVRS_IVHD_ENTRY *Ivhd,
99 IN AMD_CONFIG_PARAMS *StdHeader
100 )
101{
102 IVHD_GENERIC_ENTRY *Entry;
103 Entry = (IVHD_GENERIC_ENTRY *) ((UINT8 *) Ivhd + Ivhd->Length);
104 Entry->Type = IvhdEntryStartRange;
105 Entry->DeviceId = DEVICE_ID (StartRange);
106 Entry->DataSetting = DataSetting;
107 Ivhd->Length += sizeof (IVHD_GENERIC_ENTRY);
108 Entry = (IVHD_GENERIC_ENTRY *) ((UINT8 *) Ivhd + Ivhd->Length);
109 Entry->Type = IvhdEntryEndRange;
110 Entry->DeviceId = DEVICE_ID (EndRange);
111 Ivhd->Length += sizeof (IVHD_GENERIC_ENTRY);
112}
113
114/*----------------------------------------------------------------------------------------*/
115/**
116 * Create IVHDR entry for aliased range
117 *
118 *
119 * @param[in] StartRange Address of start range
120 * @param[in] EndRange Address of end range
121 * @param[in] Alias Address of alias requestor ID for range
122 * @param[in] DataSetting Data setting
123 * @param[in] Ivhd Pointer to IVHD entry
124 * @param[in] StdHeader Standard configuration header
125 *
126 */
127VOID
128GnbIvhdAddDeviceAliasRangeEntry (
129 IN PCI_ADDR StartRange,
130 IN PCI_ADDR EndRange,
131 IN PCI_ADDR Alias,
132 IN UINT8 DataSetting,
133 IN IVRS_IVHD_ENTRY *Ivhd,
134 IN AMD_CONFIG_PARAMS *StdHeader
135 )
136{
137 IVHD_ALIAS_ENTRY *RangeEntry;
138 IVHD_GENERIC_ENTRY *Entry;
139 UINT16 Offset;
140 Offset = (Ivhd->Length + 0x7) & (~ 0x7);
141 RangeEntry = (IVHD_ALIAS_ENTRY *) ((UINT8 *) Ivhd + Offset);
142 RangeEntry->Type = IvhdEntryAliasStartRange;
143 RangeEntry->DeviceId = DEVICE_ID (StartRange);
144 RangeEntry->AliasDeviceId = DEVICE_ID (Alias);
145 RangeEntry->DataSetting = DataSetting;
146 Ivhd->Length = sizeof (IVHD_ALIAS_ENTRY) + Offset;
147 Entry = (IVHD_GENERIC_ENTRY *) ((UINT8 *) Ivhd + Ivhd->Length);
148 Entry->Type = IvhdEntryEndRange;
149 Entry->DeviceId = DEVICE_ID (EndRange);
150 Ivhd->Length += sizeof (IVHD_GENERIC_ENTRY);
151}
152
153/*----------------------------------------------------------------------------------------*/
154/**
155 * Create IVHDR entry for special device
156 *
157 *
158 * @param[in] SpecialDevice Special device Type
159 * @param[in] Device Address of requestor ID for special device
160 * @param[in] Id Apic ID/ Hpet ID
161 * @param[in] DataSetting Data setting
162 * @param[in] Ivhd Pointer to IVHD entry
163 * @param[in] StdHeader Standard configuration header
164 *
165 */
166VOID
167GnbIvhdAddSpecialDeviceEntry (
168 IN IVHD_SPECIAL_DEVICE SpecialDevice,
169 IN PCI_ADDR Device,
170 IN UINT8 Id,
171 IN UINT8 DataSetting,
172 IN IVRS_IVHD_ENTRY *Ivhd,
173 IN AMD_CONFIG_PARAMS *StdHeader
174 )
175{
176 IVHD_SPECIAL_ENTRY *SpecialEntry;
177 UINT16 Offset;
178 Offset = (Ivhd->Length + 0x7) & (~ 0x7);
179 SpecialEntry = (IVHD_SPECIAL_ENTRY *) ((UINT8 *) Ivhd + Offset);
180 SpecialEntry->Type = IvhdEntrySpecialDevice;
181 SpecialEntry->AliasDeviceId = DEVICE_ID (Device);
182 SpecialEntry->Variety = (UINT8) SpecialDevice;
183 SpecialEntry->Handle = Id;
184 SpecialEntry->DataSetting = DataSetting;
185 Ivhd->Length = sizeof (IVHD_SPECIAL_ENTRY) + Offset;
186}
187
188/*----------------------------------------------------------------------------------------*/
189/**
190 * Create IVMD entry
191 *
192 *
193 * @param[in] Type Root type for IVMD (IvrsIvmdBlock or IvrsIvmdrBlock)
194 * @param[in] StartDevice Device ID of start device range
195 * Use 0x0000 for ALL
196 * @param[in] EndDevice Device ID of end device range
197 * Use 0xFFFF for ALL
198 * Use == StartDevice for specific device
199 * @param[in] BlockAddress Address of memory block to be excluded
200 * @param[in] BlockLength Length of memory block go be excluded
201 * @param[in] Ivmd Pointer to IVMD entry
202 * @param[in] StdHeader Standard configuration header
203 *
204 */
205VOID
206GnbIvmdAddEntry (
207 IN IVRS_BLOCK_TYPE Type,
208 IN UINT16 StartDevice,
209 IN UINT16 EndDevice,
210 IN UINT64 BlockAddress,
211 IN UINT64 BlockLength,
212 IN IVRS_IVMD_ENTRY *Ivmd,
213 IN AMD_CONFIG_PARAMS *StdHeader
214 )
215{
216 Ivmd->Flags = IVMD_FLAG_EXCLUSION_RANGE;
217 Ivmd->Length = sizeof (IVRS_IVMD_ENTRY);
218 Ivmd->DeviceId = StartDevice;
219 Ivmd->AuxiliaryData = 0x0;
220 Ivmd->Reserved = 0x0000000000000000;
221 Ivmd->BlockStart = BlockAddress;
222 Ivmd->BlockLength = BlockLength;
223 if (Type == IvrsIvmdBlock) {
224 if (StartDevice == EndDevice) {
225 Ivmd->Type = IvrsIvmdBlockSingle;
226 } else if ((StartDevice == 0x0000) && (EndDevice == 0xFFFF)) {
227 Ivmd->Type = IvrsIvmdBlock;
228 } else {
229 Ivmd->Type = IvrsIvmdBlockRange;
230 Ivmd->AuxiliaryData = EndDevice;
231 }
232 } else {
233 if (StartDevice == EndDevice) {
234 Ivmd->Type = IvrsIvmdrBlockSingle;
235 } else {
236 Ivmd->Type = IvrsIvmdrBlock;
237 }
238 }
239}
240