Index: kernel/arch/sparc64/Makefile.inc
===================================================================
--- kernel/arch/sparc64/Makefile.inc	(revision ec2c55a4c241975f1e193ce31dbbbe525c29fdf1)
+++ kernel/arch/sparc64/Makefile.inc	(revision f9a56c06291b17dff86c61d294ec807828f33f96)
@@ -67,5 +67,5 @@
 
 	CONFIG_Z8530 = y
-	DEFS += -DCONFIG_Z8530
+	DEFS += -DCONFIG_Z8530	
 endif
 ifeq ($(MACHINE),ultra)
@@ -102,2 +102,7 @@
 	arch/$(ARCH)/src/drivers/tick.c \
 	arch/$(ARCH)/src/drivers/kbd.c
+
+ifdef CONFIG_Z8530
+ARCH_SOURCES += \
+	arch/$(ARCH)/src/drivers/fhc.c
+endif
Index: kernel/arch/sparc64/include/asm.h
===================================================================
--- kernel/arch/sparc64/include/asm.h	(revision ec2c55a4c241975f1e193ce31dbbbe525c29fdf1)
+++ kernel/arch/sparc64/include/asm.h	(revision f9a56c06291b17dff86c61d294ec807828f33f96)
@@ -140,4 +140,15 @@
 }
 
+/** Write SET_SOFTINT Register.
+ *
+ * Bits set in SET_SOFTINT register will be set in SOFTINT register.
+ *
+ * @param v New value of SET_SOFTINT register.
+ */
+static inline void set_softint_write(uint64_t v)
+{
+	__asm__ volatile ("wr %0, %1, %%set_softint\n" : : "r" (v), "i" (0));
+}
+
 /** Enable interrupts.
  *
Index: kernel/arch/sparc64/include/drivers/fhc.h
===================================================================
--- kernel/arch/sparc64/include/drivers/fhc.h	(revision f9a56c06291b17dff86c61d294ec807828f33f96)
+++ kernel/arch/sparc64/include/drivers/fhc.h	(revision f9a56c06291b17dff86c61d294ec807828f33f96)
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup sparc64	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc64_FHC_H_
+#define KERN_sparc64_FHC_H_
+
+#include <arch/types.h>
+
+extern volatile uint32_t *fhc;
+
+extern void fhc_init(void);
+extern void fhc_uart_reset(void);
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc64/include/drivers/ns16550.h
===================================================================
--- kernel/arch/sparc64/include/drivers/ns16550.h	(revision ec2c55a4c241975f1e193ce31dbbbe525c29fdf1)
+++ kernel/arch/sparc64/include/drivers/ns16550.h	(revision f9a56c06291b17dff86c61d294ec807828f33f96)
@@ -40,4 +40,5 @@
 
 #define RBR_REG		0	/** Receiver Buffer Register. */
+#define IER_REG		1	/** Interrupt Enable Register. */
 #define LSR_REG		5	/** Line Status Register. */
 
@@ -45,4 +46,14 @@
 {
 	return kbd_virt_address[RBR_REG];
+}
+
+static inline uint8_t ns16550_ier_read(void)
+{
+	return kbd_virt_address[IER_REG];
+}
+
+static inline void ns16550_ier_write(uint8_t v)
+{
+	kbd_virt_address[IER_REG] = v;
 }
 
Index: kernel/arch/sparc64/include/drivers/z8530.h
===================================================================
--- kernel/arch/sparc64/include/drivers/z8530.h	(revision ec2c55a4c241975f1e193ce31dbbbe525c29fdf1)
+++ kernel/arch/sparc64/include/drivers/z8530.h	(revision f9a56c06291b17dff86c61d294ec807828f33f96)
@@ -71,4 +71,7 @@
 #define RR15	15
 
+/* Write Register 0 */
+#define WR0_ERR_RST	(0x6<<3)
+
 /* Write Register 1 */
 #define WR1_RID		(0x0<<3)	/** Receive Interrupts Disabled. */
Index: kernel/arch/sparc64/include/mm/mmu.h
===================================================================
--- kernel/arch/sparc64/include/mm/mmu.h	(revision ec2c55a4c241975f1e193ce31dbbbe525c29fdf1)
+++ kernel/arch/sparc64/include/mm/mmu.h	(revision f9a56c06291b17dff86c61d294ec807828f33f96)
@@ -36,8 +36,8 @@
 #define __sparc64_MMU_H__
 
-/** LSU Control Register ASI. */
+/* LSU Control Register ASI. */
 #define ASI_LSU_CONTROL_REG		0x45	/**< Load/Store Unit Control Register. */
 
-/** I-MMU ASIs. */
+/* I-MMU ASIs. */
 #define ASI_IMMU			0x50
 #define ASI_IMMU_TSB_8KB_PTR_REG	0x51	
@@ -48,5 +48,5 @@
 #define ASI_IMMU_DEMAP			0x57
 
-/** Virtual Addresses within ASI_IMMU. */
+/* Virtual Addresses within ASI_IMMU. */
 #define VA_IMMU_TAG_TARGET		0x0	/**< IMMU tag target register. */
 #define VA_IMMU_SFSR			0x18	/**< IMMU sync fault status register. */
@@ -54,5 +54,5 @@
 #define VA_IMMU_TAG_ACCESS		0x30	/**< IMMU TLB tag access register. */
 
-/** D-MMU ASIs. */
+/* D-MMU ASIs. */
 #define ASI_DMMU			0x58
 #define ASI_DMMU_TSB_8KB_PTR_REG	0x59	
@@ -64,5 +64,5 @@
 #define ASI_DMMU_DEMAP			0x5f
 
-/** Virtual Addresses within ASI_DMMU. */
+/* Virtual Addresses within ASI_DMMU. */
 #define VA_DMMU_TAG_TARGET		0x0	/**< DMMU tag target register. */
 #define VA_PRIMARY_CONTEXT_REG		0x8	/**< DMMU primary context register. */
Index: kernel/arch/sparc64/include/trap/interrupt.h
===================================================================
--- kernel/arch/sparc64/include/trap/interrupt.h	(revision ec2c55a4c241975f1e193ce31dbbbe525c29fdf1)
+++ kernel/arch/sparc64/include/trap/interrupt.h	(revision f9a56c06291b17dff86c61d294ec807828f33f96)
@@ -41,4 +41,20 @@
 #include <arch/stack.h>
 
+/* Interrupt ASI registers. */
+#define ASI_UDB_INTR_W			0x77
+#define ASI_INTR_DISPATCH_STATUS	0x48
+#define ASI_UDB_INTR_R			0x7f
+#define ASI_INTR_RECEIVE		0x49
+
+/* VA's used with ASI_UDB_INTR_W register. */
+#define ASI_UDB_INTR_W_DATA_0	0x40
+#define ASI_UDB_INTR_W_DATA_1	0x50
+#define ASI_UDB_INTR_W_DATA_2	0x60
+
+/* VA's used with ASI_UDB_INTR_R register. */
+#define ASI_UDB_INTR_R_DATA_0	0x40
+#define ASI_UDB_INTR_R_DATA_1	0x50
+#define ASI_UDB_INTR_R_DATA_2	0x60
+
 #define TT_INTERRUPT_LEVEL_1			0x41
 #define TT_INTERRUPT_LEVEL_2			0x42
@@ -71,7 +87,14 @@
 
 .macro INTERRUPT_VECTOR_TRAP_HANDLER
+	save %sp, -STACK_WINDOW_SAVE_AREA_SIZE, %sp
+	SIMPLE_HANDLER interrupt
+	restore
 	retry
 .endm
 #endif /* __ASM__ */
+
+#ifndef __ASM__
+extern void interrupt(void);
+#endif /* !def __ASM__ */
 
 #endif
Index: kernel/arch/sparc64/src/console.c
===================================================================
--- kernel/arch/sparc64/src/console.c	(revision ec2c55a4c241975f1e193ce31dbbbe525c29fdf1)
+++ kernel/arch/sparc64/src/console.c	(revision f9a56c06291b17dff86c61d294ec807828f33f96)
@@ -85,5 +85,5 @@
 	while (1) {
 #ifdef CONFIG_Z8530
-		z8530_poll();
+		return;
 #endif
 #ifdef CONFIG_NS16550
Index: kernel/arch/sparc64/src/drivers/fhc.c
===================================================================
--- kernel/arch/sparc64/src/drivers/fhc.c	(revision f9a56c06291b17dff86c61d294ec807828f33f96)
+++ kernel/arch/sparc64/src/drivers/fhc.c	(revision f9a56c06291b17dff86c61d294ec807828f33f96)
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup sparc64
+ * @{
+ */
+/**
+ * @file
+ * @brief	FireHose Controller (FHC) driver.
+ *
+ * Note that this driver is a result of reverse engineering
+ * rather than implementation of a specification. This
+ * is due to the fact that the FHC documentation is not
+ * publicly available.
+ */
+
+#include <arch/drivers/fhc.h>
+#include <arch/mm/page.h>
+#include <arch/types.h>
+#include <typedefs.h>
+
+#include <genarch/kbd/z8530.h>
+
+volatile uint32_t *fhc = NULL;
+
+#define FHC_UART_ADDR	0x1fff8808000ULL		/* hardcoded for Simics simulation */
+
+#define FHC_UART_IMAP	0x0
+#define FHC_UART_ICLR	0x4
+
+void fhc_init(void)
+{
+	fhc = (void *) hw_map(FHC_UART_ADDR, PAGE_SIZE);
+
+	(void) fhc[FHC_UART_ICLR];
+	fhc[FHC_UART_ICLR] = 0;
+	(void) fhc[FHC_UART_IMAP];
+	fhc[FHC_UART_IMAP] = Z8530_INTRCV_DATA0;	/* hardcoded for Simics simulation */
+	(void) fhc[FHC_UART_IMAP];
+	fhc[FHC_UART_IMAP] = 0x80000000;		/* hardcoded for Simics simulation */
+}
+
+void fhc_uart_reset(void)
+{
+	(void) fhc[FHC_UART_ICLR];
+	fhc[FHC_UART_ICLR] = 0;
+}
+
+/** @}
+ */
Index: kernel/arch/sparc64/src/drivers/kbd.c
===================================================================
--- kernel/arch/sparc64/src/drivers/kbd.c	(revision ec2c55a4c241975f1e193ce31dbbbe525c29fdf1)
+++ kernel/arch/sparc64/src/drivers/kbd.c	(revision f9a56c06291b17dff86c61d294ec807828f33f96)
@@ -61,5 +61,5 @@
 	 * However, the physical keyboard address can
 	 * be pretty much unaligned on some systems
-	 * (e.g. Ultra 5, Ultras 60).
+	 * (e.g. Ultra 5, Ultra 60).
 	 */
 	aligned_addr = ALIGN_DOWN(bootinfo.keyboard.addr, PAGE_SIZE);
Index: kernel/arch/sparc64/src/drivers/tick.c
===================================================================
--- kernel/arch/sparc64/src/drivers/tick.c	(revision ec2c55a4c241975f1e193ce31dbbbe525c29fdf1)
+++ kernel/arch/sparc64/src/drivers/tick.c	(revision f9a56c06291b17dff86c61d294ec807828f33f96)
@@ -27,5 +27,5 @@
  */
 
- /** @addtogroup sparc64	
+/** @addtogroup sparc64	
  * @{
  */
@@ -89,5 +89,4 @@
 }
 
- /** @}
+/** @}
  */
-
Index: kernel/arch/sparc64/src/trap/interrupt.c
===================================================================
--- kernel/arch/sparc64/src/trap/interrupt.c	(revision ec2c55a4c241975f1e193ce31dbbbe525c29fdf1)
+++ kernel/arch/sparc64/src/trap/interrupt.c	(revision f9a56c06291b17dff86c61d294ec807828f33f96)
@@ -34,8 +34,14 @@
 
 #include <arch/interrupt.h>
+#include <arch/trap/interrupt.h>
 #include <interrupt.h>
+#include <arch/drivers/fhc.h>
 #include <arch/types.h>
 #include <debug.h>
 #include <ipc/sysipc.h>
+#include <arch/asm.h>
+#include <arch/barrier.h>
+
+#include <genarch/kbd/z8530.h>
 
 /** Register Interrupt Level Handler.
@@ -59,5 +65,32 @@
 }
 
+void interrupt(void)
+{
+	uint64_t intrcv;
+	uint64_t data0;
+
+	intrcv = asi_u64_read(ASI_INTR_RECEIVE, 0);
+	data0 = asi_u64_read(ASI_UDB_INTR_R, ASI_UDB_INTR_R_DATA_0);
+
+	switch (data0) {
+#ifdef CONFIG_Z8530
+	case Z8530_INTRCV_DATA0:
+		/*
+		 * So far, we know we got this interrupt through the FHC.
+		 * Since we don't have enough information about the FHC and
+		 * because the interrupt looks like level sensitive,
+		 * we cannot handle it by scheduling one of the level
+		 * interrupt traps. Call the interrupt handler directly.
+		 */
+		fhc_uart_reset();
+		z8530_interrupt();
+		break;
+#endif
+	}
+
+	membar();
+	asi_u64_write(ASI_INTR_RECEIVE, 0, 0);
+}
+
 /** @}
  */
-
Index: kernel/doc/arch/sparc64
===================================================================
--- kernel/doc/arch/sparc64	(revision ec2c55a4c241975f1e193ce31dbbbe525c29fdf1)
+++ kernel/doc/arch/sparc64	(revision f9a56c06291b17dff86c61d294ec807828f33f96)
@@ -7,2 +7,18 @@
 The goal is to provide support for UltraSPARC
 implementation of SPARC V9 architecture.
+
+MACHINES
+	o Sun Ultra 5
+	o Sun Enterprise E6500 (simulated)
+		
+CPU
+	o UltraSPARC II
+	o UltraSPARC IIi
+
+SIMULATORS
+	o simics 2.2.19, simics 3.0.17
+						
+TOOLCHAIN REQUIREMENTS
+	o binutils 2.17
+	o gcc 4.1.1
+	o older versions may do as well, but are now obsoleted
Index: kernel/genarch/include/kbd/z8530.h
===================================================================
--- kernel/genarch/include/kbd/z8530.h	(revision ec2c55a4c241975f1e193ce31dbbbe525c29fdf1)
+++ kernel/genarch/include/kbd/z8530.h	(revision f9a56c06291b17dff86c61d294ec807828f33f96)
@@ -38,8 +38,11 @@
 #define KERN_Z8530_H_
 
+#define Z8530_INTRCV_DATA0	0x39	/* hardcoded for use in Simics */
+
 extern void z8530_init(void);
 extern void z8530_poll(void);
 extern void z8530_grab(void);
 extern void z8530_release(void);
+extern void z8530_interrupt(void);
 
 #endif
Index: kernel/genarch/src/kbd/z8530.c
===================================================================
--- kernel/genarch/src/kbd/z8530.c	(revision ec2c55a4c241975f1e193ce31dbbbe525c29fdf1)
+++ kernel/genarch/src/kbd/z8530.c	(revision f9a56c06291b17dff86c61d294ec807828f33f96)
@@ -39,6 +39,6 @@
 #include <genarch/kbd/scanc.h>
 #include <genarch/kbd/scanc_sun.h>
+#include <arch/drivers/fhc.h>
 #include <arch/drivers/z8530.h>
-#include <arch/drivers/kbd.h>
 #include <arch/interrupt.h>
 #include <cpu.h>
@@ -65,5 +65,4 @@
 };
 
-void z8530_interrupt(int n, istate_t *istate);
 void z8530_wait(void);
 
@@ -72,10 +71,9 @@
 {
 }
+
 /** Resume the former interrupt vector */
 void z8530_release(void)
 {
 }
-
-#include <print.h>
 
 /** Initialize z8530. */
@@ -85,6 +83,7 @@
 	stdin = &kbrd;
 
+	(void) z8530_read_a(RR8);
+
 	z8530_write_a(WR1, WR1_IARCSC);	/* interrupt on all characters */
-	z8530_write_a(WR2, 12);		/* FIXME: IRQ12 ??? */
 
 	/* 8 bits per character and enable receiver */
@@ -92,4 +91,12 @@
 	
 	z8530_write_a(WR9, WR9_MIE);	/* Master Interrupt Enable. */
+	
+	/*
+	 * We need to initialize the FireHose Controller,
+	 * to which is this z8530 attached. Otherwise
+	 * interrupts generated by the z8530 would not
+	 * be forwarded to the CPU.
+	 */
+	fhc_init();
 }
 
@@ -99,6 +106,7 @@
  * @param istate Interrupted state.
  */
-void z8530_interrupt(int n, istate_t *istate)
+void z8530_interrupt(void)
 {
+	z8530_poll();
 }
 
