Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | /* |
2 | * ========== Copyright Header Begin ========================================== | |
3 | * | |
4 | * Hypervisor Software File: vdev_intr.h | |
5 | * | |
6 | * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. | |
7 | * | |
8 | * - Do no alter or remove copyright notices | |
9 | * | |
10 | * - Redistribution and use of this software in source and binary forms, with | |
11 | * or without modification, are permitted provided that the following | |
12 | * conditions are met: | |
13 | * | |
14 | * - Redistribution of source code must retain the above copyright notice, | |
15 | * this list of conditions and the following disclaimer. | |
16 | * | |
17 | * - Redistribution in binary form must reproduce the above copyright notice, | |
18 | * this list of conditions and the following disclaimer in the | |
19 | * documentation and/or other materials provided with the distribution. | |
20 | * | |
21 | * Neither the name of Sun Microsystems, Inc. or the names of contributors | |
22 | * may be used to endorse or promote products derived from this software | |
23 | * without specific prior written permission. | |
24 | * | |
25 | * This software is provided "AS IS," without a warranty of any kind. | |
26 | * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, | |
27 | * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A | |
28 | * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN | |
29 | * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR | |
30 | * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR | |
31 | * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN | |
32 | * OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR | |
33 | * FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE | |
34 | * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, | |
35 | * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF | |
36 | * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. | |
37 | * | |
38 | * You acknowledge that this software is not designed, licensed or | |
39 | * intended for use in the design, construction, operation or maintenance of | |
40 | * any nuclear facility. | |
41 | * | |
42 | * ========== Copyright Header End ============================================ | |
43 | */ | |
44 | /* | |
45 | * Copyright 2007 Sun Microsystems, Inc. All rights reserved. | |
46 | * Use is subject to license terms. | |
47 | */ | |
48 | ||
49 | #ifndef _VDEV_INTR_H | |
50 | #define _VDEV_INTR_H | |
51 | ||
52 | #pragma ident "@(#)vdev_intr.h 1.13 07/05/03 SMI" | |
53 | ||
54 | #ifdef __cplusplus | |
55 | extern "C" { | |
56 | #endif | |
57 | ||
58 | #include <hypervisor.h> | |
59 | #include <hprivregs.h> | |
60 | #include <intr.h> | |
61 | ||
62 | /* BEGIN CSTYLED */ | |
63 | ||
64 | /* | |
65 | * vino2inst | |
66 | * +--------+ | |
67 | * dev2inst 0x0| | | |
68 | * +--------+ +--------+ | |
69 | * 0x0| | devinstances | | | |
70 | * +--------+ +---------+--------+ +--------+ | |
71 | * | | | | | | | | |
72 | * +--------+ +---------+--------+ +--------+ | |
73 | * | inst -+-------> *cookiep| *ops | +-----| inst | | |
74 | * +--------+ +---------+--------+ | +--------+ | |
75 | * | | | | | | .......... | |
76 | * +--------+ +---------+--------+ | .......... | |
77 | * .......... | *cookiep| *ops <----+ .......... | |
78 | * .......... +---------+--------+ .......... | |
79 | * .......... | | | | | | |
80 | * .......... +---------+--------+ +--------+ | |
81 | * | | | *cookiep| *ops |--+ | | | |
82 | * +--------+ +---------+--------+ | +--------+ | |
83 | * | | | | | | |
84 | * +--------+ devops | +--------+ | |
85 | * | | +----------+<---- + | | | |
86 | * +--------+ | dev2vino | +--------+ | |
87 | * | | +----------+ 0x7ff| | | |
88 | * +--------+ | getvalid | +--------+ | |
89 | *0x1f| | +----------+ | |
90 | * +--------+ | setvalid | | |
91 | * +----------+ | |
92 | * | getstate | | |
93 | * +----------+ | |
94 | * | setstate | | |
95 | * ............ | |
96 | * ............ | |
97 | * ............ | |
98 | * ............ | |
99 | * +----------+ | |
100 | * | | | |
101 | * +----------+ | |
102 | * | | | |
103 | * +----------+ | |
104 | * | |
105 | */ | |
106 | ||
107 | ||
108 | #define NDEVIDS 0x20 | |
109 | #define DEVIDMASK (NDEVIDS - 1) | |
110 | #define NINOSPERDEV 64 | |
111 | #define DEVINOMASK (NINOSPERDEV - 1) | |
112 | #define NVINOS (NINOSPERDEV * NDEVIDS) | |
113 | #define NFIREDEVS 2 | |
114 | ||
115 | ||
116 | /* | |
117 | * Number of devinstances | |
118 | * defined to be <= 256 so a single byte | |
119 | * can be used to hold an index value to this table. | |
120 | */ | |
121 | ||
122 | #define NDEV_INSTS 256 | |
123 | ||
124 | #define DEVCFGPA_MASK 0x1f | |
125 | #define DEVCFGPA_SHIFT 6 | |
126 | ||
127 | ||
128 | /* | |
129 | * Find the "opsvec" structure for a "vino" | |
130 | */ | |
131 | #define VINO2DEVINST(guest, vino, devinst, faillabel) \ | |
132 | cmp vino, NVINOS ;\ | |
133 | bgeu,pn %xcc, faillabel ;\ | |
134 | sethi %hi(GUEST_VINO2INST), devinst ;\ | |
135 | or devinst, %lo(GUEST_VINO2INST), devinst ;\ | |
136 | add guest, devinst, devinst ;\ | |
137 | ldub [devinst + vino], devinst ;\ | |
138 | brz,pn devinst, faillabel ;\ | |
139 | nop | |
140 | ||
141 | /* | |
142 | * Get the cookie for a devinst | |
143 | * | |
144 | * devinst and cookie may be the same register | |
145 | */ | |
146 | #define DEVINST2COOKIE(guest, devinst, cookie, scr, faillabel) \ | |
147 | brz,pn devinst, faillabel ;\ | |
148 | sllx devinst, DEVINST_SIZE_SHIFT, cookie ;\ | |
149 | ldx [guest + GUEST_CONFIGP], scr ;\ | |
150 | ldx [scr + CONFIG_DEVINSTANCES], scr ;\ | |
151 | add scr, cookie, cookie ;\ | |
152 | ldx [cookie + DEVINST_COOKIE], cookie | |
153 | ||
154 | /* | |
155 | * Find the "opsvec" structure for devhandle "handle" | |
156 | */ | |
157 | #define _DEVHANDLE2DEVINST(handle, opsvec, faillabel) \ | |
158 | btst DEVINOMASK, handle ;\ | |
159 | bnz,pn %xcc, faillabel ;\ | |
160 | srlx handle, DEVCFGPA_SHIFT, opsvec ;\ | |
161 | and opsvec, DEVIDMASK, opsvec | |
162 | ||
163 | #define DEVINST2INDEX(guest, devinst, index, scr, faillabel) \ | |
164 | add guest, GUEST_DEV2INST, scr ;\ | |
165 | ldub [scr + devinst], index ;\ | |
166 | brz index, faillabel ;\ | |
167 | nop | |
168 | ||
169 | #define _DEVHANDLE2OPSVEC(guest, handle, opsvec, scr, faillabel) \ | |
170 | _DEVHANDLE2DEVINST(handle, opsvec, faillabel) ;\ | |
171 | DEVINST2INDEX(guest, opsvec, opsvec, scr, faillabel) | |
172 | ||
173 | /* | |
174 | * Jump to a opsvec[devop] with a pointer to the "cookie" | |
175 | */ | |
176 | #define _JMPL_DEVOP(guest, devinst, devop, cookie, faillabel) \ | |
177 | sllx devinst, DEVINST_SIZE_SHIFT, devinst ;\ | |
178 | ldx [guest + GUEST_CONFIGP], cookie ;\ | |
179 | ldx [cookie + CONFIG_DEVINSTANCES], cookie ;\ | |
180 | add cookie, devinst, cookie ;\ | |
181 | ldx [cookie + DEVINST_OPS], devinst ;\ | |
182 | brz,pn devinst, faillabel ;\ | |
183 | ldx [cookie + DEVINST_COOKIE], cookie ;\ | |
184 | ldx [devinst + devop], devinst ;\ | |
185 | brz,pn devinst, faillabel ;\ | |
186 | nop ;\ | |
187 | jmpl devinst, %g0 ;\ | |
188 | nop | |
189 | ||
190 | /* | |
191 | * Jmp to "devop" for "vino" with pointer to the "cookie" | |
192 | */ | |
193 | #define JMPL_VINO2DEVOP(vino, devop, cookie, scr, label) \ | |
194 | GUEST_STRUCT(cookie) ;\ | |
195 | VINO2DEVINST(cookie, vino, scr, label) ;\ | |
196 | _JMPL_DEVOP(cookie, scr, devop, cookie, label) | |
197 | ||
198 | /* | |
199 | * Jmp to "devop" of device "handle" with "cookie" | |
200 | */ | |
201 | #define JMPL_DEVHANDLE2DEVOP(handle, devop, cookie, scr1, scr2, faillabel) \ | |
202 | GUEST_STRUCT(cookie) ;\ | |
203 | _DEVHANDLE2OPSVEC(cookie, handle, scr1, scr2, faillabel) ;\ | |
204 | _JMPL_DEVOP(cookie, scr1, devop, cookie, faillabel) | |
205 | /* END CSTYLED */ | |
206 | ||
207 | /* | |
208 | * The virtual interrupt management framework. | |
209 | * When a guest binds to a vintr we lookup the virtual->physical | |
210 | * mapping and store the physical cpu info in the vintr table. | |
211 | */ | |
212 | ||
213 | #define NUM_VINTRS 64 /* Must be a power of two */ | |
214 | #define VINTR_INO_MASK (NUM_VINTRS - 1) | |
215 | ||
216 | ||
217 | /* BEGIN CSTYLED */ | |
218 | ||
219 | /* guest and vdevstate may NOT be the same register */ | |
220 | #define GUEST2VDEVSTATE(guest, vdevstate) \ | |
221 | set GUEST_VDEV_STATE, vdevstate ; \ | |
222 | add guest, vdevstate, vdevstate | |
223 | ||
224 | ||
225 | /* vino and mapreg may be the same register */ | |
226 | #define VINO2MAPREG(state, vino, mapreg) \ | |
227 | and vino, DEVINOMASK, mapreg ; \ | |
228 | sllx mapreg, MAPREG_SHIFT, mapreg ; \ | |
229 | add state, mapreg, mapreg ; \ | |
230 | add mapreg, VDEV_STATE_MAPREG, mapreg | |
231 | ||
232 | /* END CSTYLED */ | |
233 | ||
234 | ||
235 | #ifndef _ASM | |
236 | ||
237 | ||
238 | struct devinst { | |
239 | void *cookie; | |
240 | struct devopsvec *ops; | |
241 | }; | |
242 | ||
243 | typedef struct devinst devinst_t; | |
244 | extern devinst_t devinstances[]; | |
245 | ||
246 | ||
247 | /* | |
248 | * Virtual INO to Device Instance | |
249 | * | |
250 | * This byte array contains the indexes into array of struct devinst | |
251 | * | |
252 | * It is used to go from vINO => device instance | |
253 | */ | |
254 | ||
255 | typedef struct vino2inst vino2inst_t; | |
256 | ||
257 | struct vino2inst { | |
258 | uint8_t vino [NVINOS]; | |
259 | }; | |
260 | ||
261 | typedef struct vino_pcie vino_pcie_t; | |
262 | struct vino_pcie { | |
263 | uint8_t vino [NPCIEDEVS][NINOSPERDEV]; | |
264 | }; | |
265 | extern const struct vino2inst config_vino2inst; | |
266 | extern const uint8_t config_dev2inst[NDEVIDS]; | |
267 | extern const struct vino_pcie config_pcie_vinos; | |
268 | ||
269 | /* | |
270 | * Virtual Interrupt Mapping Register (vmapreg), one per interrupt | |
271 | * | |
272 | * The virtual mapping register is split into two 32-bit words. The | |
273 | * first word is modified by the hypervisor asynchronously. The | |
274 | * second word contains state that is modified by the guest. | |
275 | * | |
276 | * The state field contains a sun4v interrupt state: | |
277 | * INTR_IDLE (0), INTR_RECEIVED (1), INTR_DELIVERED (2) | |
278 | * | |
279 | * The physical cpu number (pcu) is cached in the vmapreg and | |
280 | * is a translation of the guest's virtual cpu number. | |
281 | * This framework will require changes to support Dynamic | |
282 | * Reconfiguration (DR) of processors. | |
283 | * pcpu is never returned to a guest; this is for reverse lookup | |
284 | * | |
285 | * XXX have a flag or a pointer to 7 words to use in addition to data0 | |
286 | */ | |
287 | ||
288 | typedef struct vdev_mapreg vdev_mapreg_t; | |
289 | ||
290 | struct vdev_mapreg { | |
291 | uint8_t state; | |
292 | uint8_t valid; | |
293 | uint16_t pcpu; | |
294 | uint16_t vcpu; | |
295 | uint8_t ino; | |
296 | uint8_t reserved; | |
297 | uint64_t data0; | |
298 | uint64_t devcookie; | |
299 | uint64_t getstate; | |
300 | uint64_t setstate; | |
301 | uint64_t _padding[3]; | |
302 | }; | |
303 | ||
304 | ||
305 | /* | |
306 | * vdev nexus state structure, one per guest | |
307 | */ | |
308 | ||
309 | typedef struct vdev_state vdev_state_t; | |
310 | ||
311 | struct vdev_state { | |
312 | uint64_t handle; | |
313 | struct vdev_mapreg mapreg[NUM_VINTRS]; | |
314 | uint16_t inomax; /* Max INO */ | |
315 | uint16_t vinobase; /* First Vino */ | |
316 | }; | |
317 | ||
318 | ||
319 | /* | |
320 | * Definitions for vdev_intr_register & its C wrapper | |
321 | */ | |
322 | typedef int (*intr_getstate_f)(void *); | |
323 | typedef void (*intr_setstate_f)(void *, int); | |
324 | ||
325 | extern uint64_t c_vdev_intr_register(void *, int, void *, | |
326 | intr_getstate_f, intr_setstate_f); | |
327 | ||
328 | #endif /* !_ASM */ | |
329 | ||
330 | #ifdef __cplusplus | |
331 | } | |
332 | #endif | |
333 | ||
334 | #endif /* _VDEV_INTR_H */ |