1 /* 2 * SPDX-License-Identifier: GPL-2.0-or-later 3 * 4 * uefi vars device - sysbus variant. 5 */ 6 #include "qemu/osdep.h" 7 #include "migration/vmstate.h" 8 9 #include "hw/qdev-properties.h" 10 #include "hw/sysbus.h" 11 12 #include "hw/uefi/hardware-info.h" 13 #include "hw/uefi/var-service.h" 14 #include "hw/uefi/var-service-api.h" 15 16 OBJECT_DECLARE_SIMPLE_TYPE(uefi_vars_sysbus_state, UEFI_VARS_SYSBUS) 17 18 struct uefi_vars_sysbus_state { 19 SysBusDevice parent_obj; 20 struct uefi_vars_state state; 21 }; 22 23 static const VMStateDescription vmstate_uefi_vars_sysbus = { 24 .name = TYPE_UEFI_VARS_SYSBUS, 25 .fields = (VMStateField[]) { 26 VMSTATE_STRUCT(state, uefi_vars_sysbus_state, 0, 27 vmstate_uefi_vars, uefi_vars_state), 28 VMSTATE_END_OF_LIST() 29 } 30 }; 31 32 static const Property uefi_vars_sysbus_properties[] = { 33 DEFINE_PROP_SIZE("size", uefi_vars_sysbus_state, state.max_storage, 34 256 * 1024), 35 DEFINE_PROP_STRING("jsonfile", uefi_vars_sysbus_state, state.jsonfile), 36 DEFINE_PROP_BOOL("force-secure-boot", uefi_vars_sysbus_state, 37 state.force_secure_boot, false), 38 DEFINE_PROP_BOOL("disable-custom-mode", uefi_vars_sysbus_state, 39 state.disable_custom_mode, false), 40 DEFINE_PROP_BOOL("use-pio", uefi_vars_sysbus_state, 41 state.use_pio, false), 42 }; 43 44 static void uefi_vars_sysbus_init(Object *obj) 45 { 46 uefi_vars_sysbus_state *uv = UEFI_VARS_SYSBUS(obj); 47 48 uefi_vars_init(obj, &uv->state); 49 } 50 51 static void uefi_vars_sysbus_reset(DeviceState *dev) 52 { 53 uefi_vars_sysbus_state *uv = UEFI_VARS_SYSBUS(dev); 54 55 uefi_vars_hard_reset(&uv->state); 56 } 57 58 static void uefi_vars_sysbus_realize(DeviceState *dev, Error **errp) 59 { 60 uefi_vars_sysbus_state *uv = UEFI_VARS_SYSBUS(dev); 61 SysBusDevice *sysbus = SYS_BUS_DEVICE(dev); 62 63 sysbus_init_mmio(sysbus, &uv->state.mr); 64 uefi_vars_realize(&uv->state, errp); 65 } 66 67 static void uefi_vars_sysbus_class_init(ObjectClass *klass, const void *data) 68 { 69 DeviceClass *dc = DEVICE_CLASS(klass); 70 71 dc->realize = uefi_vars_sysbus_realize; 72 dc->vmsd = &vmstate_uefi_vars_sysbus; 73 dc->user_creatable = true; 74 device_class_set_legacy_reset(dc, uefi_vars_sysbus_reset); 75 device_class_set_props(dc, uefi_vars_sysbus_properties); 76 set_bit(DEVICE_CATEGORY_MISC, dc->categories); 77 } 78 79 /* generic: hardware discovery via FDT */ 80 static const TypeInfo uefi_vars_sysbus_info = { 81 .name = TYPE_UEFI_VARS_SYSBUS, 82 .parent = TYPE_SYS_BUS_DEVICE, 83 .instance_size = sizeof(uefi_vars_sysbus_state), 84 .instance_init = uefi_vars_sysbus_init, 85 .class_init = uefi_vars_sysbus_class_init, 86 }; 87 module_obj(TYPE_UEFI_VARS_SYSBUS); 88 89 static void uefi_vars_x64_realize(DeviceState *dev, Error **errp) 90 { 91 HARDWARE_INFO_SIMPLE_DEVICE hwinfo = { 92 .mmio_address = cpu_to_le64(0xfef10000), 93 }; 94 SysBusDevice *sysbus = SYS_BUS_DEVICE(dev); 95 96 uefi_vars_sysbus_realize(dev, errp); 97 98 hardware_info_register(HardwareInfoQemuUefiVars, 99 &hwinfo, sizeof(hwinfo)); 100 sysbus_mmio_map(sysbus, 0, hwinfo.mmio_address); 101 } 102 103 static void uefi_vars_x64_class_init(ObjectClass *klass, const void *data) 104 { 105 DeviceClass *dc = DEVICE_CLASS(klass); 106 107 dc->realize = uefi_vars_x64_realize; 108 } 109 110 /* x64: hardware discovery via etc/hardware-info fw_cfg */ 111 static const TypeInfo uefi_vars_x64_info = { 112 .name = TYPE_UEFI_VARS_X64, 113 .parent = TYPE_UEFI_VARS_SYSBUS, 114 .class_init = uefi_vars_x64_class_init, 115 }; 116 module_obj(TYPE_UEFI_VARS_X64); 117 118 static void uefi_vars_sysbus_register_types(void) 119 { 120 type_register_static(&uefi_vars_sysbus_info); 121 type_register_static(&uefi_vars_x64_info); 122 } 123 124 type_init(uefi_vars_sysbus_register_types) 125