now checks if another mtrr range is extended by a new one and extends it

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24582 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Jérôme Duval
2008-03-25 20:55:12 +00:00
parent c12ed8563a
commit cd9ce121d9
+23 -6
View File
@@ -78,14 +78,27 @@ free_mtrr(int32 index)
} }
/*!
Checks if the provided range overlaps an existing mtrr range
If it actually extends an existing range, extendedIndex is filled
*/
static bool static bool
is_memory_overlapping(uint64 base, uint64 length) is_memory_overlapping(uint64 base, uint64 length, int32 *extendedIndex)
{ {
*extendedIndex = -1;
for (uint32 index = 0; index < sMemoryTypeRegisterCount; index++) { for (uint32 index = 0; index < sMemoryTypeRegisterCount; index++) {
if (sMemoryTypeBitmap & (1UL << index)) { if (sMemoryTypeBitmap & (1UL << index)) {
uint64 b,l; uint64 b,l;
uint8 t; uint8 t;
x86_get_mtrr(index, &b, &l, &t); x86_get_mtrr(index, &b, &l, &t);
// check first for write combining extensions
if (base < b
&& (base + length) > (b + l)
&& t == IA32_MTR_WRITE_COMBINING) {
*extendedIndex = index;
return true;
}
if ((base > b && base < (b + l)) if ((base > b && base < (b + l))
|| ((base + length) > b || ((base + length) > b
&& (base + length) < (b + l))) && (base + length) < (b + l)))
@@ -128,7 +141,7 @@ nearest_powers(uint64 value, uint64 *lower, uint64 *upper)
static status_t static status_t
set_memory_type(int32 id, uint64 base, uint64 length, uint32 type) set_memory_type(int32 id, uint64 base, uint64 length, uint32 type)
{ {
int32 index; int32 index = -1;
if (type == 0) if (type == 0)
return B_OK; return B_OK;
@@ -158,9 +171,12 @@ set_memory_type(int32 id, uint64 base, uint64 length, uint32 type)
// check if it overlaps // check if it overlaps
if (type == IA32_MTR_WRITE_COMBINING if (type == IA32_MTR_WRITE_COMBINING
&& is_memory_overlapping(base, length)) { && is_memory_overlapping(base, length, &index)) {
dprintf("allocate MTRR failed, it overlaps an existing MTRR slot\n"); if (index < 0) {
return B_BAD_VALUE; dprintf("allocate MTRR failed, it overlaps an existing MTRR slot\n");
return B_BAD_VALUE;
}
// we replace an existing write-combining mtrr with a bigger one at the index position
} }
// length must be a power of 2; just round it up to the next value // length must be a power of 2; just round it up to the next value
@@ -175,7 +191,8 @@ set_memory_type(int32 id, uint64 base, uint64 length, uint32 type)
if (base & (length - 1)) if (base & (length - 1))
return B_BAD_VALUE; return B_BAD_VALUE;
index = allocate_mtrr(); if (index < 0)
index = allocate_mtrr();
if (index < 0) if (index < 0)
return B_ERROR; return B_ERROR;