Index: defaults/sparc64/sun4v/Makefile.config
===================================================================
--- defaults/sparc64/sun4v/Makefile.config	(revision eeb643ddb3783861fb3ee6f341c31c048865cfe1)
+++ defaults/sparc64/sun4v/Makefile.config	(revision 86018c11a1e682f179cb1ce268bf18b901b8a78b)
@@ -7,5 +7,5 @@
 CONFIG_RD_EXTERNAL = n
 
-CONFIG_LOG = y
+# CONFIG_LOG = y
 
 CONFIG_SMP = n
Index: kernel/arch/sparc64/src/drivers/niagara.c
===================================================================
--- kernel/arch/sparc64/src/drivers/niagara.c	(revision eeb643ddb3783861fb3ee6f341c31c048865cfe1)
+++ kernel/arch/sparc64/src/drivers/niagara.c	(revision 86018c11a1e682f179cb1ce268bf18b901b8a78b)
@@ -54,14 +54,4 @@
 #define POLL_INTERVAL  10000
 
-/**
- * The driver is polling based, but in order to notify the userspace
- * of a key being pressed, we need to supply the interface with some
- * interrupt number. The interrupt number can be arbitrary as it it
- * will never be used for identifying HW interrupts, but only in
- * notifying the userspace. 
- */
-#define FICTIONAL_INR		1
-
-
 static niagara_instance_t *instance = NULL;
 
@@ -95,19 +85,17 @@
 	output_buffer;
 
-#if 0
-/** Niagara character device */
-chardev_t niagara_io;
-
-/** defined in drivers/kbd.c */
-extern kbd_type_t kbd_type;
-
-/**
- * The character read will be stored here until the (notified) uspace
- * driver picks it up.
- */
-static char read_char;
-
-
-#endif
+/**
+ * Analogous to the output_buffer, see the previous definition.
+ */
+#define INPUT_BUFFER_SIZE	((PAGE_SIZE) - 2 * 8)
+static volatile struct {
+	uint64_t write_ptr;
+	uint64_t read_ptr;
+	char data[INPUT_BUFFER_SIZE];
+}
+	__attribute__ ((packed))
+	__attribute__ ((aligned(PAGE_SIZE)))
+	input_buffer;
+
 
 /** Writes a single character to the standard output. */
@@ -126,66 +114,11 @@
 }
 
-#if 0
-/**
- * Grabs the input for kernel.
- */
-void niagara_grab(void)
-{
-	ipl_t ipl = interrupts_disable();
-	spinlock_lock(&niagara_irq.lock);
-	niagara_irq.notif_cfg.notify = false;
-	spinlock_unlock(&niagara_irq.lock);
-	interrupts_restore(ipl);
-}
-
-/**
- * Releases the input so that userspace can use it.
- */
-void niagara_release(void)
-{
-	ipl_t ipl = interrupts_disable();
-	spinlock_lock(&niagara_irq.lock);
-	if (niagara_irq.notif_cfg.answerbox)
-		niagara_irq.notif_cfg.notify = true;
-	spinlock_unlock(&niagara_irq.lock);
-	interrupts_restore(ipl);
-}
-
-/**
- * Default suspend/resume operation for the input device.
- */
-static void niagara_noop(chardev_t *d)
-{
-}
-
-/**
- * Called when actively reading the character.
- */
-static char niagara_read(chardev_t *d)
-{
-	uint64_t c;
-
-	if (__hypercall_fast_ret1(0, 0, 0, 0, 0, CONS_GETCHAR, &c) == EOK) {
-		return (char) c;
-	}
-
-	return '\0';
-}
-
-/**
- * Returns the character last read. This function is called from the
- * pseudocode - the character returned by this function is passed to
- * the userspace keyboard driver.
- */
-char niagara_getc(void) {
-	return read_char;
-}
-
-#endif
-
 /**
  * Function regularly called by the keyboard polling thread. Asks the
  * hypervisor whether there is any unread character. If so, it picks it up
  * and sends it to the upper layers of HelenOS.
+ *
+ * Apart from that, it also checks whether the userspace output driver has
+ * pushed any characters to the output buffer. If so, it prints them.
  */
 static void niagara_poll(niagara_instance_t *instance)
@@ -200,5 +133,11 @@
 
 	if (__hypercall_fast_ret1(0, 0, 0, 0, 0, CONS_GETCHAR, &c) == EOK) {
-		indev_push_character(instance->srlnin, c);
+		if (!silent) {
+			indev_push_character(instance->srlnin, c);
+		} else {
+			input_buffer.data[input_buffer.write_ptr] = (char) c;
+			input_buffer.write_ptr =
+				((input_buffer.write_ptr) + 1) % INPUT_BUFFER_SIZE;
+		}
 	}
 
@@ -210,8 +149,5 @@
 static void kniagarapoll(void *instance) {
 	while (true) {
-		//MH
-		//if (!silent)
-			niagara_poll(instance);
-		
+		niagara_poll(instance);
 		thread_usleep(POLL_INTERVAL);
 	}
@@ -245,8 +181,11 @@
 	/*
 	 * Set sysinfos and pareas so that the userspace counterpart of the
-	 * niagara fb driver can communicate with kernel using a shared buffer.
+	 * niagara fb and kbd driver can communicate with kernel using shared
+	 * buffers.
  	 */
 	output_buffer.read_ptr = 0;
 	output_buffer.write_ptr = 0;
+	input_buffer.write_ptr = 0;
+	input_buffer.read_ptr = 0;
 
 	sysinfo_set_item_val("niagara.outbuf.address", NULL,
@@ -257,4 +196,11 @@
 		OUTPUT_BUFFER_SIZE);
 
+	sysinfo_set_item_val("niagara.inbuf.address", NULL,
+		KA2PA(&input_buffer));
+	sysinfo_set_item_val("niagara.inbuf.size", NULL,
+		PAGE_SIZE);
+	sysinfo_set_item_val("niagara.inbuf.datasize", NULL,
+		INPUT_BUFFER_SIZE);
+
 	static parea_t outbuf_parea;
 	outbuf_parea.pbase = (uintptr_t) (KA2PA(&output_buffer));
@@ -262,43 +208,8 @@
 	ddi_parea_register(&outbuf_parea);
 
-	#if 0
-	kbd_type = KBD_SUN4V;
-
-	devno_t devno = device_assign_devno();
-	irq_initialize(&niagara_irq);
-	niagara_irq.devno = devno;
-	niagara_irq.inr = FICTIONAL_INR;
-	niagara_irq.claim = niagara_claim;
-	niagara_irq.handler = niagara_irq_handler;
-	irq_register(&niagara_irq);
-	
-	sysinfo_set_item_val("kbd", NULL, true);
-	sysinfo_set_item_val("kbd.type", NULL, KBD_SUN4V);
-	sysinfo_set_item_val("kbd.devno", NULL, devno);
-	sysinfo_set_item_val("kbd.inr", NULL, FICTIONAL_INR);
-	#endif
-
-	/*
-	 * Set sysinfos and pareas so that the userspace counterpart of the
-	 * niagara fb driver can communicate with kernel using a shared buffer.
- 	 */
-	//output_buffer.read_ptr = 0;
-	//output_buffer.write_ptr = 0;
-
-	#if 0
-	sysinfo_set_item_val("niagara.outbuf.address", NULL,
-		KA2PA(&output_buffer));
-	sysinfo_set_item_val("niagara.outbuf.size", NULL,
-		PAGE_SIZE);
-	sysinfo_set_item_val("niagara.outbuf.datasize", NULL,
-		OUTPUT_BUFFER_SIZE);
-	static parea_t outbuf_parea;
-	outbuf_parea.pbase = (uintptr_t) (KA2PA(&output_buffer));
-	outbuf_parea.vbase = (uintptr_t) (&output_buffer);
-	outbuf_parea.frames = 1;
-	outbuf_parea.cacheable = false;
-	ddi_parea_register(&outbuf_parea);
-
-	#endif
+	static parea_t inbuf_parea;
+	inbuf_parea.pbase = (uintptr_t) (KA2PA(&input_buffer));
+	inbuf_parea.frames = 1;
+	ddi_parea_register(&inbuf_parea);
 
 	outdev_t *niagara_dev = malloc(sizeof(outdev_t), FRAME_ATOMIC);
Index: uspace/lib/libc/arch/sparc64/src/thread_entry.s
===================================================================
--- uspace/lib/libc/arch/sparc64/src/thread_entry.s	(revision eeb643ddb3783861fb3ee6f341c31c048865cfe1)
+++ uspace/lib/libc/arch/sparc64/src/thread_entry.s	(revision 86018c11a1e682f179cb1ce268bf18b901b8a78b)
@@ -38,7 +38,9 @@
 	# Create the first stack frame.
 	#
-	save %sp, -176, %sp
-	flushw
-	add %g0, -0x7ff, %fp
+
+	# MH
+	#save %sp, -176, %sp
+	#flushw
+	#add %g0, -0x7ff, %fp
 
 	sethi %hi(_gp), %l7
Index: uspace/lib/libc/generic/thread.c
===================================================================
--- uspace/lib/libc/generic/thread.c	(revision eeb643ddb3783861fb3ee6f341c31c048865cfe1)
+++ uspace/lib/libc/generic/thread.c	(revision 86018c11a1e682f179cb1ce268bf18b901b8a78b)
@@ -41,4 +41,5 @@
 #include <string.h>
 #include <async.h>
+#include <stdio.h>
 
 #ifndef THREAD_INITIAL_STACK_PAGES_NO
@@ -62,4 +63,6 @@
 	__tcb_set(f->tcb);
 
+	// MH
+	printf("uarg: %lx\n", uarg);
 	uarg->uspace_thread_function(uarg->uspace_thread_arg);
 	/* XXX: we cannot free the userspace stack while running on it */
Index: uspace/srv/hid/kbd/port/niagara.c
===================================================================
--- uspace/srv/hid/kbd/port/niagara.c	(revision eeb643ddb3783861fb3ee6f341c31c048865cfe1)
+++ uspace/srv/hid/kbd/port/niagara.c	(revision 86018c11a1e682f179cb1ce268bf18b901b8a78b)
@@ -47,6 +47,28 @@
 #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.
+ * Keep in sync with the definition from
+ * kernel/arch/sparc64/src/drivers/niagara.c.
+ */
+#define INPUT_BUFFER_SIZE	((PAGE_SIZE) - 2 * 8)
+typedef volatile struct {
+	uint64_t write_ptr;
+	uint64_t read_ptr;
+	char data[INPUT_BUFFER_SIZE];
+}
+	__attribute__ ((packed))
+	__attribute__ ((aligned(PAGE_SIZE)))
+	*input_buffer_t;
+
+input_buffer_t input_buffer;
+
 static volatile bool polling_disabled = false;
-//static void *niagara_thread_impl(void *arg);
+static void *niagara_thread_impl(void *arg);
 
 /**
@@ -56,6 +78,17 @@
 int kbd_port_init(void)
 {
-	printf("****************** Niagara keyboard driver **********************\n");
-	/*
+	input_buffer_addr = (uintptr_t) as_get_mappable_page(PAGE_SIZE);
+	int result = physmem_map(
+		(void *) sysinfo_value("niagara.inbuf.address"),
+		(void *) input_buffer_addr,
+		1, AS_AREA_READ | AS_AREA_WRITE);
+
+	if (result != 0) {
+		printf("Niagara: uspace driver couldn't map physical memory: %d\n",
+			result);
+	}
+
+	input_buffer = (input_buffer_t) input_buffer_addr;
+
 	thread_id_t tid;
 	int rc;
@@ -65,5 +98,4 @@
 		return rc;
 	}
-	*/
 	return 0;
 }
@@ -90,25 +122,12 @@
 static void niagara_key_pressed(void)
 {
-	printf("%s\n", "polling");
-/*
 	char c;
 	
-	uint32_t begin = SGCN_BUFFER_HEADER->in_begin;
-	uint32_t end = SGCN_BUFFER_HEADER->in_end;
-	uint32_t size = end - begin;
-	
-	volatile char *buf_ptr = (volatile char *)
-		SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
-	volatile uint32_t *in_wrptr_ptr = &(SGCN_BUFFER_HEADER->in_wrptr);
-	volatile uint32_t *in_rdptr_ptr = &(SGCN_BUFFER_HEADER->in_rdptr);
-	
-	while (*in_rdptr_ptr != *in_wrptr_ptr) {
-		c = *buf_ptr;
-		*in_rdptr_ptr = (((*in_rdptr_ptr) - begin + 1) % size) + begin;
-		buf_ptr = (volatile char *)
-			SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
+	while (input_buffer->read_ptr != input_buffer->write_ptr) {
+		c = input_buffer->data[input_buffer->read_ptr];
+		input_buffer->read_ptr =
+			((input_buffer->read_ptr) + 1) % INPUT_BUFFER_SIZE;
 		kbd_push_scancode(c);
 	}
-*/
 }
 
@@ -116,5 +135,4 @@
  * Thread to poll SGCN for keypresses.
  */
-/*
 static void *niagara_thread_impl(void *arg)
 {
@@ -128,5 +146,4 @@
 	return 0;
 }
-*/
 /** @}
  */
