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 |