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:
Jérôme Duval
2008-03-05 20:06:18 +00:00
parent d401b8f030
commit 2d2212bd71
+23 -10
View File
@@ -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;
} }