qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

sclpcpu.c (2668B)


      1 /*
      2  * SCLP event type
      3  *    Signal CPU - Trigger SCLP interrupt for system CPU configure or
      4  *    de-configure
      5  *
      6  * Copyright IBM, Corp. 2013
      7  *
      8  * Authors:
      9  *  Thang Pham <thang.pham@us.ibm.com>
     10  *
     11  * This work is licensed under the terms of the GNU GPL, version 2 or (at your
     12  * option) any later version.  See the COPYING file in the top-level directory.
     13  *
     14  */
     15 
     16 #include "qemu/osdep.h"
     17 #include "hw/s390x/sclp.h"
     18 #include "qemu/module.h"
     19 #include "hw/s390x/event-facility.h"
     20 #include "sysemu/cpus.h"
     21 
     22 typedef struct ConfigMgtData {
     23     EventBufferHeader ebh;
     24     uint8_t reserved;
     25     uint8_t event_qualifier;
     26 } QEMU_PACKED ConfigMgtData;
     27 
     28 #define EVENT_QUAL_CPU_CHANGE  1
     29 
     30 void raise_irq_cpu_hotplug(void)
     31 {
     32     Object *obj = object_resolve_path_type("", TYPE_SCLP_CPU_HOTPLUG, NULL);
     33 
     34     SCLP_EVENT(obj)->event_pending = true;
     35 
     36     /* Trigger SCLP read operation */
     37     sclp_service_interrupt(0);
     38 }
     39 
     40 static sccb_mask_t send_mask(void)
     41 {
     42     return SCLP_EVENT_MASK_CONFIG_MGT_DATA;
     43 }
     44 
     45 static sccb_mask_t receive_mask(void)
     46 {
     47     return 0;
     48 }
     49 
     50 static int read_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr,
     51                            int *slen)
     52 {
     53     ConfigMgtData *cdata = (ConfigMgtData *) evt_buf_hdr;
     54     if (*slen < sizeof(ConfigMgtData)) {
     55         return 0;
     56     }
     57 
     58     /* Event is no longer pending */
     59     if (!event->event_pending) {
     60         return 0;
     61     }
     62     event->event_pending = false;
     63 
     64     /* Event header data */
     65     cdata->ebh.length = cpu_to_be16(sizeof(ConfigMgtData));
     66     cdata->ebh.type = SCLP_EVENT_CONFIG_MGT_DATA;
     67     cdata->ebh.flags |= SCLP_EVENT_BUFFER_ACCEPTED;
     68 
     69     /* Trigger a rescan of CPUs by setting event qualifier */
     70     cdata->event_qualifier = EVENT_QUAL_CPU_CHANGE;
     71     *slen -= sizeof(ConfigMgtData);
     72 
     73     return 1;
     74 }
     75 
     76 static void cpu_class_init(ObjectClass *oc, void *data)
     77 {
     78     SCLPEventClass *k = SCLP_EVENT_CLASS(oc);
     79     DeviceClass *dc = DEVICE_CLASS(oc);
     80 
     81     k->get_send_mask = send_mask;
     82     k->get_receive_mask = receive_mask;
     83     k->read_event_data = read_event_data;
     84     set_bit(DEVICE_CATEGORY_MISC, dc->categories);
     85     /*
     86      * Reason: raise_irq_cpu_hotplug() depends on an unique
     87      * TYPE_SCLP_CPU_HOTPLUG device, which is already created
     88      * by the sclp event facility
     89      */
     90     dc->user_creatable = false;
     91 }
     92 
     93 static const TypeInfo sclp_cpu_info = {
     94     .name          = TYPE_SCLP_CPU_HOTPLUG,
     95     .parent        = TYPE_SCLP_EVENT,
     96     .instance_size = sizeof(SCLPEvent),
     97     .class_init    = cpu_class_init,
     98     .class_size    = sizeof(SCLPEventClass),
     99 };
    100 
    101 static void sclp_cpu_register_types(void)
    102 {
    103     type_register_static(&sclp_cpu_info);
    104 }
    105 
    106 type_init(sclp_cpu_register_types)