Read from disk
Modified: branches/xen/reactos/boot/freeldr/freeldr/Makefile
Modified: branches/xen/reactos/boot/freeldr/freeldr/arch/i386/machxen.c
Modified: branches/xen/reactos/boot/freeldr/freeldr/arch/i386/machxen.h
Added: branches/xen/reactos/boot/freeldr/freeldr/arch/i386/xendisk.c
Modified: branches/xen/reactos/boot/freeldr/freeldr/arch/i386/xenevtchn.c
Modified: branches/xen/reactos/boot/freeldr/freeldr/arch/i386/xenmem.c

Modified: branches/xen/reactos/boot/freeldr/freeldr/Makefile
--- branches/xen/reactos/boot/freeldr/freeldr/Makefile	2005-04-14 21:46:14 UTC (rev 14621)
+++ branches/xen/reactos/boot/freeldr/freeldr/Makefile	2005-04-14 21:47:57 UTC (rev 14622)
@@ -173,6 +173,7 @@
   xboxvideo.o	\
   xencons.o \
   xenctrlif.o \
+  xendisk.o \
   xenentry.o \
   xenevtchn.o \
   xenmem.o \

Modified: branches/xen/reactos/boot/freeldr/freeldr/arch/i386/machxen.c
--- branches/xen/reactos/boot/freeldr/freeldr/arch/i386/machxen.c	2005-04-14 21:46:14 UTC (rev 14621)
+++ branches/xen/reactos/boot/freeldr/freeldr/arch/i386/machxen.c	2005-04-14 21:47:57 UTC (rev 14622)
@@ -274,14 +274,6 @@
   }
 
 BOOL
-XenDiskReadLogicalSectors(ULONG DriveNumber, ULONGLONG SectorNumber,
-                          ULONG SectorCount, PVOID Buffer)
-  {
-    XEN_UNIMPLEMENTED("XenDiskReadLogicalSectors");
-    return FALSE;
-  }
-
-BOOL
 XenDiskGetPartitionEntry(ULONG DriveNumber, ULONG PartitionNumber,
                          PPARTITION_TABLE_ENTRY PartitionTableEntry)
   {

Modified: branches/xen/reactos/boot/freeldr/freeldr/arch/i386/machxen.h
--- branches/xen/reactos/boot/freeldr/freeldr/arch/i386/machxen.h	2005-04-14 21:46:14 UTC (rev 14621)
+++ branches/xen/reactos/boot/freeldr/freeldr/arch/i386/machxen.h	2005-04-14 21:47:57 UTC (rev 14622)
@@ -35,7 +35,6 @@
 extern shared_info_t *XenSharedInfo;
 
 VOID XenMachInit(VOID);
-VOID XenMemInit(start_info_t *StartInfo);
 
 VOID XenCtrlIfInit();
 BOOL XenCtrlIfSendMessageNoblock(ctrl_msg_t *Msg);
@@ -46,6 +45,7 @@
 VOID XenCtrlIfHandleEvent();
 VOID XenCtrlIfSendResponse(ctrl_msg_t *Msg);
 
+VOID XenEvtchnRegisterDisk(unsigned DiskEvtchn);
 VOID XenEvtchnRegisterCtrlIf(unsigned CtrlIfEvtchn);
 VOID XenEvtchnDisableEvents();
 VOID XenEvtchnEnableEvents();
@@ -71,11 +71,14 @@
 VOID XenVideoPrepareForReactOS(VOID);
 
 ULONG XenMemGetMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize);
+VOID XenMemInit(start_info_t *StartInfo);
+u32 XenMemVirtualToMachine(void *VirtualAddress);
 
 BOOL XenDiskReadLogicalSectors(ULONG DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer);
 BOOL XenDiskGetPartitionEntry(ULONG DriveNumber, ULONG PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry);
 BOOL XenDiskGetDriveGeometry(ULONG DriveNumber, PGEOMETRY DriveGeometry);
 ULONG XenDiskGetCacheableBlockCount(ULONG DriveNumber);
+VOID XenDiskHandleEvent();
 
 VOID XenRTCGetCurrentDateTime(PULONG Year, PULONG Month, PULONG Day, PULONG Hour, PULONG Minute, PULONG Second);
 

Added: branches/xen/reactos/boot/freeldr/freeldr/arch/i386/xendisk.c
--- branches/xen/reactos/boot/freeldr/freeldr/arch/i386/xendisk.c	2005-04-14 21:46:14 UTC (rev 14621)
+++ branches/xen/reactos/boot/freeldr/freeldr/arch/i386/xendisk.c	2005-04-14 21:47:57 UTC (rev 14622)
@@ -0,0 +1,523 @@
+/*
+ *  FreeLoader
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Based on XenoLinux drivers/xen/blkfront/blkfront.c
+ * Copyright (c) 2003-2004, Keir Fraser & Steve Hand
+ * Modifications by Mark A. Williamson are (c) Intel Research Cambridge
+ * Copyright (c) 2004, Christian Limpach
+ * Copyright (c) 2004, Andrew Warfield
+ * Copyright (c) 2005, Christopher Clark
+ * 
+ * This file may be distributed separately from the Linux kernel, or
+ * incorporated into other software packages, subject to the following license:
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "freeldr.h"
+#include "machxen.h"
+#include "evtchn.h"
+#include "io/blkif.h"
+#if 2 != XEN_VER
+#include "io/ring.h"
+#endif /* XEN_VER */
+
+#define DISK_STATE_CLOSED       0
+#define DISK_STATE_DISCONNECTED 1
+#define DISK_STATE_CONNECTED    2
+
+typedef struct _XENDISKINFO
+{
+  ULONGLONG SectorCount;
+  ULONG DriveNumber;
+  blkif_vdev_t XenDevice;
+  u16 XenInfo;
+} XENDISKINFO, *PXENDISKINFO;
+
+static BOOL XenDiskInitialized = FALSE;
+static unsigned XenDiskState = DISK_STATE_CLOSED;
+static unsigned XenDiskEvtchn;
+#if 2 == XEN_VER
+static blkif_ring_t *XenDiskRing = NULL;
+static BLKIF_RING_IDX XenDiskRespCons; /* Response consumer for comms ring. */
+static BLKIF_RING_IDX XenDiskReqProd;  /* Private request producer.         */
+#else
+static blkif_front_ring_t XenDiskRing;
+#endif /* XEN_VER */
+static BOOL XenDiskRspReceived;
+static unsigned XenDiskCount;
+static PXENDISKINFO XenDiskInfo;
+
+static void *XenDiskScratchPage;
+static u32 XenDiskScratchMachine;
+
+static void *
+XenDiskAllocatePageAlignedMemory(unsigned Size)
+{
+  void *Area;
+
+  Area = MmAllocateMemory(Size);
+  if (0 != ((ULONG_PTR) Area & (PAGE_SIZE - 1)))
+    {
+      printf("Got an unaligned page\n");
+      XenDie();
+    }
+
+  return Area;
+}
+
+/* Tell the controller to bring up the interface. */
+static void
+XenDiskSendInterfaceConnect(void)
+{
+  ctrl_msg_t CMsg;
+  blkif_fe_interface_connect_t *Msg;
+
+  CMsg.type    = CMSG_BLKIF_FE,
+  CMsg.subtype = CMSG_BLKIF_FE_INTERFACE_CONNECT,
+  CMsg.length  = sizeof(blkif_fe_interface_connect_t),
+  Msg = (void*)CMsg.msg;
+
+  Msg->handle      = 0;
+#if 2 == XEN_VER
+  Msg->shmem_frame = (XenMemVirtualToMachine(XenDiskRing) >> PAGE_SHIFT);
+#else /* XEN_VER */
+  Msg->shmem_frame = (XenMemVirtualToMachine(XenDiskRing.sring) >> PAGE_SHIFT);
+#endif /* XEN_VER */
+
+  XenCtrlIfSendMessageBlock(&CMsg);
+}
+
+/* Move from CLOSED to DISCONNECTED state. */
+static void
+XenDiskDisconnect(void)
+{
+#if 2 == XEN_VER
+  if (NULL != XenDiskRing)
+    {
+      MmFreeMemory(XenDiskRing);
+    }
+
+  XenDiskRing = (blkif_ring_t *)XenDiskAllocatePageAlignedMemory(PAGE_SIZE);
+  XenDiskRing->req_prod = 0;
+  XenDiskRing->resp_prod = 0;
+  XenDiskRespCons = 0;
+  XenDiskReqProd = 0;
+#else /* XEN_VER */
+  blkif_sring_t *SRing;
+
+  if (NULL != XenDiskRing.sring)
+    {
+      MmFreeMemory(XenDiskRing.sring);
+    }
+
+  SRing = (blkif_sring_t *)XenDiskAllocatePageAlignedMemory(PAGE_SIZE);
+  SHARED_RING_INIT(SRing);
+  FRONT_RING_INIT(&XenDiskRing, SRing, PAGE_SIZE);
+#endif /* XEN_VER */
+
+  XenDiskState  = DISK_STATE_DISCONNECTED;
+  XenDiskSendInterfaceConnect();
+}
+
+VOID
+XenDiskHandleEvent()
+{
+  XenDiskRspReceived = TRUE;
+}
+
+static void
+XenDiskConnect(blkif_fe_interface_status_t *Status)
+{
+  XenDiskEvtchn = Status->evtchn;
+  XenEvtchnRegisterDisk(XenDiskEvtchn);
+
+#ifdef CONFIG_XEN_BLKDEV_GRANT
+  rdomid       = status->domid;
+#endif
+
+  XenDiskState = DISK_STATE_CONNECTED;
+}
+
+static void
+XenDiskFree(void)
+{
+  XenDiskState = DISK_STATE_DISCONNECTED;
+
+  /* Free resources associated with old device channel. */
+#if 2 == XEN_VER
+  if (NULL != XenDiskRing)
+    {
+      MmFreeMemory(XenDiskRing);
+      XenDiskRing = NULL;
+    }
+#else /* XEN_VER */
+  if (NULL != XenDiskRing.sring)
+    {
+      MmFreeMemory(XenDiskRing.sring);
+      XenDiskRing.sring = NULL;
+    }
+#endif /* XEN_VER */
+
+  XenDiskEvtchn = 0;
+}
+
+static void
+XenDiskReset()
+{
+  XenDiskFree();
+  XenDiskDisconnect();
+}
+
+static void
+XenDiskStatus(blkif_fe_interface_status_t *Status)
+{
+  switch (Status->status)
+    {
+    case BLKIF_INTERFACE_STATUS_DISCONNECTED:
+      switch (XenDiskState)
+        {
+        case DISK_STATE_CLOSED:
+          XenDiskDisconnect();
+          break;
+        case DISK_STATE_DISCONNECTED:
+        case DISK_STATE_CONNECTED:
+          /* unexpected(status); */ /* occurs during suspend/resume */
+          XenDiskReset();
+          break;
+        }
+        break;
+
+    case BLKIF_INTERFACE_STATUS_CONNECTED:
+      switch (XenDiskState)
+        {
+        case DISK_STATE_CLOSED:
+          XenDiskDisconnect();
+          XenDiskConnect(Status);
+          break;
+        case DISK_STATE_DISCONNECTED:
+          XenDiskConnect(Status);
+          break;
+        case DISK_STATE_CONNECTED:
+          XenDiskConnect(Status);
+          break;
+        }
+      break;
+
+    default:
+      break;
+    }
+}
+
+static void
+XenDiskMsgHandler(ctrl_msg_t *Msg, unsigned long Id)
+{
+  switch (Msg->subtype)
+    {
+    case CMSG_BLKIF_FE_INTERFACE_STATUS:
+      XenDiskStatus((blkif_fe_interface_status_t *)
+                    &Msg->msg[0]);
+      break;
+    default:
+      Msg->length = 0;
+      break;
+    }
+
+  XenCtrlIfSendResponse(Msg);
+}
+
+static void
+XenDiskSendDriverStatus(BOOL Up)
+{
+  ctrl_msg_t CMsg;
+  blkif_fe_driver_status_t *Msg = (void*) CMsg.msg;
+
+  CMsg.type = CMSG_BLKIF_FE;
+  CMsg.subtype = CMSG_BLKIF_FE_DRIVER_STATUS;
+  CMsg.length  = sizeof(blkif_fe_driver_status_t);
+
+  Msg->status = (Up ? BLKIF_DRIVER_STATUS_UP : BLKIF_DRIVER_STATUS_DOWN);
+
+  XenCtrlIfSendMessageBlock(&CMsg);
+}
+
+static void
+XenDiskWaitForState(unsigned State)
+{
+  /* FIXME maybe introduce a timeout here? */
+  while (TRUE)
+    {
+      XenEvtchnDisableEvents();
+      if (XenDiskState == State)
+        {
+          XenEvtchnEnableEvents();
+          return;
+        }
+      HYPERVISOR_block();
+    }
+}
+
+static BOOL
+XenDiskControlSend(blkif_request_t *Req, blkif_response_t *Rsp)
+{
+#if 2 != XEN_VER
+  blkif_request_t *DReq;
+#endif /* XEN_VER */
+  blkif_response_t *SRsp;
+
+  while (TRUE)
+    {
+      XenEvtchnDisableEvents();
+#if 2 == XEN_VER
+      if (BLKIF_RING_SIZE != (XenDiskReqProd - XenDiskRespCons))
+#else /* XEN_VER */
+      if (! RING_FULL(&XenDiskRing))
+#endif
+        {
+          break;
+        }
+      HYPERVISOR_block();
+    }
+
+  if (DISK_STATE_CONNECTED != XenDiskState)
+    {
+      XenEvtchnEnableEvents();
+      return FALSE;
+    }
+
+#if 2 == XEN_VER
+  XenDiskRing->ring[MASK_BLKIF_IDX(XenDiskReqProd)].req = *Req;
+  XenDiskReqProd++;
+  XenDiskRing->req_prod = XenDiskReqProd;
+#else /* XEN_VER */
+  DReq = RING_GET_REQUEST(&XenDiskRing, XenDiskRing.req_prod_pvt);
+  *DReq = *Req;
+
+  XenDiskRing.req_prod_pvt++;
+  RING_PUSH_REQUESTS(&XenDiskRing);
+#endif /* XEN_VER */
+  XenDiskRspReceived = FALSE;
+
+  XenEvtchnEnableEvents();
+
+  notify_via_evtchn(XenDiskEvtchn);
+
+  while (TRUE)
+    {
+      XenEvtchnDisableEvents();
+      if (XenDiskRspReceived)
+        {
+          break;
+        }
+      HYPERVISOR_block();
+    }
+
+  if (DISK_STATE_CONNECTED != XenDiskState)
+    {
+      XenEvtchnEnableEvents();
+      return FALSE;
+    }
+
+#if 2 == XEN_VER
+  SRsp = &XenDiskRing->ring[MASK_BLKIF_IDX(XenDiskRespCons)].resp;
+  *Rsp = *SRsp;
+  XenDiskRespCons++;
+#else /* XEN_VER */
+  SRsp = RING_GET_RESPONSE(&XenDiskRing, XenDiskRing.rsp_cons);
+  *Rsp = *SRsp;
+  XenDiskRing.rsp_cons++;
+#endif /* XEN_VER */
+
+  XenDiskRspReceived = FALSE;
+  XenEvtchnEnableEvents();
+
+  return TRUE;
+}
+
+static void
+XenDiskProbe()
+{
+  blkif_response_t Rsp;
+  blkif_request_t Req;
+  unsigned Disk;
+  vdisk_t *Probe;
+  ULONG FloppyNumber, CDRomNumber, HarddiskNumber;
+
+  memset(&Req, 0, sizeof(blkif_request_t));
+  Req.operation = BLKIF_OP_PROBE;
+  Req.nr_segments = 1;
+#ifdef CONFIG_XEN_BLKDEV_GRANT
+  blkif_control_probe_send(&req, &rsp,
+                           (unsigned long)(virt_to_machine(buf)));
+#else
+  Req.frame_and_sects[0] = XenDiskScratchMachine | 7;
+
+  if (! XenDiskControlSend(&Req, &Rsp))
+    {
+      printf("Unexpected disk disconnect\n");
+      XenDie();
+    }
+#endif
+
+  if (Rsp.status <= 0)
+    {
+      printf("Could not probe disks (%d)\n", Rsp.status);
+      XenDie();
+    }
+
+  XenDiskCount = Rsp.status;
+  XenDiskInfo = MmAllocateMemory(XenDiskCount * sizeof(XENDISKINFO));
+  if (NULL == XenDiskInfo)
+    {
+      XenDie();
+    }
+  Probe = (vdisk_t *) XenDiskScratchPage;
+  FloppyNumber = 0x00;
+  HarddiskNumber = 0x80;
+  CDRomNumber = 0x9f;
+  for (Disk = 0; Disk < XenDiskCount; Disk++)
+    {
+      XenDiskInfo[Disk].SectorCount = Probe[Disk].capacity;
+      switch (VDISK_TYPE(Probe[Disk].info))
+        {
+          case VDISK_TYPE_FLOPPY:
+            XenDiskInfo[Disk].DriveNumber = FloppyNumber++;
+            break;
+          case VDISK_TYPE_CDROM:
+            XenDiskInfo[Disk].DriveNumber = CDRomNumber--;
+            break;
+          case VDISK_TYPE_DISK:
+            XenDiskInfo[Disk].DriveNumber = HarddiskNumber++;
+            break;
+          case VDISK_TYPE_TAPE:
+          case VDISK_TYPE_OPTICAL:
+          default:
+            XenDiskInfo[Disk].DriveNumber = 0xff;
+            break;
+        }
+      XenDiskInfo[Disk].XenDevice = Probe[Disk].device;
+      XenDiskInfo[Disk].XenInfo = Probe[Disk].info;
+    }
+}
+
+static void
+XenDiskInit()
+{
+  XenDiskState = DISK_STATE_CLOSED;
+
+  if (NULL == XenDiskScratchPage)
+    {
+      XenDiskScratchPage = XenDiskAllocatePageAlignedMemory(PAGE_SIZE);
+      XenDiskScratchMachine = XenMemVirtualToMachine(XenDiskScratchPage);
+    }
+
+  XenCtrlIfRegisterReceiver(CMSG_BLKIF_FE, XenDiskMsgHandler);
+
+  XenDiskSendDriverStatus(TRUE);
+  XenDiskWaitForState(DISK_STATE_CONNECTED);
+
+  XenDiskProbe();
+}
+
+BOOL
+XenDiskReadLogicalSectors(ULONG DriveNumber, ULONGLONG SectorNumber,
+                          ULONG SectorCount, PVOID Buffer)
+{
+  blkif_response_t Rsp;
+  blkif_request_t Req;
+  ULONG SectorSize;
+  ULONG Count;
+  BOOL Found;
+  unsigned Disk;
+  blkif_vdev_t Device;
+
+  if (! XenDiskInitialized)
+    {
+      XenDiskInitialized = TRUE;
+      XenDiskInit();
+    }
+
+  Found = FALSE;
+  Device = 0;
+  for (Disk = 0; Disk < XenDiskCount && ! Found; Disk++)
+    {
+      if (DriveNumber == XenDiskInfo[Disk].DriveNumber)
+        {
+          Device = XenDiskInfo[Disk].XenDevice;
+          Found = TRUE;
+        }
+    }
+  if (! Found)
+    {
+      return FALSE;
+    }
+
+  SectorSize = 512;
+  while (0 < SectorCount)
+    {
+      Count = SectorCount;
+      if (PAGE_SIZE / SectorSize < Count)
+        {
+          Count = PAGE_SIZE / SectorSize;
+        }
+      memset(&Req, 0, sizeof(blkif_request_t));
+      Req.operation = BLKIF_OP_READ;
+      Req.nr_segments = 1;
+      Req.device = Device;
+      Req.id = 0;
+      Req.sector_number = SectorNumber;
+#ifdef CONFIG_XEN_BLKDEV_GRANT
+      blkif_control_probe_send(&req, &rsp,
+                               (unsigned long)(virt_to_machine(buf)));
+#else
+      Req.frame_and_sects[0] = XenDiskScratchMachine | (Count - 1);
+
+      if (! XenDiskControlSend(&Req, &Rsp))
+        {
+          return FALSE;
+        }
+#endif
+      if (BLKIF_RSP_OKAY != Rsp.status)
+        {
+          return FALSE;
+        }
+      memcpy(Buffer, XenDiskScratchPage, Count * SectorSize);
+      SectorCount -= Count;
+      SectorNumber += Count;
+      Buffer = (void *)((char *) Buffer + Count * SectorSize);
+    }
+
+  return TRUE;
+}
+
+/* EOF */
Property changes on: branches/xen/reactos/boot/freeldr/freeldr/arch/i386/xendisk.c
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:eol-style
   + native

Modified: branches/xen/reactos/boot/freeldr/freeldr/arch/i386/xenevtchn.c
--- branches/xen/reactos/boot/freeldr/freeldr/arch/i386/xenevtchn.c	2005-04-14 21:46:14 UTC (rev 14621)
+++ branches/xen/reactos/boot/freeldr/freeldr/arch/i386/xenevtchn.c	2005-04-14 21:47:57 UTC (rev 14622)
@@ -46,17 +46,16 @@
 
 #define asmlinkage __attribute__((regparm(0)))
 
-static unsigned XenCtrlIfIndex;
+static int XenCtrlIfIndex = -1;
 static u32 XenCtrlIfBit;
+static int XenDiskIndex = -1;
+static u32 XenDiskBit;
 
-VOID
-XenEvtchnRegisterCtrlIf(unsigned CtrlIfEvtchn)
+static void
+XenEvtchnSetMask()
 {
   unsigned i;
 
-  XenCtrlIfIndex = CtrlIfEvtchn >> 5;
-  XenCtrlIfBit = 1 << (CtrlIfEvtchn & 0x1f);
-
   /* Mask all event channels except the one we're interested in */
   for (i = 0;
        i < sizeof(XenSharedInfo->evtchn_mask)
@@ -65,8 +64,19 @@
     {
       if (i == XenCtrlIfIndex)
         {
-          XenSharedInfo->evtchn_mask[i] = ~ XenCtrlIfBit;
+          if (i == XenDiskIndex)
+            {
+              XenSharedInfo->evtchn_mask[i] = ~ (XenCtrlIfBit | XenDiskBit);
+            }
+          else
+            {
+              XenSharedInfo->evtchn_mask[i] = ~ XenCtrlIfBit;
+            }
         }
+      else if (i == XenDiskIndex)
+        {
+          XenSharedInfo->evtchn_mask[i] = ~ XenDiskBit;
+        }
       else
         {
           XenSharedInfo->evtchn_mask[i] = ~ 0;
@@ -74,6 +84,24 @@
     }
 }
 
+VOID
+XenEvtchnRegisterCtrlIf(unsigned CtrlIfEvtchn)
+{
+  XenCtrlIfIndex = CtrlIfEvtchn >> 5;
+  XenCtrlIfBit = 1 << (CtrlIfEvtchn & 0x1f);
+
+  XenEvtchnSetMask();
+}
+
+VOID
+XenEvtchnRegisterDisk(unsigned DiskEvtchn)
+{
+  XenDiskIndex = DiskEvtchn >> 5;
+  XenDiskBit = 1 << (DiskEvtchn & 0x1f);
+
+  XenEvtchnSetMask();
+}
+
 /* NB. Event delivery is disabled on entry. */
 asmlinkage void
 XenEvtchnDoUpcall(struct pt_regs *Regs)
@@ -85,12 +113,31 @@
   XenSharedInfo->vcpu_data[0].evtchn_pending_sel = 0;
 #endif /* XEN_VER */
 
-  while (0 != (XenSharedInfo->evtchn_pending[XenCtrlIfIndex]
-               & ~ XenSharedInfo->evtchn_mask[XenCtrlIfIndex]
-               & XenCtrlIfBit))
+  while ((0 <= XenDiskIndex
+          && 0 != (XenSharedInfo->evtchn_pending[XenDiskIndex]
+                   & ~ XenSharedInfo->evtchn_mask[XenDiskIndex]
+                   & XenDiskBit)) ||
+         (0 <= XenCtrlIfIndex
+          && 0 != (XenSharedInfo->evtchn_pending[XenCtrlIfIndex]
+                   & ~ XenSharedInfo->evtchn_mask[XenCtrlIfIndex]
+                   & XenCtrlIfBit)))
     {
-      XenSharedInfo->evtchn_pending[XenCtrlIfIndex] &= ~ XenCtrlIfBit;
-      XenCtrlIfHandleEvent();
+      if (0 <= XenDiskIndex
+          && 0 != (XenSharedInfo->evtchn_pending[XenDiskIndex]
+                   & ~ XenSharedInfo->evtchn_mask[XenDiskIndex]
+                   & XenDiskBit))
+        {
+          XenSharedInfo->evtchn_pending[XenDiskIndex] &= ~ XenDiskBit;
+          XenDiskHandleEvent();
+        }
+      if (0 <= XenCtrlIfIndex
+          && 0 != (XenSharedInfo->evtchn_pending[XenCtrlIfIndex]
+                   & ~ XenSharedInfo->evtchn_mask[XenCtrlIfIndex]
+                   & XenCtrlIfBit))
+        {
+          XenSharedInfo->evtchn_pending[XenCtrlIfIndex] &= ~ XenCtrlIfBit;
+          XenCtrlIfHandleEvent();
+        }
     }
 }
 

Modified: branches/xen/reactos/boot/freeldr/freeldr/arch/i386/xenmem.c
--- branches/xen/reactos/boot/freeldr/freeldr/arch/i386/xenmem.c	2005-04-14 21:46:14 UTC (rev 14621)
+++ branches/xen/reactos/boot/freeldr/freeldr/arch/i386/xenmem.c	2005-04-14 21:47:57 UTC (rev 14622)
@@ -26,13 +26,13 @@
 /* Page Directory Entry */
 typedef struct _PDE
 {
-  unsigned long Pde;
+  u32 Pde;
 } PDE, *PPDE;
 
 /* Page Table Entry */
 typedef struct _PTE
 {
-  unsigned long Pte;
+  u32 Pte;
 } PTE, *PPTE;
 
 #define PGDIR_SHIFT   22
@@ -308,4 +308,15 @@
     }
 }
 
+u32
+XenMemVirtualToMachine(void *VirtualAddress)
+{
+  PPTE PageTable;
+
+  PageTable = (PPTE)((char *) XenPageDir +
+                     (PD_IDX((ULONG_PTR) VirtualAddress) + 1) * PAGE_SIZE);
+  return PageTable[PT_IDX((ULONG_PTR) VirtualAddress)].Pte
+         & PAGE_MASK;
+}
+
 /* EOF */