]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/hyperv/vmbus/vmbus.c
Upgrade our copies of clang, llvm, lld, lldb, compiler-rt and libc++ to
[FreeBSD/FreeBSD.git] / sys / dev / hyperv / vmbus / vmbus.c
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 */