⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 agp.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * VideoPort driver
 *
 * Copyright (C) 2002, 2003, 2004 ReactOS Team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; see the file COPYING.LIB.
 * If not, write to the Free Software Foundation,
 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 * $Id$
 */

#include "videoprt.h"
#include <initguid.h>
#include <wdmguid.h>

/* PRIVATE FUNCTIONS **********************************************************/

NTSTATUS
IopInitiatePnpIrp(
  PDEVICE_OBJECT DeviceObject,
  PIO_STATUS_BLOCK IoStatusBlock,
  ULONG MinorFunction,
  PIO_STACK_LOCATION Stack OPTIONAL)
{
  PDEVICE_OBJECT TopDeviceObject;
  PIO_STACK_LOCATION IrpSp;
  NTSTATUS Status;
  KEVENT Event;
  PIRP Irp;

  /* Always call the top of the device stack */
  TopDeviceObject = IoGetAttachedDeviceReference(DeviceObject);

  KeInitializeEvent(
    &Event,
    NotificationEvent,
    FALSE);

  Irp = IoBuildSynchronousFsdRequest(
    IRP_MJ_PNP,
    TopDeviceObject,
    NULL,
    0,
    NULL,
    &Event,
    IoStatusBlock);

  /* PNP IRPs are always initialized with a status code of
     STATUS_NOT_IMPLEMENTED */
  Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
  Irp->IoStatus.Information = 0;

  IrpSp = IoGetNextIrpStackLocation(Irp);
  IrpSp->MinorFunction = MinorFunction;

  if (Stack)
  {
    RtlMoveMemory(
      &IrpSp->Parameters,
      &Stack->Parameters,
      sizeof(Stack->Parameters));
  }

  Status = IoCallDriver(TopDeviceObject, Irp);
  if (Status == STATUS_PENDING)
    {
      KeWaitForSingleObject(
        &Event,
        Executive,
        KernelMode,
        FALSE,
        NULL);
      Status = IoStatusBlock->Status;
    }

  ObDereferenceObject(TopDeviceObject);

  return Status;
}


BOOLEAN NTAPI
IntAgpCommitPhysical(
   IN PVOID HwDeviceExtension,
   IN PVOID PhysicalContext,
   IN ULONG Pages,
   IN ULONG Offset)
{
   PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
   PAGP_BUS_INTERFACE_STANDARD AgpBusInterface;
   PHYSICAL_ADDRESS MappingAddr = {{0}};
   PVIDEO_PORT_AGP_MAPPING AgpMapping;
   NTSTATUS Status;

   DPRINT("AgpCommitPhysical - PhysicalContext: 0x%x Pages: %d, Offset: 0x%x\n",
          PhysicalContext, Pages, Offset);

   DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
   AgpBusInterface = &DeviceExtension->AgpInterface;
   AgpMapping = (PVIDEO_PORT_AGP_MAPPING)PhysicalContext;

   Status = AgpBusInterface->CommitMemory(AgpBusInterface->AgpContext,
                                          AgpMapping->MapHandle, Pages, Offset,
                                          NULL, &MappingAddr);

   if (!NT_SUCCESS(Status))
   {
      DPRINT1("Warning: AgpBusInterface->CommitMemory failed (Status = 0x%x)\n",
              Status);
   }
   return NT_SUCCESS(Status);
}

VOID NTAPI
IntAgpFreePhysical(
   IN PVOID HwDeviceExtension,
   IN PVOID PhysicalContext,
   IN ULONG Pages,
   IN ULONG Offset)
{
   PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
   PAGP_BUS_INTERFACE_STANDARD AgpBusInterface;
   PVIDEO_PORT_AGP_MAPPING AgpMapping;
   NTSTATUS Status;

   DPRINT("AgpFreePhysical - PhysicalContext: 0x%x Pages: %d, Offset: 0x%x\n",
          PhysicalContext, Pages, Offset);

   DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
   AgpBusInterface = &DeviceExtension->AgpInterface;
   AgpMapping = (PVIDEO_PORT_AGP_MAPPING)PhysicalContext;

   Status = AgpBusInterface->FreeMemory(AgpBusInterface->AgpContext,
                                        AgpMapping->MapHandle, Pages, Offset);
   if (!NT_SUCCESS(Status))
   {
      DPRINT1("Warning: AgpBusInterface->FreeMemory failed (Status = 0x%x)\n",
              Status);
   }
}

VOID NTAPI
IntAgpReleasePhysical(
   IN PVOID HwDeviceExtension,
   IN PVOID PhysicalContext)
{
   PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
   PAGP_BUS_INTERFACE_STANDARD AgpBusInterface;
   PVIDEO_PORT_AGP_MAPPING AgpMapping;
   NTSTATUS Status;

   DPRINT("AgpReleasePhysical - PhysicalContext: 0x%x\n", PhysicalContext);

   DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
   AgpBusInterface = &DeviceExtension->AgpInterface;
   AgpMapping = (PVIDEO_PORT_AGP_MAPPING)PhysicalContext;
   
   /* Release memory */
   Status = AgpBusInterface->ReleaseMemory(AgpBusInterface->AgpContext,
                                           AgpMapping->MapHandle);
   if (!NT_SUCCESS(Status))
   {
      DPRINT1("Warning: AgpBusInterface->ReleaseMemory failed (Status = 0x%x)\n",
              Status);
   }
   
   /* Free resources */
   ExFreePool(AgpMapping);
}

PHYSICAL_ADDRESS NTAPI
IntAgpReservePhysical(
   IN  PVOID HwDeviceExtension,
   IN  ULONG Pages,
   IN  VIDEO_PORT_CACHE_TYPE Caching,
   OUT PVOID *PhysicalContext)
{
   PHYSICAL_ADDRESS ZeroAddress = {{0}};
   PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
   PAGP_BUS_INTERFACE_STANDARD AgpBusInterface;
   MEMORY_CACHING_TYPE MemCachingType;
   PVIDEO_PORT_AGP_MAPPING AgpMapping;
   NTSTATUS Status;

   DPRINT("AgpReservePhysical - Pages: %d, Caching: 0x%x\n", Pages, Caching);

   DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
   AgpBusInterface = &DeviceExtension->AgpInterface;

   /* Translate memory caching type */
   if (Caching == VpNonCached)
     MemCachingType = MmNonCached;
   else if (Caching == VpCached)
     MemCachingType = MmCached;
   else if (Caching == VpWriteCombined)
     MemCachingType = MmWriteCombined;
   else
   {
      DPRINT1("Invalid caching type %d!\n", Caching);
      return ZeroAddress;
   }

   /* Allocate an AGP mapping structure */
   AgpMapping = ExAllocatePoolWithTag(PagedPool,
                                      sizeof(VIDEO_PORT_AGP_MAPPING),
                                      TAG_VIDEO_PORT);
   if (AgpMapping == NULL)
   {
      DPRINT1("Out of memory! Couldn't allocate AGP mapping structure!\n");
      return ZeroAddress;
   }
   RtlZeroMemory(AgpMapping, sizeof(VIDEO_PORT_AGP_MAPPING));

   /* Reserve memory for the AGP bus */
   Status = AgpBusInterface->ReserveMemory(AgpBusInterface->AgpContext,
                                           Pages,
                                           MemCachingType,
                                           &AgpMapping->MapHandle,
                                           &AgpMapping->PhysicalAddress);
   if (!NT_SUCCESS(Status) || AgpMapping->MapHandle == NULL)
   {
      ExFreePool(AgpMapping);
      DPRINT1("Warning: AgpBusInterface->ReserveMemory failed (Status = 0x%x)\n",
              Status);
      return ZeroAddress;
   }

   /* Fill the rest of the AGP mapping */
   AgpMapping->NumberOfPages = Pages;

   *PhysicalContext = (PVOID)AgpMapping;
   return AgpMapping->PhysicalAddress;
}
   

PVOID NTAPI
IntAgpCommitVirtual(
   IN PVOID HwDeviceExtension,
   IN PVOID VirtualContext,
   IN ULONG Pages,
   IN ULONG Offset)
{
   PVIDEO_PORT_AGP_VIRTUAL_MAPPING VirtualMapping;
   PVOID BaseAddress = NULL;
   NTSTATUS Status;

   DPRINT("AgpCommitVirtual - VirtualContext: 0x%x Pages: %d, Offset: 0x%x\n",
          VirtualContext, Pages, Offset);

   VirtualMapping = (PVIDEO_PORT_AGP_VIRTUAL_MAPPING)VirtualContext;

   /* I think the NT API provides no way of reserving a part of the address space
    * and setting it up to map into a specified range of physical memory later.
    * This means that we will have to release some of the reserved virtual memory
    * and map the physical memory into it using MapViewOfSection.
    *
    * - blight (2004-12-21)
    */

   if (VirtualMapping->ProcessHandle == NULL)
   {
      /* FIXME: not implemented */
   }
   else /* ProcessHandle != NULL */
   {
      /* Release some virtual memory */
      ULONG Size = Pages * PAGE_SIZE;
      ULONG OffsetInBytes = Offset * PAGE_SIZE;
      BaseAddress = (PVOID)((ULONG_PTR)VirtualMapping->MappedAddress +
                                       OffsetInBytes);
      PHYSICAL_ADDRESS PhysicalAddress = VirtualMapping->AgpMapping->PhysicalAddress;
      PhysicalAddress.QuadPart += OffsetInBytes;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -