xref: /freebsd/sys/dev/hyperv/vmbus/vmbus.c (revision b9f654b163bce26de79705e77b872427c9f2afa1)
1 /*-
2  * Copyright (c) 2009-2012,2016-2017 Microsoft Corp.
3  * Copyright (c) 2012 NetApp Inc.
4  * Copyright (c) 2012 Citrix Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice unmodified, this list of conditions, and the following
12  *    disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 /*
30  * VM Bus Driver Implementation
31  */
32 #include <sys/cdefs.h>
33 __FBSDID("$FreeBSD$");
34 
35 #include <sys/param.h>
36 #include <sys/bus.h>
37 #include <sys/kernel.h>
38 #include <sys/lock.h>
39 #include <sys/malloc.h>
40 #include <sys/module.h>
41 #include <sys/mutex.h>
42 #include <sys/smp.h>
43 #include <sys/sysctl.h>
44 #include <sys/systm.h>
45 #include <sys/taskqueue.h>
46 
47 #include <machine/bus.h>
48 #include <machine/intr_machdep.h>
49 #include <machine/md_var.h>
50 #include <machine/resource.h>
51 #include <x86/include/apicvar.h>
52 
53 #include <contrib/dev/acpica/include/acpi.h>
54 #include <dev/acpica/acpivar.h>
55 
56 #include <dev/hyperv/include/hyperv.h>
57 #include <dev/hyperv/include/vmbus_xact.h>
58 #include <dev/hyperv/vmbus/hyperv_reg.h>
59 #include <dev/hyperv/vmbus/hyperv_var.h>
60 #include <dev/hyperv/vmbus/vmbus_reg.h>
61 #include <dev/hyperv/vmbus/vmbus_var.h>
62 #include <dev/hyperv/vmbus/vmbus_chanvar.h>
63 
64 #include "acpi_if.h"
65 #include "pcib_if.h"
66 #include "vmbus_if.h"
67 
68 #define VMBUS_GPADL_START		0xe1e10
69 
70 struct vmbus_msghc {
71 	struct vmbus_xact		*mh_xact;
72 	struct hypercall_postmsg_in	mh_inprm_save;
73 };
74 
75 static void			vmbus_identify(driver_t *, device_t);
76 static int			vmbus_probe(device_t);
77 static int			vmbus_attach(device_t);
78 static int			vmbus_detach(device_t);
79 static int			vmbus_read_ivar(device_t, device_t, int,
80 				    uintptr_t *);
81 static int			vmbus_child_pnpinfo_str(device_t, device_t,
82 				    char *, size_t);
83 static struct resource		*vmbus_alloc_resource(device_t dev,
84 				    device_t child, int type, int *rid,
85 				    rman_res_t start, rman_res_t end,
86 				    rman_res_t count, u_int flags);
87 static int			vmbus_alloc_msi(device_t bus, device_t dev,
88 				    int count, int maxcount, int *irqs);
89 static int			vmbus_release_msi(device_t bus, device_t dev,
90 				    int count, int *irqs);
91 static int			vmbus_alloc_msix(device_t bus, device_t dev,
92 				    int *irq);
93 static int			vmbus_release_msix(device_t bus, device_t dev,
94 				    int irq);
95 static int			vmbus_map_msi(device_t bus, device_t dev,
96 				    int irq, uint64_t *addr, uint32_t *data);
97 static uint32_t			vmbus_get_version_method(device_t, device_t);
98 static int			vmbus_probe_guid_method(device_t, device_t,
99 				    const struct hyperv_guid *);
100 static uint32_t			vmbus_get_vcpu_id_method(device_t bus,
101 				    device_t dev, int cpu);
102 static struct taskqueue		*vmbus_get_eventtq_method(device_t, device_t,
103 				    int);
104 #ifdef EARLY_AP_STARTUP
105 static void			vmbus_intrhook(void *);
106 #endif
107 
108 static int			vmbus_init(struct vmbus_softc *);
109 static int			vmbus_connect(struct vmbus_softc *, uint32_t);
110 static int			vmbus_req_channels(struct vmbus_softc *sc);
111 static void			vmbus_disconnect(struct vmbus_softc *);
112 static int			vmbus_scan(struct vmbus_softc *);
113 static void			vmbus_scan_teardown(struct vmbus_softc *);
114 static void			vmbus_scan_done(struct vmbus_softc *,
115 				    const struct vmbus_message *);
116 static void			vmbus_chanmsg_handle(struct vmbus_softc *,
117 				    const struct vmbus_message *);
118 static void			vmbus_msg_task(void *, int);
119 static void			vmbus_synic_setup(void *);
120 static void			vmbus_synic_teardown(void *);
121 static int			vmbus_sysctl_version(SYSCTL_HANDLER_ARGS);
122 static int			vmbus_dma_alloc(struct vmbus_softc *);
123 static void			vmbus_dma_free(struct vmbus_softc *);
124 static int			vmbus_intr_setup(struct vmbus_softc *);
125 static void			vmbus_intr_teardown(struct vmbus_softc *);
126 static int			vmbus_doattach(struct vmbus_softc *);
127 static void			vmbus_event_proc_dummy(struct vmbus_softc *,
128 				    int);
129 
130 static struct vmbus_softc	*vmbus_sc;
131 
132 SYSCTL_NODE(_hw, OID_AUTO, vmbus, CTLFLAG_RD | CTLFLAG_MPSAFE, NULL,
133     "Hyper-V vmbus");
134 
135 static int			vmbus_pin_evttask = 1;
136 SYSCTL_INT(_hw_vmbus, OID_AUTO, pin_evttask, CTLFLAG_RDTUN,
137     &vmbus_pin_evttask, 0, "Pin event tasks to their respective CPU");
138 
139 extern inthand_t IDTVEC(vmbus_isr), IDTVEC(vmbus_isr_pti);
140 
141 static const uint32_t		vmbus_version[] = {
142 	VMBUS_VERSION_WIN8_1,
143 	VMBUS_VERSION_WIN8,
144 	VMBUS_VERSION_WIN7,
145 	VMBUS_VERSION_WS2008
146 };
147 
148 static const vmbus_chanmsg_proc_t
149 vmbus_chanmsg_handlers[VMBUS_CHANMSG_TYPE_MAX] = {
150 	VMBUS_CHANMSG_PROC(CHOFFER_DONE, vmbus_scan_done),
151 	VMBUS_CHANMSG_PROC_WAKEUP(CONNECT_RESP)
152 };
153 
154 static device_method_t vmbus_methods[] = {
155 	/* Device interface */
156 	DEVMETHOD(device_identify,		vmbus_identify),
157 	DEVMETHOD(device_probe,			vmbus_probe),
158 	DEVMETHOD(device_attach,		vmbus_attach),
159 	DEVMETHOD(device_detach,		vmbus_detach),
160 	DEVMETHOD(device_shutdown,		bus_generic_shutdown),
161 	DEVMETHOD(device_suspend,		bus_generic_suspend),
162 	DEVMETHOD(device_resume,		bus_generic_resume),
163 
164 	/* Bus interface */
165 	DEVMETHOD(bus_add_child,		bus_generic_add_child),
166 	DEVMETHOD(bus_print_child,		bus_generic_print_child),
167 	DEVMETHOD(bus_read_ivar,		vmbus_read_ivar),
168 	DEVMETHOD(bus_child_pnpinfo_str,	vmbus_child_pnpinfo_str),
169 	DEVMETHOD(bus_alloc_resource,		vmbus_alloc_resource),
170 	DEVMETHOD(bus_release_resource,		bus_generic_release_resource),
171 	DEVMETHOD(bus_activate_resource,	bus_generic_activate_resource),
172 	DEVMETHOD(bus_deactivate_resource,	bus_generic_deactivate_resource),
173 	DEVMETHOD(bus_setup_intr,		bus_generic_setup_intr),
174 	DEVMETHOD(bus_teardown_intr,		bus_generic_teardown_intr),
175 #if __FreeBSD_version >= 1100000
176 	DEVMETHOD(bus_get_cpus,			bus_generic_get_cpus),
177 #endif
178 
179 	/* pcib interface */
180 	DEVMETHOD(pcib_alloc_msi,		vmbus_alloc_msi),
181 	DEVMETHOD(pcib_release_msi,		vmbus_release_msi),
182 	DEVMETHOD(pcib_alloc_msix,		vmbus_alloc_msix),
183 	DEVMETHOD(pcib_release_msix,		vmbus_release_msix),
184 	DEVMETHOD(pcib_map_msi,			vmbus_map_msi),
185 
186 	/* Vmbus interface */
187 	DEVMETHOD(vmbus_get_version,		vmbus_get_version_method),
188 	DEVMETHOD(vmbus_probe_guid,		vmbus_probe_guid_method),
189 	DEVMETHOD(vmbus_get_vcpu_id,		vmbus_get_vcpu_id_method),
190 	DEVMETHOD(vmbus_get_event_taskq,	vmbus_get_eventtq_method),
191 
192 	DEVMETHOD_END
193 };
194 
195 static driver_t vmbus_driver = {
196 	"vmbus",
197 	vmbus_methods,
198 	sizeof(struct vmbus_softc)
199 };
200 
201 static devclass_t vmbus_devclass;
202 
203 DRIVER_MODULE(vmbus, pcib, vmbus_driver, vmbus_devclass, NULL, NULL);
204 DRIVER_MODULE(vmbus, acpi_syscontainer, vmbus_driver, vmbus_devclass,
205     NULL, NULL);
206 
207 MODULE_DEPEND(vmbus, acpi, 1, 1, 1);
208 MODULE_DEPEND(vmbus, pci, 1, 1, 1);
209 MODULE_VERSION(vmbus, 1);
210 
211 static __inline struct vmbus_softc *
212 vmbus_get_softc(void)
213 {
214 	return vmbus_sc;
215 }
216 
217 void
218 vmbus_msghc_reset(struct vmbus_msghc *mh, size_t dsize)
219 {
220 	struct hypercall_postmsg_in *inprm;
221 
222 	if (dsize > HYPERCALL_POSTMSGIN_DSIZE_MAX)
223 		panic("invalid data size %zu", dsize);
224 
225 	inprm = vmbus_xact_req_data(mh->mh_xact);
226 	memset(inprm, 0, HYPERCALL_POSTMSGIN_SIZE);
227 	inprm->hc_connid = VMBUS_CONNID_MESSAGE;
228 	inprm->hc_msgtype = HYPERV_MSGTYPE_CHANNEL;
229 	inprm->hc_dsize = dsize;
230 }
231 
232 struct vmbus_msghc *
233 vmbus_msghc_get(struct vmbus_softc *sc, size_t dsize)
234 {
235 	struct vmbus_msghc *mh;
236 	struct vmbus_xact *xact;
237 
238 	if (dsize > HYPERCALL_POSTMSGIN_DSIZE_MAX)
239 		panic("invalid data size %zu", dsize);
240 
241 	xact = vmbus_xact_get(sc->vmbus_xc,
242 	    dsize + __offsetof(struct hypercall_postmsg_in, hc_data[0]));
243 	if (xact == NULL)
244 		return (NULL);
245 
246 	mh = vmbus_xact_priv(xact, sizeof(*mh));
247 	mh->mh_xact = xact;
248 
249 	vmbus_msghc_reset(mh, dsize);
250 	return (mh);
251 }
252 
253 void
254 vmbus_msghc_put(struct vmbus_softc *sc __unused, struct vmbus_msghc *mh)
255 {
256 
257 	vmbus_xact_put(mh->mh_xact);
258 }
259 
260 void *
261 vmbus_msghc_dataptr(struct vmbus_msghc *mh)
262 {
263 	struct hypercall_postmsg_in *inprm;
264 
265 	inprm = vmbus_xact_req_data(mh->mh_xact);
266 	return (inprm->hc_data);
267 }
268 
269 int
270 vmbus_msghc_exec_noresult(struct vmbus_msghc *mh)
271 {
272 	sbintime_t time = SBT_1MS;
273 	struct hypercall_postmsg_in *inprm;
274 	bus_addr_t inprm_paddr;
275 	int i;
276 
277 	inprm = vmbus_xact_req_data(mh->mh_xact);
278 	inprm_paddr = vmbus_xact_req_paddr(mh->mh_xact);
279 
280 	/*
281 	 * Save the input parameter so that we could restore the input
282 	 * parameter if the Hypercall failed.
283 	 *
284 	 * XXX
285 	 * Is this really necessary?!  i.e. Will the Hypercall ever
286 	 * overwrite the input parameter?
287 	 */
288 	memcpy(&mh->mh_inprm_save, inprm, HYPERCALL_POSTMSGIN_SIZE);
289 
290 	/*
291 	 * In order to cope with transient failures, e.g. insufficient
292 	 * resources on host side, we retry the post message Hypercall
293 	 * several times.  20 retries seem sufficient.
294 	 */
295 #define HC_RETRY_MAX	20
296 
297 	for (i = 0; i < HC_RETRY_MAX; ++i) {
298 		uint64_t status;
299 
300 		status = hypercall_post_message(inprm_paddr);
301 		if (status == HYPERCALL_STATUS_SUCCESS)
302 			return 0;
303 
304 		pause_sbt("hcpmsg", time, 0, C_HARDCLOCK);
305 		if (time < SBT_1S * 2)
306 			time *= 2;
307 
308 		/* Restore input parameter and try again */
309 		memcpy(inprm, &mh->mh_inprm_save, HYPERCALL_POSTMSGIN_SIZE);
310 	}
311 
312 #undef HC_RETRY_MAX
313 
314 	return EIO;
315 }
316 
317 int
318 vmbus_msghc_exec(struct vmbus_softc *sc __unused, struct vmbus_msghc *mh)
319 {
320 	int error;
321 
322 	vmbus_xact_activate(mh->mh_xact);
323 	error = vmbus_msghc_exec_noresult(mh);
324 	if (error)
325 		vmbus_xact_deactivate(mh->mh_xact);
326 	return error;
327 }
328 
329 void
330 vmbus_msghc_exec_cancel(struct vmbus_softc *sc __unused, struct vmbus_msghc *mh)
331 {
332 
333 	vmbus_xact_deactivate(mh->mh_xact);
334 }
335 
336 const struct vmbus_message *
337 vmbus_msghc_wait_result(struct vmbus_softc *sc __unused, struct vmbus_msghc *mh)
338 {
339 	size_t resp_len;
340 
341 	return (vmbus_xact_wait(mh->mh_xact, &resp_len));
342 }
343 
344 const struct vmbus_message *
345 vmbus_msghc_poll_result(struct vmbus_softc *sc __unused, struct vmbus_msghc *mh)
346 {
347 	size_t resp_len;
348 
349 	return (vmbus_xact_poll(mh->mh_xact, &resp_len));
350 }
351 
352 void
353 vmbus_msghc_wakeup(struct vmbus_softc *sc, const struct vmbus_message *msg)
354 {
355 
356 	vmbus_xact_ctx_wakeup(sc->vmbus_xc, msg, sizeof(*msg));
357 }
358 
359 uint32_t
360 vmbus_gpadl_alloc(struct vmbus_softc *sc)
361 {
362 	uint32_t gpadl;
363 
364 again:
365 	gpadl = atomic_fetchadd_int(&sc->vmbus_gpadl, 1);
366 	if (gpadl == 0)
367 		goto again;
368 	return (gpadl);
369 }
370 
371 static int
372 vmbus_connect(struct vmbus_softc *sc, uint32_t version)
373 {
374 	struct vmbus_chanmsg_connect *req;
375 	const struct vmbus_message *msg;
376 	struct vmbus_msghc *mh;
377 	int error, done = 0;
378 
379 	mh = vmbus_msghc_get(sc, sizeof(*req));
380 	if (mh == NULL)
381 		return ENXIO;
382 
383 	req = vmbus_msghc_dataptr(mh);
384 	req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_CONNECT;
385 	req->chm_ver = version;
386 	req->chm_evtflags = sc->vmbus_evtflags_dma.hv_paddr;
387 	req->chm_mnf1 = sc->vmbus_mnf1_dma.hv_paddr;
388 	req->chm_mnf2 = sc->vmbus_mnf2_dma.hv_paddr;
389 
390 	error = vmbus_msghc_exec(sc, mh);
391 	if (error) {
392 		vmbus_msghc_put(sc, mh);
393 		return error;
394 	}
395 
396 	msg = vmbus_msghc_wait_result(sc, mh);
397 	done = ((const struct vmbus_chanmsg_connect_resp *)
398 	    msg->msg_data)->chm_done;
399 
400 	vmbus_msghc_put(sc, mh);
401 
402 	return (done ? 0 : EOPNOTSUPP);
403 }
404 
405 static int
406 vmbus_init(struct vmbus_softc *sc)
407 {
408 	int i;
409 
410 	for (i = 0; i < nitems(vmbus_version); ++i) {
411 		int error;
412 
413 		error = vmbus_connect(sc, vmbus_version[i]);
414 		if (!error) {
415 			sc->vmbus_version = vmbus_version[i];
416 			device_printf(sc->vmbus_dev, "version %u.%u\n",
417 			    VMBUS_VERSION_MAJOR(sc->vmbus_version),
418 			    VMBUS_VERSION_MINOR(sc->vmbus_version));
419 			return 0;
420 		}
421 	}
422 	return ENXIO;
423 }
424 
425 static void
426 vmbus_disconnect(struct vmbus_softc *sc)
427 {
428 	struct vmbus_chanmsg_disconnect *req;
429 	struct vmbus_msghc *mh;
430 	int error;
431 
432 	mh = vmbus_msghc_get(sc, sizeof(*req));
433 	if (mh == NULL) {
434 		device_printf(sc->vmbus_dev,
435 		    "can not get msg hypercall for disconnect\n");
436 		return;
437 	}
438 
439 	req = vmbus_msghc_dataptr(mh);
440 	req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_DISCONNECT;
441 
442 	error = vmbus_msghc_exec_noresult(mh);
443 	vmbus_msghc_put(sc, mh);
444 
445 	if (error) {
446 		device_printf(sc->vmbus_dev,
447 		    "disconnect msg hypercall failed\n");
448 	}
449 }
450 
451 static int
452 vmbus_req_channels(struct vmbus_softc *sc)
453 {
454 	struct vmbus_chanmsg_chrequest *req;
455 	struct vmbus_msghc *mh;
456 	int error;
457 
458 	mh = vmbus_msghc_get(sc, sizeof(*req));
459 	if (mh == NULL)
460 		return ENXIO;
461 
462 	req = vmbus_msghc_dataptr(mh);
463 	req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_CHREQUEST;
464 
465 	error = vmbus_msghc_exec_noresult(mh);
466 	vmbus_msghc_put(sc, mh);
467 
468 	return error;
469 }
470 
471 static void
472 vmbus_scan_done_task(void *xsc, int pending __unused)
473 {
474 	struct vmbus_softc *sc = xsc;
475 
476 	mtx_lock(&Giant);
477 	sc->vmbus_scandone = true;
478 	mtx_unlock(&Giant);
479 	wakeup(&sc->vmbus_scandone);
480 }
481 
482 static void
483 vmbus_scan_done(struct vmbus_softc *sc,
484     const struct vmbus_message *msg __unused)
485 {
486 
487 	taskqueue_enqueue(sc->vmbus_devtq, &sc->vmbus_scandone_task);
488 }
489 
490 static int
491 vmbus_scan(struct vmbus_softc *sc)
492 {
493 	int error;
494 
495 	/*
496 	 * Identify, probe and attach for non-channel devices.
497 	 */
498 	bus_generic_probe(sc->vmbus_dev);
499 	bus_generic_attach(sc->vmbus_dev);
500 
501 	/*
502 	 * This taskqueue serializes vmbus devices' attach and detach
503 	 * for channel offer and rescind messages.
504 	 */
505 	sc->vmbus_devtq = taskqueue_create("vmbus dev", M_WAITOK,
506 	    taskqueue_thread_enqueue, &sc->vmbus_devtq);
507 	taskqueue_start_threads(&sc->vmbus_devtq, 1, PI_NET, "vmbusdev");
508 	TASK_INIT(&sc->vmbus_scandone_task, 0, vmbus_scan_done_task, sc);
509 
510 	/*
511 	 * This taskqueue handles sub-channel detach, so that vmbus
512 	 * device's detach running in vmbus_devtq can drain its sub-
513 	 * channels.
514 	 */
515 	sc->vmbus_subchtq = taskqueue_create("vmbus subch", M_WAITOK,
516 	    taskqueue_thread_enqueue, &sc->vmbus_subchtq);
517 	taskqueue_start_threads(&sc->vmbus_subchtq, 1, PI_NET, "vmbussch");
518 
519 	/*
520 	 * Start vmbus scanning.
521 	 */
522 	error = vmbus_req_channels(sc);
523 	if (error) {
524 		device_printf(sc->vmbus_dev, "channel request failed: %d\n",
525 		    error);
526 		return (error);
527 	}
528 
529 	/*
530 	 * Wait for all vmbus devices from the initial channel offers to be
531 	 * attached.
532 	 */
533 	GIANT_REQUIRED;
534 	while (!sc->vmbus_scandone)
535 		mtx_sleep(&sc->vmbus_scandone, &Giant, 0, "vmbusdev", 0);
536 
537 	if (bootverbose) {
538 		device_printf(sc->vmbus_dev, "device scan, probe and attach "
539 		    "done\n");
540 	}
541 	return (0);
542 }
543 
544 static void
545 vmbus_scan_teardown(struct vmbus_softc *sc)
546 {
547 
548 	GIANT_REQUIRED;
549 	if (sc->vmbus_devtq != NULL) {
550 		mtx_unlock(&Giant);
551 		taskqueue_free(sc->vmbus_devtq);
552 		mtx_lock(&Giant);
553 		sc->vmbus_devtq = NULL;
554 	}
555 	if (sc->vmbus_subchtq != NULL) {
556 		mtx_unlock(&Giant);
557 		taskqueue_free(sc->vmbus_subchtq);
558 		mtx_lock(&Giant);
559 		sc->vmbus_subchtq = NULL;
560 	}
561 }
562 
563 static void
564 vmbus_chanmsg_handle(struct vmbus_softc *sc, const struct vmbus_message *msg)
565 {
566 	vmbus_chanmsg_proc_t msg_proc;
567 	uint32_t msg_type;
568 
569 	msg_type = ((const struct vmbus_chanmsg_hdr *)msg->msg_data)->chm_type;
570 	if (msg_type >= VMBUS_CHANMSG_TYPE_MAX) {
571 		device_printf(sc->vmbus_dev, "unknown message type 0x%x\n",
572 		    msg_type);
573 		return;
574 	}
575 
576 	msg_proc = vmbus_chanmsg_handlers[msg_type];
577 	if (msg_proc != NULL)
578 		msg_proc(sc, msg);
579 
580 	/* Channel specific processing */
581 	vmbus_chan_msgproc(sc, msg);
582 }
583 
584 static void
585 vmbus_msg_task(void *xsc, int pending __unused)
586 {
587 	struct vmbus_softc *sc = xsc;
588 	volatile struct vmbus_message *msg;
589 
590 	msg = VMBUS_PCPU_GET(sc, message, curcpu) + VMBUS_SINT_MESSAGE;
591 	for (;;) {
592 		if (msg->msg_type == HYPERV_MSGTYPE_NONE) {
593 			/* No message */
594 			break;
595 		} else if (msg->msg_type == HYPERV_MSGTYPE_CHANNEL) {
596 			/* Channel message */
597 			vmbus_chanmsg_handle(sc,
598 			    __DEVOLATILE(const struct vmbus_message *, msg));
599 		}
600 
601 		msg->msg_type = HYPERV_MSGTYPE_NONE;
602 		/*
603 		 * Make sure the write to msg_type (i.e. set to
604 		 * HYPERV_MSGTYPE_NONE) happens before we read the
605 		 * msg_flags and EOMing. Otherwise, the EOMing will
606 		 * not deliver any more messages since there is no
607 		 * empty slot
608 		 *
609 		 * NOTE:
610 		 * mb() is used here, since atomic_thread_fence_seq_cst()
611 		 * will become compiler fence on UP kernel.
612 		 */
613 		mb();
614 		if (msg->msg_flags & VMBUS_MSGFLAG_PENDING) {
615 			/*
616 			 * This will cause message queue rescan to possibly
617 			 * deliver another msg from the hypervisor
618 			 */
619 			wrmsr(MSR_HV_EOM, 0);
620 		}
621 	}
622 }
623 
624 static __inline int
625 vmbus_handle_intr1(struct vmbus_softc *sc, struct trapframe *frame, int cpu)
626 {
627 	volatile struct vmbus_message *msg;
628 	struct vmbus_message *msg_base;
629 
630 	msg_base = VMBUS_PCPU_GET(sc, message, cpu);
631 
632 	/*
633 	 * Check event timer.
634 	 *
635 	 * TODO: move this to independent IDT vector.
636 	 */
637 	msg = msg_base + VMBUS_SINT_TIMER;
638 	if (msg->msg_type == HYPERV_MSGTYPE_TIMER_EXPIRED) {
639 		msg->msg_type = HYPERV_MSGTYPE_NONE;
640 
641 		vmbus_et_intr(frame);
642 
643 		/*
644 		 * Make sure the write to msg_type (i.e. set to
645 		 * HYPERV_MSGTYPE_NONE) happens before we read the
646 		 * msg_flags and EOMing. Otherwise, the EOMing will
647 		 * not deliver any more messages since there is no
648 		 * empty slot
649 		 *
650 		 * NOTE:
651 		 * mb() is used here, since atomic_thread_fence_seq_cst()
652 		 * will become compiler fence on UP kernel.
653 		 */
654 		mb();
655 		if (msg->msg_flags & VMBUS_MSGFLAG_PENDING) {
656 			/*
657 			 * This will cause message queue rescan to possibly
658 			 * deliver another msg from the hypervisor
659 			 */
660 			wrmsr(MSR_HV_EOM, 0);
661 		}
662 	}
663 
664 	/*
665 	 * Check events.  Hot path for network and storage I/O data; high rate.
666 	 *
667 	 * NOTE:
668 	 * As recommended by the Windows guest fellows, we check events before
669 	 * checking messages.
670 	 */
671 	sc->vmbus_event_proc(sc, cpu);
672 
673 	/*
674 	 * Check messages.  Mainly management stuffs; ultra low rate.
675 	 */
676 	msg = msg_base + VMBUS_SINT_MESSAGE;
677 	if (__predict_false(msg->msg_type != HYPERV_MSGTYPE_NONE)) {
678 		taskqueue_enqueue(VMBUS_PCPU_GET(sc, message_tq, cpu),
679 		    VMBUS_PCPU_PTR(sc, message_task, cpu));
680 	}
681 
682 	return (FILTER_HANDLED);
683 }
684 
685 void
686 vmbus_handle_intr(struct trapframe *trap_frame)
687 {
688 	struct vmbus_softc *sc = vmbus_get_softc();
689 	int cpu = curcpu;
690 
691 	/*
692 	 * Disable preemption.
693 	 */
694 	critical_enter();
695 
696 	/*
697 	 * Do a little interrupt counting.
698 	 */
699 	(*VMBUS_PCPU_GET(sc, intr_cnt, cpu))++;
700 
701 	vmbus_handle_intr1(sc, trap_frame, cpu);
702 
703 	/*
704 	 * Enable preemption.
705 	 */
706 	critical_exit();
707 }
708 
709 static void
710 vmbus_synic_setup(void *xsc)
711 {
712 	struct vmbus_softc *sc = xsc;
713 	int cpu = curcpu;
714 	uint64_t val, orig;
715 	uint32_t sint;
716 
717 	if (hyperv_features & CPUID_HV_MSR_VP_INDEX) {
718 		/* Save virtual processor id. */
719 		VMBUS_PCPU_GET(sc, vcpuid, cpu) = rdmsr(MSR_HV_VP_INDEX);
720 	} else {
721 		/* Set virtual processor id to 0 for compatibility. */
722 		VMBUS_PCPU_GET(sc, vcpuid, cpu) = 0;
723 	}
724 
725 	/*
726 	 * Setup the SynIC message.
727 	 */
728 	orig = rdmsr(MSR_HV_SIMP);
729 	val = MSR_HV_SIMP_ENABLE | (orig & MSR_HV_SIMP_RSVD_MASK) |
730 	    ((VMBUS_PCPU_GET(sc, message_dma.hv_paddr, cpu) >> PAGE_SHIFT) <<
731 	     MSR_HV_SIMP_PGSHIFT);
732 	wrmsr(MSR_HV_SIMP, val);
733 
734 	/*
735 	 * Setup the SynIC event flags.
736 	 */
737 	orig = rdmsr(MSR_HV_SIEFP);
738 	val = MSR_HV_SIEFP_ENABLE | (orig & MSR_HV_SIEFP_RSVD_MASK) |
739 	    ((VMBUS_PCPU_GET(sc, event_flags_dma.hv_paddr, cpu)
740 	      >> PAGE_SHIFT) << MSR_HV_SIEFP_PGSHIFT);
741 	wrmsr(MSR_HV_SIEFP, val);
742 
743 
744 	/*
745 	 * Configure and unmask SINT for message and event flags.
746 	 */
747 	sint = MSR_HV_SINT0 + VMBUS_SINT_MESSAGE;
748 	orig = rdmsr(sint);
749 	val = sc->vmbus_idtvec | MSR_HV_SINT_AUTOEOI |
750 	    (orig & MSR_HV_SINT_RSVD_MASK);
751 	wrmsr(sint, val);
752 
753 	/*
754 	 * Configure and unmask SINT for timer.
755 	 */
756 	sint = MSR_HV_SINT0 + VMBUS_SINT_TIMER;
757 	orig = rdmsr(sint);
758 	val = sc->vmbus_idtvec | MSR_HV_SINT_AUTOEOI |
759 	    (orig & MSR_HV_SINT_RSVD_MASK);
760 	wrmsr(sint, val);
761 
762 	/*
763 	 * All done; enable SynIC.
764 	 */
765 	orig = rdmsr(MSR_HV_SCONTROL);
766 	val = MSR_HV_SCTRL_ENABLE | (orig & MSR_HV_SCTRL_RSVD_MASK);
767 	wrmsr(MSR_HV_SCONTROL, val);
768 }
769 
770 static void
771 vmbus_synic_teardown(void *arg)
772 {
773 	uint64_t orig;
774 	uint32_t sint;
775 
776 	/*
777 	 * Disable SynIC.
778 	 */
779 	orig = rdmsr(MSR_HV_SCONTROL);
780 	wrmsr(MSR_HV_SCONTROL, (orig & MSR_HV_SCTRL_RSVD_MASK));
781 
782 	/*
783 	 * Mask message and event flags SINT.
784 	 */
785 	sint = MSR_HV_SINT0 + VMBUS_SINT_MESSAGE;
786 	orig = rdmsr(sint);
787 	wrmsr(sint, orig | MSR_HV_SINT_MASKED);
788 
789 	/*
790 	 * Mask timer SINT.
791 	 */
792 	sint = MSR_HV_SINT0 + VMBUS_SINT_TIMER;
793 	orig = rdmsr(sint);
794 	wrmsr(sint, orig | MSR_HV_SINT_MASKED);
795 
796 	/*
797 	 * Teardown SynIC message.
798 	 */
799 	orig = rdmsr(MSR_HV_SIMP);
800 	wrmsr(MSR_HV_SIMP, (orig & MSR_HV_SIMP_RSVD_MASK));
801 
802 	/*
803 	 * Teardown SynIC event flags.
804 	 */
805 	orig = rdmsr(MSR_HV_SIEFP);
806 	wrmsr(MSR_HV_SIEFP, (orig & MSR_HV_SIEFP_RSVD_MASK));
807 }
808 
809 static int
810 vmbus_dma_alloc(struct vmbus_softc *sc)
811 {
812 	bus_dma_tag_t parent_dtag;
813 	uint8_t *evtflags;
814 	int cpu;
815 
816 	parent_dtag = bus_get_dma_tag(sc->vmbus_dev);
817 	CPU_FOREACH(cpu) {
818 		void *ptr;
819 
820 		/*
821 		 * Per-cpu messages and event flags.
822 		 */
823 		ptr = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
824 		    PAGE_SIZE, VMBUS_PCPU_PTR(sc, message_dma, cpu),
825 		    BUS_DMA_WAITOK | BUS_DMA_ZERO);
826 		if (ptr == NULL)
827 			return ENOMEM;
828 		VMBUS_PCPU_GET(sc, message, cpu) = ptr;
829 
830 		ptr = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
831 		    PAGE_SIZE, VMBUS_PCPU_PTR(sc, event_flags_dma, cpu),
832 		    BUS_DMA_WAITOK | BUS_DMA_ZERO);
833 		if (ptr == NULL)
834 			return ENOMEM;
835 		VMBUS_PCPU_GET(sc, event_flags, cpu) = ptr;
836 	}
837 
838 	evtflags = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
839 	    PAGE_SIZE, &sc->vmbus_evtflags_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO);
840 	if (evtflags == NULL)
841 		return ENOMEM;
842 	sc->vmbus_rx_evtflags = (u_long *)evtflags;
843 	sc->vmbus_tx_evtflags = (u_long *)(evtflags + (PAGE_SIZE / 2));
844 	sc->vmbus_evtflags = evtflags;
845 
846 	sc->vmbus_mnf1 = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
847 	    PAGE_SIZE, &sc->vmbus_mnf1_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO);
848 	if (sc->vmbus_mnf1 == NULL)
849 		return ENOMEM;
850 
851 	sc->vmbus_mnf2 = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
852 	    sizeof(struct vmbus_mnf), &sc->vmbus_mnf2_dma,
853 	    BUS_DMA_WAITOK | BUS_DMA_ZERO);
854 	if (sc->vmbus_mnf2 == NULL)
855 		return ENOMEM;
856 
857 	return 0;
858 }
859 
860 static void
861 vmbus_dma_free(struct vmbus_softc *sc)
862 {
863 	int cpu;
864 
865 	if (sc->vmbus_evtflags != NULL) {
866 		hyperv_dmamem_free(&sc->vmbus_evtflags_dma, sc->vmbus_evtflags);
867 		sc->vmbus_evtflags = NULL;
868 		sc->vmbus_rx_evtflags = NULL;
869 		sc->vmbus_tx_evtflags = NULL;
870 	}
871 	if (sc->vmbus_mnf1 != NULL) {
872 		hyperv_dmamem_free(&sc->vmbus_mnf1_dma, sc->vmbus_mnf1);
873 		sc->vmbus_mnf1 = NULL;
874 	}
875 	if (sc->vmbus_mnf2 != NULL) {
876 		hyperv_dmamem_free(&sc->vmbus_mnf2_dma, sc->vmbus_mnf2);
877 		sc->vmbus_mnf2 = NULL;
878 	}
879 
880 	CPU_FOREACH(cpu) {
881 		if (VMBUS_PCPU_GET(sc, message, cpu) != NULL) {
882 			hyperv_dmamem_free(
883 			    VMBUS_PCPU_PTR(sc, message_dma, cpu),
884 			    VMBUS_PCPU_GET(sc, message, cpu));
885 			VMBUS_PCPU_GET(sc, message, cpu) = NULL;
886 		}
887 		if (VMBUS_PCPU_GET(sc, event_flags, cpu) != NULL) {
888 			hyperv_dmamem_free(
889 			    VMBUS_PCPU_PTR(sc, event_flags_dma, cpu),
890 			    VMBUS_PCPU_GET(sc, event_flags, cpu));
891 			VMBUS_PCPU_GET(sc, event_flags, cpu) = NULL;
892 		}
893 	}
894 }
895 
896 static int
897 vmbus_intr_setup(struct vmbus_softc *sc)
898 {
899 	int cpu;
900 
901 	CPU_FOREACH(cpu) {
902 		char buf[MAXCOMLEN + 1];
903 		cpuset_t cpu_mask;
904 
905 		/* Allocate an interrupt counter for Hyper-V interrupt */
906 		snprintf(buf, sizeof(buf), "cpu%d:hyperv", cpu);
907 		intrcnt_add(buf, VMBUS_PCPU_PTR(sc, intr_cnt, cpu));
908 
909 		/*
910 		 * Setup taskqueue to handle events.  Task will be per-
911 		 * channel.
912 		 */
913 		VMBUS_PCPU_GET(sc, event_tq, cpu) = taskqueue_create_fast(
914 		    "hyperv event", M_WAITOK, taskqueue_thread_enqueue,
915 		    VMBUS_PCPU_PTR(sc, event_tq, cpu));
916 		if (vmbus_pin_evttask) {
917 			CPU_SETOF(cpu, &cpu_mask);
918 			taskqueue_start_threads_cpuset(
919 			    VMBUS_PCPU_PTR(sc, event_tq, cpu), 1, PI_NET,
920 			    &cpu_mask, "hvevent%d", cpu);
921 		} else {
922 			taskqueue_start_threads(
923 			    VMBUS_PCPU_PTR(sc, event_tq, cpu), 1, PI_NET,
924 			    "hvevent%d", cpu);
925 		}
926 
927 		/*
928 		 * Setup tasks and taskqueues to handle messages.
929 		 */
930 		VMBUS_PCPU_GET(sc, message_tq, cpu) = taskqueue_create_fast(
931 		    "hyperv msg", M_WAITOK, taskqueue_thread_enqueue,
932 		    VMBUS_PCPU_PTR(sc, message_tq, cpu));
933 		CPU_SETOF(cpu, &cpu_mask);
934 		taskqueue_start_threads_cpuset(
935 		    VMBUS_PCPU_PTR(sc, message_tq, cpu), 1, PI_NET, &cpu_mask,
936 		    "hvmsg%d", cpu);
937 		TASK_INIT(VMBUS_PCPU_PTR(sc, message_task, cpu), 0,
938 		    vmbus_msg_task, sc);
939 	}
940 
941 	/*
942 	 * All Hyper-V ISR required resources are setup, now let's find a
943 	 * free IDT vector for Hyper-V ISR and set it up.
944 	 */
945 	sc->vmbus_idtvec = lapic_ipi_alloc(pti ? IDTVEC(vmbus_isr_pti) :
946 	    IDTVEC(vmbus_isr));
947 	if (sc->vmbus_idtvec < 0) {
948 		device_printf(sc->vmbus_dev, "cannot find free IDT vector\n");
949 		return ENXIO;
950 	}
951 	if (bootverbose) {
952 		device_printf(sc->vmbus_dev, "vmbus IDT vector %d\n",
953 		    sc->vmbus_idtvec);
954 	}
955 	return 0;
956 }
957 
958 static void
959 vmbus_intr_teardown(struct vmbus_softc *sc)
960 {
961 	int cpu;
962 
963 	if (sc->vmbus_idtvec >= 0) {
964 		lapic_ipi_free(sc->vmbus_idtvec);
965 		sc->vmbus_idtvec = -1;
966 	}
967 
968 	CPU_FOREACH(cpu) {
969 		if (VMBUS_PCPU_GET(sc, event_tq, cpu) != NULL) {
970 			taskqueue_free(VMBUS_PCPU_GET(sc, event_tq, cpu));
971 			VMBUS_PCPU_GET(sc, event_tq, cpu) = NULL;
972 		}
973 		if (VMBUS_PCPU_GET(sc, message_tq, cpu) != NULL) {
974 			taskqueue_drain(VMBUS_PCPU_GET(sc, message_tq, cpu),
975 			    VMBUS_PCPU_PTR(sc, message_task, cpu));
976 			taskqueue_free(VMBUS_PCPU_GET(sc, message_tq, cpu));
977 			VMBUS_PCPU_GET(sc, message_tq, cpu) = NULL;
978 		}
979 	}
980 }
981 
982 static int
983 vmbus_read_ivar(device_t dev, device_t child, int index, uintptr_t *result)
984 {
985 	return (ENOENT);
986 }
987 
988 static int
989 vmbus_child_pnpinfo_str(device_t dev, device_t child, char *buf, size_t buflen)
990 {
991 	const struct vmbus_channel *chan;
992 	char guidbuf[HYPERV_GUID_STRLEN];
993 
994 	chan = vmbus_get_channel(child);
995 	if (chan == NULL) {
996 		/* Event timer device, which does not belong to a channel */
997 		return (0);
998 	}
999 
1000 	strlcat(buf, "classid=", buflen);
1001 	hyperv_guid2str(&chan->ch_guid_type, guidbuf, sizeof(guidbuf));
1002 	strlcat(buf, guidbuf, buflen);
1003 
1004 	strlcat(buf, " deviceid=", buflen);
1005 	hyperv_guid2str(&chan->ch_guid_inst, guidbuf, sizeof(guidbuf));
1006 	strlcat(buf, guidbuf, buflen);
1007 
1008 	return (0);
1009 }
1010 
1011 int
1012 vmbus_add_child(struct vmbus_channel *chan)
1013 {
1014 	struct vmbus_softc *sc = chan->ch_vmbus;
1015 	device_t parent = sc->vmbus_dev;
1016 
1017 	mtx_lock(&Giant);
1018 
1019 	chan->ch_dev = device_add_child(parent, NULL, -1);
1020 	if (chan->ch_dev == NULL) {
1021 		mtx_unlock(&Giant);
1022 		device_printf(parent, "device_add_child for chan%u failed\n",
1023 		    chan->ch_id);
1024 		return (ENXIO);
1025 	}
1026 	device_set_ivars(chan->ch_dev, chan);
1027 	device_probe_and_attach(chan->ch_dev);
1028 
1029 	mtx_unlock(&Giant);
1030 	return (0);
1031 }
1032 
1033 int
1034 vmbus_delete_child(struct vmbus_channel *chan)
1035 {
1036 	int error = 0;
1037 
1038 	mtx_lock(&Giant);
1039 	if (chan->ch_dev != NULL) {
1040 		error = device_delete_child(chan->ch_vmbus->vmbus_dev,
1041 		    chan->ch_dev);
1042 		chan->ch_dev = NULL;
1043 	}
1044 	mtx_unlock(&Giant);
1045 	return (error);
1046 }
1047 
1048 static int
1049 vmbus_sysctl_version(SYSCTL_HANDLER_ARGS)
1050 {
1051 	struct vmbus_softc *sc = arg1;
1052 	char verstr[16];
1053 
1054 	snprintf(verstr, sizeof(verstr), "%u.%u",
1055 	    VMBUS_VERSION_MAJOR(sc->vmbus_version),
1056 	    VMBUS_VERSION_MINOR(sc->vmbus_version));
1057 	return sysctl_handle_string(oidp, verstr, sizeof(verstr), req);
1058 }
1059 
1060 /*
1061  * We need the function to make sure the MMIO resource is allocated from the
1062  * ranges found in _CRS.
1063  *
1064  * For the release function, we can use bus_generic_release_resource().
1065  */
1066 static struct resource *
1067 vmbus_alloc_resource(device_t dev, device_t child, int type, int *rid,
1068     rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
1069 {
1070 	device_t parent = device_get_parent(dev);
1071 	struct resource *res;
1072 
1073 #ifdef NEW_PCIB
1074 	if (type == SYS_RES_MEMORY) {
1075 		struct vmbus_softc *sc = device_get_softc(dev);
1076 
1077 		res = pcib_host_res_alloc(&sc->vmbus_mmio_res, child, type,
1078 		    rid, start, end, count, flags);
1079 	} else
1080 #endif
1081 	{
1082 		res = BUS_ALLOC_RESOURCE(parent, child, type, rid, start,
1083 		    end, count, flags);
1084 	}
1085 
1086 	return (res);
1087 }
1088 
1089 static int
1090 vmbus_alloc_msi(device_t bus, device_t dev, int count, int maxcount, int *irqs)
1091 {
1092 
1093 	return (PCIB_ALLOC_MSI(device_get_parent(bus), dev, count, maxcount,
1094 	    irqs));
1095 }
1096 
1097 static int
1098 vmbus_release_msi(device_t bus, device_t dev, int count, int *irqs)
1099 {
1100 
1101 	return (PCIB_RELEASE_MSI(device_get_parent(bus), dev, count, irqs));
1102 }
1103 
1104 static int
1105 vmbus_alloc_msix(device_t bus, device_t dev, int *irq)
1106 {
1107 
1108 	return (PCIB_ALLOC_MSIX(device_get_parent(bus), dev, irq));
1109 }
1110 
1111 static int
1112 vmbus_release_msix(device_t bus, device_t dev, int irq)
1113 {
1114 
1115 	return (PCIB_RELEASE_MSIX(device_get_parent(bus), dev, irq));
1116 }
1117 
1118 static int
1119 vmbus_map_msi(device_t bus, device_t dev, int irq, uint64_t *addr,
1120 	uint32_t *data)
1121 {
1122 
1123 	return (PCIB_MAP_MSI(device_get_parent(bus), dev, irq, addr, data));
1124 }
1125 
1126 static uint32_t
1127 vmbus_get_version_method(device_t bus, device_t dev)
1128 {
1129 	struct vmbus_softc *sc = device_get_softc(bus);
1130 
1131 	return sc->vmbus_version;
1132 }
1133 
1134 static int
1135 vmbus_probe_guid_method(device_t bus, device_t dev,
1136     const struct hyperv_guid *guid)
1137 {
1138 	const struct vmbus_channel *chan = vmbus_get_channel(dev);
1139 
1140 	if (memcmp(&chan->ch_guid_type, guid, sizeof(struct hyperv_guid)) == 0)
1141 		return 0;
1142 	return ENXIO;
1143 }
1144 
1145 static uint32_t
1146 vmbus_get_vcpu_id_method(device_t bus, device_t dev, int cpu)
1147 {
1148 	const struct vmbus_softc *sc = device_get_softc(bus);
1149 
1150 	return (VMBUS_PCPU_GET(sc, vcpuid, cpu));
1151 }
1152 
1153 static struct taskqueue *
1154 vmbus_get_eventtq_method(device_t bus, device_t dev __unused, int cpu)
1155 {
1156 	const struct vmbus_softc *sc = device_get_softc(bus);
1157 
1158 	KASSERT(cpu >= 0 && cpu < mp_ncpus, ("invalid cpu%d", cpu));
1159 	return (VMBUS_PCPU_GET(sc, event_tq, cpu));
1160 }
1161 
1162 #ifdef NEW_PCIB
1163 #define VTPM_BASE_ADDR 0xfed40000
1164 #define FOUR_GB (1ULL << 32)
1165 
1166 enum parse_pass { parse_64, parse_32 };
1167 
1168 struct parse_context {
1169 	device_t vmbus_dev;
1170 	enum parse_pass pass;
1171 };
1172 
1173 static ACPI_STATUS
1174 parse_crs(ACPI_RESOURCE *res, void *ctx)
1175 {
1176 	const struct parse_context *pc = ctx;
1177 	device_t vmbus_dev = pc->vmbus_dev;
1178 
1179 	struct vmbus_softc *sc = device_get_softc(vmbus_dev);
1180 	UINT64 start, end;
1181 
1182 	switch (res->Type) {
1183 	case ACPI_RESOURCE_TYPE_ADDRESS32:
1184 		start = res->Data.Address32.Address.Minimum;
1185 		end = res->Data.Address32.Address.Maximum;
1186 		break;
1187 
1188 	case ACPI_RESOURCE_TYPE_ADDRESS64:
1189 		start = res->Data.Address64.Address.Minimum;
1190 		end = res->Data.Address64.Address.Maximum;
1191 		break;
1192 
1193 	default:
1194 		/* Unused types. */
1195 		return (AE_OK);
1196 	}
1197 
1198 	/*
1199 	 * We don't use <1MB addresses.
1200 	 */
1201 	if (end < 0x100000)
1202 		return (AE_OK);
1203 
1204 	/* Don't conflict with vTPM. */
1205 	if (end >= VTPM_BASE_ADDR && start < VTPM_BASE_ADDR)
1206 		end = VTPM_BASE_ADDR - 1;
1207 
1208 	if ((pc->pass == parse_32 && start < FOUR_GB) ||
1209 	    (pc->pass == parse_64 && start >= FOUR_GB))
1210 		pcib_host_res_decodes(&sc->vmbus_mmio_res, SYS_RES_MEMORY,
1211 		    start, end, 0);
1212 
1213 	return (AE_OK);
1214 }
1215 
1216 static void
1217 vmbus_get_crs(device_t dev, device_t vmbus_dev, enum parse_pass pass)
1218 {
1219 	struct parse_context pc;
1220 	ACPI_STATUS status;
1221 
1222 	if (bootverbose)
1223 		device_printf(dev, "walking _CRS, pass=%d\n", pass);
1224 
1225 	pc.vmbus_dev = vmbus_dev;
1226 	pc.pass = pass;
1227 	status = AcpiWalkResources(acpi_get_handle(dev), "_CRS",
1228 			parse_crs, &pc);
1229 
1230 	if (bootverbose && ACPI_FAILURE(status))
1231 		device_printf(dev, "_CRS: not found, pass=%d\n", pass);
1232 }
1233 
1234 static void
1235 vmbus_get_mmio_res_pass(device_t dev, enum parse_pass pass)
1236 {
1237 	device_t acpi0, parent;
1238 
1239 	parent = device_get_parent(dev);
1240 
1241 	acpi0 = device_get_parent(parent);
1242 	if (strcmp("acpi0", device_get_nameunit(acpi0)) == 0) {
1243 		device_t *children;
1244 		int count;
1245 
1246 		/*
1247 		 * Try to locate VMBUS resources and find _CRS on them.
1248 		 */
1249 		if (device_get_children(acpi0, &children, &count) == 0) {
1250 			int i;
1251 
1252 			for (i = 0; i < count; ++i) {
1253 				if (!device_is_attached(children[i]))
1254 					continue;
1255 
1256 				if (strcmp("vmbus_res",
1257 				    device_get_name(children[i])) == 0)
1258 					vmbus_get_crs(children[i], dev, pass);
1259 			}
1260 			free(children, M_TEMP);
1261 		}
1262 
1263 		/*
1264 		 * Try to find _CRS on acpi.
1265 		 */
1266 		vmbus_get_crs(acpi0, dev, pass);
1267 	} else {
1268 		device_printf(dev, "not grandchild of acpi\n");
1269 	}
1270 
1271 	/*
1272 	 * Try to find _CRS on parent.
1273 	 */
1274 	vmbus_get_crs(parent, dev, pass);
1275 }
1276 
1277 static void
1278 vmbus_get_mmio_res(device_t dev)
1279 {
1280 	struct vmbus_softc *sc = device_get_softc(dev);
1281 	/*
1282 	 * We walk the resources twice to make sure that: in the resource
1283 	 * list, the 32-bit resources appear behind the 64-bit resources.
1284 	 * NB: resource_list_add() uses INSERT_TAIL. This way, when we
1285 	 * iterate through the list to find a range for a 64-bit BAR in
1286 	 * vmbus_alloc_resource(), we can make sure we try to use >4GB
1287 	 * ranges first.
1288 	 */
1289 	pcib_host_res_init(dev, &sc->vmbus_mmio_res);
1290 
1291 	vmbus_get_mmio_res_pass(dev, parse_64);
1292 	vmbus_get_mmio_res_pass(dev, parse_32);
1293 }
1294 
1295 static void
1296 vmbus_free_mmio_res(device_t dev)
1297 {
1298 	struct vmbus_softc *sc = device_get_softc(dev);
1299 
1300 	pcib_host_res_free(dev, &sc->vmbus_mmio_res);
1301 }
1302 #endif	/* NEW_PCIB */
1303 
1304 static void
1305 vmbus_identify(driver_t *driver, device_t parent)
1306 {
1307 
1308 	if (device_get_unit(parent) != 0 || vm_guest != VM_GUEST_HV ||
1309 	    (hyperv_features & CPUID_HV_MSR_SYNIC) == 0)
1310 		return;
1311 	device_add_child(parent, "vmbus", -1);
1312 }
1313 
1314 static int
1315 vmbus_probe(device_t dev)
1316 {
1317 
1318 	if (device_get_unit(dev) != 0 || vm_guest != VM_GUEST_HV ||
1319 	    (hyperv_features & CPUID_HV_MSR_SYNIC) == 0)
1320 		return (ENXIO);
1321 
1322 	device_set_desc(dev, "Hyper-V Vmbus");
1323 	return (BUS_PROBE_DEFAULT);
1324 }
1325 
1326 /**
1327  * @brief Main vmbus driver initialization routine.
1328  *
1329  * Here, we
1330  * - initialize the vmbus driver context
1331  * - setup various driver entry points
1332  * - invoke the vmbus hv main init routine
1333  * - get the irq resource
1334  * - invoke the vmbus to add the vmbus root device
1335  * - setup the vmbus root device
1336  * - retrieve the channel offers
1337  */
1338 static int
1339 vmbus_doattach(struct vmbus_softc *sc)
1340 {
1341 	struct sysctl_oid_list *child;
1342 	struct sysctl_ctx_list *ctx;
1343 	int ret;
1344 
1345 	if (sc->vmbus_flags & VMBUS_FLAG_ATTACHED)
1346 		return (0);
1347 
1348 #ifdef NEW_PCIB
1349 	vmbus_get_mmio_res(sc->vmbus_dev);
1350 #endif
1351 
1352 	sc->vmbus_flags |= VMBUS_FLAG_ATTACHED;
1353 
1354 	sc->vmbus_gpadl = VMBUS_GPADL_START;
1355 	mtx_init(&sc->vmbus_prichan_lock, "vmbus prichan", NULL, MTX_DEF);
1356 	TAILQ_INIT(&sc->vmbus_prichans);
1357 	mtx_init(&sc->vmbus_chan_lock, "vmbus channel", NULL, MTX_DEF);
1358 	TAILQ_INIT(&sc->vmbus_chans);
1359 	sc->vmbus_chmap = malloc(
1360 	    sizeof(struct vmbus_channel *) * VMBUS_CHAN_MAX, M_DEVBUF,
1361 	    M_WAITOK | M_ZERO);
1362 
1363 	/*
1364 	 * Create context for "post message" Hypercalls
1365 	 */
1366 	sc->vmbus_xc = vmbus_xact_ctx_create(bus_get_dma_tag(sc->vmbus_dev),
1367 	    HYPERCALL_POSTMSGIN_SIZE, VMBUS_MSG_SIZE,
1368 	    sizeof(struct vmbus_msghc));
1369 	if (sc->vmbus_xc == NULL) {
1370 		ret = ENXIO;
1371 		goto cleanup;
1372 	}
1373 
1374 	/*
1375 	 * Allocate DMA stuffs.
1376 	 */
1377 	ret = vmbus_dma_alloc(sc);
1378 	if (ret != 0)
1379 		goto cleanup;
1380 
1381 	/*
1382 	 * Setup interrupt.
1383 	 */
1384 	ret = vmbus_intr_setup(sc);
1385 	if (ret != 0)
1386 		goto cleanup;
1387 
1388 	/*
1389 	 * Setup SynIC.
1390 	 */
1391 	if (bootverbose)
1392 		device_printf(sc->vmbus_dev, "smp_started = %d\n", smp_started);
1393 	smp_rendezvous(NULL, vmbus_synic_setup, NULL, sc);
1394 	sc->vmbus_flags |= VMBUS_FLAG_SYNIC;
1395 
1396 	/*
1397 	 * Initialize vmbus, e.g. connect to Hypervisor.
1398 	 */
1399 	ret = vmbus_init(sc);
1400 	if (ret != 0)
1401 		goto cleanup;
1402 
1403 	if (sc->vmbus_version == VMBUS_VERSION_WS2008 ||
1404 	    sc->vmbus_version == VMBUS_VERSION_WIN7)
1405 		sc->vmbus_event_proc = vmbus_event_proc_compat;
1406 	else
1407 		sc->vmbus_event_proc = vmbus_event_proc;
1408 
1409 	ret = vmbus_scan(sc);
1410 	if (ret != 0)
1411 		goto cleanup;
1412 
1413 	ctx = device_get_sysctl_ctx(sc->vmbus_dev);
1414 	child = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->vmbus_dev));
1415 	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "version",
1416 	    CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0,
1417 	    vmbus_sysctl_version, "A", "vmbus version");
1418 
1419 	return (ret);
1420 
1421 cleanup:
1422 	vmbus_scan_teardown(sc);
1423 	vmbus_intr_teardown(sc);
1424 	vmbus_dma_free(sc);
1425 	if (sc->vmbus_xc != NULL) {
1426 		vmbus_xact_ctx_destroy(sc->vmbus_xc);
1427 		sc->vmbus_xc = NULL;
1428 	}
1429 	free(__DEVOLATILE(void *, sc->vmbus_chmap), M_DEVBUF);
1430 	mtx_destroy(&sc->vmbus_prichan_lock);
1431 	mtx_destroy(&sc->vmbus_chan_lock);
1432 
1433 	return (ret);
1434 }
1435 
1436 static void
1437 vmbus_event_proc_dummy(struct vmbus_softc *sc __unused, int cpu __unused)
1438 {
1439 }
1440 
1441 #ifdef EARLY_AP_STARTUP
1442 
1443 static void
1444 vmbus_intrhook(void *xsc)
1445 {
1446 	struct vmbus_softc *sc = xsc;
1447 
1448 	if (bootverbose)
1449 		device_printf(sc->vmbus_dev, "intrhook\n");
1450 	vmbus_doattach(sc);
1451 	config_intrhook_disestablish(&sc->vmbus_intrhook);
1452 }
1453 
1454 #endif	/* EARLY_AP_STARTUP */
1455 
1456 static int
1457 vmbus_attach(device_t dev)
1458 {
1459 	vmbus_sc = device_get_softc(dev);
1460 	vmbus_sc->vmbus_dev = dev;
1461 	vmbus_sc->vmbus_idtvec = -1;
1462 
1463 	/*
1464 	 * Event processing logic will be configured:
1465 	 * - After the vmbus protocol version negotiation.
1466 	 * - Before we request channel offers.
1467 	 */
1468 	vmbus_sc->vmbus_event_proc = vmbus_event_proc_dummy;
1469 
1470 #ifdef EARLY_AP_STARTUP
1471 	/*
1472 	 * Defer the real attach until the pause(9) works as expected.
1473 	 */
1474 	vmbus_sc->vmbus_intrhook.ich_func = vmbus_intrhook;
1475 	vmbus_sc->vmbus_intrhook.ich_arg = vmbus_sc;
1476 	config_intrhook_establish(&vmbus_sc->vmbus_intrhook);
1477 #else	/* !EARLY_AP_STARTUP */
1478 	/*
1479 	 * If the system has already booted and thread
1480 	 * scheduling is possible indicated by the global
1481 	 * cold set to zero, we just call the driver
1482 	 * initialization directly.
1483 	 */
1484 	if (!cold)
1485 		vmbus_doattach(vmbus_sc);
1486 #endif	/* EARLY_AP_STARTUP */
1487 
1488 	return (0);
1489 }
1490 
1491 static int
1492 vmbus_detach(device_t dev)
1493 {
1494 	struct vmbus_softc *sc = device_get_softc(dev);
1495 
1496 	bus_generic_detach(dev);
1497 	vmbus_chan_destroy_all(sc);
1498 
1499 	vmbus_scan_teardown(sc);
1500 
1501 	vmbus_disconnect(sc);
1502 
1503 	if (sc->vmbus_flags & VMBUS_FLAG_SYNIC) {
1504 		sc->vmbus_flags &= ~VMBUS_FLAG_SYNIC;
1505 		smp_rendezvous(NULL, vmbus_synic_teardown, NULL, NULL);
1506 	}
1507 
1508 	vmbus_intr_teardown(sc);
1509 	vmbus_dma_free(sc);
1510 
1511 	if (sc->vmbus_xc != NULL) {
1512 		vmbus_xact_ctx_destroy(sc->vmbus_xc);
1513 		sc->vmbus_xc = NULL;
1514 	}
1515 
1516 	free(__DEVOLATILE(void *, sc->vmbus_chmap), M_DEVBUF);
1517 	mtx_destroy(&sc->vmbus_prichan_lock);
1518 	mtx_destroy(&sc->vmbus_chan_lock);
1519 
1520 #ifdef NEW_PCIB
1521 	vmbus_free_mmio_res(dev);
1522 #endif
1523 
1524 	return (0);
1525 }
1526 
1527 #ifndef EARLY_AP_STARTUP
1528 
1529 static void
1530 vmbus_sysinit(void *arg __unused)
1531 {
1532 	struct vmbus_softc *sc = vmbus_get_softc();
1533 
1534 	if (vm_guest != VM_GUEST_HV || sc == NULL)
1535 		return;
1536 
1537 	/*
1538 	 * If the system has already booted and thread
1539 	 * scheduling is possible, as indicated by the
1540 	 * global cold set to zero, we just call the driver
1541 	 * initialization directly.
1542 	 */
1543 	if (!cold)
1544 		vmbus_doattach(sc);
1545 }
1546 /*
1547  * NOTE:
1548  * We have to start as the last step of SI_SUB_SMP, i.e. after SMP is
1549  * initialized.
1550  */
1551 SYSINIT(vmbus_initialize, SI_SUB_SMP, SI_ORDER_ANY, vmbus_sysinit, NULL);
1552 
1553 #endif	/* !EARLY_AP_STARTUP */
1554