Index: uspace/lib/c/generic/ddi.c
===================================================================
--- uspace/lib/c/generic/ddi.c	(revision eeb5cc2d5850c270487563d1838d9f371d7f8e73)
+++ uspace/lib/c/generic/ddi.c	(revision 7de1988cde59f3ad2459d423b31be5ea19d7df75)
@@ -42,4 +42,7 @@
 #include <ddi.h>
 #include <libarch/ddi.h>
+#include <device/hw_res.h>
+#include <device/hw_res_parsed.h>
+#include <device/pio_window.h>
 #include <libc.h>
 #include <task.h>
@@ -136,5 +139,15 @@
 }
 
-/** Enable PIO for specified HW resource.
+/** Enable PIO for specified address range.
+ *
+ * @param range I/O range to be enable.
+ * @param virt  Virtual address for application's PIO operations. 
+ */
+int pio_enable_range(addr_range_t *range, void **virt)
+{
+	return pio_enable(RNGABSPTR(*range), RNGSZ(*range), virt);
+}
+
+/** Enable PIO for specified HW resource wrt. to the PIO window.
  *
  * @param win      PIO window. May be NULL if the resources are known to be
Index: uspace/lib/c/generic/device/hw_res_parsed.c
===================================================================
--- uspace/lib/c/generic/device/hw_res_parsed.c	(revision eeb5cc2d5850c270487563d1838d9f371d7f8e73)
+++ uspace/lib/c/generic/device/hw_res_parsed.c	(revision 7de1988cde59f3ad2459d423b31be5ea19d7df75)
@@ -80,12 +80,36 @@
 }
 
+static uint64_t absolutize(uint64_t addr, bool relative, uint64_t base)
+{
+	if (!relative)
+		return addr;
+	else
+		return addr + base;
+}
+
+static uint64_t relativize(uint64_t addr, bool relative, uint64_t base)
+{
+	if (relative)
+		return addr;
+	else
+		return addr - base;
+}
+
 static void hw_res_parse_add_io_range(hw_res_list_parsed_t *out,
-    const hw_resource_t *res, int flags)
-{
+    const pio_window_t *win, const hw_resource_t *res, int flags)
+{
+	endianness_t endianness;
+	uint64_t absolute;
+	uint64_t relative;
+	size_t size;
+
 	assert(res && (res->type == IO_RANGE));
 	
-	uint64_t address = res->res.io_range.address;
-	endianness_t endianness = res->res.io_range.endianness;
-	size_t size = res->res.io_range.size;
+	absolute = absolutize(res->res.io_range.address,
+	    res->res.io_range.relative, win->io.base);
+	relative = relativize(res->res.io_range.address,
+	    res->res.io_range.relative, win->io.base);
+	size = res->res.io_range.size;
+	endianness = res->res.io_range.endianness;
 	
 	if ((size == 0) && (!(flags & HW_RES_KEEP_ZERO_AREA)))
@@ -97,26 +121,38 @@
 	if (!keep_duplicit) {
 		for (size_t i = 0; i < count; i++) {
-			uint64_t s_address = out->io_ranges.ranges[i].address;
-			size_t s_size = out->io_ranges.ranges[i].size;
+			uint64_t s_address;
+			size_t s_size;
+
+			s_address = RNGABS(out->io_ranges.ranges[i]);
+			s_size = RNGSZ(out->io_ranges.ranges[i]);
 			
-			if ((address == s_address) && (size == s_size))
-				return;
-		}
-	}
-	
-	out->io_ranges.ranges[count].address = address;
+			if ((absolute == s_address) && (size == s_size))
+				return;
+		}
+	}
+	
+	RNGABS(out->io_ranges.ranges[count]) = absolute;
+	RNGREL(out->io_ranges.ranges[count]) = relative;
+	RNGSZ(out->io_ranges.ranges[count]) = size;
 	out->io_ranges.ranges[count].endianness = endianness;
-	out->io_ranges.ranges[count].size = size;
 	out->io_ranges.count++;
 }
 
 static void hw_res_parse_add_mem_range(hw_res_list_parsed_t *out,
-    const hw_resource_t *res, int flags)
-{
+    const pio_window_t *win, const hw_resource_t *res, int flags)
+{
+	endianness_t endianness;
+	uint64_t absolute;
+	uint64_t relative;
+	size_t size;
+	
 	assert(res && (res->type == MEM_RANGE));
 	
-	uint64_t address = res->res.mem_range.address;
-	endianness_t endianness = res->res.mem_range.endianness;
-	size_t size = res->res.mem_range.size;
+	absolute = absolutize(res->res.mem_range.address,
+	    res->res.mem_range.relative, win->mem.base);
+	relative = relativize(res->res.mem_range.address,
+	    res->res.mem_range.relative, win->mem.base);
+	size = res->res.mem_range.size;
+	endianness = res->res.mem_range.endianness;
 	
 	if ((size == 0) && (!(flags & HW_RES_KEEP_ZERO_AREA)))
@@ -128,15 +164,19 @@
 	if (!keep_duplicit) {
 		for (size_t i = 0; i < count; ++i) {
-			uint64_t s_address = out->mem_ranges.ranges[i].address;
-			size_t s_size = out->mem_ranges.ranges[i].size;
+			uint64_t s_address;
+			size_t s_size;
+
+			s_address = RNGABS(out->mem_ranges.ranges[i]);;
+			s_size = RNGSZ(out->mem_ranges.ranges[i]);
 			
-			if ((address == s_address) && (size == s_size))
-				return;
-		}
-	}
-	
-	out->mem_ranges.ranges[count].address = address;
+			if ((absolute == s_address) && (size == s_size))
+				return;
+		}
+	}
+	
+	RNGABS(out->mem_ranges.ranges[count]) = absolute;
+	RNGREL(out->mem_ranges.ranges[count]) = relative;
+	RNGSZ(out->mem_ranges.ranges[count]) = size;
 	out->mem_ranges.ranges[count].endianness = endianness;
-	out->mem_ranges.ranges[count].size = size;
 	out->mem_ranges.count++;
 }
@@ -144,21 +184,21 @@
 /** Parse list of hardware resources
  *
- * @param      hw_resources Original structure resource
- * @param[out] out          Output parsed resources
- * @param      flags        Flags of the parsing.
- *                          HW_RES_KEEP_ZERO_AREA for keeping
- *                          zero-size areas, HW_RES_KEEP_DUPLICITIES
- *                          for keep duplicit areas
+ * @param      win          PIO window.
+ * @param      res          Original structure resource.
+ * @param[out] out          Output parsed resources.
+ * @param      flags        Flags of the parsing:
+ *                          HW_RES_KEEP_ZERO_AREA for keeping zero-size areas,
+ *                          HW_RES_KEEP_DUPLICITIES to keep duplicit areas.
  *
  * @return EOK if succeed, error code otherwise.
  *
  */
-int hw_res_list_parse(const hw_resource_list_t *hw_resources,
-    hw_res_list_parsed_t *out, int flags)
-{
-	if ((!hw_resources) || (!out))
+int hw_res_list_parse(const pio_window_t *win,
+    const hw_resource_list_t *res, hw_res_list_parsed_t *out, int flags)
+{
+	if (!res || !out)
 		return EINVAL;
 	
-	size_t res_count = hw_resources->count;
+	size_t res_count = res->count;
 	hw_res_list_parsed_clean(out);
 	
@@ -174,5 +214,5 @@
 	
 	for (size_t i = 0; i < res_count; ++i) {
-		const hw_resource_t *resource = &(hw_resources->resources[i]);
+		const hw_resource_t *resource = &res->resources[i];
 		
 		switch (resource->type) {
@@ -181,8 +221,8 @@
 			break;
 		case IO_RANGE:
-			hw_res_parse_add_io_range(out, resource, flags);
+			hw_res_parse_add_io_range(out, win, resource, flags);
 			break;
 		case MEM_RANGE:
-			hw_res_parse_add_mem_range(out, resource, flags);
+			hw_res_parse_add_mem_range(out, win, resource, flags);
 			break;
 		case DMA_CHANNEL_8:
@@ -216,4 +256,7 @@
     hw_res_list_parsed_t *hw_res_parsed, int flags)
 {
+	pio_window_t pio_window;
+	int rc;
+
 	if (!hw_res_parsed)
 		return EBADMEM;
@@ -222,10 +265,15 @@
 	hw_res_list_parsed_clean(hw_res_parsed);
 	memset(&hw_resources, 0, sizeof(hw_resource_list_t));
-	
-	int rc = hw_res_get_resource_list(sess, &hw_resources);
+
+	rc = pio_window_get(sess, &pio_window);
+	if (rc != EOK)
+		return rc; 
+	
+	rc = hw_res_get_resource_list(sess, &hw_resources);
 	if (rc != EOK)
 		return rc;
-	
-	rc = hw_res_list_parse(&hw_resources, hw_res_parsed, flags);
+
+	rc = hw_res_list_parse(&pio_window, &hw_resources, hw_res_parsed,
+	    flags);
 	hw_res_clean_resource_list(&hw_resources);
 	
Index: uspace/lib/c/include/ddi.h
===================================================================
--- uspace/lib/c/include/ddi.h	(revision eeb5cc2d5850c270487563d1838d9f371d7f8e73)
+++ uspace/lib/c/include/ddi.h	(revision 7de1988cde59f3ad2459d423b31be5ea19d7df75)
@@ -41,4 +41,5 @@
 #include <abi/ddi/irq.h>
 #include <device/hw_res.h>
+#include <device/hw_res_parsed.h>
 #include <device/pio_window.h>
 #include <task.h>
@@ -57,4 +58,5 @@
 extern int dmamem_unmap_anonymous(void *);
 
+extern int pio_enable_range(addr_range_t *, void **);
 extern int pio_enable_resource(pio_window_t *, hw_resource_t *, void **);
 extern int pio_enable(void *, size_t, void **);
Index: uspace/lib/c/include/device/hw_res_parsed.h
===================================================================
--- uspace/lib/c/include/device/hw_res_parsed.h	(revision eeb5cc2d5850c270487563d1838d9f371d7f8e73)
+++ uspace/lib/c/include/device/hw_res_parsed.h	(revision 7de1988cde59f3ad2459d423b31be5ea19d7df75)
@@ -37,4 +37,5 @@
 
 #include <device/hw_res.h>
+#include <device/pio_window.h>
 #include <str.h>
 
@@ -45,14 +46,28 @@
 #define HW_RES_KEEP_DUPLICIT   0x2
 
+
+#define RNGABS(rng)	(rng).address.absolute
+#define RNGREL(rng)	(rng).address.relative
+#define RNGSZ(rng)	(rng).size
+
+#define RNGABSPTR(rng)	((void *) ((uintptr_t) RNGABS((rng))))
+
+typedef struct address64 {
+	/** Aboslute address. */ 
+	uint64_t absolute;
+	/** PIO window base relative address. */
+	uint64_t relative; 
+} address64_t;
+
 /** Address range structure */
 typedef struct addr_range {
 	/** Start address */
-	uint64_t address;
-	
-	/** Endianness */
-	endianness_t endianness;
+	address64_t address;
 	
 	/** Area size */
 	size_t size;
+
+	/** Endianness */
+	endianness_t endianness;
 } addr_range_t;
 
@@ -139,5 +154,5 @@
 }
 
-extern int hw_res_list_parse(const hw_resource_list_t *,
+extern int hw_res_list_parse(const pio_window_t *, const hw_resource_list_t *,
     hw_res_list_parsed_t *, int);
 extern int hw_res_get_list_parsed(async_sess_t *, hw_res_list_parsed_t *, int);
