xref: /qemu/include/hw/s390x/s390_flic.h (revision 84aacddd)
13a553fc6SJens Freimann /*
27b35d0c4SCornelia Huck  * QEMU S390x floating interrupt controller (flic)
33a553fc6SJens Freimann  *
43a553fc6SJens Freimann  * Copyright 2014 IBM Corp.
53a553fc6SJens Freimann  * Author(s): Jens Freimann <jfrei@linux.vnet.ibm.com>
67b35d0c4SCornelia Huck  *            Cornelia Huck <cornelia.huck@de.ibm.com>
73a553fc6SJens Freimann  *
83a553fc6SJens Freimann  * This work is licensed under the terms of the GNU GPL, version 2 or (at
93a553fc6SJens Freimann  * your option) any later version. See the COPYING file in the top-level
103a553fc6SJens Freimann  * directory.
113a553fc6SJens Freimann  */
123a553fc6SJens Freimann 
132a6a4076SMarkus Armbruster #ifndef HW_S390_FLIC_H
142a6a4076SMarkus Armbruster #define HW_S390_FLIC_H
153a553fc6SJens Freimann 
163a553fc6SJens Freimann #include "hw/sysbus.h"
17d426d9fbSCornelia Huck #include "hw/s390x/adapter.h"
18d426d9fbSCornelia Huck #include "hw/virtio/virtio.h"
19b194e447SDavid Hildenbrand #include "qemu/queue.h"
20db1015e9SEduardo Habkost #include "qom/object.h"
21d426d9fbSCornelia Huck 
22069097daSHalil Pasic /*
23069097daSHalil Pasic  * Reserve enough gsis to accommodate all virtio devices.
24069097daSHalil Pasic  * If any other user of adapter routes needs more of these,
25069097daSHalil Pasic  * we need to bump the value; but virtio looks like the
26069097daSHalil Pasic  * maximum right now.
27069097daSHalil Pasic  */
28069097daSHalil Pasic #define ADAPTER_ROUTES_MAX_GSI VIRTIO_QUEUE_MAX
298dfbaa6aSJason Wang 
30d426d9fbSCornelia Huck typedef struct AdapterRoutes {
31d426d9fbSCornelia Huck     AdapterInfo adapter;
32d426d9fbSCornelia Huck     int num_routes;
338dfbaa6aSJason Wang     int gsi[ADAPTER_ROUTES_MAX_GSI];
34d426d9fbSCornelia Huck } AdapterRoutes;
353a553fc6SJens Freimann 
36517ff12cSHalil Pasic extern const VMStateDescription vmstate_adapter_routes;
37517ff12cSHalil Pasic 
387b35d0c4SCornelia Huck #define TYPE_S390_FLIC_COMMON "s390-flic"
39c821774aSEduardo Habkost OBJECT_DECLARE_TYPE(S390FLICState, S390FLICStateClass,
4030b5707cSEduardo Habkost                     S390_FLIC_COMMON)
417b35d0c4SCornelia Huck 
42db1015e9SEduardo Habkost struct S390FLICState {
437b35d0c4SCornelia Huck     SysBusDevice parent_obj;
44e61cc6b5SHalil Pasic     /* to limit AdapterRoutes.num_routes for compat */
45e61cc6b5SHalil Pasic     uint32_t adapter_routes_max_batch;
466c1dd652SFei Li     bool ais_supported;
47*9d1b0f5bSPaolo Bonzini     bool migration_enabled;
48db1015e9SEduardo Habkost };
497b35d0c4SCornelia Huck 
507b35d0c4SCornelia Huck 
51db1015e9SEduardo Habkost struct S390FLICStateClass {
527b35d0c4SCornelia Huck     DeviceClass parent_class;
537b35d0c4SCornelia Huck 
5403cf077aSCornelia Huck     int (*register_io_adapter)(S390FLICState *fs, uint32_t id, uint8_t isc,
551497c160SFei Li                                bool swap, bool maskable, uint8_t flags);
56d426d9fbSCornelia Huck     int (*io_adapter_map)(S390FLICState *fs, uint32_t id, uint64_t map_addr,
57d426d9fbSCornelia Huck                           bool do_map);
58d426d9fbSCornelia Huck     int (*add_adapter_routes)(S390FLICState *fs, AdapterRoutes *routes);
59d426d9fbSCornelia Huck     void (*release_adapter_routes)(S390FLICState *fs, AdapterRoutes *routes);
609eccb862SHalil Pasic     int (*clear_io_irq)(S390FLICState *fs, uint16_t subchannel_id,
619eccb862SHalil Pasic                         uint16_t subchannel_nr);
626c1dd652SFei Li     int (*modify_ais_mode)(S390FLICState *fs, uint8_t isc, uint16_t mode);
631622ffd5SYi Min Zhao     int (*inject_airq)(S390FLICState *fs, uint8_t type, uint8_t isc,
641622ffd5SYi Min Zhao                        uint8_t flags);
65e6505d53SDavid Hildenbrand     void (*inject_service)(S390FLICState *fs, uint32_t parm);
66e6505d53SDavid Hildenbrand     void (*inject_io)(S390FLICState *fs, uint16_t subchannel_id,
67e6505d53SDavid Hildenbrand                       uint16_t subchannel_nr, uint32_t io_int_parm,
68e6505d53SDavid Hildenbrand                       uint32_t io_int_word);
69e6505d53SDavid Hildenbrand     void (*inject_crw_mchk)(S390FLICState *fs);
70db1015e9SEduardo Habkost };
717b35d0c4SCornelia Huck 
727b35d0c4SCornelia Huck #define TYPE_KVM_S390_FLIC "s390-flic-kvm"
73b13f9bdfSEduardo Habkost typedef struct KVMS390FLICState KVMS390FLICState;
748110fa1dSEduardo Habkost DECLARE_INSTANCE_CHECKER(KVMS390FLICState, KVM_S390_FLIC,
758110fa1dSEduardo Habkost                          TYPE_KVM_S390_FLIC)
763a553fc6SJens Freimann 
777b35d0c4SCornelia Huck #define TYPE_QEMU_S390_FLIC "s390-flic-qemu"
788063396bSEduardo Habkost OBJECT_DECLARE_SIMPLE_TYPE(QEMUS390FLICState, QEMU_S390_FLIC)
793a553fc6SJens Freimann 
806c1dd652SFei Li #define SIC_IRQ_MODE_ALL 0
816c1dd652SFei Li #define SIC_IRQ_MODE_SINGLE 1
826c1dd652SFei Li #define AIS_MODE_MASK(isc) (0x80 >> isc)
836c1dd652SFei Li 
84b194e447SDavid Hildenbrand #define ISC_TO_PENDING_IO(_isc) (0x80 >> (_isc))
85b194e447SDavid Hildenbrand #define CR6_TO_PENDING_IO(_cr6) (((_cr6) >> 24) & 0xff)
86b194e447SDavid Hildenbrand 
87b194e447SDavid Hildenbrand /* organize the ISC bits so that the macros above work */
88b194e447SDavid Hildenbrand #define FLIC_PENDING_IO_ISC7            (1 << 0)
89b194e447SDavid Hildenbrand #define FLIC_PENDING_IO_ISC6            (1 << 1)
90b194e447SDavid Hildenbrand #define FLIC_PENDING_IO_ISC5            (1 << 2)
91b194e447SDavid Hildenbrand #define FLIC_PENDING_IO_ISC4            (1 << 3)
92b194e447SDavid Hildenbrand #define FLIC_PENDING_IO_ISC3            (1 << 4)
93b194e447SDavid Hildenbrand #define FLIC_PENDING_IO_ISC2            (1 << 5)
94b194e447SDavid Hildenbrand #define FLIC_PENDING_IO_ISC1            (1 << 6)
95b194e447SDavid Hildenbrand #define FLIC_PENDING_IO_ISC0            (1 << 7)
96b194e447SDavid Hildenbrand #define FLIC_PENDING_SERVICE            (1 << 8)
97b194e447SDavid Hildenbrand #define FLIC_PENDING_MCHK_CR            (1 << 9)
98b194e447SDavid Hildenbrand 
99b194e447SDavid Hildenbrand #define FLIC_PENDING_IO (FLIC_PENDING_IO_ISC0 | FLIC_PENDING_IO_ISC1 | \
100b194e447SDavid Hildenbrand                          FLIC_PENDING_IO_ISC2 | FLIC_PENDING_IO_ISC3 | \
101b194e447SDavid Hildenbrand                          FLIC_PENDING_IO_ISC4 | FLIC_PENDING_IO_ISC5 | \
102b194e447SDavid Hildenbrand                          FLIC_PENDING_IO_ISC6 | FLIC_PENDING_IO_ISC7)
103b194e447SDavid Hildenbrand 
104b194e447SDavid Hildenbrand typedef struct QEMUS390FlicIO {
105b194e447SDavid Hildenbrand     uint16_t id;
106b194e447SDavid Hildenbrand     uint16_t nr;
107b194e447SDavid Hildenbrand     uint32_t parm;
108b194e447SDavid Hildenbrand     uint32_t word;
109b194e447SDavid Hildenbrand     QLIST_ENTRY(QEMUS390FlicIO) next;
110b194e447SDavid Hildenbrand } QEMUS390FlicIO;
111b194e447SDavid Hildenbrand 
112db1015e9SEduardo Habkost struct QEMUS390FLICState {
1137b35d0c4SCornelia Huck     S390FLICState parent_obj;
114b194e447SDavid Hildenbrand     uint32_t pending;
115b194e447SDavid Hildenbrand     uint32_t service_param;
1166c1dd652SFei Li     uint8_t simm;
1176c1dd652SFei Li     uint8_t nimm;
118b194e447SDavid Hildenbrand     QLIST_HEAD(, QEMUS390FlicIO) io[8];
119db1015e9SEduardo Habkost };
1207b35d0c4SCornelia Huck 
121b194e447SDavid Hildenbrand uint32_t qemu_s390_flic_dequeue_service(QEMUS390FLICState *flic);
122b194e447SDavid Hildenbrand QEMUS390FlicIO *qemu_s390_flic_dequeue_io(QEMUS390FLICState *flic,
123b194e447SDavid Hildenbrand                                           uint64_t cr6);
124b194e447SDavid Hildenbrand void qemu_s390_flic_dequeue_crw_mchk(QEMUS390FLICState *flic);
125b194e447SDavid Hildenbrand bool qemu_s390_flic_has_service(QEMUS390FLICState *flic);
126b194e447SDavid Hildenbrand bool qemu_s390_flic_has_io(QEMUS390FLICState *fs, uint64_t cr6);
127b194e447SDavid Hildenbrand bool qemu_s390_flic_has_crw_mchk(QEMUS390FLICState *flic);
128b194e447SDavid Hildenbrand bool qemu_s390_flic_has_any(QEMUS390FLICState *flic);
129b194e447SDavid Hildenbrand 
1307b35d0c4SCornelia Huck void s390_flic_init(void);
1317b35d0c4SCornelia Huck 
1327b35d0c4SCornelia Huck S390FLICState *s390_get_flic(void);
133f68ecdd4SDavid Hildenbrand QEMUS390FLICState *s390_get_qemu_flic(S390FLICState *fs);
1346762808fSDavid Hildenbrand S390FLICStateClass *s390_get_flic_class(S390FLICState *fs);
135d4c603d7SGerd Hoffmann void s390_crw_mchk(void);
136d4c603d7SGerd Hoffmann void s390_io_interrupt(uint16_t subchannel_id, uint16_t subchannel_nr,
137d4c603d7SGerd Hoffmann                        uint32_t io_int_parm, uint32_t io_int_word);
138e7be8d49SYi Min Zhao bool ais_needed(void *opaque);
1393a553fc6SJens Freimann 
1402a6a4076SMarkus Armbruster #endif /* HW_S390_FLIC_H */
141