Index: abi/include/ipc/methods.h
===================================================================
--- abi/include/ipc/methods.h	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ abi/include/ipc/methods.h	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -127,5 +127,8 @@
  *
  * on answer, the recipient must set:
- * - ARG1 - dst as_area base adress
+ *
+ * - ARG1 - dst as_area lower bound
+ * - ARG2 - dst as_area base adress pointer
+ *          (filled automatically by the kernel)
  *
  */
@@ -133,7 +136,6 @@
 
 /** Receive as_area over IPC.
- * - ARG1 - destination as_area base address
- * - ARG2 - destination as_area size
- * - ARG3 - user defined argument
+ * - ARG1 - destination as_area size
+ * - ARG2 - user defined argument
  *
  * on answer, the recipient must set:
@@ -141,4 +143,6 @@
  * - ARG1 - source as_area base address
  * - ARG2 - flags that will be used for sharing
+ * - ARG3 - dst as_area lower bound
+ * - ARG4 - dst as_area base address (filled automatically by kernel)
  *
  */
Index: abi/include/syscall.h
===================================================================
--- abi/include/syscall.h	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ abi/include/syscall.h	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -60,5 +60,4 @@
 	SYS_AS_AREA_CHANGE_FLAGS,
 	SYS_AS_AREA_DESTROY,
-	SYS_AS_GET_UNMAPPED_AREA,
 	
 	SYS_PAGE_FIND_MAPPING,
@@ -85,7 +84,9 @@
 	SYS_DEVICE_ASSIGN_DEVNO,
 	SYS_PHYSMEM_MAP,
+	SYS_PHYSMEM_UNMAP,
 	SYS_DMAMEM_MAP,
 	SYS_DMAMEM_UNMAP,
 	SYS_IOSPACE_ENABLE,
+	SYS_IOSPACE_DISABLE,
 	SYS_IRQ_REGISTER,
 	SYS_IRQ_UNREGISTER,
Index: kernel/generic/include/ddi/ddi.h
===================================================================
--- kernel/generic/include/ddi/ddi.h	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ kernel/generic/include/ddi/ddi.h	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -55,11 +55,14 @@
 extern void ddi_parea_register(parea_t *);
 
-extern sysarg_t sys_physmem_map(uintptr_t, uintptr_t, size_t, unsigned int);
+extern sysarg_t sys_physmem_map(uintptr_t, size_t, unsigned int, void *,
+    uintptr_t);
+extern sysarg_t sys_physmem_unmap(uintptr_t);
 
-extern sysarg_t sys_dmamem_map(uintptr_t, size_t, unsigned int, unsigned int,
-    void *);
+extern sysarg_t sys_dmamem_map(size_t, unsigned int, unsigned int, void *,
+    void *, uintptr_t);
 extern sysarg_t sys_dmamem_unmap(uintptr_t, size_t, unsigned int);
 
 extern sysarg_t sys_iospace_enable(ddi_ioarg_t *);
+extern sysarg_t sys_iospace_disable(ddi_ioarg_t *);
 
 /*
Index: kernel/generic/include/mm/as.h
===================================================================
--- kernel/generic/include/mm/as.h	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ kernel/generic/include/mm/as.h	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -242,10 +242,10 @@
 extern int as_page_fault(uintptr_t, pf_access_t, istate_t *);
 
-extern as_area_t *as_area_create(as_t *, unsigned int, size_t, uintptr_t,
-    unsigned int, mem_backend_t *, mem_backend_data_t *);
+extern as_area_t *as_area_create(as_t *, unsigned int, size_t, unsigned int,
+    mem_backend_t *, mem_backend_data_t *, uintptr_t *, uintptr_t);
 extern int as_area_destroy(as_t *, uintptr_t);
 extern int as_area_resize(as_t *, uintptr_t, size_t, unsigned int);
-extern int as_area_share(as_t *, uintptr_t, size_t, as_t *, uintptr_t,
-    unsigned int);
+extern int as_area_share(as_t *, uintptr_t, size_t, as_t *, unsigned int,
+    uintptr_t *, uintptr_t);
 extern int as_area_change_flags(as_t *, unsigned int, uintptr_t);
 
@@ -284,9 +284,8 @@
 
 /* Address space area related syscalls. */
-extern sysarg_t sys_as_area_create(uintptr_t, size_t, unsigned int);
+extern sysarg_t sys_as_area_create(uintptr_t, size_t, unsigned int, uintptr_t);
 extern sysarg_t sys_as_area_resize(uintptr_t, size_t, unsigned int);
 extern sysarg_t sys_as_area_change_flags(uintptr_t, unsigned int);
 extern sysarg_t sys_as_area_destroy(uintptr_t);
-extern sysarg_t sys_as_get_unmapped_area(uintptr_t, size_t);
 
 /* Introspection functions. */
Index: kernel/generic/src/ddi/ddi.c
===================================================================
--- kernel/generic/src/ddi/ddi.c	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ kernel/generic/src/ddi/ddi.c	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -90,11 +90,12 @@
  *
  * @param phys  Physical address of the starting frame.
- * @param virt  Virtual address of the starting page.
  * @param pages Number of pages to map.
  * @param flags Address space area flags for the mapping.
+ * @param virt  Virtual address of the starting page.
+ * @param bound Lowest virtual address bound.
  *
  * @return EOK on success.
  * @return EPERM if the caller lacks capabilities to use this syscall.
- * @return EBADMEM if phys or virt is not page aligned.
+ * @return EBADMEM if phys is not page aligned.
  * @return ENOENT if there is no task matching the specified ID or
  *         the physical address space is not enabled for mapping.
@@ -102,13 +103,10 @@
  *
  */
-NO_TRACE static int ddi_physmem_map(uintptr_t phys, uintptr_t virt, size_t pages,
-    unsigned int flags)
+NO_TRACE static int physmem_map(uintptr_t phys, size_t pages,
+    unsigned int flags, uintptr_t *virt, uintptr_t bound)
 {
 	ASSERT(TASK);
 	
 	if ((phys % FRAME_SIZE) != 0)
-		return EBADMEM;
-	
-	if ((virt % PAGE_SIZE) != 0)
 		return EBADMEM;
 	
@@ -185,6 +183,6 @@
 	
 map:
-	if (!as_area_create(TASK->as, flags, FRAMES2SIZE(pages), virt,
-	    AS_AREA_ATTR_NONE, &phys_backend, &backend_data)) {
+	if (!as_area_create(TASK->as, flags, FRAMES2SIZE(pages),
+	    AS_AREA_ATTR_NONE, &phys_backend, &backend_data, virt, bound)) {
 		/*
 		 * The address space area was not created.
@@ -210,4 +208,44 @@
 }
 
+NO_TRACE static int physmem_unmap(uintptr_t virt)
+{
+	// TODO: implement unmap
+	return EOK;
+}
+
+/** Wrapper for SYS_PHYSMEM_MAP syscall.
+ *
+ * @param phys     Physical base address to map
+ * @param pages    Number of pages
+ * @param flags    Flags of newly mapped pages
+ * @param virt_ptr Destination virtual address
+ * @param bound    Lowest virtual address bound.
+ *
+ * @return 0 on success, otherwise it returns error code found in errno.h
+ *
+ */
+sysarg_t sys_physmem_map(uintptr_t phys, size_t pages, unsigned int flags,
+    void *virt_ptr, uintptr_t bound)
+{
+	uintptr_t virt = (uintptr_t) -1;
+	int rc = physmem_map(ALIGN_DOWN(phys, FRAME_SIZE), pages, flags,
+	    &virt, bound);
+	if (rc != EOK)
+		return rc;
+	
+	rc = copy_to_uspace(virt_ptr, &virt, sizeof(virt));
+	if (rc != EOK) {
+		physmem_unmap((uintptr_t) virt);
+		return rc;
+	}
+	
+	return EOK;
+}
+
+sysarg_t sys_physmem_unmap(uintptr_t virt)
+{
+	return physmem_unmap(virt);
+}
+
 /** Enable range of I/O space for task.
  *
@@ -220,6 +258,5 @@
  *
  */
-NO_TRACE static int ddi_iospace_enable(task_id_t id, uintptr_t ioaddr,
-    size_t size)
+NO_TRACE static int iospace_enable(task_id_t id, uintptr_t ioaddr, size_t size)
 {
 	/*
@@ -246,28 +283,8 @@
 	/* Lock the task and release the lock protecting tasks_btree. */
 	irq_spinlock_exchange(&tasks_lock, &task->lock);
-	
 	int rc = ddi_iospace_enable_arch(task, ioaddr, size);
-	
 	irq_spinlock_unlock(&task->lock, true);
 	
 	return rc;
-}
-
-/** Wrapper for SYS_PHYSMEM_MAP syscall.
- *
- * @param phys  Physical base address to map
- * @param virt  Destination virtual address
- * @param pages Number of pages
- * @param flags Flags of newly mapped pages
- *
- * @return 0 on success, otherwise it returns error code found in errno.h
- *
- */
-sysarg_t sys_physmem_map(uintptr_t phys, uintptr_t virt,
-    size_t pages, unsigned int flags)
-{
-	return (sysarg_t)
-	    ddi_physmem_map(ALIGN_DOWN(phys, FRAME_SIZE),
-	    ALIGN_DOWN(virt, PAGE_SIZE), pages, flags);
 }
 
@@ -286,68 +303,109 @@
 		return (sysarg_t) rc;
 	
-	return (sysarg_t) ddi_iospace_enable((task_id_t) arg.task_id,
+	return (sysarg_t) iospace_enable((task_id_t) arg.task_id,
 	    (uintptr_t) arg.ioaddr, (size_t) arg.size);
 }
 
-NO_TRACE static int dmamem_map(uintptr_t virt, size_t size,
-    unsigned int map_flags, unsigned int flags, void **phys)
+sysarg_t sys_iospace_disable(ddi_ioarg_t *uspace_io_arg)
+{
+	// TODO: implement
+	return ENOTSUP;
+}
+
+NO_TRACE static int dmamem_map(uintptr_t virt, size_t size, unsigned int map_flags,
+    unsigned int flags, void **phys)
 {
 	ASSERT(TASK);
 	
+	// TODO: implement locking of non-anonymous mapping
+	return page_find_mapping(virt, phys);
+}
+
+NO_TRACE static int dmamem_map_anonymous(size_t size, unsigned int map_flags,
+    unsigned int flags, void **phys, uintptr_t *virt, uintptr_t bound)
+{
+	ASSERT(TASK);
+	
+	size_t pages = SIZE2FRAMES(size);
+	uint8_t order;
+	
+	/* We need the 2^order >= pages */
+	if (pages == 1)
+		order = 0;
+	else
+		order = fnzb(pages - 1) + 1;
+	
+	*phys = frame_alloc_noreserve(order, 0);
+	if (*phys == NULL)
+		return ENOMEM;
+	
+	mem_backend_data_t backend_data;
+	backend_data.base = (uintptr_t) *phys;
+	backend_data.frames = pages;
+	
+	if (!as_area_create(TASK->as, map_flags, size,
+	    AS_AREA_ATTR_NONE, &phys_backend, &backend_data, virt, bound)) {
+		frame_free_noreserve((uintptr_t) *phys);
+		return ENOMEM;
+	}
+	
+	return EOK;
+}
+
+NO_TRACE static int dmamem_unmap(uintptr_t virt, size_t size)
+{
+	// TODO: implement unlocking & unmap
+	return EOK;
+}
+
+NO_TRACE static int dmamem_unmap_anonymous(uintptr_t virt)
+{
+	// TODO: implement unlocking & unmap
+	return EOK;
+}
+
+sysarg_t sys_dmamem_map(size_t size, unsigned int map_flags, unsigned int flags,
+    void *phys_ptr, void *virt_ptr, uintptr_t bound)
+{
 	if ((flags & DMAMEM_FLAGS_ANONYMOUS) == 0) {
-		// TODO: implement locking of non-anonymous mapping
-		return page_find_mapping(virt, phys);
+		/*
+		 * Non-anonymous DMA mapping
+		 */
+		
+		void *phys;
+		int rc = dmamem_map((uintptr_t) virt_ptr, size, map_flags,
+		    flags, &phys);
+		
+		if (rc != EOK)
+			return rc;
+		
+		rc = copy_to_uspace(phys_ptr, &phys, sizeof(phys));
+		if (rc != EOK) {
+			dmamem_unmap((uintptr_t) virt_ptr, size);
+			return rc;
+		}
 	} else {
-		// TODO: implement locking
-		
-		if ((virt % PAGE_SIZE) != 0)
-			return EBADMEM;
-		
-		size_t pages = SIZE2FRAMES(size);
-		uint8_t order;
-		
-		/* We need the 2^order >= pages */
-		if (pages == 1)
-			order = 0;
-		else
-			order = fnzb(pages - 1) + 1;
-		
-		*phys = frame_alloc_noreserve(order, 0);
-		if (*phys == NULL)
-			return ENOMEM;
-		
-		mem_backend_data_t backend_data;
-		backend_data.base = (uintptr_t) *phys;
-		backend_data.frames = pages;
-		
-		if (!as_area_create(TASK->as, map_flags, size, virt,
-		    AS_AREA_ATTR_NONE, &phys_backend, &backend_data)) {
-			frame_free_noreserve((uintptr_t) *phys);
-			return ENOMEM;
+		/*
+		 * Anonymous DMA mapping
+		 */
+		
+		void *phys;
+		uintptr_t virt = (uintptr_t) -1;
+		int rc = dmamem_map_anonymous(size, map_flags, flags,
+		    &phys, &virt, bound);
+		if (rc != EOK)
+			return rc;
+		
+		rc = copy_to_uspace(phys_ptr, &phys, sizeof(phys));
+		if (rc != EOK) {
+			dmamem_unmap_anonymous((uintptr_t) virt);
+			return rc;
 		}
 		
-		return EOK;
-	}
-}
-
-NO_TRACE static int dmamem_unmap(uintptr_t virt, size_t size,
-    unsigned int flags)
-{
-	// TODO: implement unlocking & unmap
-	return EOK;
-}
-
-sysarg_t sys_dmamem_map(uintptr_t virt, size_t size, unsigned int map_flags,
-    unsigned int flags, void *phys_ptr)
-{
-	void *phys;
-	int rc = dmamem_map(virt, size, map_flags, flags, &phys);
-	if (rc != EOK)
-		return rc;
-	
-	rc = copy_to_uspace(phys_ptr, &phys, sizeof(phys));
-	if (rc != EOK) {
-		dmamem_unmap(virt, size, flags);
-		return rc;
+		rc = copy_to_uspace(virt_ptr, &virt, sizeof(virt));
+		if (rc != EOK) {
+			dmamem_unmap_anonymous((uintptr_t) virt);
+			return rc;
+		}
 	}
 	
@@ -357,5 +415,8 @@
 sysarg_t sys_dmamem_unmap(uintptr_t virt, size_t size, unsigned int flags)
 {
-	return dmamem_unmap(virt, size, flags);
+	if ((flags & DMAMEM_FLAGS_ANONYMOUS) == 0)
+		return dmamem_unmap(virt, size);
+	else
+		return dmamem_unmap_anonymous(virt);
 }
 
Index: kernel/generic/src/ipc/sysipc.c
===================================================================
--- kernel/generic/src/ipc/sysipc.c	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ kernel/generic/src/ipc/sysipc.c	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -271,7 +271,13 @@
 			irq_spinlock_unlock(&answer->sender->lock, true);
 			
+			uintptr_t dst_base = (uintptr_t) -1;
 			int rc = as_area_share(as, IPC_GET_ARG1(*olddata),
-			    IPC_GET_ARG2(*olddata), AS,
-			    IPC_GET_ARG1(answer->data), IPC_GET_ARG3(*olddata));
+			    IPC_GET_ARG2(*olddata), AS, IPC_GET_ARG3(*olddata),
+			    &dst_base, IPC_GET_ARG1(answer->data));
+			
+			if (rc == EOK)
+				rc = copy_to_uspace((void *) IPC_GET_ARG2(answer->data),
+				    &dst_base, sizeof(dst_base));
+			
 			IPC_SET_RETVAL(answer->data, rc);
 			return rc;
@@ -283,7 +289,9 @@
 			irq_spinlock_unlock(&answer->sender->lock, true);
 			
+			uintptr_t dst_base = (uintptr_t) -1;
 			int rc = as_area_share(AS, IPC_GET_ARG1(answer->data),
-			    IPC_GET_ARG2(*olddata), as, IPC_GET_ARG1(*olddata),
-			    IPC_GET_ARG2(answer->data));
+			    IPC_GET_ARG1(*olddata), as, IPC_GET_ARG2(answer->data),
+			    &dst_base, IPC_GET_ARG3(answer->data));
+			IPC_SET_ARG4(answer->data, dst_base);
 			IPC_SET_RETVAL(answer->data, rc);
 		}
Index: kernel/generic/src/lib/elf.c
===================================================================
--- kernel/generic/src/lib/elf.c	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ kernel/generic/src/lib/elf.c	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -226,6 +226,6 @@
 	size_t mem_sz = entry->p_memsz + (entry->p_vaddr - base);
 	
-	as_area_t *area = as_area_create(as, flags, mem_sz, base,
-	    AS_AREA_ATTR_NONE, &elf_backend, &backend_data);
+	as_area_t *area = as_area_create(as, flags, mem_sz,
+	    AS_AREA_ATTR_NONE, &elf_backend, &backend_data, &base, 0);
 	if (!area)
 		return EE_MEMORY;
Index: kernel/generic/src/mm/as.c
===================================================================
--- kernel/generic/src/mm/as.c	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ kernel/generic/src/mm/as.c	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -387,4 +387,71 @@
 }
 
+/** Return pointer to unmapped address space area
+ *
+ * The address space must be already locked when calling
+ * this function.
+ *
+ * @param as    Address space.
+ * @param bound Lowest address bound.
+ * @param size  Requested size of the allocation.
+ *
+ * @return Address of the beginning of unmapped address space area.
+ * @return -1 if no suitable address space area was found.
+ *
+ */
+NO_TRACE static uintptr_t as_get_unmapped_area(as_t *as, uintptr_t bound,
+    size_t size)
+{
+	ASSERT(mutex_locked(&as->lock));
+	
+	if (size == 0)
+		return (uintptr_t) -1;
+	
+	/*
+	 * Make sure we allocate from page-aligned
+	 * address. Check for possible overflow in
+	 * each step.
+	 */
+	
+	size_t pages = SIZE2FRAMES(size);
+	
+	/*
+	 * Find the lowest unmapped address aligned on the size
+	 * boundary, not smaller than bound and of the required size.
+	 */
+	
+	/* First check the bound address itself */
+	uintptr_t addr = ALIGN_UP(bound, PAGE_SIZE);
+	if ((addr >= bound) &&
+	    (check_area_conflicts(as, addr, pages, NULL)))
+		return addr;
+	
+	/* Eventually check the addresses behind each area */
+	list_foreach(as->as_area_btree.leaf_list, cur) {
+		btree_node_t *node =
+		    list_get_instance(cur, btree_node_t, leaf_link);
+		
+		for (btree_key_t i = 0; i < node->keys; i++) {
+			as_area_t *area = (as_area_t *) node->value[i];
+			
+			mutex_lock(&area->lock);
+			
+			addr =
+			    ALIGN_UP(area->base + P2SZ(area->pages), PAGE_SIZE);
+			bool avail =
+			    ((addr >= bound) && (addr >= area->base) &&
+			    (check_area_conflicts(as, addr, pages, area)));
+			
+			mutex_unlock(&area->lock);
+			
+			if (avail)
+				return addr;
+		}
+	}
+	
+	/* No suitable address space area found */
+	return (uintptr_t) -1;
+}
+
 /** Create address space area of common attributes.
  *
@@ -394,8 +461,11 @@
  * @param flags        Flags of the area memory.
  * @param size         Size of area.
- * @param base         Base address of area.
  * @param attrs        Attributes of the area.
  * @param backend      Address space area backend. NULL if no backend is used.
  * @param backend_data NULL or a pointer to an array holding two void *.
+ * @param base         Starting virtual address of the area.
+ *                     If set to -1, a suitable mappable area is found.
+ * @param bound        Lowest address bound if base is set to -1.
+ *                     Otherwise ignored.
  *
  * @return Address space area on success or NULL on failure.
@@ -403,8 +473,8 @@
  */
 as_area_t *as_area_create(as_t *as, unsigned int flags, size_t size,
-    uintptr_t base, unsigned int attrs, mem_backend_t *backend,
-    mem_backend_data_t *backend_data)
-{
-	if ((base % PAGE_SIZE) != 0)
+    unsigned int attrs, mem_backend_t *backend,
+    mem_backend_data_t *backend_data, uintptr_t *base, uintptr_t bound)
+{
+	if ((*base != (uintptr_t) -1) && ((*base % PAGE_SIZE) != 0))
 		return NULL;
 	
@@ -420,5 +490,13 @@
 	mutex_lock(&as->lock);
 	
-	if (!check_area_conflicts(as, base, pages, NULL)) {
+	if (*base == (uintptr_t) -1) {
+		*base = as_get_unmapped_area(as, bound, size);
+		if (*base == (uintptr_t) -1) {
+			mutex_unlock(&as->lock);
+			return NULL;
+		}
+	}
+	
+	if (!check_area_conflicts(as, *base, pages, NULL)) {
 		mutex_unlock(&as->lock);
 		return NULL;
@@ -434,5 +512,5 @@
 	area->pages = pages;
 	area->resident = 0;
-	area->base = base;
+	area->base = *base;
 	area->sh_info = NULL;
 	area->backend = backend;
@@ -452,5 +530,6 @@
 	
 	btree_create(&area->used_space);
-	btree_insert(&as->as_area_btree, base, (void *) area, NULL);
+	btree_insert(&as->as_area_btree, *base, (void *) area,
+	    NULL);
 	
 	mutex_unlock(&as->lock);
@@ -860,6 +939,9 @@
  * @param acc_size       Expected size of the source area.
  * @param dst_as         Pointer to destination address space.
- * @param dst_base       Target base address.
  * @param dst_flags_mask Destination address space area flags mask.
+ * @param dst_base       Target base address. If set to -1,
+ *                       a suitable mappable area is found.
+ * @param bound          Lowest address bound if dst_base is set to -1.
+ *                       Otherwise ignored.
  *
  * @return Zero on success.
@@ -873,5 +955,6 @@
  */
 int as_area_share(as_t *src_as, uintptr_t src_base, size_t acc_size,
-    as_t *dst_as, uintptr_t dst_base, unsigned int dst_flags_mask)
+    as_t *dst_as, unsigned int dst_flags_mask, uintptr_t *dst_base,
+    uintptr_t bound)
 {
 	mutex_lock(&src_as->lock);
@@ -945,6 +1028,7 @@
 	 * to support sharing in less privileged mode.
 	 */
-	as_area_t *dst_area = as_area_create(dst_as, dst_flags_mask, src_size,
-	    dst_base, AS_AREA_ATTR_PARTIAL, src_backend, &src_backend_data);
+	as_area_t *dst_area = as_area_create(dst_as, dst_flags_mask,
+	    src_size, AS_AREA_ATTR_PARTIAL, src_backend,
+	    &src_backend_data, dst_base, bound);
 	if (!dst_area) {
 		/*
@@ -1955,15 +2039,16 @@
  */
 
-/** Wrapper for as_area_create(). */
-sysarg_t sys_as_area_create(uintptr_t address, size_t size, unsigned int flags)
-{
-	if (as_area_create(AS, flags | AS_AREA_CACHEABLE, size, address,
-	    AS_AREA_ATTR_NONE, &anon_backend, NULL))
-		return (sysarg_t) address;
-	else
+sysarg_t sys_as_area_create(uintptr_t base, size_t size, unsigned int flags,
+    uintptr_t bound)
+{
+	uintptr_t virt = base;
+	as_area_t *area = as_area_create(AS, flags | AS_AREA_CACHEABLE, size,
+	    AS_AREA_ATTR_NONE, &anon_backend, NULL, &virt, bound);
+	if (area == NULL)
 		return (sysarg_t) -1;
-}
-
-/** Wrapper for as_area_resize(). */
+	
+	return (sysarg_t) virt;
+}
+
 sysarg_t sys_as_area_resize(uintptr_t address, size_t size, unsigned int flags)
 {
@@ -1971,5 +2056,4 @@
 }
 
-/** Wrapper for as_area_change_flags(). */
 sysarg_t sys_as_area_change_flags(uintptr_t address, unsigned int flags)
 {
@@ -1977,75 +2061,7 @@
 }
 
-/** Wrapper for as_area_destroy(). */
 sysarg_t sys_as_area_destroy(uintptr_t address)
 {
 	return (sysarg_t) as_area_destroy(AS, address);
-}
-
-/** Return pointer to unmapped address space area
- *
- * @param base Lowest address bound.
- * @param size Requested size of the allocation.
- *
- * @return Pointer to the beginning of unmapped address space area.
- *
- */
-sysarg_t sys_as_get_unmapped_area(uintptr_t base, size_t size)
-{
-	if (size == 0)
-		return 0;
-	
-	/*
-	 * Make sure we allocate from page-aligned
-	 * address. Check for possible overflow in
-	 * each step.
-	 */
-	
-	size_t pages = SIZE2FRAMES(size);
-	uintptr_t ret = 0;
-	
-	/*
-	 * Find the lowest unmapped address aligned on the sz
-	 * boundary, not smaller than base and of the required size.
-	 */
-	
-	mutex_lock(&AS->lock);
-	
-	/* First check the base address itself */
-	uintptr_t addr = ALIGN_UP(base, PAGE_SIZE);
-	if ((addr >= base) &&
-	    (check_area_conflicts(AS, addr, pages, NULL)))
-		ret = addr;
-	
-	/* Eventually check the addresses behind each area */
-	list_foreach(AS->as_area_btree.leaf_list, cur) {
-		if (ret != 0)
-			break;
-
-		btree_node_t *node =
-		    list_get_instance(cur, btree_node_t, leaf_link);
-		
-		btree_key_t i;
-		for (i = 0; (ret == 0) && (i < node->keys); i++) {
-			uintptr_t addr;
-
-			as_area_t *area = (as_area_t *) node->value[i];
-			
-			mutex_lock(&area->lock);
-			
-			addr = ALIGN_UP(area->base + P2SZ(area->pages),
-			    PAGE_SIZE);
-			
-			if ((addr >= base) && (addr >= area->base) &&
-			    (check_area_conflicts(AS, addr, pages, area)))
-				ret = addr;
-			
-			mutex_unlock(&area->lock);
-		}
-	}
-	
-	mutex_unlock(&AS->lock);
-	
-	return (sysarg_t) ret;
 }
 
Index: kernel/generic/src/proc/program.c
===================================================================
--- kernel/generic/src/proc/program.c	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ kernel/generic/src/proc/program.c	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -87,8 +87,8 @@
 	 * Create the stack address space area.
 	 */
+	uintptr_t virt = USTACK_ADDRESS;
 	as_area_t *area = as_area_create(as,
 	    AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE,
-	    STACK_SIZE, USTACK_ADDRESS, AS_AREA_ATTR_NONE,
-	    &anon_backend, NULL);
+	    STACK_SIZE, AS_AREA_ATTR_NONE, &anon_backend, NULL, &virt, 0);
 	if (!area)
 		return ENOMEM;
Index: kernel/generic/src/syscall/syscall.c
===================================================================
--- kernel/generic/src/syscall/syscall.c	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ kernel/generic/src/syscall/syscall.c	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -146,5 +146,4 @@
 	(syshandler_t) sys_as_area_change_flags,
 	(syshandler_t) sys_as_area_destroy,
-	(syshandler_t) sys_as_get_unmapped_area,
 	
 	/* Page mapping related syscalls. */
@@ -176,7 +175,9 @@
 	(syshandler_t) sys_device_assign_devno,
 	(syshandler_t) sys_physmem_map,
+	(syshandler_t) sys_physmem_unmap,
 	(syshandler_t) sys_dmamem_map,
 	(syshandler_t) sys_dmamem_unmap,
 	(syshandler_t) sys_iospace_enable,
+	(syshandler_t) sys_iospace_disable,
 	(syshandler_t) sys_irq_register,
 	(syshandler_t) sys_irq_unregister,
Index: uspace/app/klog/klog.c
===================================================================
--- uspace/app/klog/klog.c	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ uspace/app/klog/klog.c	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -205,13 +205,6 @@
 	klog_length = size / sizeof(wchar_t);
 	
-	klog = (wchar_t *) as_get_mappable_page(size);
-	if (klog == NULL) {
-		fprintf(stderr, "%s: Unable to allocate virtual memory area\n",
-		    NAME);
-		return ENOMEM;
-	}
-	
-	rc = physmem_map((void *) faddr, (void *) klog, pages,
-	    AS_AREA_READ | AS_AREA_CACHEABLE);
+	rc = physmem_map((void *) faddr, pages,
+	    AS_AREA_READ | AS_AREA_CACHEABLE, (void *) &klog);
 	if (rc != EOK) {
 		fprintf(stderr, "%s: Unable to map klog\n", NAME);
Index: uspace/app/tester/mm/common.c
===================================================================
--- uspace/app/tester/mm/common.c	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ uspace/app/tester/mm/common.c	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -342,16 +342,9 @@
 	link_initialize(&area->link);
 	
-	/* Map the memory area */
-	void *addr = as_get_mappable_page(size);
-	if (addr == NULL) {
+	area->addr = as_area_create((void *) -1, size,
+	    AS_AREA_WRITE | AS_AREA_READ);
+	if (area->addr == (void *) -1) {
 		free(area);
 		check_consistency("map_area (a)");
-		return NULL;
-	}
-	
-	area->addr = as_area_create(addr, size, AS_AREA_WRITE | AS_AREA_READ);
-	if (area->addr == (void *) -1) {
-		free(area);
-		check_consistency("map_area (b)");
 		return NULL;
 	}
Index: uspace/app/tester/mm/mapping1.c
===================================================================
--- uspace/app/tester/mm/mapping1.c	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ uspace/app/tester/mm/mapping1.c	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -35,15 +35,16 @@
 #include "../tester.h"
 
-#define BUFFER1_PAGES 4
-#define BUFFER2_PAGES 2
+#define BUFFER1_PAGES  4
+#define BUFFER2_PAGES  2
 
 static void *create_as_area(size_t size)
 {
-	void *result = as_get_mappable_page(size);
 	TPRINTF("Creating AS area...\n");
-	if (as_area_create(result, size,
-	    AS_AREA_READ | AS_AREA_WRITE) != result) {
+	
+	void *result = as_area_create((void *) -1, size,
+	    AS_AREA_READ | AS_AREA_WRITE);
+	if (result == (void *) -1)
 		return NULL;
-	}
+	
 	return result;
 }
Index: uspace/drv/bus/usb/uhci/utils/malloc32.h
===================================================================
--- uspace/drv/bus/usb/uhci/utils/malloc32.h	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ uspace/drv/bus/usb/uhci/utils/malloc32.h	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -98,11 +98,9 @@
 static inline void * get_page(void)
 {
-	void *free_address = as_get_mappable_page(UHCI_REQUIRED_PAGE_SIZE);
-	if (free_address == 0)
+	void *address = as_area_create((void *) -1, UHCI_REQUIRED_PAGE_SIZE,
+	    AS_AREA_READ | AS_AREA_WRITE);
+	if (address == (void *) -1)
 		return NULL;
-	void *address = as_area_create(free_address, UHCI_REQUIRED_PAGE_SIZE,
-		  AS_AREA_READ | AS_AREA_WRITE);
-	if (address != free_address)
-		return NULL;
+	
 	return address;
 }
Index: uspace/drv/bus/usb/usbmast/main.c
===================================================================
--- uspace/drv/bus/usb/usbmast/main.c	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ uspace/drv/bus/usb/usbmast/main.c	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -300,13 +300,11 @@
 		return;
 	}
-
-	comm_buf = as_get_mappable_page(comm_size);
-	if (comm_buf == NULL) {
+	
+	(void) async_share_out_finalize(callid, &comm_buf);
+	if (comm_buf == (void *) -1) {
 		async_answer_0(callid, EHANGUP);
 		return;
 	}
-
-	(void) async_share_out_finalize(callid, comm_buf);
-
+	
 	mfun = (usbmast_fun_t *) ((ddf_fun_t *)arg)->driver_data;
 
Index: uspace/lib/c/generic/as.c
===================================================================
--- uspace/lib/c/generic/as.c	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ uspace/lib/c/generic/as.c	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -45,15 +45,18 @@
 /** Create address space area.
  *
- * @param address Virtual address where to place new address space area.
- * @param size    Size of the area.
- * @param flags   Flags describing type of the area.
+ * @param base  Starting virtual address of the area.
+ *              If set to (void *) -1, the kernel finds
+ *              a mappable area.
+ * @param size  Size of the area.
+ * @param flags Flags describing type of the area.
  *
- * @return address on success, (void *) -1 otherwise.
+ * @return Starting virtual address of the created area on success.
+ * @return (void *) -1 otherwise.
  *
  */
-void *as_area_create(void *address, size_t size, unsigned int flags)
+void *as_area_create(void *base, size_t size, unsigned int flags)
 {
-	return (void *) __SYSCALL3(SYS_AS_AREA_CREATE, (sysarg_t) address,
-	    (sysarg_t) size, (sysarg_t) flags);
+	return (void *) __SYSCALL4(SYS_AS_AREA_CREATE, (sysarg_t) base,
+	    (sysarg_t) size, (sysarg_t) flags, (sysarg_t) __entry);
 }
 
@@ -102,17 +105,4 @@
 }
 
-/** Return pointer to unmapped address space area
- *
- * @param size Requested size of the allocation.
- *
- * @return Pointer to the beginning of unmapped address space area.
- *
- */
-void *as_get_mappable_page(size_t size)
-{
-	return (void *) __SYSCALL2(SYS_AS_GET_UNMAPPED_AREA,
-	    (sysarg_t) __entry, (sysarg_t) size);
-}
-
 /** Find mapping to physical address.
  *
Index: uspace/lib/c/generic/async.c
===================================================================
--- uspace/lib/c/generic/async.c	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ uspace/lib/c/generic/async.c	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -1998,25 +1998,27 @@
  *
  * @param exch  Exchange for sending the message.
- * @param dst   Destination address space area base.
  * @param size  Size of the destination address space area.
  * @param arg   User defined argument.
  * @param flags Storage for the received flags. Can be NULL.
+ * @param dst   Destination address space area base. Cannot be NULL.
  *
  * @return Zero on success or a negative error code from errno.h.
  *
  */
-int async_share_in_start(async_exch_t *exch, void *dst, size_t size,
-    sysarg_t arg, unsigned int *flags)
+int async_share_in_start(async_exch_t *exch, size_t size, sysarg_t arg,
+    unsigned int *flags, void **dst)
 {
 	if (exch == NULL)
 		return ENOENT;
 	
-	sysarg_t tmp_flags;
-	int res = async_req_3_2(exch, IPC_M_SHARE_IN, (sysarg_t) dst,
-	    (sysarg_t) size, arg, NULL, &tmp_flags);
+	sysarg_t _flags = 0;
+	sysarg_t _dst = (sysarg_t) -1;
+	int res = async_req_2_4(exch, IPC_M_SHARE_IN, (sysarg_t) size,
+	    arg, NULL, &_flags, NULL, &_dst);
 	
 	if (flags)
-		*flags = (unsigned int) tmp_flags;
-	
+		*flags = (unsigned int) _flags;
+	
+	*dst = (void *) _dst;
 	return res;
 }
@@ -2047,5 +2049,5 @@
 		return false;
 	
-	*size = (size_t) IPC_GET_ARG2(data);
+	*size = (size_t) IPC_GET_ARG1(data);
 	return true;
 }
@@ -2053,5 +2055,5 @@
 /** Wrapper for answering the IPC_M_SHARE_IN calls using the async framework.
  *
- * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ
+ * This wrapper only makes it more comfortable to answer IPC_M_SHARE_IN
  * calls so that the user doesn't have to remember the meaning of each IPC
  * argument.
@@ -2131,5 +2133,5 @@
  *
  */
-int async_share_out_finalize(ipc_callid_t callid, void *dst)
+int async_share_out_finalize(ipc_callid_t callid, void **dst)
 {
 	return ipc_share_out_finalize(callid, dst);
Index: uspace/lib/c/generic/ddi.c
===================================================================
--- uspace/lib/c/generic/ddi.c	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ uspace/lib/c/generic/ddi.c	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -45,4 +45,5 @@
 #include <align.h>
 #include <libarch/config.h>
+#include "private/libc.h"
 
 /** Return unique device number.
@@ -61,7 +62,7 @@
  *
  * @param phys  Physical address of the starting frame.
- * @param virt  Virtual address of the starting page.
  * @param pages Number of pages to map.
  * @param flags Flags for the new address space area.
+ * @param virt  Virtual address of the starting page.
  *
  * @return EOK on success
@@ -72,8 +73,8 @@
  *
  */
-int physmem_map(void *phys, void *virt, size_t pages, unsigned int flags)
+int physmem_map(void *phys, size_t pages, unsigned int flags, void **virt)
 {
-	return __SYSCALL4(SYS_PHYSMEM_MAP, (sysarg_t) phys,
-	    (sysarg_t) virt, pages, flags);
+	return __SYSCALL5(SYS_PHYSMEM_MAP, (sysarg_t) phys,
+	    pages, flags, (sysarg_t) virt, (sysarg_t) __entry);
 }
 
@@ -81,7 +82,7 @@
     unsigned int flags, void **phys)
 {
-	return (int) __SYSCALL5(SYS_DMAMEM_MAP, (sysarg_t) virt,
-	    (sysarg_t) size, (sysarg_t) map_flags, (sysarg_t) flags,
-	    (sysarg_t) phys);
+	return (int) __SYSCALL6(SYS_DMAMEM_MAP, (sysarg_t) size,
+	    (sysarg_t) map_flags, (sysarg_t) flags & ~DMAMEM_FLAGS_ANONYMOUS,
+	    (sysarg_t) phys, (sysarg_t) virt, 0);
 }
 
@@ -89,16 +90,12 @@
     unsigned int flags, void **phys, void **virt)
 {
-	*virt = as_get_mappable_page(size);
-	if (*virt == NULL)
-		return ENOMEM;
-	
-	return dmamem_map(*virt, size, map_flags,
-	    flags | DMAMEM_FLAGS_ANONYMOUS, phys);
+	return (int) __SYSCALL6(SYS_DMAMEM_MAP, (sysarg_t) size,
+	    (sysarg_t) map_flags, (sysarg_t) flags | DMAMEM_FLAGS_ANONYMOUS,
+	    (sysarg_t) phys, (sysarg_t) virt, (sysarg_t) __entry);
 }
 
-int dmamem_unmap(void *virt, size_t size, unsigned int flags)
+int dmamem_unmap(void *virt, size_t size)
 {
-	return __SYSCALL3(SYS_DMAMEM_UNMAP, (sysarg_t) virt, (sysarg_t) size,
-	    (sysarg_t) flags);
+	return __SYSCALL3(SYS_DMAMEM_UNMAP, (sysarg_t) virt, (sysarg_t) size, 0);
 }
 
@@ -138,30 +135,33 @@
  * @param pio_addr I/O start address.
  * @param size     Size of the I/O region.
- * @param use_addr Address where the final address for
- *                 application's PIO will be stored.
+ * @param virt     Virtual address for application's
+ *                 PIO operations.
  *
- * @return Zero on success or negative error code.
+ * @return EOK on success.
+ * @return Negative error code on failure.
  *
  */
-int pio_enable(void *pio_addr, size_t size, void **use_addr)
+int pio_enable(void *pio_addr, size_t size, void **virt)
 {
-	void *phys;
-	void *virt;
-	size_t offset;
-	unsigned int pages;
-	
 #ifdef IO_SPACE_BOUNDARY
 	if (pio_addr < IO_SPACE_BOUNDARY) {
-		*use_addr = pio_addr;
+		*virt = pio_addr;
 		return iospace_enable(task_get_id(), pio_addr, size);
 	}
 #endif
 	
-	phys = (void *) ALIGN_DOWN((uintptr_t) pio_addr, PAGE_SIZE);
-	offset = pio_addr - phys;
-	pages = ALIGN_UP(offset + size, PAGE_SIZE) >> PAGE_WIDTH;
-	virt = as_get_mappable_page(pages << PAGE_WIDTH);
-	*use_addr = virt + offset;
-	return physmem_map(phys, virt, pages, AS_AREA_READ | AS_AREA_WRITE);
+	void *phys_frame =
+	    (void *) ALIGN_DOWN((uintptr_t) pio_addr, PAGE_SIZE);
+	size_t offset = pio_addr - phys_frame;
+	size_t pages = SIZE2PAGES(offset + size);
+	
+	void *virt_page;
+	int rc = physmem_map(phys_frame, pages,
+	    AS_AREA_READ | AS_AREA_WRITE, &virt_page);
+	if (rc != EOK)
+		return rc;
+	
+	*virt = virt_page + offset;
+	return EOK;
 }
 
Index: uspace/lib/c/generic/ipc.c
===================================================================
--- uspace/lib/c/generic/ipc.c	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ uspace/lib/c/generic/ipc.c	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -48,4 +48,5 @@
 #include <fibril.h>
 #include <macros.h>
+#include "private/libc.h"
 
 /**
@@ -760,22 +761,24 @@
  *
  * @param phoneid Phone that will be used to contact the receiving side.
- * @param dst     Destination address space area base.
  * @param size    Size of the destination address space area.
  * @param arg     User defined argument.
  * @param flags   Storage for received flags. Can be NULL.
+ * @param dst     Destination address space area base. Cannot be NULL.
  *
  * @return Zero on success or a negative error code from errno.h.
  *
  */
-int ipc_share_in_start(int phoneid, void *dst, size_t size, sysarg_t arg,
-    unsigned int *flags)
-{
-	sysarg_t tmp_flags = 0;
-	int res = ipc_call_sync_3_2(phoneid, IPC_M_SHARE_IN, (sysarg_t) dst,
-	    (sysarg_t) size, arg, NULL, &tmp_flags);
+int ipc_share_in_start(int phoneid, size_t size, sysarg_t arg,
+    unsigned int *flags, void **dst)
+{
+	sysarg_t _flags = 0;
+	sysarg_t _dst = (sysarg_t) -1;
+	int res = ipc_call_sync_2_4(phoneid, IPC_M_SHARE_IN, (sysarg_t) size,
+	    arg, NULL, &_flags, NULL, &_dst);
 	
 	if (flags)
-		*flags = (unsigned int) tmp_flags;
-	
+		*flags = (unsigned int) _flags;
+	
+	*dst = (void *) _dst;
 	return res;
 }
@@ -783,5 +786,5 @@
 /** Wrapper for answering the IPC_M_SHARE_IN calls.
  *
- * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ
+ * This wrapper only makes it more comfortable to answer IPC_M_SHARE_IN
  * calls so that the user doesn't have to remember the meaning of each
  * IPC argument.
@@ -796,5 +799,6 @@
 int ipc_share_in_finalize(ipc_callid_t callid, void *src, unsigned int flags)
 {
-	return ipc_answer_2(callid, EOK, (sysarg_t) src, (sysarg_t) flags);
+	return ipc_answer_3(callid, EOK, (sysarg_t) src, (sysarg_t) flags,
+	    (sysarg_t) __entry);
 }
 
@@ -826,7 +830,7 @@
  *
  */
-int ipc_share_out_finalize(ipc_callid_t callid, void *dst)
-{
-	return ipc_answer_1(callid, EOK, (sysarg_t) dst);
+int ipc_share_out_finalize(ipc_callid_t callid, void **dst)
+{
+	return ipc_answer_2(callid, EOK, (sysarg_t) __entry, (sysarg_t) dst);
 }
 
Index: uspace/lib/c/generic/malloc.c
===================================================================
--- uspace/lib/c/generic/malloc.c	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ uspace/lib/c/generic/malloc.c	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -283,13 +283,8 @@
 static bool area_create(size_t size)
 {
-	void *start = as_get_mappable_page(size);
-	if (start == NULL)
-		return false;
-	
-	/* Align the heap area on page boundary */
-	void *astart = (void *) ALIGN_UP((uintptr_t) start, PAGE_SIZE);
+	/* Align the heap area size on page boundary */
 	size_t asize = ALIGN_UP(size, PAGE_SIZE);
-	
-	astart = as_area_create(astart, asize, AS_AREA_WRITE | AS_AREA_READ);
+	void *astart = as_area_create((void *) -1, asize,
+	    AS_AREA_WRITE | AS_AREA_READ);
 	if (astart == (void *) -1)
 		return false;
Index: uspace/lib/c/generic/mman.c
===================================================================
--- uspace/lib/c/generic/mman.c	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ uspace/lib/c/generic/mman.c	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -42,5 +42,5 @@
 {
 	if (!start)
-		start = as_get_mappable_page(length);
+		start = (void *) -1;
 	
 //	if (!((flags & MAP_SHARED) ^ (flags & MAP_PRIVATE)))
Index: uspace/lib/c/generic/time.c
===================================================================
--- uspace/lib/c/generic/time.c	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ uspace/lib/c/generic/time.c	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -147,12 +147,7 @@
 		}
 		
-		void *addr = as_get_mappable_page(PAGE_SIZE);
-		if (addr == NULL) {
-			errno = ENOMEM;
-			return -1;
-		}
-		
-		rc = physmem_map((void *) faddr, addr, 1,
-		    AS_AREA_READ | AS_AREA_CACHEABLE);
+		void *addr;
+		rc = physmem_map((void *) faddr, 1,
+		    AS_AREA_READ | AS_AREA_CACHEABLE, &addr);
 		if (rc != EOK) {
 			as_area_destroy(addr);
Index: uspace/lib/c/include/as.h
===================================================================
--- uspace/lib/c/include/as.h	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ uspace/lib/c/include/as.h	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -59,5 +59,4 @@
 extern int as_area_destroy(void *);
 extern void *set_maxheapsize(size_t);
-extern void *as_get_mappable_page(size_t);
 extern int as_get_physical_mapping(const void *, uintptr_t *);
 
Index: uspace/lib/c/include/async.h
===================================================================
--- uspace/lib/c/include/async.h	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ uspace/lib/c/include/async.h	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -346,15 +346,15 @@
  */
 
-#define async_share_in_start_0_0(exch, dst, size) \
-	async_share_in_start(exch, dst, size, 0, NULL)
-#define async_share_in_start_0_1(exch, dst, size, flags) \
-	async_share_in_start(exch, dst, size, 0, flags)
-#define async_share_in_start_1_0(exch, dst, size, arg) \
-	async_share_in_start(exch, dst, size, arg, NULL)
-#define async_share_in_start_1_1(exch, dst, size, arg, flags) \
-	async_share_in_start(exch, dst, size, arg, flags)
-
-extern int async_share_in_start(async_exch_t *, void *, size_t, sysarg_t,
-    unsigned int *);
+#define async_share_in_start_0_0(exch, size, dst) \
+	async_share_in_start(exch, size, 0, NULL, dst)
+#define async_share_in_start_0_1(exch, size, flags, dst) \
+	async_share_in_start(exch, size, 0, flags, dst)
+#define async_share_in_start_1_0(exch, size, arg, dst) \
+	async_share_in_start(exch, size, arg, NULL, dst)
+#define async_share_in_start_1_1(exch, size, arg, flags, dst) \
+	async_share_in_start(exch, size, arg, flags, dst)
+
+extern int async_share_in_start(async_exch_t *, size_t, sysarg_t,
+    unsigned int *, void **);
 extern bool async_share_in_receive(ipc_callid_t *, size_t *);
 extern int async_share_in_finalize(ipc_callid_t, void *, unsigned int);
@@ -362,5 +362,5 @@
 extern int async_share_out_start(async_exch_t *, void *, unsigned int);
 extern bool async_share_out_receive(ipc_callid_t *, size_t *, unsigned int *);
-extern int async_share_out_finalize(ipc_callid_t, void *);
+extern int async_share_out_finalize(ipc_callid_t, void **);
 
 /*
Index: uspace/lib/c/include/ddi.h
===================================================================
--- uspace/lib/c/include/ddi.h	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ uspace/lib/c/include/ddi.h	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -42,10 +42,10 @@
 extern int device_assign_devno(void);
 
-extern int physmem_map(void *, void *, size_t, unsigned int);
+extern int physmem_map(void *, size_t, unsigned int, void **);
 
 extern int dmamem_map(void *, size_t, unsigned int, unsigned int, void **);
 extern int dmamem_map_anonymous(size_t, unsigned int, unsigned int, void **,
     void **);
-extern int dmamem_unmap(void *, size_t, unsigned int);
+extern int dmamem_unmap(void *, size_t);
 extern int dmamem_unmap_anonymous(void *);
 
Index: uspace/lib/c/include/ipc/ipc.h
===================================================================
--- uspace/lib/c/include/ipc/ipc.h	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ uspace/lib/c/include/ipc/ipc.h	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -271,17 +271,17 @@
  */
 
-#define ipc_share_in_start_0_0(phoneid, dst, size) \
-	ipc_share_in_start((phoneid), (dst), (size), 0, NULL)
-#define ipc_share_in_start_0_1(phoneid, dst, size, flags) \
-	ipc_share_in_start((phoneid), (dst), (size), 0, (flags))
-#define ipc_share_in_start_1_0(phoneid, dst, size, arg) \
-	ipc_share_in_start((phoneid), (dst), (size), (arg), NULL)
-#define ipc_share_in_start_1_1(phoneid, dst, size, arg, flags) \
-	ipc_share_in_start((phoneid), (dst), (size), (arg), (flags))
-
-extern int ipc_share_in_start(int, void *, size_t, sysarg_t, unsigned int *);
+#define ipc_share_in_start_0_0(phoneid, size, dst) \
+	ipc_share_in_start((phoneid), (size), 0, NULL, (dst))
+#define ipc_share_in_start_0_1(phoneid, size, flags, dst) \
+	ipc_share_in_start((phoneid), (size), 0, (flags), (dst))
+#define ipc_share_in_start_1_0(phoneid, size, arg, dst) \
+	ipc_share_in_start((phoneid), (size), (arg), NULL, (dst))
+#define ipc_share_in_start_1_1(phoneid, size, arg, flags, dst) \
+	ipc_share_in_start((phoneid), (size), (arg), (flags), (dst))
+
+extern int ipc_share_in_start(int, size_t, sysarg_t, unsigned int *, void **);
 extern int ipc_share_in_finalize(ipc_callid_t, void *, unsigned int);
 extern int ipc_share_out_start(int, void *, unsigned int);
-extern int ipc_share_out_finalize(ipc_callid_t, void *);
+extern int ipc_share_out_finalize(ipc_callid_t, void **);
 extern int ipc_data_read_start(int, void *, size_t);
 extern int ipc_data_read_finalize(ipc_callid_t, const void *, size_t);
Index: uspace/lib/fb/imgmap.c
===================================================================
--- uspace/lib/fb/imgmap.c	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ uspace/lib/fb/imgmap.c	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -420,8 +420,7 @@
 	
 	if ((flags & IMGMAP_FLAG_SHARED) == IMGMAP_FLAG_SHARED) {
-		imgmap = (imgmap_t *) as_get_mappable_page(size);
-		
-		if (as_area_create((void *) imgmap, size, AS_AREA_READ |
-		    AS_AREA_WRITE | AS_AREA_CACHEABLE) != (void *) imgmap)
+		imgmap = (imgmap_t *) as_area_create((void *) -1, size,
+		    AS_AREA_READ | AS_AREA_WRITE);
+		if (imgmap == (void *) -1)
 			return NULL;
 	} else {
Index: uspace/lib/fb/screenbuffer.c
===================================================================
--- uspace/lib/fb/screenbuffer.c	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ uspace/lib/fb/screenbuffer.c	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -79,8 +79,7 @@
 	
 	if ((flags & SCREENBUFFER_FLAG_SHARED) == SCREENBUFFER_FLAG_SHARED) {
-		scrbuf = (screenbuffer_t *) as_get_mappable_page(size);
-		
-		if (as_area_create((void *) scrbuf, size, AS_AREA_READ |
-		    AS_AREA_WRITE | AS_AREA_CACHEABLE) != (void *) scrbuf)
+		scrbuf = (screenbuffer_t *) as_area_create((void *) -1, size,
+		    AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE);
+		if (scrbuf == (void *) -1)
 			return NULL;
 	} else {
Index: uspace/lib/fs/libfs.c
===================================================================
--- uspace/lib/fs/libfs.c	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ uspace/lib/fs/libfs.c	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -336,17 +336,12 @@
 	
 	/*
-	 * Allocate piece of address space for PLB.
-	 */
-	reg.plb_ro = as_get_mappable_page(PLB_SIZE);
-	if (!reg.plb_ro) {
+	 * Request sharing the Path Lookup Buffer with VFS.
+	 */
+	rc = async_share_in_start_0_0(exch, PLB_SIZE, (void *) &reg.plb_ro);
+	if (reg.plb_ro == (void *) -1) {
 		async_exchange_end(exch);
 		async_wait_for(req, NULL);
 		return ENOMEM;
 	}
-	
-	/*
-	 * Request sharing the Path Lookup Buffer with VFS.
-	 */
-	rc = async_share_in_start_0_0(exch, reg.plb_ro, PLB_SIZE);
 	
 	async_exchange_end(exch);
Index: uspace/lib/net/generic/packet_remote.c
===================================================================
--- uspace/lib/net/generic/packet_remote.c	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ uspace/lib/net/generic/packet_remote.c	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -66,10 +66,8 @@
     packet_id_t packet_id, size_t size)
 {
-	*packet = (packet_t *) as_get_mappable_page(size);
-	
 	async_exch_t *exch = async_exchange_begin(sess);
 	ipc_call_t answer;
 	aid_t message = async_send_1(exch, NET_PACKET_GET, packet_id, &answer);
-	int rc = async_share_in_start_0_0(exch, *packet, size);
+	int rc = async_share_in_start_0_0(exch, size, (void *) packet);
 	async_exchange_end(exch);
 	
@@ -79,4 +77,7 @@
 	if (rc != EOK)
 		return rc;
+	
+	if (packet == (void *) -1)
+		return ENOMEM;
 	
 	rc = pm_add(*packet);
Index: uspace/lib/nic/src/nic_driver.c
===================================================================
--- uspace/lib/nic/src/nic_driver.c	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ uspace/lib/nic/src/nic_driver.c	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -1345,5 +1345,5 @@
 int nic_dma_unlock_packet(packet_t *packet, size_t size)
 {
-	return dmamem_unmap(packet, size, 0);
+	return dmamem_unmap(packet, size);
 }
 
Index: uspace/srv/bd/ata_bd/ata_bd.c
===================================================================
--- uspace/srv/bd/ata_bd/ata_bd.c	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ uspace/srv/bd/ata_bd/ata_bd.c	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -309,11 +309,9 @@
 	}
 
-	fs_va = as_get_mappable_page(comm_size);
-	if (fs_va == NULL) {
+	(void) async_share_out_finalize(callid, &fs_va);
+	if (fs_va == (void *) -1) {
 		async_answer_0(callid, EHANGUP);
 		return;
 	}
-
-	(void) async_share_out_finalize(callid, fs_va);
 
 	while (true) {
Index: uspace/srv/bd/file_bd/file_bd.c
===================================================================
--- uspace/srv/bd/file_bd/file_bd.c	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ uspace/srv/bd/file_bd/file_bd.c	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -190,11 +190,9 @@
 	}
 
-	fs_va = as_get_mappable_page(comm_size);
-	if (fs_va == NULL) {
+	(void) async_share_out_finalize(callid, &fs_va);
+	if (fs_va == (void *) -1) {
 		async_answer_0(callid, EHANGUP);
 		return;
 	}
-
-	(void) async_share_out_finalize(callid, fs_va);
 
 	while (true) {
Index: uspace/srv/bd/gxe_bd/gxe_bd.c
===================================================================
--- uspace/srv/bd/gxe_bd/gxe_bd.c	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ uspace/srv/bd/gxe_bd/gxe_bd.c	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -193,11 +193,9 @@
 	}
 
-	fs_va = as_get_mappable_page(comm_size);
-	if (fs_va == NULL) {
+	(void) async_share_out_finalize(callid, &fs_va);
+	if (fs_va == (void *) -1) {
 		async_answer_0(callid, EHANGUP);
 		return;
 	}
-
-	(void) async_share_out_finalize(callid, fs_va);
 
 	while (true) {
Index: uspace/srv/bd/part/guid_part/guid_part.c
===================================================================
--- uspace/srv/bd/part/guid_part/guid_part.c	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ uspace/srv/bd/part/guid_part/guid_part.c	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -348,11 +348,9 @@
 	}
 
-	fs_va = as_get_mappable_page(comm_size);
-	if (fs_va == NULL) {
+	(void) async_share_out_finalize(callid, &fs_va);
+	if (fs_va == (void *) -1) {
 		async_answer_0(callid, EHANGUP);
 		return;
 	}
-
-	(void) async_share_out_finalize(callid, fs_va);
 
 	while (true) {
Index: uspace/srv/bd/part/mbr_part/mbr_part.c
===================================================================
--- uspace/srv/bd/part/mbr_part/mbr_part.c	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ uspace/srv/bd/part/mbr_part/mbr_part.c	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -425,11 +425,9 @@
 	}
 
-	fs_va = as_get_mappable_page(comm_size);
-	if (fs_va == NULL) {
+	(void) async_share_out_finalize(callid, &fs_va);
+	if (fs_va == (void *) -1) {
 		async_answer_0(callid, EHANGUP);
 		return;
 	}
-
-	(void) async_share_out_finalize(callid, fs_va);
 
 	while (1) {
Index: uspace/srv/bd/rd/rd.c
===================================================================
--- uspace/srv/bd/rd/rd.c	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ uspace/srv/bd/rd/rd.c	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -105,8 +105,6 @@
 	unsigned int flags;
 	if (async_share_out_receive(&callid, &comm_size, &flags)) {
-		fs_va = as_get_mappable_page(comm_size);
-		if (fs_va) {
-			(void) async_share_out_finalize(callid, fs_va);
-		} else {
+		(void) async_share_out_finalize(callid, &fs_va);
+		if (fs_va == (void *) -1) {
 			async_answer_0(callid, EHANGUP);
 			return;
@@ -224,11 +222,10 @@
 	
 	rd_size = ALIGN_UP(size, block_size);
-	rd_addr = as_get_mappable_page(rd_size);
-	
 	unsigned int flags =
 	    AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE;
-	ret = physmem_map((void *) addr_phys, rd_addr,
-	    ALIGN_UP(rd_size, PAGE_SIZE) >> PAGE_WIDTH, flags);
-	if (ret < 0) {
+	
+	ret = physmem_map((void *) addr_phys,
+	    ALIGN_UP(rd_size, PAGE_SIZE) >> PAGE_WIDTH, flags, &rd_addr);
+	if (ret != EOK) {
 		printf("%s: Error mapping RAM disk\n", NAME);
 		return false;
Index: uspace/srv/hid/fb/fb.c
===================================================================
--- uspace/srv/hid/fb/fb.c	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ uspace/srv/hid/fb/fb.c	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -304,7 +304,6 @@
 	}
 	
-	frontbuf->data = as_get_mappable_page(frontbuf->size);
-	int rc = async_answer_1(callid, EOK, (sysarg_t) frontbuf->data);
-	if (rc != EOK) {
+	int rc = async_share_out_finalize(callid, &frontbuf->data);
+	if ((rc != EOK) || (frontbuf->data == (void *) -1)) {
 		free(frontbuf);
 		async_answer_0(iid, ENOMEM);
@@ -348,7 +347,6 @@
 	}
 	
-	imagemap->data = as_get_mappable_page(imagemap->size);
-	int rc = async_answer_1(callid, EOK, (sysarg_t) imagemap->data);
-	if (rc != EOK) {
+	int rc = async_share_out_finalize(callid, &imagemap->data);
+	if ((rc != EOK) || (imagemap->data == (void *) -1)) {
 		free(imagemap);
 		async_answer_0(iid, ENOMEM);
Index: uspace/srv/hid/fb/port/ega.c
===================================================================
--- uspace/srv/hid/fb/port/ega.c	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ uspace/srv/hid/fb/port/ega.c	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -280,10 +280,8 @@
 	
 	ega.size = (width * height) << 1;
-	ega.addr = as_get_mappable_page(ega.size);
-	if (ega.addr == NULL)
-		return ENOMEM;
-	
-	rc = physmem_map((void *) paddr, ega.addr,
-	    ALIGN_UP(ega.size, PAGE_SIZE) >> PAGE_WIDTH, AS_AREA_READ | AS_AREA_WRITE);
+	
+	rc = physmem_map((void *) paddr,
+	    ALIGN_UP(ega.size, PAGE_SIZE) >> PAGE_WIDTH,
+	    AS_AREA_READ | AS_AREA_WRITE, (void *) &ega.addr);
 	if (rc != EOK)
 		return rc;
Index: uspace/srv/hid/fb/port/kchar.c
===================================================================
--- uspace/srv/hid/fb/port/kchar.c	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ uspace/srv/hid/fb/port/kchar.c	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -83,10 +83,7 @@
 		return rc;
 	
-	kchar.addr = as_get_mappable_page(1);
-	if (kchar.addr == NULL)
-		return ENOMEM;
-	
-	rc = physmem_map((void *) paddr, kchar.addr,
-	    ALIGN_UP(1, PAGE_SIZE) >> PAGE_WIDTH, AS_AREA_READ | AS_AREA_WRITE);
+	rc = physmem_map((void *) paddr,
+	    ALIGN_UP(1, PAGE_SIZE) >> PAGE_WIDTH,
+	    AS_AREA_READ | AS_AREA_WRITE, (void *) &kchar.addr);
 	if (rc != EOK)
 		return rc;
Index: uspace/srv/hid/fb/port/kfb.c
===================================================================
--- uspace/srv/hid/fb/port/kfb.c	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ uspace/srv/hid/fb/port/kfb.c	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -756,12 +756,8 @@
 	
 	kfb.size = scanline * height;
-	kfb.addr = as_get_mappable_page(kfb.size);
-	if (kfb.addr == NULL) {
-		free(kfb.glyphs);
-		return ENOMEM;
-	}
-	
-	rc = physmem_map((void *) paddr + offset, kfb.addr,
-	    ALIGN_UP(kfb.size, PAGE_SIZE) >> PAGE_WIDTH, AS_AREA_READ | AS_AREA_WRITE);
+	
+	rc = physmem_map((void *) paddr + offset,
+	    ALIGN_UP(kfb.size, PAGE_SIZE) >> PAGE_WIDTH,
+	    AS_AREA_READ | AS_AREA_WRITE, (void *) &kfb.addr);
 	if (rc != EOK) {
 		free(kfb.glyphs);
Index: uspace/srv/hid/fb/port/niagara.c
===================================================================
--- uspace/srv/hid/fb/port/niagara.c	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ uspace/srv/hid/fb/port/niagara.c	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -103,11 +103,6 @@
 		return rc;
 	
-	niagara.fifo =
-	    (output_fifo_t *) as_get_mappable_page(sizeof(output_fifo_t));
-	if (niagara.fifo == NULL)
-		return ENOMEM;
-	
-	rc = physmem_map((void *) paddr, (void *) niagara.fifo, 1,
-	    AS_AREA_READ | AS_AREA_WRITE);
+	rc = physmem_map((void *) paddr, 1,
+	    AS_AREA_READ | AS_AREA_WRITE, (void *) &niagara.fifo);
 	if (rc != EOK)
 		return rc;
Index: uspace/srv/hid/input/port/niagara.c
===================================================================
--- uspace/srv/hid/input/port/niagara.c	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ uspace/srv/hid/input/port/niagara.c	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -63,9 +63,4 @@
 #define POLL_INTERVAL  10000
 
-/**
- * Virtual address mapped to the buffer shared with the kernel counterpart.
- */
-static uintptr_t input_buffer_addr;
-
 /*
  * Kernel counterpart of the driver pushes characters (it has read) here.
@@ -102,8 +97,6 @@
 		return -1;
 	
-	input_buffer_addr = (uintptr_t) as_get_mappable_page(PAGE_SIZE);
-	int rc = physmem_map((void *) paddr, (void *) input_buffer_addr,
-	    1, AS_AREA_READ | AS_AREA_WRITE);
-	
+	int rc = physmem_map((void *) paddr, 1,
+	    AS_AREA_READ | AS_AREA_WRITE, (void *) &input_buffer);
 	if (rc != 0) {
 		printf("Niagara: uspace driver couldn't map physical memory: %d\n",
@@ -111,6 +104,4 @@
 		return rc;
 	}
-	
-	input_buffer = (input_buffer_t) input_buffer_addr;
 	
 	thread_id_t tid;
Index: uspace/srv/hw/irc/obio/obio.c
===================================================================
--- uspace/srv/hw/irc/obio/obio.c	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ uspace/srv/hw/irc/obio/obio.c	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -124,9 +124,8 @@
 	
 	base_phys = (void *) paddr;
-	base_virt = as_get_mappable_page(OBIO_SIZE);
 	
 	int flags = AS_AREA_READ | AS_AREA_WRITE;
-	int retval = physmem_map(base_phys, (void *) base_virt,
-	    ALIGN_UP(OBIO_SIZE, PAGE_SIZE) >> PAGE_WIDTH, flags);
+	int retval = physmem_map(base_phys,
+	    ALIGN_UP(OBIO_SIZE, PAGE_SIZE) >> PAGE_WIDTH, flags, &base_virt);
 	
 	if (retval < 0) {
Index: uspace/srv/vfs/vfs.c
===================================================================
--- uspace/srv/vfs/vfs.c	(revision 24cf31f19724828b0cded5929fb87846a91981a2)
+++ uspace/srv/vfs/vfs.c	(revision fbcdeb887f643e4a875e51120a2ddbf6fe35e4b3)
@@ -172,12 +172,7 @@
 	 * Allocate and initialize the Path Lookup Buffer.
 	 */
-	plb = as_get_mappable_page(PLB_SIZE);
-	if (!plb) {
-		printf(NAME ": Cannot allocate a mappable piece of address space\n");
-		return ENOMEM;
-	}
-	
-	if (as_area_create(plb, PLB_SIZE, AS_AREA_READ | AS_AREA_WRITE |
-	    AS_AREA_CACHEABLE) != plb) {
+	plb = as_area_create((void *) -1, PLB_SIZE,
+	    AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE);
+	if (plb == (void *) -1) {
 		printf(NAME ": Cannot create address space area\n");
 		return ENOMEM;
