Index: uspace/drv/char/sun4v-con/main.c
===================================================================
--- uspace/drv/char/sun4v-con/main.c	(revision ce96ec2299b06e284c79c869211af878c35567d6)
+++ uspace/drv/char/sun4v-con/main.c	(revision 19d2ce011edc2ee831f0e815316d64bb3c764581)
@@ -32,4 +32,5 @@
 #include <ddf/driver.h>
 #include <ddf/log.h>
+#include <device/hw_res_parsed.h>
 #include <errno.h>
 #include <stdio.h>
@@ -58,7 +59,37 @@
 };
 
+static int sun4v_con_get_res(ddf_dev_t *dev, sun4v_con_res_t *res)
+{
+	async_sess_t *parent_sess;
+	hw_res_list_parsed_t hw_res;
+	int rc;
+
+	parent_sess = ddf_dev_parent_sess_get(dev);
+	if (parent_sess == NULL)
+		return ENOMEM;
+
+	hw_res_list_parsed_init(&hw_res);
+	rc = hw_res_get_list_parsed(parent_sess, &hw_res, 0);
+	if (rc != EOK)
+		return rc;
+
+	if (hw_res.mem_ranges.count != 1) {
+		rc = EINVAL;
+		goto error;
+	}
+
+	res->base = RNGABS(hw_res.mem_ranges.ranges[0]);
+	return EOK;
+error:
+	hw_res_list_parsed_clean(&hw_res);
+	return rc;
+}
+
+
 static int sun4v_con_dev_add(ddf_dev_t *dev)
 {
 	sun4v_con_t *sun4v_con;
+	sun4v_con_res_t res;
+	int rc;
 
         ddf_msg(LVL_DEBUG, "sun4v_con_dev_add(%p)", dev);
@@ -71,5 +102,11 @@
 	sun4v_con->dev = dev;
 
-	return sun4v_con_add(sun4v_con);
+	rc = sun4v_con_get_res(dev, &res);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed getting hardware resource list.\n");
+		return EIO;
+	}
+
+	return sun4v_con_add(sun4v_con, &res);
 }
 
Index: uspace/drv/char/sun4v-con/sun4v-con.c
===================================================================
--- uspace/drv/char/sun4v-con/sun4v-con.c	(revision ce96ec2299b06e284c79c869211af878c35567d6)
+++ uspace/drv/char/sun4v-con/sun4v-con.c	(revision 19d2ce011edc2ee831f0e815316d64bb3c764581)
@@ -38,5 +38,4 @@
 #include <ipc/char.h>
 #include <stdbool.h>
-#include <sysinfo.h>
 #include <thread.h>
 
@@ -72,9 +71,10 @@
 
 /** Add sun4v console device. */
-int sun4v_con_add(sun4v_con_t *con)
+int sun4v_con_add(sun4v_con_t *con, sun4v_con_res_t *res)
 {
 	ddf_fun_t *fun = NULL;
 	int rc;
 
+	con->res = *res;
 	input_buffer = (input_buffer_t) AS_AREA_ANY;
 
@@ -88,12 +88,5 @@
 	ddf_fun_set_conn_handler(fun, sun4v_con_connection);
 
-	sysarg_t paddr;
-	rc = sysinfo_get_value("niagara.inbuf.address", &paddr);
-	if (rc != EOK) {
-		ddf_msg(LVL_ERROR, "niagara.inbuf.address not set (%d)", rc);
-		goto error;
-	}
-
-	rc = physmem_map(paddr, 1, AS_AREA_READ | AS_AREA_WRITE,
+	rc = physmem_map(res->base, 1, AS_AREA_READ | AS_AREA_WRITE,
 	    (void *) &input_buffer);
 	if (rc != EOK) {
Index: uspace/drv/char/sun4v-con/sun4v-con.h
===================================================================
--- uspace/drv/char/sun4v-con/sun4v-con.h	(revision ce96ec2299b06e284c79c869211af878c35567d6)
+++ uspace/drv/char/sun4v-con/sun4v-con.h	(revision 19d2ce011edc2ee831f0e815316d64bb3c764581)
@@ -41,15 +41,17 @@
 #include <stdint.h>
 
+/** Sun4v console resources */
+typedef struct {
+	uintptr_t base;
+} sun4v_con_res_t;
+
 /** Sun4v console */
 typedef struct {
 	async_sess_t *client_sess;
 	ddf_dev_t *dev;
+	sun4v_con_res_t res;
 } sun4v_con_t;
 
-extern int sun4v_con_init(sun4v_con_t *);
-extern void sun4v_con_write(uint8_t data);
-
-
-extern int sun4v_con_add(sun4v_con_t *);
+extern int sun4v_con_add(sun4v_con_t *, sun4v_con_res_t *);
 extern int sun4v_con_remove(sun4v_con_t *);
 extern int sun4v_con_gone(sun4v_con_t *);
Index: uspace/drv/platform/msim/msim.c
===================================================================
--- uspace/drv/platform/msim/msim.c	(revision ce96ec2299b06e284c79c869211af878c35567d6)
+++ uspace/drv/platform/msim/msim.c	(revision 19d2ce011edc2ee831f0e815316d64bb3c764581)
@@ -65,10 +65,10 @@
 static void msim_init(void);
 
-/** The root device driver's standard operations. */
+/** Standard driver operations. */
 static driver_ops_t msim_ops = {
 	.dev_add = &msim_dev_add
 };
 
-/** The root device driver structure. */
+/** Driver structure. */
 static driver_t msim_driver = {
 	.name = NAME,
@@ -194,4 +194,7 @@
 	
 	msim_fun_t *fun = ddf_fun_data_alloc(fnode, sizeof(msim_fun_t));
+	if (fun == NULL)
+		goto failure;
+	
 	*fun = *fun_proto;
 	
@@ -230,9 +233,8 @@
 }
 
-/** Get the root device.
- *
- * @param dev		The device which is root of the whole device tree (both
- *			of HW and pseudo devices).
- * @return		Zero on success, negative error number otherwise.
+/** Add MSIM platform device.
+ *
+ * @param dev DDF device
+ * @return Zero on success or non-zero error code.
  */
 static int msim_dev_add(ddf_dev_t *dev)
Index: uspace/drv/platform/sun4v/sun4v.c
===================================================================
--- uspace/drv/platform/sun4v/sun4v.c	(revision ce96ec2299b06e284c79c869211af878c35567d6)
+++ uspace/drv/platform/sun4v/sun4v.c	(revision 19d2ce011edc2ee831f0e815316d64bb3c764581)
@@ -36,13 +36,21 @@
  */
 
+#include <as.h>
 #include <assert.h>
-#include <stdio.h>
-#include <errno.h>
-#include <stdlib.h>
-
 #include <ddf/driver.h>
 #include <ddf/log.h>
+#include <errno.h>
+#include <ops/hw_res.h>
+#include <ops/pio_window.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sysinfo.h>
 
 #define NAME "sun4v"
+
+typedef struct sun4v_fun {
+	hw_resource_list_t hw_resources;
+	pio_window_t pio_window;
+} sun4v_fun_t;
 
 static int sun4v_dev_add(ddf_dev_t *dev);
@@ -57,5 +65,69 @@
 };
 
-static int sun4v_add_fun(ddf_dev_t *dev, const char *name, const char *str_match_id)
+static hw_resource_t console_res[] = {
+	{
+		.type = MEM_RANGE,
+		.res.mem_range = {
+			.address = 0,
+			.size = PAGE_SIZE,
+			.relative = true,
+			.endianness = LITTLE_ENDIAN
+		}
+	},
+};
+
+static sun4v_fun_t console_data = {
+	.hw_resources = {
+		sizeof(console_res) / sizeof(console_res[0]),
+		console_res
+	},
+	.pio_window = {
+		.mem = {
+			.base = 0,
+			.size = PAGE_SIZE
+		}
+	}
+};
+
+/** Obtain function soft-state from DDF function node */
+static sun4v_fun_t *sun4v_fun(ddf_fun_t *fnode)
+{
+	return ddf_fun_data_get(fnode);
+}
+
+static hw_resource_list_t *sun4v_get_resources(ddf_fun_t *fnode)
+{
+	sun4v_fun_t *fun = sun4v_fun(fnode);
+
+	assert(fun != NULL);
+	return &fun->hw_resources;
+}
+
+static int sun4v_enable_interrupt(ddf_fun_t *fun, int irq)
+{
+	return true;
+}
+
+static pio_window_t *sun4v_get_pio_window(ddf_fun_t *fnode)
+{
+	sun4v_fun_t *fun = sun4v_fun(fnode);
+
+	assert(fun != NULL);
+	return &fun->pio_window;
+}
+
+static hw_res_ops_t fun_hw_res_ops = {
+	.get_resource_list = &sun4v_get_resources,
+	.enable_interrupt = &sun4v_enable_interrupt,
+};
+
+static pio_window_ops_t fun_pio_window_ops = {
+	.get_pio_window = &sun4v_get_pio_window
+};
+
+static ddf_dev_ops_t sun4v_fun_ops;
+
+static int sun4v_add_fun(ddf_dev_t *dev, const char *name,
+    const char *str_match_id, sun4v_fun_t *fun_proto)
 {
 	ddf_msg(LVL_NOTE, "Adding function '%s'.", name);
@@ -72,4 +144,12 @@
 	}
 
+	sun4v_fun_t *fun = ddf_fun_data_alloc(fnode, sizeof(sun4v_fun_t));
+	if (fun == NULL) {
+		rc = ENOMEM;
+		goto error;
+	}
+
+	*fun = *fun_proto;
+
 	/* Add match ID */
 	rc = ddf_fun_add_match_id(fnode, str_match_id, 100);
@@ -79,6 +159,10 @@
 	}
 
+	/* Set provided operations to the device. */
+	ddf_fun_set_ops(fnode, &sun4v_fun_ops);
+
 	/* Register function. */
-	if (ddf_fun_bind(fnode) != EOK) {
+	rc = ddf_fun_bind(fnode);
+	if (rc != EOK) {
 		ddf_msg(LVL_ERROR, "Failed binding function %s.", name);
 		goto error;
@@ -98,5 +182,5 @@
 	int rc;
 
-	rc = sun4v_add_fun(dev, "console", "sun4v/console");
+	rc = sun4v_add_fun(dev, "console", "sun4v/console", &console_data);
 	if (rc != EOK)
 		return rc;
@@ -108,5 +192,5 @@
 static int sun4v_dev_add(ddf_dev_t *dev)
 {
-	ddf_msg(LVL_NOTE, "sun4v_dev_add, device handle = %d",
+	ddf_msg(LVL_DEBUG, "sun4v_dev_add, device handle = %d",
 	    (int)ddf_dev_get_handle(dev));
 
@@ -119,4 +203,28 @@
 }
 
+static int sun4v_init(void)
+{
+	int rc;
+	sysarg_t paddr;
+
+	sun4v_fun_ops.interfaces[HW_RES_DEV_IFACE] = &fun_hw_res_ops;
+	sun4v_fun_ops.interfaces[PIO_WINDOW_DEV_IFACE] = &fun_pio_window_ops;
+
+	rc = ddf_log_init(NAME);
+	if (rc != EOK) {
+		printf(NAME ": Failed initializing logging service\n");
+		return rc;
+	}
+
+	rc = sysinfo_get_value("niagara.inbuf.address", &paddr);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "niagara.inbuf.address not set (%d)", rc);
+		return rc;
+	}
+
+	console_data.pio_window.mem.base = paddr;
+	return EOK;
+}
+
 int main(int argc, char *argv[])
 {
@@ -125,9 +233,7 @@
 	printf(NAME ": Sun4v platform driver\n");
 
-	rc = ddf_log_init(NAME);
-	if (rc != EOK) {
-		printf(NAME ": Failed initializing logging service");
+	rc = sun4v_init();
+	if (rc != EOK)
 		return 1;
-	}
 
 	return ddf_driver_main(&sun4v_driver);
