Make two runs of MTRR setting when setting memory ranges to write-back. At the
first run only set up uncacheable MTRRs and in the second run set the write-back ones up. If this order is not followed, we could set too large ranges to cacheable first and then limit it back to uncacheable later. On systems with enough physical memory this would lead to a temporary situation in which areas become cacheable that must not be, resulting in system hangs or other unexpected behaviour. Fixes last part of #4018. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31027 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
96b24aef3f
commit
f835a75f31
@ -272,33 +272,48 @@ set_memory_write_back(int32 id, uint64 base, uint64 length)
|
||||
|
||||
#ifdef TRACE_MTRR
|
||||
dprintf("solutions: ");
|
||||
for (int i=0; i<sSolutionCount; i++) {
|
||||
dprintf("0x%Lx ", sSolutions[i]);
|
||||
}
|
||||
dprintf("\n");
|
||||
for (int i=0; i<sSolutionCount; i++)
|
||||
dprintf("0x%Lx ", sSolutions[i]);
|
||||
dprintf("\n");
|
||||
#endif
|
||||
|
||||
bool nextDown = false;
|
||||
for (int i = 0; i < sSolutionCount; i++) {
|
||||
if (sSolutions[i] < 0) {
|
||||
if (nextDown)
|
||||
base += sSolutions[i];
|
||||
err = set_memory_type(id, base, -sSolutions[i], nextDown ? B_MTR_UC : B_MTR_WB);
|
||||
if (err != B_OK) {
|
||||
dprintf("set_memory_type returned %s (0x%lx)\n", strerror(err), err);
|
||||
for (int run = 0; run < 2; run++) {
|
||||
bool nextDown = false;
|
||||
uint64 newBase = base;
|
||||
|
||||
for (int i = 0; i < sSolutionCount; i++) {
|
||||
if (sSolutions[i] < 0) {
|
||||
if (nextDown)
|
||||
newBase += sSolutions[i];
|
||||
|
||||
if ((run == 0) == nextDown) {
|
||||
err = set_memory_type(id, newBase, -sSolutions[i],
|
||||
nextDown ? B_MTR_UC : B_MTR_WB);
|
||||
if (err != B_OK) {
|
||||
dprintf("set_memory_type returned %s (0x%lx)\n",
|
||||
strerror(err), err);
|
||||
}
|
||||
}
|
||||
|
||||
if (!nextDown)
|
||||
newBase -= sSolutions[i];
|
||||
nextDown = !nextDown;
|
||||
} else {
|
||||
if (nextDown)
|
||||
newBase -= sSolutions[i];
|
||||
|
||||
if ((run == 0) == nextDown) {
|
||||
err = set_memory_type(id, newBase, sSolutions[i],
|
||||
nextDown ? B_MTR_UC : B_MTR_WB);
|
||||
if (err != B_OK) {
|
||||
dprintf("set_memory_type returned %s (0x%lx)\n",
|
||||
strerror(err), err);
|
||||
}
|
||||
}
|
||||
|
||||
if (!nextDown)
|
||||
newBase += sSolutions[i];
|
||||
}
|
||||
if (!nextDown)
|
||||
base -= sSolutions[i];
|
||||
nextDown = !nextDown;
|
||||
} else {
|
||||
if (nextDown)
|
||||
base -= sSolutions[i];
|
||||
err = set_memory_type(id, base, sSolutions[i], nextDown ? B_MTR_UC : B_MTR_WB);
|
||||
if (err != B_OK) {
|
||||
dprintf("set_memory_type returned %s (0x%lx)\n", strerror(err), err);
|
||||
}
|
||||
if (!nextDown)
|
||||
base += sSolutions[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user