here with 3GB of memory, a 4GB MTRR slot is being written, which triggers a reboot.
we now split more than 2GB MTRR slot, we might improve this and split more and more. this could fix the bug #1711. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24244 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -91,21 +91,23 @@ set_memory_type(int32 id, uint64 base, uint64 length, uint32 type)
|
|||||||
if (type == 0)
|
if (type == 0)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
|
uint32 newType;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case B_MTR_UC:
|
case B_MTR_UC:
|
||||||
type = IA32_MTR_UNCACHED;
|
newType = IA32_MTR_UNCACHED;
|
||||||
break;
|
break;
|
||||||
case B_MTR_WC:
|
case B_MTR_WC:
|
||||||
type = IA32_MTR_WRITE_COMBINING;
|
newType = IA32_MTR_WRITE_COMBINING;
|
||||||
break;
|
break;
|
||||||
case B_MTR_WT:
|
case B_MTR_WT:
|
||||||
type = IA32_MTR_WRITE_THROUGH;
|
newType = IA32_MTR_WRITE_THROUGH;
|
||||||
break;
|
break;
|
||||||
case B_MTR_WP:
|
case B_MTR_WP:
|
||||||
type = IA32_MTR_WRITE_PROTECTED;
|
newType = IA32_MTR_WRITE_PROTECTED;
|
||||||
break;
|
break;
|
||||||
case B_MTR_WB:
|
case B_MTR_WB:
|
||||||
type = IA32_MTR_WRITE_BACK;
|
newType = IA32_MTR_WRITE_BACK;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -116,14 +118,19 @@ set_memory_type(int32 id, uint64 base, uint64 length, uint32 type)
|
|||||||
return B_NOT_SUPPORTED;
|
return B_NOT_SUPPORTED;
|
||||||
|
|
||||||
// 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
|
||||||
length = nearest_power(length);
|
uint64 newLength = nearest_power(length);
|
||||||
if (length + base <= base) {
|
|
||||||
|
// avoids more than 2GB slots
|
||||||
|
if (newLength > 0x80000000)
|
||||||
|
newLength = 0x80000000;
|
||||||
|
|
||||||
|
if (newLength + base <= base) {
|
||||||
// 4GB overflow
|
// 4GB overflow
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// base must be aligned to the length
|
// base must be aligned to the length
|
||||||
if (base & (length - 1))
|
if (base & (newLength - 1))
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
index = allocate_mtrr();
|
index = allocate_mtrr();
|
||||||
@@ -131,10 +138,16 @@ set_memory_type(int32 id, uint64 base, uint64 length, uint32 type)
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
TRACE(("allocate MTRR slot %ld, base = %Lx, length = %Lx\n", index,
|
TRACE(("allocate MTRR slot %ld, base = %Lx, length = %Lx\n", index,
|
||||||
base, length));
|
base, newLength));
|
||||||
|
|
||||||
sMemoryTypeIDs[index] = id;
|
sMemoryTypeIDs[index] = id;
|
||||||
x86_set_mtrr(index, base, length, type);
|
x86_set_mtrr(index, base, newLength, newType);
|
||||||
|
|
||||||
|
// now handle remaining memory
|
||||||
|
if (length > newLength) {
|
||||||
|
// TODO iterate over smaller lengths to avoid the PCI hole after the physical memory.
|
||||||
|
set_memory_type(id, base + newLength, length - newLength, type);
|
||||||
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user