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_EXTENSIONPPORT_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 }


Generated on Sat May 15 19:45:14 2004 for test by doxygen 1.3.7