Removed REGION_WIRING_* and REGION_ADDR_* and replaced them by their
BeOS counterparts. Improved output of dump_region_list(). Cleanup. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7850 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+209
-215
@@ -20,7 +20,6 @@
|
|||||||
#include <vm_store_null.h>
|
#include <vm_store_null.h>
|
||||||
#include <vm_store_vnode.h>
|
#include <vm_store_vnode.h>
|
||||||
#include <memheap.h>
|
#include <memheap.h>
|
||||||
#include <malloc.h>
|
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
#include <console.h>
|
#include <console.h>
|
||||||
#include <int.h>
|
#include <int.h>
|
||||||
@@ -231,12 +230,12 @@ find_and_insert_region_slot(vm_virtual_map *map, addr_t start, addr_t size, addr
|
|||||||
// dprintf("map->base 0x%x, map->size 0x%x\n", map->base, map->size);
|
// dprintf("map->base 0x%x, map->size 0x%x\n", map->base, map->size);
|
||||||
|
|
||||||
// do some sanity checking
|
// do some sanity checking
|
||||||
if(start < map->base || size == 0 || (end - 1) > (map->base + (map->size - 1)) || start + size > end)
|
if (start < map->base || size == 0 || (end - 1) > (map->base + (map->size - 1)) || start + size > end)
|
||||||
return ERR_VM_BAD_ADDRESS;
|
return ERR_VM_BAD_ADDRESS;
|
||||||
|
|
||||||
// walk up to the spot where we should start searching
|
// walk up to the spot where we should start searching
|
||||||
next_r = map->region_list;
|
next_r = map->region_list;
|
||||||
while(next_r) {
|
while (next_r) {
|
||||||
if(next_r->base >= start + size) {
|
if(next_r->base >= start + size) {
|
||||||
// we have a winner
|
// we have a winner
|
||||||
break;
|
break;
|
||||||
@@ -251,12 +250,13 @@ find_and_insert_region_slot(vm_virtual_map *map, addr_t start, addr_t size, addr
|
|||||||
if(next_r) dprintf("next_r->base 0x%x, next_r->size 0x%x\n", next_r->base, next_r->size);
|
if(next_r) dprintf("next_r->base 0x%x, next_r->size 0x%x\n", next_r->base, next_r->size);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch(addr_type) {
|
switch (addr_type) {
|
||||||
case REGION_ADDR_ANY_ADDRESS:
|
case B_ANY_ADDRESS:
|
||||||
|
case B_ANY_KERNEL_ADDRESS:
|
||||||
// find a hole big enough for a new region
|
// find a hole big enough for a new region
|
||||||
if(!last_r) {
|
if (!last_r) {
|
||||||
// see if we can build it at the beginning of the virtual map
|
// see if we can build it at the beginning of the virtual map
|
||||||
if(!next_r || (next_r->base >= map->base + size)) {
|
if (!next_r || (next_r->base >= map->base + size)) {
|
||||||
foundspot = true;
|
foundspot = true;
|
||||||
region->base = map->base;
|
region->base = map->base;
|
||||||
break;
|
break;
|
||||||
@@ -265,8 +265,8 @@ find_and_insert_region_slot(vm_virtual_map *map, addr_t start, addr_t size, addr
|
|||||||
next_r = next_r->aspace_next;
|
next_r = next_r->aspace_next;
|
||||||
}
|
}
|
||||||
// keep walking
|
// keep walking
|
||||||
while(next_r) {
|
while (next_r) {
|
||||||
if(next_r->base >= last_r->base + last_r->size + size) {
|
if (next_r->base >= last_r->base + last_r->size + size) {
|
||||||
// we found a spot
|
// we found a spot
|
||||||
foundspot = true;
|
foundspot = true;
|
||||||
region->base = last_r->base + last_r->size;
|
region->base = last_r->base + last_r->size;
|
||||||
@@ -275,30 +275,31 @@ find_and_insert_region_slot(vm_virtual_map *map, addr_t start, addr_t size, addr
|
|||||||
last_r = next_r;
|
last_r = next_r;
|
||||||
next_r = next_r->aspace_next;
|
next_r = next_r->aspace_next;
|
||||||
}
|
}
|
||||||
if((map->base + (map->size - 1)) >= (last_r->base + last_r->size + (size - 1))) {
|
if ((map->base + (map->size - 1)) >= (last_r->base + last_r->size + (size - 1))) {
|
||||||
// found a spot
|
// found a spot
|
||||||
foundspot = true;
|
foundspot = true;
|
||||||
region->base = last_r->base + last_r->size;
|
region->base = last_r->base + last_r->size;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case REGION_ADDR_EXACT_ADDRESS:
|
case B_EXACT_ADDRESS:
|
||||||
|
case B_EXACT_KERNEL_ADDRESS:
|
||||||
// see if we can create it exactly here
|
// see if we can create it exactly here
|
||||||
if(!last_r) {
|
if (!last_r) {
|
||||||
if(!next_r || (next_r->base >= start + size)) {
|
if(!next_r || (next_r->base >= start + size)) {
|
||||||
foundspot = true;
|
foundspot = true;
|
||||||
region->base = start;
|
region->base = start;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(next_r) {
|
if (next_r) {
|
||||||
if(last_r->base + last_r->size <= start && next_r->base >= start + size) {
|
if (last_r->base + last_r->size <= start && next_r->base >= start + size) {
|
||||||
foundspot = true;
|
foundspot = true;
|
||||||
region->base = start;
|
region->base = start;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if((last_r->base + (last_r->size - 1)) <= start - 1) {
|
if ((last_r->base + (last_r->size - 1)) <= start - 1) {
|
||||||
foundspot = true;
|
foundspot = true;
|
||||||
region->base = start;
|
region->base = start;
|
||||||
}
|
}
|
||||||
@@ -309,27 +310,27 @@ find_and_insert_region_slot(vm_virtual_map *map, addr_t start, addr_t size, addr
|
|||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(foundspot) {
|
if (!foundspot)
|
||||||
region->size = size;
|
|
||||||
if(last_r) {
|
|
||||||
region->aspace_next = last_r->aspace_next;
|
|
||||||
last_r->aspace_next = region;
|
|
||||||
} else {
|
|
||||||
region->aspace_next = map->region_list;
|
|
||||||
map->region_list = region;
|
|
||||||
}
|
|
||||||
map->change_count++;
|
|
||||||
return B_NO_ERROR;
|
|
||||||
} else {
|
|
||||||
return ERR_VM_NO_REGION_SLOT;
|
return ERR_VM_NO_REGION_SLOT;
|
||||||
|
|
||||||
|
region->size = size;
|
||||||
|
if (last_r) {
|
||||||
|
region->aspace_next = last_r->aspace_next;
|
||||||
|
last_r->aspace_next = region;
|
||||||
|
} else {
|
||||||
|
region->aspace_next = map->region_list;
|
||||||
|
map->region_list = region;
|
||||||
}
|
}
|
||||||
|
map->change_count++;
|
||||||
|
return B_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// a ref to the cache holding this store must be held before entering here
|
// a ref to the cache holding this store must be held before entering here
|
||||||
static int map_backing_store(vm_address_space *aspace, vm_store *store,
|
static int
|
||||||
void **vaddr, off_t offset, addr_t size,
|
map_backing_store(vm_address_space *aspace, vm_store *store, void **vaddr,
|
||||||
int addr_type, int wiring, int lock, int mapping,
|
off_t offset, addr_t size, int addr_type, int wiring, int lock,
|
||||||
vm_region **_region, const char *region_name)
|
int mapping, vm_region **_region, const char *region_name)
|
||||||
{
|
{
|
||||||
vm_cache *cache;
|
vm_cache *cache;
|
||||||
vm_cache_ref *cache_ref;
|
vm_cache_ref *cache_ref;
|
||||||
@@ -345,7 +346,7 @@ static int map_backing_store(vm_address_space *aspace, vm_store *store,
|
|||||||
|
|
||||||
region = _vm_create_region_struct(aspace, region_name, wiring, lock);
|
region = _vm_create_region_struct(aspace, region_name, wiring, lock);
|
||||||
if (!region)
|
if (!region)
|
||||||
return ENOMEM;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
cache = store->cache;
|
cache = store->cache;
|
||||||
cache_ref = cache->ref;
|
cache_ref = cache->ref;
|
||||||
@@ -355,13 +356,13 @@ static int map_backing_store(vm_address_space *aspace, vm_store *store,
|
|||||||
if (mapping == REGION_PRIVATE_MAP) {
|
if (mapping == REGION_PRIVATE_MAP) {
|
||||||
// create an anonymous store object
|
// create an anonymous store object
|
||||||
nu_store = vm_store_create_anonymous_noswap();
|
nu_store = vm_store_create_anonymous_noswap();
|
||||||
if(nu_store == NULL)
|
if (nu_store == NULL)
|
||||||
panic("map_backing_store: vm_create_store_anonymous_noswap returned NULL");
|
panic("map_backing_store: vm_create_store_anonymous_noswap returned NULL");
|
||||||
nu_cache = vm_cache_create(nu_store);
|
nu_cache = vm_cache_create(nu_store);
|
||||||
if(nu_cache == NULL)
|
if (nu_cache == NULL)
|
||||||
panic("map_backing_store: vm_cache_create returned NULL");
|
panic("map_backing_store: vm_cache_create returned NULL");
|
||||||
nu_cache_ref = vm_cache_ref_create(nu_cache);
|
nu_cache_ref = vm_cache_ref_create(nu_cache);
|
||||||
if(nu_cache_ref == NULL)
|
if (nu_cache_ref == NULL)
|
||||||
panic("map_backing_store: vm_cache_ref_create returned NULL");
|
panic("map_backing_store: vm_cache_ref_create returned NULL");
|
||||||
nu_cache->temporary = 1;
|
nu_cache->temporary = 1;
|
||||||
nu_cache->scan_skip = cache->scan_skip;
|
nu_cache->scan_skip = cache->scan_skip;
|
||||||
@@ -378,12 +379,12 @@ static int map_backing_store(vm_address_space *aspace, vm_store *store,
|
|||||||
|
|
||||||
mutex_lock(&cache_ref->lock);
|
mutex_lock(&cache_ref->lock);
|
||||||
// If we don't have enough committed space to cover through to the new end of region...
|
// If we don't have enough committed space to cover through to the new end of region...
|
||||||
if(store->committed_size < offset + size) {
|
if (store->committed_size < offset + size) {
|
||||||
// try to commit more memory
|
// try to commit more memory
|
||||||
off_t old_store_commitment = store->committed_size; // Note what we had
|
off_t old_store_commitment = store->committed_size; // Note what we had
|
||||||
off_t commitment = (store->ops->commit)(store, offset + size); // Commit through to the new end
|
off_t commitment = (store->ops->commit)(store, offset + size); // Commit through to the new end
|
||||||
if(commitment < offset + size) { // Uh oh - didn't work
|
if (commitment < offset + size) { // Uh oh - didn't work
|
||||||
if(cache->temporary) { // If this is a temporary cache, Check to see if we ran out of space and return error.
|
if (cache->temporary) { // If this is a temporary cache, Check to see if we ran out of space and return error.
|
||||||
int state = disable_interrupts();
|
int state = disable_interrupts();
|
||||||
acquire_spinlock(&max_commit_lock);
|
acquire_spinlock(&max_commit_lock);
|
||||||
|
|
||||||
@@ -414,7 +415,7 @@ static int map_backing_store(vm_address_space *aspace, vm_store *store,
|
|||||||
acquire_sem_etc(aspace->virtual_map.sem, WRITE_COUNT, 0, 0);
|
acquire_sem_etc(aspace->virtual_map.sem, WRITE_COUNT, 0, 0);
|
||||||
|
|
||||||
// check to see if this aspace has entered DELETE state
|
// check to see if this aspace has entered DELETE state
|
||||||
if(aspace->state == VM_ASPACE_STATE_DELETION) {
|
if (aspace->state == VM_ASPACE_STATE_DELETION) {
|
||||||
// okay, someone is trying to delete this aspace now, so we can't
|
// okay, someone is trying to delete this aspace now, so we can't
|
||||||
// insert the region, so back out
|
// insert the region, so back out
|
||||||
err = ERR_VM_INVALID_ASPACE;
|
err = ERR_VM_INVALID_ASPACE;
|
||||||
@@ -424,22 +425,25 @@ static int map_backing_store(vm_address_space *aspace, vm_store *store,
|
|||||||
{
|
{
|
||||||
addr_t search_addr, search_end;
|
addr_t search_addr, search_end;
|
||||||
|
|
||||||
if(addr_type == REGION_ADDR_EXACT_ADDRESS) {
|
switch (addr_type) {
|
||||||
search_addr = (addr_t)*vaddr;
|
case B_EXACT_ADDRESS:
|
||||||
search_end = (addr_t)*vaddr + size;
|
case B_EXACT_KERNEL_ADDRESS:
|
||||||
} else if(addr_type == REGION_ADDR_ANY_ADDRESS) {
|
search_addr = (addr_t)*vaddr;
|
||||||
search_addr = aspace->virtual_map.base;
|
search_end = (addr_t)*vaddr + size;
|
||||||
search_end = aspace->virtual_map.base + (aspace->virtual_map.size - 1);
|
break;
|
||||||
} else {
|
case B_ANY_ADDRESS:
|
||||||
err = EINVAL;
|
case B_ANY_KERNEL_ADDRESS:
|
||||||
goto err1b;
|
search_addr = aspace->virtual_map.base;
|
||||||
|
search_end = aspace->virtual_map.base + (aspace->virtual_map.size - 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
err = EINVAL;
|
||||||
|
goto err1b;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = find_and_insert_region_slot(&aspace->virtual_map,
|
err = find_and_insert_region_slot(&aspace->virtual_map, search_addr, size,
|
||||||
search_addr, size,
|
search_end, addr_type, region);
|
||||||
search_end, addr_type,
|
if (err < 0)
|
||||||
region);
|
|
||||||
if(err < 0)
|
|
||||||
goto err1b;
|
goto err1b;
|
||||||
*vaddr = (addr_t *)region->base;
|
*vaddr = (addr_t *)region->base;
|
||||||
}
|
}
|
||||||
@@ -496,44 +500,65 @@ vm_create_anonymous_region(aspace_id aid, const char *name, void **address,
|
|||||||
TRACE(("create_anonymous_region: %s: size 0x%lx\n", name, size));
|
TRACE(("create_anonymous_region: %s: size 0x%lx\n", name, size));
|
||||||
|
|
||||||
/* check parameters */
|
/* check parameters */
|
||||||
if (addr_type != REGION_ADDR_ANY_ADDRESS && addr_type != REGION_ADDR_EXACT_ADDRESS)
|
switch (addr_type) {
|
||||||
return B_BAD_VALUE;
|
case B_ANY_ADDRESS:
|
||||||
|
case B_EXACT_ADDRESS:
|
||||||
|
//case B_BASE_ADDRESS:
|
||||||
|
case B_ANY_KERNEL_ADDRESS:
|
||||||
|
case B_ANY_KERNEL_BLOCK_ADDRESS:
|
||||||
|
case B_EXACT_KERNEL_ADDRESS:
|
||||||
|
break;
|
||||||
|
case B_BASE_ADDRESS:
|
||||||
|
dprintf("create_area: B_BASE_ADDRESS demanded (switch to B_ANY_ADDRESS)!\n");
|
||||||
|
addr_type = B_ANY_ADDRESS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
switch (wiring) {
|
switch (wiring) {
|
||||||
case REGION_WIRING_WIRED:
|
case B_NO_LOCK:
|
||||||
case REGION_WIRING_WIRED_ALREADY:
|
case B_FULL_LOCK:
|
||||||
case REGION_WIRING_WIRED_CONTIG:
|
case B_LAZY_LOCK:
|
||||||
case REGION_WIRING_LAZY:
|
case B_CONTIGUOUS:
|
||||||
|
case B_ALREADY_WIRED:
|
||||||
|
break;
|
||||||
|
case B_LOMEM:
|
||||||
|
dprintf("B_LOMEM is not yet supported!\n");
|
||||||
|
wiring = B_FULL_LOCK;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
aspace = vm_get_aspace_by_id(aid);
|
aspace = vm_get_aspace_by_id(aid);
|
||||||
if(aspace == NULL)
|
if (aspace == NULL)
|
||||||
return ERR_VM_INVALID_ASPACE;
|
return ERR_VM_INVALID_ASPACE;
|
||||||
|
|
||||||
size = PAGE_ALIGN(size);
|
size = PAGE_ALIGN(size);
|
||||||
|
|
||||||
// create an anonymous store object
|
// create an anonymous store object
|
||||||
store = vm_store_create_anonymous_noswap();
|
store = vm_store_create_anonymous_noswap();
|
||||||
if(store == NULL)
|
if (store == NULL)
|
||||||
panic("vm_create_anonymous_region: vm_create_store_anonymous_noswap returned NULL");
|
panic("vm_create_anonymous_region: vm_create_store_anonymous_noswap returned NULL");
|
||||||
cache = vm_cache_create(store);
|
cache = vm_cache_create(store);
|
||||||
if(cache == NULL)
|
if (cache == NULL)
|
||||||
panic("vm_create_anonymous_region: vm_cache_create returned NULL");
|
panic("vm_create_anonymous_region: vm_cache_create returned NULL");
|
||||||
cache_ref = vm_cache_ref_create(cache);
|
cache_ref = vm_cache_ref_create(cache);
|
||||||
if(cache_ref == NULL)
|
if (cache_ref == NULL)
|
||||||
panic("vm_create_anonymous_region: vm_cache_ref_create returned NULL");
|
panic("vm_create_anonymous_region: vm_cache_ref_create returned NULL");
|
||||||
cache->temporary = 1;
|
cache->temporary = 1;
|
||||||
|
|
||||||
switch (wiring) {
|
switch (wiring) {
|
||||||
case REGION_WIRING_WIRED:
|
case B_LAZY_LOCK: // for now
|
||||||
case REGION_WIRING_WIRED_ALREADY:
|
case B_FULL_LOCK:
|
||||||
case REGION_WIRING_WIRED_CONTIG:
|
case B_CONTIGUOUS:
|
||||||
|
case B_ALREADY_WIRED:
|
||||||
cache->scan_skip = 1;
|
cache->scan_skip = 1;
|
||||||
break;
|
break;
|
||||||
case REGION_WIRING_LAZY:
|
case B_NO_LOCK:
|
||||||
|
//case B_LAZY_LOCK:
|
||||||
cache->scan_skip = 0;
|
cache->scan_skip = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -543,7 +568,7 @@ vm_create_anonymous_region(aspace_id aid, const char *name, void **address,
|
|||||||
vm_cache_acquire_ref(cache_ref, true);
|
vm_cache_acquire_ref(cache_ref, true);
|
||||||
err = map_backing_store(aspace, store, address, 0, size, addr_type, wiring, lock, REGION_NO_PRIVATE_MAP, ®ion, name);
|
err = map_backing_store(aspace, store, address, 0, size, addr_type, wiring, lock, REGION_NO_PRIVATE_MAP, ®ion, name);
|
||||||
vm_cache_release_ref(cache_ref);
|
vm_cache_release_ref(cache_ref);
|
||||||
if(err < 0) {
|
if (err < 0) {
|
||||||
vm_put_aspace(aspace);
|
vm_put_aspace(aspace);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -551,21 +576,24 @@ vm_create_anonymous_region(aspace_id aid, const char *name, void **address,
|
|||||||
// dprintf("create_anonymous_region: done calling map_backing store\n");
|
// dprintf("create_anonymous_region: done calling map_backing store\n");
|
||||||
|
|
||||||
cache_ref = store->cache->ref;
|
cache_ref = store->cache->ref;
|
||||||
switch(wiring) {
|
switch (wiring) {
|
||||||
case REGION_WIRING_LAZY:
|
case B_NO_LOCK:
|
||||||
|
case B_LAZY_LOCK:
|
||||||
break; // do nothing
|
break; // do nothing
|
||||||
case REGION_WIRING_WIRED: {
|
case B_FULL_LOCK:
|
||||||
|
{
|
||||||
// pages aren't mapped at this point, but we just simulate a fault on
|
// pages aren't mapped at this point, but we just simulate a fault on
|
||||||
// every page, which should allocate them
|
// every page, which should allocate them
|
||||||
addr_t va;
|
addr_t va;
|
||||||
// XXX remove
|
// XXX remove
|
||||||
for(va = region->base; va < region->base + region->size; va += PAGE_SIZE) {
|
for (va = region->base; va < region->base + region->size; va += PAGE_SIZE) {
|
||||||
// dprintf("mapping wired pages: region 0x%x, cache_ref 0x%x 0x%x\n", region, cache_ref, region->cache_ref);
|
// dprintf("mapping wired pages: region 0x%x, cache_ref 0x%x 0x%x\n", region, cache_ref, region->cache_ref);
|
||||||
vm_soft_fault(va, false, false);
|
vm_soft_fault(va, false, false);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case REGION_WIRING_WIRED_ALREADY: {
|
case B_ALREADY_WIRED:
|
||||||
|
{
|
||||||
// the pages should already be mapped. This is only really useful during
|
// the pages should already be mapped. This is only really useful during
|
||||||
// boot time. Find the appropriate vm_page objects and stick them in
|
// boot time. Find the appropriate vm_page objects and stick them in
|
||||||
// the cache object.
|
// the cache object.
|
||||||
@@ -578,15 +606,15 @@ vm_create_anonymous_region(aspace_id aid, const char *name, void **address,
|
|||||||
|
|
||||||
mutex_lock(&cache_ref->lock);
|
mutex_lock(&cache_ref->lock);
|
||||||
(*aspace->translation_map.ops->lock)(&aspace->translation_map);
|
(*aspace->translation_map.ops->lock)(&aspace->translation_map);
|
||||||
for(va = region->base; va < region->base + region->size; va += PAGE_SIZE, offset += PAGE_SIZE) {
|
for (va = region->base; va < region->base + region->size; va += PAGE_SIZE, offset += PAGE_SIZE) {
|
||||||
err = (*aspace->translation_map.ops->query)(&aspace->translation_map,
|
err = (*aspace->translation_map.ops->query)(&aspace->translation_map,
|
||||||
va, &pa, &flags);
|
va, &pa, &flags);
|
||||||
if(err < 0) {
|
if (err < 0) {
|
||||||
// dprintf("vm_create_anonymous_region: error looking up mapping for va 0x%x\n", va);
|
// dprintf("vm_create_anonymous_region: error looking up mapping for va 0x%x\n", va);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
page = vm_lookup_page(pa / PAGE_SIZE);
|
page = vm_lookup_page(pa / PAGE_SIZE);
|
||||||
if(page == NULL) {
|
if (page == NULL) {
|
||||||
// dprintf("vm_create_anonymous_region: error looking up vm_page structure for pa 0x%x\n", pa);
|
// dprintf("vm_create_anonymous_region: error looking up vm_page structure for pa 0x%x\n", pa);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -598,7 +626,7 @@ vm_create_anonymous_region(aspace_id aid, const char *name, void **address,
|
|||||||
mutex_unlock(&cache_ref->lock);
|
mutex_unlock(&cache_ref->lock);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case REGION_WIRING_WIRED_CONTIG: {
|
case B_CONTIGUOUS: {
|
||||||
addr_t va;
|
addr_t va;
|
||||||
addr_t phys_addr;
|
addr_t phys_addr;
|
||||||
int err;
|
int err;
|
||||||
@@ -856,7 +884,7 @@ vm_clone_region(aspace_id aid, char *name, void **address, int addr_type,
|
|||||||
return ERR_VM_INVALID_ASPACE;
|
return ERR_VM_INVALID_ASPACE;
|
||||||
|
|
||||||
src_region = vm_get_region_by_id(source_region);
|
src_region = vm_get_region_by_id(source_region);
|
||||||
if(src_region == NULL) {
|
if (src_region == NULL) {
|
||||||
vm_put_aspace(aspace);
|
vm_put_aspace(aspace);
|
||||||
return ERR_VM_INVALID_REGION;
|
return ERR_VM_INVALID_REGION;
|
||||||
}
|
}
|
||||||
@@ -1032,19 +1060,19 @@ display_mem(int argc, char **argv)
|
|||||||
|
|
||||||
address = atoul(argv[1]);
|
address = atoul(argv[1]);
|
||||||
|
|
||||||
if(argc >= 3) {
|
if (argc >= 3) {
|
||||||
num = -1;
|
num = -1;
|
||||||
num = atoi(argv[2]);
|
num = atoi(argv[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// build the format string
|
// build the format string
|
||||||
if(strcmp(argv[0], "db") == 0) {
|
if (strcmp(argv[0], "db") == 0) {
|
||||||
item_size = 1;
|
item_size = 1;
|
||||||
display_width = 16;
|
display_width = 16;
|
||||||
} else if(strcmp(argv[0], "ds") == 0) {
|
} else if (strcmp(argv[0], "ds") == 0) {
|
||||||
item_size = 2;
|
item_size = 2;
|
||||||
display_width = 8;
|
display_width = 8;
|
||||||
} else if(strcmp(argv[0], "dw") == 0) {
|
} else if (strcmp(argv[0], "dw") == 0) {
|
||||||
item_size = 4;
|
item_size = 4;
|
||||||
display_width = 4;
|
display_width = 4;
|
||||||
} else {
|
} else {
|
||||||
@@ -1053,20 +1081,20 @@ display_mem(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
dprintf("[0x%lx] '", address);
|
dprintf("[0x%lx] '", address);
|
||||||
for(j=0; j<min(display_width, num) * item_size; j++) {
|
for (j = 0; j < min(display_width, num) * item_size; j++) {
|
||||||
char c = *((char *)address + j);
|
char c = *((char *)address + j);
|
||||||
if(!isalnum(c)) {
|
if (!isalnum(c)) {
|
||||||
c = '.';
|
c = '.';
|
||||||
}
|
}
|
||||||
dprintf("%c", c);
|
dprintf("%c", c);
|
||||||
}
|
}
|
||||||
dprintf("'");
|
dprintf("'");
|
||||||
for(i=0; i<num; i++) {
|
for (i = 0; i < num; i++) {
|
||||||
if((i % display_width) == 0 && i != 0) {
|
if ((i % display_width) == 0 && i != 0) {
|
||||||
dprintf("\n[0x%lx] '", address + i * item_size);
|
dprintf("\n[0x%lx] '", address + i * item_size);
|
||||||
for(j=0; j<min(display_width, (num-i)) * item_size; j++) {
|
for (j = 0; j < min(display_width, (num-i)) * item_size; j++) {
|
||||||
char c = *((char *)address + i * item_size + j);
|
char c = *((char *)address + i * item_size + j);
|
||||||
if(!isalnum(c)) {
|
if (!isalnum(c)) {
|
||||||
c = '.';
|
c = '.';
|
||||||
}
|
}
|
||||||
dprintf("%c", c);
|
dprintf("%c", c);
|
||||||
@@ -1074,7 +1102,7 @@ display_mem(int argc, char **argv)
|
|||||||
dprintf("'");
|
dprintf("'");
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(item_size) {
|
switch (item_size) {
|
||||||
case 1:
|
case 1:
|
||||||
dprintf(" 0x%02x", *((uint8 *)address + i));
|
dprintf(" 0x%02x", *((uint8 *)address + i));
|
||||||
break;
|
break;
|
||||||
@@ -1092,7 +1120,9 @@ display_mem(int argc, char **argv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dump_cache_ref(int argc, char **argv)
|
|
||||||
|
static int
|
||||||
|
dump_cache_ref(int argc, char **argv)
|
||||||
{
|
{
|
||||||
addr_t address;
|
addr_t address;
|
||||||
vm_region *region;
|
vm_region *region;
|
||||||
@@ -1126,7 +1156,9 @@ static int dump_cache_ref(int argc, char **argv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *page_state_to_text(int state)
|
|
||||||
|
static const char *
|
||||||
|
page_state_to_text(int state)
|
||||||
{
|
{
|
||||||
switch(state) {
|
switch(state) {
|
||||||
case PAGE_STATE_ACTIVE:
|
case PAGE_STATE_ACTIVE:
|
||||||
@@ -1150,17 +1182,19 @@ static const char *page_state_to_text(int state)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dump_cache(int argc, char **argv)
|
|
||||||
|
static int
|
||||||
|
dump_cache(int argc, char **argv)
|
||||||
{
|
{
|
||||||
addr_t address;
|
addr_t address;
|
||||||
vm_cache *cache;
|
vm_cache *cache;
|
||||||
vm_page *page;
|
vm_page *page;
|
||||||
|
|
||||||
if(argc < 2) {
|
if (argc < 2) {
|
||||||
dprintf("cache: not enough arguments\n");
|
dprintf("cache: not enough arguments\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(strlen(argv[1]) < 2 || argv[1][0] != '0' || argv[1][1] != 'x') {
|
if (strlen(argv[1]) < 2 || argv[1][0] != '0' || argv[1][1] != 'x') {
|
||||||
dprintf("cache: invalid argument, pass address\n");
|
dprintf("cache: invalid argument, pass address\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1190,7 +1224,9 @@ static int dump_cache(int argc, char **argv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _dump_region(vm_region *region)
|
|
||||||
|
static void
|
||||||
|
_dump_region(vm_region *region)
|
||||||
{
|
{
|
||||||
dprintf("dump of region at %p:\n", region);
|
dprintf("dump of region at %p:\n", region);
|
||||||
dprintf("name: '%s'\n", region->name);
|
dprintf("name: '%s'\n", region->name);
|
||||||
@@ -1207,23 +1243,25 @@ static void _dump_region(vm_region *region)
|
|||||||
dprintf("cache_prev: %p\n", region->cache_prev);
|
dprintf("cache_prev: %p\n", region->cache_prev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dump_region(int argc, char **argv)
|
|
||||||
|
static int
|
||||||
|
dump_region(int argc, char **argv)
|
||||||
{
|
{
|
||||||
// int i;
|
// int i;
|
||||||
vm_region *region;
|
vm_region *region;
|
||||||
|
|
||||||
if(argc < 2) {
|
if (argc < 2) {
|
||||||
dprintf("region: not enough arguments\n");
|
dprintf("region: not enough arguments\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the argument looks like a hex number, treat it as such
|
// if the argument looks like a hex number, treat it as such
|
||||||
if(strlen(argv[1]) > 2 && argv[1][0] == '0' && argv[1][1] == 'x') {
|
if (strlen(argv[1]) > 2 && argv[1][0] == '0' && argv[1][1] == 'x') {
|
||||||
unsigned long num = strtoul(argv[1], NULL, 16);
|
unsigned long num = strtoul(argv[1], NULL, 16);
|
||||||
region_id id = num;
|
region_id id = num;
|
||||||
|
|
||||||
region = hash_lookup(region_table, &id);
|
region = hash_lookup(region_table, &id);
|
||||||
if(region == NULL) {
|
if (region == NULL) {
|
||||||
dprintf("invalid region id\n");
|
dprintf("invalid region id\n");
|
||||||
} else {
|
} else {
|
||||||
_dump_region(region);
|
_dump_region(region);
|
||||||
@@ -1234,8 +1272,8 @@ static int dump_region(int argc, char **argv)
|
|||||||
struct hash_iterator iter;
|
struct hash_iterator iter;
|
||||||
|
|
||||||
hash_open(region_table, &iter);
|
hash_open(region_table, &iter);
|
||||||
while((region = hash_next(region_table, &iter)) != NULL) {
|
while ((region = hash_next(region_table, &iter)) != NULL) {
|
||||||
if(region->name != NULL && strcmp(argv[1], region->name) == 0) {
|
if (region->name != NULL && strcmp(argv[1], region->name) == 0) {
|
||||||
_dump_region(region);
|
_dump_region(region);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1243,7 +1281,9 @@ static int dump_region(int argc, char **argv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
region_id find_region_by_address (addr_t vaddress)
|
|
||||||
|
region_id
|
||||||
|
find_region_by_address(addr_t vaddress)
|
||||||
{
|
{
|
||||||
vm_address_space *aspace;
|
vm_address_space *aspace;
|
||||||
vm_region *region;
|
vm_region *region;
|
||||||
@@ -1259,12 +1299,14 @@ region_id find_region_by_address (addr_t vaddress)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
region_id find_region_by_name(const char *name)
|
|
||||||
|
region_id
|
||||||
|
find_region_by_name(const char *name)
|
||||||
{
|
{
|
||||||
vm_region *region;
|
vm_region *region;
|
||||||
struct hash_iterator iter;
|
struct hash_iterator iter;
|
||||||
hash_open(region_table, &iter);
|
hash_open(region_table, &iter);
|
||||||
while((region = hash_next(region_table, &iter)) != NULL)
|
while ((region = hash_next(region_table, &iter)) != NULL)
|
||||||
{
|
{
|
||||||
if (!strcmp(region->name,name))
|
if (!strcmp(region->name,name))
|
||||||
return region->id;
|
return region->id;
|
||||||
@@ -1273,23 +1315,27 @@ region_id find_region_by_name(const char *name)
|
|||||||
return B_NAME_NOT_FOUND;
|
return B_NAME_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dump_region_list(int argc, char **argv)
|
|
||||||
|
static int
|
||||||
|
dump_region_list(int argc, char **argv)
|
||||||
{
|
{
|
||||||
vm_region *region;
|
vm_region *region;
|
||||||
struct hash_iterator iter;
|
struct hash_iterator iter;
|
||||||
|
|
||||||
dprintf("addr\tid\t%32s\tbase\t\tsize\tlock\twiring\n", "name");
|
dprintf("addr\t id base\t\tsize\t\tprotect\tlock\tname\n");
|
||||||
|
|
||||||
hash_open(region_table, &iter);
|
hash_open(region_table, &iter);
|
||||||
while((region = hash_next(region_table, &iter)) != NULL) {
|
while ((region = hash_next(region_table, &iter)) != NULL) {
|
||||||
dprintf("%p\t0x%lx\t%32s\t0x%lx\t\t0x%lx\t%d\t%d\n",
|
dprintf("%p %5lx %p\t%p\t%d\t%d\t%s\n", region, region->id, (void *)region->base,
|
||||||
region, region->id, region->name, region->base, region->size, region->lock, region->wiring);
|
(void *)region->size, region->lock, region->wiring, region->name);
|
||||||
}
|
}
|
||||||
hash_close(region_table, &iter, false);
|
hash_close(region_table, &iter, false);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _dump_aspace(vm_address_space *aspace)
|
|
||||||
|
static void
|
||||||
|
_dump_aspace(vm_address_space *aspace)
|
||||||
{
|
{
|
||||||
vm_region *region;
|
vm_region *region;
|
||||||
|
|
||||||
@@ -1306,7 +1352,7 @@ static void _dump_aspace(vm_address_space *aspace)
|
|||||||
dprintf("virtual_map.sem: 0x%lx\n", aspace->virtual_map.sem);
|
dprintf("virtual_map.sem: 0x%lx\n", aspace->virtual_map.sem);
|
||||||
dprintf("virtual_map.region_hint: %p\n", aspace->virtual_map.region_hint);
|
dprintf("virtual_map.region_hint: %p\n", aspace->virtual_map.region_hint);
|
||||||
dprintf("virtual_map.region_list:\n");
|
dprintf("virtual_map.region_list:\n");
|
||||||
for(region = aspace->virtual_map.region_list; region != NULL; region = region->aspace_next) {
|
for (region = aspace->virtual_map.region_list; region != NULL; region = region->aspace_next) {
|
||||||
dprintf(" region 0x%lx: ", region->id);
|
dprintf(" region 0x%lx: ", region->id);
|
||||||
dprintf("base_addr = 0x%lx ", region->base);
|
dprintf("base_addr = 0x%lx ", region->base);
|
||||||
dprintf("size = 0x%lx ", region->size);
|
dprintf("size = 0x%lx ", region->size);
|
||||||
@@ -1315,23 +1361,25 @@ static void _dump_aspace(vm_address_space *aspace)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dump_aspace(int argc, char **argv)
|
|
||||||
|
static int
|
||||||
|
dump_aspace(int argc, char **argv)
|
||||||
{
|
{
|
||||||
// int i;
|
// int i;
|
||||||
vm_address_space *aspace;
|
vm_address_space *aspace;
|
||||||
|
|
||||||
if(argc < 2) {
|
if (argc < 2) {
|
||||||
dprintf("aspace: not enough arguments\n");
|
dprintf("aspace: not enough arguments\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the argument looks like a hex number, treat it as such
|
// if the argument looks like a hex number, treat it as such
|
||||||
if(strlen(argv[1]) > 2 && argv[1][0] == '0' && argv[1][1] == 'x') {
|
if (strlen(argv[1]) > 2 && argv[1][0] == '0' && argv[1][1] == 'x') {
|
||||||
unsigned long num = atoul(argv[1]);
|
unsigned long num = atoul(argv[1]);
|
||||||
aspace_id id = num;
|
aspace_id id = num;
|
||||||
|
|
||||||
aspace = hash_lookup(aspace_table, &id);
|
aspace = hash_lookup(aspace_table, &id);
|
||||||
if(aspace == NULL) {
|
if (aspace == NULL) {
|
||||||
dprintf("invalid aspace id\n");
|
dprintf("invalid aspace id\n");
|
||||||
} else {
|
} else {
|
||||||
_dump_aspace(aspace);
|
_dump_aspace(aspace);
|
||||||
@@ -1342,7 +1390,7 @@ static int dump_aspace(int argc, char **argv)
|
|||||||
struct hash_iterator iter;
|
struct hash_iterator iter;
|
||||||
|
|
||||||
hash_open(aspace_table, &iter);
|
hash_open(aspace_table, &iter);
|
||||||
while((aspace = hash_next(aspace_table, &iter)) != NULL) {
|
while ((aspace = hash_next(aspace_table, &iter)) != NULL) {
|
||||||
if(aspace->name != NULL && strcmp(argv[1], aspace->name) == 0) {
|
if(aspace->name != NULL && strcmp(argv[1], aspace->name) == 0) {
|
||||||
_dump_aspace(aspace);
|
_dump_aspace(aspace);
|
||||||
}
|
}
|
||||||
@@ -1351,7 +1399,9 @@ static int dump_aspace(int argc, char **argv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dump_aspace_list(int argc, char **argv)
|
|
||||||
|
static int
|
||||||
|
dump_aspace_list(int argc, char **argv)
|
||||||
{
|
{
|
||||||
vm_address_space *as;
|
vm_address_space *as;
|
||||||
struct hash_iterator iter;
|
struct hash_iterator iter;
|
||||||
@@ -1359,7 +1409,7 @@ static int dump_aspace_list(int argc, char **argv)
|
|||||||
dprintf("addr\tid\t%32s\tbase\t\tsize\n", "name");
|
dprintf("addr\tid\t%32s\tbase\t\tsize\n", "name");
|
||||||
|
|
||||||
hash_open(aspace_table, &iter);
|
hash_open(aspace_table, &iter);
|
||||||
while((as = hash_next(aspace_table, &iter)) != NULL) {
|
while ((as = hash_next(aspace_table, &iter)) != NULL) {
|
||||||
dprintf("%p\t0x%lx\t%32s\t0x%lx\t\t0x%lx\n",
|
dprintf("%p\t0x%lx\t%32s\t0x%lx\t\t0x%lx\n",
|
||||||
as, as->id, as->name, as->virtual_map.base, as->virtual_map.size);
|
as, as->id, as->name, as->virtual_map.base, as->virtual_map.size);
|
||||||
}
|
}
|
||||||
@@ -1367,7 +1417,9 @@ static int dump_aspace_list(int argc, char **argv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
vm_address_space *vm_get_kernel_aspace(void)
|
|
||||||
|
vm_address_space *
|
||||||
|
vm_get_kernel_aspace(void)
|
||||||
{
|
{
|
||||||
/* we can treat this one a little differently since it can't be deleted */
|
/* we can treat this one a little differently since it can't be deleted */
|
||||||
acquire_sem_etc(aspace_hash_sem, READ_COUNT, 0, 0);
|
acquire_sem_etc(aspace_hash_sem, READ_COUNT, 0, 0);
|
||||||
@@ -1376,47 +1428,55 @@ vm_address_space *vm_get_kernel_aspace(void)
|
|||||||
return kernel_aspace;
|
return kernel_aspace;
|
||||||
}
|
}
|
||||||
|
|
||||||
aspace_id vm_get_kernel_aspace_id(void)
|
|
||||||
|
aspace_id
|
||||||
|
vm_get_kernel_aspace_id(void)
|
||||||
{
|
{
|
||||||
return kernel_aspace->id;
|
return kernel_aspace->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
vm_address_space *vm_get_current_user_aspace(void)
|
|
||||||
|
vm_address_space *
|
||||||
|
vm_get_current_user_aspace(void)
|
||||||
{
|
{
|
||||||
return vm_get_aspace_by_id(vm_get_current_user_aspace_id());
|
return vm_get_aspace_by_id(vm_get_current_user_aspace_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
aspace_id vm_get_current_user_aspace_id(void)
|
|
||||||
|
aspace_id
|
||||||
|
vm_get_current_user_aspace_id(void)
|
||||||
{
|
{
|
||||||
struct thread *t = thread_get_current_thread();
|
struct thread *t = thread_get_current_thread();
|
||||||
|
|
||||||
if(t)
|
if (t)
|
||||||
return t->team->_aspace_id;
|
return t->team->_aspace_id;
|
||||||
else
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vm_put_aspace(vm_address_space *aspace)
|
|
||||||
|
void
|
||||||
|
vm_put_aspace(vm_address_space *aspace)
|
||||||
{
|
{
|
||||||
// vm_region *region;
|
// vm_region *region;
|
||||||
bool removeit = false;
|
bool removeit = false;
|
||||||
|
|
||||||
acquire_sem_etc(aspace_hash_sem, WRITE_COUNT, 0, 0);
|
acquire_sem_etc(aspace_hash_sem, WRITE_COUNT, 0, 0);
|
||||||
if(atomic_add(&aspace->ref_count, -1) == 1) {
|
if (atomic_add(&aspace->ref_count, -1) == 1) {
|
||||||
hash_remove(aspace_table, aspace);
|
hash_remove(aspace_table, aspace);
|
||||||
removeit = true;
|
removeit = true;
|
||||||
}
|
}
|
||||||
release_sem_etc(aspace_hash_sem, WRITE_COUNT, 0);
|
release_sem_etc(aspace_hash_sem, WRITE_COUNT, 0);
|
||||||
|
|
||||||
if(!removeit)
|
if (!removeit)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
TRACE(("vm_put_aspace: reached zero ref, deleting aspace\n"));
|
TRACE(("vm_put_aspace: reached zero ref, deleting aspace\n"));
|
||||||
|
|
||||||
if(aspace == kernel_aspace)
|
if (aspace == kernel_aspace)
|
||||||
panic("vm_put_aspace: tried to delete the kernel aspace!\n");
|
panic("vm_put_aspace: tried to delete the kernel aspace!\n");
|
||||||
|
|
||||||
if(aspace->virtual_map.region_list)
|
if (aspace->virtual_map.region_list)
|
||||||
panic("vm_put_aspace: aspace at %p has zero ref count, but region list isn't empty!\n", aspace);
|
panic("vm_put_aspace: aspace at %p has zero ref count, but region list isn't empty!\n", aspace);
|
||||||
|
|
||||||
(*aspace->translation_map.ops->destroy)(&aspace->translation_map);
|
(*aspace->translation_map.ops->destroy)(&aspace->translation_map);
|
||||||
@@ -1428,20 +1488,22 @@ void vm_put_aspace(vm_address_space *aspace)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
aspace_id vm_create_aspace(const char *name, addr_t base, addr_t size, bool kernel)
|
|
||||||
|
aspace_id
|
||||||
|
vm_create_aspace(const char *name, addr_t base, addr_t size, bool kernel)
|
||||||
{
|
{
|
||||||
vm_address_space *aspace;
|
vm_address_space *aspace;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
|
||||||
aspace = (vm_address_space *)malloc(sizeof(vm_address_space));
|
aspace = (vm_address_space *)malloc(sizeof(vm_address_space));
|
||||||
if(aspace == NULL)
|
if (aspace == NULL)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
|
||||||
TRACE(("vm_create_aspace: %s: %lx bytes starting at 0x%lx => %p\n", name, size, base, aspace));
|
TRACE(("vm_create_aspace: %s: %lx bytes starting at 0x%lx => %p\n", name, size, base, aspace));
|
||||||
|
|
||||||
aspace->name = (char *)malloc(strlen(name) + 1);
|
aspace->name = (char *)malloc(strlen(name) + 1);
|
||||||
if(aspace->name == NULL ) {
|
if (aspace->name == NULL ) {
|
||||||
free(aspace);
|
free(aspace);
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
}
|
}
|
||||||
@@ -1459,7 +1521,7 @@ aspace_id vm_create_aspace(const char *name, addr_t base, addr_t size, bool kern
|
|||||||
|
|
||||||
// initialize the corresponding translation map
|
// initialize the corresponding translation map
|
||||||
err = vm_translation_map_create(&aspace->translation_map, kernel);
|
err = vm_translation_map_create(&aspace->translation_map, kernel);
|
||||||
if(err < 0) {
|
if (err < 0) {
|
||||||
free(aspace->name);
|
free(aspace->name);
|
||||||
free(aspace);
|
free(aspace);
|
||||||
return err;
|
return err;
|
||||||
@@ -1491,7 +1553,7 @@ vm_delete_aspace(aspace_id aid)
|
|||||||
vm_address_space *aspace;
|
vm_address_space *aspace;
|
||||||
|
|
||||||
aspace = vm_get_aspace_by_id(aid);
|
aspace = vm_get_aspace_by_id(aid);
|
||||||
if(aspace == NULL)
|
if (aspace == NULL)
|
||||||
return ERR_VM_INVALID_ASPACE;
|
return ERR_VM_INVALID_ASPACE;
|
||||||
|
|
||||||
TRACE(("vm_delete_aspace: called on aspace 0x%lx\n", aid));
|
TRACE(("vm_delete_aspace: called on aspace 0x%lx\n", aid));
|
||||||
@@ -1499,7 +1561,7 @@ vm_delete_aspace(aspace_id aid)
|
|||||||
// put this aspace in the deletion state
|
// put this aspace in the deletion state
|
||||||
// this guarantees that no one else will add regions to the list
|
// this guarantees that no one else will add regions to the list
|
||||||
acquire_sem_etc(aspace->virtual_map.sem, WRITE_COUNT, 0, 0);
|
acquire_sem_etc(aspace->virtual_map.sem, WRITE_COUNT, 0, 0);
|
||||||
if(aspace->state == VM_ASPACE_STATE_DELETION) {
|
if (aspace->state == VM_ASPACE_STATE_DELETION) {
|
||||||
// abort, someone else is already deleting this aspace
|
// abort, someone else is already deleting this aspace
|
||||||
release_sem_etc(aspace->virtual_map.sem, WRITE_COUNT, 0);
|
release_sem_etc(aspace->virtual_map.sem, WRITE_COUNT, 0);
|
||||||
vm_put_aspace(aspace);
|
vm_put_aspace(aspace);
|
||||||
@@ -1509,7 +1571,7 @@ vm_delete_aspace(aspace_id aid)
|
|||||||
|
|
||||||
// delete all the regions in this aspace
|
// delete all the regions in this aspace
|
||||||
region = aspace->virtual_map.region_list;
|
region = aspace->virtual_map.region_list;
|
||||||
while(region) {
|
while (region) {
|
||||||
next = region->aspace_next;
|
next = region->aspace_next;
|
||||||
// decrement the ref on this region, may actually push the ref < 0, but that's okay
|
// decrement the ref on this region, may actually push the ref < 0, but that's okay
|
||||||
_vm_put_region(region, true);
|
_vm_put_region(region, true);
|
||||||
@@ -1530,6 +1592,7 @@ vm_delete_aspace(aspace_id aid)
|
|||||||
int
|
int
|
||||||
vm_resize_region(aspace_id aid, region_id rid, size_t newSize)
|
vm_resize_region(aspace_id aid, region_id rid, size_t newSize)
|
||||||
{
|
{
|
||||||
|
// ToDo: this is broken!
|
||||||
vm_cache_ref *myCacheRef;
|
vm_cache_ref *myCacheRef;
|
||||||
vm_region *myRegion,*current;
|
vm_region *myRegion,*current;
|
||||||
size_t oldSize;
|
size_t oldSize;
|
||||||
@@ -1628,13 +1691,13 @@ create_preloaded_image_areas(struct preloaded_image *image)
|
|||||||
memcpy(name, fileName, length);
|
memcpy(name, fileName, length);
|
||||||
strcpy(name + length, "_text");
|
strcpy(name + length, "_text");
|
||||||
address = (void *)ROUNDOWN(image->text_region.start, PAGE_SIZE);
|
address = (void *)ROUNDOWN(image->text_region.start, PAGE_SIZE);
|
||||||
image->text_region.id = vm_create_anonymous_region(vm_get_kernel_aspace_id(), name, &address, REGION_ADDR_EXACT_ADDRESS,
|
image->text_region.id = vm_create_anonymous_region(vm_get_kernel_aspace_id(), name, &address, B_EXACT_KERNEL_ADDRESS,
|
||||||
PAGE_ALIGN(image->text_region.size), REGION_WIRING_WIRED_ALREADY, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
|
PAGE_ALIGN(image->text_region.size), B_ALREADY_WIRED, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
|
||||||
|
|
||||||
strcpy(name + length, "_data");
|
strcpy(name + length, "_data");
|
||||||
address = (void *)ROUNDOWN(image->data_region.start, PAGE_SIZE);
|
address = (void *)ROUNDOWN(image->data_region.start, PAGE_SIZE);
|
||||||
image->data_region.id = vm_create_anonymous_region(vm_get_kernel_aspace_id(), name, &address, REGION_ADDR_EXACT_ADDRESS,
|
image->data_region.id = vm_create_anonymous_region(vm_get_kernel_aspace_id(), name, &address, B_EXACT_KERNEL_ADDRESS,
|
||||||
PAGE_ALIGN(image->data_region.size), REGION_WIRING_WIRED_ALREADY, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
|
PAGE_ALIGN(image->data_region.size), B_ALREADY_WIRED, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1706,8 +1769,8 @@ vm_init(kernel_args *ka)
|
|||||||
// allocate regions to represent stuff that already exists
|
// allocate regions to represent stuff that already exists
|
||||||
|
|
||||||
address = (void *)ROUNDOWN(heap_base, PAGE_SIZE);
|
address = (void *)ROUNDOWN(heap_base, PAGE_SIZE);
|
||||||
vm_create_anonymous_region(vm_get_kernel_aspace_id(), "kernel_heap", &address, REGION_ADDR_EXACT_ADDRESS,
|
vm_create_anonymous_region(vm_get_kernel_aspace_id(), "kernel_heap", &address, B_EXACT_KERNEL_ADDRESS,
|
||||||
HEAP_SIZE, REGION_WIRING_WIRED_ALREADY, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
|
HEAP_SIZE, B_ALREADY_WIRED, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
|
||||||
|
|
||||||
ka->kernel_image.name = "kernel";
|
ka->kernel_image.name = "kernel";
|
||||||
// the lazy boot loader currently doesn't set the kernel's name...
|
// the lazy boot loader currently doesn't set the kernel's name...
|
||||||
@@ -1724,12 +1787,12 @@ vm_init(kernel_args *ka)
|
|||||||
|
|
||||||
sprintf(temp, "idle_thread%d_kstack", i);
|
sprintf(temp, "idle_thread%d_kstack", i);
|
||||||
address = (void *)ka->cpu_kstack[i].start;
|
address = (void *)ka->cpu_kstack[i].start;
|
||||||
vm_create_anonymous_region(vm_get_kernel_aspace_id(), temp, &address, REGION_ADDR_EXACT_ADDRESS,
|
vm_create_anonymous_region(vm_get_kernel_aspace_id(), temp, &address, B_EXACT_KERNEL_ADDRESS,
|
||||||
ka->cpu_kstack[i].size, REGION_WIRING_WIRED_ALREADY, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
|
ka->cpu_kstack[i].size, B_ALREADY_WIRED, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
void *null;
|
void *null;
|
||||||
vm_map_physical_memory(vm_get_kernel_aspace_id(), "bootdir", &null, REGION_ADDR_ANY_ADDRESS,
|
vm_map_physical_memory(vm_get_kernel_aspace_id(), "bootdir", &null, B_ANY_KERNEL_ADDRESS,
|
||||||
ka->bootdir_addr.size, B_KERNEL_READ_AREA, ka->bootdir_addr.start);
|
ka->bootdir_addr.size, B_KERNEL_READ_AREA, ka->bootdir_addr.start);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2387,65 +2450,10 @@ resize_area(area_id area, size_t newSize)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
|
||||||
convertAddressSpec(uint32 *_spec)
|
|
||||||
{
|
|
||||||
switch (*_spec) {
|
|
||||||
case B_ANY_KERNEL_ADDRESS:
|
|
||||||
case B_ANY_ADDRESS:
|
|
||||||
*_spec = REGION_ADDR_ANY_ADDRESS;
|
|
||||||
break;
|
|
||||||
case B_EXACT_KERNEL_ADDRESS:
|
|
||||||
case B_EXACT_ADDRESS:
|
|
||||||
*_spec = REGION_ADDR_EXACT_ADDRESS;
|
|
||||||
break;
|
|
||||||
case B_BASE_ADDRESS:
|
|
||||||
dprintf("create_area: B_BASE_ADDRESS demanded (switch to B_ANY_ADDRESS)!\n");
|
|
||||||
*_spec = REGION_ADDR_ANY_ADDRESS;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
dprintf("create_area: invalid address spec!\n");
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
}
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
|
||||||
convertLockToWiring(uint32 *_lock)
|
|
||||||
{
|
|
||||||
switch (*_lock) {
|
|
||||||
case B_ALREADY_WIRED:
|
|
||||||
*_lock = REGION_WIRING_WIRED_ALREADY;
|
|
||||||
break;
|
|
||||||
case B_LOMEM:
|
|
||||||
dprintf("create_area: asked for B_LOMEM - unsupported (switch to B_FULL_LOCK)!\n");
|
|
||||||
case B_FULL_LOCK:
|
|
||||||
case B_LAZY_LOCK: // ToDo: lazy lock is not supported by the VM yet
|
|
||||||
*_lock = REGION_WIRING_WIRED;
|
|
||||||
break;
|
|
||||||
case B_CONTIGUOUS:
|
|
||||||
*_lock = REGION_WIRING_WIRED_CONTIG;
|
|
||||||
break;
|
|
||||||
case B_NO_LOCK:
|
|
||||||
*_lock = REGION_WIRING_WIRED_CONTIG;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
dprintf("create_area: invalid locking mode!\n");
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
}
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
area_id
|
area_id
|
||||||
map_physical_memory(const char *name, void *physicalAddress, size_t numBytes,
|
map_physical_memory(const char *name, void *physicalAddress, size_t numBytes,
|
||||||
uint32 addressSpec, uint32 protection, void **_virtualAddress)
|
uint32 addressSpec, uint32 protection, void **_virtualAddress)
|
||||||
{
|
{
|
||||||
if (convertAddressSpec(&addressSpec) < B_OK)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
|
|
||||||
if ((protection & B_KERNEL_PROTECTION) == 0)
|
if ((protection & B_KERNEL_PROTECTION) == 0)
|
||||||
protection |= B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA;
|
protection |= B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA;
|
||||||
|
|
||||||
@@ -2466,13 +2474,6 @@ area_id
|
|||||||
create_area_etc(struct team *team, const char *name, void **address, uint32 addressSpec,
|
create_area_etc(struct team *team, const char *name, void **address, uint32 addressSpec,
|
||||||
uint32 size, uint32 lock, uint32 protection)
|
uint32 size, uint32 lock, uint32 protection)
|
||||||
{
|
{
|
||||||
if (convertAddressSpec(&addressSpec) < B_OK)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
|
|
||||||
// create_area() "lock" is vm_create_anonymous_region() "wiring"
|
|
||||||
if (convertLockToWiring(&lock) < B_OK)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
|
|
||||||
return vm_create_anonymous_region(team->_aspace_id, (char *)name, address,
|
return vm_create_anonymous_region(team->_aspace_id, (char *)name, address,
|
||||||
addressSpec, size, lock, protection);
|
addressSpec, size, lock, protection);
|
||||||
}
|
}
|
||||||
@@ -2498,13 +2499,6 @@ create_area(const char *name, void **address, uint32 addressSpec, size_t size, u
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (convertAddressSpec(&addressSpec) < B_OK)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
|
|
||||||
// create_area() "lock" is vm_create_anonymous_region() "wiring"
|
|
||||||
if (convertLockToWiring(&lock) < B_OK)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
|
|
||||||
return vm_create_anonymous_region(areaSpace, (char *)name, address,
|
return vm_create_anonymous_region(areaSpace, (char *)name, address,
|
||||||
addressSpec, size, lock, protection);
|
addressSpec, size, lock, protection);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user