{\r
PCI_ROOT_BRIDGE_INSTANCE *PrivateData;\r
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *PciRbAddr;\r
- UINT64 MaxCount;\r
+ UINT32 Stride;\r
UINT64 Base;\r
UINT64 Limit;\r
\r
//\r
// Check to see if Address is aligned\r
//\r
- if ((Address & (UINT64)(mInStride[Width] - 1)) != 0) {\r
+ Stride = mInStride[Width];\r
+ if ((Address & (UINT64)(Stride - 1)) != 0) {\r
return EFI_UNSUPPORTED;\r
}\r
\r
// Since Limit can be the maximum integer value supported by the CPU and Count \r
// can also be the maximum integer value supported by the CPU, this range\r
// check must be adjusted to avoid all oveflow conditions.\r
- // \r
- // The following form of the range check is equivalent but assumes that \r
- // Limit is of the form (2^n - 1).\r
//\r
if (OperationType == IoOperation) {\r
Base = PrivateData->IoBase;\r
Limit = MAX_PCI_REG_ADDRESS;\r
}\r
\r
+ if (Limit < Address) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
if (Address < Base) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- if (Count == 0) {\r
- if (Address > Limit) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- } else { \r
- MaxCount = RShiftU64 (Limit, Width);\r
- if (MaxCount < (Count - 1)) {\r
+ //\r
+ // Base <= Address <= Limit\r
+ //\r
+ if (Address == 0 && Limit == MAX_UINT64) {\r
+ //\r
+ // 2^64 bytes are valid to transfer. With Stride == 1, that's simply\r
+ // impossible to reach in Count; with Stride in {2, 4, 8}, we can divide\r
+ // both 2^64 and Stride with 2.\r
+ //\r
+ if (Stride > 1 && Count > DivU64x32 (BIT63, Stride / 2)) {\r
return EFI_UNSUPPORTED;\r
}\r
- if (Address > LShiftU64 (MaxCount - Count + 1, Width)) {\r
+ } else {\r
+ //\r
+ // (Limit - Address) does not wrap, and it is smaller than MAX_UINT64.\r
+ //\r
+ if (Count > DivU64x32 (Limit - Address + 1, Stride)) {\r
return EFI_UNSUPPORTED;\r
}\r
}\r