]>
Commit | Line | Data |
---|---|---|
b5cec4c5 DG |
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 | */ | |
2a6a4076 MA |
27 | |
28 | #ifndef XICS_H | |
29 | #define XICS_H | |
b5cec4c5 | 30 | |
c04d6cfa AL |
31 | #include "hw/sysbus.h" |
32 | ||
5a3d7b23 AK |
33 | #define TYPE_XICS_COMMON "xics-common" |
34 | #define XICS_COMMON(obj) OBJECT_CHECK(XICSState, (obj), TYPE_XICS_COMMON) | |
35 | ||
161deaf2 BH |
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) | |
c04d6cfa | 42 | |
161deaf2 BH |
43 | #define TYPE_XICS_SPAPR_KVM "xics-spapr-kvm" |
44 | #define XICS_SPAPR_KVM(obj) \ | |
45 | OBJECT_CHECK(KVMXICSState, (obj), TYPE_XICS_SPAPR_KVM) | |
11ad93f6 | 46 | |
5a3d7b23 AK |
47 | #define XICS_COMMON_CLASS(klass) \ |
48 | OBJECT_CLASS_CHECK(XICSStateClass, (klass), TYPE_XICS_COMMON) | |
161deaf2 BH |
49 | #define XICS_SPAPR_CLASS(klass) \ |
50 | OBJECT_CLASS_CHECK(XICSStateClass, (klass), TYPE_XICS_SPAPR) | |
5a3d7b23 AK |
51 | #define XICS_COMMON_GET_CLASS(obj) \ |
52 | OBJECT_GET_CLASS(XICSStateClass, (obj), TYPE_XICS_COMMON) | |
161deaf2 BH |
53 | #define XICS_SPAPR_GET_CLASS(obj) \ |
54 | OBJECT_GET_CLASS(XICSStateClass, (obj), TYPE_XICS_SPAPR) | |
5a3d7b23 | 55 | |
b5cec4c5 | 56 | #define XICS_IPI 0x2 |
c04d6cfa AL |
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 | */ | |
5a3d7b23 | 65 | typedef struct XICSStateClass XICSStateClass; |
c04d6cfa | 66 | typedef struct XICSState XICSState; |
d1b5682d | 67 | typedef struct ICPStateClass ICPStateClass; |
c04d6cfa | 68 | typedef struct ICPState ICPState; |
d1b5682d | 69 | typedef struct ICSStateClass ICSStateClass; |
c04d6cfa AL |
70 | typedef struct ICSState ICSState; |
71 | typedef struct ICSIRQState ICSIRQState; | |
72 | ||
5a3d7b23 AK |
73 | struct XICSStateClass { |
74 | DeviceClass parent_class; | |
75 | ||
5eb92ccc | 76 | void (*cpu_setup)(XICSState *icp, PowerPCCPU *cpu); |
5a3d7b23 AK |
77 | }; |
78 | ||
c04d6cfa AL |
79 | struct XICSState { |
80 | /*< private >*/ | |
738d5db8 | 81 | DeviceState parent_obj; |
c04d6cfa AL |
82 | /*< public >*/ |
83 | uint32_t nr_servers; | |
c04d6cfa | 84 | ICPState *ss; |
cc706a53 | 85 | QLIST_HEAD(, ICSState) ics; |
c04d6cfa AL |
86 | }; |
87 | ||
88 | #define TYPE_ICP "icp" | |
89 | #define ICP(obj) OBJECT_CHECK(ICPState, (obj), TYPE_ICP) | |
90 | ||
11ad93f6 DG |
91 | #define TYPE_KVM_ICP "icp-kvm" |
92 | #define KVM_ICP(obj) OBJECT_CHECK(ICPState, (obj), TYPE_KVM_ICP) | |
93 | ||
d1b5682d AK |
94 | #define ICP_CLASS(klass) \ |
95 | OBJECT_CLASS_CHECK(ICPStateClass, (klass), TYPE_ICP) | |
96 | #define ICP_GET_CLASS(obj) \ | |
97 | OBJECT_GET_CLASS(ICPStateClass, (obj), TYPE_ICP) | |
98 | ||
99 | struct ICPStateClass { | |
100 | DeviceClass parent_class; | |
101 | ||
102 | void (*pre_save)(ICPState *s); | |
103 | int (*post_load)(ICPState *s, int version_id); | |
104 | }; | |
105 | ||
c04d6cfa AL |
106 | struct ICPState { |
107 | /*< private >*/ | |
108 | DeviceState parent_obj; | |
109 | /*< public >*/ | |
11ad93f6 | 110 | CPUState *cs; |
cc706a53 | 111 | ICSState *xirr_owner; |
c04d6cfa AL |
112 | uint32_t xirr; |
113 | uint8_t pending_priority; | |
114 | uint8_t mfrr; | |
115 | qemu_irq output; | |
a45863bd | 116 | bool cap_irq_xics_enabled; |
d49c603b CLG |
117 | |
118 | XICSState *xics; | |
c04d6cfa AL |
119 | }; |
120 | ||
d4d7a59a BH |
121 | #define TYPE_ICS_BASE "ics-base" |
122 | #define ICS_BASE(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_BASE) | |
c04d6cfa | 123 | |
d4d7a59a BH |
124 | /* Retain ics for sPAPR for migration from existing sPAPR guests */ |
125 | #define TYPE_ICS_SIMPLE "ics" | |
126 | #define ICS_SIMPLE(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_SIMPLE) | |
11ad93f6 | 127 | |
d4d7a59a BH |
128 | #define TYPE_ICS_KVM "icskvm" |
129 | #define ICS_KVM(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_KVM) | |
130 | ||
131 | #define ICS_BASE_CLASS(klass) \ | |
132 | OBJECT_CLASS_CHECK(ICSStateClass, (klass), TYPE_ICS_BASE) | |
133 | #define ICS_BASE_GET_CLASS(obj) \ | |
134 | OBJECT_GET_CLASS(ICSStateClass, (obj), TYPE_ICS_BASE) | |
d1b5682d AK |
135 | |
136 | struct ICSStateClass { | |
137 | DeviceClass parent_class; | |
138 | ||
4e4169f7 | 139 | void (*realize)(DeviceState *dev, Error **errp); |
d1b5682d AK |
140 | void (*pre_save)(ICSState *s); |
141 | int (*post_load)(ICSState *s, int version_id); | |
d4d7a59a BH |
142 | void (*reject)(ICSState *s, uint32_t irq); |
143 | void (*resend)(ICSState *s); | |
144 | void (*eoi)(ICSState *s, uint32_t irq); | |
d1b5682d AK |
145 | }; |
146 | ||
c04d6cfa AL |
147 | struct ICSState { |
148 | /*< private >*/ | |
149 | DeviceState parent_obj; | |
150 | /*< public >*/ | |
151 | uint32_t nr_irqs; | |
152 | uint32_t offset; | |
153 | qemu_irq *qirqs; | |
c04d6cfa | 154 | ICSIRQState *irqs; |
27f24582 | 155 | XICSState *xics; |
cc706a53 | 156 | QLIST_ENTRY(ICSState) list; |
c04d6cfa | 157 | }; |
b5cec4c5 | 158 | |
9c7027ba BH |
159 | static inline bool ics_valid_irq(ICSState *ics, uint32_t nr) |
160 | { | |
15ed653f | 161 | return (ics->offset != 0) && (nr >= ics->offset) |
9c7027ba BH |
162 | && (nr < (ics->offset + ics->nr_irqs)); |
163 | } | |
164 | ||
c04d6cfa AL |
165 | struct ICSIRQState { |
166 | uint32_t server; | |
167 | uint8_t priority; | |
168 | uint8_t saved_priority; | |
169 | #define XICS_STATUS_ASSERTED 0x1 | |
170 | #define XICS_STATUS_SENT 0x2 | |
171 | #define XICS_STATUS_REJECTED 0x4 | |
172 | #define XICS_STATUS_MASKED_PENDING 0x8 | |
173 | uint8_t status; | |
4af88944 AK |
174 | /* (flags & XICS_FLAGS_IRQ_MASK) == 0 means the interrupt is not allocated */ |
175 | #define XICS_FLAGS_IRQ_LSI 0x1 | |
176 | #define XICS_FLAGS_IRQ_MSI 0x2 | |
177 | #define XICS_FLAGS_IRQ_MASK 0x3 | |
178 | uint8_t flags; | |
c04d6cfa | 179 | }; |
b5cec4c5 | 180 | |
161deaf2 | 181 | #define XICS_IRQS_SPAPR 1024 |
9dbae977 | 182 | |
c04d6cfa | 183 | qemu_irq xics_get_qirq(XICSState *icp, int irq); |
681bfade CLG |
184 | int spapr_ics_alloc(ICSState *ics, int irq_hint, bool lsi, Error **errp); |
185 | int spapr_ics_alloc_block(ICSState *ics, int num, bool lsi, bool align, | |
cc706a53 | 186 | Error **errp); |
681bfade | 187 | void spapr_ics_free(ICSState *ics, int irq, int num); |
9b9a1908 | 188 | void spapr_dt_xics(XICSState *xics, void *fdt, uint32_t phandle); |
b5cec4c5 | 189 | |
c04d6cfa | 190 | void xics_cpu_setup(XICSState *icp, PowerPCCPU *cpu); |
4a4b344c | 191 | void xics_cpu_destroy(XICSState *icp, PowerPCCPU *cpu); |
b5cec4c5 | 192 | |
9c7027ba BH |
193 | /* Internal XICS interfaces */ |
194 | int xics_get_cpu_index_by_dt_id(int cpu_dt_id); | |
195 | ||
e3403258 CLG |
196 | void icp_set_cppr(ICPState *icp, uint8_t cppr); |
197 | void icp_set_mfrr(ICPState *icp, uint8_t mfrr); | |
9c7027ba | 198 | uint32_t icp_accept(ICPState *ss); |
1cbd2220 | 199 | uint32_t icp_ipoll(ICPState *ss, uint32_t *mfrr); |
e3403258 | 200 | void icp_eoi(ICPState *icp, uint32_t xirr); |
9c7027ba | 201 | |
d4d7a59a BH |
202 | void ics_simple_write_xive(ICSState *ics, int nr, int server, |
203 | uint8_t priority, uint8_t saved_priority); | |
9c7027ba BH |
204 | |
205 | void ics_set_irq_type(ICSState *ics, int srcno, bool lsi); | |
206 | ||
cc706a53 | 207 | ICSState *xics_find_source(XICSState *icp, int irq); |
9c7027ba | 208 | |
2a6a4076 | 209 | #endif /* XICS_H */ |