diff options
Diffstat (limited to 'hw/s390x')
-rw-r--r-- | hw/s390x/css.c | 10 | ||||
-rw-r--r-- | hw/s390x/css.h | 2 | ||||
-rw-r--r-- | hw/s390x/event-facility.c | 93 | ||||
-rw-r--r-- | hw/s390x/ipl.c | 25 | ||||
-rw-r--r-- | hw/s390x/s390-virtio-ccw.c | 8 | ||||
-rw-r--r-- | hw/s390x/s390-virtio-hcall.c | 14 | ||||
-rw-r--r-- | hw/s390x/s390-virtio.c | 2 | ||||
-rw-r--r-- | hw/s390x/sclp.c | 69 | ||||
-rw-r--r-- | hw/s390x/virtio-ccw.c | 102 | ||||
-rw-r--r-- | hw/s390x/virtio-ccw.h | 4 |
10 files changed, 220 insertions, 109 deletions
diff --git a/hw/s390x/css.c b/hw/s390x/css.c index 75b04b45af..7074d2b3d5 100644 --- a/hw/s390x/css.c +++ b/hw/s390x/css.c @@ -116,6 +116,15 @@ void css_conditional_io_interrupt(SubchDev *sch) } } +void css_adapter_interrupt(uint8_t isc) +{ + S390CPU *cpu = s390_cpu_addr2state(0); + uint32_t io_int_word = (isc << 27) | IO_INT_WORD_AI; + + trace_css_adapter_interrupt(isc); + s390_io_interrupt(cpu, 0, 0, 0, io_int_word); +} + static void sch_handle_clear_func(SubchDev *sch) { PMCW *p = &sch->curr_status.pmcw; @@ -1259,6 +1268,7 @@ void css_reset_sch(SubchDev *sch) sch->channel_prog = 0x0; sch->last_cmd_valid = false; sch->orb = NULL; + sch->thinint_active = false; } void css_reset(void) diff --git a/hw/s390x/css.h b/hw/s390x/css.h index b536ab5957..e9b440540d 100644 --- a/hw/s390x/css.h +++ b/hw/s390x/css.h @@ -77,6 +77,7 @@ struct SubchDev { CCW1 last_cmd; bool last_cmd_valid; ORB *orb; + bool thinint_active; /* transport-provided data: */ int (*ccw_cb) (SubchDev *, CCW1); SenseId id; @@ -97,4 +98,5 @@ void css_queue_crw(uint8_t rsc, uint8_t erc, int chain, uint16_t rsid); void css_generate_sch_crws(uint8_t cssid, uint8_t ssid, uint16_t schid, int hotplugged, int add); void css_generate_chp_crws(uint8_t cssid, uint8_t chpid); +void css_adapter_interrupt(uint8_t isc); #endif diff --git a/hw/s390x/event-facility.c b/hw/s390x/event-facility.c index a73c0b924a..0777a93916 100644 --- a/hw/s390x/event-facility.c +++ b/hw/s390x/event-facility.c @@ -21,13 +21,13 @@ #include "hw/s390x/sclp.h" #include "hw/s390x/event-facility.h" -typedef struct EventTypesBus { +typedef struct SCLPEventsBus { BusState qbus; -} EventTypesBus; +} SCLPEventsBus; struct SCLPEventFacility { - EventTypesBus sbus; - DeviceState *qdev; + SysBusDevice parent_obj; + SCLPEventsBus sbus; /* guest' receive mask */ unsigned int receive_mask; }; @@ -291,7 +291,7 @@ static void sclp_events_bus_class_init(ObjectClass *klass, void *data) { } -static const TypeInfo s390_sclp_events_bus_info = { +static const TypeInfo sclp_events_bus_info = { .name = TYPE_SCLP_EVENTS_BUS, .parent = TYPE_BUS, .class_init = sclp_events_bus_class_init, @@ -299,7 +299,7 @@ static const TypeInfo s390_sclp_events_bus_info = { static void command_handler(SCLPEventFacility *ef, SCCB *sccb, uint64_t code) { - switch (code) { + switch (code & SCLP_CMD_CODE_MASK) { case SCLP_CMD_READ_EVENT_DATA: read_event_data(ef, sccb); break; @@ -315,21 +315,26 @@ static void command_handler(SCLPEventFacility *ef, SCCB *sccb, uint64_t code) } } -static int init_event_facility(S390SCLPDevice *sdev) +static const VMStateDescription vmstate_event_facility = { + .name = "vmstate-event-facility", + .version_id = 0, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .fields = (VMStateField[]) { + VMSTATE_UINT32(receive_mask, SCLPEventFacility), + VMSTATE_END_OF_LIST() + } +}; + +static int init_event_facility(SCLPEventFacility *event_facility) { - SCLPEventFacility *event_facility; + DeviceState *sdev = DEVICE(event_facility); DeviceState *quiesce; - event_facility = g_malloc0(sizeof(SCLPEventFacility)); - sdev->ef = event_facility; - sdev->sclp_command_handler = command_handler; - sdev->event_pending = event_pending; - - /* Spawn a new sclp-events facility */ + /* Spawn a new bus for SCLP events */ qbus_create_inplace(&event_facility->sbus, sizeof(event_facility->sbus), - TYPE_SCLP_EVENTS_BUS, DEVICE(sdev), NULL); + TYPE_SCLP_EVENTS_BUS, sdev, NULL); event_facility->sbus.qbus.allow_hotplug = 0; - event_facility->qdev = (DeviceState *) sdev; quiesce = qdev_create(&event_facility->sbus.qbus, "sclpquiesce"); if (!quiesce) { @@ -346,43 +351,57 @@ static int init_event_facility(S390SCLPDevice *sdev) static void reset_event_facility(DeviceState *dev) { - S390SCLPDevice *sdev = SCLP_S390_DEVICE(dev); + SCLPEventFacility *sdev = EVENT_FACILITY(dev); - sdev->ef->receive_mask = 0; + sdev->receive_mask = 0; } static void init_event_facility_class(ObjectClass *klass, void *data) { - DeviceClass *dc = DEVICE_CLASS(klass); - S390SCLPDeviceClass *k = SCLP_S390_DEVICE_CLASS(klass); + SysBusDeviceClass *sbdc = SYS_BUS_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(sbdc); + SCLPEventFacilityClass *k = EVENT_FACILITY_CLASS(dc); dc->reset = reset_event_facility; + dc->vmsd = &vmstate_event_facility; k->init = init_event_facility; + k->command_handler = command_handler; + k->event_pending = event_pending; } -static const TypeInfo s390_sclp_event_facility_info = { - .name = "s390-sclp-event-facility", - .parent = TYPE_DEVICE_S390_SCLP, - .instance_size = sizeof(S390SCLPDevice), +static const TypeInfo sclp_event_facility_info = { + .name = TYPE_SCLP_EVENT_FACILITY, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(SCLPEventFacility), .class_init = init_event_facility_class, + .class_size = sizeof(SCLPEventFacilityClass), }; -static int event_qdev_init(DeviceState *qdev) +static void event_realize(DeviceState *qdev, Error **errp) { - SCLPEvent *event = DO_UPCAST(SCLPEvent, qdev, qdev); + SCLPEvent *event = SCLP_EVENT(qdev); SCLPEventClass *child = SCLP_EVENT_GET_CLASS(event); - return child->init(event); + if (child->init) { + int rc = child->init(event); + if (rc < 0) { + error_setg(errp, "SCLP event initialization failed."); + return; + } + } } -static int event_qdev_exit(DeviceState *qdev) +static void event_unrealize(DeviceState *qdev, Error **errp) { - SCLPEvent *event = DO_UPCAST(SCLPEvent, qdev, qdev); + SCLPEvent *event = SCLP_EVENT(qdev); SCLPEventClass *child = SCLP_EVENT_GET_CLASS(event); if (child->exit) { - child->exit(event); + int rc = child->exit(event); + if (rc < 0) { + error_setg(errp, "SCLP event exit failed."); + return; + } } - return 0; } static void event_class_init(ObjectClass *klass, void *data) @@ -391,11 +410,11 @@ static void event_class_init(ObjectClass *klass, void *data) dc->bus_type = TYPE_SCLP_EVENTS_BUS; dc->unplug = qdev_simple_unplug_cb; - dc->init = event_qdev_init; - dc->exit = event_qdev_exit; + dc->realize = event_realize; + dc->unrealize = event_unrealize; } -static const TypeInfo s390_sclp_event_type_info = { +static const TypeInfo sclp_event_type_info = { .name = TYPE_SCLP_EVENT, .parent = TYPE_DEVICE, .instance_size = sizeof(SCLPEvent), @@ -406,9 +425,9 @@ static const TypeInfo s390_sclp_event_type_info = { static void register_types(void) { - type_register_static(&s390_sclp_events_bus_info); - type_register_static(&s390_sclp_event_facility_info); - type_register_static(&s390_sclp_event_type_info); + type_register_static(&sclp_events_bus_info); + type_register_static(&sclp_event_facility_info); + type_register_static(&sclp_event_type_info); } type_init(register_types) diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c index 1a6397b88e..32d38a08f6 100644 --- a/hw/s390x/ipl.c +++ b/hw/s390x/ipl.c @@ -95,24 +95,29 @@ static int s390_ipl_init(SysBusDevice *dev) } return 0; } else { - kernel_size = load_elf(ipl->kernel, NULL, NULL, NULL, NULL, + uint64_t pentry = KERN_IMAGE_START; + kernel_size = load_elf(ipl->kernel, NULL, NULL, &pentry, NULL, NULL, 1, ELF_MACHINE, 0); - if (kernel_size == -1) { + if (kernel_size < 0) { kernel_size = load_image_targphys(ipl->kernel, 0, ram_size); } - if (kernel_size == -1) { + if (kernel_size < 0) { fprintf(stderr, "could not load kernel '%s'\n", ipl->kernel); return -1; } - /* we have to overwrite values in the kernel image, which are "rom" */ - strcpy(rom_ptr(KERN_PARM_AREA), ipl->cmdline); - /* - * we can not rely on the ELF entry point, since up to 3.2 this - * value was 0x800 (the SALIPL loader) and it wont work. For - * all (Linux) cases 0x10000 (KERN_IMAGE_START) should be fine. + * Is it a Linux kernel (starting at 0x10000)? If yes, we fill in the + * kernel parameters here as well. Note: For old kernels (up to 3.2) + * we can not rely on the ELF entry point - it was 0x800 (the SALIPL + * loader) and it won't work. For this case we force it to 0x10000, too. */ - ipl->start_addr = KERN_IMAGE_START; + if (pentry == KERN_IMAGE_START || pentry == 0x800) { + ipl->start_addr = KERN_IMAGE_START; + /* Overwrite parameters in the kernel image, which are "rom" */ + strcpy(rom_ptr(KERN_PARM_AREA), ipl->cmdline); + } else { + ipl->start_addr = pentry; + } } if (ipl->initrd) { ram_addr_t initrd_offset; diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c index 733d988871..0d4f6ae2f3 100644 --- a/hw/s390x/s390-virtio-ccw.c +++ b/hw/s390x/s390-virtio-ccw.c @@ -13,13 +13,14 @@ #include "exec/address-spaces.h" #include "s390-virtio.h" #include "hw/s390x/sclp.h" +#include "hw/s390x/s390_flic.h" #include "ioinst.h" #include "css.h" #include "virtio-ccw.h" void io_subsystem_reset(void) { - DeviceState *css, *sclp; + DeviceState *css, *sclp, *flic; css = DEVICE(object_resolve_path_type("", "virtual-css-bridge", NULL)); if (css) { @@ -30,6 +31,10 @@ void io_subsystem_reset(void) if (sclp) { qdev_reset_all(sclp); } + flic = DEVICE(object_resolve_path_type("", "s390-flic", NULL)); + if (flic) { + qdev_reset_all(flic); + } } static int virtio_ccw_hcall_notify(const uint64_t *args) @@ -99,6 +104,7 @@ static void ccw_init(QEMUMachineInitArgs *args) s390_sclp_init(); s390_init_ipl_dev(args->kernel_filename, args->kernel_cmdline, args->initrd_filename, "s390-ccw.img"); + s390_flic_init(); /* register hypercalls */ virtio_ccw_register_hcalls(); diff --git a/hw/s390x/s390-virtio-hcall.c b/hw/s390x/s390-virtio-hcall.c index ee626493c6..c7bdc2005d 100644 --- a/hw/s390x/s390-virtio-hcall.c +++ b/hw/s390x/s390-virtio-hcall.c @@ -26,11 +26,15 @@ void s390_register_virtio_hypercall(uint64_t code, s390_virtio_fn fn) int s390_virtio_hypercall(CPUS390XState *env) { - s390_virtio_fn fn = s390_diag500_table[env->regs[1]]; - - if (!fn) { - return -EINVAL; + s390_virtio_fn fn; + + if (env->regs[1] < MAX_DIAG_SUBCODES) { + fn = s390_diag500_table[env->regs[1]]; + if (fn) { + env->regs[2] = fn(&env->regs[2]); + return 0; + } } - return fn(&env->regs[2]); + return -EINVAL; } diff --git a/hw/s390x/s390-virtio.c b/hw/s390x/s390-virtio.c index 9eeda97920..0f03fd18b9 100644 --- a/hw/s390x/s390-virtio.c +++ b/hw/s390x/s390-virtio.c @@ -36,6 +36,7 @@ #include "hw/s390x/s390-virtio-bus.h" #include "hw/s390x/sclp.h" +#include "hw/s390x/s390_flic.h" #include "hw/s390x/s390-virtio.h" //#define DEBUG_S390 @@ -251,6 +252,7 @@ static void s390_init(QEMUMachineInitArgs *args) s390_sclp_init(); s390_init_ipl_dev(args->kernel_filename, args->kernel_cmdline, args->initrd_filename, ZIPL_FILENAME); + s390_flic_init(); /* register hypercalls */ s390_virtio_register_hcalls(); diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c index 4e0c564c5c..d8ddf35e58 100644 --- a/hw/s390x/sclp.c +++ b/hw/s390x/sclp.c @@ -18,11 +18,12 @@ #include "sysemu/sysemu.h" #include "hw/s390x/sclp.h" +#include "hw/s390x/event-facility.h" -static inline S390SCLPDevice *get_event_facility(void) +static inline SCLPEventFacility *get_event_facility(void) { ObjectProperty *op = object_property_find(qdev_get_machine(), - "s390-sclp-event-facility", + TYPE_SCLP_EVENT_FACILITY, NULL); assert(op); return op->opaque; @@ -89,9 +90,10 @@ static void sclp_read_cpu_info(SCCB *sccb) sccb->h.response_code = cpu_to_be16(SCLP_RC_NORMAL_READ_COMPLETION); } -static void sclp_execute(SCCB *sccb, uint64_t code) +static void sclp_execute(SCCB *sccb, uint32_t code) { - S390SCLPDevice *sdev = get_event_facility(); + SCLPEventFacility *ef = get_event_facility(); + SCLPEventFacilityClass *efc = EVENT_FACILITY_GET_CLASS(ef); switch (code & SCLP_CMD_CODE_MASK) { case SCLP_CMDW_READ_SCP_INFO: @@ -102,12 +104,12 @@ static void sclp_execute(SCCB *sccb, uint64_t code) sclp_read_cpu_info(sccb); break; default: - sdev->sclp_command_handler(sdev->ef, sccb, code); + efc->command_handler(ef, sccb, code); break; } } -int sclp_service_call(uint32_t sccb, uint64_t code) +int sclp_service_call(CPUS390XState *env, uint64_t sccb, uint32_t code) { int r = 0; SCCB work_sccb; @@ -115,11 +117,16 @@ int sclp_service_call(uint32_t sccb, uint64_t code) hwaddr sccb_len = sizeof(SCCB); /* first some basic checks on program checks */ + if (env->psw.mask & PSW_MASK_PSTATE) { + r = -PGM_PRIVILEGED; + goto out; + } if (cpu_physical_memory_is_io(sccb)) { r = -PGM_ADDRESSING; goto out; } - if (sccb & ~0x7ffffff8ul) { + if ((sccb & ~0x1fffUL) == 0 || (sccb & ~0x1fffUL) == env->psa + || (sccb & ~0x7ffffff8UL) != 0) { r = -PGM_SPECIFICATION; goto out; } @@ -151,11 +158,13 @@ out: void sclp_service_interrupt(uint32_t sccb) { - S390SCLPDevice *sdev = get_event_facility(); + SCLPEventFacility *ef = get_event_facility(); + SCLPEventFacilityClass *efc = EVENT_FACILITY_GET_CLASS(ef); + uint32_t param = sccb & ~3; /* Indicate whether an event is still pending */ - param |= sdev->event_pending(sdev->ef) ? 1 : 0; + param |= efc->event_pending(ef) ? 1 : 0; if (!param) { /* No need to send an interrupt, there's nothing to be notified about */ @@ -168,47 +177,9 @@ void sclp_service_interrupt(uint32_t sccb) void s390_sclp_init(void) { - DeviceState *dev = qdev_create(NULL, "s390-sclp-event-facility"); + DeviceState *dev = qdev_create(NULL, TYPE_SCLP_EVENT_FACILITY); - object_property_add_child(qdev_get_machine(), "s390-sclp-event-facility", + object_property_add_child(qdev_get_machine(), TYPE_SCLP_EVENT_FACILITY, OBJECT(dev), NULL); qdev_init_nofail(dev); } - -static int s390_sclp_dev_init(SysBusDevice *dev) -{ - int r; - S390SCLPDevice *sdev = (S390SCLPDevice *)dev; - S390SCLPDeviceClass *sclp = SCLP_S390_DEVICE_GET_CLASS(dev); - - r = sclp->init(sdev); - if (!r) { - assert(sdev->event_pending); - assert(sdev->sclp_command_handler); - } - - return r; -} - -static void s390_sclp_device_class_init(ObjectClass *klass, void *data) -{ - SysBusDeviceClass *dc = SYS_BUS_DEVICE_CLASS(klass); - - dc->init = s390_sclp_dev_init; -} - -static const TypeInfo s390_sclp_device_info = { - .name = TYPE_DEVICE_S390_SCLP, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(S390SCLPDevice), - .class_init = s390_sclp_device_class_init, - .class_size = sizeof(S390SCLPDeviceClass), - .abstract = true, -}; - -static void s390_sclp_register_types(void) -{ - type_register_static(&s390_sclp_device_info); -} - -type_init(s390_sclp_register_types) diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index f6e0e3e4ae..a01801e342 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -1,7 +1,7 @@ /* * virtio ccw target implementation * - * Copyright 2012 IBM Corp. + * Copyright 2012,2014 IBM Corp. * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com> * * This work is licensed under the terms of the GNU GPL, version 2 or (at @@ -188,6 +188,13 @@ typedef struct VirtioFeatDesc { uint8_t index; } QEMU_PACKED VirtioFeatDesc; +typedef struct VirtioThinintInfo { + hwaddr summary_indicator; + hwaddr device_indicator; + uint64_t ind_bit; + uint8_t isc; +} QEMU_PACKED VirtioThinintInfo; + /* Specify where the virtqueues for the subchannel are in guest memory. */ static int virtio_ccw_set_vqs(SubchDev *sch, uint64_t addr, uint32_t align, uint16_t index, uint16_t num) @@ -237,6 +244,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) bool check_len; int len; hwaddr hw_len; + VirtioThinintInfo *thinint; if (!dev) { return -EINVAL; @@ -428,6 +436,11 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) ret = -EINVAL; break; } + if (sch->thinint_active) { + /* Trigger a command reject. */ + ret = -ENOSYS; + break; + } if (!ccw.cda) { ret = -EFAULT; } else { @@ -480,6 +493,42 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) ret = 0; } break; + case CCW_CMD_SET_IND_ADAPTER: + if (check_len) { + if (ccw.count != sizeof(*thinint)) { + ret = -EINVAL; + break; + } + } else if (ccw.count < sizeof(*thinint)) { + /* Can't execute command. */ + ret = -EINVAL; + break; + } + len = sizeof(*thinint); + hw_len = len; + if (!ccw.cda) { + ret = -EFAULT; + } else if (dev->indicators && !sch->thinint_active) { + /* Trigger a command reject. */ + ret = -ENOSYS; + } else { + thinint = cpu_physical_memory_map(ccw.cda, &hw_len, 0); + if (!thinint) { + ret = -EFAULT; + } else { + len = hw_len; + dev->summary_indicator = thinint->summary_indicator; + dev->indicators = thinint->device_indicator; + dev->thinint_isc = thinint->isc; + dev->ind_bit = thinint->ind_bit; + cpu_physical_memory_unmap(thinint, hw_len, 0, hw_len); + sch->thinint_active = ((dev->indicators != 0) && + (dev->summary_indicator != 0)); + sch->curr_status.scsw.count = ccw.count - len; + ret = 0; + } + } + break; default: ret = -ENOSYS; break; @@ -511,6 +560,7 @@ static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev) sch->channel_prog = 0x0; sch->last_cmd_valid = false; sch->orb = NULL; + sch->thinint_active = false; /* * Use a device number if provided. Otherwise, fall back to subchannel * number. @@ -858,6 +908,28 @@ static inline VirtioCcwDevice *to_virtio_ccw_dev_fast(DeviceState *d) return container_of(d, VirtioCcwDevice, parent_obj); } +static uint8_t virtio_set_ind_atomic(SubchDev *sch, uint64_t ind_loc, + uint8_t to_be_set) +{ + uint8_t ind_old, ind_new; + hwaddr len = 1; + uint8_t *ind_addr; + + ind_addr = cpu_physical_memory_map(ind_loc, &len, 1); + if (!ind_addr) { + error_report("%s(%x.%x.%04x): unable to access indicator", + __func__, sch->cssid, sch->ssid, sch->schid); + return -1; + } + do { + ind_old = *ind_addr; + ind_new = ind_old | to_be_set; + } while (atomic_cmpxchg(ind_addr, ind_old, ind_new) != ind_old); + cpu_physical_memory_unmap(ind_addr, len, 1, len); + + return ind_old; +} + static void virtio_ccw_notify(DeviceState *d, uint16_t vector) { VirtioCcwDevice *dev = to_virtio_ccw_dev_fast(d); @@ -872,9 +944,26 @@ static void virtio_ccw_notify(DeviceState *d, uint16_t vector) if (!dev->indicators) { return; } - indicators = ldq_phys(&address_space_memory, dev->indicators); - indicators |= 1ULL << vector; - stq_phys(&address_space_memory, dev->indicators, indicators); + if (sch->thinint_active) { + /* + * In the adapter interrupt case, indicators points to a + * memory area that may be (way) larger than 64 bit and + * ind_bit indicates the start of the indicators in a big + * endian notation. + */ + virtio_set_ind_atomic(sch, dev->indicators + + (dev->ind_bit + vector) / 8, + 0x80 >> ((dev->ind_bit + vector) % 8)); + if (!virtio_set_ind_atomic(sch, dev->summary_indicator, + 0x01)) { + css_adapter_interrupt(dev->thinint_isc); + } + } else { + indicators = ldq_phys(&address_space_memory, dev->indicators); + indicators |= 1ULL << vector; + stq_phys(&address_space_memory, dev->indicators, indicators); + css_conditional_io_interrupt(sch); + } } else { if (!dev->indicators2) { return; @@ -883,10 +972,8 @@ static void virtio_ccw_notify(DeviceState *d, uint16_t vector) indicators = ldq_phys(&address_space_memory, dev->indicators2); indicators |= 1ULL << vector; stq_phys(&address_space_memory, dev->indicators2, indicators); + css_conditional_io_interrupt(sch); } - - css_conditional_io_interrupt(sch); - } static unsigned virtio_ccw_get_features(DeviceState *d) @@ -907,6 +994,7 @@ static void virtio_ccw_reset(DeviceState *d) css_reset_sch(dev->sch); dev->indicators = 0; dev->indicators2 = 0; + dev->summary_indicator = 0; } static void virtio_ccw_vmstate_change(DeviceState *d, bool running) diff --git a/hw/s390x/virtio-ccw.h b/hw/s390x/virtio-ccw.h index 00932c746d..4393e44814 100644 --- a/hw/s390x/virtio-ccw.h +++ b/hw/s390x/virtio-ccw.h @@ -38,6 +38,7 @@ #define CCW_CMD_SET_IND 0x43 #define CCW_CMD_SET_CONF_IND 0x53 #define CCW_CMD_READ_VQ_CONF 0x32 +#define CCW_CMD_SET_IND_ADAPTER 0x73 #define TYPE_VIRTIO_CCW_DEVICE "virtio-ccw-device" #define VIRTIO_CCW_DEVICE(obj) \ @@ -83,9 +84,12 @@ struct VirtioCcwDevice { bool ioeventfd_started; bool ioeventfd_disabled; uint32_t flags; + uint8_t thinint_isc; /* Guest provided values: */ hwaddr indicators; hwaddr indicators2; + hwaddr summary_indicator; + uint64_t ind_bit; }; /* virtual css bus type */ |