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

📄 mmcpci.c

📁 基于RM9200主芯片
💻 C
📖 第 1 页 / 共 2 页
字号:
  CfgData.VendorID = PCI_INVALID_VENDORID;
  PciReadConfig(BusNumber,
        SlotNumber,
        &CfgData,
        0,
        PCI_COMMON_HDR_LENGTH);
  if (CfgData.VendorID == PCI_INVALID_VENDORID)
    return STATUS_UNSUCCESSFUL;

  /* save a copy of the configuration space */
  RtlCopyMemory(&OrigCfgData, &CfgData, PCI_COMMON_HDR_LENGTH);

  switch (PCI_CONFIG_TYPE(&CfgData)) {
    case 0:
      for (i=0; i<PCI_TYPE0_ADDRESSES; i++) {
    BaseAddress[i] = &CfgData.u.type0.BaseAddresses[i];
    OrigAddress[i] = &OrigCfgData.u.type0.BaseAddresses[i];
      }
      BaseAddress[PCI_TYPE0_ADDRESSES] = &CfgData.u.type0.ROMBaseAddress;
      OrigAddress[PCI_TYPE0_ADDRESSES] = &OrigCfgData.u.type0.ROMBaseAddress;
      RomIndex = PCI_TYPE0_ADDRESSES;
      NoBaseAddress = PCI_TYPE0_ADDRESSES + 1;
      break;

    case 1:
      for (i=0; i<PCI_TYPE1_ADDRESSES; i++) {
    BaseAddress[i] = &CfgData.u.type1.BaseAddresses[i];
    OrigAddress[i] = &OrigCfgData.u.type1.BaseAddresses[i];
      }
      BaseAddress[PCI_TYPE1_ADDRESSES] = &CfgData.u.type1.ExpansionROMBase;
      OrigAddress[PCI_TYPE1_ADDRESSES] = &OrigCfgData.u.type1.ExpansionROMBase;
      RomIndex = PCI_TYPE1_ADDRESSES;
      NoBaseAddress = PCI_TYPE1_ADDRESSES + 1;
      break;

    default:
      return STATUS_UNSUCCESSFUL;
  }

  EnableRomBase = TRUE;
  if ((*BaseAddress[RomIndex] & PCI_ROMADDRESS_ENABLED) == 0) {
    EnableRomBase = FALSE;
    NoBaseAddress -= 1;
  }

  i = sizeof(IO_RESOURCE_REQUIREMENTS_LIST)
    + sizeof(IO_RESOURCE_DESCRIPTOR) * (PCI_TYPE0_ADDRESSES + 2) * 2;
  WorkingPool = (PUCHAR)LocalAlloc(LMEM_FIXED, i);
  if (WorkingPool == NULL)
    return STATUS_INSUFFICIENT_RESOURCES;

  RtlZeroMemory(WorkingPool, i);
  CompleteList = (PIO_RESOURCE_REQUIREMENTS_LIST)WorkingPool;

  /* write all 1s to each base address register to determine its block range */
  for (i=0; i<NoBaseAddress; i++)
    *BaseAddress[i] = 0xffffffff;

  /* turn off address decoding while trying to determine the block size */
  CfgData.Command &= ~(USHORT)(PCI_ENABLE_IO_SPACE | PCI_ENABLE_MEMORY_SPACE);
  *BaseAddress[RomIndex] &= ~(ULONG)PCI_ROMADDRESS_ENABLED;

  PciWriteConfig(BusNumber,
         SlotNumber,
         &CfgData,
         0,
         PCI_COMMON_HDR_LENGTH);
  PciReadConfig(BusNumber,
        SlotNumber,
        &CfgData,
        0,
        PCI_COMMON_HDR_LENGTH);

  /* build an IO_RESOURCE_REQUIREMENTS_LIST for the PCI device */
  CompleteList->InterfaceType = PCIBus;
  CompleteList->BusNumber = BusNumber;
  CompleteList->SlotNumber = SlotNumber.u.AsULONG;
  CompleteList->AlternativeLists = 1;
  CompleteList->List[0].Version = 1;
  CompleteList->List[0].Revision = 1;
  CompleteList->List[0].Count = 0;

  IoDescriptor = CompleteList->List[0].Descriptors;

  RequestedInterrupt = FALSE;
  if (CfgData.u.type0.InterruptPin != 0
      && CfgData.u.type0.InterruptLine != 0xff) {
    RequestedInterrupt = TRUE;
    CompleteList->List[0].Count++;

    IoDescriptor->Option = 0;
    IoDescriptor->Type = CmResourceTypeInterrupt;
    IoDescriptor->ShareDisposition = CmResourceShareShared;
    IoDescriptor->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
    IoDescriptor->u.Interrupt.MinimumVector = CfgData.u.type0.InterruptLine;
    IoDescriptor->u.Interrupt.MaximumVector = 0xff;
    IoDescriptor++;
  }

  /* mask off reserved bits */
  *BaseAddress[RomIndex] &= ~0xfffff800;

  i = 0;
  while (i < NoBaseAddress) {
    ULONG Address;

    Address = *BaseAddress[i];

    if (Address != 0) {
      ULONG Length;
      ULONG MaxAddress;
      BOOLEAN IoSpace;
      BOOLEAN Address64;

      IoSpace = (Address & PCI_ADDRESS_IO_SPACE) != 0 ? TRUE : FALSE;
      Address64 = (Address && PCI_ADDRESS_MEMORY_TYPE_MASK) == PCI_TYPE_64BIT
            ? TRUE : FALSE;

      Length = 1 << (IoSpace ? 2 : 4);
      while ((Address & Length) == 0)
    Length <<= 1;

      MaxAddress = Length;
      while (MaxAddress != 0 && (Address & MaxAddress) != 0)
    MaxAddress <<= 1;
      MaxAddress--;

      DBGCHK(TEXT("NTCOMPAT"), (Length & ~MaxAddress) == 0);

      IoDescriptor->Option = 0;

      if (IoSpace) {
    if (!Address64 && (OrigCfgData.Command & PCI_ENABLE_IO_SPACE) != 0) {
      IoDescriptor->Option = IO_RESOURCE_PREFERRED;
      IoDescriptor->Type = CmResourceTypePort;
      IoDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
      IoDescriptor->Flags = CM_RESOURCE_PORT_IO;
      IoDescriptor->u.Port.Length = Length;
      IoDescriptor->u.Port.Alignment = Length;
      IoDescriptor->u.Port.MinimumAddress.LowPart
        = *OrigAddress[i] & 0xfffffffc;
      IoDescriptor->u.Port.MaximumAddress.LowPart
        = IoDescriptor->u.Port.MinimumAddress.LowPart + Length - 1;
      CompleteList->List[0].Count++;
      IoDescriptor++;

      IoDescriptor->Option = IO_RESOURCE_ALTERNATIVE;
    }

    IoDescriptor->Type = CmResourceTypePort;
    IoDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
    IoDescriptor->Flags = CM_RESOURCE_PORT_IO;
    IoDescriptor->u.Port.Length = Length;
    IoDescriptor->u.Port.Alignment = Length;
    IoDescriptor->u.Port.MinimumAddress.LowPart = 0;
    IoDescriptor->u.Port.MaximumAddress.LowPart = MaxAddress;
      } else {
    IoDescriptor->Flags = i == RomIndex
                  ? CM_RESOURCE_MEMORY_READ_ONLY
                  : CM_RESOURCE_MEMORY_READ_WRITE;
    if (Address & PCI_ADDRESS_MEMORY_PREFETCHABLE)
      IoDescriptor->Flags |= CM_RESOURCE_MEMORY_PREFETCHABLE;

    if (!Address64
        && (i == RomIndex
        || (OrigCfgData.Command & PCI_ENABLE_MEMORY_SPACE))) {
      USHORT Flags = IoDescriptor->Flags;

      IoDescriptor->Option = IO_RESOURCE_PREFERRED;
      IoDescriptor->Type = CmResourceTypeMemory;
      IoDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
      IoDescriptor->u.Memory.Length = Length;
      IoDescriptor->u.Memory.Alignment = Length;
      IoDescriptor->u.Memory.MinimumAddress.LowPart
        = *OrigAddress[i] & 0xfffffff0;
      IoDescriptor->u.Memory.MaximumAddress.LowPart
        = IoDescriptor->u.Memory.MinimumAddress.LowPart + Length - 1;

      CompleteList->List[0].Count++;
      IoDescriptor++;

      IoDescriptor->Flags = Flags;
      IoDescriptor->Option = IO_RESOURCE_ALTERNATIVE;
    }

    IoDescriptor->Type = CmResourceTypeMemory;
    IoDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
    IoDescriptor->u.Memory.Length = Length;
    IoDescriptor->u.Memory.Alignment = Length;
    IoDescriptor->u.Memory.MinimumAddress.LowPart = 0;
    IoDescriptor->u.Memory.MaximumAddress.LowPart
      = (Address & PCI_ADDRESS_MEMORY_TYPE_MASK) == PCI_TYPE_20BIT
          ? 0x000fffff : MaxAddress;
      }

      CompleteList->List[0].Count++;
      IoDescriptor++;

      if (Address64)
    i++;
    }

    i++;
  }

  CompleteList->ListSize = (ULONG)IoDescriptor - (ULONG)CompleteList;

  /* restore settings */
  PciWriteConfig(BusNumber,
         SlotNumber,
         &OrigCfgData.RevisionID,
         FIELD_OFFSET(PCI_COMMON_CONFIG, RevisionID),
         PCI_COMMON_HDR_LENGTH
           - FIELD_OFFSET(PCI_COMMON_CONFIG, RevisionID));
  PciWriteConfig(BusNumber,
         SlotNumber,
         &OrigCfgData,
         0,
         FIELD_OFFSET(PCI_COMMON_CONFIG, RevisionID));



    /*

  if (IoAssignResources(RegistryPath,
            DriverClassName,
            DriverObject,
            DeviceObject,
            CompleteList,
            AllocatedResources) != STATUS_SUCCESS) {
    LocalFree((HLOCAL)WorkingPool);
    return STATUS_UNSUCCESSFUL;
  }



   */



  CmDescriptor
    = (*AllocatedResources)->List[0].PartialResourceList.PartialDescriptors;


  if (RequestedInterrupt) {
    /* IoAssignResources preserves the resource order */
    /* type0 and type1 overlay InterruptLine */
    CfgData.u.type0.InterruptLine = (UCHAR)CmDescriptor->u.Interrupt.Vector;
    CmDescriptor++;
  }

  i = 0;
  while (i < NoBaseAddress) {
    ULONG Address;

    Address = *BaseAddress[i];
    if (Address != 0) {
      *BaseAddress[i] = Address & PCI_ADDRESS_IO_SPACE
              ? CmDescriptor->u.Port.Start.LowPart
              : CmDescriptor->u.Memory.Start.LowPart;
      CmDescriptor++;
      if ((Address && PCI_ADDRESS_MEMORY_TYPE_MASK) == PCI_TYPE_64BIT)
    i++;
    }
    i++;
  }

  /* turn address decoding off and write assigned resources to the
   * configuration space */
  PciWriteConfig(BusNumber,
         SlotNumber,
         &CfgData,
         0,
         PCI_COMMON_HDR_LENGTH);

  /* enable address decoding */
  if (EnableRomBase && *BaseAddress[RomIndex] != 0) {
    *BaseAddress[RomIndex] |= PCI_ROMADDRESS_ENABLED;
    /* type0 and type1 overlay ROMBaseAddress */
    PciWriteConfig(BusNumber,
           SlotNumber,
           BaseAddress[RomIndex],
           (ULONG)BaseAddress[RomIndex] - (ULONG)&CfgData,
           4);
  }
  CfgData.Command |= PCI_ENABLE_IO_SPACE
               | PCI_ENABLE_MEMORY_SPACE
               | PCI_ENABLE_BUS_MASTER;
  PciWriteConfig(BusNumber,
         SlotNumber,
         &CfgData.Command,
         FIELD_OFFSET(PCI_COMMON_CONFIG, Command),
         4);

  LocalFree((HLOCAL)WorkingPool);

  return STATUS_SUCCESS;
}




⌨️ 快捷键说明

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