win-pvdrivers

changeset 341:744c19115142

save/restore now works when /gplpv is _not_ specified. Still a way to go before it works when /gplpv is specified...
author James Harper <james.harper@bendigoit.com.au>
date Wed Jun 25 10:26:51 2008 +1000 (2008-06-25)
parents 2be08f708250
children eabe51317e3a
files xenpci/evtchn.c xenpci/xenbus.c xenpci/xenpci.h xenpci/xenpci_fdo.c
line diff
     1.1 --- a/xenpci/evtchn.c	Sun Jun 22 18:14:30 2008 -0700
     1.2 +++ b/xenpci/evtchn.c	Wed Jun 25 10:26:51 2008 +1000
     1.3 @@ -98,10 +98,15 @@ EvtChn_DpcBounce(PRKDPC Dpc, PVOID Conte
     1.4    UNREFERENCED_PARAMETER(SystemArgument1);
     1.5    UNREFERENCED_PARAMETER(SystemArgument2);
     1.6  
     1.7 +if (((PXENPCI_DEVICE_DATA)action->xpdd)->suspending)
     1.8 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
     1.9 +
    1.10    if (action->type == EVT_ACTION_TYPE_IRQ)
    1.11      sw_interrupt((UCHAR)action->vector);
    1.12    else
    1.13      action->ServiceRoutine(NULL, action->ServiceContext);
    1.14 +if (((PXENPCI_DEVICE_DATA)action->xpdd)->suspending)
    1.15 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    1.16  }
    1.17  
    1.18  static DDKAPI BOOLEAN
    1.19 @@ -117,7 +122,8 @@ EvtChn_Interrupt(PKINTERRUPT Interrupt, 
    1.20    unsigned int port;
    1.21    ev_action_t *ev_action;
    1.22  
    1.23 -//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ " (cpu = %d)\n", cpu));
    1.24 +if (xpdd->suspending)
    1.25 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ " (cpu = %d)\n", cpu));
    1.26  
    1.27    UNREFERENCED_PARAMETER(Interrupt);
    1.28  
    1.29 @@ -151,7 +157,8 @@ EvtChn_Interrupt(PKINTERRUPT Interrupt, 
    1.30      }
    1.31    }
    1.32  
    1.33 -//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    1.34 +if (xpdd->suspending)
    1.35 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    1.36  
    1.37    return TRUE;
    1.38  }
    1.39 @@ -172,6 +179,7 @@ EvtChn_Bind(PVOID Context, evtchn_port_t
    1.40  
    1.41    xpdd->ev_actions[Port].ServiceRoutine = ServiceRoutine;
    1.42    xpdd->ev_actions[Port].ServiceContext = ServiceContext;
    1.43 +  xpdd->ev_actions[Port].xpdd = xpdd;
    1.44    KeMemoryBarrier();
    1.45    xpdd->ev_actions[Port].type = EVT_ACTION_TYPE_NORMAL;
    1.46  
    1.47 @@ -198,6 +206,7 @@ EvtChn_BindDpc(PVOID Context, evtchn_por
    1.48  
    1.49    xpdd->ev_actions[Port].ServiceRoutine = ServiceRoutine;
    1.50    xpdd->ev_actions[Port].ServiceContext = ServiceContext;
    1.51 +  xpdd->ev_actions[Port].xpdd = xpdd;
    1.52    KeInitializeDpc(&xpdd->ev_actions[Port].Dpc, EvtChn_DpcBounce, &xpdd->ev_actions[Port]);
    1.53    KeMemoryBarrier(); // make sure that the new service routine is only called once the context is set up
    1.54    xpdd->ev_actions[Port].type = EVT_ACTION_TYPE_DPC;
    1.55 @@ -225,6 +234,7 @@ EvtChn_BindIrq(PVOID Context, evtchn_por
    1.56  
    1.57    KeInitializeDpc(&xpdd->ev_actions[Port].Dpc, EvtChn_DpcBounce, &xpdd->ev_actions[Port]);
    1.58    xpdd->ev_actions[Port].vector = vector;
    1.59 +  xpdd->ev_actions[Port].xpdd = xpdd;
    1.60    KeMemoryBarrier();
    1.61    xpdd->ev_actions[Port].type = EVT_ACTION_TYPE_IRQ;
    1.62  
     2.1 --- a/xenpci/xenbus.c	Sun Jun 22 18:14:30 2008 -0700
     2.2 +++ b/xenpci/xenbus.c	Wed Jun 25 10:26:51 2008 +1000
     2.3 @@ -41,7 +41,8 @@ static int allocate_xenbus_id(PXENPCI_DE
     2.4    static int probe;
     2.5    int o_probe;
     2.6  
     2.7 -//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
     2.8 +if (xpdd->suspending)
     2.9 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    2.10  
    2.11    for (;;)
    2.12    {
    2.13 @@ -68,7 +69,8 @@ static int allocate_xenbus_id(PXENPCI_DE
    2.14    //init_waitqueue_head(&req_info[o_probe].waitq);
    2.15    KeInitializeEvent(&xpdd->req_info[o_probe].WaitEvent, SynchronizationEvent, FALSE);
    2.16  
    2.17 -//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    2.18 +if (xpdd->suspending)
    2.19 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    2.20  
    2.21    return o_probe;
    2.22  }
    2.23 @@ -136,7 +138,8 @@ static void xb_write(
    2.24    struct xsd_sockmsg m = {type, req_id, trans_id };
    2.25    struct write_req header_req = { &m, sizeof(m) };
    2.26  
    2.27 -//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    2.28 +if (xpdd->suspending)
    2.29 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    2.30  
    2.31    for (r = 0; r < nr_reqs; r++)
    2.32      len += (size_t)req[r].len;
    2.33 @@ -201,7 +204,8 @@ static void xb_write(
    2.34    /* Send evtchn to notify remote */
    2.35    EvtChn_Notify(xpdd, xpdd->xen_store_evtchn);
    2.36  
    2.37 -//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    2.38 +if (xpdd->suspending)
    2.39 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    2.40  }
    2.41  
    2.42  static struct xsd_sockmsg *
    2.43 @@ -214,7 +218,8 @@ xenbus_msg_reply(
    2.44  {
    2.45    int id;
    2.46  
    2.47 -//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    2.48 +if (xpdd->suspending)
    2.49 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    2.50  
    2.51    id = allocate_xenbus_id(xpdd);
    2.52  
    2.53 @@ -224,7 +229,8 @@ xenbus_msg_reply(
    2.54  
    2.55    release_xenbus_id(xpdd, id);
    2.56  
    2.57 -//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    2.58 +if (xpdd->suspending)
    2.59 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    2.60  
    2.61    return xpdd->req_info[id].Reply;
    2.62  }
    2.63 @@ -242,7 +248,8 @@ XenBus_Read(
    2.64    char *res;
    2.65    char *msg;
    2.66  
    2.67 -//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    2.68 +if (xpdd->suspending)
    2.69 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    2.70  
    2.71    ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
    2.72  
    2.73 @@ -258,7 +265,8 @@ XenBus_Read(
    2.74    ExFreePoolWithTag(rep, XENPCI_POOL_TAG);
    2.75    *value = res;
    2.76  
    2.77 -//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    2.78 +if (xpdd->suspending)
    2.79 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    2.80  
    2.81    return NULL;
    2.82  }
    2.83 @@ -280,7 +288,8 @@ XenBus_Write(
    2.84    struct xsd_sockmsg *rep;
    2.85    char *msg;
    2.86  
    2.87 -//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    2.88 +if (xpdd->suspending)
    2.89 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    2.90  
    2.91    ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
    2.92  
    2.93 @@ -290,7 +299,8 @@ XenBus_Write(
    2.94      return msg;
    2.95    ExFreePoolWithTag(rep, XENPCI_POOL_TAG);
    2.96  
    2.97 -//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    2.98 +if (xpdd->suspending)
    2.99 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   2.100  
   2.101    return NULL;
   2.102  }
   2.103 @@ -596,10 +606,20 @@ VOID
   2.104  XenBus_Resume(PXENPCI_DEVICE_DATA xpdd)
   2.105  {
   2.106    int i;
   2.107 +
   2.108 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   2.109 +  
   2.110 +  hvm_set_parameter(xpdd, HVM_PARAM_CALLBACK_IRQ, xpdd->irq_number);
   2.111    
   2.112    for (i = 0; i < MAX_WATCH_ENTRIES; i++)
   2.113 +  {
   2.114      if (xpdd->XenBus_WatchEntries[i].Active)
   2.115 +    {
   2.116 +      KdPrint((__DRIVER_NAME "     Adding watch for path = %s\n", xpdd->XenBus_WatchEntries[i].Path));
   2.117        XenBus_SendAddWatch(xpdd, XBT_NIL, xpdd->XenBus_WatchEntries[i].Path, i);
   2.118 +    }
   2.119 +  }
   2.120 +  KdPrint((__DRIVER_NAME " <-- XenBus_AddWatch\n"));
   2.121  }
   2.122  
   2.123  char *
   2.124 @@ -651,11 +671,11 @@ XenBus_AddWatch(
   2.125    if (msg)
   2.126    {
   2.127      xpdd->XenBus_WatchEntries[i].Active = 0;
   2.128 -    KdPrint((__DRIVER_NAME " <-- XenBus_AddWatch (%s)\n", msg));
   2.129 +    //KdPrint((__DRIVER_NAME " <-- XenBus_AddWatch (%s)\n", msg));
   2.130      return msg;
   2.131    }
   2.132  
   2.133 -  KdPrint((__DRIVER_NAME " <-- XenBus_AddWatch\n"));
   2.134 +  //KdPrint((__DRIVER_NAME " <-- XenBus_AddWatch\n"));
   2.135  
   2.136    return NULL;
   2.137  }
     3.1 --- a/xenpci/xenpci.h	Sun Jun 22 18:14:30 2008 -0700
     3.2 +++ b/xenpci/xenpci.h	Wed Jun 25 10:26:51 2008 +1000
     3.3 @@ -78,6 +78,7 @@ typedef struct _ev_action_t {
     3.4    KDPC Dpc;
     3.5    ULONG vector;
     3.6    ULONG Count;
     3.7 +  PVOID xpdd;
     3.8  } ev_action_t;
     3.9  
    3.10  typedef struct _XENBUS_WATCH_RING
    3.11 @@ -172,6 +173,7 @@ typedef struct {
    3.12    KIRQL irq_level;
    3.13    KAFFINITY irq_affinity;
    3.14  
    3.15 +  PHYSICAL_ADDRESS shared_info_area_unmapped;
    3.16    shared_info_t *shared_info_area;
    3.17  
    3.18    PHYSICAL_ADDRESS platform_mmio_addr;
     4.1 --- a/xenpci/xenpci_fdo.c	Sun Jun 22 18:14:30 2008 -0700
     4.2 +++ b/xenpci/xenpci_fdo.c	Wed Jun 25 10:26:51 2008 +1000
     4.3 @@ -132,32 +132,31 @@ XenPci_Init(PXENPCI_DEVICE_DATA xpdd)
     4.4  {
     4.5    struct xen_add_to_physmap xatp;
     4.6    int ret;
     4.7 -  PHYSICAL_ADDRESS shared_info_area_unmapped;
     4.8  
     4.9    KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    4.10  
    4.11    hvm_get_stubs(xpdd);
    4.12  
    4.13 -  shared_info_area_unmapped = XenPci_AllocMMIO(xpdd, PAGE_SIZE);
    4.14 -  KdPrint((__DRIVER_NAME " shared_info_area_unmapped.QuadPart = %lx\n", shared_info_area_unmapped.QuadPart));
    4.15 +  if (!xpdd->shared_info_area_unmapped.QuadPart)
    4.16 +  {
    4.17 +    xpdd->shared_info_area_unmapped = XenPci_AllocMMIO(xpdd, PAGE_SIZE);
    4.18 +    xpdd->shared_info_area = MmMapIoSpace(xpdd->shared_info_area_unmapped,
    4.19 +      PAGE_SIZE, MmNonCached);
    4.20 +  }
    4.21 +  KdPrint((__DRIVER_NAME " shared_info_area_unmapped.QuadPart = %lx\n", xpdd->shared_info_area_unmapped.QuadPart));
    4.22    xatp.domid = DOMID_SELF;
    4.23    xatp.idx = 0;
    4.24    xatp.space = XENMAPSPACE_shared_info;
    4.25 -  xatp.gpfn = (xen_pfn_t)(shared_info_area_unmapped.QuadPart >> PAGE_SHIFT);
    4.26 +  xatp.gpfn = (xen_pfn_t)(xpdd->shared_info_area_unmapped.QuadPart >> PAGE_SHIFT);
    4.27    KdPrint((__DRIVER_NAME " gpfn = %d\n", xatp.gpfn));
    4.28    ret = HYPERVISOR_memory_op(xpdd, XENMEM_add_to_physmap, &xatp);
    4.29    KdPrint((__DRIVER_NAME " hypervisor memory op ret = %d\n", ret));
    4.30 -  xpdd->shared_info_area = MmMapIoSpace(shared_info_area_unmapped,
    4.31 -    PAGE_SIZE, MmNonCached);
    4.32 +
    4.33    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    4.34  
    4.35    return STATUS_SUCCESS;
    4.36  }
    4.37  
    4.38 -#if 0
    4.39 -WDFQUEUE ReadQueue;
    4.40 -#endif
    4.41 -
    4.42  static NTSTATUS
    4.43  XenPci_Pnp_IoCompletion(PDEVICE_OBJECT device_object, PIRP irp, PVOID context)
    4.44  {
    4.45 @@ -302,9 +301,24 @@ XenBus_ShutdownIoCancel(PDEVICE_OBJECT d
    4.46    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
    4.47  }
    4.48  
    4.49 +static VOID
    4.50 +XenPci_CompleteResume(PDEVICE_OBJECT device_object, PVOID context)
    4.51 +{
    4.52 +  PXENPCI_DEVICE_DATA xpdd;
    4.53 +
    4.54 +  UNREFERENCED_PARAMETER(context);
    4.55 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    4.56 +
    4.57 +  xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
    4.58 +
    4.59 +  XenBus_Resume(xpdd);
    4.60 +
    4.61 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    4.62 +}
    4.63 +
    4.64  struct {
    4.65 -  ULONG do_spin;
    4.66 -  ULONG nr_spinning;
    4.67 +  volatile ULONG do_spin;
    4.68 +  volatile LONG nr_spinning;
    4.69  } typedef SUSPEND_INFO, *PSUSPEND_INFO;
    4.70  
    4.71  static VOID
    4.72 @@ -317,9 +331,10 @@ XenPci_Suspend(
    4.73    PXENPCI_DEVICE_DATA xpdd = Context;
    4.74    PSUSPEND_INFO suspend_info = SystemArgument1;
    4.75    ULONG ActiveProcessorCount;
    4.76 -  KIRQL OldIrql;
    4.77 +  KIRQL old_irql;
    4.78    int cancelled;
    4.79    int i;
    4.80 +  PIO_WORKITEM work_item;
    4.81  
    4.82    UNREFERENCED_PARAMETER(Dpc);
    4.83    UNREFERENCED_PARAMETER(SystemArgument2);
    4.84 @@ -328,34 +343,42 @@ XenPci_Suspend(
    4.85  
    4.86    if (KeGetCurrentProcessorNumber() != 0)
    4.87    {
    4.88 +    KeRaiseIrql(HIGH_LEVEL, &old_irql);
    4.89      KdPrint((__DRIVER_NAME "     spinning...\n"));
    4.90 -    InterlockedIncrement((volatile LONG *)&suspend_info->nr_spinning);
    4.91 +    InterlockedIncrement(&suspend_info->nr_spinning);
    4.92      KeMemoryBarrier();
    4.93      while(suspend_info->do_spin)
    4.94      {
    4.95        /* we should be able to wait more nicely than this... */
    4.96      }
    4.97      KeMemoryBarrier();
    4.98 -    InterlockedDecrement((volatile LONG *)&suspend_info->nr_spinning);    
    4.99 +    InterlockedDecrement(&suspend_info->nr_spinning);    
   4.100      KdPrint((__DRIVER_NAME "     ...done spinning\n"));
   4.101      KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n", KeGetCurrentProcessorNumber()));
   4.102 +    KeLowerIrql(old_irql);
   4.103      return;
   4.104    }
   4.105    ActiveProcessorCount = (ULONG)KeNumberProcessors;
   4.106  
   4.107 +  KeRaiseIrql(HIGH_LEVEL, &old_irql);
   4.108 +  
   4.109    KdPrint((__DRIVER_NAME "     waiting for all other processors to spin\n"));
   4.110 -  while (suspend_info->nr_spinning < ActiveProcessorCount - 1)
   4.111 +  while (suspend_info->nr_spinning < (LONG)ActiveProcessorCount - 1)
   4.112    {
   4.113        /* we should be able to wait more nicely than this... */
   4.114    }
   4.115    KdPrint((__DRIVER_NAME "     all other processors are spinning\n"));
   4.116  
   4.117 -  KeRaiseIrql(HIGH_LEVEL, &OldIrql);
   4.118    KdPrint((__DRIVER_NAME "     calling suspend\n"));
   4.119    cancelled = hvm_shutdown(Context, SHUTDOWN_suspend);
   4.120    KdPrint((__DRIVER_NAME "     back from suspend, cancelled = %d\n", cancelled));
   4.121 -  KeLowerIrql(OldIrql);
   4.122  
   4.123 +  XenPci_Init(xpdd);
   4.124 +
   4.125 +  GntTbl_Map(Context, 0, NR_GRANT_FRAMES - 1);
   4.126 +
   4.127 +  KeLowerIrql(old_irql);
   4.128 +  
   4.129    KdPrint((__DRIVER_NAME "     waiting for all other processors to stop spinning\n"));
   4.130    suspend_info->do_spin = 0;
   4.131    while (suspend_info->nr_spinning != 0)
   4.132 @@ -364,19 +387,19 @@ XenPci_Suspend(
   4.133    }
   4.134    KdPrint((__DRIVER_NAME "     all other processors have stopped spinning\n"));
   4.135  
   4.136 +  // enable xen interrupts again
   4.137    for (i = 0; i < MAX_VIRT_CPUS; i++)
   4.138    {
   4.139 -    xpdd->shared_info_area->vcpu_info[i].evtchn_upcall_mask = 1;
   4.140 +    xpdd->shared_info_area->vcpu_info[i].evtchn_upcall_mask = 0;
   4.141    }
   4.142  
   4.143 -  GntTbl_Map(Context, 0, NR_GRANT_FRAMES - 1);
   4.144 -  XenBus_Resume(xpdd);
   4.145 -  // TODO: Enable xenbus
   4.146 -  // TODO: Enable all our devices  
   4.147 -
   4.148 -  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n", KeGetCurrentProcessorNumber()));
   4.149 +	work_item = IoAllocateWorkItem(xpdd->common.fdo);
   4.150 +	IoQueueWorkItem(work_item, XenPci_CompleteResume, DelayedWorkQueue, NULL);
   4.151 +  
   4.152 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   4.153  }
   4.154  
   4.155 +/* Called at PASSIVE_LEVEL */
   4.156  static VOID
   4.157  XenPci_BeginSuspend(PXENPCI_DEVICE_DATA xpdd)
   4.158  {
   4.159 @@ -403,6 +426,8 @@ XenPci_BeginSuspend(PXENPCI_DEVICE_DATA 
   4.160      {
   4.161        xpdd->shared_info_area->vcpu_info[i].evtchn_upcall_mask = 1;
   4.162      }
   4.163 +    KeFlushQueuedDpcs();
   4.164 +
   4.165      //ActiveProcessorCount = KeQueryActiveProcessorCount(&ActiveProcessorMask); // this is for Vista+
   4.166      ActiveProcessorCount = (ULONG)KeNumberProcessors;
   4.167      KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);