summaryrefslogtreecommitdiff
path: root/src/vendorcode/amd/cimx/rd890/nbIommu.h
blob: 7fc2c5c90897e4ee56ca10eaa504677a05ae3a35 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
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;                        ///<Control regsiter block address
} L2_HASH_CONTROL;

#pragma pack (pop)

#endif