1 /* 2 * QEMU PowerPC pSeries Logical Partition (aka sPAPR) hardware System Emulator 3 * 4 * PAPR Virtualized Interrupt System, aka ICS/ICP aka xics 5 * 6 * Copyright (c) 2010,2011 David Gibson, IBM Corporation. 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a copy 9 * of this software and associated documentation files (the "Software"), to deal 10 * in the Software without restriction, including without limitation the rights 11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 * copies of the Software, and to permit persons to whom the Software is 13 * furnished to do so, subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice shall be included in 16 * all copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 * THE SOFTWARE. 25 * 26 */ 27 28 #ifndef XICS_H 29 #define XICS_H 30 31 #include "hw/sysbus.h" 32 33 #define TYPE_XICS_COMMON "xics-common" 34 #define XICS_COMMON(obj) OBJECT_CHECK(XICSState, (obj), TYPE_XICS_COMMON) 35 36 /* 37 * Retain xics as the type name to be compatible for migration. Rest all the 38 * functions, class and variables are renamed as xics_spapr. 39 */ 40 #define TYPE_XICS_SPAPR "xics" 41 #define XICS_SPAPR(obj) OBJECT_CHECK(XICSState, (obj), TYPE_XICS_SPAPR) 42 43 #define TYPE_XICS_SPAPR_KVM "xics-spapr-kvm" 44 #define XICS_SPAPR_KVM(obj) \ 45 OBJECT_CHECK(KVMXICSState, (obj), TYPE_XICS_SPAPR_KVM) 46 47 #define XICS_COMMON_CLASS(klass) \ 48 OBJECT_CLASS_CHECK(XICSStateClass, (klass), TYPE_XICS_COMMON) 49 #define XICS_SPAPR_CLASS(klass) \ 50 OBJECT_CLASS_CHECK(XICSStateClass, (klass), TYPE_XICS_SPAPR) 51 #define XICS_COMMON_GET_CLASS(obj) \ 52 OBJECT_GET_CLASS(XICSStateClass, (obj), TYPE_XICS_COMMON) 53 #define XICS_SPAPR_GET_CLASS(obj) \ 54 OBJECT_GET_CLASS(XICSStateClass, (obj), TYPE_XICS_SPAPR) 55 56 #define XICS_IPI 0x2 57 #define XICS_BUID 0x1 58 #define XICS_IRQ_BASE (XICS_BUID << 12) 59 60 /* 61 * We currently only support one BUID which is our interrupt base 62 * (the kernel implementation supports more but we don't exploit 63 * that yet) 64 */ 65 typedef struct XICSStateClass XICSStateClass; 66 typedef struct XICSState XICSState; 67 typedef struct ICPStateClass ICPStateClass; 68 typedef struct ICPState ICPState; 69 typedef struct ICSStateClass ICSStateClass; 70 typedef struct ICSState ICSState; 71 typedef struct ICSIRQState ICSIRQState; 72 typedef struct XICSFabric XICSFabric; 73 74 struct XICSStateClass { 75 DeviceClass parent_class; 76 }; 77 78 struct XICSState { 79 /*< private >*/ 80 DeviceState parent_obj; 81 /*< public >*/ 82 }; 83 84 #define TYPE_ICP "icp" 85 #define ICP(obj) OBJECT_CHECK(ICPState, (obj), TYPE_ICP) 86 87 #define TYPE_KVM_ICP "icp-kvm" 88 #define KVM_ICP(obj) OBJECT_CHECK(ICPState, (obj), TYPE_KVM_ICP) 89 90 #define ICP_CLASS(klass) \ 91 OBJECT_CLASS_CHECK(ICPStateClass, (klass), TYPE_ICP) 92 #define ICP_GET_CLASS(obj) \ 93 OBJECT_GET_CLASS(ICPStateClass, (obj), TYPE_ICP) 94 95 struct ICPStateClass { 96 DeviceClass parent_class; 97 98 void (*pre_save)(ICPState *s); 99 int (*post_load)(ICPState *s, int version_id); 100 void (*cpu_setup)(ICPState *icp, PowerPCCPU *cpu); 101 }; 102 103 struct ICPState { 104 /*< private >*/ 105 DeviceState parent_obj; 106 /*< public >*/ 107 CPUState *cs; 108 ICSState *xirr_owner; 109 uint32_t xirr; 110 uint8_t pending_priority; 111 uint8_t mfrr; 112 qemu_irq output; 113 bool cap_irq_xics_enabled; 114 115 XICSFabric *xics; 116 }; 117 118 #define TYPE_ICS_BASE "ics-base" 119 #define ICS_BASE(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_BASE) 120 121 /* Retain ics for sPAPR for migration from existing sPAPR guests */ 122 #define TYPE_ICS_SIMPLE "ics" 123 #define ICS_SIMPLE(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_SIMPLE) 124 125 #define TYPE_ICS_KVM "icskvm" 126 #define ICS_KVM(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_KVM) 127 128 #define ICS_BASE_CLASS(klass) \ 129 OBJECT_CLASS_CHECK(ICSStateClass, (klass), TYPE_ICS_BASE) 130 #define ICS_BASE_GET_CLASS(obj) \ 131 OBJECT_GET_CLASS(ICSStateClass, (obj), TYPE_ICS_BASE) 132 133 struct ICSStateClass { 134 DeviceClass parent_class; 135 136 void (*realize)(DeviceState *dev, Error **errp); 137 void (*pre_save)(ICSState *s); 138 int (*post_load)(ICSState *s, int version_id); 139 void (*reject)(ICSState *s, uint32_t irq); 140 void (*resend)(ICSState *s); 141 void (*eoi)(ICSState *s, uint32_t irq); 142 }; 143 144 struct ICSState { 145 /*< private >*/ 146 DeviceState parent_obj; 147 /*< public >*/ 148 uint32_t nr_irqs; 149 uint32_t offset; 150 qemu_irq *qirqs; 151 ICSIRQState *irqs; 152 XICSFabric *xics; 153 }; 154 155 static inline bool ics_valid_irq(ICSState *ics, uint32_t nr) 156 { 157 return (ics->offset != 0) && (nr >= ics->offset) 158 && (nr < (ics->offset + ics->nr_irqs)); 159 } 160 161 struct ICSIRQState { 162 uint32_t server; 163 uint8_t priority; 164 uint8_t saved_priority; 165 #define XICS_STATUS_ASSERTED 0x1 166 #define XICS_STATUS_SENT 0x2 167 #define XICS_STATUS_REJECTED 0x4 168 #define XICS_STATUS_MASKED_PENDING 0x8 169 uint8_t status; 170 /* (flags & XICS_FLAGS_IRQ_MASK) == 0 means the interrupt is not allocated */ 171 #define XICS_FLAGS_IRQ_LSI 0x1 172 #define XICS_FLAGS_IRQ_MSI 0x2 173 #define XICS_FLAGS_IRQ_MASK 0x3 174 uint8_t flags; 175 }; 176 177 typedef struct XICSFabric { 178 Object parent; 179 } XICSFabric; 180 181 #define TYPE_XICS_FABRIC "xics-fabric" 182 #define XICS_FABRIC(obj) \ 183 OBJECT_CHECK(XICSFabric, (obj), TYPE_XICS_FABRIC) 184 #define XICS_FABRIC_CLASS(klass) \ 185 OBJECT_CLASS_CHECK(XICSFabricClass, (klass), TYPE_XICS_FABRIC) 186 #define XICS_FABRIC_GET_CLASS(obj) \ 187 OBJECT_GET_CLASS(XICSFabricClass, (obj), TYPE_XICS_FABRIC) 188 189 typedef struct XICSFabricClass { 190 InterfaceClass parent; 191 ICSState *(*ics_get)(XICSFabric *xi, int irq); 192 void (*ics_resend)(XICSFabric *xi); 193 ICPState *(*icp_get)(XICSFabric *xi, int server); 194 void (*icp_resend)(XICSFabric *xi); 195 } XICSFabricClass; 196 197 #define XICS_IRQS_SPAPR 1024 198 199 int spapr_ics_alloc(ICSState *ics, int irq_hint, bool lsi, Error **errp); 200 int spapr_ics_alloc_block(ICSState *ics, int num, bool lsi, bool align, 201 Error **errp); 202 void spapr_ics_free(ICSState *ics, int irq, int num); 203 void spapr_dt_xics(int nr_servers, void *fdt, uint32_t phandle); 204 205 qemu_irq xics_get_qirq(XICSFabric *xi, int irq); 206 ICPState *xics_icp_get(XICSFabric *xi, int server); 207 void xics_cpu_setup(XICSFabric *xi, PowerPCCPU *cpu); 208 void xics_cpu_destroy(XICSFabric *xi, PowerPCCPU *cpu); 209 210 /* Internal XICS interfaces */ 211 int xics_get_cpu_index_by_dt_id(int cpu_dt_id); 212 213 void icp_set_cppr(ICPState *icp, uint8_t cppr); 214 void icp_set_mfrr(ICPState *icp, uint8_t mfrr); 215 uint32_t icp_accept(ICPState *ss); 216 uint32_t icp_ipoll(ICPState *ss, uint32_t *mfrr); 217 void icp_eoi(ICPState *icp, uint32_t xirr); 218 219 void ics_simple_write_xive(ICSState *ics, int nr, int server, 220 uint8_t priority, uint8_t saved_priority); 221 222 void ics_set_irq_type(ICSState *ics, int srcno, bool lsi); 223 224 void ics_resend(ICSState *ics); 225 void icp_resend(ICPState *ss); 226 227 #endif /* XICS_H */ 228