Some work in progress of the MTRR support. Shouldn't do any harm yet :-)

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15525 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2005-12-13 00:06:52 +00:00
parent b7e7814c79
commit 2ed21b8525
16 changed files with 299 additions and 114 deletions
+40 -16
View File
@@ -935,20 +935,22 @@ vm_create_anonymous_area(aspace_id aid, const char *name, void **address,
area_id
vm_map_physical_memory(aspace_id aid, const char *name, void **_address,
uint32 addressSpec, addr_t size, uint32 protection, addr_t phys_addr)
vm_map_physical_memory(aspace_id areaID, const char *name, void **_address,
uint32 addressSpec, addr_t size, uint32 protection,
addr_t physicalAddress)
{
vm_area *area;
vm_cache *cache;
vm_cache_ref *cache_ref;
vm_cache_ref *cacheRef;
vm_store *store;
addr_t map_offset;
addr_t mapOffset;
status_t status;
vm_address_space *aspace = vm_get_aspace_by_id(aid);
vm_address_space *aspace = vm_get_aspace_by_id(areaID);
TRACE(("vm_map_physical_memory(aspace = %ld, \"%s\", virtual = %p, spec = %ld,"
" size = %lu, protection = %ld, phys = %p)\n",
aid, name, _address, addressSpec, size, protection, (void *)phys_addr));
areaID, name, _address, addressSpec, size, protection,
(void *)physicalAddress));
if (!arch_vm_supports_protection(protection))
return B_NOT_SUPPORTED;
@@ -958,33 +960,36 @@ vm_map_physical_memory(aspace_id aid, const char *name, void **_address,
// if the physical address is somewhat inside a page,
// move the actual area down to align on a page boundary
map_offset = phys_addr % B_PAGE_SIZE;
size += map_offset;
phys_addr -= map_offset;
mapOffset = physicalAddress % B_PAGE_SIZE;
size += mapOffset;
physicalAddress -= mapOffset;
size = PAGE_ALIGN(size);
// create an device store object
store = vm_store_create_device(phys_addr);
// TODO: panic???
store = vm_store_create_device(physicalAddress);
if (store == NULL)
panic("vm_map_physical_memory: vm_store_create_device returned NULL");
cache = vm_cache_create(store);
if (cache == NULL)
panic("vm_map_physical_memory: vm_cache_create returned NULL");
cache_ref = vm_cache_ref_create(cache);
if (cache_ref == NULL)
cacheRef = vm_cache_ref_create(cache);
if (cacheRef == NULL)
panic("vm_map_physical_memory: vm_cache_ref_create returned NULL");
// tell the page scanner to skip over this area, it's pages are special
cache->scan_skip = 1;
vm_cache_acquire_ref(cache_ref, true);
vm_cache_acquire_ref(cacheRef, true);
status = map_backing_store(aspace, store, _address, 0, size,
addressSpec & ~B_MTR_MASK, 0, protection, REGION_NO_PRIVATE_MAP, &area, name);
vm_cache_release_ref(cache_ref);
vm_cache_release_ref(cacheRef);
if (status >= B_OK && (addressSpec & B_MTR_MASK) != 0) {
// set requested memory type
status = arch_vm_set_memory_type(area, addressSpec & B_MTR_MASK);
status = arch_vm_set_memory_type(area, physicalAddress,
addressSpec & B_MTR_MASK);
if (status < B_OK)
vm_put_area(area);
}
@@ -1003,7 +1008,7 @@ vm_map_physical_memory(aspace_id aid, const char *name, void **_address,
// modify the pointer returned to be offset back into the new area
// the same way the physical address in was offset
*_address = (void *)((addr_t)*_address + map_offset);
*_address = (void *)((addr_t)*_address + mapOffset);
return area->id;
}
@@ -2750,6 +2755,25 @@ vm_try_reserve_memory(size_t amount)
}
status_t
vm_set_area_memory_type(area_id id, addr_t physicalBase, uint32 type)
{
vm_area *area = vm_get_area(id);
if (area == NULL)
return B_BAD_VALUE;
status_t status = arch_vm_set_memory_type(area, physicalBase, type);
if (status < B_OK)
goto out;
arch_cpu_invalidate_TLB_range(area->base, area->size);
out:
vm_put_area(area);
return status;
}
/** This function enforces some protection properties:
* - if B_WRITE_AREA is set, B_WRITE_KERNEL_AREA is set as well
* - if only B_READ_AREA has been set, B_KERNEL_READ_AREA is also set