Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
Show First 20 Lines • Show All 139 Lines • ▼ Show 20 Lines | |||||
* The purpose of this routine is to determine the type of VMBUS protocol | * The purpose of this routine is to determine the type of VMBUS protocol | ||||
* message to process - an event or a channel message. | * message to process - an event or a channel message. | ||||
*/ | */ | ||||
static inline int | static inline int | ||||
hv_vmbus_isr(struct trapframe *frame) | hv_vmbus_isr(struct trapframe *frame) | ||||
{ | { | ||||
int cpu; | int cpu; | ||||
hv_vmbus_message* msg; | hv_vmbus_message* msg; | ||||
hv_vmbus_synic_event_flags* event; | |||||
void* page_addr; | void* page_addr; | ||||
cpu = PCPU_GET(cpuid); | cpu = PCPU_GET(cpuid); | ||||
/* | /* | ||||
* The Windows team has advised that we check for events | * The Windows team has advised that we check for events | ||||
* before checking for messages. This is the way they do it | * before checking for messages. This is the way they do it | ||||
* in Windows when running as a guest in Hyper-V | * in Windows when running as a guest in Hyper-V | ||||
*/ | */ | ||||
page_addr = hv_vmbus_g_context.syn_ic_event_page[cpu]; | |||||
event = (hv_vmbus_synic_event_flags*) | |||||
page_addr + HV_VMBUS_MESSAGE_SINT; | |||||
if ((hv_vmbus_protocal_version == HV_VMBUS_VERSION_WS2008) || | |||||
(hv_vmbus_protocal_version == HV_VMBUS_VERSION_WIN7)) { | |||||
/* Since we are a child, we only need to check bit 0 */ | |||||
if (synch_test_and_clear_bit(0, &event->flags32[0])) { | |||||
hv_vmbus_on_events(cpu); | hv_vmbus_on_events(cpu); | ||||
} | |||||
} else { | |||||
/* | |||||
* On host with Win8 or above, we can directly look at | |||||
* the event page. If bit n is set, we have an interrupt | |||||
* on the channel with id n. | |||||
* Directly schedule the event software interrupt on | |||||
* current cpu. | |||||
*/ | |||||
hv_vmbus_on_events(cpu); | |||||
} | |||||
/* Check if there are actual msgs to be process */ | /* Check if there are actual msgs to be process */ | ||||
page_addr = hv_vmbus_g_context.syn_ic_msg_page[cpu]; | page_addr = hv_vmbus_g_context.syn_ic_msg_page[cpu]; | ||||
msg = (hv_vmbus_message*) page_addr + HV_VMBUS_TIMER_SINT; | msg = (hv_vmbus_message*) page_addr + HV_VMBUS_TIMER_SINT; | ||||
/* we call eventtimer process the message */ | /* we call eventtimer process the message */ | ||||
if (msg->header.message_type == HV_MESSAGE_TIMER_EXPIRED) { | if (msg->header.message_type == HV_MESSAGE_TIMER_EXPIRED) { | ||||
msg->header.message_type = HV_MESSAGE_TYPE_NONE; | msg->header.message_type = HV_MESSAGE_TYPE_NONE; | ||||
▲ Show 20 Lines • Show All 490 Lines • Show Last 20 Lines |