Index: uspace/lib/c/generic/device/hw_res_parsed.c
===================================================================
--- uspace/lib/c/generic/device/hw_res_parsed.c	(revision cf02eaf20ca2a7fcb7eb5934b972b18b7bc1e6a3)
+++ uspace/lib/c/generic/device/hw_res_parsed.c	(revision 07733961aa0e69f8ccc3a986068ad31674911dbe)
@@ -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);
 	
