From cd9ce121d91c3bad01b46c0f10cc65c90ff7cda5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Tue, 25 Mar 2008 20:55:12 +0000 Subject: [PATCH] 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 --- src/system/kernel/arch/x86/arch_vm.cpp | 29 ++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/system/kernel/arch/x86/arch_vm.cpp b/src/system/kernel/arch/x86/arch_vm.cpp index 12a324c206..231995cb8b 100644 --- a/src/system/kernel/arch/x86/arch_vm.cpp +++ b/src/system/kernel/arch/x86/arch_vm.cpp @@ -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 -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++) { if (sMemoryTypeBitmap & (1UL << index)) { uint64 b,l; uint8 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)) || ((base + length) > b && (base + length) < (b + l))) @@ -128,7 +141,7 @@ nearest_powers(uint64 value, uint64 *lower, uint64 *upper) static status_t set_memory_type(int32 id, uint64 base, uint64 length, uint32 type) { - int32 index; + int32 index = -1; if (type == 0) return B_OK; @@ -158,9 +171,12 @@ set_memory_type(int32 id, uint64 base, uint64 length, uint32 type) // check if it overlaps if (type == IA32_MTR_WRITE_COMBINING - && is_memory_overlapping(base, length)) { - dprintf("allocate MTRR failed, it overlaps an existing MTRR slot\n"); - return B_BAD_VALUE; + && is_memory_overlapping(base, length, &index)) { + if (index < 0) { + 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 @@ -175,7 +191,8 @@ set_memory_type(int32 id, uint64 base, uint64 length, uint32 type) if (base & (length - 1)) return B_BAD_VALUE; - index = allocate_mtrr(); + if (index < 0) + index = allocate_mtrr(); if (index < 0) return B_ERROR;