summaryrefslogtreecommitdiffstats
path: root/include/hw/pci-host/q35.h
blob: 976fbae5996b12f22f7e2faad95d5d16c639da5d (plain) (blame)
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
/*
 * q35.h
 *
 * Copyright (c) 2009 Isaku Yamahata <yamahata at valinux co jp>
 *                    VA Linux Systems Japan K.K.
 * Copyright (C) 2012 Jason Baron <jbaron@redhat.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>
 */

#ifndef HW_Q35_H
#define HW_Q35_H

#include "hw/isa/isa.h"
#include "hw/sysbus.h"
#include "hw/i386/pc.h"
#include "hw/isa/apm.h"
#include "hw/pci/pci.h"
#include "hw/pci/pcie_host.h"
#include "hw/acpi/acpi.h"
#include "hw/acpi/ich9.h"
#include "hw/pci-host/pam.h"
#include "hw/i386/intel_iommu.h"
#include "qemu/units.h"

#define TYPE_Q35_HOST_DEVICE "q35-pcihost"
#define Q35_HOST_DEVICE(obj) \
     OBJECT_CHECK(Q35PCIHost, (obj), TYPE_Q35_HOST_DEVICE)

#define TYPE_MCH_PCI_DEVICE "mch"
#define MCH_PCI_DEVICE(obj) \
     OBJECT_CHECK(MCHPCIState, (obj), TYPE_MCH_PCI_DEVICE)

typedef struct MCHPCIState {
    /*< private >*/
    PCIDevice parent_obj;
    /*< public >*/

    MemoryRegion *ram_memory;
    MemoryRegion *pci_address_space;
    MemoryRegion *system_memory;
    MemoryRegion *address_space_io;
    PAMMemoryRegion pam_regions[13];
    MemoryRegion smram_region, open_high_smram;
    MemoryRegion smram, low_smram, high_smram;
    MemoryRegion tseg_blackhole, tseg_window;
    MemoryRegion smbase_blackhole, smbase_window;
    bool has_smram_at_smbase;
    Range pci_hole;
    uint64_t below_4g_mem_size;
    uint64_t above_4g_mem_size;
    uint64_t pci_hole64_size;
    uint32_t short_root_bus;
    uint16_t ext_tseg_mbytes;
} MCHPCIState;

typedef struct Q35PCIHost {
    /*< private >*/
    PCIExpressHost parent_obj;
    /*< public >*/

    bool pci_hole64_fix;
    MCHPCIState mch;
} Q35PCIHost;

#define Q35_MASK(bit, ms_bit, ls_bit) \
((uint##bit##_t)(((1ULL << ((ms_bit) + 1)) - 1) & ~((1ULL << ls_bit) - 1)))

/*
 * gmch part
 */

#define MCH_HOST_PROP_RAM_MEM "ram-mem"
#define MCH_HOST_PROP_PCI_MEM "pci-mem"
#define MCH_HOST_PROP_SYSTEM_MEM "system-mem"
#define MCH_HOST_PROP_IO_MEM "io-mem"

/* PCI configuration */
#define MCH_HOST_BRIDGE                        "MCH"

#define MCH_HOST_BRIDGE_CONFIG_ADDR            0xcf8
#define MCH_HOST_BRIDGE_CONFIG_DATA            0xcfc

/* D0:F0 configuration space */
#define MCH_HOST_BRIDGE_REVISION_DEFAULT       0x0

#define MCH_HOST_BRIDGE_EXT_TSEG_MBYTES        0x50
#define MCH_HOST_BRIDGE_EXT_TSEG_MBYTES_SIZE   2
#define MCH_HOST_BRIDGE_EXT_TSEG_MBYTES_QUERY  0xffff
#define MCH_HOST_BRIDGE_EXT_TSEG_MBYTES_MAX    0xfff

#define MCH_HOST_BRIDGE_SMBASE_SIZE            (128 * KiB)
#define MCH_HOST_BRIDGE_SMBASE_ADDR            0x30000
#define MCH_HOST_BRIDGE_F_SMBASE               0x9c
#define MCH_HOST_BRIDGE_F_SMBASE_QUERY         0xff
#define MCH_HOST_BRIDGE_F_SMBASE_IN_RAM        0x01
#define MCH_HOST_BRIDGE_F_SMBASE_LCK           0x02

#define MCH_HOST_BRIDGE_PCIEXBAR               0x60    /* 64bit register */
#define MCH_HOST_BRIDGE_PCIEXBAR_SIZE          8       /* 64bit register */
#define MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT       0xb0000000
#define MCH_HOST_BRIDGE_PCIEXBAR_MAX           (0x10000000) /* 256M */
#define MCH_HOST_BRIDGE_PCIEXBAR_ADMSK         Q35_MASK(64, 35, 28)
#define MCH_HOST_BRIDGE_PCIEXBAR_128ADMSK      ((uint64_t)(1 << 26))
#define MCH_HOST_BRIDGE_PCIEXBAR_64ADMSK       ((uint64_t)(1 << 25))
#define MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_MASK   ((uint64_t)(0x3 << 1))
#define MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_256M   ((uint64_t)(0x0 << 1))
#define MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_128M   ((uint64_t)(0x1 << 1))
#define MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_64M    ((uint64_t)(0x2 << 1))
#define MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_RVD    ((uint64_t)(0x3 << 1))
#define MCH_HOST_BRIDGE_PCIEXBAREN             ((uint64_t)1)

#define MCH_HOST_BRIDGE_PAM_NB                 7
#define MCH_HOST_BRIDGE_PAM_SIZE               7
#define MCH_HOST_BRIDGE_PAM0                   0x90
#define MCH_HOST_BRIDGE_PAM_BIOS_AREA          0xf0000
#define MCH_HOST_BRIDGE_PAM_AREA_SIZE          0x10000 /* 16KB */
#define MCH_HOST_BRIDGE_PAM1                   0x91
#define MCH_HOST_BRIDGE_PAM_EXPAN_AREA         0xc0000
#define MCH_HOST_BRIDGE_PAM_EXPAN_SIZE         0x04000
#define MCH_HOST_BRIDGE_PAM2                   0x92
#define MCH_HOST_BRIDGE_PAM3                   0x93
#define MCH_HOST_BRIDGE_PAM4                   0x94
#define MCH_HOST_BRIDGE_PAM_EXBIOS_AREA        0xe0000
#define MCH_HOST_BRIDGE_PAM_EXBIOS_SIZE        0x04000
#define MCH_HOST_BRIDGE_PAM5                   0x95
#define MCH_HOST_BRIDGE_PAM6                   0x96
#define MCH_HOST_BRIDGE_PAM_WE_HI              ((uint8_t)(0x2 << 4))
#define MCH_HOST_BRIDGE_PAM_RE_HI              ((uint8_t)(0x1 << 4))
#define MCH_HOST_BRIDGE_PAM_HI_MASK            ((uint8_t)(0x3 << 4))
#define MCH_HOST_BRIDGE_PAM_WE_LO              ((uint8_t)0x2)
#define MCH_HOST_BRIDGE_PAM_RE_LO              ((uint8_t)0x1)
#define MCH_HOST_BRIDGE_PAM_LO_MASK            ((uint8_t)0x3)
#define MCH_HOST_BRIDGE_PAM_WE                 ((uint8_t)0x2)
#define MCH_HOST_BRIDGE_PAM_RE                 ((uint8_t)0x1)
#define MCH_HOST_BRIDGE_PAM_MASK               ((uint8_t)0x3)

#define MCH_HOST_BRIDGE_SMRAM                  0x9d
#define MCH_HOST_BRIDGE_SMRAM_SIZE             2
#define MCH_HOST_BRIDGE_SMRAM_D_OPEN           ((uint8_t)(1 << 6))
#define MCH_HOST_BRIDGE_SMRAM_D_CLS            ((uint8_t)(1 << 5))
#define MCH_HOST_BRIDGE_SMRAM_D_LCK            ((uint8_t)(1 << 4))
#define MCH_HOST_BRIDGE_SMRAM_G_SMRAME         ((uint8_t)(1 << 3))
#define MCH_HOST_BRIDGE_SMRAM_C_BASE_SEG_MASK  ((uint8_t)0x7)
#define MCH_HOST_BRIDGE_SMRAM_C_BASE_SEG       ((uint8_t)0x2)  /* hardwired to b010 */
#define MCH_HOST_BRIDGE_SMRAM_C_BASE           0xa0000
#define MCH_HOST_BRIDGE_SMRAM_C_END            0xc0000
#define MCH_HOST_BRIDGE_SMRAM_C_SIZE           0x20000
#define MCH_HOST_BRIDGE_UPPER_SYSTEM_BIOS_END  0x100000
#define MCH_HOST_BRIDGE_SMRAM_DEFAULT           \
    MCH_HOST_BRIDGE_SMRAM_C_BASE_SEG
#define MCH_HOST_BRIDGE_SMRAM_WMASK             \
    (MCH_HOST_BRIDGE_SMRAM_D_OPEN |             \
     MCH_HOST_BRIDGE_SMRAM_D_CLS |              \
     MCH_HOST_BRIDGE_SMRAM_D_LCK |              \
     MCH_HOST_BRIDGE_SMRAM_G_SMRAME)
#define MCH_HOST_BRIDGE_SMRAM_WMASK_LCK         \
    MCH_HOST_BRIDGE_SMRAM_D_CLS

#define MCH_HOST_BRIDGE_ESMRAMC                0x9e
#define MCH_HOST_BRIDGE_ESMRAMC_H_SMRAME       ((uint8_t)(1 << 7))
#define MCH_HOST_BRIDGE_ESMRAMC_E_SMERR        ((uint8_t)(1 << 6))
#define MCH_HOST_BRIDGE_ESMRAMC_SM_CACHE       ((uint8_t)(1 << 5))
#define MCH_HOST_BRIDGE_ESMRAMC_SM_L1          ((uint8_t)(1 << 4))
#define MCH_HOST_BRIDGE_ESMRAMC_SM_L2          ((uint8_t)(1 << 3))
#define MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_MASK   ((uint8_t)(0x3 << 1))
#define MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_1MB    ((uint8_t)(0x0 << 1))
#define MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_2MB    ((uint8_t)(0x1 << 1))
#define MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_8MB    ((uint8_t)(0x2 << 1))
#define MCH_HOST_BRIDGE_ESMRAMC_T_EN           ((uint8_t)1)
#define MCH_HOST_BRIDGE_ESMRAMC_DEFAULT \
    (MCH_HOST_BRIDGE_ESMRAMC_SM_CACHE | \
     MCH_HOST_BRIDGE_ESMRAMC_SM_L1 |    \
     MCH_HOST_BRIDGE_ESMRAMC_SM_L2)
#define MCH_HOST_BRIDGE_ESMRAMC_WMASK               \
    (MCH_HOST_BRIDGE_ESMRAMC_H_SMRAME |             \
     MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_MASK |         \
     MCH_HOST_BRIDGE_ESMRAMC_T_EN)
#define MCH_HOST_BRIDGE_ESMRAMC_WMASK_LCK     0

/* D1:F0 PCIE* port*/
#define MCH_PCIE_DEV                           1
#define MCH_PCIE_FUNC                          0

uint64_t mch_mcfg_base(void);

/*
 * Arbitrary but unique BNF number for IOAPIC device.
 *
 * TODO: make sure there would have no conflict with real PCI bus
 */
#define Q35_PSEUDO_BUS_PLATFORM         (0xff)
#define Q35_PSEUDO_DEVFN_IOAPIC         (0x00)

#endif /* HW_Q35_H */