20
#include "qemu/osdep.h"
22
#include "hw/pci/pci_bridge.h"
23
#include "hw/pci/pci_host.h"
24
#include "hw/cxl/cxl.h"
25
#include "hw/mem/memory-device.h"
26
#include "hw/acpi/acpi.h"
27
#include "hw/acpi/aml-build.h"
28
#include "hw/acpi/bios-linker-loader.h"
29
#include "hw/acpi/cxl.h"
30
#include "qapi/error.h"
33
void build_cxl_dsm_method(Aml *dev)
35
Aml *method, *ifctx, *ifctx2;
37
method = aml_method("_DSM", 4, AML_SERIALIZED);
42
function = aml_arg(2);
44
ifctx = aml_if(aml_equal(
45
uuid, aml_touuid("F365F9A6-A7DE-4071-A66A-B40C0B4F8E52")));
48
ifctx2 = aml_if(aml_equal(function, aml_int(0)));
50
uint8_t byte_list[1] = { 0x01 };
53
aml_return(aml_buffer(sizeof(byte_list), byte_list)));
55
aml_append(ifctx, ifctx2);
65
ifctx2 = aml_if(aml_equal(function, aml_int(1)));
83
pak1 = aml_package(2);
85
aml_append(pak1, aml_int(0));
87
aml_append(pak1, aml_int(1));
91
aml_append(pak, aml_int(1));
92
aml_append(pak, pak1);
94
aml_append(ifctx2, aml_return(pak));
96
aml_append(ifctx, ifctx2);
98
aml_append(method, ifctx);
99
aml_append(dev, method);
102
static void cedt_build_chbs(GArray *table_data, PXBCXLDev *cxl)
104
PXBDev *pxb = PXB_DEV(cxl);
105
SysBusDevice *sbd = SYS_BUS_DEVICE(cxl->cxl_host_bridge);
106
struct MemoryRegion *mr = sbd->mmio[0].memory;
109
build_append_int_noprefix(table_data, 0, 1);
112
build_append_int_noprefix(table_data, 0, 1);
115
build_append_int_noprefix(table_data, 32, 2);
118
build_append_int_noprefix(table_data, pxb->bus_nr, 4);
121
build_append_int_noprefix(table_data, 1, 4);
124
build_append_int_noprefix(table_data, 0, 4);
127
build_append_int_noprefix(table_data, mr->container->addr + mr->addr, 8);
130
build_append_int_noprefix(table_data, memory_region_size(mr), 8);
138
static void cedt_build_cfmws(GArray *table_data, CXLState *cxls)
142
for (it = cxls->fixed_windows; it; it = it->next) {
143
CXLFixedWindow *fw = it->data;
147
build_append_int_noprefix(table_data, 1, 1);
150
build_append_int_noprefix(table_data, 0, 1);
153
build_append_int_noprefix(table_data, 36 + 4 * fw->num_targets, 2);
156
build_append_int_noprefix(table_data, 0, 4);
159
build_append_int_noprefix(table_data, fw->mr.addr, 8);
162
build_append_int_noprefix(table_data, fw->size, 8);
165
build_append_int_noprefix(table_data, fw->enc_int_ways, 1);
168
build_append_int_noprefix(table_data, 0, 1);
171
build_append_int_noprefix(table_data, 0, 2);
174
build_append_int_noprefix(table_data, fw->enc_int_gran, 4);
177
build_append_int_noprefix(table_data, 0x0f, 2);
180
build_append_int_noprefix(table_data, 0, 2);
183
for (i = 0; i < fw->num_targets; i++) {
184
g_assert(fw->target_hbs[i]);
185
build_append_int_noprefix(table_data, PXB_DEV(fw->target_hbs[i])->bus_nr, 4);
190
static int cxl_foreach_pxb_hb(Object *obj, void *opaque)
194
if (object_dynamic_cast(obj, TYPE_PXB_CXL_DEV)) {
195
cedt_build_chbs(cedt->buf, PXB_CXL_DEV(obj));
201
void cxl_build_cedt(GArray *table_offsets, GArray *table_data,
202
BIOSLinker *linker, const char *oem_id,
203
const char *oem_table_id, CXLState *cxl_state)
206
AcpiTable table = { .sig = "CEDT", .rev = 1, .oem_id = oem_id,
207
.oem_table_id = oem_table_id };
209
acpi_add_table(table_offsets, table_data);
210
acpi_table_begin(&table, table_data);
211
cedt = init_aml_allocator();
215
object_child_foreach_recursive(object_get_root(), cxl_foreach_pxb_hb, cedt);
216
cedt_build_cfmws(cedt->buf, cxl_state);
219
g_array_append_vals(table_data, cedt->buf->data, cedt->buf->len);
220
free_aml_allocator();
222
acpi_table_end(linker, &table);
225
static Aml *__build_cxl_osc_method(void)
227
Aml *method, *if_uuid, *else_uuid, *if_arg1_not_1, *if_cxl, *if_caps_masked;
228
Aml *a_ctrl = aml_local(0);
229
Aml *a_cdw1 = aml_name("CDW1");
231
method = aml_method("_OSC", 4, AML_NOTSERIALIZED);
233
aml_append(method, aml_create_dword_field(aml_arg(3), aml_int(0), "CDW1"));
249
aml_lor(aml_equal(aml_arg(0),
250
aml_touuid("33DB4D5B-1FF7-401C-9657-7441C03DD766")),
251
aml_equal(aml_arg(0),
252
aml_touuid("68F2D50B-C469-4D8A-BD3D-941A103FD3FC"))));
253
aml_append(if_uuid, aml_create_dword_field(aml_arg(3), aml_int(4), "CDW2"));
254
aml_append(if_uuid, aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3"));
256
aml_append(if_uuid, aml_store(aml_name("CDW3"), a_ctrl));
263
aml_append(if_uuid, aml_and(a_ctrl, aml_int(0x1F), a_ctrl));
270
if_arg1_not_1 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(0x1))));
271
aml_append(if_arg1_not_1, aml_or(a_cdw1, aml_int(0x08), a_cdw1));
272
aml_append(if_uuid, if_arg1_not_1);
274
if_caps_masked = aml_if(aml_lnot(aml_equal(aml_name("CDW3"), a_ctrl)));
277
aml_append(if_caps_masked, aml_or(a_cdw1, aml_int(0x10), a_cdw1));
278
aml_append(if_uuid, if_caps_masked);
280
aml_append(if_uuid, aml_store(aml_name("CDW2"), aml_name("SUPP")));
281
aml_append(if_uuid, aml_store(aml_name("CDW3"), aml_name("CTRL")));
284
aml_append(if_uuid, aml_store(a_ctrl, aml_name("CDW3")));
287
if_cxl = aml_if(aml_equal(
288
aml_arg(0), aml_touuid("68F2D50B-C469-4D8A-BD3D-941A103FD3FC")));
290
aml_append(if_cxl, aml_create_dword_field(aml_arg(3), aml_int(12), "CDW4"));
292
aml_append(if_cxl, aml_create_dword_field(aml_arg(3), aml_int(16), "CDW5"));
293
aml_append(if_cxl, aml_store(aml_name("CDW4"), aml_name("SUPC")));
294
aml_append(if_cxl, aml_store(aml_name("CDW5"), aml_name("CTRC")));
298
aml_or(aml_name("CDW5"), aml_int(0x1), aml_name("CDW5")));
299
aml_append(if_uuid, if_cxl);
301
aml_append(if_uuid, aml_return(aml_arg(3)));
302
aml_append(method, if_uuid);
309
else_uuid = aml_else();
311
aml_append(else_uuid,
312
aml_or(aml_name("CDW1"), aml_int(0x4), aml_name("CDW1")));
313
aml_append(else_uuid, aml_return(aml_arg(3)));
314
aml_append(method, else_uuid);
319
void build_cxl_osc_method(Aml *dev)
321
aml_append(dev, aml_name_decl("SUPP", aml_int(0)));
322
aml_append(dev, aml_name_decl("CTRL", aml_int(0)));
323
aml_append(dev, aml_name_decl("SUPC", aml_int(0)));
324
aml_append(dev, aml_name_decl("CTRC", aml_int(0)));
325
aml_append(dev, __build_cxl_osc_method());