1 /* 2 * CXL host parameter parsing routines 3 * 4 * Copyright (c) 2022 Huawei 5 * Modeled loosely on the NUMA options handling in hw/core/numa.c 6 */ 7 8 #include "qemu/osdep.h" 9 #include "qemu/units.h" 10 #include "qemu/bitmap.h" 11 #include "qemu/error-report.h" 12 #include "qapi/error.h" 13 #include "sysemu/qtest.h" 14 #include "hw/boards.h" 15 16 #include "qapi/qapi-visit-machine.h" 17 #include "hw/cxl/cxl.h" 18 19 void cxl_fixed_memory_window_config(MachineState *ms, 20 CXLFixedMemoryWindowOptions *object, 21 Error **errp) 22 { 23 CXLFixedWindow *fw = g_malloc0(sizeof(*fw)); 24 strList *target; 25 int i; 26 27 for (target = object->targets; target; target = target->next) { 28 fw->num_targets++; 29 } 30 31 fw->enc_int_ways = cxl_interleave_ways_enc(fw->num_targets, errp); 32 if (*errp) { 33 return; 34 } 35 36 fw->targets = g_malloc0_n(fw->num_targets, sizeof(*fw->targets)); 37 for (i = 0, target = object->targets; target; i++, target = target->next) { 38 /* This link cannot be resolved yet, so stash the name for now */ 39 fw->targets[i] = g_strdup(target->value); 40 } 41 42 if (object->size % (256 * MiB)) { 43 error_setg(errp, 44 "Size of a CXL fixed memory window must my a multiple of 256MiB"); 45 return; 46 } 47 fw->size = object->size; 48 49 if (object->has_interleave_granularity) { 50 fw->enc_int_gran = 51 cxl_interleave_granularity_enc(object->interleave_granularity, 52 errp); 53 if (*errp) { 54 return; 55 } 56 } else { 57 /* Default to 256 byte interleave */ 58 fw->enc_int_gran = 0; 59 } 60 61 ms->cxl_devices_state->fixed_windows = 62 g_list_append(ms->cxl_devices_state->fixed_windows, fw); 63 64 return; 65 } 66 67 void cxl_fixed_memory_window_link_targets(Error **errp) 68 { 69 MachineState *ms = MACHINE(qdev_get_machine()); 70 71 if (ms->cxl_devices_state && ms->cxl_devices_state->fixed_windows) { 72 GList *it; 73 74 for (it = ms->cxl_devices_state->fixed_windows; it; it = it->next) { 75 CXLFixedWindow *fw = it->data; 76 int i; 77 78 for (i = 0; i < fw->num_targets; i++) { 79 Object *o; 80 bool ambig; 81 82 o = object_resolve_path_type(fw->targets[i], 83 TYPE_PXB_CXL_DEVICE, 84 &ambig); 85 if (!o) { 86 error_setg(errp, "Could not resolve CXLFM target %s", 87 fw->targets[i]); 88 return; 89 } 90 fw->target_hbs[i] = PXB_CXL_DEV(o); 91 } 92 } 93 } 94 } 95