Some under-cooked thoughts:
Assuming 32-bit physical addresses (no pae, no long mode, etc.)
If the mask is 0xf9000000 (this creates holes), then consider only the zeroes which lie towards the left of the LSB that is 1.
In the below figure, the LSB that is 1 is at bit position 24 (counting from 0), so consider the zeroes at bit positions 25 and 26.
Code:
3322 2222 2222 1111 1111 1100 0000 0000
1098 7654 3210 9876 5432 1098 7654 3210
---------------------------------------------------
1111 1001 0000 0000 0000 0000 0000 0000
# These 4 range-sets, when ANDed with the mask 0xf9000000, will output the same result, for a given choice of g, h, i, j, k and m bits.
ghij k00m ....
ghij k01m ....
ghij k10m ....
ghij k11m ....
Suppose we choose the base address with bits 25 and 26 to be 0 (to simplify matters):
Code:
ghij k..m ....
-------------
1011 1001 ....
That corresponds to base 0xb9000000. These ranges are mapped:
Code:
[0xb9000000, 0xb9fffffff] (corresponding to 1011 1001 ....)
[0xbb000000, 0xbbfffffff] (corresponding to 1011 1011 ....)
[0xbd000000, 0xbdfffffff] (corresponding to 1011 1101 ....)
[0xbf000000, 0xbffffffff] (corresponding to 1011 1111 ....)
The size of the mapping is exactly -0xf9000000 = 0x7000000. (Note that the last unmapped region, beginning at 0xc0000000, is ignored).
Thus, the # of mapped regions in a discontinuous range is equal to 2^a where a == # of zeros in the mask left to the LSB that is 1, assuming that the base address is approriately chosen, else it may be less. The base address choice which results in the largest possible region is when all those zero-positions (which are left to the LSB that is 1 in the mask) are kept as zero.
The total size of the region is -mask, when ignoring the size of the last unmapped region of the MTRR, and when assuming that the base address chosen is one of the "natural" base addresses for the given mask.
This should help in creating an array of base, size of the mappings (multiple such maps per MTRR if there are discontinuous regions in an MTRR). Then the "MTRR Precedences" can be applied, range intersection can be performed, etc.