Index: Makefile
===================================================================
--- Makefile	(revision b7f364ec06d3f71937db23cb5f58ef39397da7b7)
+++ Makefile	(revision 9a8d91b75a1fd931c8f781ec517362f92ed670d3)
@@ -109,4 +109,5 @@
 	generic/src/console/cmd.c \
 	generic/src/cpu/cpu.c \
+	generic/src/ddi/ddi.c \
 	generic/src/interrupt/interrupt.c \
 	generic/src/main/main.c \
Index: generic/include/ddi/ddi.h
===================================================================
--- generic/include/ddi/ddi.h	(revision 9a8d91b75a1fd931c8f781ec517362f92ed670d3)
+++ generic/include/ddi/ddi.h	(revision 9a8d91b75a1fd931c8f781ec517362f92ed670d3)
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2006 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __DDI_H__
+#define __DDI_H__
+
+#include <ddi/ddi_arg.h>
+#include <arch/types.h>
+
+extern __native sys_map_physmem(ddi_arg_t *uspace_ddi_arg);
+
+#endif
Index: generic/include/ddi/ddi_arg.h
===================================================================
--- generic/include/ddi/ddi_arg.h	(revision 9a8d91b75a1fd931c8f781ec517362f92ed670d3)
+++ generic/include/ddi/ddi_arg.h	(revision 9a8d91b75a1fd931c8f781ec517362f92ed670d3)
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2006 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __DDI_ARG_H__
+#define __DDI_ARG_H__
+
+/** Structure encapsulating arguments for SYS_MAP_PHYSMEM syscall. */
+typedef struct {
+	unsigned long long task_id;	/** ID of the destination task. */
+	void *phys_base;		/** Physical address of starting frame. */
+	void *virt_base;		/** Virtual address of starting page. */
+	unsigned long pages;		/** Number of pages to map. */
+	int writable;			/** True if the mapping should be writable. */
+} ddi_arg_t;
+
+#endif
Index: generic/include/errno.h
===================================================================
--- generic/include/errno.h	(revision b7f364ec06d3f71937db23cb5f58ef39397da7b7)
+++ generic/include/errno.h	(revision 9a8d91b75a1fd931c8f781ec517362f92ed670d3)
@@ -38,5 +38,5 @@
 #define EFORWARD   -5  /* Forward error */
 #define EPERM      -6  /* Permission denied */
-#define EHANGUP    -7  /* Answerbox closed cionnection, call sys_ipc_hangup
+#define EHANGUP    -7  /* Answerbox closed connection, call sys_ipc_hangup
 			* to close the connection. Used by answerbox
 			* to close the connection.  */
Index: generic/include/mm/as.h
===================================================================
--- generic/include/mm/as.h	(revision b7f364ec06d3f71937db23cb5f58ef39397da7b7)
+++ generic/include/mm/as.h	(revision 9a8d91b75a1fd931c8f781ec517362f92ed670d3)
@@ -57,4 +57,5 @@
 #define AS_AREA_WRITE	2
 #define AS_AREA_EXEC	4
+#define AS_AREA_DEVICE	8
 
 /** Address space area structure.
Index: generic/include/proc/task.h
===================================================================
--- generic/include/proc/task.h	(revision b7f364ec06d3f71937db23cb5f58ef39397da7b7)
+++ generic/include/proc/task.h	(revision 9a8d91b75a1fd931c8f781ec517362f92ed670d3)
@@ -59,4 +59,5 @@
 extern task_t *task_create(as_t *as, char *name);
 extern task_t *task_run_program(void *program_addr, char *name);
+extern task_t *task_find_by_id(task_id_t id);
 
 extern __native sys_get_task_id(task_id_t *uspace_task_id);
Index: generic/include/syscall/syscall.h
===================================================================
--- generic/include/syscall/syscall.h	(revision b7f364ec06d3f71937db23cb5f58ef39397da7b7)
+++ generic/include/syscall/syscall.h	(revision 9a8d91b75a1fd931c8f781ec517362f92ed670d3)
@@ -49,4 +49,5 @@
 	SYS_IPC_WAIT,
 	SYS_IPC_HANGUP,
+	SYS_MAP_PHYSMEM,
 	SYSCALL_END
 } syscall_t;
Index: generic/src/ddi/ddi.c
===================================================================
--- generic/src/ddi/ddi.c	(revision 9a8d91b75a1fd931c8f781ec517362f92ed670d3)
+++ generic/src/ddi/ddi.c	(revision 9a8d91b75a1fd931c8f781ec517362f92ed670d3)
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2006 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <ddi/ddi.h>
+#include <ddi/ddi_arg.h>
+#include <proc/task.h>
+#include <security/cap.h>
+#include <mm/frame.h>
+#include <mm/page.h>
+#include <mm/as.h>
+#include <synch/spinlock.h>
+#include <arch.h>
+#include <align.h>
+#include <errno.h>
+
+/** Map piece of physical memory into virtual address space of specified task.
+ *
+ * @param id Task ID of the destination task.
+ * @param pf Physical frame address of the starting frame.
+ * @param vp Virtual page address of the starting page.
+ * @param pages Number of pages to map.
+ * @param writable If true, the mapping will be created writable.
+ *
+ * @return 0 on success, EPERM if the caller lacks capabilities to use this syscall,
+ *	   ENOENT if there is no task matching the specified ID and ENOMEM if
+ *	   there was a problem in creating address space area.
+ */
+static int ddi_map_physmem(task_id_t id, __address pf, __address vp, count_t pages, bool writable)
+{
+	ipl_t ipl;
+	cap_t caps;
+	task_t *t;
+	int flags;
+	count_t i;
+	
+	/*
+	 * Make sure the caller is authorised to make this syscall.
+	 */
+	caps = cap_get(TASK);
+	if (!(caps & CAP_MEM_MANAGER))
+		return EPERM;
+	
+	ipl = interrupts_disable();
+	spinlock_lock(&tasks_lock);
+	
+	t = task_find_by_id(id);
+	
+	if (!t) {
+		/*
+		 * There is no task with the specified ID.
+		 */
+		spinlock_unlock(&tasks_lock);
+		interrupts_restore(ipl);
+		return ENOENT;
+	}
+
+	/*
+	 * TODO: We are currently lacking support for task destroying.
+	 * Once it is added to the kernel, we must take care to
+	 * synchronize in a way that prevents race conditions here.
+	 */
+	
+	/* Lock the task and release the lock protecting tasks_btree. */
+	spinlock_lock(&t->lock);
+	spinlock_unlock(&tasks_lock);
+	
+	flags = AS_AREA_DEVICE | AS_AREA_READ;
+	if (writable)
+		flags |= AS_AREA_WRITE;
+	if (!as_area_create(t->as, flags, pages * PAGE_SIZE, vp)) {
+		/*
+		 * The address space area could not have been created.
+		 * We report it using ENOMEM.
+		 */
+		spinlock_unlock(&t->lock);
+		interrupts_restore(ipl);
+		return ENOMEM;
+	}
+	
+	/* Initialize page tables. */
+	for (i = 0; i < pages; i++)
+		as_set_mapping(t->as, vp + i * PAGE_SIZE, pf + i * FRAME_SIZE);
+
+	spinlock_unlock(&t->lock);
+	interrupts_restore(ipl);
+	return 0;
+}
+
+/** Wrapper for SYS_MAP_PHYSMEM syscall.
+ *
+ * @param User space address of DDI argument structure.
+ *
+ * @return 0 on success, otherwise it returns error code found in errno.h
+ */ 
+__native sys_map_physmem(ddi_arg_t *uspace_ddi_arg)
+{
+	ddi_arg_t arg;
+	
+	copy_from_uspace(&arg, uspace_ddi_arg, sizeof(ddi_arg_t));
+	return (__native) ddi_map_physmem((task_id_t) arg.task_id, ALIGN_DOWN((__address) arg.phys_base, FRAME_SIZE),
+					  ALIGN_DOWN((__address) arg.virt_base, PAGE_SIZE), (count_t) arg.pages,
+					  (bool) arg.writable);
+}
Index: generic/src/mm/as.c
===================================================================
--- generic/src/mm/as.c	(revision b7f364ec06d3f71937db23cb5f58ef39397da7b7)
+++ generic/src/mm/as.c	(revision 9a8d91b75a1fd931c8f781ec517362f92ed670d3)
@@ -353,5 +353,5 @@
 	int flags;
 
-	flags = PAGE_USER | PAGE_PRESENT | PAGE_CACHEABLE;
+	flags = PAGE_USER | PAGE_PRESENT;
 	
 	if (a->flags & AS_AREA_READ)
@@ -364,4 +364,7 @@
 		flags |= PAGE_EXEC;
 	
+	if (!(a->flags & AS_AREA_DEVICE))
+		flags |= PAGE_CACHEABLE;
+		
 	return flags;
 }
Index: generic/src/proc/task.c
===================================================================
--- generic/src/proc/task.c	(revision b7f364ec06d3f71937db23cb5f58ef39397da7b7)
+++ generic/src/proc/task.c	(revision 9a8d91b75a1fd931c8f781ec517362f92ed670d3)
@@ -173,4 +173,20 @@
 }
 
+/** Find task structure corresponding to task ID.
+ *
+ * The tasks_lock must be already held by the caller of this function
+ * and interrupts must be disabled.
+ *
+ * @param id Task ID.
+ *
+ * @return Task structure address or NULL if there is no such task ID.
+ */
+task_t *task_find_by_id(task_id_t id)
+{
+	btree_node_t *leaf;
+	
+	return (task_t *) btree_search(&tasks_btree, (btree_key_t) id, &leaf);
+}
+
 /** Print task list */
 void task_print_list(void)
Index: generic/src/syscall/syscall.c
===================================================================
--- generic/src/syscall/syscall.c	(revision b7f364ec06d3f71937db23cb5f58ef39397da7b7)
+++ generic/src/syscall/syscall.c	(revision 9a8d91b75a1fd931c8f781ec517362f92ed670d3)
@@ -38,4 +38,5 @@
 #include <ipc/sysipc.h>
 #include <synch/futex.h>
+#include <ddi/ddi.h>
 
 static __native sys_io(int fd, const void * buf, size_t count) {
@@ -92,4 +93,5 @@
 	sys_ipc_forward_fast,
 	sys_ipc_wait_for_call,
-	sys_ipc_hangup
+	sys_ipc_hangup,
+	sys_map_physmem
 };
