@@ -102,55 +102,68 @@ static int check_type_overlap(u8 *prev, u8 *curr)
102
102
return 0 ;
103
103
}
104
104
105
- /*
106
- * Error/Semi-error returns:
107
- * MTRR_TYPE_INVALID - when MTRR is not enabled
108
- * *repeat == 1 implies [start:end] spanned across MTRR range and type returned
109
- * corresponds only to [start:*partial_end].
110
- * Caller has to lookup again for [*partial_end:end].
105
+ /**
106
+ * mtrr_type_lookup_fixed - look up memory type in MTRR fixed entries
107
+ *
108
+ * Return the MTRR fixed memory type of 'start'.
109
+ *
110
+ * MTRR fixed entries are divided into the following ways:
111
+ * 0x00000 - 0x7FFFF : This range is divided into eight 64KB sub-ranges
112
+ * 0x80000 - 0xBFFFF : This range is divided into sixteen 16KB sub-ranges
113
+ * 0xC0000 - 0xFFFFF : This range is divided into sixty-four 4KB sub-ranges
114
+ *
115
+ * Return Values:
116
+ * MTRR_TYPE_(type) - Matched memory type
117
+ * MTRR_TYPE_INVALID - Unmatched
118
+ */
119
+ static u8 mtrr_type_lookup_fixed (u64 start , u64 end )
120
+ {
121
+ int idx ;
122
+
123
+ if (start >= 0x100000 )
124
+ return MTRR_TYPE_INVALID ;
125
+
126
+ /* 0x0 - 0x7FFFF */
127
+ if (start < 0x80000 ) {
128
+ idx = 0 ;
129
+ idx += (start >> 16 );
130
+ return mtrr_state .fixed_ranges [idx ];
131
+ /* 0x80000 - 0xBFFFF */
132
+ } else if (start < 0xC0000 ) {
133
+ idx = 1 * 8 ;
134
+ idx += ((start - 0x80000 ) >> 14 );
135
+ return mtrr_state .fixed_ranges [idx ];
136
+ }
137
+
138
+ /* 0xC0000 - 0xFFFFF */
139
+ idx = 3 * 8 ;
140
+ idx += ((start - 0xC0000 ) >> 12 );
141
+ return mtrr_state .fixed_ranges [idx ];
142
+ }
143
+
144
+ /**
145
+ * mtrr_type_lookup_variable - look up memory type in MTRR variable entries
146
+ *
147
+ * Return Value:
148
+ * MTRR_TYPE_(type) - Matched memory type or default memory type (unmatched)
149
+ *
150
+ * Output Argument:
151
+ * repeat - Set to 1 when [start:end] spanned across MTRR range and type
152
+ * returned corresponds only to [start:*partial_end]. Caller has
153
+ * to lookup again for [*partial_end:end].
111
154
*/
112
- static u8 __mtrr_type_lookup (u64 start , u64 end , u64 * partial_end , int * repeat )
155
+ static u8 mtrr_type_lookup_variable (u64 start , u64 end , u64 * partial_end ,
156
+ int * repeat )
113
157
{
114
158
int i ;
115
159
u64 base , mask ;
116
160
u8 prev_match , curr_match ;
117
161
118
162
* repeat = 0 ;
119
- if (!mtrr_state_set )
120
- return MTRR_TYPE_INVALID ;
121
-
122
- if (!(mtrr_state .enabled & MTRR_STATE_MTRR_ENABLED ))
123
- return MTRR_TYPE_INVALID ;
124
163
125
- /* Make end inclusive end, instead of exclusive */
164
+ /* Make end inclusive instead of exclusive */
126
165
end -- ;
127
166
128
- /* Look in fixed ranges. Just return the type as per start */
129
- if ((start < 0x100000 ) &&
130
- (mtrr_state .have_fixed ) &&
131
- (mtrr_state .enabled & MTRR_STATE_MTRR_FIXED_ENABLED )) {
132
- int idx ;
133
-
134
- if (start < 0x80000 ) {
135
- idx = 0 ;
136
- idx += (start >> 16 );
137
- return mtrr_state .fixed_ranges [idx ];
138
- } else if (start < 0xC0000 ) {
139
- idx = 1 * 8 ;
140
- idx += ((start - 0x80000 ) >> 14 );
141
- return mtrr_state .fixed_ranges [idx ];
142
- } else {
143
- idx = 3 * 8 ;
144
- idx += ((start - 0xC0000 ) >> 12 );
145
- return mtrr_state .fixed_ranges [idx ];
146
- }
147
- }
148
-
149
- /*
150
- * Look in variable ranges
151
- * Look of multiple ranges matching this address and pick type
152
- * as per MTRR precedence
153
- */
154
167
prev_match = MTRR_TYPE_INVALID ;
155
168
for (i = 0 ; i < num_var_ranges ; ++ i ) {
156
169
unsigned short start_state , end_state , inclusive ;
@@ -186,7 +199,8 @@ static u8 __mtrr_type_lookup(u64 start, u64 end, u64 *partial_end, int *repeat)
186
199
* advised to lookup again after having adjusted start
187
200
* and end.
188
201
*
189
- * Note: This way we handle multiple overlaps as well.
202
+ * Note: This way we handle overlaps with multiple
203
+ * entries and the default type properly.
190
204
*/
191
205
if (start_state )
192
206
* partial_end = base + get_mtrr_size (mask );
@@ -215,44 +229,64 @@ static u8 __mtrr_type_lookup(u64 start, u64 end, u64 *partial_end, int *repeat)
215
229
return curr_match ;
216
230
}
217
231
218
- if (mtrr_tom2 ) {
219
- if (start >= (1ULL <<32 ) && (end < mtrr_tom2 ))
220
- return MTRR_TYPE_WRBACK ;
221
- }
222
-
223
232
if (prev_match != MTRR_TYPE_INVALID )
224
233
return prev_match ;
225
234
226
235
return mtrr_state .def_type ;
227
236
}
228
237
229
- /*
230
- * Returns the effective MTRR type for the region
231
- * Error return:
232
- * MTRR_TYPE_INVALID - when MTRR is not enabled
238
+ /**
239
+ * mtrr_type_lookup - look up memory type in MTRR
240
+ *
241
+ * Return Values:
242
+ * MTRR_TYPE_(type) - The effective MTRR type for the region
243
+ * MTRR_TYPE_INVALID - MTRR is disabled
233
244
*/
234
245
u8 mtrr_type_lookup (u64 start , u64 end )
235
246
{
236
247
u8 type , prev_type ;
237
248
int repeat ;
238
249
u64 partial_end ;
239
250
240
- type = __mtrr_type_lookup (start , end , & partial_end , & repeat );
251
+ if (!mtrr_state_set )
252
+ return MTRR_TYPE_INVALID ;
253
+
254
+ if (!(mtrr_state .enabled & MTRR_STATE_MTRR_ENABLED ))
255
+ return MTRR_TYPE_INVALID ;
256
+
257
+ /*
258
+ * Look up the fixed ranges first, which take priority over
259
+ * the variable ranges.
260
+ */
261
+ if ((start < 0x100000 ) &&
262
+ (mtrr_state .have_fixed ) &&
263
+ (mtrr_state .enabled & MTRR_STATE_MTRR_FIXED_ENABLED ))
264
+ return mtrr_type_lookup_fixed (start , end );
265
+
266
+ /*
267
+ * Look up the variable ranges. Look of multiple ranges matching
268
+ * this address and pick type as per MTRR precedence.
269
+ */
270
+ type = mtrr_type_lookup_variable (start , end , & partial_end , & repeat );
241
271
242
272
/*
243
273
* Common path is with repeat = 0.
244
274
* However, we can have cases where [start:end] spans across some
245
- * MTRR range. Do repeated lookups for that case here.
275
+ * MTRR ranges and/or the default type. Do repeated lookups for
276
+ * that case here.
246
277
*/
247
278
while (repeat ) {
248
279
prev_type = type ;
249
280
start = partial_end ;
250
- type = __mtrr_type_lookup (start , end , & partial_end , & repeat );
281
+ type = mtrr_type_lookup_variable (start , end , & partial_end , & repeat );
251
282
252
283
if (check_type_overlap (& prev_type , & type ))
253
284
return type ;
254
285
}
255
286
287
+ if (mtrr_tom2 && (start >= (1ULL <<32 )) && (end < mtrr_tom2 ))
288
+ return MTRR_TYPE_WRBACK ;
289
+
256
290
return type ;
257
291
}
258
292
0 commit comments