1
v3 -> v4:
2
- based on 'cxl/cxl-host: Support creation of a new CXL Host Bridge'[1]
3
- Align base addresses of CXL relevant Windows
4
- Remove redundant header files
5
1
v2 -> v3:
6
v2 -> v3:
2
- create a new host bridge type: TYPE_SBSA_CXL_HOST
7
- create a new host bridge type: TYPE_SBSA_CXL_HOST
3
- CXL exclusive ECAM, PIO, MMIO32 & MMIO64 space in sbsa-ref
8
- CXL exclusive ECAM, PIO, MMIO32 & MMIO64 space in sbsa-ref
4
- combine all cxl infrastructure creating into one function
9
- combine all cxl infrastructure creating into one function
5
10
...
...
13
- Less experience and not particularly confident in sbsa-ref address space design
18
- Less experience and not particularly confident in sbsa-ref address space design
14
so this might be stupidly broken in a way I've not considered.
19
so this might be stupidly broken in a way I've not considered.
15
20
16
Background
21
Background
17
==========
22
==========
18
Currently the base CXL support for arm platforms is only on Jonathan's patches[1]
23
Currently the base CXL support for arm platforms is only on Jonathan's patches[2]
19
which have not yet merged into upstream. SBSA-REF can be more like a real machine,
24
which have not yet merged into upstream. SBSA-REF can be more like a real machine,
20
thus the support of cxl could be meaningful.
25
thus my initial purpose is to support the simplest cxl VH topology on sbsa-ref to
26
verify the basic cxl function usage, therefore, some real machine could refer the
27
cxl running result on sbsa-ref.
21
28
22
This series leverages Jonathan's patches[1] to design [SBSA_CXL_CHBCR] and
29
This series leverages Jonathan's patches to design [SBSA_CXL_CHBCR] and
23
[SBSA_CXL_FIXED_WINDOW] spaces for sbsa-ref layout.
30
[SBSA_CXL_FIXED_WINDOW] spaces for sbsa-ref layout.
24
31
25
Regard to the burden of edk2 firmware, I try to build a static CEDT table and add
32
Regard to the burden of edk2 firmware, I try to build a static CEDT table and add
26
acpi0016, acpi0017 and other cxl relevant contents into acpi tables[2][3]. Hence it
33
acpi0016, acpi0017 and other cxl relevant contents into acpi tables[3][4]. Hence it
27
doesn't need to communicate cxl contents via DT to edk2.
34
doesn't need to communicate cxl contents via DT to edk2.
28
35
29
CXL HOST design
36
CXL HOST design
30
===============
37
===============
31
In previous version, the pxb-cxl-host with any cxl root ports and cxl endpoint devices
38
In previous version, the pxb-cxl-host with any cxl root ports and cxl endpoint devices
32
would occupy the BDF number of the original pcie domain resulting in the max available
39
would occupy the BDF number of the original pcie domain resulting in the max available
33
pcie devices on sbsa-ref would decrease, which seems to bring a series of trouble.
40
pcie devices on sbsa-ref would decrease, which seems to bring a series of trouble. With
41
this patch[1], sbsa-ref could use the new cxl host bridge type (TYPE_CXL_HOST) to
42
avoid above problem.
34
43
35
In this version, to avoid that problems, the new host bridge type is defined
44
For [SBSA_CXL_CHBCR], this creates a default cxl host bridge (0001:00) with two cxl root
36
(TYPE_SBSA_CXL_HOST). Actually, this new device could be considered as a prototype of
45
ports on sbsa-ref, and the new memory layout places 64K space for one hard coded cxl host
37
an independent cxl host bridge which combines gpex features(mmio windows & irq) and
46
bridge register regions in the sbsa-ref memmap. It means for now only two cxl type3
38
pxb-cxl features(CHBCR) at meanwhile. If this could be work, we can just remove the
47
devices could be added on the cxl host, but personally it could satisfy my initial purpose
39
prefix of 'SBSA' and introduce it as a general qemu object on other boards.
48
mentioned above.
40
41
For [SBSA_CXL_CHBCR], since this creates a default cxl host bridge (0001:00)
42
with two cxl root ports on sbsa-ref, the new memory layout places 64K space for
43
one hard coded cxl host bridge register regions in the sbsa-ref memmap. (Meaning
44
for now only two cxl type3 devices could be added on the cxl host)
45
49
46
And the memory layout provides separate space windows for the cxl host bridge in the
50
And the memory layout provides separate space windows for the cxl host bridge in the
47
sbsa-ref memmap:
51
sbsa-ref memmap:
48
- 64K CXL Host Bridge Component Registers (CHBCR)
52
- 64K CXL Host Bridge Component Registers (CHBCR)
49
- 64K CXL_PIO
53
- 64K CXL_PIO
...
...
132
I am looking for suggestions on if there are better ways to do it.
136
I am looking for suggestions on if there are better ways to do it.
133
137
134
This series patches are here to hopefully some comments to guide me!
138
This series patches are here to hopefully some comments to guide me!
135
139
136
Link:
140
Link:
137
[1]: https://lore.kernel.org/linux-cxl/20220616141950.23374-1-Jonathan.Cameron@huawei.com/
141
[1]: https://lists.nongnu.org/archive/html/qemu-arm/2024-12/msg00350.html
138
[2]: https://edk2.groups.io/g/devel/topic/rfc_edk2_patch_v3_0_1/109403423#
142
[2]: https://lore.kernel.org/linux-cxl/20220616141950.23374-1-Jonathan.Cameron@huawei.com/
139
[3]: https://edk2.groups.io/g/devel/topic/rfc_patch_edk2_platforms_v3/109768222
143
[3]: https://edk2.groups.io/g/devel/message/120851
144
[4]: https://edk2.groups.io/g/devel/topic/rfc_patch_edk2_platforms_v4/110023229
140
145
141
Yuquan Wang (1):
146
Yuquan Wang (1):
142
hw/arm/sbsa-ref: Support CXL Host Bridge & CFMW
147
hw/arm/sbsa-ref: Support CXL Host Bridge & CFMW
143
148
144
docs/system/arm/sbsa.rst | 4 +
149
docs/system/arm/sbsa.rst | 4 ++
145
hw/arm/sbsa-ref.c | 139 ++++++++++++++++++++++++++++++-
150
hw/arm/sbsa-ref.c | 135 ++++++++++++++++++++++++++++++++++++++-
146
hw/cxl/cxl-host-stubs.c | 2 +
151
2 files changed, 138 insertions(+), 1 deletion(-)
147
hw/cxl/cxl-host.c | 169 +++++++++++++++++++++++++++++++++++++-
148
include/hw/cxl/cxl.h | 22 +++++
149
include/hw/cxl/cxl_host.h | 5 ++
150
6 files changed, 339 insertions(+), 2 deletions(-)
151
152
152
--
153
--
153
2.34.1
154
2.34.1
diff view generated by jsdifflib
...
...
13
13
14
- 1T CXL_FIXED_WINDOW
14
- 1T CXL_FIXED_WINDOW
15
15
16
Signed-off-by: Yuquan Wang <wangyuquan1236@phytium.com.cn>
16
Signed-off-by: Yuquan Wang <wangyuquan1236@phytium.com.cn>
17
---
17
---
18
docs/system/arm/sbsa.rst | 4 +
18
docs/system/arm/sbsa.rst | 4 ++
19
hw/arm/sbsa-ref.c | 139 ++++++++++++++++++++++++++++++-
19
hw/arm/sbsa-ref.c | 135 ++++++++++++++++++++++++++++++++++++++-
20
hw/cxl/cxl-host-stubs.c | 2 +
20
2 files changed, 138 insertions(+), 1 deletion(-)
21
hw/cxl/cxl-host.c | 169 +++++++++++++++++++++++++++++++++++++-
22
include/hw/cxl/cxl.h | 22 +++++
23
include/hw/cxl/cxl_host.h | 5 ++
24
6 files changed, 339 insertions(+), 2 deletions(-)
25
21
26
diff --git a/docs/system/arm/sbsa.rst b/docs/system/arm/sbsa.rst
22
diff --git a/docs/system/arm/sbsa.rst b/docs/system/arm/sbsa.rst
27
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
28
--- a/docs/system/arm/sbsa.rst
24
--- a/docs/system/arm/sbsa.rst
29
+++ b/docs/system/arm/sbsa.rst
25
+++ b/docs/system/arm/sbsa.rst
...
...
55
#include "hw/ide/ide-bus.h"
51
#include "hw/ide/ide-bus.h"
56
#include "hw/ide/ahci-sysbus.h"
52
#include "hw/ide/ahci-sysbus.h"
57
#include "hw/intc/arm_gicv3_common.h"
53
#include "hw/intc/arm_gicv3_common.h"
58
#include "hw/intc/arm_gicv3_its_common.h"
54
#include "hw/intc/arm_gicv3_its_common.h"
59
#include "hw/loader.h"
55
#include "hw/loader.h"
60
+#include "hw/pci/pci_bridge.h"
61
+#include "hw/pci/pci_bus.h"
62
+#include "hw/pci/pcie_port.h"
56
+#include "hw/pci/pcie_port.h"
63
#include "hw/pci-host/gpex.h"
57
#include "hw/pci-host/gpex.h"
64
+#include "hw/pci-bridge/pci_expander_bridge.h"
65
#include "hw/qdev-properties.h"
58
#include "hw/qdev-properties.h"
66
#include "hw/usb.h"
59
#include "hw/usb.h"
67
#include "hw/usb/xhci.h"
68
@@ -XXX,XX +XXX,XX @@ enum {
60
@@ -XXX,XX +XXX,XX @@ enum {
69
SBSA_SECURE_MEM,
61
SBSA_SECURE_MEM,
70
SBSA_AHCI,
62
SBSA_AHCI,
71
SBSA_XHCI,
63
SBSA_XHCI,
72
+ SBSA_CXL,
64
+ SBSA_CXL,
...
...
90
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry sbsa_ref_memmap[] = {
82
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry sbsa_ref_memmap[] = {
91
/* Space here reserved for more SMMUs */
83
/* Space here reserved for more SMMUs */
92
[SBSA_AHCI] = { 0x60100000, 0x00010000 },
84
[SBSA_AHCI] = { 0x60100000, 0x00010000 },
93
[SBSA_XHCI] = { 0x60110000, 0x00010000 },
85
[SBSA_XHCI] = { 0x60110000, 0x00010000 },
94
+ /* 64K CXL Host Bridge Registers space */
86
+ /* 64K CXL Host Bridge Registers space */
95
+ [SBSA_CXL_CHBCR] = { 0x60120000, 0x00010000 },
87
+ [SBSA_CXL_CHBCR] = { 0x60200000, 0x00010000 },
96
+ /* 64K CXL PIO space */
88
+ /* 64K CXL PIO space */
97
+ [SBSA_CXL_PIO] = { 0x60130000, 0x00010000 },
89
+ [SBSA_CXL_PIO] = { 0x60300000, 0x00010000 },
98
+ /* 128M CXL 32-bit MMIO space */
90
+ /* 128M CXL 32-bit MMIO space */
99
+ [SBSA_CXL_MMIO] = { 0x60140000, 0x08000000 },
91
+ [SBSA_CXL_MMIO] = { 0x60400000, 0x08000000 },
100
+ /* 256M CXL ECAM space */
92
+ /* 256M CXL ECAM space */
101
+ [SBSA_CXL_ECAM] = { 0x68140000, 0x10000000 },
93
+ [SBSA_CXL_ECAM] = { 0x68500000, 0x10000000 },
102
/* Space here reserved for other devices */
94
/* Space here reserved for other devices */
103
[SBSA_PCIE_PIO] = { 0x7fff0000, 0x00010000 },
95
[SBSA_PCIE_PIO] = { 0x7fff0000, 0x00010000 },
104
/* 32-bit address PCIE MMIO space */
96
/* 32-bit address PCIE MMIO space */
105
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry sbsa_ref_memmap[] = {
97
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry sbsa_ref_memmap[] = {
106
/* ~1TB PCIE MMIO space (4GB to 1024GB boundary) */
98
/* ~1TB PCIE MMIO space (4GB to 1024GB boundary) */
...
...
133
@@ -XXX,XX +XXX,XX @@ static void create_smmu(const SBSAMachineState *sms, PCIBus *bus)
125
@@ -XXX,XX +XXX,XX @@ static void create_smmu(const SBSAMachineState *sms, PCIBus *bus)
134
}
126
}
135
}
127
}
136
128
137
+static void create_cxl_fixed_window(SBSAMachineState *sms,
129
+static void create_cxl_fixed_window(SBSAMachineState *sms,
138
+ MemoryRegion *mem, SbsaCXLHost *host)
130
+ MemoryRegion *mem, CXLHostBridge *host)
139
+{
131
+{
140
+ PCIBus *cxlbus = PCI_HOST_BRIDGE(host)->bus;
132
+ PCIBus *cxlbus = PCI_HOST_BRIDGE(host)->bus;
141
+ char *cxl_host = object_get_canonical_path(OBJECT(cxlbus));
133
+ char *cxl_host = object_get_canonical_path(OBJECT(cxlbus));
142
+ hwaddr base = sbsa_ref_memmap[SBSA_CXL_FIXED_WINDOW].base;
134
+ hwaddr base = sbsa_ref_memmap[SBSA_CXL_FIXED_WINDOW].base;
143
+ GList *it;
135
+ GList *it;
...
...
153
+ &sbsa_ref_cfmwoptions, &error_fatal);
145
+ &sbsa_ref_cfmwoptions, &error_fatal);
154
+
146
+
155
+ it = sms->cxl_devices_state.fixed_windows;
147
+ it = sms->cxl_devices_state.fixed_windows;
156
+ fw = it->data;
148
+ fw = it->data;
157
+ fw->base = base;
149
+ fw->base = base;
158
+ fw->sbsa_target = host;
150
+ fw->target_chb[0] = host;
159
+
151
+
160
+ memory_region_init_io(&fw->mr, OBJECT(sms), &cfmws_ops, fw,
152
+ memory_region_init_io(&fw->mr, OBJECT(sms), &cfmws_ops, fw,
161
+ "cxl-fixed-memory-region", fw->size);
153
+ "cxl-fixed-memory-region", fw->size);
162
+
154
+
163
+ memory_region_add_subregion(mem, fw->base, &fw->mr);
155
+ memory_region_add_subregion(mem, fw->base, &fw->mr);
164
+}
156
+}
165
+
157
+
166
+static void create_cxl(SBSAMachineState *sms)
158
+static void create_cxl(SBSAMachineState *sms)
167
+{
159
+{
168
+ hwaddr base_ecam = sbsa_ref_memmap[SBSA_CXL_ECAM].base;
169
+ hwaddr size_ecam = sbsa_ref_memmap[SBSA_CXL_ECAM].size;
170
+ hwaddr base_mmio = sbsa_ref_memmap[SBSA_CXL_MMIO].base;
171
+ hwaddr size_mmio = sbsa_ref_memmap[SBSA_CXL_MMIO].size;
172
+ hwaddr base_mmio_high = sbsa_ref_memmap[SBSA_CXL_MMIO_HIGH].base;
173
+ hwaddr size_mmio_high = sbsa_ref_memmap[SBSA_CXL_MMIO_HIGH].size;
174
+ hwaddr base_pio = sbsa_ref_memmap[SBSA_CXL_PIO].base;
160
+ hwaddr base_pio = sbsa_ref_memmap[SBSA_CXL_PIO].base;
175
+ int irq = sbsa_ref_irqmap[SBSA_CXL];
161
+ int irq = sbsa_ref_irqmap[SBSA_CXL];
176
+ MemoryRegion *mmio_alias, *mmio_alias_high, *mmio_reg;
162
+ MemoryRegion *mmio_alias, *mmio_alias_high, *mmio_reg;
177
+ MemoryRegion *ecam_alias, *ecam_reg;
163
+ MemoryRegion *ecam_alias, *ecam_reg;
178
+ MemoryRegion *sysmem = get_system_memory();
164
+ MemoryRegion *sysmem = get_system_memory();
179
+ MemoryRegion *chbcr = &sms->cxl_devices_state.host_mr;
165
+ MemoryRegion *chbcr = &sms->cxl_devices_state.host_mr;
180
+ DeviceState *dev;
166
+ DeviceState *dev;
181
+ SbsaCXLHost *host;
167
+ CXLHostBridge *host;
182
+ PCIHostState *cxl;
168
+ PCIHostState *cxl;
183
+ PCIDevice *cxlrp;
169
+ PCIDevice *cxlrp;
184
+ PCIEPort *p;
170
+ PCIEPort *p;
185
+ PCIESlot *s;
171
+ PCIESlot *s;
186
+ int i;
172
+ int i;
187
+
173
+
188
+ dev = qdev_new(TYPE_SBSA_CXL_HOST);
174
+ dev = qdev_new(TYPE_CXL_HOST);
189
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
175
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
190
+ sms->cxl_devices_state.is_enabled = true;
176
+ sms->cxl_devices_state.is_enabled = true;
191
+
177
+
192
+ /* Map CXL ECAM space */
178
+ /* Map CXL ECAM space */
193
+ ecam_alias = g_new0(MemoryRegion, 1);
179
+ ecam_alias = g_new0(MemoryRegion, 1);
194
+ ecam_reg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1);
180
+ ecam_reg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1);
195
+ memory_region_init_alias(ecam_alias, OBJECT(dev), "cxl-ecam",
181
+ memory_region_init_alias(ecam_alias, OBJECT(dev), "cxl-ecam",
196
+ ecam_reg, 0, size_ecam);
182
+ ecam_reg, 0, sbsa_ref_memmap[SBSA_CXL_ECAM].size);
197
+ memory_region_add_subregion(get_system_memory(), base_ecam, ecam_alias);
183
+ memory_region_add_subregion(get_system_memory(),
184
+ sbsa_ref_memmap[SBSA_CXL_ECAM].base, ecam_alias);
198
+
185
+
199
+ /* Map CXL MMIO space */
186
+ /* Map CXL MMIO space */
200
+ mmio_alias = g_new0(MemoryRegion, 1);
187
+ mmio_alias = g_new0(MemoryRegion, 1);
201
+ mmio_reg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 2);
188
+ mmio_reg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 2);
202
+ memory_region_init_alias(mmio_alias, OBJECT(dev), "cxl-mmio",
189
+ memory_region_init_alias(mmio_alias, OBJECT(dev), "cxl-mmio",
203
+ mmio_reg, base_mmio, size_mmio);
190
+ mmio_reg, sbsa_ref_memmap[SBSA_CXL_MMIO].base,
204
+ memory_region_add_subregion(get_system_memory(), base_mmio, mmio_alias);
191
+ sbsa_ref_memmap[SBSA_CXL_MMIO].size);
192
+ memory_region_add_subregion(get_system_memory(),
193
+ sbsa_ref_memmap[SBSA_CXL_MMIO].base, mmio_alias);
205
+
194
+
206
+ /* Map CXL MMIO_HIGH space */
195
+ /* Map CXL MMIO_HIGH space */
207
+ mmio_alias_high = g_new0(MemoryRegion, 1);
196
+ mmio_alias_high = g_new0(MemoryRegion, 1);
208
+ memory_region_init_alias(mmio_alias_high, OBJECT(dev), "cxl-mmio-high",
197
+ memory_region_init_alias(mmio_alias_high, OBJECT(dev), "cxl-mmio-high",
209
+ mmio_reg, base_mmio_high, size_mmio_high);
198
+ mmio_reg, sbsa_ref_memmap[SBSA_CXL_MMIO_HIGH].base,
210
+ memory_region_add_subregion(get_system_memory(), base_mmio_high,
199
+ sbsa_ref_memmap[SBSA_CXL_MMIO_HIGH].size);
211
+ mmio_alias_high);
200
+ memory_region_add_subregion(get_system_memory(),
201
+ sbsa_ref_memmap[SBSA_CXL_MMIO_HIGH].base, mmio_alias_high);
212
+
202
+
213
+ /* Map CXL IO port space */
203
+ /* Map CXL IO port space */
214
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 3, base_pio);
204
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 3, base_pio);
215
+
205
+
216
+ for (i = 0; i < SBSA_CXL_NUM_IRQS; i++) {
206
+ for (i = 0; i < CXL_HOST_NUM_IRQS; i++) {
217
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
207
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
218
+ qdev_get_gpio_in(sms->gic, irq + i));
208
+ qdev_get_gpio_in(sms->gic, irq + i));
219
+ sbsa_cxl_set_irq_num(SBSA_CXL_HOST(dev), i, irq + i);
209
+ cxl_host_set_irq_num(CXL_HOST(dev), i, irq + i);
220
+ }
210
+ }
221
+
211
+
222
+ /* Map CXL CHBCR space */
212
+ /* Map CXL CHBCR space */
223
+ memory_region_init(chbcr, OBJECT(sms), "cxl_host_reg",
213
+ memory_region_init(chbcr, OBJECT(sms), "cxl_host_reg",
224
+ sbsa_ref_memmap[SBSA_CXL_CHBCR].size);
214
+ sbsa_ref_memmap[SBSA_CXL_CHBCR].size);
225
+ memory_region_add_subregion(sysmem, sbsa_ref_memmap[SBSA_CXL_CHBCR].base, chbcr);
215
+ memory_region_add_subregion(sysmem, sbsa_ref_memmap[SBSA_CXL_CHBCR].base,
216
+ chbcr);
226
+
217
+
227
+ cxl = PCI_HOST_BRIDGE(dev);
218
+ cxl = PCI_HOST_BRIDGE(dev);
228
+
219
+
229
+ /* Connect two cxl root ports */
220
+ /* Connect two cxl root ports */
230
+ for (i = 0; i < 2; i++) {
221
+ for (i = 0; i < 2; i++) {
...
...
234
+ p->port = i;
225
+ p->port = i;
235
+ s->slot = i;
226
+ s->slot = i;
236
+ pci_realize_and_unref(cxlrp, cxl->bus, &error_fatal);
227
+ pci_realize_and_unref(cxlrp, cxl->bus, &error_fatal);
237
+ }
228
+ }
238
+
229
+
239
+ host = SBSA_CXL_HOST(dev);
230
+ host = CXL_HOST(dev);
240
+ sbsa_cxl_hook_up_registers(&sms->cxl_devices_state, host, &error_fatal);
231
+ cxl_host_hook_up_registers(&sms->cxl_devices_state, host, &error_fatal);
241
+
232
+
242
+ create_cxl_fixed_window(sms, sysmem, host);
233
+ create_cxl_fixed_window(sms, sysmem, host);
243
+}
234
+}
244
+
235
+
245
static void create_pcie(SBSAMachineState *sms)
236
static void create_pcie(SBSAMachineState *sms)
...
...
252
+ create_cxl(sms);
243
+ create_cxl(sms);
253
+
244
+
254
create_secure_ec(secure_sysmem);
245
create_secure_ec(secure_sysmem);
255
246
256
sms->bootinfo.ram_size = machine->ram_size;
247
sms->bootinfo.ram_size = machine->ram_size;
257
diff --git a/hw/cxl/cxl-host-stubs.c b/hw/cxl/cxl-host-stubs.c
258
index XXXXXXX..XXXXXXX 100644
259
--- a/hw/cxl/cxl-host-stubs.c
260
+++ b/hw/cxl/cxl-host-stubs.c
261
@@ -XXX,XX +XXX,XX @@
262
void cxl_fmws_link_targets(CXLState *stat, Error **errp) {};
263
void cxl_machine_init(Object *obj, CXLState *state) {};
264
void cxl_hook_up_pxb_registers(PCIBus *bus, CXLState *state, Error **errp) {};
265
+void cxl_fixed_memory_window_config(CXLState *cxl_state,
266
+ CXLFixedMemoryWindowOptions *object, Error **errp) {};
267
268
const MemoryRegionOps cfmws_ops;
269
diff --git a/hw/cxl/cxl-host.c b/hw/cxl/cxl-host.c
270
index XXXXXXX..XXXXXXX 100644
271
--- a/hw/cxl/cxl-host.c
272
+++ b/hw/cxl/cxl-host.c
273
@@ -XXX,XX +XXX,XX @@
274
#include "qapi/qapi-visit-machine.h"
275
#include "hw/cxl/cxl.h"
276
#include "hw/cxl/cxl_host.h"
277
+#include "hw/irq.h"
278
#include "hw/pci/pci_bus.h"
279
#include "hw/pci/pci_bridge.h"
280
#include "hw/pci/pci_host.h"
281
#include "hw/pci/pcie_port.h"
282
#include "hw/pci-bridge/pci_expander_bridge.h"
283
284
-static void cxl_fixed_memory_window_config(CXLState *cxl_state,
285
+void cxl_fixed_memory_window_config(CXLState *cxl_state,
286
CXLFixedMemoryWindowOptions *object,
287
Error **errp)
288
{
289
@@ -XXX,XX +XXX,XX @@ static PCIDevice *cxl_cfmws_find_device(CXLFixedWindow *fw, hwaddr addr)
290
/* Address is relative to memory region. Convert to HPA */
291
addr += fw->base;
292
293
+ if (fw->sbsa_target) {
294
+ hb = PCI_HOST_BRIDGE(fw->sbsa_target);
295
+ SbsaCXLHost *host = fw->sbsa_target;
296
+
297
+ hb_cstate = &host->cxl_cstate;
298
+ cache_mem = hb_cstate->crb.cache_mem_registers;
299
+ target_found = cxl_hdm_find_target(cache_mem, addr, &target);
300
+ rp = pcie_find_port_by_pn(hb->bus, target);
301
+ goto done;
302
+ }
303
+
304
rb_index = (addr / cxl_decode_ig(fw->enc_int_gran)) % fw->num_targets;
305
hb = PCI_HOST_BRIDGE(fw->target_hbs[rb_index]->cxl_host_bridge);
306
if (!hb || !hb->bus || !pci_bus_is_cxl(hb->bus)) {
307
@@ -XXX,XX +XXX,XX @@ static PCIDevice *cxl_cfmws_find_device(CXLFixedWindow *fw, hwaddr addr)
308
}
309
}
310
311
+done:
312
d = pci_bridge_get_sec_bus(PCI_BRIDGE(rp))->devices[0];
313
if (!d) {
314
return NULL;
315
@@ -XXX,XX +XXX,XX @@ void cxl_hook_up_pxb_registers(PCIBus *bus, CXLState *state, Error **errp)
316
}
317
}
318
}
319
+
320
+/****************************************************************************
321
+ * Sbsa CXL host
322
+ */
323
+
324
+static void sbsa_cxl_set_irq(void *opaque, int irq_num, int level)
325
+{
326
+ SbsaCXLHost *host = opaque;
327
+
328
+ qemu_set_irq(host->irq[irq_num], level);
329
+}
330
+
331
+int sbsa_cxl_set_irq_num(SbsaCXLHost *host, int index, int gsi)
332
+{
333
+ if (index >= SBSA_CXL_NUM_IRQS) {
334
+ return -EINVAL;
335
+ }
336
+
337
+ host->irq_num[index] = gsi;
338
+ return 0;
339
+}
340
+
341
+static PCIINTxRoute sbsa_cxl_route_intx_pin_to_irq(void *opaque, int pin)
342
+{
343
+ PCIINTxRoute route;
344
+ SbsaCXLHost *host = opaque;
345
+ int gsi = host->irq_num[pin];
346
+
347
+ route.irq = gsi;
348
+ if (gsi < 0) {
349
+ route.mode = PCI_INTX_DISABLED;
350
+ } else {
351
+ route.mode = PCI_INTX_ENABLED;
352
+ }
353
+
354
+ return route;
355
+}
356
+
357
+static const char *sbsa_host_root_bus_path(PCIHostState *host_bridge,
358
+ PCIBus *rootbus)
359
+{
360
+ return "0001:00";
361
+}
362
+
363
+void sbsa_cxl_hook_up_registers(CXLState *cxl_state, SbsaCXLHost *host, Error **errp)
364
+{
365
+ CXLComponentState *cxl_cstate = &host->cxl_cstate;
366
+ struct MemoryRegion *mr = &cxl_cstate->crb.component_registers;
367
+ hwaddr offset;
368
+
369
+ offset = memory_region_size(mr) * cxl_state->next_mr_idx;
370
+ if (offset > memory_region_size(&cxl_state->host_mr)) {
371
+ error_setg(errp, "Insufficient space for sbsa cxl host register space");
372
+ return;
373
+ }
374
+
375
+ memory_region_add_subregion(&cxl_state->host_mr, offset, mr);
376
+ cxl_state->next_mr_idx++;
377
+}
378
+
379
+static void sbsa_cxl_host_reset(SbsaCXLHost *host)
380
+{
381
+ CXLComponentState *cxl_cstate = &host->cxl_cstate;
382
+ uint32_t *reg_state = cxl_cstate->crb.cache_mem_registers;
383
+ uint32_t *write_msk = cxl_cstate->crb.cache_mem_regs_write_mask;
384
+
385
+ cxl_component_register_init_common(reg_state, write_msk, CXL2_RC);
386
+
387
+ ARRAY_FIELD_DP32(reg_state, CXL_HDM_DECODER_CAPABILITY, TARGET_COUNT,
388
+ 8);
389
+}
390
+
391
+static void sbsa_cxl_realize(DeviceState *dev, Error **errp)
392
+{
393
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
394
+ SbsaCXLHost *host = SBSA_CXL_HOST(dev);
395
+ CXLComponentState *cxl_cstate = &host->cxl_cstate;
396
+ struct MemoryRegion *mr = &cxl_cstate->crb.component_registers;
397
+ PCIBus *cxlbus;
398
+ PCIHostState *pci = PCI_HOST_BRIDGE(dev);
399
+ PCIExpressHost *pex = PCIE_HOST_BRIDGE(dev);
400
+ int i;
401
+
402
+ /* CHBCR MMIO init */
403
+ sbsa_cxl_host_reset(host);
404
+ cxl_component_register_block_init(OBJECT(dev), cxl_cstate,
405
+ TYPE_SBSA_CXL_HOST);
406
+ sysbus_init_mmio(sbd, mr);
407
+
408
+ /* PCIe Host MMIO init */
409
+ pcie_host_mmcfg_init(pex, PCIE_MMCFG_SIZE_MAX);
410
+ sysbus_init_mmio(sbd, &pex->mmio);
411
+
412
+ memory_region_init(&host->io_mmio, OBJECT(host), "cxl_host_mmio", UINT64_MAX);
413
+ memory_region_init(&host->io_ioport, OBJECT(host), "cxl_host_ioport", 64 * 1024);
414
+
415
+ memory_region_init_io(&host->io_mmio_window, OBJECT(host),
416
+ &unassigned_io_ops, OBJECT(host),
417
+ "cxl_host_mmio_window", UINT64_MAX);
418
+ memory_region_init_io(&host->io_ioport_window, OBJECT(host),
419
+ &unassigned_io_ops, OBJECT(host),
420
+ "cxl_host_ioport_window", 64 * 1024);
421
+
422
+ memory_region_add_subregion(&host->io_mmio_window, 0, &host->io_mmio);
423
+ memory_region_add_subregion(&host->io_ioport_window, 0, &host->io_ioport);
424
+ sysbus_init_mmio(sbd, &host->io_mmio_window);
425
+ sysbus_init_mmio(sbd, &host->io_ioport_window);
426
+
427
+ sysbus_init_mmio(sbd, &host->io_mmio);
428
+ sysbus_init_mmio(sbd, &host->io_ioport);
429
+
430
+ for (i = 0; i < SBSA_CXL_NUM_IRQS; i++) {
431
+ sysbus_init_irq(sbd, &host->irq[i]);
432
+ host->irq_num[i] = -1;
433
+ }
434
+
435
+ pci->bus = pci_register_root_bus(dev, "cxlhost.0", sbsa_cxl_set_irq,
436
+ pci_swizzle_map_irq_fn, host, &host->io_mmio,
437
+ &host->io_ioport, 0, 4, TYPE_CXL_BUS);
438
+ cxlbus = pci->bus;
439
+ cxlbus->flags |= PCI_BUS_CXL;
440
+
441
+ pci_bus_set_route_irq_fn(pci->bus, sbsa_cxl_route_intx_pin_to_irq);
442
+}
443
+
444
+static void sbsa_cxl_host_class_init(ObjectClass *class, void *data)
445
+{
446
+ DeviceClass *dc = DEVICE_CLASS(class);
447
+ PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(class);
448
+
449
+ hc->root_bus_path = sbsa_host_root_bus_path;
450
+ dc->realize = sbsa_cxl_realize;
451
+ dc->desc = "Sbsa CXL Host Bridge";
452
+ set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
453
+ dc->fw_name = "cxl";
454
+
455
+}
456
+
457
+/*
458
+ * SBSA CXL HOST
459
+ */
460
+static const TypeInfo sbsa_cxl_host_info = {
461
+ .name = TYPE_SBSA_CXL_HOST,
462
+ .parent = TYPE_PCIE_HOST_BRIDGE,
463
+ .instance_size = sizeof(SbsaCXLHost),
464
+ .class_init = sbsa_cxl_host_class_init,
465
+};
466
+
467
+static void cxl_host_register(void)
468
+{
469
+ type_register_static(&sbsa_cxl_host_info);
470
+}
471
+
472
+type_init(cxl_host_register)
473
diff --git a/include/hw/cxl/cxl.h b/include/hw/cxl/cxl.h
474
index XXXXXXX..XXXXXXX 100644
475
--- a/include/hw/cxl/cxl.h
476
+++ b/include/hw/cxl/cxl.h
477
@@ -XXX,XX +XXX,XX @@
478
#include "cxl_pci.h"
479
#include "cxl_component.h"
480
#include "cxl_device.h"
481
+#include "hw/pci/pcie_host.h"
482
483
#define CXL_CACHE_LINE_SIZE 64
484
#define CXL_COMPONENT_REG_BAR_IDX 0
485
@@ -XXX,XX +XXX,XX @@
486
487
#define CXL_WINDOW_MAX 10
488
489
+#define TYPE_SBSA_CXL_HOST "sbsa-cxl-host"
490
+OBJECT_DECLARE_SIMPLE_TYPE(SbsaCXLHost, SBSA_CXL_HOST)
491
+
492
+#define SBSA_CXL_NUM_IRQS 4
493
+
494
typedef struct PXBCXLDev PXBCXLDev;
495
496
+struct SbsaCXLHost {
497
+ PCIExpressHost parent_obj;
498
+
499
+ CXLComponentState cxl_cstate;
500
+ bool passthrough;
501
+ int rp_count;
502
+
503
+ MemoryRegion io_ioport;
504
+ MemoryRegion io_mmio;
505
+ MemoryRegion io_ioport_window;
506
+ MemoryRegion io_mmio_window;
507
+ qemu_irq irq[SBSA_CXL_NUM_IRQS];
508
+ int irq_num[SBSA_CXL_NUM_IRQS];
509
+};
510
+
511
typedef struct CXLFixedWindow {
512
uint64_t size;
513
char **targets;
514
PXBCXLDev *target_hbs[16];
515
+ SbsaCXLHost *sbsa_target;
516
uint8_t num_targets;
517
uint8_t enc_int_ways;
518
uint8_t enc_int_gran;
519
diff --git a/include/hw/cxl/cxl_host.h b/include/hw/cxl/cxl_host.h
520
index XXXXXXX..XXXXXXX 100644
521
--- a/include/hw/cxl/cxl_host.h
522
+++ b/include/hw/cxl/cxl_host.h
523
@@ -XXX,XX +XXX,XX @@
524
void cxl_machine_init(Object *obj, CXLState *state);
525
void cxl_fmws_link_targets(CXLState *stat, Error **errp);
526
void cxl_hook_up_pxb_registers(PCIBus *bus, CXLState *state, Error **errp);
527
+void cxl_fixed_memory_window_config(CXLState *cxl_state,
528
+ CXLFixedMemoryWindowOptions *object, Error **errp);
529
+
530
+int sbsa_cxl_set_irq_num(SbsaCXLHost *host, int index, int gsi);
531
+void sbsa_cxl_hook_up_registers(CXLState *cxl_state, SbsaCXLHost *host, Error **errp);
532
533
extern const MemoryRegionOps cfmws_ops;
534
535
--
248
--
536
2.34.1
249
2.34.1
diff view generated by jsdifflib