test: pnpmemio.c File Reference

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# pnpmemio.c File Reference

`#include "iop.h"`

Go to the source code of this file.

## Classes

struct | _PORT_ARBITER_EXTENSION

## Defines

#define | BUGFEST_HACKS
#define | MAX_ULONGLONG ((ULONGLONG) -1)
#define | MAX_ALIAS_PORT 0x0000FFFF
#define | ADDRESS_SPACE_MEMORY 0x0
#define | ADDRESS_SPACE_PORT 0x1
#define | ADDRESS_SPACE_USER_MEMORY 0x2
#define | ADDRESS_SPACE_USER_PORT 0x3
#define | ADDRESS_SPACE_DENSE_MEMORY 0x4
#define | ADDRESS_SPACE_USER_DENSE_MEMORY 0x6
#define | MAX_SCORE MAXLONG

## Typedefs

typedef _PORT_ARBITER_EXTENSION | PORT_ARBITER_EXTENSION
typedef _PORT_ARBITER_EXTENSION * | PPORT_ARBITER_EXTENSION

## Functions

VOID | IopPortBacktrackAllocation (IN PARBITER_INSTANCE Arbiter, IN PARBITER_ALLOCATION_STATE State)
BOOLEAN | IopPortGetNextAlias (ULONG IoDescriptorFlags, ULONGLONG LastAlias, PULONGLONG NextAlias)
BOOLEAN | IopPortFindSuitableRange (PARBITER_INSTANCE Arbiter, PARBITER_ALLOCATION_STATE State)
BOOLEAN | IopMemFindSuitableRange (PARBITER_INSTANCE Arbiter, PARBITER_ALLOCATION_STATE State)
NTSTATUS | IopGenericUnpackRequirement (IN PIO_RESOURCE_DESCRIPTOR Descriptor, OUT PULONGLONG Minimum, OUT PULONGLONG Maximum, OUT PULONG Length, OUT PULONG Alignment)
NTSTATUS | IopGenericPackResource (IN PIO_RESOURCE_DESCRIPTOR Requirement, IN ULONGLONG Start, OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor)
LONG | IopGenericScoreRequirement (IN PIO_RESOURCE_DESCRIPTOR Descriptor)
NTSTATUS | IopGenericUnpackResource (IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor, OUT PULONGLONG Start, OUT PULONG Length)
BOOLEAN | IopPortIsAliasedRangeAvailable (IN PARBITER_INSTANCE Arbiter, IN PARBITER_ALLOCATION_STATE State)
NTSTATUS | IopMemInitialize (VOID)
VOID | IopPortAddAllocation (IN PARBITER_INSTANCE Arbiter, IN PARBITER_ALLOCATION_STATE State)
NTSTATUS | IopTranslateBusAddress (IN PHYSICAL_ADDRESS SourceAddress, IN UCHAR SourceResourceType, OUT PPHYSICAL_ADDRESS TargetAddress, OUT PUCHAR TargetResourceType)
NTSTATUS | IopGenericTranslateOrdering (OUT PIO_RESOURCE_DESCRIPTOR Target, IN PIO_RESOURCE_DESCRIPTOR Source)
NTSTATUS | IopPortInitialize (VOID)
BOOLEAN | IopPortIsAliasedRangeAvailable (PARBITER_INSTANCE Arbiter, PARBITER_ALLOCATION_STATE State)

## Define Documentation

#define ADDRESS_SPACE_DENSE_MEMORY 0x4

| Definition at line 151 of file pnpmemio.c. Referenced by IopTranslateBusAddress().

#define ADDRESS_SPACE_MEMORY 0x0

| Definition at line 147 of file pnpmemio.c. Referenced by IopTranslateBusAddress().

#define ADDRESS_SPACE_PORT 0x1

| Definition at line 148 of file pnpmemio.c. Referenced by IopTranslateBusAddress().

#define ADDRESS_SPACE_USER_DENSE_MEMORY 0x6

| Definition at line 152 of file pnpmemio.c. Referenced by IopTranslateBusAddress().

#define ADDRESS_SPACE_USER_MEMORY 0x2

| Definition at line 149 of file pnpmemio.c. Referenced by IopTranslateBusAddress().

#define ADDRESS_SPACE_USER_PORT 0x3

| Definition at line 150 of file pnpmemio.c. Referenced by IopTranslateBusAddress().

#define BUGFEST_HACKS

| Definition at line 24 of file pnpmemio.c.

#define MAX_ALIAS_PORT 0x0000FFFF

| Definition at line 31 of file pnpmemio.c. Referenced by IopPortGetNextAlias().

#define MAX_SCORE MAXLONG

| Referenced by IopGenericScoreRequirement().

#define MAX_ULONGLONG ((ULONGLONG) -1)

| Definition at line 30 of file pnpmemio.c.

## Typedef Documentation

typedef struct _PORT_ARBITER_EXTENSION PORT_ARBITER_EXTENSION

typedef struct _PORT_ARBITER_EXTENSION * PPORT_ARBITER_EXTENSION

## Function Documentation

NTSTATUS IopGenericPackResource | ( | IN PIO_RESOURCE_DESCRIPTOR | Requirement,
|  | IN ULONGLONG | Start,
|  | OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR | Descriptor
| ) |

Definition at line 630 of file pnpmemio.c.

References ARB_PRINT, ASSERT, PAGED_CODE, and Start.

Referenced by IopMemInitialize(), and IopPortInitialize().

    00638                    :
    00639
    00640     This routine packs an resource descriptor.
    00641
    00642 Arguments:
    00643
    00644     Requirement - The requirement from which this resource was chosen.
    00645
    00646     Start - The start value of the resource.
    00647
    00648     Descriptor - Pointer to the descriptor to pack into.
    00649
    00650 Return Value:
    00651
    00652     Returns the status of this operation.
    00653
    00654 --*/
    00655
    00656 {
    00657
    00658     PAGED_CODE();
    00659     ASSERT(Descriptor);
    00660     ASSERT(Requirement);
    00661     ASSERT(Requirement->Type == CmResourceTypePort
    00662            || Requirement->Type == CmResourceTypeMemory);
    00663
    00664     Descriptor->Type = Requirement->Type;
    00665     Descriptor->Flags = Requirement->Flags;
    00666     Descriptor->ShareDisposition = Requirement->ShareDisposition;
    00667     Descriptor->u.Generic.Start.QuadPart = Start;
    00668     Descriptor->u.Generic.Length = Requirement->u.Generic.Length;
    00669
    00670     ARB_PRINT(2,
    00671                 ("Packing %s resource %p => 0x%I64x length 0x%x\n",
    00672                 Descriptor->Type == CmResourceTypePort ? "port" : "memory",
    00673                 Descriptor,
    00674                 Descriptor->u.Port.Start.QuadPart,
    00675                 Descriptor->u.Port.Length
    00676                 ));
    00677
    00678     return STATUS_SUCCESS;
    00679 }

LONG IopGenericScoreRequirement | ( | IN PIO_RESOURCE_DESCRIPTOR | Descriptor | ) |

Definition at line 542 of file pnpmemio.c.

References ALIGN_ADDRESS_UP, ARB_PRINT, ASSERT, MAX_SCORE, and PAGED_CODE.

Referenced by IopMemInitialize(), and IopPortInitialize().

    00548                    :
    00549
    00550     This routine scores a requirement based on how flexible it is.  The least
    00551     flexible devices are scored the least and so when the arbitration list is
    00552     sorted we try to allocate their resources first.
    00553
    00554 Arguments:
    00555
    00556     Descriptor - The descriptor describing the requirement to score.
    00557
    00558
    00559 Return Value:
    00560
    00561     The score.
    00562
    00563 --*/
    00564
    00565 {
    00566     LONG score;
    00567     ULONGLONG start, end;
    00568     LONGLONG bigscore;
    00569     ULONG alignment;
    00570
    00571     PAGED_CODE();
    00572
    00573 #define MAX_SCORE MAXLONG
    00574
    00575     ASSERT(Descriptor);
    00576     ASSERT((Descriptor->Type == CmResourceTypePort) ||
    00577            (Descriptor->Type == CmResourceTypeMemory));
    00578
    00579     alignment = Descriptor->u.Generic.Alignment;
    00580
    00581     //
    00582     // Fix the broken hardware that reports 0 alignment
    00583     // Since this is not a PCI device, set the alignment to 1.
    00584     //
    00585     //
    00586
    00587     if (alignment == 0 &&
    00588         ((Descriptor->Type == CmResourceTypePort) ||
    00589          (Descriptor->Type == CmResourceTypeMemory))) {
    00590         alignment = 1;
    00591     }
    00592
    00593
    00594
    00595     start = ALIGN_ADDRESS_UP(
    00596                 Descriptor->u.Generic.MinimumAddress.QuadPart,
    00597                 alignment
    00598                 );
    00599
    00600     end = Descriptor->u.Generic.MaximumAddress.QuadPart;
    00601
    00602     //
    00603     // The score is the number of possible allocations that could be made
    00604     // given the alignment and length constraints
    00605     //
    00606
    00607     bigscore = (((end - Descriptor->u.Generic.Length + 1) - start)
    00608                     / alignment) + 1;
    00609
    00610     score = (LONG)bigscore;
    00611     if (bigscore < 0) {
    00612         score = -1;
    00613     } else if (bigscore > MAX_SCORE) {
    00614         score = MAX_SCORE;
    00615     }
    00616
    00617     ARB_PRINT(2,
    00618                 ("Scoring port resource %p(0x%I64x-0x%I64x) => %i\n",
    00619                 Descriptor->Type == CmResourceTypePort ? "port" : "memory",
    00620                 Descriptor,
    00621                 Descriptor->u.Generic.MinimumAddress.QuadPart,
    00622                 end,
    00623                 score
    00624                 ));
    00625
    00626     return score;
    00627 }

NTSTATUS IopGenericTranslateOrdering | ( | OUT PIO_RESOURCE_DESCRIPTOR | Target,
|  | IN PIO_RESOURCE_DESCRIPTOR | Source
| ) |

Definition at line 263 of file pnpmemio.c.

References ASSERT, IopTranslateBusAddress(), NT_SUCCESS, NTSTATUS(), and PAGED_CODE.

Referenced by IopMemInitialize(), and IopPortInitialize().

    00270                    :
    00271
    00272     This routine is called during arbiter initialization to translate the
    00273     orderings.
    00274
    00275 Parameters:
    00276
    00277     Target - Place to put the translated descriptor
    00278
    00279     Source - Descriptor to translate
    00280
    00281 Return Value:
    00282
    00283     STATUS_SUCCESS
    00284
    00285
    00286
    00287 */
    00288
    00289 {
    00290     NTSTATUS status;
    00291     UCHAR initialResourceType, minResourceType, maxResourceType;
    00292     PAGED_CODE();
    00293
    00294
    00295     *Target = *Source;
    00296
    00297     if (Source->Type != CmResourceTypeMemory
    00298     && Source->Type != CmResourceTypePort) {
    00299         return STATUS_SUCCESS;
    00300     }
    00301
    00302     initialResourceType = Source->Type;
    00303
    00304     //
    00305     // Translate the minimum
    00306     //
    00307
    00308     status = IopTranslateBusAddress(Source->u.Generic.MinimumAddress,
    00309                                     initialResourceType,
    00310                                     &Target->u.Generic.MinimumAddress,
    00311                                     &minResourceType
    00312                                     );
    00313
    00314     if (NT_SUCCESS(status)) {
    00315
    00316         //
    00317         // Translate the maximum iff we could translate the minimum
    00318         //
    00319
    00320         status = IopTranslateBusAddress(Source->u.Generic.MaximumAddress,
    00321                                         initialResourceType,
    00322                                         &Target->u.Generic.MaximumAddress,
    00323                                         &maxResourceType
    00324                                         );
    00325
    00326     }
    00327
    00328     //
    00329     // If we couldn't translate both ends of the range then we want to skip this
    00330     // range - set it's type to CmResourceTypeNull
    00331     //
    00332
    00333     if (!NT_SUCCESS(status)) {
    00334         Target->Type = CmResourceTypeNull;
    00335     } else {
    00336         ASSERT(minResourceType == maxResourceType);
    00337         Target->Type = minResourceType;
    00338     }
    00339
    00340     return STATUS_SUCCESS;
    00341
    00342 }

NTSTATUS IopGenericUnpackRequirement | ( | IN PIO_RESOURCE_DESCRIPTOR | Descriptor,
|  | OUT PULONGLONG | Minimum,
|  | OUT PULONGLONG | Maximum,
|  | OUT PULONG | Length,
|  | OUT PULONG | Alignment
| ) |

Definition at line 463 of file pnpmemio.c.

References ARB_PRINT, ASSERT, and PAGED_CODE.

Referenced by IopMemInitialize(), and IopPortInitialize().

    00473                    :
    00474
    00475     This routine unpacks an resource requirement descriptor.
    00476
    00477 Arguments:
    00478
    00479     Descriptor - The descriptor describing the requirement to unpack.
    00480
    00481     Minimum - Pointer to where the minimum acceptable start value should be
    00482         unpacked to.
    00483
    00484     Maximum - Pointer to where the maximum acceptable end value should be
    00485         unpacked to.
    00486
    00487     Length - Pointer to where the required length should be unpacked to.
    00488
    00489     Minimum - Pointer to where the required alignment should be unpacked to.
    00490
    00491 Return Value:
    00492
    00493     Returns the status of this operation.
    00494
    00495 --*/
    00496
    00497 {
    00498     PAGED_CODE();
    00499     ASSERT(Descriptor);
    00500     ASSERT(Descriptor->Type == CmResourceTypePort
    00501            || Descriptor->Type == CmResourceTypeMemory);
    00502
    00503
    00504     *Minimum = (ULONGLONG) Descriptor->u.Generic.MinimumAddress.QuadPart;
    00505     *Maximum = (ULONGLONG) Descriptor->u.Generic.MaximumAddress.QuadPart;
    00506     *Length = Descriptor->u.Generic.Length;
    00507     *Alignment = Descriptor->u.Generic.Alignment;
    00508
    00509     //
    00510     // Fix the broken hardware that reports 0 alignment
    00511     //
    00512
    00513     if (*Alignment == 0) {
    00514         *Alignment = 1;
    00515     }
    00516
    00517     //
    00518     // Fix broken INF's that report they support 24bit memory > 0xFFFFFF
    00519     //
    00520
    00521     if (Descriptor->Type == CmResourceTypeMemory
    00522     && Descriptor->Flags & CM_RESOURCE_MEMORY_24
    00523     && Descriptor->u.Memory.MaximumAddress.QuadPart > 0xFFFFFF) {
    00524         *Maximum = 0xFFFFFF;
    00525     }
    00526
    00527     ARB_PRINT(2,
    00528                 ("Unpacking %s requirement %p => 0x%I64x-0x%I64x length 0x%x alignment 0x%x\n",
    00529                 Descriptor->Type == CmResourceTypePort ? "port" : "memory",
    00530                 Descriptor,
    00531                 *Minimum,
    00532                 *Maximum,
    00533                 *Length,
    00534                 *Alignment
    00535                 ));
    00536
    00537     return STATUS_SUCCESS;
    00538
    00539 }

NTSTATUS IopGenericUnpackResource | ( | IN PCM_PARTIAL_RESOURCE_DESCRIPTOR | Descriptor,
|  | OUT PULONGLONG | Start,
|  | OUT PULONG | Length
| ) |

Definition at line 682 of file pnpmemio.c.

References ARB_PRINT, ASSERT, PAGED_CODE, and Start.

Referenced by IopMemInitialize(), and IopPortInitialize().

    00690                    :
    00691
    00692     This routine unpacks an resource descriptor.
    00693
    00694 Arguments:
    00695
    00696     Descriptor - The descriptor describing the resource to unpack.
    00697
    00698     Start - Pointer to where the start value should be unpacked to.
    00699
    00700     Length - Pointer to where the length value should be unpacked to.
    00701
    00702 Return Value:
    00703
    00704     Returns the status of this operation.
    00705
    00706 --*/
    00707
    00708 {
    00709
    00710     PAGED_CODE();
    00711     ASSERT(Descriptor);
    00712     ASSERT(Descriptor->Type == CmResourceTypePort
    00713            || Descriptor->Type == CmResourceTypeMemory);
    00714
    00715     *Start = Descriptor->u.Generic.Start.QuadPart;
    00716     *Length = Descriptor->u.Generic.Length;
    00717
    00718     ARB_PRINT(2,
    00719                 ("Unpacking %s resource %p => 0x%I64x Length 0x%x\n",
    00720                 Descriptor->Type == CmResourceTypePort ? "port" : "memory",
    00721                 Descriptor,
    00722                 *Start,
    00723                 *Length
    00724                 ));
    00725
    00726     return STATUS_SUCCESS;
    00727
    00728 }
    #if 0

BOOLEAN IopMemFindSuitableRange | ( | PARBITER_INSTANCE | Arbiter,
|  | PARBITER_ALLOCATION_STATE | State
| ) |

Definition at line 1342 of file pnpmemio.c.

References ArbFindSuitableRange(), ARBITER_FLAG_BOOT_CONFIG, ARBITER_RANGE_BOOT_ALLOCATED, _ARBITER_ALLOCATION_STATE::Entry, _ARBITER_LIST_ENTRY::Flags, and _ARBITER_ALLOCATION_STATE::RangeAvailableAttributes.

Referenced by IopMemInitialize().

    01348                    :
    01349
    01350     This routine is called from AllocateEntry once we have decided where we want
    01351     to allocate from.  It tries to find a free range that matches the
    01352     requirements in State while restricting its possible solutions to the range
    01353     State->Start to State->CurrentMaximum.  On success State->Start and
    01354     State->End represent this range.  Conflicts between boot configs are allowed
    01355
    01356 Arguments:
    01357
    01358     Arbiter - The instance data of the arbiter who was called.
    01359
    01360     State - The state of the current arbitration.
    01361
    01362 Return Value:
    01363
    01364     TRUE if we found a range, FALSE otherwise.
    01365
    01366 --*/
    01367 {
    01368     //
    01369     // If this was a boot config then consider other boot configs to be
    01370     // available
    01371     //
    01372
    01373     if (State->Entry->Flags & ARBITER_FLAG_BOOT_CONFIG) {
    01374         State->RangeAvailableAttributes |= ARBITER_RANGE_BOOT_ALLOCATED;
    01375     }
    01376
    01377     //
    01378     // Do the default thing
    01379     //
    01380
    01381     return ArbFindSuitableRange(Arbiter, State);
    01382 }

NTSTATUS IopMemInitialize | ( | VOID |  | ) |

| Referenced by IopInitializePlugPlayServices().

VOID IopPortAddAllocation | ( | IN PARBITER_INSTANCE | Arbiter,
|  | IN PARBITER_ALLOCATION_STATE | State
| ) |

Definition at line 1146 of file pnpmemio.c.

References ARB_PRINT, ARBITER_ALTERNATIVE_FLAG_SHARED, ARBITER_RANGE_ALIAS, ASSERT, IopPortGetNextAlias(), NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, and RtlAddRange().

Referenced by IopPortInitialize().

    01153                    :
    01154
    01155     This routine is called from AllocateEntry once we have found a possible
    01156     solution (State->Start - State->End).  It adds the ranges that will not be
    01157     available if we commit to this solution to Arbiter->PossibleAllocation.
    01158
    01159 Arguments:
    01160
    01161     Arbiter - The instance data of the arbiter who was called.
    01162
    01163     State - The state of the current arbitration.
    01164
    01165 Return Value:
    01166
    01167     None.
    01168
    01169 --*/
    01170
    01171 {
    01172     NTSTATUS status;
    01173     ULONGLONG alias;
    01174     BOOLEAN isAlias;
    01175
    01176     PAGED_CODE();
    01177
    01178     ASSERT(Arbiter);
    01179     ASSERT(State);
    01180
    01181     status = RtlAddRange(Arbiter->PossibleAllocation,
    01182                  State->Start,
    01183                  State->End,
    01184                  State->RangeAttributes,
    01185                  RTL_RANGE_LIST_ADD_IF_CONFLICT +
    01186                     (State->CurrentAlternative->Flags & ARBITER_ALTERNATIVE_FLAG_SHARED
    01187                         ? RTL_RANGE_LIST_ADD_SHARED : 0),
    01188                  NULL,
    01189                  State->Entry->PhysicalDeviceObject
    01190                  );
    01191
    01192     ASSERT(NT_SUCCESS(status));
    01193
    01194     //
    01195     // Add any aliases
    01196     //
    01197
    01198     alias = State->Start;
    01199     ARB_PRINT(2, ("Adding aliases\n"));
    01200
    01201     while (IopPortGetNextAlias(State->CurrentAlternative->Descriptor->Flags,
    01202                              alias,
    01203                              &alias)) {
    01204
    01205         status = RtlAddRange(Arbiter->PossibleAllocation,
    01206                      alias,
    01207                      alias + State->CurrentAlternative->Length - 1,
    01208                      (UCHAR) (State->RangeAttributes | ARBITER_RANGE_ALIAS),
    01209                      RTL_RANGE_LIST_ADD_IF_CONFLICT +
    01210                         (State->CurrentAlternative->Flags & ARBITER_ALTERNATIVE_FLAG_SHARED
    01211                             ? RTL_RANGE_LIST_ADD_SHARED : 0),
    01212                      NULL,
    01213                      State->Entry->PhysicalDeviceObject
    01214                      );
    01215
    01216         //
    01217         // We have already checked if these ranges are available
    01218         // so we should not fail...
    01219         //
    01220
    01221         ASSERT(NT_SUCCESS(status));
    01222     }
    01223 }

VOID IopPortBacktrackAllocation | ( | IN PARBITER_INSTANCE | Arbiter,
|  | IN PARBITER_ALLOCATION_STATE | State
| ) |

Definition at line 890 of file pnpmemio.c.

References ARB_PRINT, ArbBacktrackAllocation(), ASSERT, IopPortGetNextAlias(), NT_SUCCESS, NTSTATUS(), PAGED_CODE, and RtlDeleteRange().

Referenced by IopPortInitialize().

    00897                    :
    00898
    00899     This routine is called from AllocateEntry if the possible solution
    00900     (State->Start - State->End) does not allow us to allocate resources to
    00901     the rest of the devices being considered.  It deletes the ranges that were
    00902     added to Arbiter->PossibleAllocation by AddAllocation including those
    00903     associated with ISA aliases.
    00904
    00905 Arguments:
    00906
    00907     Arbiter - The instance data of the arbiter who was called.
    00908
    00909     State - The state of the current arbitration.
    00910
    00911 Return Value:
    00912
    00913     None.
    00914
    00915 --*/
    00916
    00917
    00918 {
    00919
    00920     NTSTATUS status;
    00921     ULONGLONG alias = State->Start;
    00922
    00923     PAGED_CODE();
    00924
    00925     //
    00926     // Delete the aliases
    00927     //
    00928
    00929     ARB_PRINT(2, ("\t\tDeleting aliases\n"));
    00930
    00931     while (IopPortGetNextAlias(State->CurrentAlternative->Flags,
    00932                                alias,
    00933                                &alias)) {
    00934
    00935         status = RtlDeleteRange(
    00936                      Arbiter->PossibleAllocation,
    00937                      alias,
    00938                      alias + State->CurrentAlternative->Length - 1,
    00939                      State->Entry->PhysicalDeviceObject
    00940                      );
    00941
    00942         //
    00943         // We should not fail...
    00944         //
    00945
    00946         ASSERT(NT_SUCCESS(status));
    00947     }
    00948
    00949     //
    00950     // Now call the original function to delete the base range
    00951     //
    00952
    00953     ArbBacktrackAllocation(Arbiter, State);
    00954
    00955 }

BOOLEAN IopPortFindSuitableRange | ( | PARBITER_INSTANCE | Arbiter,
|  | PARBITER_ALLOCATION_STATE | State
| ) |

Definition at line 959 of file pnpmemio.c.

References _ARBITER_ALTERNATIVE::Alignment, ARBITER_ALTERNATIVE_FLAG_SHARED, ARBITER_FLAG_BOOT_CONFIG, ARBITER_RANGE_BOOT_ALLOCATED, ArbiterRequestLegacyAssigned, ArbiterRequestLegacyReported, _ARBITER_ALLOCATION_STATE::CurrentAlternative, _ARBITER_ALLOCATION_STATE::CurrentMaximum, _ARBITER_ALLOCATION_STATE::CurrentMinimum, _ARBITER_ALLOCATION_STATE::End, _ARBITER_ALLOCATION_STATE::Entry, FALSE, _ARBITER_ALTERNATIVE::Flags, _ARBITER_LIST_ENTRY::Flags, IopPortIsAliasedRangeAvailable(), _ARBITER_ALTERNATIVE::Length, NT_SUCCESS, NTSTATUS(), PAGED_CODE, _ARBITER_LIST_ENTRY::RequestSource, RtlFindRange(), _ARBITER_ALLOCATION_STATE::Start, and TRUE.

Referenced by IopPortInitialize().

    00965                    :
    00966
    00967     This routine is called from AllocateEntry once we have decided where we want
    00968     to allocate from.  It tries to find a free range that matches the
    00969     requirements in State while restricting its possible solutions to the range
    00970     State->Start to State->CurrentMaximum.  On success State->Start and
    00971     State->End represent this range.  Conflicts with ISA aliases are considered.
    00972
    00973 Arguments:
    00974
    00975     Arbiter - The instance data of the arbiter who was called.
    00976
    00977     State - The state of the current arbitration.
    00978
    00979 Return Value:
    00980
    00981     TRUE if we found a range, FALSE otherwise.
    00982
    00983 --*/
    00984 {
    00985     NTSTATUS status;
    00986     UCHAR userFlagsMask = 0;
    00987
    00988     PAGED_CODE();
    00989
    00990     //
    00991     // If we are asking for zero ports then trivially succeed with the minimum
    00992     // value
    00993     //
    00994
    00995     if (State->CurrentAlternative->Length == 0) {
    00996         State->End = State->Start;
    00997         return TRUE;
    00998     }
    00999
    01000     //
    01001     // For legacy requests from IoAssignResources (directly or by way of
    01002     // HalAssignSlotResources) or IoReportResourceUsage we consider preallocated
    01003     // resources to be available for backward compatibility reasons.
    01004     //
    01005     // If we are allocating a devices boot config then we consider all other
    01006     // boot configs to be available.
    01007     //
    01008
    01009     if (State->Entry->RequestSource == ArbiterRequestLegacyReported
    01010         || State->Entry->RequestSource == ArbiterRequestLegacyAssigned
    01011         || State->Entry->Flags & ARBITER_FLAG_BOOT_CONFIG) {
    01012
    01013         userFlagsMask = ARBITER_RANGE_BOOT_ALLOCATED;
    01014     }
    01015
    01016     //
    01017     // Try to satisfy the request
    01018     //
    01019
    01020     while (State->CurrentMinimum <= State->CurrentMaximum) {
    01021
    01022         //
    01023         // Select the first free alternative from the current alternative
    01024         //
    01025
    01026         status = RtlFindRange(
    01027                      Arbiter->PossibleAllocation,
    01028                      State->CurrentMinimum,
    01029                      State->CurrentMaximum,
    01030                      State->CurrentAlternative->Length,
    01031                      State->CurrentAlternative->Alignment,
    01032                      State->CurrentAlternative->Flags &
    01033                         ARBITER_ALTERNATIVE_FLAG_SHARED ?
    01034                             RTL_RANGE_LIST_SHARED_OK : 0,
    01035                      userFlagsMask,
    01036                      Arbiter->ConflictCallbackContext,
    01037                      Arbiter->ConflictCallback,
    01038                      &State->Start
    01039                      );
    01040
    01041
    01042         //
    01043         // Did we find a range and if not can we override any conflict
    01044         //
    01045         if (NT_SUCCESS(status)
    01046         || Arbiter->OverrideConflict(Arbiter, State)) {
    01047
    01048             State->End = State->Start + State->CurrentAlternative->Length - 1;
    01049
    01050             //
    01051             // Check if the aliases are available
    01052             //
    01053             if (IopPortIsAliasedRangeAvailable(Arbiter, State)) {
    01054
    01055                 //
    01056                 // We found a suitable range so return
    01057                 //
    01058
    01059                 return TRUE;
    01060
    01061             } else {
    01062
    01063                 //
    01064                 // This range's aliases arn't available so try the next range
    01065                 //
    01066
    01067                 State->Start += State->CurrentAlternative->Length;
    01068
    01069                 continue;
    01070             }
    01071         } else {
    01072
    01073             //
    01074             // We couldn't find a base range
    01075             //
    01076
    01077             break;
    01078         }
    01079     }
    01080
    01081     return FALSE;
    01082 }

BOOLEAN IopPortGetNextAlias | ( | ULONG | IoDescriptorFlags,
|  | ULONGLONG | LastAlias,
|  | PULONGLONG | NextAlias
| ) |

Definition at line 1087 of file pnpmemio.c.

References FALSE, MAX_ALIAS_PORT, PAGED_CODE, and TRUE.

Referenced by IopPortAddAllocation(), IopPortBacktrackAllocation(), and IopPortIsAliasedRangeAvailable().

    01094                    :
    01095
    01096     This routine calculates the next alias of an IO port up to MAX_ALIAS_PORT.
    01097
    01098 Arguments:
    01099
    01100     IoDescriptorFlags - The flags from the requirement descriptor indicating the
    01101         type of alias if any.
    01102
    01103     LastAlias - The alias previous to this one.
    01104
    01105     NextAlias - Point to where the next alias should be returned
    01106
    01107 Return Value:
    01108
    01109     TRUE if we found an alias, FALSE otherwise.
    01110
    01111 --*/
    01112
    01113 {
    01114     ULONGLONG next;
    01115
    01116     PAGED_CODE();
    01117
    01118     if (IoDescriptorFlags & CM_RESOURCE_PORT_10_BIT_DECODE) {
    01119         next = LastAlias + (1 << 10);
    01120     } else if (IoDescriptorFlags & CM_RESOURCE_PORT_12_BIT_DECODE) {
    01121         next = LastAlias + (1 << 12);
    01122     } else {
    01123
    01124         // BUGBUG - should CM_RESOURCE_PORT_16_BIT_DECODE be set?
    01125         //
    01126         // There are no aliases
    01127         //
    01128
    01129         return FALSE;
    01130     }
    01131
    01132     //
    01133     // Check that we are below the maximum aliased port
    01134     //
    01135
    01136     if (next > MAX_ALIAS_PORT) {
    01137         return FALSE;
    01138     } else {
    01139         *NextAlias = next;
    01140         return TRUE;
    01141     }
    01142 }

NTSTATUS IopPortInitialize | ( | VOID |  | ) |

Definition at line 349 of file pnpmemio.c.

References _ARBITER_INSTANCE::AddAllocation, ArbInitializeArbiterInstance(), _ARBITER_INSTANCE::BacktrackAllocation, _ARBITER_INSTANCE::FindSuitableRange, IopGenericPackResource(), IopGenericScoreRequirement(), IopGenericTranslateOrdering(), IopGenericUnpackRequirement(), IopGenericUnpackResource(), IopPortAddAllocation(), IopPortBacktrackAllocation(), IopPortFindSuitableRange(), IopRootPortArbiter, L, NULL, _ARBITER_INSTANCE::PackResource, PAGED_CODE, _ARBITER_INSTANCE::ScoreRequirement, _ARBITER_INSTANCE::UnpackRequirement, and _ARBITER_INSTANCE::UnpackResource.

Referenced by IopInitializePlugPlayServices().

    00355                    :
    00356
    00357     This routine initializes the arbiter
    00358
    00359 Parameters:
    00360
    00361     None
    00362
    00363 Return Value:
    00364
    00365     None
    00366
    00367 --*/
    00368
    00369 {
    00370     PAGED_CODE();
    00371
    00372     //
    00373     // Fill in the non-default action handlers
    00374     //
    00375
    00376     IopRootPortArbiter.FindSuitableRange    = IopPortFindSuitableRange;
    00377     IopRootPortArbiter.AddAllocation        = IopPortAddAllocation;
    00378     IopRootPortArbiter.BacktrackAllocation  = IopPortBacktrackAllocation;
    00379
    00380     IopRootPortArbiter.UnpackRequirement    = IopGenericUnpackRequirement;
    00381     IopRootPortArbiter.PackResource         = IopGenericPackResource;
    00382     IopRootPortArbiter.UnpackResource       = IopGenericUnpackResource;
    00383     IopRootPortArbiter.ScoreRequirement     = IopGenericScoreRequirement;
    00384
    00385     return ArbInitializeArbiterInstance(&IopRootPortArbiter,
    00386                                         NULL,     // Indicates ROOT arbiter
    00387                                         CmResourceTypePort,
    00388                                         L"RootPort",
    00389                                         L"Root",
    00390                                         IopGenericTranslateOrdering
    00391                                         );
    00392
    00393 }

BOOLEAN IopPortIsAliasedRangeAvailable | ( | PARBITER_INSTANCE | Arbiter,
|  | PARBITER_ALLOCATION_STATE | State
| ) |

Definition at line 1227 of file pnpmemio.c.

References ARB_PRINT, ARBITER_ALLOCATION_STATE, ARBITER_ALTERNATIVE_FLAG_SHARED, ARBITER_RANGE_BOOT_ALLOCATED, ArbiterRequestLegacyAssigned, ArbiterRequestLegacyReported, ASSERT, _ARBITER_ALLOCATION_STATE::CurrentAlternative, _ARBITER_ALLOCATION_STATE::CurrentMaximum, _ARBITER_ALLOCATION_STATE::CurrentMinimum, _ARBITER_ALTERNATIVE::Descriptor, _ARBITER_ALLOCATION_STATE::Entry, FALSE, _ARBITER_ALTERNATIVE::Flags, IopPortGetNextAlias(), _ARBITER_ALTERNATIVE::Length, NT_SUCCESS, NTSTATUS(), PAGED_CODE, _ARBITER_LIST_ENTRY::RequestSource, RtlIsRangeAvailable(), _ARBITER_ALLOCATION_STATE::Start, and TRUE.

Referenced by IopPortFindSuitableRange().

    01234                    :
    01235
    01236     This routine determines if the range (Start-(Length-1)) is available taking
    01237     into account any aliases.
    01238
    01239 Arguments:
    01240
    01241     Arbiter - The instance data of the arbiter who was called.
    01242
    01243     State - The state of the current arbitration.
    01244
    01245 Return Value:
    01246
    01247     TRUE if the range is available, FALSE otherwise.
    01248
    01249 --*/
    01250
    01251 {
    01252     NTSTATUS status;
    01253     ULONGLONG alias = State->Start;
    01254     BOOLEAN aliasAvailable;
    01255     UCHAR userFlagsMask = 0;
    01256
    01257     PAGED_CODE();
    01258
    01259 #if defined(BUGFEST_HACKS)
    01260     //
    01261     // For the purposes of the Bug^H^H^HPlugFest don't mind is aliases conflict
    01262     // with any devices but still add them...
    01263     //
    01264     return TRUE;
    01265 #endif
    01266
    01267     //
    01268     // For legacy requests from IoAssignResources (directly or by way of
    01269     // HalAssignSlotResources) or IoReportResourceUsage we consider preallocated
    01270     // resources to be available for backward compatibility reasons.
    01271     //
    01272     if (State->Entry->RequestSource == ArbiterRequestLegacyReported
    01273         || State->Entry->RequestSource == ArbiterRequestLegacyAssigned) {
    01274
    01275         userFlagsMask |= ARBITER_RANGE_BOOT_ALLOCATED;
    01276     }
    01277
    01278     while (IopPortGetNextAlias(State->CurrentAlternative->Descriptor->Flags,
    01279                              alias,
    01280                              &alias)) {
    01281
    01282         status = RtlIsRangeAvailable(
    01283                      Arbiter->PossibleAllocation,
    01284                      alias,
    01285                      alias + State->CurrentAlternative->Length - 1,
    01286                      State->CurrentAlternative->Flags & ARBITER_ALTERNATIVE_FLAG_SHARED ?
    01287                         RTL_RANGE_LIST_SHARED_OK : 0,
    01288                      userFlagsMask,
    01289                      Arbiter->ConflictCallbackContext,
    01290                      Arbiter->ConflictCallback,
    01291                      &aliasAvailable
    01292                      );
    01293
    01294         ASSERT(NT_SUCCESS(status));
    01295
    01296         if (!aliasAvailable) {
    01297
    01298             ARBITER_ALLOCATION_STATE tempState;
    01299
    01300             //
    01301             // Check if we allow this conflict by calling OverrideConflict -
    01302             // we will need to falsify ourselves an allocation state first
    01303             //
    01304             // BUGBUG - this works but relies on knowing what OverrideConflict
    01305             // looks at.  A better fix invloves storing the aliases in another
    01306             // list but this it too much of a change for Win2k
    01307             //
    01308
    01309             RtlCopyMemory(&tempState, State, sizeof(ARBITER_ALLOCATION_STATE));
    01310
    01311             tempState.CurrentMinimum = alias;
    01312             tempState.CurrentMaximum = alias + State->CurrentAlternative->Length - 1;
    01313
    01314             if (Arbiter->OverrideConflict(Arbiter, &tempState)) {
    01315                 //
    01316                 // We decided this conflict was ok so contine checking the rest
    01317                 // of the aliases
    01318                 //
    01319
    01320                 continue;
    01321
    01322             }
    01323
    01324             //
    01325             // An alias isn't available - get another possibility
    01326             //
    01327
    01328             ARB_PRINT(2,
    01329                         ("\t\tAlias 0x%x-0x%x not available\n",
    01330                         alias,
    01331                         alias + State->CurrentAlternative->Length - 1
    01332                         ));
    01333
    01334             return FALSE;
    01335         }
    01336     }
    01337
    01338     return TRUE;
    01339 }

BOOLEAN IopPortIsAliasedRangeAvailable | ( | IN PARBITER_INSTANCE | Arbiter,
|  | IN PARBITER_ALLOCATION_STATE | State
| ) |

NTSTATUS IopTranslateBusAddress | ( | IN PHYSICAL_ADDRESS | SourceAddress,
|  | IN UCHAR | SourceResourceType,
|  | OUT PPHYSICAL_ADDRESS | TargetAddress,
|  | OUT PUCHAR | TargetResourceType
| ) |

Definition at line 155 of file pnpmemio.c.

References ADDRESS_SPACE_DENSE_MEMORY, ADDRESS_SPACE_MEMORY, ADDRESS_SPACE_PORT, ADDRESS_SPACE_USER_DENSE_MEMORY, ADDRESS_SPACE_USER_MEMORY, ADDRESS_SPACE_USER_PORT, ARB_PRINT, ASSERT, HalTranslateBusAddress(), NTSTATUS(), and PAGED_CODE.

Referenced by IopGenericTranslateOrdering().

    00163                    :
    00164
    00165     This routine translates addresses.
    00166
    00167 Parameters:
    00168
    00169     SourceAddress - The address to translate
    00170
    00171     ResourceType - The resource type (IO or Memory) we are translaing.  If the
    00172         address space changes from IO->Memory this will be updated.
    00173
    00174     TargetAddress - Pointer to where the target should be translated to.
    00175
    00176 Return Value:
    00177
    00178     STATUS_SUCCESS or an error status
    00179
    00180 --*/
    00181
    00182 {
    00183     NTSTATUS status = STATUS_UNSUCCESSFUL;
    00184     ULONG sourceAddressSpace, targetAddressSpace;
    00185     BOOLEAN translated;
    00186
    00187     PAGED_CODE();
    00188
    00189     //
    00190     // Select the appropriate address space
    00191     //
    00192
    00193     if (SourceResourceType == CmResourceTypeMemory) {
    00194         sourceAddressSpace = ADDRESS_SPACE_MEMORY;
    00195     } else if (SourceResourceType == CmResourceTypePort) {
    00196         sourceAddressSpace = ADDRESS_SPACE_PORT;
    00197     } else {
    00198         return STATUS_INVALID_PARAMETER;
    00199     }
    00200
    00201     ARB_PRINT(
    00202         2,
    00203         ("Translating %s address 0x%I64x => ",
    00204         SourceResourceType == CmResourceTypeMemory ? "Memory" : "I/O",
    00205         SourceAddress.QuadPart
    00206        ));
    00207
    00208     //
    00209     // HACKHACK Ask the HAL to translate on ISA bus - if we can't then just
    00210     // don't translate because this must be a PCI system so the root arbiters
    00211     // don't do much (Yes it's a steaming hack but it'll work for beta 1)
    00212     //
    00213
    00214     targetAddressSpace = sourceAddressSpace;
    00215     translated = HalTranslateBusAddress(
    00216                      Isa,
    00217                      0,
    00218                      SourceAddress,
    00219                      &targetAddressSpace,
    00220                      TargetAddress
    00221                      );
    00222
    00223     if (!translated) {
    00224         ARB_PRINT(2,("Translation failed!\n"));
    00225         return STATUS_UNSUCCESSFUL;
    00226     }
    00227
    00228     //
    00229     // Update the resource type in the target if we have gone from Io to Memory
    00230     //
    00231
    00232
    00233     //
    00234     // BUBBUG - update the length for IO -> Memory (Dense vs Sparse)
    00235     // I think the answer is dense -> spares is multiply length by 32
    00236     //
    00237
    00238     if (targetAddressSpace == ADDRESS_SPACE_MEMORY
    00239     ||  targetAddressSpace == ADDRESS_SPACE_USER_MEMORY
    00240     ||  targetAddressSpace == ADDRESS_SPACE_DENSE_MEMORY
    00241     ||  targetAddressSpace == ADDRESS_SPACE_USER_DENSE_MEMORY) {
    00242         *TargetResourceType = CmResourceTypeMemory;
    00243     } else if (targetAddressSpace == ADDRESS_SPACE_PORT
    00244            ||  targetAddressSpace == ADDRESS_SPACE_USER_PORT) {
    00245         *TargetResourceType = CmResourceTypePort;
    00246     } else {
    00247         ASSERT(0 && "Translation has returned an unknown address space");
    00248     }
    00249
    00250     ARB_PRINT(
    00251         2,
    00252         ("%s address 0x%I64x\n",
    00253         *TargetResourceType == CmResourceTypeMemory ? "Memory" : "I/O",
    00254         TargetAddress->QuadPart
    00255         ));
    00256
    00257     return STATUS_SUCCESS;
    00258
    00259 }