Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/hyperv/vmbus/vmbus.c
Show First 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | |||||
#include <sys/mutex.h> | #include <sys/mutex.h> | ||||
#include <sys/sbuf.h> | #include <sys/sbuf.h> | ||||
#include <sys/smp.h> | #include <sys/smp.h> | ||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <sys/taskqueue.h> | #include <sys/taskqueue.h> | ||||
#include <vm/vm.h> | #include <vm/vm.h> | ||||
#include <vm/vm_extern.h> | |||||
#include <vm/vm_param.h> | #include <vm/vm_param.h> | ||||
#include <vm/pmap.h> | #include <vm/pmap.h> | ||||
#include <machine/bus.h> | #include <machine/bus.h> | ||||
#if defined(__aarch64__) | #if defined(__aarch64__) | ||||
#include <dev/psci/smccc.h> | #include <dev/psci/smccc.h> | ||||
#include <dev/hyperv/vmbus/aarch64/hyperv_machdep.h> | #include <dev/hyperv/vmbus/aarch64/hyperv_machdep.h> | ||||
#include <dev/hyperv/vmbus/aarch64/hyperv_reg.h> | #include <dev/hyperv/vmbus/aarch64/hyperv_reg.h> | ||||
▲ Show 20 Lines • Show All 362 Lines • ▼ Show 20 Lines | vmbus_connect(struct vmbus_softc *sc, uint32_t version) | ||||
mh = vmbus_msghc_get(sc, sizeof(*req)); | mh = vmbus_msghc_get(sc, sizeof(*req)); | ||||
if (mh == NULL) | if (mh == NULL) | ||||
return ENXIO; | return ENXIO; | ||||
req = vmbus_msghc_dataptr(mh); | req = vmbus_msghc_dataptr(mh); | ||||
req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_CONNECT; | req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_CONNECT; | ||||
req->chm_ver = version; | req->chm_ver = version; | ||||
req->chm_evtflags = sc->vmbus_evtflags_dma.hv_paddr; | req->chm_evtflags = pmap_kextract((vm_offset_t)sc->vmbus_evtflags); | ||||
req->chm_mnf1 = sc->vmbus_mnf1_dma.hv_paddr; | req->chm_mnf1 = pmap_kextract((vm_offset_t)sc->vmbus_mnf1); | ||||
req->chm_mnf2 = sc->vmbus_mnf2_dma.hv_paddr; | req->chm_mnf2 = pmap_kextract((vm_offset_t)sc->vmbus_mnf2); | ||||
error = vmbus_msghc_exec(sc, mh); | error = vmbus_msghc_exec(sc, mh); | ||||
if (error) { | if (error) { | ||||
vmbus_msghc_put(sc, mh); | vmbus_msghc_put(sc, mh); | ||||
return error; | return error; | ||||
} | } | ||||
msg = vmbus_msghc_wait_result(sc, mh); | msg = vmbus_msghc_wait_result(sc, mh); | ||||
▲ Show 20 Lines • Show All 300 Lines • ▼ Show 20 Lines | if (hyperv_features & CPUID_HV_MSR_VP_INDEX) { | ||||
/* Set virtual processor id to 0 for compatibility. */ | /* Set virtual processor id to 0 for compatibility. */ | ||||
VMBUS_PCPU_GET(sc, vcpuid, cpu) = 0; | VMBUS_PCPU_GET(sc, vcpuid, cpu) = 0; | ||||
} | } | ||||
/* | /* | ||||
* Setup the SynIC message. | * Setup the SynIC message. | ||||
*/ | */ | ||||
orig = RDMSR(MSR_HV_SIMP); | orig = RDMSR(MSR_HV_SIMP); | ||||
val = MSR_HV_SIMP_ENABLE | (orig & MSR_HV_SIMP_RSVD_MASK) | | val = pmap_kextract((vm_offset_t)VMBUS_PCPU_GET(sc, message, cpu)) & | ||||
((VMBUS_PCPU_GET(sc, message_dma.hv_paddr, cpu) >> PAGE_SHIFT) | MSR_HV_SIMP_PGMASK; | ||||
schakrabarti_microsoft.com: Please use a Macro here instead 12 bit shift. Same for the code below. | |||||
<< MSR_HV_SIMP_PGSHIFT); | val |= MSR_HV_SIMP_ENABLE | (orig & MSR_HV_SIMP_RSVD_MASK); | ||||
WRMSR(MSR_HV_SIMP, val); | WRMSR(MSR_HV_SIMP, val); | ||||
/* | /* | ||||
* Setup the SynIC event flags. | * Setup the SynIC event flags. | ||||
*/ | */ | ||||
orig = RDMSR(MSR_HV_SIEFP); | orig = RDMSR(MSR_HV_SIEFP); | ||||
val = MSR_HV_SIEFP_ENABLE | (orig & MSR_HV_SIEFP_RSVD_MASK) | | val = pmap_kextract((vm_offset_t)VMBUS_PCPU_GET(sc, event_flags, cpu)) & | ||||
((VMBUS_PCPU_GET(sc, event_flags_dma.hv_paddr, cpu) >> PAGE_SHIFT) | MSR_HV_SIMP_PGMASK; | ||||
<< MSR_HV_SIEFP_PGSHIFT); | val |= MSR_HV_SIEFP_ENABLE | (orig & MSR_HV_SIEFP_RSVD_MASK); | ||||
WRMSR(MSR_HV_SIEFP, val); | WRMSR(MSR_HV_SIEFP, val); | ||||
/* | /* | ||||
* Configure and unmask SINT for message and event flags. | * Configure and unmask SINT for message and event flags. | ||||
*/ | */ | ||||
sint = MSR_HV_SINT0 + VMBUS_SINT_MESSAGE; | sint = MSR_HV_SINT0 + VMBUS_SINT_MESSAGE; | ||||
orig = RDMSR(sint); | orig = RDMSR(sint); | ||||
val = sc->vmbus_idtvec | MSR_HV_SINT_AUTOEOI | | val = sc->vmbus_idtvec | MSR_HV_SINT_AUTOEOI | | ||||
▲ Show 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | vmbus_synic_teardown(void *arg) | ||||
*/ | */ | ||||
orig = RDMSR(MSR_HV_SIEFP); | orig = RDMSR(MSR_HV_SIEFP); | ||||
WRMSR(MSR_HV_SIEFP, (orig & MSR_HV_SIEFP_RSVD_MASK)); | WRMSR(MSR_HV_SIEFP, (orig & MSR_HV_SIEFP_RSVD_MASK)); | ||||
} | } | ||||
static int | static int | ||||
vmbus_dma_alloc(struct vmbus_softc *sc) | vmbus_dma_alloc(struct vmbus_softc *sc) | ||||
{ | { | ||||
bus_dma_tag_t parent_dtag; | |||||
uint8_t *evtflags; | uint8_t *evtflags; | ||||
int cpu; | int cpu; | ||||
parent_dtag = bus_get_dma_tag(sc->vmbus_dev); | |||||
CPU_FOREACH(cpu) { | CPU_FOREACH(cpu) { | ||||
void *ptr; | void *ptr; | ||||
/* | /* | ||||
* Per-cpu messages and event flags. | * Per-cpu messages and event flags. | ||||
*/ | */ | ||||
ptr = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0, | ptr = contigmalloc(PAGE_SIZE, M_DEVBUF, M_WAITOK | M_ZERO, | ||||
PAGE_SIZE, VMBUS_PCPU_PTR(sc, message_dma, cpu), | 0ul, ~0ul, PAGE_SIZE, 0); | ||||
BUS_DMA_WAITOK | BUS_DMA_ZERO); | |||||
if (ptr == NULL) | if (ptr == NULL) | ||||
return ENOMEM; | return ENOMEM; | ||||
VMBUS_PCPU_GET(sc, message, cpu) = ptr; | VMBUS_PCPU_GET(sc, message, cpu) = ptr; | ||||
ptr = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0, | ptr = contigmalloc(PAGE_SIZE, M_DEVBUF, M_WAITOK | M_ZERO, | ||||
PAGE_SIZE, VMBUS_PCPU_PTR(sc, event_flags_dma, cpu), | 0ul, ~0ul, PAGE_SIZE, 0); | ||||
BUS_DMA_WAITOK | BUS_DMA_ZERO); | |||||
if (ptr == NULL) | if (ptr == NULL) | ||||
return ENOMEM; | return ENOMEM; | ||||
VMBUS_PCPU_GET(sc, event_flags, cpu) = ptr; | VMBUS_PCPU_GET(sc, event_flags, cpu) = ptr; | ||||
} | } | ||||
evtflags = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0, | evtflags = contigmalloc(PAGE_SIZE, M_DEVBUF, M_WAITOK | M_ZERO, | ||||
PAGE_SIZE, &sc->vmbus_evtflags_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO); | 0ul, ~0ul, PAGE_SIZE, 0); | ||||
if (evtflags == NULL) | if (evtflags == NULL) | ||||
return ENOMEM; | return ENOMEM; | ||||
sc->vmbus_rx_evtflags = (u_long *)evtflags; | sc->vmbus_rx_evtflags = (u_long *)evtflags; | ||||
sc->vmbus_tx_evtflags = (u_long *)(evtflags + (PAGE_SIZE / 2)); | sc->vmbus_tx_evtflags = (u_long *)(evtflags + (PAGE_SIZE / 2)); | ||||
sc->vmbus_evtflags = evtflags; | sc->vmbus_evtflags = evtflags; | ||||
sc->vmbus_mnf1 = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0, | sc->vmbus_mnf1 = contigmalloc(PAGE_SIZE, M_DEVBUF, M_WAITOK | M_ZERO, | ||||
PAGE_SIZE, &sc->vmbus_mnf1_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO); | 0ul, ~0ul, PAGE_SIZE, 0); | ||||
if (sc->vmbus_mnf1 == NULL) | if (sc->vmbus_mnf1 == NULL) | ||||
return ENOMEM; | return ENOMEM; | ||||
sc->vmbus_mnf2 = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0, | sc->vmbus_mnf2 = contigmalloc(sizeof(struct vmbus_mnf), M_DEVBUF, | ||||
sizeof(struct vmbus_mnf), &sc->vmbus_mnf2_dma, | M_WAITOK | M_ZERO, 0ul, ~0ul, PAGE_SIZE, 0); | ||||
BUS_DMA_WAITOK | BUS_DMA_ZERO); | |||||
if (sc->vmbus_mnf2 == NULL) | if (sc->vmbus_mnf2 == NULL) | ||||
return ENOMEM; | return ENOMEM; | ||||
return 0; | return 0; | ||||
} | } | ||||
static void | static void | ||||
vmbus_dma_free(struct vmbus_softc *sc) | vmbus_dma_free(struct vmbus_softc *sc) | ||||
{ | { | ||||
int cpu; | int cpu; | ||||
if (sc->vmbus_evtflags != NULL) { | if (sc->vmbus_evtflags != NULL) { | ||||
hyperv_dmamem_free(&sc->vmbus_evtflags_dma, sc->vmbus_evtflags); | contigfree(sc->vmbus_evtflags, PAGE_SIZE, M_DEVBUF); | ||||
sc->vmbus_evtflags = NULL; | sc->vmbus_evtflags = NULL; | ||||
sc->vmbus_rx_evtflags = NULL; | sc->vmbus_rx_evtflags = NULL; | ||||
sc->vmbus_tx_evtflags = NULL; | sc->vmbus_tx_evtflags = NULL; | ||||
} | } | ||||
if (sc->vmbus_mnf1 != NULL) { | if (sc->vmbus_mnf1 != NULL) { | ||||
hyperv_dmamem_free(&sc->vmbus_mnf1_dma, sc->vmbus_mnf1); | contigfree(sc->vmbus_mnf1, PAGE_SIZE, M_DEVBUF); | ||||
sc->vmbus_mnf1 = NULL; | sc->vmbus_mnf1 = NULL; | ||||
} | } | ||||
if (sc->vmbus_mnf2 != NULL) { | if (sc->vmbus_mnf2 != NULL) { | ||||
hyperv_dmamem_free(&sc->vmbus_mnf2_dma, sc->vmbus_mnf2); | contigfree(sc->vmbus_mnf2, sizeof(struct vmbus_mnf), M_DEVBUF); | ||||
sc->vmbus_mnf2 = NULL; | sc->vmbus_mnf2 = NULL; | ||||
} | } | ||||
CPU_FOREACH(cpu) { | CPU_FOREACH(cpu) { | ||||
if (VMBUS_PCPU_GET(sc, message, cpu) != NULL) { | if (VMBUS_PCPU_GET(sc, message, cpu) != NULL) { | ||||
hyperv_dmamem_free( | contigfree(VMBUS_PCPU_GET(sc, message, cpu), PAGE_SIZE, | ||||
VMBUS_PCPU_PTR(sc, message_dma, cpu), | M_DEVBUF); | ||||
VMBUS_PCPU_GET(sc, message, cpu)); | |||||
VMBUS_PCPU_GET(sc, message, cpu) = NULL; | VMBUS_PCPU_GET(sc, message, cpu) = NULL; | ||||
} | } | ||||
if (VMBUS_PCPU_GET(sc, event_flags, cpu) != NULL) { | if (VMBUS_PCPU_GET(sc, event_flags, cpu) != NULL) { | ||||
hyperv_dmamem_free( | contigfree(VMBUS_PCPU_GET(sc, event_flags, cpu), | ||||
VMBUS_PCPU_PTR(sc, event_flags_dma, cpu), | PAGE_SIZE, M_DEVBUF); | ||||
VMBUS_PCPU_GET(sc, event_flags, cpu)); | |||||
VMBUS_PCPU_GET(sc, event_flags, cpu) = NULL; | VMBUS_PCPU_GET(sc, event_flags, cpu) = NULL; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
static int | static int | ||||
vmbus_intr_setup(struct vmbus_softc *sc) | vmbus_intr_setup(struct vmbus_softc *sc) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 700 Lines • Show Last 20 Lines |
Please use a Macro here instead 12 bit shift. Same for the code below.