Index: .bzrignore
===================================================================
--- .bzrignore	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ .bzrignore	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -33,5 +33,5 @@
 uspace/app/kill/kill
 uspace/app/killall/killall
-uspace/app/klog/klog
+uspace/app/kio/kio
 uspace/app/loc/loc
 uspace/app/logset/logset
@@ -82,5 +82,5 @@
 uspace/dist/app/kill
 uspace/dist/app/killall
-uspace/dist/app/klog
+uspace/dist/app/kio
 uspace/dist/app/loc
 uspace/dist/app/logset
@@ -279,2 +279,10 @@
 uspace/app/viewer/viewer
 uspace/dist/app/viewer
+uspace/app/hdisk/hdisk
+uspace/dist/app/hdisk
+uspace/app/untar/untar
+uspace/dist/app/untar
+uspace/lib/posix/redefs-hide-libc-symbols.list
+uspace/lib/posix/redefs-show-posix-symbols.list
+uspace/srv/klog/klog
+uspace/dist/srv/klog
Index: HelenOS.config
===================================================================
--- HelenOS.config	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ HelenOS.config	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -32,12 +32,13 @@
 % Platform
 @ "abs32le" abstract 32-bit little endian
-@ "amd64" AMD64/Intel EM64T (PC)
+@ "amd64" AMD64/EM64T 64-bit (PC)
 @ "arm32" ARM 32-bit
-@ "ia32" Intel IA-32 (PC)
-@ "ia64" Intel IA-64
+@ "ia32" IA-32 32-bit (PC)
+@ "ia64" IA-64 64-bit
 @ "mips32" MIPS 32-bit
 @ "mips64" MIPS 64-bit
-@ "ppc32" PowerPC 32-bit (iMac G4)
-@ "sparc64" Sun UltraSPARC 64-bit
+@ "ppc32" PowerPC 32-bit
+@ "sparc32" SPARCv8 32-bit
+@ "sparc64" SPARCv9 64-bit
 ! PLATFORM (choice)
 
@@ -62,8 +63,13 @@
 
 % Machine type
+@ "leon3" Gaisler Aeroflex LEON3
+! [PLATFORM=sparc32] MACHINE (choice)
+
+% Machine type
 @ "gta02" GTA02 / Neo FreeRunner
 @ "integratorcp" Integratorcp
 @ "beagleboardxm" BeagleBoard-xM
 @ "beaglebone" BeagleBone
+@ "raspberrypi" Raspberry Pi
 ! [PLATFORM=arm32] MACHINE (choice)
 
@@ -82,4 +88,8 @@
 
 % CPU type
+@ "leon3" Gaisler Aeroflex LEON3
+! [PLATFORM=sparc32&MACHINE=leon3] PROCESSOR (choice)
+
+% CPU type
 @ "us" UltraSPARC I-II subarchitecture
 @ "us3" UltraSPARC III-IV subarchitecture
@@ -99,4 +109,7 @@
 ! [PLATFORM=arm32&MACHINE=integratorcp] PROCESSOR (choice)
 
+% CPU type
+@ "arm1176" ARM1176
+! [PLATFORM=arm32&MACHINE=raspberrypi] PROCESSOR (choice)
 
 # Add more ARMv4 CPUs
@@ -109,4 +122,9 @@
 @ "armv5" ARMv5
 ! [PLATFORM=arm32&(PROCESSOR=arm926ej_s)] PROCESSOR_ARCH (choice)
+
+# Add more ARMv6 CPUs
+% CPU arch
+@ "armv6" ARMv6
+! [PLATFORM=arm32&(PROCESSOR=arm1176)] PROCESSOR_ARCH (choice)
 
 # Add more ARMv7-A CPUs
@@ -173,4 +191,8 @@
 
 % Kernel architecture
+@ "sparc32"
+! [PLATFORM=sparc32] KARCH (choice)
+
+% Kernel architecture
 @ "sparc64"
 ! [PLATFORM=sparc64] KARCH (choice)
@@ -220,4 +242,8 @@
 
 % User space architecture
+@ "sparc32"
+! [PLATFORM=sparc32] UARCH (choice)
+
+% User space architecture
 @ "sparc64"
 ! [PLATFORM=sparc64] UARCH (choice)
@@ -265,4 +291,8 @@
 @ "ppc64"
 ! [PLATFORM=ppc64] BARCH (choice)
+
+% Boot architecture
+@ "sparc32"
+! [PLATFORM=sparc32] BARCH (choice)
 
 % Boot architecture
@@ -314,5 +344,5 @@
 @ "gcc_helenos" GNU C Compiler (experimental HelenOS-specific cross-compiler)
 @ "clang" Clang
-! [PLATFORM=abs32le|PLATFORM=arm32|PLATFORM=sparc64] COMPILER (choice)
+! [PLATFORM=abs32le|PLATFORM=arm32|PLATFORM=sparc32|PLATFORM=sparc64] COMPILER (choice)
 
 
@@ -341,5 +371,5 @@
 
 % Hierarchical page tables support
-! [PLATFORM=abs32le|PLATFORM=ia32|PLATFORM=amd64|PLATFORM=arm32|PLATFORM=mips32|PLATFORM=ppc32] CONFIG_PAGE_PT (y)
+! [PLATFORM=abs32le|PLATFORM=ia32|PLATFORM=amd64|PLATFORM=arm32|PLATFORM=mips32|PLATFORM=ppc32|PLATFORM=sparc32] CONFIG_PAGE_PT (y)
 
 % Page hash table support
@@ -347,11 +377,11 @@
 
 % Software integer division support
-! [PLATFORM=abs32le|PLATFORM=ia32|PLATFORM=arm32|PLATFORM=ia64|PLATFORM=mips32|PLATFORM=mips64|PLATFORM=ppc32] CONFIG_SOFTINT (y)
+! [PLATFORM=abs32le|PLATFORM=ia32|PLATFORM=arm32|PLATFORM=ia64|PLATFORM=mips32|PLATFORM=mips64|PLATFORM=ppc32|PLATFORM=sparc32] CONFIG_SOFTINT (y)
 
 % ASID support
-! [PLATFORM=ia64|PLATFORM=mips32|PLATFORM=mips64|PLATFORM=ppc32|PLATFORM=sparc64] CONFIG_ASID (y)
+! [PLATFORM=ia64|PLATFORM=mips32|PLATFORM=mips64|PLATFORM=ppc32|PLATFORM=sparc32|PLATFORM=sparc64] CONFIG_ASID (y)
 
 % ASID FIFO support
-! [PLATFORM=ia64|PLATFORM=mips32|PLATFORM=mips64|PLATFORM=ppc32|PLATFORM=sparc64] CONFIG_ASID_FIFO (y)
+! [PLATFORM=ia64|PLATFORM=mips32|PLATFORM=mips64|PLATFORM=ppc32|PLATFORM=sparc32|PLATFORM=sparc64] CONFIG_ASID_FIFO (y)
 
 % OpenFirmware tree support
@@ -446,5 +476,5 @@
 % Output device class
 @ "generic" Monitor or serial line
-! [PLATFORM=arm32&(MACHINE=gta02|MACHINE=integratorcp|MACHINE=beagleboardxm|MACHINE=beaglebone)] CONFIG_HID_OUT (choice)
+! [PLATFORM=arm32&(MACHINE=gta02|MACHINE=integratorcp|MACHINE=beagleboardxm|MACHINE=beaglebone|MACHINE=raspberrypi)] CONFIG_HID_OUT (choice)
 
 % Output device class
@@ -477,6 +507,6 @@
 ! [(CONFIG_HID_IN=generic|CONFIG_HID_IN=serial)&PLATFORM=ia64&MACHINE=i460GX] CONFIG_NS16550 (y/n)
 
-% Support for ARM926 on-chip UART
-! [(CONFIG_HID_OUT=generic|CONFIG_HID_OUT=serial)&PLATFORM=arm32&MACHINE=integratorcp] CONFIG_ARM926_UART (y/n)
+% Support for PL011 UART
+! [(CONFIG_HID_OUT=generic|CONFIG_HID_OUT=serial)&PLATFORM=arm32&(MACHINE=integratorcp|MACHINE=raspberrypi)] CONFIG_PL011_UART (y/n)
 
 % Support for Samsung S3C24XX on-chip UART
@@ -492,4 +522,13 @@
 ! [(CONFIG_HID_OUT=generic|CONFIG_HID_OUT=serial)&PLATFORM=arm32&(MACHINE=beagleboardxm|MACHINE=beaglebone)] CONFIG_OMAP_UART (y/n)
 
+% Support for GRLIB UART
+! [PLATFORM=sparc32&MACHINE=leon3] CONFIG_GRLIB_UART (y)
+
+% Support for GRLIB IRQMP
+! [PLATFORM=sparc32&MACHINE=leon3] CONFIG_GRLIB_IRQMP (y)
+
+% Support for BCM2835 mailbox
+! [PLATFORM=arm32&MACHINE=raspberrypi] CONFIG_BCM2835_MAILBOX (y/n)
+
 % Support for i8042 controller
 ! [CONFIG_PC_KBD=y] CONFIG_I8042 (y)
@@ -511,5 +550,5 @@
 
 % Serial line input module
-! [CONFIG_DSRLNIN=y|(PLATFORM=arm32&MACHINE=gta02)|(PLATFORM=arm32&MACHINE=integratorcp&CONFIG_ARM926_UART=y)|(PLATFORM=arm32&MACHINE=beaglebone&CONFIG_OMAP_UART=y)|(PLATFORM=arm32&MACHINE=beagleboardxm&CONFIG_OMAP_UART=y)|(PLATFORM=ia64&MACHINE=i460GX&CONFIG_NS16550=y)|(PLATFORM=ia64&MACHINE=ski)|(PLATFORM=sparc64&PROCESSOR=sun4v)] CONFIG_SRLN (y)
+! [CONFIG_DSRLNIN=y|(PLATFORM=sparc32)|(PLATFORM=arm32&MACHINE=gta02)|(PLATFORM=arm32&MACHINE=integratorcp&CONFIG_PL011_UART=y)|(PLATFORM=arm32&MACHINE=beaglebone&CONFIG_OMAP_UART=y)|(PLATFORM=arm32&MACHINE=beagleboardxm&CONFIG_OMAP_UART=y)|(PLATFORM=ia64&MACHINE=i460GX&CONFIG_NS16550=y)|(PLATFORM=ia64&MACHINE=ski)|(PLATFORM=sparc64&PROCESSOR=sun4v)|(PLATFORM=arm32&MACHINE=raspberrypi&CONFIG_PL011_UART=y)] CONFIG_SRLN (y)
 
 % EGA support
@@ -626,2 +665,6 @@
 @ "5" Linux kernel
 ! [PLATFORM=arm32&MACHINE!=beagleboardxm&MACHINE!=beaglebone] UIMAGE_OS (choice)
+
+% uImage OS type
+@ "5" Linux kernel
+! [PLATFORM=sparc32] UIMAGE_OS (choice)
Index: abi/include/abi/ipc/event.h
===================================================================
--- abi/include/abi/ipc/event.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ abi/include/abi/ipc/event.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -38,10 +38,12 @@
 /** Global events */
 typedef enum event_type {
-	/** New data available in kernel log */
-	EVENT_KLOG = 0,
+	/** New data available in kernel character buffer */
+	EVENT_KIO = 0,
 	/** Returning from kernel console to uspace */
 	EVENT_KCONSOLE,
 	/** A task/thread has faulted and will be terminated */
 	EVENT_FAULT,
+	/** New data available in kernel log */
+	EVENT_KLOG,
 	EVENT_END
 } event_type_t;
Index: abi/include/abi/kio.h
===================================================================
--- abi/include/abi/kio.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ abi/include/abi/kio.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2012 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 generic
+ * @{
+ */
+/** @file
+ */
+
+#ifndef ABI_KIO_H_
+#define ABI_KIO_H_
+
+enum {
+	KIO_UNKNOW,
+	KIO_WRITE,
+	KIO_UPDATE,
+	KIO_COMMAND
+};
+
+#endif
+
+/** @}
+ */
Index: abi/include/abi/klog.h
===================================================================
--- abi/include/abi/klog.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ abi/include/abi/klog.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2012 Jakub Jermar
+ * Copyright (c) 2014 Martin Sucha
  * All rights reserved.
  *
@@ -36,10 +36,8 @@
 #define ABI_KLOG_H_
 
-enum {
-	KLOG_UNKNOW,
+typedef enum {
 	KLOG_WRITE,
-	KLOG_UPDATE,
-	KLOG_COMMAND
-};
+	KLOG_READ
+} klog_operation_t;
 
 #endif
Index: abi/include/abi/log.h
===================================================================
--- abi/include/abi/log.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ abi/include/abi/log.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2011 Vojtech Horky
+ * Copyright (c) 2011 Jiri Svoboda
+ * Copyright (c) 2013 Martin Sucha
+ * 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 genericlog
+ * @{
+ */
+/** @file
+ */
+
+#ifndef ABI_LOG_H_
+#define ABI_LOG_H_
+
+/** Log message level. */
+typedef enum {
+	/** Fatal error, program is not able to recover at all. */
+	LVL_FATAL,
+	/** Serious error but the program can recover from it. */
+	LVL_ERROR,
+	/** Easily recoverable problem. */
+	LVL_WARN,
+	/** Information message that ought to be printed by default. */
+	LVL_NOTE,
+	/** Debugging purpose message. */
+	LVL_DEBUG,
+	/** More detailed debugging message. */
+	LVL_DEBUG2,
+	
+	/** For checking range of values */
+	LVL_LIMIT
+} log_level_t;
+
+/* Who is the source of the message? */
+typedef enum {
+	LF_OTHER = 0,
+	LF_USPACE,
+	LF_ARCH
+} log_facility_t;
+
+#endif
+
+/** @}
+ */
Index: abi/include/abi/syscall.h
===================================================================
--- abi/include/abi/syscall.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ abi/include/abi/syscall.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -37,5 +37,5 @@
 
 typedef enum {
-	SYS_KLOG = 0,
+	SYS_KIO = 0,
 	SYS_TLS_SET = 1,  /* Hardcoded for AMD64, IA-32 (fibril.S in uspace) */
 	
@@ -99,4 +99,6 @@
 	SYS_DEBUG_ACTIVATE_CONSOLE,
 	
+	SYS_KLOG,
+	
 	SYSCALL_END
 } syscall_t;
Index: boot/Makefile
===================================================================
--- boot/Makefile	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ boot/Makefile	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -80,4 +80,7 @@
 		cp "$(USPACE_PATH)/$(DRVS_PATH)/$$file_dir/$$file_name/$$file_name.dev" "$(DIST_PATH)/$(DRVS_PATH)/$$file_name/" ; \
 	done
+	if ls $(DIST_OVERLAY_PATH)/* >/dev/null; then \
+		cp -r -L $(DIST_OVERLAY_PATH)/* "$(DIST_PATH)"; \
+	fi
 
 clean: clean_dist
@@ -94,5 +97,5 @@
 	rm -f $(USPACE_PATH)/dist/srv/*
 	rm -rf $(USPACE_PATH)/dist/drv/*
-	rm -f $(USPACE_PATH)/dist/lib/*
+	rm -rf $(USPACE_PATH)/dist/lib/*
 	rm -rf $(USPACE_PATH)/dist/inc/*
 	rm -f $(USPACE_PATH)/dist/app/*
Index: boot/Makefile.common
===================================================================
--- boot/Makefile.common	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ boot/Makefile.common	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -48,4 +48,5 @@
 USPACE_PATH = $(ROOT_PATH)/uspace
 DIST_PATH = $(USPACE_PATH)/dist
+DIST_OVERLAY_PATH = $(USPACE_PATH)/overlay
 TOOLS_PATH = $(ROOT_PATH)/tools
 DRVS_PATH = drv
@@ -95,5 +96,6 @@
 	$(USPACE_PATH)/srv/devman/devman \
 	$(USPACE_PATH)/srv/fs/locfs/locfs \
-	$(USPACE_PATH)/srv/hid/compositor/compositor
+	$(USPACE_PATH)/srv/hid/compositor/compositor \
+	$(USPACE_PATH)/srv/klog/klog
 
 RD_SRVS_NON_ESSENTIAL = \
@@ -160,5 +162,5 @@
 	$(USPACE_PATH)/app/bdsh/bdsh \
 	$(USPACE_PATH)/app/getterm/getterm \
-	$(USPACE_PATH)/app/klog/klog \
+	$(USPACE_PATH)/app/kio/kio \
 	$(USPACE_PATH)/app/vlaunch/vlaunch \
 	$(USPACE_PATH)/app/vterm/vterm
@@ -177,4 +179,5 @@
 	$(USPACE_PATH)/app/download/download \
 	$(USPACE_PATH)/app/edit/edit \
+	$(USPACE_PATH)/app/hdisk/hdisk \
 	$(USPACE_PATH)/app/inet/inet \
 	$(USPACE_PATH)/app/kill/kill \
@@ -205,4 +208,5 @@
 	$(USPACE_PATH)/app/sysinfo/sysinfo \
 	$(USPACE_PATH)/app/top/top \
+	$(USPACE_PATH)/app/untar/untar \
 	$(USPACE_PATH)/app/usbinfo/usbinfo \
 	$(USPACE_PATH)/app/vuhid/vuh \
Index: boot/arch/arm32/Makefile.inc
===================================================================
--- boot/arch/arm32/Makefile.inc	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ boot/arch/arm32/Makefile.inc	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -43,4 +43,12 @@
 endif
 
+ifeq ($(MACHINE), raspberrypi)
+	BOOT_OUTPUT = image.boot
+	POST_OUTPUT = $(ROOT_PATH)/uImage.bin	
+	LADDR = 0x00008000
+	SADDR = 0x00008000
+	POSTBUILD = Makefile.uboot	     
+endif
+
 BFD_NAME = elf32-littlearm
 BFD_OUTPUT = $(BFD_NAME)
Index: boot/arch/arm32/include/arch.h
===================================================================
--- boot/arch/arm32/include/arch.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ boot/arch/arm32/include/arch.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -46,4 +46,6 @@
 #elif defined MACHINE_beaglebone
 #define BOOT_BASE       0x80000000
+#elif defined MACHINE_raspberrypi
+#define BOOT_BASE	0x00008000
 #else
 #define BOOT_BASE	0x00000000
Index: boot/arch/arm32/include/main.h
===================================================================
--- boot/arch/arm32/include/main.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ boot/arch/arm32/include/main.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -75,4 +75,24 @@
 #define ICP_SCONS_ADDR		0x16000000
 
+/** Raspberry PI serial console registers */
+#define BCM2835_UART0_BASE	0x20201000
+#define BCM2835_UART0_DR	(BCM2835_UART0_BASE + 0x00)
+#define BCM2835_UART0_FR	(BCM2835_UART0_BASE + 0x18)
+#define BCM2835_UART0_ILPR	(BCM2835_UART0_BASE + 0x20)
+#define BCM2835_UART0_IBRD	(BCM2835_UART0_BASE + 0x24)
+#define BCM2835_UART0_FBRD	(BCM2835_UART0_BASE + 0x28)
+#define BCM2835_UART0_LCRH	(BCM2835_UART0_BASE + 0x2C)
+#define BCM2835_UART0_CR	(BCM2835_UART0_BASE + 0x30)
+#define BCM2835_UART0_ICR	(BCM2835_UART0_BASE + 0x44)
+
+#define BCM2835_UART0_FR_TXFF	(1 << 5)
+#define BCM2835_UART0_LCRH_FEN	(1 << 4)
+#define BCM2835_UART0_LCRH_WL8	((1 << 5) | (1 << 6))
+#define BCM2835_UART0_CR_UARTEN	(1 << 0)
+#define BCM2835_UART0_CR_TXE	(1 << 8)
+#define BCM2835_UART0_CR_RXE	(1 << 9)
+
+
+
 extern void bootstrap(void);
 
Index: boot/arch/arm32/include/mm.h
===================================================================
--- boot/arch/arm32/include/mm.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ boot/arch/arm32/include/mm.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -68,4 +68,8 @@
 #define AM335x_RAM_END     0xC0000000
 
+/** Start of ram memory on BCM2835 */
+#define BCM2835_RAM_START   0
+/** End of ram memory on BCM2835 */
+#define BCM2835_RAM_END     0x20000000
 
 /* Page table level 0 entry - "section" format is used
Index: boot/arch/arm32/src/mm.c
===================================================================
--- boot/arch/arm32/src/mm.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ boot/arch/arm32/src/mm.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -116,4 +116,7 @@
 	if (address >= AM335x_RAM_START && address < AM335x_RAM_END)
 		return 1;
+#elif defined MACHINE_raspberrypi
+	if (address < BCM2835_RAM_END)
+		return 1;
 #endif
 	return address * 0;
Index: boot/arch/arm32/src/putchar.c
===================================================================
--- boot/arch/arm32/src/putchar.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ boot/arch/arm32/src/putchar.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -122,4 +122,46 @@
 #endif
 
+#ifdef MACHINE_raspberrypi
+
+static int raspi_init;
+
+static inline void write32(uint32_t addr, uint32_t data)
+{
+	*(volatile uint32_t *)(addr) = data;
+}
+
+static inline uint32_t read32(uint32_t addr)
+{
+	return *(volatile uint32_t *)(addr);
+}
+
+static void scons_init_raspi(void)
+{
+	write32(BCM2835_UART0_CR, 0x0);		/* Disable UART */
+	write32(BCM2835_UART0_ICR, 0x7f);	/* Clear interrupts */
+	write32(BCM2835_UART0_IBRD, 1);		/* Set integer baud rate */
+	write32(BCM2835_UART0_FBRD, 40);	/* Set fractional baud rate */
+	write32(BCM2835_UART0_LCRH,
+		BCM2835_UART0_LCRH_FEN |	/* Enable FIFOs */
+		BCM2835_UART0_LCRH_WL8);	/* Word length: 8 */
+	write32(BCM2835_UART0_CR,
+		BCM2835_UART0_CR_UARTEN |	/* Enable UART */
+		BCM2835_UART0_CR_TXE |		/* Enable TX */
+		BCM2835_UART0_CR_RXE);		/* Enable RX */
+}
+
+static void scons_sendb_raspi(uint8_t byte)
+{
+	if (!raspi_init) {
+		scons_init_raspi();
+		raspi_init = 1;
+	}
+
+	while (read32(BCM2835_UART0_FR) & BCM2835_UART0_FR_TXFF);
+
+	write32(BCM2835_UART0_DR, byte);
+}
+#endif
+
 /** Send a byte to the serial console.
  *
@@ -139,4 +181,7 @@
 #ifdef MACHINE_integratorcp
 	scons_sendb_icp(byte);
+#endif
+#ifdef MACHINE_raspberrypi
+	scons_sendb_raspi(byte);
 #endif
 }
Index: boot/arch/sparc32/Makefile.inc
===================================================================
--- boot/arch/sparc32/Makefile.inc	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ boot/arch/sparc32/Makefile.inc	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,58 @@
+#
+# Copyright (c) 2013 Jakub Klama
+# 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.
+#
+
+ifeq ($(MACHINE), leon3)
+	BOOT_OUTPUT = image.boot
+	POST_OUTPUT = $(ROOT_PATH)/uImage.bin
+	LADDR = 0x40000000
+	SADDR = 0x40000000
+	POSTBUILD = Makefile.uboot
+endif
+
+BFD_NAME = elf32-sparc
+BFD_OUTPUT = $(BFD_NAME)
+BFD_ARCH = sparc
+
+BITS = 32
+ENDIANESS = BE
+
+SOURCES = \
+	arch/$(BARCH)/src/asm.S \
+	arch/$(BARCH)/src/ambapp.c \
+	arch/$(BARCH)/src/main.c \
+	arch/$(BARCH)/src/mm.c \
+	arch/$(BARCH)/src/putchar.c \
+	$(COMPS_C) \
+	genarch/src/division.c \
+	generic/src/memstr.c \
+	generic/src/printf_core.c \
+	generic/src/vprintf.c \
+	generic/src/printf.c \
+	generic/src/str.c \
+	generic/src/version.c \
+	generic/src/inflate.c
Index: boot/arch/sparc32/_link.ld.in
===================================================================
--- boot/arch/sparc32/_link.ld.in	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ boot/arch/sparc32/_link.ld.in	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,37 @@
+#include <arch/arch.h>
+
+ENTRY(start)
+
+SECTIONS {
+	. = BOOT_BASE;
+	.text : {
+		*(BOOTSTRAP);
+		*(.text);
+	}
+	. = BOOT_BASE + 0x8000;
+	.data : {
+		bdata_start = .;
+		*(BOOTPT);      /* bootstrap page table */
+		*(BOOTSTACK);   /* bootstrap stack */
+		*(.data);       /* initialized data */
+		*(.rodata);
+		*(.rodata.*);
+		*(.sdata);
+		*(.reginfo);
+		*(.sbss);
+		*(.scommon);
+		*(.bss);        /* uninitialized static variables */
+		*(COMMON);      /* global variables */
+[[COMPONENTS]]
+	}
+	bdata_end = .;
+	
+	/DISCARD/ : {
+		*(.gnu.*);
+		*(.ARM.*);
+		*(.mdebug*);
+		*(.pdr);
+		*(.comment);
+		*(.note.*);
+	}
+}
Index: boot/arch/sparc32/include/ambapp.h
===================================================================
--- boot/arch/sparc32/include/ambapp.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ boot/arch/sparc32/include/ambapp.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2013 Jakub Klama
+ * 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 sparc32boot
+ * @{
+ */
+/** @file
+ * @brief Definitions of structures and addresses of AMBA Plug&Play interface
+ */
+
+#ifndef BOOT_sparc32_AMBAPP_H
+#define BOOT_sparc32_AMBAPP_H
+
+#define AMBAPP_MAX_DEVICES     64
+#define AMBAPP_AHBMASTER_AREA  0xfffff000
+#define AMBAPP_AHBSLAVE_AREA   0xfffff800
+#define AMBAPP_CONF_AREA       0xff000
+
+typedef enum {
+	GAISLER = 1,
+	ESA = 4
+} amba_vendor_id_t;
+
+typedef enum {
+	GAISLER_LEON3    = 0x003,
+	GAISLER_LEON3DSU = 0x004,
+	GAISLER_ETHAHB   = 0x005,
+	GAISLER_APBMST   = 0x006,
+	GAISLER_AHBUART  = 0x007,
+	GAISLER_SRCTRL   = 0x008,
+	GAISLER_SDCTRL   = 0x009,
+	GAISLER_APBUART  = 0x00c,
+	GAISLER_IRQMP    = 0x00d,
+	GAISLER_AHBRAM   = 0x00e,
+	GAISLER_GPTIMER  = 0x011,
+	GAISLER_PCITRG   = 0x012,
+	GAISLER_PCISBRG  = 0x013,
+	GAISLER_PCIFBRG  = 0x014,
+	GAISLER_PCITRACE = 0x015,
+	GAISLER_PCIDMA   = 0x016,
+	GAISLER_AHBTRACE = 0x017,
+	GAISLER_ETHDSU   = 0x018,
+	GAISLER_PIOPORT  = 0x01a,
+	GAISLER_AHBJTAG  = 0x01c,
+	GAISLER_SPW      = 0x01f,
+	GAISLER_ATACTRL  = 0x024,
+	GAISLER_VGA      = 0x061,
+	GAISLER_KBD      = 0x060,
+	GAISLER_ETHMAC   = 0x01d,
+	GAISLER_DDRSPA   = 0x025,
+	GAISLER_EHCI     = 0x026,
+	GAISLER_UHCI     = 0x027,
+	GAISLER_SPW2     = 0x029,
+	GAISLER_DDR2SPA  = 0x02e,
+	GAISLER_AHBSTAT  = 0x052,
+	GAISLER_FTMCTRL  = 0x054,
+	ESA_MCTRL        = 0x00f,
+} amba_device_id_t;
+
+typedef struct {
+	/* Primary serial port location */
+	uintptr_t uart_base;
+	size_t uart_size;
+	int uart_irq;
+	/* Timers location */
+	uintptr_t timer_base;
+	size_t timer_size;
+	int timer_irq;
+} amba_info_t;
+
+typedef struct {
+	amba_vendor_id_t vendor_id;
+	amba_device_id_t device_id;
+	int irq;
+	int version;
+	uint32_t args[3];
+	struct {
+		uintptr_t start;
+		uintptr_t size;
+		bool prefetchable;
+		bool cacheable;
+	} bars[4];
+} amba_device_t;
+
+typedef struct {
+	unsigned int addr : 12;
+	unsigned int reserved : 2;
+	unsigned int prefetchable : 1;
+	unsigned int cacheable : 1;
+	unsigned int mask : 12;
+	unsigned int type : 4;
+} __attribute__((packed)) ambapp_bar_t;
+
+typedef struct {
+	unsigned int vendor_id : 8;
+	unsigned int device_id : 24;
+	unsigned int reserved : 2;
+	unsigned int version : 5;
+	unsigned int irq : 5;
+	uint32_t user_defined[3];
+	ambapp_bar_t bar[4];
+} __attribute__((packed)) ambapp_entry_t;
+
+typedef struct {
+	unsigned int ram_read_ws : 1;
+	unsigned int ram_write_ws : 1;
+	unsigned int ram_width : 2;
+	unsigned int rmw : 1;
+	unsigned int rbrdy : 1;
+	unsigned int : 1;
+	unsigned int bank_size : 4;
+	unsigned int si : 1;
+	unsigned int se : 1;
+	unsigned int : 1;
+	unsigned int ms : 1;
+	unsigned int : 1;
+	unsigned int d64 : 1;
+	unsigned int sdram_cmd : 2;
+	unsigned int sdram_colsz : 2;
+	unsigned int sdram_banksz : 3;
+	unsigned int tcas : 1;
+	unsigned int trfc : 3;
+	unsigned int trp : 1;
+	unsigned int sdrf : 1;
+} __attribute__((packed)) mctrl_mcfg2_t;
+
+extern uintptr_t amba_uart_base;
+
+extern void ambapp_scan(void);
+extern bool ambapp_fake(void);
+extern void ambapp_qemu_fake_scan(void);
+extern void ambapp_print_devices(void);
+extern amba_device_t *ambapp_lookup_first(amba_vendor_id_t, amba_device_id_t);
+
+#endif
+
+/** @}
+ */
Index: boot/arch/sparc32/include/arch.h
===================================================================
--- boot/arch/sparc32/include/arch.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ boot/arch/sparc32/include/arch.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2013 Jakub Klama
+ * 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.
+ */
+
+#ifndef BOOT_sparc32_ARCH_H
+#define BOOT_sparc32_ARCH_H
+
+#define PTL0_ENTRIES     256
+#define PTL0_SHIFT       24
+#define PTL0_SIZE        (1 << 24)
+#define PTL0_ENTRY_SIZE  4
+
+/* ASI assignments: */
+#define ASI_CACHEMISS  0x01
+#define ASI_CACHECTRL  0x02
+#define ASI_MMUREGS    0x19
+#define ASI_MMUBYPASS  0x1c
+
+/*
+ * Address where the boot stage image starts
+ * (beginning of usable physical memory).
+ */
+
+#define BOOT_BASE   0x40000000
+#define BOOT_OFFSET (BOOT_BASE + 0xa00000)
+
+#define PA_OFFSET  0x40000000
+
+#ifndef __ASM__
+	#define PA2KA(addr)  (((uintptr_t) (addr)) + PA_OFFSET)
+#else
+	#define PA2KA(addr)  ((addr) + PA_OFFSET)
+#endif
+
+#endif
+
+/** @}
+ */
Index: boot/arch/sparc32/include/asm.h
===================================================================
--- boot/arch/sparc32/include/asm.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ boot/arch/sparc32/include/asm.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2013 Jakub Klama
+ * 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.
+ */
+
+#ifndef BOOT_sparc32_ASM_H_
+#define BOOT_sparc32_ASM_H_
+
+#include <typedefs.h>
+
+extern uintptr_t boot_ctx_table;
+
+static inline uint32_t asi_u32_read(unsigned int asi, uintptr_t va)
+{
+	uint32_t v;
+	
+	asm volatile (
+		"lda [%[va]] %[asi], %[v]\n"
+		: [v] "=r" (v)
+		: [va] "r" (va),
+		  [asi] "i" (asi)
+	);
+	
+	return v;
+}
+
+static inline void asi_u32_write(unsigned int asi, uintptr_t va, uint32_t v)
+{
+	asm volatile (
+		"sta %[v], [%[va]] %[asi]\n"
+		:: [v] "r" (v),
+		   [va] "r" (va),
+		   [asi] "i" (asi)
+		: "memory"
+	);
+}
+
+extern void jump_to_kernel(void *, bootinfo_t *);
+
+#endif
Index: boot/arch/sparc32/include/main.h
===================================================================
--- boot/arch/sparc32/include/main.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ boot/arch/sparc32/include/main.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013 Jakub Klama
+ * 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 sparc32boot
+ * @{
+ */
+/** @file
+ * @brief Boot related declarations.
+ */
+
+#ifndef BOOT_sparc32_MAIN_H
+#define BOOT_sparc32_MAIN_H
+
+/** Address where characters to be printed are expected. */
+#define APBUART_SCONS_THR      0x80000100
+#define APBUART_SCONS_THR_MMU  0xb0000100
+
+extern void bootstrap(void);
+
+#endif
+
+/** @}
+ */
Index: boot/arch/sparc32/include/mm.h
===================================================================
--- boot/arch/sparc32/include/mm.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ boot/arch/sparc32/include/mm.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2013 Jakub Klama
+ * 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 sparc32boot
+ * @{
+ */
+/** @file
+ * @brief Memory management used while booting the kernel.
+ *
+ * So called "section" paging is used while booting the kernel. The term
+ * "section" comes from the ARM architecture specification and stands for the
+ * following: one-level paging, 1MB sized pages, 4096 entries in the page
+ * table.
+ */
+
+#ifndef BOOT_sparc32_MM_H
+#define BOOT_sparc32_MM_H
+
+#include <typedefs.h>
+
+#define PAGE_SIZE  (1 << 12)
+
+typedef struct {
+	uint32_t pa;
+	uint32_t size;
+	uint32_t va;
+	uint32_t cacheable;
+} section_mapping_t;
+
+typedef struct {
+	unsigned int ppn : 24;
+	unsigned int cacheable : 1;
+	unsigned int modified : 1;
+	unsigned int referenced : 1;
+	unsigned int acc : 3;
+	unsigned int et : 2;
+} __attribute__((packed)) pte_t;
+
+extern pte_t boot_pt[PTL0_ENTRIES];
+
+extern void mmu_init(void);
+
+#define PTE_ET_DESCRIPTOR  1
+#define PTE_ET_ENTRY       2
+#define PTE_ACC_RWX        3
+#define MMU_CONTROL_EN     (1 << 0)
+
+#endif
+
+/** @}
+ */
Index: boot/arch/sparc32/include/types.h
===================================================================
--- boot/arch/sparc32/include/types.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ boot/arch/sparc32/include/types.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2006 Martin Decky
+ * Copyright (c) 2013 Jakub Klama
+ * 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 sparc32boot
+ * @{
+ */
+/** @file
+ * @brief Definitions of basic types like #uintptr_t.
+ */
+
+#ifndef BOOT_sparc32_TYPES_H
+#define BOOT_sparc32_TYPES_H
+
+#define TASKMAP_MAX_RECORDS        32
+#define BOOTINFO_TASK_NAME_BUFLEN  32
+
+typedef uint32_t size_t;
+typedef uint32_t uintptr_t;
+
+typedef uint32_t pfn_t;
+
+typedef struct {
+	/** Address where the task was placed. */
+	void *addr;
+	/** Size of the task's binary. */
+	size_t size;
+	/** Task name. */
+	char name[BOOTINFO_TASK_NAME_BUFLEN];
+} task_t;
+
+typedef struct {
+	size_t cnt;
+	task_t tasks[TASKMAP_MAX_RECORDS];
+	/* Fields below are LEON-specific */
+	uintptr_t uart_base;
+	uintptr_t intc_base;
+	uintptr_t timer_base;
+	int uart_irq;
+	int timer_irq;
+	uint32_t memsize;
+} bootinfo_t;
+
+#endif
+
+/** @}
+ */
Index: boot/arch/sparc32/src/ambapp.c
===================================================================
--- boot/arch/sparc32/src/ambapp.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ boot/arch/sparc32/src/ambapp.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2013 Jakub Klama
+ * 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 sparc32boot
+ * @{
+ */
+/** @file
+ * @brief Bootstrap.
+ */
+
+#include <arch/asm.h>
+#include <arch/common.h>
+#include <arch/arch.h>
+#include <arch/ambapp.h>
+#include <arch/mm.h>
+#include <arch/main.h>
+#include <arch/_components.h>
+#include <halt.h>
+#include <printf.h>
+#include <memstr.h>
+#include <version.h>
+#include <macros.h>
+#include <align.h>
+#include <str.h>
+#include <errno.h>
+
+uintptr_t amba_uart_base;
+
+static amba_device_t amba_devices[AMBAPP_MAX_DEVICES];
+static unsigned int amba_devices_found;
+static bool amba_fake;
+
+static void ambapp_scan_area(uintptr_t, unsigned int);
+
+void ambapp_scan()
+{
+	amba_fake = false;
+	
+	/* Scan for AHB masters & slaves */
+	ambapp_scan_area(AMBAPP_AHBMASTER_AREA, 64);
+	ambapp_scan_area(AMBAPP_AHBSLAVE_AREA, 63);
+	
+	/* Scan for APB slaves on APBMST */
+	amba_device_t *apbmst = ambapp_lookup_first(GAISLER, GAISLER_APBMST);
+	if (apbmst != NULL)
+		ambapp_scan_area(apbmst->bars[0].start, 16);
+	
+	/* If we found nothing, fake device entries */
+	if (amba_devices_found == 0)
+		ambapp_qemu_fake_scan();
+}
+
+static void ambapp_scan_area(uintptr_t master_bar, unsigned int max_entries)
+{
+	ambapp_entry_t *entry = (ambapp_entry_t *) (master_bar | AMBAPP_CONF_AREA);
+	
+	for (unsigned int i = 0; i < max_entries; i++) {
+		if (amba_devices_found == AMBAPP_MAX_DEVICES)
+			return;
+		
+		if (entry->vendor_id == 0xff)
+			continue;
+		
+		amba_device_t *device = &amba_devices[amba_devices_found];
+		device->vendor_id = (amba_vendor_id_t) entry->vendor_id;
+		device->device_id = (amba_device_id_t) entry->device_id;
+		device->version = entry->version;
+		device->irq = entry->irq;
+		
+		for (unsigned int bar = 0; bar < 4; bar++) {
+			device->bars[bar].start = entry->bar[bar].addr << 20;
+			device->bars[bar].size = entry->bar[bar].mask;
+			device->bars[bar].prefetchable = (bool) entry->bar[bar].prefetchable;
+			device->bars[bar].cacheable = (bool) entry->bar[bar].cacheable;
+		}
+		
+		amba_devices_found++;
+	}
+}
+
+void ambapp_qemu_fake_scan()
+{
+	/* UART */
+	amba_devices[0].vendor_id = GAISLER;
+	amba_devices[0].device_id = GAISLER_APBUART;
+	amba_devices[0].version = 1;
+	amba_devices[0].irq = 3;
+	amba_devices[0].bars[0].start = 0x80000100;
+	amba_devices[0].bars[0].size = 0x100;
+	
+	/* IRQMP */
+	amba_devices[1].vendor_id = GAISLER;
+	amba_devices[1].device_id = GAISLER_IRQMP;
+	amba_devices[1].version = 1;
+	amba_devices[1].irq = -1;
+	amba_devices[1].bars[0].start = 0x80000200;
+	amba_devices[1].bars[0].size = 0x100;
+	
+	/* GPTIMER */
+	amba_devices[2].vendor_id = GAISLER;
+	amba_devices[2].device_id = GAISLER_GPTIMER;
+	amba_devices[2].version = 1;
+	amba_devices[2].irq = 8;
+	amba_devices[2].bars[0].start = 0x80000300;
+	amba_devices[2].bars[0].size = 0x100;
+	
+	amba_fake = true;
+	amba_devices_found = 3;
+}
+
+bool ambapp_fake()
+{
+	return amba_fake;
+}
+
+void ambapp_print_devices()
+{
+	printf("ABMA devices:\n");
+	
+	for (unsigned int i = 0; i < amba_devices_found; i++) {
+		amba_device_t *dev = &amba_devices[i];
+		
+		printf("<%1x:%03x> at 0x%08x ", dev->vendor_id, dev->device_id,
+		    dev->bars[0].start);
+		
+		if (dev->irq == -1)
+			printf("\n");
+		else
+			printf("irq %d\n", dev->irq);
+	}
+}
+
+amba_device_t *ambapp_lookup_first(amba_vendor_id_t vendor,
+    amba_device_id_t device)
+{
+	for (unsigned int i = 0; i < amba_devices_found; i++) {
+		if ((amba_devices[i].vendor_id == vendor) &&
+		    (amba_devices[i].device_id == device))
+			return &amba_devices[i];
+	}
+	
+	return NULL;
+}
Index: boot/arch/sparc32/src/asm.S
===================================================================
--- boot/arch/sparc32/src/asm.S	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ boot/arch/sparc32/src/asm.S	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,66 @@
+#
+# Copyright (c) 2007 Michal Kebrt
+# 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.
+#
+
+#include <arch/arch.h>
+
+.section BOOTSTRAP
+
+.global start
+.global boot_pt
+.global boot_ctx_table
+.global boot_stack
+.global halt
+.global jump_to_kernel
+
+start:
+	b bootstrap
+	nop
+
+.section BOOTPT
+.align 4096
+boot_pt:
+	.space PTL0_ENTRIES * PTL0_ENTRY_SIZE
+
+boot_ctx_table:
+	.space 4
+
+.section BOOTSTACK
+	.space 4096
+boot_stack:
+
+.text
+
+halt:
+	b halt
+	nop
+
+jump_to_kernel:
+	set 0x80a00000, %l0
+	mov %i1, %o0
+	jmp %l0
+	nop
Index: boot/arch/sparc32/src/main.c
===================================================================
--- boot/arch/sparc32/src/main.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ boot/arch/sparc32/src/main.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2013 Jakub Klama
+ * 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 sparc32boot
+ * @{
+ */
+/** @file
+ * @brief Bootstrap.
+ */
+
+#include <arch/asm.h>
+#include <arch/common.h>
+#include <arch/arch.h>
+#include <arch/ambapp.h>
+#include <arch/mm.h>
+#include <arch/main.h>
+#include <arch/_components.h>
+#include <halt.h>
+#include <printf.h>
+#include <memstr.h>
+#include <version.h>
+#include <macros.h>
+#include <align.h>
+#include <str.h>
+#include <errno.h>
+#include <inflate.h>
+
+#define TOP2ADDR(top)  (((void *) PA2KA(BOOT_OFFSET)) + (top))
+
+static bootinfo_t bootinfo;
+
+void bootstrap(void)
+{
+	/* Initialize AMBA P&P device list */
+	ambapp_scan();
+	
+	/* Look for UART */
+	amba_device_t *uart = ambapp_lookup_first(GAISLER, GAISLER_APBUART);
+	amba_uart_base = uart->bars[0].start;
+	bootinfo.uart_base = amba_uart_base;
+	bootinfo.uart_irq = uart->irq;
+	
+	/* Look for IRQMP */
+	amba_device_t *irqmp = ambapp_lookup_first(GAISLER, GAISLER_IRQMP);
+	bootinfo.intc_base = irqmp->bars[0].start;
+	
+	/* Look for timer */
+	amba_device_t *timer = ambapp_lookup_first(GAISLER, GAISLER_GPTIMER);
+	bootinfo.timer_base = timer->bars[0].start;
+	bootinfo.timer_irq = timer->irq;
+	
+	/* Look for memory controller and obtain memory size */
+	if (!ambapp_fake()) {
+		amba_device_t *mctrl = ambapp_lookup_first(ESA, ESA_MCTRL);
+		volatile mctrl_mcfg2_t *mcfg2 = (volatile mctrl_mcfg2_t *)
+		    (mctrl->bars[0].start + 0x4);
+		bootinfo.memsize = (1 << (13 + mcfg2->bank_size));
+	} else
+		bootinfo.memsize = 64 * 1024 * 1024;
+	
+	/* Standard output is now initialized */
+	version_print();
+	
+	for (size_t i = 0; i < COMPONENTS; i++) {
+		printf(" %p|%p: %s image (%u/%u bytes)\n", components[i].start,
+		    components[i].start, components[i].name, components[i].inflated,
+		    components[i].size);
+	}
+	
+	ambapp_print_devices();
+	
+	printf("Memory size: %u MB\n", bootinfo.memsize >> 20);
+	
+	mmu_init();
+	
+	void *dest[COMPONENTS];
+	size_t top = 0;
+	size_t cnt = 0;
+	bootinfo.cnt = 0;
+	for (size_t i = 0; i < min(COMPONENTS, TASKMAP_MAX_RECORDS); i++) {
+		top = ALIGN_UP(top, PAGE_SIZE);
+		
+		if (i > 0) {
+			bootinfo.tasks[bootinfo.cnt].addr = TOP2ADDR(top);
+			bootinfo.tasks[bootinfo.cnt].size = components[i].inflated;
+			
+			str_cpy(bootinfo.tasks[bootinfo.cnt].name,
+			    BOOTINFO_TASK_NAME_BUFLEN, components[i].name);
+			
+			bootinfo.cnt++;
+		}
+		
+		dest[i] = TOP2ADDR(top);
+		
+		top += components[i].inflated;
+		cnt++;
+	}
+	
+	printf("\nInflating components ... ");
+	
+	for (size_t i = cnt; i > 0; i--) {
+		void *tail = components[i - 1].start + components[i - 1].size;
+		if (tail >= dest[i - 1]) {
+			printf("\n%s: Image too large to fit (%p >= %p), halting.\n",
+			    components[i].name, tail, dest[i - 1]);
+			halt();
+		}
+		
+		printf("%s ", components[i - 1].name);
+		
+		int err = inflate(components[i - 1].start, components[i - 1].size,
+		    dest[i - 1], components[i - 1].inflated);
+		if (err != EOK) {
+			printf("\n%s: Inflating error %d\n", components[i - 1].name, err);
+			halt();
+		}
+	}
+	
+	printf("Booting the kernel ... \n");
+	jump_to_kernel((void *) PA2KA(BOOT_OFFSET), &bootinfo);
+}
+
+/** @}
+ */
Index: boot/arch/sparc32/src/mm.c
===================================================================
--- boot/arch/sparc32/src/mm.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ boot/arch/sparc32/src/mm.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2013 Jakub Klama
+ * 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 sparc32boot
+ * @{
+ */
+/** @file
+ * @brief Bootstrap.
+ */
+
+#include <arch/asm.h>
+#include <arch/common.h>
+#include <arch/arch.h>
+#include <arch/mm.h>
+#include <arch/main.h>
+#include <arch/_components.h>
+#include <halt.h>
+#include <printf.h>
+#include <memstr.h>
+#include <version.h>
+#include <macros.h>
+#include <align.h>
+#include <str.h>
+#include <errno.h>
+#include <inflate.h>
+
+#define OFF2SEC(_addr)  ((_addr) >> PTL0_SHIFT)
+#define SEC2OFF(_sec)   ((_sec) << PTL0_SHIFT)
+
+static section_mapping_t mappings[] = {
+	{ 0x40000000, 0x3fffffff, 0x40000000, 1 },
+	{ 0x40000000, 0x2fffffff, 0x80000000, 1 },
+	{ 0x80000000, 0x0fffffff, 0xb0000000, 0 },
+	{ 0, 0, 0, 0 },
+};
+
+static void mmu_enable(void)
+{
+	boot_ctx_table = ((uintptr_t) &boot_pt[0] >> 4) | PTE_ET_DESCRIPTOR;
+	
+	/* Set Context Table Pointer register */
+	asi_u32_write(ASI_MMUREGS, 0x100, ((uint32_t) &boot_ctx_table) >> 4);
+	
+	/* Select context 0 */
+	asi_u32_write(ASI_MMUREGS, 0x200, 0);
+	
+	/* Enable MMU */
+	uint32_t cr = asi_u32_read(ASI_MMUREGS, 0x000);
+	cr |= 1;
+	asi_u32_write(ASI_MMUREGS, 0x000, cr);
+}
+
+static void mmu_disable()
+{
+	uint32_t cr = asi_u32_read(ASI_MMUREGS, 0x000);
+	cr &= ~1;
+	asi_u32_write(ASI_MMUREGS, 0x000, cr);
+}
+
+void mmu_init(void)
+{
+	mmu_disable();
+	
+	for (unsigned int i = 0; mappings[i].size != 0; i++) {
+		unsigned int ptr = 0;
+		for (uint32_t sec = OFF2SEC(mappings[i].va);
+		    sec < OFF2SEC(mappings[i].va + mappings[i].size);
+		    sec++) {
+			boot_pt[sec].ppn = ((mappings[i].pa + SEC2OFF(ptr++)) >> 12) & 0xffffff;
+			boot_pt[sec].cacheable = mappings[i].cacheable;
+			boot_pt[sec].acc = PTE_ACC_RWX;
+			boot_pt[sec].et = PTE_ET_ENTRY;
+		}
+	}
+	
+	mmu_enable();
+}
Index: boot/arch/sparc32/src/putchar.c
===================================================================
--- boot/arch/sparc32/src/putchar.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ boot/arch/sparc32/src/putchar.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2007 Michal Kebrt
+ * Copyright (c) 2009 Vineeth Pillai
+ * Copyright (c) 2010 Jiri Svoboda
+ * Copyright (c) 2013 Jakub Klama
+ * 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 sparc32boot
+ * @{
+ */
+/** @file
+ * @brief bootloader output logic
+ */
+
+#include <typedefs.h>
+#include <arch/asm.h>
+#include <arch/arch.h>
+#include <arch/main.h>
+#include <arch/mm.h>
+#include <putchar.h>
+#include <str.h>
+
+/** Send a byte to the LEON3 serial console.
+ *
+ * @param byte Byte to send.
+ *
+ */
+static void scons_sendb(uint8_t byte)
+{
+	asi_u32_write(ASI_MMUBYPASS, APBUART_SCONS_THR, byte);
+}
+
+/** Display a character
+ *
+ * @param ch Character to display
+ *
+ */
+void putchar(const wchar_t ch)
+{
+	if (ch == '\n')
+		scons_sendb('\r');
+	
+	if (ascii_check(ch))
+		scons_sendb((uint8_t) ch);
+	else
+		scons_sendb(U_SPECIAL);
+}
+
+/** @}
+ */
Index: contrib/arch/HelenOS.adl
===================================================================
--- contrib/arch/HelenOS.adl	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ contrib/arch/HelenOS.adl	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -22,5 +22,5 @@
 	
 	/* Kernel log */
-	inst klog klog;
+	inst kio kio;
 	
 	[/uspace/lib/libc/bind%ns]
@@ -30,5 +30,5 @@
 	[/uspace/lib/libc/bind%vfs]
 	[/uspace/lib/libc/bind%console]
-	[/uspace/lib/libc/bind%klog]
+	[/uspace/lib/libc/bind%kio]
 	
 	bind ns:kbd to console:kbd;
@@ -58,4 +58,4 @@
 	bind console:sys_console to kernel:sys_console;
 	
-	bind klog:ns to ns:ns;
+	bind kio:ns to ns:ns;
 };
Index: contrib/arch/kernel/kernel.adl
===================================================================
--- contrib/arch/kernel/kernel.adl	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ contrib/arch/kernel/kernel.adl	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -3,9 +3,9 @@
  *****************************/
 
-interface sys_klog {
+interface sys_kio {
 		/* Print using kernel facility */
-		sysarg_t sys_klog(int fd, const void *buf, size_t size);
-	protocol:
-		?sys_klog*
+		sysarg_t sys_kio(int fd, const void *buf, size_t size);
+	protocol:
+		?sys_kio*
 };
 
@@ -251,5 +251,5 @@
 frame sys_console {
 	provides:
-		sys_klog sys_klog;
+		sys_kio sys_kio;
 		sys_console sys_console;
 };
@@ -316,5 +316,5 @@
 	inst sys_debug sys_debug;
 	
-	delegate sys_klog to sys_console:sys_klog;
+	delegate sys_kio to sys_console:sys_kio;
 	delegate sys_console to sys_console:sys_console;
 	delegate sys_tls to sys_proc:sys_tls;
Index: contrib/arch/uspace/app/kio/kio.adl
===================================================================
--- contrib/arch/uspace/app/kio/kio.adl	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ contrib/arch/uspace/app/kio/kio.adl	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,9 @@
+frame kio {
+	requires:
+		naming_service ns;
+		[/uspace/lib/libc/requires]
+	initialization:
+		!ns.ipc_m_share_in /* SERVICE_MEM_KIO */
+	protocol:
+		[/uspace/lib/libc/protocol]
+};
Index: ntrib/arch/uspace/app/klog/klog.adl
===================================================================
--- contrib/arch/uspace/app/klog/klog.adl	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,9 +1,0 @@
-frame klog {
-	requires:
-		naming_service ns;
-		[/uspace/lib/libc/requires]
-	initialization:
-		!ns.ipc_m_share_in /* SERVICE_MEM_KLOG */
-	protocol:
-		[/uspace/lib/libc/protocol]
-};
Index: contrib/arch/uspace/lib/libc/bind
===================================================================
--- contrib/arch/uspace/lib/libc/bind	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ contrib/arch/uspace/lib/libc/bind	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -1,4 +1,4 @@
 /* Bind %% to kernel interfaces */
-bind %%:sys_klog to kernel:sys_klog;
+bind %%:sys_kio to kernel:sys_kio;
 bind %%:sys_tls to kernel:sys_tls;
 bind %%:sys_thread to kernel:sys_thread;
Index: contrib/arch/uspace/lib/libc/protocol
===================================================================
--- contrib/arch/uspace/lib/libc/protocol	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ contrib/arch/uspace/lib/libc/protocol	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -1,5 +1,5 @@
 /* Protocol according to which libc uses kernel syscalls */
 (
-	!sys_klog.sys_klog +
+	!sys_kio.sys_kio +
 	!sys_tls.sys_tls_set +
 	!sys_thread.sys_thread_create +
Index: contrib/arch/uspace/lib/libc/requires
===================================================================
--- contrib/arch/uspace/lib/libc/requires	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ contrib/arch/uspace/lib/libc/requires	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -1,4 +1,4 @@
 /* Kernel interfaces required by libc */
-sys_klog sys_klog;
+sys_kio sys_kio;
 sys_tls sys_tls;
 sys_thread sys_thread;
Index: contrib/arch/uspace/lib/libc/subsume
===================================================================
--- contrib/arch/uspace/lib/libc/subsume	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ contrib/arch/uspace/lib/libc/subsume	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -1,4 +1,4 @@
 /* Subsume %% to kernel interfaces */
-subsume %%:sys_klog to sys_klog;
+subsume %%:sys_kio to sys_kio;
 subsume %%:sys_tls to sys_tls;
 subsume %%:sys_thread to sys_thread;
Index: contrib/arch/uspace/srv/ns/ns.adl
===================================================================
--- contrib/arch/uspace/srv/ns/ns.adl	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ contrib/arch/uspace/srv/ns/ns.adl	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -6,5 +6,5 @@
 		sysarg_t ipc_m_connect_me_to(in sysarg_t service, in sysarg_t arg2, in sysarg_t arg3, in sysarg_t flags);
 		
-		/* Share real-time clock page or klog page */
+		/* Share real-time clock page or kio page */
 		sysarg_t ipc_m_share_in(in sysarg_t as_area_base, in sysarg_t as_area_size, in sysarg_t service);
 		
Index: ntrib/conf/arm32-qe.sh
===================================================================
--- contrib/conf/arm32-qe.sh	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,3 +1,0 @@
-#!/bin/sh
-
-qemu-system-arm $@ -M integratorcp --kernel image.boot -serial stdio
Index: ntrib/conf/ia32-qe.sh
===================================================================
--- contrib/conf/ia32-qe.sh	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,22 +1,0 @@
-#!/bin/sh
-
-if [ -z "${QEMU_BINARY}" ] ; then
-	QEMU_BINARY="`which --tty-only qemu 2> /dev/null`"
-fi
-
-if [ -z "${QEMU_BINARY}" ] ; then
-	QEMU_BINARY="`which --tty-only qemu-system-i386 2> /dev/null`"
-fi
-
-if [ -z "${QEMU_BINARY}" ] ; then
-	echo "QEMU binary not found"
-fi
-
-DISK_IMG=hdisk.img
-
-# Create a disk image if it does not exist
-if [ ! -f "$DISK_IMG" ]; then
-	tools/mkfat.py 1048576 uspace/dist/data "$DISK_IMG"
-fi
-
-"${QEMU_BINARY}" "$@" -m 64 -hda "$DISK_IMG" -cdrom image.iso -boot d -soundhw sb16
Index: ntrib/conf/net-qe.sh
===================================================================
--- contrib/conf/net-qe.sh	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,34 +1,0 @@
-#!/bin/sh
-
-if [ -z "${QEMU_BINARY}" ] ; then
-	QEMU_BINARY="`which --tty-only qemu 2> /dev/null`"
-fi
-
-if [ -z "${QEMU_BINARY}" ] ; then
-	QEMU_BINARY="`which --tty-only qemu-system-x86_64 2> /dev/null`"
-fi
-
-if [ -z "${QEMU_BINARY}" ] ; then
-	QEMU_BINARY="`which --tty-only qemu-system-i386 2> /dev/null`"
-fi
-
-if [ -z "${QEMU_BINARY}" ] ; then
-	echo "QEMU binary not found"
-fi
-
-case "$1" in
-	ne2k)
-		shift
-		"${QEMU_BINARY}" "$@" -device ne2k_isa,irq=5,vlan=0 -net user -boot d -redir udp:8080::8080 -redir udp:8081::8081 -redir tcp:8080::8080 -redir tcp:8081::8081 -cdrom image.iso
-		;;
-	e1k)
-		shift
-		"${QEMU_BINARY}" "$@" -device e1000,vlan=0 -net user -boot d -redir udp:8080::8080 -redir udp:8081::8081 -redir tcp:8080::8080 -redir tcp:8081::8081 -cdrom image.iso
-		;;
-	rtl8139)
-		shift
-		"${QEMU_BINARY}" "$@" -device rtl8139,vlan=0 -net user -boot d -redir udp:8080::8080 -redir udp:8081::8081 -redir tcp:8080::8080 -redir tcp:8081::8081 -cdrom image.iso
-		;;
-	*)
-		echo "Usage: $0 {ne2k|e1k|rtl8139}"
-esac
Index: ntrib/conf/ppc32-qe.sh
===================================================================
--- contrib/conf/ppc32-qe.sh	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,3 +1,0 @@
-#!/bin/sh
-
-qemu-system-ppc $@ -M g3beige -boot d -cdrom image.iso
Index: contrib/conf/ski.conf
===================================================================
--- contrib/conf/ski.conf	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ contrib/conf/ski.conf	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -1,1 +1,2 @@
 load image.boot
+c
Index: ntrib/conf/sparc64-qe
===================================================================
--- contrib/conf/sparc64-qe	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,3 +1,0 @@
-#!/bin/sh
-
-qemu-system-sparc64 $@ -M sun4u -boot d -cdrom image.iso
Index: defaults/arm32/raspberrypi/Makefile.config
===================================================================
--- defaults/arm32/raspberrypi/Makefile.config	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ defaults/arm32/raspberrypi/Makefile.config	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,8 @@
+# Machine type
+MACHINE = raspberrypi
+
+# RAM disk format
+RDFMT = fat
+
+#framebuffer
+CONFIG_FB = n
Index: defaults/sparc32/Makefile.config
===================================================================
--- defaults/sparc32/Makefile.config	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ defaults/sparc32/Makefile.config	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,60 @@
+# Platform
+PLATFORM = sparc32
+
+# Ramdisk format
+RDFMT = ext4fs
+
+# Compiler
+COMPILER = gcc_cross
+
+# Support for SMP
+CONFIG_SMP = n
+
+# Debug build
+CONFIG_DEBUG = y
+
+# Deadlock detection support for spinlocks
+CONFIG_DEBUG_SPINLOCK = y
+
+# Lazy FPU context switching
+CONFIG_FPU_LAZY = y
+
+# Use TSB
+CONFIG_TSB = y
+
+# Virtually indexed D-cache support
+CONFIG_VIRT_IDX_DCACHE = y
+
+# Support for userspace debuggers
+CONFIG_UDEBUG = y
+
+# Kernel console support
+CONFIG_KCONSOLE = y
+
+# Kernel symbol information
+CONFIG_SYMTAB = y
+
+# Detailed kernel logging
+CONFIG_LOG = n
+
+# Kernel function tracing
+CONFIG_TRACE = n
+
+# Compile kernel tests
+CONFIG_TEST = y
+
+# Input device class
+CONFIG_HID_IN = generic
+
+# Output device class
+CONFIG_HID_OUT = generic
+
+# Start AP processors by the loader
+CONFIG_AP = y
+
+# Load disk drivers on startup
+CONFIG_START_BD = n
+
+# Mount /data on startup
+CONFIG_MOUNT_DATA = n
+
Index: defaults/sparc32/leon3/Makefile.config
===================================================================
--- defaults/sparc32/leon3/Makefile.config	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ defaults/sparc32/leon3/Makefile.config	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,14 @@
+# Machine type
+MACHINE = leon3
+
+# CPU type
+PROCESSOR = leon3
+
+# Barebone build with essential binaries only
+CONFIG_BAREBONE = y
+
+# GRLIB APBUART
+CONFIG_GRLIB_UART = y
+
+# GRLIB IRQMP
+CONFIG_GRLIB_IRQMP = y
Index: defaults/sparc32/output
===================================================================
--- defaults/sparc32/output	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ defaults/sparc32/output	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,1 @@
+image.boot
Index: kernel/Makefile
===================================================================
--- kernel/Makefile	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/Makefile	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -212,4 +212,5 @@
 	generic/src/debug/debug.c \
 	generic/src/interrupt/interrupt.c \
+	generic/src/log/log.c \
 	generic/src/main/main.c \
 	generic/src/main/kinit.c \
Index: kernel/arch/amd64/src/interrupt.c
===================================================================
--- kernel/arch/amd64/src/interrupt.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/arch/amd64/src/interrupt.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -35,4 +35,5 @@
 #include <arch/interrupt.h>
 #include <print.h>
+#include <log.h>
 #include <debug.h>
 #include <panic.h>
@@ -66,16 +67,16 @@
 void istate_decode(istate_t *istate)
 {
-	printf("cs =%0#18" PRIx64 "\trip=%0#18" PRIx64 "\t"
+	log_printf("cs =%0#18" PRIx64 "\trip=%0#18" PRIx64 "\t"
 	    "rfl=%0#18" PRIx64 "\terr=%0#18" PRIx64 "\n",
 	    istate->cs, istate->rip, istate->rflags, istate->error_word);
 	
 	if (istate_from_uspace(istate))
-		printf("ss =%0#18" PRIx64 "\n", istate->ss);
-	
-	printf("rax=%0#18" PRIx64 "\trbx=%0#18" PRIx64 "\t"
+		log_printf("ss =%0#18" PRIx64 "\n", istate->ss);
+	
+	log_printf("rax=%0#18" PRIx64 "\trbx=%0#18" PRIx64 "\t"
 	    "rcx=%0#18" PRIx64 "\trdx=%0#18" PRIx64 "\n",
 	    istate->rax, istate->rbx, istate->rcx, istate->rdx);
 	
-	printf("rsi=%0#18" PRIx64 "\trdi=%0#18" PRIx64 "\t"
+	log_printf("rsi=%0#18" PRIx64 "\trdi=%0#18" PRIx64 "\t"
 	    "rbp=%0#18" PRIx64 "\trsp=%0#18" PRIx64 "\n",
 	    istate->rsi, istate->rdi, istate->rbp,
@@ -83,9 +84,9 @@
 	    (uintptr_t) &istate->rsp);
 	
-	printf("r8 =%0#18" PRIx64 "\tr9 =%0#18" PRIx64 "\t"
+	log_printf("r8 =%0#18" PRIx64 "\tr9 =%0#18" PRIx64 "\t"
 	    "r10=%0#18" PRIx64 "\tr11=%0#18" PRIx64 "\n",
 	    istate->r8, istate->r9, istate->r10, istate->r11);
 	
-	printf("r12=%0#18" PRIx64 "\tr13=%0#18" PRIx64 "\t"
+	log_printf("r12=%0#18" PRIx64 "\tr13=%0#18" PRIx64 "\t"
 	    "r14=%0#18" PRIx64 "\tr15=%0#18" PRIx64 "\n",
 	    istate->r12, istate->r13, istate->r14, istate->r15);
@@ -193,5 +194,6 @@
 		 */
 #ifdef CONFIG_DEBUG
-		printf("cpu%u: spurious interrupt (inum=%u)\n", CPU->id, inum);
+		log(LF_ARCH, LVL_DEBUG, "cpu%u: spurious interrupt (inum=%u)",
+		    CPU->id, inum);
 #endif
 	}
Index: kernel/arch/arm32/Makefile.inc
===================================================================
--- kernel/arch/arm32/Makefile.inc	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/arch/arm32/Makefile.inc	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -89,4 +89,8 @@
 endif
 
+ifeq ($(MACHINE),raspberrypi)
+	ARCH_SOURCES += arch/$(KARCH)/src/mach/raspberrypi/raspberrypi.c
+endif
+
 ifeq ($(CONFIG_PL050),y)
 	ARCH_SOURCES += genarch/src/drivers/pl050/pl050.c
Index: kernel/arch/arm32/_link.ld.in
===================================================================
--- kernel/arch/arm32/_link.ld.in	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/arch/arm32/_link.ld.in	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -13,4 +13,6 @@
 #elif defined MACHINE_beaglebone
 #define KERNEL_LOAD_ADDRESS 0x80a00000
+#elif defined MACHINE_raspberrypi
+#define KERNEL_LOAD_ADDRESS 0x80a08000
 #else
 #define KERNEL_LOAD_ADDRESS 0x80a00000
Index: kernel/arch/arm32/include/arch/cp15.h
===================================================================
--- kernel/arch/arm32/include/arch/cp15.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/arch/arm32/include/arch/cp15.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -231,4 +231,5 @@
 	SCTLR_FAST_IRQ_EN_FLAG       = 1 << 21, /* Disable impl. specific feat*/
 	SCTLR_UNALIGNED_EN_FLAG      = 1 << 22, /* Must be 1 on armv7 */
+	SCTLR_EXTENDED_PT_EN_FLAG    = 1 << 23,
 	SCTLR_IRQ_VECTORS_EN_FLAG    = 1 << 24,
 	SCTLR_BIG_ENDIAN_EXC_FLAG    = 1 << 25,
Index: kernel/arch/arm32/include/arch/mach/integratorcp/integratorcp.h
===================================================================
--- kernel/arch/arm32/include/arch/mach/integratorcp/integratorcp.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/arch/arm32/include/arch/mach/integratorcp/integratorcp.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -46,5 +46,6 @@
 #define ICP_IRQC_MAX_IRQ  8
 #define ICP_KBD_IRQ       3
-#define ICP_TIMER_IRQ    6
+#define ICP_TIMER_IRQ     6
+#define ICP_UART0_IRQ     1
 
 /** Timer frequency */
Index: kernel/arch/arm32/include/arch/mach/raspberrypi/raspberrypi.h
===================================================================
--- kernel/arch/arm32/include/arch/mach/raspberrypi/raspberrypi.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/arm32/include/arch/mach/raspberrypi/raspberrypi.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2013 Beniamino Galvani
+ * 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 arm32raspberrypi raspberrypi
+ *  @brief Raspberry Pi platform.
+ *  @ingroup arm32
+ * @{
+ */
+/** @file
+ *  @brief Raspberry Pi platform driver.
+ */
+
+#ifndef KERN_arm32_raspberrypi_H_
+#define KERN_arm32_raspberrypi_H_
+
+#include <arch/machine_func.h>
+
+extern struct arm_machine_ops raspberrypi_machine_ops;
+
+#define BCM2835_UART0_BASE_ADDRESS   0x20201000
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm32/include/arch/mm/frame.h
===================================================================
--- kernel/arch/arm32/include/arch/mm/frame.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/arch/arm32/include/arch/mm/frame.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -63,4 +63,9 @@
 #define BOOT_PAGE_TABLE_ADDRESS  0x80008000
 
+#elif defined MACHINE_raspberrypi
+
+#define PHYSMEM_START_ADDR       0x00000000
+#define BOOT_PAGE_TABLE_ADDRESS  0x00010000
+
 #else
 
Index: kernel/arch/arm32/include/arch/mm/page_armv6.h
===================================================================
--- kernel/arch/arm32/include/arch/mm/page_armv6.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/arch/arm32/include/arch/mm/page_armv6.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -278,7 +278,12 @@
 	}
 	
+#if defined(PROCESSOR_ARCH_armv6)
+	/* FIXME: this disables caches */
+	p->shareable = 1;
+#else
 	/* Shareable is ignored for devices (non-cacheable),
 	 * turn it off for normal memory. */
 	p->shareable = 0;
+#endif
 	
 	p->non_global = !(flags & PAGE_GLOBAL);
Index: kernel/arch/arm32/src/mach/gta02/gta02.c
===================================================================
--- kernel/arch/arm32/src/mach/gta02/gta02.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/arch/arm32/src/mach/gta02/gta02.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -41,7 +41,7 @@
 #include <genarch/fb/fb.h>
 #include <abi/fb/visuals.h>
-#include <genarch/drivers/s3c24xx_uart/s3c24xx_uart.h>
-#include <genarch/drivers/s3c24xx_irqc/s3c24xx_irqc.h>
-#include <genarch/drivers/s3c24xx_timer/s3c24xx_timer.h>
+#include <genarch/drivers/s3c24xx/uart.h>
+#include <genarch/drivers/s3c24xx/irqc.h>
+#include <genarch/drivers/s3c24xx/timer.h>
 #include <genarch/srln/srln.h>
 #include <sysinfo/sysinfo.h>
@@ -49,4 +49,5 @@
 #include <ddi/ddi.h>
 #include <ddi/device.h>
+#include <log.h>
 
 #define GTA02_MEMORY_START	0x30000000	/* physical */
@@ -149,5 +150,5 @@
 	} else {
 		/* Spurious interrupt.*/
-		printf("cpu%d: spurious interrupt (inum=%d)\n",
+		log(LF_ARCH, LVL_DEBUG, "cpu%d: spurious interrupt (inum=%d)",
 		    CPU->id, inum);
 	}
Index: kernel/arch/arm32/src/mach/integratorcp/integratorcp.c
===================================================================
--- kernel/arch/arm32/src/mach/integratorcp/integratorcp.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/arch/arm32/src/mach/integratorcp/integratorcp.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -37,11 +37,10 @@
 #include <ipc/irq.h>
 #include <console/chardev.h>
+#include <genarch/drivers/pl011/pl011.h>
 #include <genarch/drivers/pl050/pl050.h>
-#include <genarch/drivers/arm926_uart/arm926_uart.h>
 #include <genarch/kbrd/kbrd.h>
 #include <genarch/srln/srln.h>
 #include <console/console.h>
 #include <sysinfo/sysinfo.h>
-#include <print.h>
 #include <ddi/device.h>
 #include <mm/page.h>
@@ -53,5 +52,6 @@
 #include <abi/fb/visuals.h>
 #include <ddi/ddi.h>
-#include <print.h>
+#include <log.h>
+
 
 
@@ -61,5 +61,5 @@
 	icp_hw_map_t hw_map;
 	irq_t timer_irq;
-	arm926_uart_t uart;
+	pl011_uart_t uart;
 } icp;
 
@@ -275,5 +275,6 @@
 			} else {
 				/* Spurious interrupt.*/
-				printf("cpu%d: spurious interrupt (inum=%d)\n",
+				log(LF_ARCH, LVL_DEBUG,
+				    "cpu%d: spurious interrupt (inum=%d)",
 				    CPU->id, i);
 			}
@@ -314,7 +315,6 @@
 		stdout_wire(fbdev);
 #endif
-#ifdef CONFIG_ARM926_UART
-	if (arm926_uart_init(&icp.uart, ARM926_UART0_IRQ,
-	    ARM926_UART0_BASE_ADDRESS, sizeof(arm926_uart_regs_t)))
+#ifdef CONFIG_PL011_UART
+	if (pl011_uart_init(&icp.uart, ICP_UART0_IRQ, ICP_UART))
 		stdout_wire(&icp.uart.outdev);
 #endif
@@ -350,11 +350,11 @@
 	    ICP_KBD);
 
-#ifdef CONFIG_ARM926_UART
+#ifdef CONFIG_PL011_UART
         srln_instance_t *srln_instance = srln_init();
         if (srln_instance) {
                 indev_t *sink = stdin_wire();
                 indev_t *srln = srln_wire(srln_instance, sink);
-                arm926_uart_input_wire(&icp.uart, srln);
-		icp_irqc_unmask(ARM926_UART0_IRQ);
+                pl011_uart_input_wire(&icp.uart, srln);
+                icp_irqc_unmask(ICP_UART0_IRQ);
         }
 #endif
Index: kernel/arch/arm32/src/mach/raspberrypi/raspberrypi.c
===================================================================
--- kernel/arch/arm32/src/mach/raspberrypi/raspberrypi.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/arm32/src/mach/raspberrypi/raspberrypi.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2013 Beniamino Galvani
+ * 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 arm32raspberrypi
+ * @{
+ */
+/** @file
+ *  @brief Raspberry PI platform driver.
+ */
+
+#include <arch/exception.h>
+#include <arch/mach/raspberrypi/raspberrypi.h>
+#include <genarch/drivers/pl011/pl011.h>
+#include <genarch/drivers/bcm2835/irc.h>
+#include <genarch/drivers/bcm2835/timer.h>
+#include <genarch/drivers/bcm2835/mbox.h>
+#include <arch/mm/page.h>
+#include <mm/page.h>
+#include <mm/km.h>
+#include <genarch/fb/fb.h>
+#include <abi/fb/visuals.h>
+#include <genarch/srln/srln.h>
+#include <sysinfo/sysinfo.h>
+#include <interrupt.h>
+#include <ddi/ddi.h>
+#include <ddi/device.h>
+
+#define RPI_DEFAULT_MEMORY_START	0
+#define RPI_DEFAULT_MEMORY_SIZE		0x08000000
+#define RPI_MEMORY_SKIP			0x8000
+
+static void raspberrypi_init(void);
+static void raspberrypi_timer_irq_start(void);
+static void raspberrypi_cpu_halt(void);
+static void raspberrypi_get_memory_extents(uintptr_t *start, size_t *size);
+static void raspberrypi_irq_exception(unsigned int exc_no, istate_t *istate);
+static void raspberrypi_frame_init(void);
+static void raspberrypi_output_init(void);
+static void raspberrypi_input_init(void);
+static size_t raspberrypi_get_irq_count(void);
+static const char *raspberrypi_get_platform_name(void);
+
+static struct {
+	pl011_uart_t	uart;
+	bcm2835_irc_t	*irc;
+	bcm2835_timer_t	*timer;
+} raspi;
+
+struct arm_machine_ops raspberrypi_machine_ops = {
+	raspberrypi_init,
+	raspberrypi_timer_irq_start,
+	raspberrypi_cpu_halt,
+	raspberrypi_get_memory_extents,
+	raspberrypi_irq_exception,
+	raspberrypi_frame_init,
+	raspberrypi_output_init,
+	raspberrypi_input_init,
+	raspberrypi_get_irq_count,
+	raspberrypi_get_platform_name
+};
+
+static irq_ownership_t raspberrypi_timer_irq_claim(irq_t *irq)
+{
+	return IRQ_ACCEPT;
+}
+
+static void raspberrypi_timer_irq_handler(irq_t *irq)
+{
+	bcm2835_timer_irq_ack(raspi.timer);
+	spinlock_unlock(&irq->lock);
+	clock();
+	spinlock_lock(&irq->lock);
+}
+
+static void raspberrypi_init(void)
+{
+	/* Initialize interrupt controller */
+	raspi.irc = (void *) km_map(BCM2835_IRC_ADDR, sizeof(bcm2835_irc_t),
+				    PAGE_NOT_CACHEABLE);
+	ASSERT(raspi.irc);
+	bcm2835_irc_init(raspi.irc);
+
+	/* Initialize system timer */
+	raspi.timer = (void *) km_map(BCM2835_TIMER_ADDR,
+				      sizeof(bcm2835_timer_t),
+				      PAGE_NOT_CACHEABLE);
+}
+
+static void raspberrypi_timer_irq_start(void)
+{
+	/* Initialize timer IRQ */
+	static irq_t timer_irq;
+	irq_initialize(&timer_irq);
+	timer_irq.devno = device_assign_devno();
+	timer_irq.inr = BCM2835_TIMER1_IRQ;
+	timer_irq.claim = raspberrypi_timer_irq_claim;
+	timer_irq.handler = raspberrypi_timer_irq_handler;
+	irq_register(&timer_irq);
+
+	bcm2835_irc_enable(raspi.irc, BCM2835_TIMER1_IRQ);
+	bcm2835_timer_start(raspi.timer);
+}
+
+static void raspberrypi_cpu_halt(void)
+{
+	while (1) ;
+}
+
+/** Get extents of available memory.
+ *
+ * @param start		Place to store memory start address (physical).
+ * @param size		Place to store memory size.
+ */
+static void raspberrypi_get_memory_extents(uintptr_t *start, size_t *size)
+{
+	uint32_t mbase, msize;
+
+	if (bcm2835_prop_get_memory(&mbase, &msize)) {
+		*start = mbase + RPI_MEMORY_SKIP;
+		*size  = msize - RPI_MEMORY_SKIP;
+	} else {
+		/* Stick to safe default values */
+		*start = RPI_DEFAULT_MEMORY_START + RPI_MEMORY_SKIP;
+		*size  = RPI_DEFAULT_MEMORY_SIZE - RPI_MEMORY_SKIP;
+	}
+}
+
+static void raspberrypi_irq_exception(unsigned int exc_no, istate_t *istate)
+{
+	const unsigned inum = bcm2835_irc_inum_get(raspi.irc);
+
+	irq_t *irq = irq_dispatch_and_lock(inum);
+	if (irq) {
+		/* The IRQ handler was found. */
+		irq->handler(irq);
+		spinlock_unlock(&irq->lock);
+	} else {
+		/* Spurious interrupt.*/
+		printf("cpu%d: spurious interrupt (inum=%d)\n", CPU->id, inum);
+		bcm2835_irc_disable(raspi.irc, inum);
+	}
+}
+
+static void raspberrypi_frame_init(void)
+{
+}
+
+static void raspberrypi_output_init(void)
+{
+#ifdef CONFIG_FB
+	fb_properties_t prop;
+	if (bcm2835_fb_init(&prop)) {
+		outdev_t *fb_dev = fb_init(&prop);
+		if (fb_dev)
+			stdout_wire(fb_dev);
+	}
+#endif
+
+#ifdef CONFIG_PL011_UART
+	if (pl011_uart_init(&raspi.uart, BCM2835_UART_IRQ,
+			    BCM2835_UART0_BASE_ADDRESS))
+		stdout_wire(&raspi.uart.outdev);
+#endif
+}
+
+static void raspberrypi_input_init(void)
+{
+	srln_instance_t *srln_instance = srln_init();
+	if (srln_instance) {
+		indev_t *sink = stdin_wire();
+		indev_t *srln = srln_wire(srln_instance, sink);
+
+		pl011_uart_input_wire(&raspi.uart, srln);
+		bcm2835_irc_enable(raspi.irc, BCM2835_UART_IRQ);
+	}
+}
+
+size_t raspberrypi_get_irq_count(void)
+{
+	return BCM2835_IRQ_COUNT;
+}
+
+const char *raspberrypi_get_platform_name(void)
+{
+	return "raspberrypi";
+}
+
+/** @}
+ */
Index: kernel/arch/arm32/src/machine_func.c
===================================================================
--- kernel/arch/arm32/src/machine_func.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/arch/arm32/src/machine_func.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -43,4 +43,5 @@
 #include <arch/mach/beagleboardxm/beagleboardxm.h>
 #include <arch/mach/beaglebone/beaglebone.h>
+#include <arch/mach/raspberrypi/raspberrypi.h>
 
 /** Pointer to machine_ops structure being used. */
@@ -58,4 +59,6 @@
 #elif defined(MACHINE_beaglebone)
 	machine_ops = &bbone_machine_ops;
+#elif defined(MACHINE_raspberrypi)
+	machine_ops = &raspberrypi_machine_ops;
 #else
 #error Machine type not defined.
Index: kernel/arch/ia32/src/drivers/i8259.c
===================================================================
--- kernel/arch/ia32/src/drivers/i8259.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/arch/ia32/src/drivers/i8259.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -42,5 +42,5 @@
 #include <arch/asm.h>
 #include <arch.h>
-#include <print.h>
+#include <log.h>
 #include <interrupt.h>
 
@@ -129,5 +129,5 @@
 {
 #ifdef CONFIG_DEBUG
-	printf("cpu%u: PIC spurious interrupt\n", CPU->id);
+	log(LF_ARCH, LVL_DEBUG, "cpu%u: PIC spurious interrupt", CPU->id);
 #endif
 }
Index: kernel/arch/ia32/src/smp/apic.c
===================================================================
--- kernel/arch/ia32/src/smp/apic.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/arch/ia32/src/smp/apic.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -42,5 +42,5 @@
 #include <interrupt.h>
 #include <arch/interrupt.h>
-#include <print.h>
+#include <log.h>
 #include <arch/asm.h>
 #include <arch.h>
@@ -135,5 +135,5 @@
 {
 #ifdef CONFIG_DEBUG
-	printf("cpu%u: APIC spurious interrupt\n", CPU->id);
+	log(LF_ARCH, LVL_DEBUG, "cpu%u: APIC spurious interrupt", CPU->id);
 #endif
 }
@@ -241,18 +241,23 @@
 	esr.value = l_apic[ESR];
 	
-	if (esr.send_checksum_error)
-		printf("Send Checksum Error\n");
-	if (esr.receive_checksum_error)
-		printf("Receive Checksum Error\n");
-	if (esr.send_accept_error)
-		printf("Send Accept Error\n");
-	if (esr.receive_accept_error)
-		printf("Receive Accept Error\n");
-	if (esr.send_illegal_vector)
-		printf("Send Illegal Vector\n");
-	if (esr.received_illegal_vector)
-		printf("Received Illegal Vector\n");
-	if (esr.illegal_register_address)
-		printf("Illegal Register Address\n");
+	if (esr.err_bitmap) {
+		log_begin(LF_ARCH, LVL_ERROR);
+		log_printf("APIC errors detected:");
+		if (esr.send_checksum_error)
+			log_printf("\nSend Checksum Error");
+		if (esr.receive_checksum_error)
+			log_printf("\nReceive Checksum Error");
+		if (esr.send_accept_error)
+			log_printf("\nSend Accept Error");
+		if (esr.receive_accept_error)
+			log_printf("\nReceive Accept Error");
+		if (esr.send_illegal_vector)
+			log_printf("\nSend Illegal Vector");
+		if (esr.received_illegal_vector)
+			log_printf("\nReceived Illegal Vector");
+		if (esr.illegal_register_address)
+			log_printf("\nIllegal Register Address");
+		log_end();
+	}
 	
 	return !esr.err_bitmap;
@@ -270,5 +275,5 @@
 			retries = 0;
 #ifdef CONFIG_DEBUG
-			printf("IPI is pending.\n");
+			log(LF_ARCH, LVL_DEBUG, "IPI is pending.");
 #endif
 			delay(20);
@@ -489,10 +494,11 @@
 {
 #ifdef LAPIC_VERBOSE
-	printf("LVT on cpu%u, LAPIC ID: %" PRIu8 "\n",
+	log_begin(LF_ARCH, LVL_DEBUG);
+	log_printf("LVT on cpu%u, LAPIC ID: %" PRIu8 "\n",
 	    CPU->id, l_apic_id());
 	
 	lvt_tm_t tm;
 	tm.value = l_apic[LVT_Tm];
-	printf("LVT Tm: vector=%" PRIu8 ", %s, %s, %s\n",
+	log_printf("LVT Tm: vector=%" PRIu8 ", %s, %s, %s\n",
 	    tm.vector, delivs_str[tm.delivs], mask_str[tm.masked],
 	    tm_mode_str[tm.mode]);
@@ -500,5 +506,5 @@
 	lvt_lint_t lint;
 	lint.value = l_apic[LVT_LINT0];
-	printf("LVT LINT0: vector=%" PRIu8 ", %s, %s, %s, irr=%u, %s, %s\n",
+	log_printf("LVT LINT0: vector=%" PRIu8 ", %s, %s, %s, irr=%u, %s, %s\n",
 	    tm.vector, delmod_str[lint.delmod], delivs_str[lint.delivs],
 	    intpol_str[lint.intpol], lint.irr, trigmod_str[lint.trigger_mode],
@@ -506,5 +512,5 @@
 	
 	lint.value = l_apic[LVT_LINT1];
-	printf("LVT LINT1: vector=%" PRIu8 ", %s, %s, %s, irr=%u, %s, %s\n",
+	log_printf("LVT LINT1: vector=%" PRIu8 ", %s, %s, %s, irr=%u, %s, %s\n",
 	    tm.vector, delmod_str[lint.delmod], delivs_str[lint.delivs],
 	    intpol_str[lint.intpol], lint.irr, trigmod_str[lint.trigger_mode],
@@ -513,6 +519,7 @@
 	lvt_error_t error;
 	error.value = l_apic[LVT_Err];
-	printf("LVT Err: vector=%" PRIu8 ", %s, %s\n", error.vector,
+	log_printf("LVT Err: vector=%" PRIu8 ", %s, %s\n", error.vector,
 	    delivs_str[error.delivs], mask_str[error.masked]);
+	log_end();
 #endif
 }
Index: kernel/arch/ia32/src/smp/mps.c
===================================================================
--- kernel/arch/ia32/src/smp/mps.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/arch/ia32/src/smp/mps.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -36,5 +36,5 @@
 
 #include <config.h>
-#include <print.h>
+#include <log.h>
 #include <debug.h>
 #include <arch/smp/mps.h>
@@ -181,5 +181,5 @@
 	buf[6] = 0;
 	
-	printf("MPS: bus=%" PRIu8 " (%s)\n", bus->bus_id, buf);
+	log(LF_ARCH, LVL_DEBUG, "MPS: bus=%" PRIu8 " (%s)", bus->bus_id, buf);
 #endif
 }
@@ -205,58 +205,60 @@
 {
 #ifdef MPSCT_VERBOSE
-	printf("MPS: ");
+	log_begin(LF_ARCH, LVL_DEBUG);
+	log_printf("MPS: ");
 	
 	switch (iointr->intr_type) {
 	case 0:
-		printf("INT");
-		break;
-	case 1:
-		printf("NMI");
-		break;
-	case 2:
-		printf("SMI");
-		break;
-	case 3:
-		printf("ExtINT");
-		break;
-	}
-	
-	printf(", ");
+		log_printf("INT");
+		break;
+	case 1:
+		log_printf("NMI");
+		break;
+	case 2:
+		log_printf("SMI");
+		break;
+	case 3:
+		log_printf("ExtINT");
+		break;
+	}
+	
+	log_printf(", ");
 	
 	switch (iointr->poel & 3) {
 	case 0:
-		printf("bus-like");
-		break;
-	case 1:
-		printf("active high");
-		break;
-	case 2:
-		printf("reserved");
-		break;
-	case 3:
-		printf("active low");
-		break;
-	}
-	
-	printf(", ");
+		log_printf("bus-like");
+		break;
+	case 1:
+		log_printf("active high");
+		break;
+	case 2:
+		log_printf("reserved");
+		break;
+	case 3:
+		log_printf("active low");
+		break;
+	}
+	
+	log_printf(", ");
 	
 	switch ((iointr->poel >> 2) & 3) {
 	case 0:
-		printf("bus-like");
-		break;
-	case 1:
-		printf("edge-triggered");
-		break;
-	case 2:
-		printf("reserved");
-		break;
-	case 3:
-		printf("level-triggered");
-		break;
-	}
-	
-	printf(", bus=%" PRIu8 " irq=%" PRIu8 " io_apic=%" PRIu8" pin=%"
-	    PRIu8 "\n", iointr->src_bus_id, iointr->src_bus_irq,
+		log_printf("bus-like");
+		break;
+	case 1:
+		log_printf("edge-triggered");
+		break;
+	case 2:
+		log_printf("reserved");
+		break;
+	case 3:
+		log_printf("level-triggered");
+		break;
+	}
+	
+	log_printf(", bus=%" PRIu8 " irq=%" PRIu8 " io_apic=%" PRIu8" pin=%"
+	    PRIu8, iointr->src_bus_id, iointr->src_bus_irq,
 	    iointr->dst_io_apic_id, iointr->dst_io_apic_pin);
+	log_end();
 #endif
 }
@@ -266,58 +268,60 @@
 {
 #ifdef MPSCT_VERBOSE
-	printf("MPS: ");
+	log_begin(LF_ARCH, LVL_DEBUG);
+	log_printf("MPS: ");
 	
 	switch (lintr->intr_type) {
 	case 0:
-		printf("INT");
-		break;
-	case 1:
-		printf("NMI");
-		break;
-	case 2:
-		printf("SMI");
-		break;
-	case 3:
-		printf("ExtINT");
-		break;
-	}
-	
-	printf(", ");
+		log_printf("INT");
+		break;
+	case 1:
+		log_printf("NMI");
+		break;
+	case 2:
+		log_printf("SMI");
+		break;
+	case 3:
+		log_printf("ExtINT");
+		break;
+	}
+	
+	log_printf(", ");
 	
 	switch (lintr->poel & 3) {
 	case 0:
-		printf("bus-like");
-		break;
-	case 1:
-		printf("active high");
-		break;
-	case 2:
-		printf("reserved");
-		break;
-	case 3:
-		printf("active low");
-		break;
-	}
-	
-	printf(", ");
+		log_printf("bus-like");
+		break;
+	case 1:
+		log_printf("active high");
+		break;
+	case 2:
+		log_printf("reserved");
+		break;
+	case 3:
+		log_printf("active low");
+		break;
+	}
+	
+	log_printf(", ");
 	
 	switch ((lintr->poel >> 2) & 3) {
 	case 0:
-		printf("bus-like");
-		break;
-	case 1:
-		printf("edge-triggered");
-		break;
-	case 2:
-		printf("reserved");
-		break;
-	case 3:
-		printf("level-triggered");
-		break;
-	}
-	
-	printf(", bus=%" PRIu8 " irq=%" PRIu8 " l_apic=%" PRIu8" pin=%"
-	    PRIu8 "\n", lintr->src_bus_id, lintr->src_bus_irq,
+		log_printf("bus-like");
+		break;
+	case 1:
+		log_printf("edge-triggered");
+		break;
+	case 2:
+		log_printf("reserved");
+		break;
+	case 3:
+		log_printf("level-triggered");
+		break;
+	}
+	
+	log_printf(", bus=%" PRIu8 " irq=%" PRIu8 " l_apic=%" PRIu8" pin=%"
+	    PRIu8, lintr->src_bus_id, lintr->src_bus_irq,
 	    lintr->dst_l_apic_id, lintr->dst_l_apic_pin);
+	log_end();
 #endif
 }
@@ -332,6 +336,7 @@
 		switch (cur[CT_EXT_ENTRY_TYPE]) {
 		default:
-			printf("MPS: Skipping MP Configuration Table extended "
-			    "entry type %" PRIu8 "\n", cur[CT_EXT_ENTRY_TYPE]);
+			log(LF_ARCH, LVL_NOTE, "MPS: Skipping MP Configuration"
+			    " Table extended entry type %" PRIu8,
+			    cur[CT_EXT_ENTRY_TYPE]);
 		}
 	}
@@ -341,15 +346,15 @@
 {
 	if (ct->signature != CT_SIGNATURE) {
-		printf("MPS: Wrong ct->signature\n");
+		log(LF_ARCH, LVL_WARN, "MPS: Wrong ct->signature");
 		return;
 	}
 	
 	if (!mps_ct_check()) {
-		printf("MPS: Wrong ct checksum\n");
+		log(LF_ARCH, LVL_WARN, "MPS: Wrong ct checksum");
 		return;
 	}
 	
 	if (ct->oem_table) {
-		printf("MPS: ct->oem_table not supported\n");
+		log(LF_ARCH, LVL_WARN, "MPS: ct->oem_table not supported");
 		return;
 	}
@@ -402,5 +407,5 @@
 			 * Something is wrong. Fallback to UP mode.
 			 */
-			printf("MPS: ct badness %" PRIu8 "\n", *cur);
+			log(LF_ARCH, LVL_WARN, "MPS: ct badness %" PRIu8, *cur);
 			return;
 		}
@@ -418,5 +423,5 @@
 	 * Not yet implemented.
 	 */
-	printf("MPS: Default configuration not supported\n");
+	log(LF_ARCH, LVL_WARN, "MPS: Default configuration not supported");
 }
 
@@ -449,9 +454,9 @@
 	
 fs_found:
-	printf("%p: MPS Floating Pointer Structure\n", fs);
+	log(LF_ARCH, LVL_NOTE, "%p: MPS Floating Pointer Structure", fs);
 	
 	if ((fs->config_type == 0) && (fs->configuration_table)) {
 		if (fs->mpfib2 >> 7) {
-			printf("MPS: PIC mode not supported\n");
+			log(LF_ARCH, LVL_WARN, "MPS: PIC mode not supported\n");
 			return;
 		}
Index: kernel/arch/ia32/src/smp/smp.c
===================================================================
--- kernel/arch/ia32/src/smp/smp.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/arch/ia32/src/smp/smp.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -52,5 +52,5 @@
 #include <mm/slab.h>
 #include <mm/as.h>
-#include <print.h>
+#include <log.h>
 #include <memstr.h>
 #include <arch/drivers/i8259.h>
@@ -129,6 +129,6 @@
 		
 		if (ops->cpu_apic_id(i) == bsp_l_apic) {
-			printf("kmp: bad processor entry #%u, will not send IPI "
-			    "to myself\n", i);
+			log(LF_ARCH, LVL_ERROR, "kmp: bad processor entry #%u, "
+			    "will not send IPI to myself", i);
 			continue;
 		}
@@ -162,10 +162,10 @@
 			if (waitq_sleep_timeout(&ap_completion_wq, 1000000,
 			    SYNCH_FLAGS_NONE) == ESYNCH_TIMEOUT) {
-				printf("%s: waiting for cpu%u (APIC ID = %d) "
-				    "timed out\n", __FUNCTION__, i,
-				    ops->cpu_apic_id(i));
+				log(LF_ARCH, LVL_NOTE, "%s: waiting for cpu%u "
+				    "(APIC ID = %d) timed out", __FUNCTION__,
+				    i, ops->cpu_apic_id(i));
 			}
 		} else
-			printf("INIT IPI for l_apic%d failed\n",
+			log(LF_ARCH, LVL_ERROR, "INIT IPI for l_apic%d failed",
 			    ops->cpu_apic_id(i));
 	}
Index: kernel/arch/mips32/src/debugger.c
===================================================================
--- kernel/arch/mips32/src/debugger.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/arch/mips32/src/debugger.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -39,4 +39,5 @@
 #include <console/cmd.h>
 #include <print.h>
+#include <log.h>
 #include <panic.h>
 #include <arch.h>
@@ -294,17 +295,21 @@
 	cmd_initialize(&bkpts_info);
 	if (!cmd_register(&bkpts_info))
-		printf("Cannot register command %s\n", bkpts_info.name);
+		log(LF_OTHER, LVL_WARN, "Cannot register command %s",
+		    bkpts_info.name);
 	
 	cmd_initialize(&delbkpt_info);
 	if (!cmd_register(&delbkpt_info))
-		printf("Cannot register command %s\n", delbkpt_info.name);
+		log(LF_OTHER, LVL_WARN, "Cannot register command %s",
+		    delbkpt_info.name);
 	
 	cmd_initialize(&addbkpt_info);
 	if (!cmd_register(&addbkpt_info))
-		printf("Cannot register command %s\n", addbkpt_info.name);
+		log(LF_OTHER, LVL_WARN, "Cannot register command %s",
+		    addbkpt_info.name);
 	
 	cmd_initialize(&addbkpte_info);
 	if (!cmd_register(&addbkpte_info))
-		printf("Cannot register command %s\n", addbkpte_info.name);
+		log(LF_OTHER, LVL_WARN, "Cannot register command %s",
+		    addbkpte_info.name);
 #endif /* CONFIG_KCONSOLE */
 }
Index: kernel/arch/mips32/src/exception.c
===================================================================
--- kernel/arch/mips32/src/exception.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/arch/mips32/src/exception.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -48,4 +48,5 @@
 #include <arch/debugger.h>
 #include <symtab.h>
+#include <log.h>
 
 static const char *exctable[] = {
@@ -74,37 +75,37 @@
 void istate_decode(istate_t *istate)
 {
-	printf("epc=%#010" PRIx32 "\tsta=%#010" PRIx32 "\t"
+	log_printf("epc=%#010" PRIx32 "\tsta=%#010" PRIx32 "\t"
 	    "lo =%#010" PRIx32 "\thi =%#010" PRIx32 "\n",
 	    istate->epc, istate->status, istate->lo, istate->hi);
 	
-	printf("a0 =%#010" PRIx32 "\ta1 =%#010" PRIx32 "\t"
+	log_printf("a0 =%#010" PRIx32 "\ta1 =%#010" PRIx32 "\t"
 	    "a2 =%#010" PRIx32 "\ta3 =%#010" PRIx32 "\n",
 	    istate->a0, istate->a1, istate->a2, istate->a3);
 	
-	printf("t0 =%#010" PRIx32 "\tt1 =%#010" PRIx32 "\t"
+	log_printf("t0 =%#010" PRIx32 "\tt1 =%#010" PRIx32 "\t"
 	    "t2 =%#010" PRIx32 "\tt3 =%#010" PRIx32 "\n",
 	    istate->t0, istate->t1, istate->t2, istate->t3);
 	
-	printf("t4 =%#010" PRIx32 "\tt5 =%#010" PRIx32 "\t"
+	log_printf("t4 =%#010" PRIx32 "\tt5 =%#010" PRIx32 "\t"
 	    "t6 =%#010" PRIx32 "\tt7 =%#010" PRIx32 "\n",
 	    istate->t4, istate->t5, istate->t6, istate->t7);
 	
-	printf("t8 =%#010" PRIx32 "\tt9 =%#010" PRIx32 "\t"
+	log_printf("t8 =%#010" PRIx32 "\tt9 =%#010" PRIx32 "\t"
 	    "v0 =%#010" PRIx32 "\tv1 =%#010" PRIx32 "\n",
 	    istate->t8, istate->t9, istate->v0, istate->v1);
 	
-	printf("s0 =%#010" PRIx32 "\ts1 =%#010" PRIx32 "\t"
+	log_printf("s0 =%#010" PRIx32 "\ts1 =%#010" PRIx32 "\t"
 	    "s2 =%#010" PRIx32 "\ts3 =%#010" PRIx32 "\n",
 	    istate->s0, istate->s1, istate->s2, istate->s3);
 	
-	printf("s4 =%#010" PRIx32 "\ts5 =%#010" PRIx32 "\t"
+	log_printf("s4 =%#010" PRIx32 "\ts5 =%#010" PRIx32 "\t"
 	    "s6 =%#010" PRIx32 "\ts7 =%#010" PRIx32 "\n",
 	    istate->s4, istate->s5, istate->s6, istate->s7);
 	
-	printf("s8 =%#010" PRIx32 "\tat =%#010" PRIx32 "\t"
+	log_printf("s8 =%#010" PRIx32 "\tat =%#010" PRIx32 "\t"
 	    "kt0=%#010" PRIx32 "\tkt1=%#010" PRIx32 "\n",
 	    istate->s8, istate->at, istate->kt0, istate->kt1);
 	
-	printf("sp =%#010" PRIx32 "\tra =%#010" PRIx32 "\t"
+	log_printf("sp =%#010" PRIx32 "\tra =%#010" PRIx32 "\t"
 	    "gp =%#010" PRIx32 "\n",
 	    istate->sp, istate->ra, istate->gp);
@@ -194,5 +195,6 @@
 				 */
 #ifdef CONFIG_DEBUG
-				printf("cpu%u: spurious interrupt (inum=%u)\n",
+				log(LF_ARCH, LVL_DEBUG,
+				    "cpu%u: spurious interrupt (inum=%u)",
 				    CPU->id, i);
 #endif
Index: kernel/arch/mips32/src/mm/tlb.c
===================================================================
--- kernel/arch/mips32/src/mm/tlb.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/arch/mips32/src/mm/tlb.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -43,4 +43,5 @@
 #include <synch/mutex.h>
 #include <print.h>
+#include <log.h>
 #include <debug.h>
 #include <align.h>
@@ -217,5 +218,5 @@
 	 */
 	if (index.p) {
-		printf("%s: TLBP failed in exception handler (badvaddr=%#"
+		log(LF_ARCH, LVL_WARN, "%s: TLBP failed in exception handler (badvaddr=%#"
 		    PRIxn ", ASID=%d).\n", __func__, badvaddr,
 		    AS ? AS->asid : -1);
Index: kernel/arch/ppc32/src/interrupt.c
===================================================================
--- kernel/arch/ppc32/src/interrupt.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/arch/ppc32/src/interrupt.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -44,4 +44,5 @@
 #include <arch/mm/pht.h>
 #include <print.h>
+#include <log.h>
 
 void start_decrementer(void)
@@ -55,44 +56,44 @@
 void istate_decode(istate_t *istate)
 {
-	printf("r0 =%0#10" PRIx32 "\tr1 =%0#10" PRIx32 "\t"
+	log_printf("r0 =%0#10" PRIx32 "\tr1 =%0#10" PRIx32 "\t"
 	    "r2 =%0#10" PRIx32 "\n", istate->r0, istate->sp, istate->r2);
 	
-	printf("r3 =%0#10" PRIx32 "\tr4 =%0#10" PRIx32 "\t"
+	log_printf("r3 =%0#10" PRIx32 "\tr4 =%0#10" PRIx32 "\t"
 	    "r5 =%0#10" PRIx32 "\n", istate->r3, istate->r4, istate->r5);
 	
-	printf("r6 =%0#10" PRIx32 "\tr7 =%0#10" PRIx32 "\t"
+	log_printf("r6 =%0#10" PRIx32 "\tr7 =%0#10" PRIx32 "\t"
 	    "r8 =%0#10" PRIx32 "\n", istate->r6, istate->r7, istate->r8);
 	
-	printf("r9 =%0#10" PRIx32 "\tr10=%0#10" PRIx32 "\t"
+	log_printf("r9 =%0#10" PRIx32 "\tr10=%0#10" PRIx32 "\t"
 	    "r11=%0#10" PRIx32 "\n", istate->r9, istate->r10, istate->r11);
 	
-	printf("r12=%0#10" PRIx32 "\tr13=%0#10" PRIx32 "\t"
+	log_printf("r12=%0#10" PRIx32 "\tr13=%0#10" PRIx32 "\t"
 	    "r14=%0#10" PRIx32 "\n", istate->r12, istate->r13, istate->r14);
 	
-	printf("r15=%0#10" PRIx32 "\tr16=%0#10" PRIx32 "\t"
+	log_printf("r15=%0#10" PRIx32 "\tr16=%0#10" PRIx32 "\t"
 	    "r17=%0#10" PRIx32 "\n", istate->r15, istate->r16, istate->r17);
 	
-	printf("r18=%0#10" PRIx32 "\tr19=%0#10" PRIx32 "\t"
+	log_printf("r18=%0#10" PRIx32 "\tr19=%0#10" PRIx32 "\t"
 	    "r20=%0#10" PRIx32 "\n", istate->r18, istate->r19, istate->r20);
 	
-	printf("r21=%0#10" PRIx32 "\tr22=%0#10" PRIx32 "\t"
+	log_printf("r21=%0#10" PRIx32 "\tr22=%0#10" PRIx32 "\t"
 	    "r23=%0#10" PRIx32 "\n", istate->r21, istate->r22, istate->r23);
 	
-	printf("r24=%0#10" PRIx32 "\tr25=%0#10" PRIx32 "\t"
+	log_printf("r24=%0#10" PRIx32 "\tr25=%0#10" PRIx32 "\t"
 	    "r26=%0#10" PRIx32 "\n", istate->r24, istate->r25, istate->r26);
 	
-	printf("r27=%0#10" PRIx32 "\tr28=%0#10" PRIx32 "\t"
+	log_printf("r27=%0#10" PRIx32 "\tr28=%0#10" PRIx32 "\t"
 	    "r29=%0#10" PRIx32 "\n", istate->r27, istate->r28, istate->r29);
 	
-	printf("r30=%0#10" PRIx32 "\tr31=%0#10" PRIx32 "\n",
+	log_printf("r30=%0#10" PRIx32 "\tr31=%0#10" PRIx32 "\n",
 	    istate->r30, istate->r31);
 	
-	printf("cr =%0#10" PRIx32 "\tpc =%0#10" PRIx32 "\t"
+	log_printf("cr =%0#10" PRIx32 "\tpc =%0#10" PRIx32 "\t"
 	    "lr =%0#10" PRIx32 "\n", istate->cr, istate->pc, istate->lr);
 	
-	printf("ctr=%0#10" PRIx32 "\txer=%0#10" PRIx32 "\t"
+	log_printf("ctr=%0#10" PRIx32 "\txer=%0#10" PRIx32 "\t"
 	    "dar=%0#10" PRIx32 "\n", istate->ctr, istate->xer, istate->dar);
 	
-	printf("srr1=%0#10" PRIx32 "\n", istate->srr1);
+	log_printf("srr1=%0#10" PRIx32 "\n", istate->srr1);
 }
 
@@ -130,6 +131,6 @@
 			 */
 #ifdef CONFIG_DEBUG
-			printf("cpu%u: spurious interrupt (inum=%" PRIu8 ")\n",
-			    CPU->id, inum);
+			log(LF_ARCH, LVL_DEBUG, "cpu%u: spurious interrupt"
+			    " (inum=%" PRIu8 ")", CPU->id, inum);
 #endif
 		}
Index: kernel/arch/sparc32/Makefile.inc
===================================================================
--- kernel/arch/sparc32/Makefile.inc	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/Makefile.inc	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,60 @@
+#
+# Copyright (c) 2010 Martin Decky
+# 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.
+#
+
+BFD = binary
+
+BITS = 32
+ENDIANESS = BE
+
+ARCH_SOURCES = \
+	arch/$(KARCH)/src/start.S \
+	arch/$(KARCH)/src/trap_table.S \
+	arch/$(KARCH)/src/context.S \
+	arch/$(KARCH)/src/debug/stacktrace.c \
+	arch/$(KARCH)/src/proc/scheduler.c \
+	arch/$(KARCH)/src/proc/task.c \
+	arch/$(KARCH)/src/proc/thread.c \
+	arch/$(KARCH)/src/sparc32.c \
+	arch/$(KARCH)/src/machine_func.c \
+	arch/$(KARCH)/src/userspace.c \
+	arch/$(KARCH)/src/exception.c \
+	arch/$(KARCH)/src/cpu/cpu.c \
+	arch/$(KARCH)/src/ddi/ddi.c \
+	arch/$(KARCH)/src/smp/smp.c \
+	arch/$(KARCH)/src/smp/ipi.c \
+	arch/$(KARCH)/src/mm/km.c \
+	arch/$(KARCH)/src/mm/as.c \
+	arch/$(KARCH)/src/mm/frame.c \
+	arch/$(KARCH)/src/mm/page.c \
+	arch/$(KARCH)/src/mm/tlb.c
+
+ifeq ($(MACHINE),leon3)
+	ARCH_SOURCES += \
+		arch/$(KARCH)/src/machine/leon3/leon3.c
+endif
+
Index: kernel/arch/sparc32/_link.ld.in
===================================================================
--- kernel/arch/sparc32/_link.ld.in	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/_link.ld.in	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,48 @@
+#define KERNEL_LOAD_ADDRESS  0x80a00000
+
+ENTRY(kernel_image_start)
+
+SECTIONS {
+	. = KERNEL_LOAD_ADDRESS;
+	
+	.text : {
+		ktext_start = .;
+		*(.text);
+		ktext_end = .;
+	}
+	
+	.data : {
+		kdata_start = .;
+		*(.data);                       /* initialized data */
+		. = ALIGN(8);
+		hardcoded_ktext_size = .;
+		LONG(ktext_end - ktext_start);
+		hardcoded_kdata_size = .;
+		LONG(kdata_end - kdata_start);
+		hardcoded_load_address = .;
+		LONG(KERNEL_LOAD_ADDRESS);
+		*(.bss);                        /* uninitialized static variables */
+		*(COMMON);                      /* global variables */
+		
+		*(.rodata*);
+		*(.sdata);
+		*(.reginfo);
+		. = ALIGN(8);
+		symbol_table = .;
+		*(symtab.*);
+	}
+	
+	.sbss : {
+		*(.sbss);
+		*(.scommon);
+	}
+	
+	kdata_end = .;
+	
+	/DISCARD/ : {
+		*(.mdebug*);
+		*(.pdr);
+		*(.comment);
+		*(.note);
+	}
+}
Index: kernel/arch/sparc32/include/arch/ambapp.h
===================================================================
--- kernel/arch/sparc32/include/arch/ambapp.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/include/arch/ambapp.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2013 Jakub Klama
+ * 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 sparc32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc32_AMBAPP_H_
+#define KERN_sparc32_AMBAPP_H_
+
+typedef struct {
+	/* Primary serial port location */
+	uintptr_t uart_base;
+	size_t uart_size;
+	int uart_irq;
+	/* Timers location */
+	uintptr_t timer_base;
+	size_t timer_size;
+	int timer_irq;
+} ambapp_info_t;
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc32/include/arch/arch.h
===================================================================
--- kernel/arch/sparc32/include/arch/arch.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/include/arch/arch.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2010 Martin Decky
+ * Copyright (c) 2013 Jakub Klama
+ * 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 sparc32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc32_ARCH_H_
+#define KERN_sparc32_ARCH_H_
+
+#ifndef __ASM__
+
+#include <typedefs.h>
+#include <arch/istate.h>
+
+#define NWINDOWS  8
+
+/* ASI assignments: */
+#define ASI_CACHEMISS  0x01
+#define ASI_CACHECTRL  0x02
+#define ASI_MMUCACHE   0x10
+#define ASI_MMUREGS    0x19
+#define ASI_MMUBYPASS  0x1c
+#define ASI_MMUFLUSH   0x18
+
+#define TASKMAP_MAX_RECORDS  32
+#define CPUMAP_MAX_RECORDS   32
+
+#define BOOTINFO_TASK_NAME_BUFLEN  32
+
+typedef struct {
+	void *addr;
+	size_t size;
+	char name[BOOTINFO_TASK_NAME_BUFLEN];
+} utask_t;
+
+typedef struct {
+	size_t cnt;
+	utask_t tasks[TASKMAP_MAX_RECORDS];
+	/* Fields below are LEON-specific */
+	uintptr_t uart_base;
+	uintptr_t intc_base;
+	uintptr_t timer_base;
+	int uart_irq;
+	int timer_irq;
+	uint32_t memsize;
+} bootinfo_t;
+
+extern void arch_pre_main(void *, bootinfo_t *);
+extern void write_to_invalid(uint32_t, uint32_t, uint32_t);
+extern void read_from_invalid(uint32_t *, uint32_t *, uint32_t *);
+extern void preemptible_save_uspace(uintptr_t, istate_t *);
+extern void preemptible_restore_uspace(uintptr_t, istate_t *);
+extern void flush_windows(void);
+
+#endif
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc32/include/arch/asm.h
===================================================================
--- kernel/arch/sparc32/include/arch/asm.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/include/arch/asm.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2010 Martin Decky
+ * 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 sparc32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc32_ASM_H_
+#define KERN_sparc32_ASM_H_
+
+#include <typedefs.h>
+#include <config.h>
+#include <trace.h>
+#include <arch/register.h>
+
+NO_TRACE static inline void asm_delay_loop(uint32_t usec)
+{
+	// FIXME TODO
+}
+
+NO_TRACE static inline __attribute__((noreturn)) void cpu_halt(void)
+{
+	// FIXME TODO
+	while (true);
+}
+
+NO_TRACE static inline void cpu_sleep(void)
+{
+	// FIXME TODO
+}
+
+NO_TRACE static inline void pio_write_8(ioport8_t *port, uint8_t val)
+{
+	*port = val;
+}
+
+NO_TRACE static inline void pio_write_16(ioport16_t *port, uint16_t val)
+{
+	*port = val;
+}
+
+NO_TRACE static inline void pio_write_32(ioport32_t *port, uint32_t val)
+{
+	*port = val;
+}
+
+NO_TRACE static inline uint8_t pio_read_8(ioport8_t *port)
+{
+	return *port;
+}
+
+NO_TRACE static inline uint16_t pio_read_16(ioport16_t *port)
+{
+	return *port;
+}
+
+NO_TRACE static inline uint32_t pio_read_32(ioport32_t *port)
+{
+	return *port;
+}
+
+NO_TRACE static inline uint32_t psr_read(void)
+{
+	uint32_t v;
+	
+	asm volatile (
+		"mov %%psr, %[v]\n"
+		: [v] "=r" (v)
+	);
+	
+	return v;
+}
+
+NO_TRACE static inline uint32_t wim_read(void)
+{
+	uint32_t v;
+	
+	asm volatile (
+		"mov %%wim, %[v]\n"
+		: [v] "=r" (v)
+	);
+	
+	return v;
+}
+
+NO_TRACE static inline uint32_t asi_u32_read(unsigned int asi, uintptr_t va)
+{
+	uint32_t v;
+	
+	asm volatile (
+		"lda [%[va]] %[asi], %[v]\n"
+		: [v] "=r" (v)
+		: [va] "r" (va),
+		  [asi] "i" (asi)
+	);
+	
+	return v;
+}
+
+NO_TRACE static inline void asi_u32_write(unsigned int asi, uintptr_t va,
+    uint32_t v)
+{
+	asm volatile (
+		"sta %[v], [%[va]] %[asi]\n"
+		:: [v] "r" (v),
+		   [va] "r" (va),
+		   [asi] "i" (asi)
+		: "memory"
+	);
+}
+
+NO_TRACE static inline void psr_write(uint32_t psr)
+{
+	asm volatile (
+		"mov %[v], %%psr\n"
+		:: [v] "r" (psr)
+	);
+}
+
+NO_TRACE static inline void wim_write(uint32_t wim)
+{
+	asm volatile (
+		"mov %[v], %%wim\n"
+		:: [v] "r" (wim)
+	);
+}
+
+NO_TRACE static inline ipl_t interrupts_enable(void)
+{
+	psr_reg_t psr;
+	psr.value = psr_read();
+	
+	ipl_t pil;
+	pil = psr.pil;
+	
+	psr.pil = 0x00;
+	psr_write(psr.value);
+	
+	return pil;
+}
+
+NO_TRACE static inline ipl_t interrupts_disable(void)
+{
+	psr_reg_t psr;
+	psr.value = psr_read();
+	
+	ipl_t pil;
+	pil = psr.pil;
+	
+	psr.pil = 0x0f;
+	psr_write(psr.value);
+	
+	return pil;
+}
+
+NO_TRACE static inline void interrupts_restore(ipl_t ipl)
+{
+	psr_reg_t psr;
+	psr.value = psr_read();
+	psr.pil = ipl;
+	psr_write(psr.value);
+}
+
+NO_TRACE static inline ipl_t interrupts_read(void)
+{
+	psr_reg_t psr;
+	psr.value = psr_read();
+	return psr.pil;
+}
+
+NO_TRACE static inline bool interrupts_disabled(void)
+{
+	psr_reg_t psr;
+	psr.value = psr_read();
+	return (psr.pil == 0x0f);
+}
+
+NO_TRACE static inline uintptr_t get_stack_base(void)
+{
+	uintptr_t v;
+	
+	asm volatile (
+		"and %%sp, %[size], %[v]\n" 
+		: [v] "=r" (v)
+		: [size] "r" (~(STACK_SIZE - 1))
+	);
+	
+	return v;
+}
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc32/include/arch/atomic.h
===================================================================
--- kernel/arch/sparc32/include/arch/atomic.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/include/arch/atomic.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2010 Martin Decky
+ * 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 sparc32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc32_ATOMIC_H_
+#define KERN_sparc32_ATOMIC_H_
+
+#include <typedefs.h>
+#include <arch/asm.h>
+#include <arch/barrier.h>
+#include <preemption.h>
+#include <verify.h>
+#include <trace.h>
+
+NO_TRACE ATOMIC static inline void atomic_inc(atomic_t *val)
+    WRITES(&val->count)
+    REQUIRES_EXTENT_MUTABLE(val)
+    REQUIRES(val->count < ATOMIC_COUNT_MAX)
+{
+	// FIXME: Isn't there any intrinsic atomic operation?
+	ipl_t ipl = interrupts_disable();
+	val->count++;
+	interrupts_restore(ipl);
+}
+
+NO_TRACE ATOMIC static inline void atomic_dec(atomic_t *val)
+    WRITES(&val->count)
+    REQUIRES_EXTENT_MUTABLE(val)
+    REQUIRES(val->count > ATOMIC_COUNT_MIN)
+{
+	// FIXME: Isn't there any intrinsic atomic operation?
+	ipl_t ipl = interrupts_disable();
+	val->count--;
+	interrupts_restore(ipl);
+}
+
+NO_TRACE ATOMIC static inline atomic_count_t atomic_postinc(atomic_t *val)
+    WRITES(&val->count)
+    REQUIRES_EXTENT_MUTABLE(val)
+    REQUIRES(val->count < ATOMIC_COUNT_MAX)
+{
+	// FIXME: Isn't there any intrinsic atomic operation?
+	
+	ipl_t ipl = interrupts_disable();
+	atomic_count_t prev = val->count;
+	
+	val->count++;
+	interrupts_restore(ipl);
+	return prev;
+}
+
+NO_TRACE ATOMIC static inline atomic_count_t atomic_postdec(atomic_t *val)
+    WRITES(&val->count)
+    REQUIRES_EXTENT_MUTABLE(val)
+    REQUIRES(val->count > ATOMIC_COUNT_MIN)
+{
+	// FIXME: Isn't there any intrinsic atomic operation?
+	
+	ipl_t ipl = interrupts_disable();
+	atomic_count_t prev = val->count;
+	
+	val->count--;
+	interrupts_restore(ipl);
+	return prev;
+}
+
+#define atomic_preinc(val)  (atomic_postinc(val) + 1)
+#define atomic_predec(val)  (atomic_postdec(val) - 1)
+
+NO_TRACE ATOMIC static inline atomic_count_t test_and_set(atomic_t *val)
+    WRITES(&val->count)
+    REQUIRES_EXTENT_MUTABLE(val)
+{
+	atomic_count_t prev;
+	volatile uintptr_t ptr = (uintptr_t) &val->count;
+	
+	asm volatile (
+		"ldstub [%[ptr]] %[prev]\n"
+		: [prev] "=r" (prev)
+		: [ptr] "r" (ptr)
+		: "memory"
+	);
+	
+	return prev;
+}
+
+NO_TRACE static inline void atomic_lock_arch(atomic_t *val)
+    WRITES(&val->count)
+    REQUIRES_EXTENT_MUTABLE(val)
+{
+	atomic_count_t tmp1 = 0;
+	
+	volatile uintptr_t ptr = (uintptr_t) &val->count;
+	
+	preemption_disable();
+	
+	asm volatile (
+		"0:\n"
+			"ldstub %0, %1\n"
+			"tst %1\n"
+			"be 2f\n"
+			"nop\n"
+		"1:\n"
+			"ldub %0, %1\n"
+			"tst %1\n"
+			"bne 1b\n"
+			"nop\n"
+			"ba,a 0b\n"
+		"2:\n"
+		: "+m" (*((atomic_count_t *) ptr)),
+		  "+r" (tmp1)
+		: "r" (0)
+	);
+	
+	/*
+	 * Prevent critical section code from bleeding out this way up.
+	 */
+	CS_ENTER_BARRIER();
+}
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc32/include/arch/barrier.h
===================================================================
--- kernel/arch/sparc32/include/arch/barrier.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/include/arch/barrier.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2005 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 sparc32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc32_BARRIER_H_
+#define KERN_sparc32_BARRIER_H_
+
+/*
+ * Provisions are made to prevent compiler from reordering instructions itself.
+ */
+
+#define CS_ENTER_BARRIER() \
+	asm volatile ( \
+		"stbar\n" \
+		::: "memory" \
+	)
+
+#define CS_LEAVE_BARRIER() \
+	asm volatile ( \
+		"stbar\n" \
+		::: "memory" \
+	)
+
+#define memory_barrier() \
+	asm volatile ( \
+		"stbar\n" \
+		::: "memory" \
+	)
+
+#define read_barrier() \
+	asm volatile ( \
+		"stbar\n" \
+		::: "memory" \
+	)
+
+#define write_barrier() \
+	asm volatile ( \
+		"stbar\n" \
+		::: "memory" \
+	)
+
+#define smc_coherence(addr)
+#define smc_coherence_block(addr, size)
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc32/include/arch/context.h
===================================================================
--- kernel/arch/sparc32/include/arch/context.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/include/arch/context.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2005 Jakub Jermar
+ * Copyright (c) 2013 Jakub Klama
+ * 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 sparc32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc32_CONTEXT_H_
+#define KERN_sparc32_CONTEXT_H_
+
+#include <arch/stack.h>
+#include <typedefs.h>
+#include <align.h>
+
+#define SP_DELTA  (STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE)
+
+#define context_set(c, _pc, stack, size) \
+	do { \
+		(c)->pc = ((uintptr_t) _pc) - 8; \
+		(c)->sp = ((uintptr_t) stack) + ALIGN_UP((size), \
+		    STACK_ALIGNMENT) - (SP_DELTA); \
+		(c)->fp = (c)->fp; \
+	} while (0)
+
+/*
+ * Save only registers that must be preserved across
+ * function calls.
+ */
+typedef struct {
+	uintptr_t sp;  /* %o6 */
+	uintptr_t pc;  /* %o7 */
+	uint32_t i0;
+	uint32_t i1;
+	uint32_t i2;
+	uint32_t i3;
+	uint32_t i4;
+	uint32_t i5;
+	uintptr_t fp;  /* %i6 */
+	uintptr_t i7;
+	uint32_t l0;
+	uint32_t l1;
+	uint32_t l2;
+	uint32_t l3;
+	uint32_t l4;
+	uint32_t l5;
+	uint32_t l6;
+	uint32_t l7;
+	ipl_t ipl;
+} context_t;
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc32/include/arch/context_offset.h
===================================================================
--- kernel/arch/sparc32/include/arch/context_offset.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/include/arch/context_offset.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2005 Jakub Jermar
+ * Copyright (c) 2013 Jakub Klama
+ * 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.
+ */
+
+#ifndef KERN_sparc32_CONTEXT_OFFSET_H_
+#define KERN_sparc32_CONTEXT_OFFSET_H_
+
+#define OFFSET_SP  0
+#define OFFSET_PC  4
+#define OFFSET_I0  8
+#define OFFSET_I1  12
+#define OFFSET_I2  16
+#define OFFSET_I3  20
+#define OFFSET_I4  24
+#define OFFSET_I5  28
+#define OFFSET_FP  32
+#define OFFSET_I7  36
+#define OFFSET_L0  40
+#define OFFSET_L1  44
+#define OFFSET_L2  48
+#define OFFSET_L3  52
+#define OFFSET_L4  56
+#define OFFSET_L5  60
+#define OFFSET_L6  64
+#define OFFSET_L7  68
+
+#ifndef KERNEL
+
+#define OFFSET_TP  72
+
+#endif
+
+#ifdef __ASM__
+
+.macro CONTEXT_SAVE_ARCH_CORE ctx:req
+	st %sp, [\ctx + OFFSET_SP]
+	st %o7, [\ctx + OFFSET_PC]
+	st %i0, [\ctx + OFFSET_I0]
+	st %i1, [\ctx + OFFSET_I1]
+	st %i2, [\ctx + OFFSET_I2]
+	st %i3, [\ctx + OFFSET_I3]
+	st %i4, [\ctx + OFFSET_I4]
+	st %i5, [\ctx + OFFSET_I5]
+	st %fp, [\ctx + OFFSET_FP]
+	st %i7, [\ctx + OFFSET_I7]
+	st %l0, [\ctx + OFFSET_L0]
+	st %l1, [\ctx + OFFSET_L1]
+	st %l2, [\ctx + OFFSET_L2]
+	st %l3, [\ctx + OFFSET_L3]
+	st %l4, [\ctx + OFFSET_L4]
+	st %l5, [\ctx + OFFSET_L5]
+	st %l6, [\ctx + OFFSET_L6]
+	st %l7, [\ctx + OFFSET_L7]
+#ifndef KERNEL
+	st %g7, [\ctx + OFFSET_TP]
+#endif
+.endm
+
+.macro CONTEXT_RESTORE_ARCH_CORE ctx:req
+	ld [\ctx + OFFSET_SP], %sp
+	ld [\ctx + OFFSET_PC], %o7
+	ld [\ctx + OFFSET_I0], %i0
+	ld [\ctx + OFFSET_I1], %i1
+	ld [\ctx + OFFSET_I2], %i2
+	ld [\ctx + OFFSET_I3], %i3
+	ld [\ctx + OFFSET_I4], %i4
+	ld [\ctx + OFFSET_I5], %i5
+	ld [\ctx + OFFSET_FP], %fp
+	ld [\ctx + OFFSET_I7], %i7
+	ld [\ctx + OFFSET_L0], %l0
+	ld [\ctx + OFFSET_L1], %l1
+	ld [\ctx + OFFSET_L2], %l2
+	ld [\ctx + OFFSET_L3], %l3
+	ld [\ctx + OFFSET_L4], %l4
+	ld [\ctx + OFFSET_L5], %l5
+	ld [\ctx + OFFSET_L6], %l6
+	ld [\ctx + OFFSET_L7], %l7
+#ifndef KERNEL
+	ld [\ctx + OFFSET_TP], %g7
+#endif
+.endm
+
+#endif /* __ASM__ */
+
+#endif
Index: kernel/arch/sparc32/include/arch/cpu.h
===================================================================
--- kernel/arch/sparc32/include/arch/cpu.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/include/arch/cpu.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2010 Martin Decky
+ * 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 sparc32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc32_CPU_H_
+#define KERN_sparc32_CPU_H_
+
+typedef struct {
+} cpu_arch_t;
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc32/include/arch/cycle.h
===================================================================
--- kernel/arch/sparc32/include/arch/cycle.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/include/arch/cycle.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2010 Martin Decky
+ * 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 sparc32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc32_CYCLE_H_
+#define KERN_sparc32_CYCLE_H_
+
+#include <trace.h>
+
+NO_TRACE static inline uint64_t get_cycle(void)
+{
+	// FIXME TODO
+	return 0;
+}
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc32/include/arch/elf.h
===================================================================
--- kernel/arch/sparc32/include/arch/elf.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/include/arch/elf.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2010 Martin Decky
+ * 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 sparc32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc32_ELF_H_
+#define KERN_sparc32_ELF_H_
+
+#define ELF_MACHINE        EM_SPARC
+#define ELF_DATA_ENCODING  ELFDATA2MSB
+#define ELF_CLASS          ELFCLASS32
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc32/include/arch/exception.h
===================================================================
--- kernel/arch/sparc32/include/arch/exception.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/include/arch/exception.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2005 Jakub Jermar
+ * Copyright (c) 2013 Jakub Klama
+ * 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 sparc64interrupt
+ * @{
+ */
+/**
+ * @file
+ */
+
+#ifndef KERN_sparc32_EXCEPTION_H_
+#define KERN_sparc32_EXCEPTION_H_
+
+#define TT_INSTRUCTION_ACCESS_EXCEPTION  0x01
+#define TT_ILLEGAL_INSTRUCTION           0x02
+#define TT_PRIVILEGED_INSTRUCTION        0x03
+#define TT_MEM_ADDRESS_NOT_ALIGNED       0x07
+#define TT_FP_DISABLED                   0x08
+#define TT_DATA_ACCESS_EXCEPTION         0x09
+#define TT_INSTRUCTION_ACCESS_ERROR      0x21
+#define TT_DATA_ACCESS_ERROR             0x29
+#define TT_DIVISION_BY_ZERO              0x2a
+#define TT_DATA_ACCESS_MMU_MISS          0x2c
+#define TT_INSTRUCTION_ACCESS_MMU_MISS   0x3c
+
+#ifndef __ASM__
+
+extern void instruction_access_exception(int, istate_t *);
+extern void instruction_access_error(int, istate_t *);
+extern void illegal_instruction(int, istate_t *);
+extern void privileged_instruction(int, istate_t *);
+extern void fp_disabled(int, istate_t *);
+extern void fp_exception(int, istate_t *);
+extern void tag_overflow(int, istate_t *);
+extern void division_by_zero(int, istate_t *);
+extern void data_access_exception(int, istate_t *);
+extern void data_access_error(int, istate_t *);
+extern void data_access_mmu_miss(int, istate_t *);
+extern void data_store_error(int, istate_t *);
+extern void mem_address_not_aligned(int, istate_t *);
+
+extern sysarg_t syscall(sysarg_t, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t);
+extern void irq_exception(unsigned int, istate_t *);
+
+#endif /* !__ASM__ */
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc32/include/arch/faddr.h
===================================================================
--- kernel/arch/sparc32/include/arch/faddr.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/include/arch/faddr.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2010 Martin Decky
+ * 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 sparc32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc32_FADDR_H_
+#define KERN_sparc32_FADDR_H_
+
+#include <typedefs.h>
+
+#define FADDR(fptr)  ((uintptr_t) (fptr))
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc32/include/arch/fpu_context.h
===================================================================
--- kernel/arch/sparc32/include/arch/fpu_context.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/include/arch/fpu_context.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2010 Martin Decky
+ * 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 sparc32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc32_FPU_CONTEXT_H_
+#define KERN_sparc32_FPU_CONTEXT_H_
+
+#include <typedefs.h>
+
+#define FPU_CONTEXT_ALIGN  16
+
+typedef struct {
+} fpu_context_t;
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc32/include/arch/interrupt.h
===================================================================
--- kernel/arch/sparc32/include/arch/interrupt.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/include/arch/interrupt.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2010 Martin Decky
+ * 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 sparc32interrupt
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc32_INTERRUPT_H_
+#define KERN_sparc32_INTERRUPT_H_
+
+#include <typedefs.h>
+#include <arch/istate.h>
+
+#define IVT_ITEMS  32
+#define IVT_FIRST  0
+
+#define VECTOR_TLB_SHOOTDOWN_IPI  0
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc32/include/arch/istate.h
===================================================================
--- kernel/arch/sparc32/include/arch/istate.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/include/arch/istate.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2010 Martin Decky
+ * 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 sparc32interrupt
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc32_ISTATE_H_
+#define KERN_sparc32_ISTATE_H_
+
+#include <trace.h>
+
+#ifdef KERNEL
+
+#include <verify.h>
+
+#else /* KERNEL */
+
+#define REQUIRES_EXTENT_MUTABLE(arg)
+#define WRITES(arg)
+
+#endif /* KERNEL */
+
+typedef struct istate {
+	uintptr_t pstate;
+	uintptr_t pc;
+	uintptr_t npc;
+	uint32_t stack[];
+} istate_t;
+
+NO_TRACE static inline int istate_from_uspace(istate_t *istate)
+    REQUIRES_EXTENT_MUTABLE(istate)
+{
+	return !(istate->pc & UINT32_C(0x80000000));
+}
+
+NO_TRACE static inline void istate_set_retaddr(istate_t *istate,
+    uintptr_t retaddr)
+    WRITES(&istate->ip)
+{
+	istate->pc = retaddr;
+}
+
+NO_TRACE static inline uintptr_t istate_get_pc(istate_t *istate)
+    REQUIRES_EXTENT_MUTABLE(istate)
+{
+	return istate->pc;
+}
+
+NO_TRACE static inline uintptr_t istate_get_fp(istate_t *istate)
+    REQUIRES_EXTENT_MUTABLE(istate)
+{
+	return 0;
+}
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc32/include/arch/machine/leon3/leon3.h
===================================================================
--- kernel/arch/sparc32/include/arch/machine/leon3/leon3.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/include/arch/machine/leon3/leon3.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2010 Jiri Svoboda
+ * 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 sparc32leon3
+ * @brief LEON3 System-on-chip.
+ * @ingroup sparc32
+ * @{
+ */
+
+#ifndef KERN_sparc32_LEON3_H_
+#define KERN_sparc32_LEON3_H_
+
+#include <arch/machine_func.h>
+
+#define LEON3_SDRAM_START  0x40000000
+#define LEON3_IRQ_COUNT    15
+
+extern struct sparc_machine_ops leon3_machine_ops;
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc32/include/arch/machine_func.h
===================================================================
--- kernel/arch/sparc32/include/arch/machine_func.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/include/arch/machine_func.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2007 Michal Kebrt
+ * Copyright (c) 2009 Vineeth Pillai
+ * 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 sparc32
+ * @{
+ */
+/** @file
+ * @brief Declarations of machine specific functions.
+ *
+ * These functions enable to differentiate more kinds of SPARC emulators
+ * or CPUs. It is the same concept as "arch" functions on the architecture
+ * level.
+ */
+
+#ifndef KERN_sparc32_MACHINE_FUNC_H_
+#define KERN_sparc32_MACHINE_FUNC_H_
+
+#include <arch.h>
+
+#include <console/console.h>
+#include <typedefs.h>
+#include <arch/exception.h>
+
+struct sparc_machine_ops {
+	void (*machine_init)(bootinfo_t *);
+	void (*machine_cpu_halt)(void);
+	void (*machine_get_memory_extents)(uintptr_t *, size_t *);
+	void (*machine_timer_irq_start)(void);
+	void (*machine_irq_exception)(unsigned int, istate_t *);
+	void (*machine_output_init)(void);
+	void (*machine_input_init)(void);
+	size_t (*machine_get_irq_count)(void);
+	const char *(*machine_get_platform_name)(void);
+};
+
+/** Pointer to sparc_machine_ops structure being used. */
+extern struct sparc_machine_ops *machine_ops;
+
+/** Initialize machine_ops pointer. */
+extern void machine_ops_init(void);
+
+/** Map HW devices to the kernel address space using #hw_map. */
+extern void machine_init(bootinfo_t *);
+
+/** Start timer. */
+extern void machine_timer_irq_start(void);
+
+/** Halt CPU. */
+extern void machine_cpu_halt(void);
+
+/** Get extents of available memory.
+ *
+ * @param start Place to store memory start address.
+ * @param size  Place to store memory size.
+ */
+extern void machine_get_memory_extents(uintptr_t *start, size_t *size);
+
+/** Interrupt exception handler.
+ *
+ * @param exc_no Interrupt exception number.
+ * @param istate Saved processor state.
+ */
+extern void machine_irq_exception(unsigned int exc_no, istate_t *istate);
+
+/** Machine specific frame initialization */
+extern void machine_frame_init(void);
+
+/* Configure the serial line output device. */
+extern void machine_output_init(void);
+
+/** Configure the serial line input device. */
+extern void machine_input_init(void);
+
+extern size_t machine_get_irq_count(void);
+
+extern const char *machine_get_platform_name(void);
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc32/include/arch/mm/as.h
===================================================================
--- kernel/arch/sparc32/include/arch/mm/as.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/include/arch/mm/as.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2010 Martin Decky
+ * Copyright (c) 2013 Jakub Klama
+ * 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 sparc32mm
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc32_AS_H_
+#define KERN_sparc32_AS_H_
+
+#define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH  0
+
+#define KERNEL_ADDRESS_SPACE_START_ARCH  UINT32_C(0x80000000)
+#define KERNEL_ADDRESS_SPACE_END_ARCH    UINT32_C(0xffffffff)
+#define USER_ADDRESS_SPACE_START_ARCH    UINT32_C(0x00000000)
+#define USER_ADDRESS_SPACE_END_ARCH      UINT32_C(0x7fffffff)
+
+typedef struct {
+} as_arch_t;
+
+#include <genarch/mm/as_pt.h>
+
+#define as_constructor_arch(as, flags)  (as != as)
+#define as_destructor_arch(as)          (as != as)
+#define as_create_arch(as, flags)       (as != as)
+#define as_deinstall_arch(as)
+#define as_invalidate_translation_cache(as, page, cnt)
+
+extern uintptr_t as_context_table;
+
+extern void as_arch_init(void);
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc32/include/arch/mm/asid.h
===================================================================
--- kernel/arch/sparc32/include/arch/mm/asid.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/include/arch/mm/asid.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2010 Martin Decky
+ * 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 sparc32mm
+ * @{
+ */
+
+#ifndef KERN_sparc32_ASID_H_
+#define KERN_sparc32_ASID_H_
+
+#include <typedefs.h>
+
+typedef uint32_t asid_t;
+
+#define ASID_MAX_ARCH  255
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc32/include/arch/mm/frame.h
===================================================================
--- kernel/arch/sparc32/include/arch/mm/frame.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/include/arch/mm/frame.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2010 Martin Decky
+ * 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 sparc32mm
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc32_FRAME_H_
+#define KERN_sparc32_FRAME_H_
+
+#define FRAME_WIDTH  12  /* 4K */
+#define FRAME_SIZE   (1 << FRAME_WIDTH)
+
+#include <typedefs.h>
+
+#define PHYSMEM_START_ADDR  0x40000000
+
+#define BOOT_PT_ADDRESS      0x40008000
+#define BOOT_PT_START_FRAME  (BOOT_PT_ADDRESS >> FRAME_WIDTH)
+#define BOOT_PT_SIZE_FRAMES  1
+
+extern void frame_low_arch_init(void);
+extern void frame_high_arch_init(void);
+extern void physmem_print(void);
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc32/include/arch/mm/km.h
===================================================================
--- kernel/arch/sparc32/include/arch/mm/km.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/include/arch/mm/km.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2011 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 sparc32mm
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc32_KM_H_
+#define KERN_sparc32_KM_H_
+
+#include <typedefs.h>
+
+#define KM_SPARC32_IDENTITY_START  UINT32_C(0x80000000)
+#define KM_SPARC32_IDENTITY_SIZE   UINT32_C(0x70000000)
+
+#define KM_SPARC32_NON_IDENTITY_START  UINT32_C(0xf0000000)
+#define KM_SPARC32_NON_IDENTITY_SIZE   UINT32_C(0xff00000)
+
+extern void km_identity_arch_init(void);
+extern void km_non_identity_arch_init(void);
+extern bool km_is_non_identity_arch(uintptr_t);
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc32/include/arch/mm/page.h
===================================================================
--- kernel/arch/sparc32/include/arch/mm/page.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/include/arch/mm/page.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,267 @@
+/*
+ * Copyright (c) 2010 Martin Decky
+ * Copyright (c) 2013 Jakub Klama
+ * 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 sparc32mm
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc32_PAGE_H_
+#define KERN_sparc32_PAGE_H_
+
+#ifndef __ASM__
+
+#include <arch/mm/frame.h>
+#include <trace.h>
+
+#define PAGE_WIDTH  FRAME_WIDTH
+#define PAGE_SIZE   FRAME_SIZE
+
+#define FRAME_LOWPRIO  0
+
+#define KA2PA(x)  (((uintptr_t) (x)) - UINT32_C(0x40000000))
+#define PA2KA(x)  (((uintptr_t) (x)) + UINT32_C(0x40000000))
+
+#define PTE_ET_INVALID     0
+#define PTE_ET_DESCRIPTOR  1
+#define PTE_ET_ENTRY       2
+
+#define PTE_ACC_USER_RO_KERNEL_RO    0
+#define PTE_ACC_USER_RW_KERNEL_RW    1
+#define PTE_ACC_USER_RX_KERNEL_RX    2
+#define PTE_ACC_USER_RWX_KERNEL_RWX  3
+#define PTE_ACC_USER_XO_KERNEL_XO    4
+#define PTE_ACC_USER_RO_KERNEL_RW    5
+#define PTE_ACC_USER_NO_KERNEL_RX    6
+#define PTE_ACC_USER_NO_KERNEL_RWX   7
+
+/* Number of entries in each level. */
+#define PTL0_ENTRIES_ARCH  256
+#define PTL1_ENTRIES_ARCH  0
+#define PTL2_ENTRIES_ARCH  64
+#define PTL3_ENTRIES_ARCH  64
+
+/* Page table sizes for each level. */
+#define PTL0_FRAMES_ARCH  1
+#define PTL1_FRAMES_ARCH  1
+#define PTL2_FRAMES_ARCH  1
+#define PTL3_FRAMES_ARCH  1
+
+/* Macros calculating indices for each level. */
+#define PTL0_INDEX_ARCH(vaddr)  (((vaddr) >> 24) & 0xffU)
+#define PTL1_INDEX_ARCH(vaddr)  0
+#define PTL2_INDEX_ARCH(vaddr)  (((vaddr) >> 18) & 0x3fU)
+#define PTL3_INDEX_ARCH(vaddr)  (((vaddr) >> 12) & 0x3fU)
+
+/* Get PTE address accessors for each level. */
+#define GET_PTL1_ADDRESS_ARCH(ptl0, i) \
+	((pte_t *) ((((pte_t *) (ptl0))[(i)].frame_address) << 12))
+#define GET_PTL2_ADDRESS_ARCH(ptl1, i) \
+	KA2PA(ptl1)
+#define GET_PTL3_ADDRESS_ARCH(ptl2, i) \
+	((pte_t *) ((((pte_t *) (ptl2))[(i)].frame_address) << 12))
+#define GET_FRAME_ADDRESS_ARCH(ptl3, i) \
+	((uintptr_t) ((((pte_t *) (ptl3))[(i)].frame_address) << 12))
+
+/* Set PTE address accessors for each level. */
+#define SET_PTL0_ADDRESS_ARCH(ptl0)
+#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) \
+	(((pte_t *) (ptl0))[(i)].frame_address = (a) >> 12)
+#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a)
+#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a) \
+	(((pte_t *) (ptl2))[(i)].frame_address = (a) >> 12)
+#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) \
+	(((pte_t *) (ptl3))[(i)].frame_address = (a) >> 12)
+
+/* Get PTE flags accessors for each level. */
+#define GET_PTL1_FLAGS_ARCH(ptl0, i) \
+	get_pt_flags((pte_t *) (ptl0), (size_t) (i))
+#define GET_PTL2_FLAGS_ARCH(ptl1, i) \
+	PAGE_PRESENT
+#define GET_PTL3_FLAGS_ARCH(ptl2, i) \
+	get_pt_flags((pte_t *) (ptl2), (size_t) (i))
+#define GET_FRAME_FLAGS_ARCH(ptl3, i) \
+	get_pt_flags((pte_t *) (ptl3), (size_t) (i))
+
+/* Set PTE flags accessors for each level. */
+#define SET_PTL1_FLAGS_ARCH(ptl0, i, x)
+#define SET_PTL2_FLAGS_ARCH(ptl1, i, x)
+#define SET_PTL3_FLAGS_ARCH(ptl2, i, x)
+#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) \
+	set_pte_flags((pte_t *) (ptl3), (size_t) (i), (x))
+
+/* Set PTE present bit accessors for each level. */
+#define SET_PTL1_PRESENT_ARCH(ptl0, i)	\
+	set_ptd_present((pte_t *) (ptl0), (size_t) (i))
+#define SET_PTL2_PRESENT_ARCH(ptl1, i)
+#define SET_PTL3_PRESENT_ARCH(ptl2, i) \
+	set_ptd_present((pte_t *) (ptl2), (size_t) (i))
+#define SET_FRAME_PRESENT_ARCH(ptl3, i) \
+	set_pte_present((pte_t *) (ptl3), (size_t) (i))
+
+/* Macros for querying the last level entries. */
+#define PTE_VALID_ARCH(p) \
+	(*((uint32_t *) (p)) != 0)
+#define PTE_PRESENT_ARCH(p) \
+	((p)->et != 0)
+#define PTE_GET_FRAME_ARCH(p) \
+	((p)->frame_address << FRAME_WIDTH)
+#define PTE_WRITABLE_ARCH(p) \
+	pte_is_writeable(p)
+#define PTE_EXECUTABLE_ARCH(p) \
+	pte_is_executable(p)
+
+#include <mm/mm.h>
+#include <arch/interrupt.h>
+#include <typedefs.h>
+
+/** Page Table Descriptor. */
+typedef struct {
+	unsigned int table_pointer : 30;
+	unsigned int et : 2;
+} __attribute__((packed)) ptd_t;
+
+/** Page Table Entry. */
+typedef struct {
+	unsigned int frame_address : 24;
+	unsigned int cacheable : 1;
+	unsigned int modified : 1;
+	unsigned int referenced : 1;
+	unsigned int acc : 3;
+	unsigned int et : 2;
+} __attribute__((packed)) pte_t;
+
+NO_TRACE static inline void set_ptl0_addr(pte_t *pt)
+{
+}
+
+NO_TRACE static inline bool pte_is_writeable(pte_t *pt)
+{
+	return ((pt->acc == PTE_ACC_USER_RW_KERNEL_RW) ||
+	    (pt->acc == PTE_ACC_USER_RWX_KERNEL_RWX) ||
+	    (pt->acc == PTE_ACC_USER_RO_KERNEL_RW) ||
+	    (pt->acc == PTE_ACC_USER_NO_KERNEL_RWX));
+}
+
+NO_TRACE static inline bool pte_is_executable(pte_t *pt)
+{
+	return ((pt->acc != PTE_ACC_USER_RO_KERNEL_RO) &&
+	    (pt->acc != PTE_ACC_USER_RW_KERNEL_RW) &&
+	    (pt->acc != PTE_ACC_USER_RO_KERNEL_RW));
+}
+
+NO_TRACE static inline unsigned int get_pt_flags(pte_t *pt, size_t i)
+    REQUIRES_ARRAY_MUTABLE(pt, PTL0_ENTRIES_ARCH)
+{
+	pte_t *p = &pt[i];
+	
+	bool notpresent = (p->et == 0);
+	
+	return ((p->cacheable << PAGE_CACHEABLE_SHIFT) |
+	    (notpresent << PAGE_PRESENT_SHIFT) |
+	    (((p->acc != PTE_ACC_USER_NO_KERNEL_RX) &&
+	    (p->acc != PTE_ACC_USER_NO_KERNEL_RWX)) << PAGE_USER_SHIFT) |
+	    (1 << PAGE_READ_SHIFT) |
+	    (((p->acc == PTE_ACC_USER_RW_KERNEL_RW) ||
+	    (p->acc == PTE_ACC_USER_RWX_KERNEL_RWX) ||
+	    (p->acc == PTE_ACC_USER_RO_KERNEL_RW) ||
+	    (p->acc == PTE_ACC_USER_NO_KERNEL_RWX)) << PAGE_WRITE_SHIFT) |
+	    (((p->acc != PTE_ACC_USER_RO_KERNEL_RO) &&
+	    (p->acc != PTE_ACC_USER_RW_KERNEL_RW) &&
+	    (p->acc != PTE_ACC_USER_RO_KERNEL_RW)) << PAGE_EXEC_SHIFT) |
+	    (1 << PAGE_GLOBAL_SHIFT));
+}
+
+NO_TRACE static inline void set_ptd_flags(pte_t *pt, size_t i, int flags)
+    WRITES(ARRAY_RANGE(pt, PTL0_ENTRIES_ARCH))
+    REQUIRES_ARRAY_MUTABLE(pt, PTL0_ENTRIES_ARCH)
+{
+	pte_t *p = &pt[i];
+	
+	p->et = (flags & PAGE_NOT_PRESENT) ?
+	    PTE_ET_INVALID : PTE_ET_DESCRIPTOR;
+}
+
+NO_TRACE static inline void set_pte_flags(pte_t *pt, size_t i, int flags)
+    WRITES(ARRAY_RANGE(pt, PTL0_ENTRIES_ARCH))
+    REQUIRES_ARRAY_MUTABLE(pt, PTL0_ENTRIES_ARCH)
+{
+	pte_t *p = &pt[i];
+	
+	p->et = PTE_ET_ENTRY;
+	p->acc = PTE_ACC_USER_NO_KERNEL_RWX;
+	
+	if (flags & PAGE_USER) {
+		if (flags & PAGE_EXEC) {
+			if (flags & PAGE_READ)
+				p->acc = PTE_ACC_USER_RX_KERNEL_RX;
+			if (flags & PAGE_WRITE)
+				p->acc = PTE_ACC_USER_RWX_KERNEL_RWX;
+		} else {
+			if (flags & PAGE_READ)
+				p->acc = PTE_ACC_USER_RO_KERNEL_RW;
+			if (flags & PAGE_WRITE)
+				p->acc = PTE_ACC_USER_RW_KERNEL_RW;
+		}
+	}
+	
+	if (flags & PAGE_NOT_PRESENT)
+		p->et = PTE_ET_INVALID;
+	
+	p->cacheable = (flags & PAGE_CACHEABLE) != 0;
+}
+
+NO_TRACE static inline void set_ptd_present(pte_t *pt, size_t i)
+    WRITES(ARRAY_RANGE(pt, PTL0_ENTRIES_ARCH))
+    REQUIRES_ARRAY_MUTABLE(pt, PTL0_ENTRIES_ARCH)
+{
+	pte_t *p = &pt[i];
+	
+	p->et = PTE_ET_DESCRIPTOR;
+}
+
+NO_TRACE static inline void set_pte_present(pte_t *pt, size_t i)
+    WRITES(ARRAY_RANGE(pt, PTL0_ENTRIES_ARCH))
+    REQUIRES_ARRAY_MUTABLE(pt, PTL0_ENTRIES_ARCH)
+{
+	pte_t *p = &pt[i];
+	
+	p->et = PTE_ET_ENTRY;
+}
+
+extern void page_arch_init(void);
+extern void page_fault(unsigned int, istate_t *);
+
+#endif
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc32/include/arch/mm/page_fault.h
===================================================================
--- kernel/arch/sparc32/include/arch/mm/page_fault.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/include/arch/mm/page_fault.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2013 Jakub Klama
+ * 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 sparc32mm
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc32_PAGE_FAULT_H_
+#define KERN_sparc32_PAGE_FAULT_H_
+
+typedef enum {
+	FAULT_TYPE_LOAD_USER_DATA = 0,
+	FAULT_TYPE_LOAD_SUPERVISOR_DATA = 1,
+	FAULT_TYPE_EXECUTE_USER = 2,
+	FAULT_TYPE_EXECUTE_SUPERVISOR = 3,
+	FAULT_TYPE_STORE_USER_DATA = 4,
+	FAULT_TYPE_STORE_SUPERVISOR_DATA = 5,
+	FAULT_TYPE_STORE_USER_INSTRUCTION = 6,
+	FAULT_TYPE_STORE_SUPERVISOR_INSTRUCTION = 7,
+} mmu_fault_type_t;
+
+/** MMU Fault Status register. */
+typedef struct {
+	unsigned int : 14;
+	unsigned int ebe : 8;
+	unsigned int l : 2;
+	unsigned int at : 3;
+	unsigned int ft : 3;
+	unsigned int fav : 1;
+	unsigned int ow : 1;
+} __attribute__((packed)) mmu_fault_status_t;
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc32/include/arch/mm/tlb.h
===================================================================
--- kernel/arch/sparc32/include/arch/mm/tlb.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/include/arch/mm/tlb.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2013 Jakub Klama
+ * 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 sparc32mm
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc32_TLB_H_
+#define KERN_sparc32_TLB_H_
+
+#define MMU_CONTROL        0x000
+#define MMU_CONTEXT_TABLE  0x100
+#define MMU_CONTEXT        0x200
+#define MMU_FAULT_STATUS   0x300
+#define MMU_FAULT_ADDRESS  0x400
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc32/include/arch/proc/task.h
===================================================================
--- kernel/arch/sparc32/include/arch/proc/task.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/include/arch/proc/task.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2010 Martin Decky
+ * 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 sparc32proc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc32_TASK_H_
+#define KERN_sparc32_TASK_H_
+
+#include <typedefs.h>
+#include <adt/bitmap.h>
+
+typedef struct {
+} task_arch_t;
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc32/include/arch/proc/thread.h
===================================================================
--- kernel/arch/sparc32/include/arch/proc/thread.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/include/arch/proc/thread.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013 Jakub Klama
+ * 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 sparc32proc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc32_THREAD_H_
+#define KERN_sparc32_THREAD_H_
+
+#include <typedefs.h>
+
+typedef struct {
+	/** Buffer for register windows with userspace content. */
+	uint8_t *uspace_window_buffer;
+} thread_arch_t;
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc32/include/arch/register.h
===================================================================
--- kernel/arch/sparc32/include/arch/register.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/include/arch/register.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2013 Jakub Klama
+ * 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 sparc32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc32_REGISTER_H_
+#define KERN_sparc32_REGISTER_H_
+
+#include <typedefs.h>
+
+/** Processor State Register. */
+typedef union {
+	uint32_t value;
+	struct {
+		unsigned int impl : 4;
+		unsigned int ver : 4;
+		unsigned int icc : 4;
+		unsigned int : 6;
+		unsigned int ec : 1;
+		unsigned int ef : 1;
+		unsigned int pil : 4;
+		unsigned int s : 1;
+		unsigned int ps : 1;
+		unsigned int et : 1;
+		unsigned int cwp : 5;
+	} __attribute__((packed));
+} psr_reg_t;
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc32/include/arch/regwin.h
===================================================================
--- kernel/arch/sparc32/include/arch/regwin.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/include/arch/regwin.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2005 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 sparc32interrupt
+ * @{
+ */
+/**
+ * @file
+ * @brief This file contains register window trap handlers.
+ */
+
+#ifndef KERN_sparc32_REGWIN_H_
+#define KERN_sparc32_REGWIN_H_
+
+#include <arch/stack.h>
+#include <arch/arch.h>
+#include <align.h>
+
+/* Window Save Area offsets. */
+#define L0_OFFSET  0
+#define L1_OFFSET  4
+#define L2_OFFSET  8
+#define L3_OFFSET  12
+#define L4_OFFSET  16
+#define L5_OFFSET  20
+#define L6_OFFSET  24
+#define L7_OFFSET  28
+#define I0_OFFSET  32
+#define I1_OFFSET  36
+#define I2_OFFSET  40
+#define I3_OFFSET  44
+#define I4_OFFSET  48
+#define I5_OFFSET  52
+#define I6_OFFSET  56
+#define I7_OFFSET  60
+
+/* User space Window Buffer constants. */
+#define UWB_SIZE       ((NWINDOWS - 1) * STACK_WINDOW_SAVE_AREA_SIZE)
+#define UWB_ALIGNMENT  1024
+#define UWB_ASIZE      ALIGN_UP(UWB_SIZE, UWB_ALIGNMENT)
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc32/include/arch/stack.h
===================================================================
--- kernel/arch/sparc32/include/arch/stack.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/include/arch/stack.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2005 Jakub Jermar
+ * Copyright (c) 2013 Jakub Klama
+ * 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 sparc32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc32_STACK_H_
+#define KERN_sparc32_STACK_H_
+
+#include <config.h>
+
+#define MEM_STACK_SIZE  STACK_SIZE
+
+#define STACK_ITEM_SIZE  4
+#define STACK_ALIGNMENT  8
+
+/**
+ * 16-extended-word save area for %i[0-7] and %l[0-7] registers.
+ */
+#define STACK_WINDOW_SAVE_AREA_SIZE  (16 * STACK_ITEM_SIZE)
+
+/**
+ * Six extended words for first six arguments.
+ */
+#define STACK_ARG_SAVE_AREA_SIZE  (6 * STACK_ITEM_SIZE)
+
+/**
+ * Offsets of arguments on stack.
+ */
+#define STACK_ARG0  0
+#define STACK_ARG1  4
+#define STACK_ARG2  8
+#define STACK_ARG3  12
+#define STACK_ARG4  16
+#define STACK_ARG5  20
+#define STACK_ARG6  24
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc32/include/arch/trap.h
===================================================================
--- kernel/arch/sparc32/include/arch/trap.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/include/arch/trap.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2013 Jakub Klama
+ * 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 sparc32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc32_TRAP_H_
+#define KERN_sparc32_TRAP_H_
+
+#define TRAP_ENTRY_SIZE   16
+#define TRAP_TABLE_COUNT  256
+#define TRAP_TABLE_SIZE   (TRAP_ENTRY_SIZE * TRAP_TABLE_COUNT)
+
+#ifndef __ASM__
+
+extern void *trap_table;
+
+#endif
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc32/include/arch/types.h
===================================================================
--- kernel/arch/sparc32/include/arch/types.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/include/arch/types.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2010 Martin Decky
+ * 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 sparc32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc32_TYPES_H_
+#define KERN_sparc32_TYPES_H_
+
+#define ATOMIC_COUNT_MIN  UINT32_MIN
+#define ATOMIC_COUNT_MAX  UINT32_MAX
+
+typedef uint32_t size_t;
+typedef int32_t ssize_t;
+
+typedef uint32_t uintptr_t;
+typedef uint32_t pfn_t;
+
+typedef uint32_t ipl_t;
+
+typedef uint32_t sysarg_t;
+typedef int32_t native_t;
+typedef uint32_t atomic_count_t;
+
+typedef struct {
+} fncptr_t;
+
+#define INTN_C(c)   INT32_C(c)
+#define UINTN_C(c)  UINT32_C(c)
+
+#define PRIdn  PRId32  /**< Format for native_t. */
+#define PRIun  PRIu32  /**< Format for sysarg_t. */
+#define PRIxn  PRIx32  /**< Format for hexadecimal sysarg_t. */
+#define PRIua  PRIu32  /**< Format for atomic_count_t. */
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc32/src/context.S
===================================================================
--- kernel/arch/sparc32/src/context.S	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/src/context.S	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,98 @@
+#
+# Copyright (c) 2005 Jakub Jermar
+# Copyright (c) 2013 Jakub Klama
+# 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.
+#
+
+#include <arch/context_offset.h>
+#include <arch/arch.h>
+
+.text
+
+.global context_save_arch
+.global context_restore_arch
+
+/*
+ * context_save_arch() is required not to create its own stack frame. See the
+ * generic context.h for explanation.
+ */
+context_save_arch:
+	#
+	# Force all our active register windows to memory so that we can find
+	# them there even if e.g. the thread is migrated to another processor.
+	#
+	
+	## flushw
+	mov 7, %g1
+	1:
+		subcc %g1, 1, %g1
+		bg 1b
+		save %sp, -64, %sp
+	
+	mov 7, %g1
+	1:
+		subcc %g1, 1, %g1
+		bg 1b
+		restore
+	
+	CONTEXT_SAVE_ARCH_CORE %o0
+	retl
+	mov 1, %o0		! context_save_arch returns 1
+
+context_restore_arch:
+	#
+	# Forget all previous windows, they are not going to be needed again.
+	# Enforce a window fill on the next RESTORE instruction by setting
+	# CANRESTORE to zero and other window configuration registers
+	# accordingly. Note that the same can be achieved by executing the
+	# FLUSHW instruction, but since we don't need to remember the previous
+	# windows, we do the former and save thus some unnecessary window
+	# spills.
+	#
+	
+	## rdpr %pstate, %l0
+	## andn %l0, PSTATE_IE_BIT, %l1
+	## wrpr %l1, %pstate
+	## wrpr %g0, 0, %canrestore
+	## wrpr %g0, 0, %otherwin
+	## wrpr %g0, NWINDOWS - 2, %cansave
+	## wrpr %l0, %pstate
+	
+	mov 7, %g1
+	1:
+		subcc %g1, 1, %g1
+		bg 1b
+		save %sp, -64, %sp
+	
+	mov 7, %g1
+	1:
+		subcc %g1, 1, %g1
+		bg 1b
+		restore
+	
+	CONTEXT_RESTORE_ARCH_CORE %o0
+	retl
+	xor %o0, %o0, %o0	! context_restore_arch returns 0
Index: kernel/arch/sparc32/src/cpu/cpu.c
===================================================================
--- kernel/arch/sparc32/src/cpu/cpu.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/src/cpu/cpu.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2010 Martin Decky
+ * 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 sparc32
+ * @{
+ */
+/** @file
+ */
+
+#include <arch/cpu.h>
+#include <arch.h>
+#include <typedefs.h>
+#include <print.h>
+#include <fpu_context.h>
+
+void fpu_disable(void)
+{
+}
+
+void fpu_enable(void)
+{
+}
+
+void cpu_arch_init(void)
+{
+}
+
+void cpu_identify(void)
+{
+}
+
+void cpu_print_report(cpu_t *cpu)
+{
+}
+
+/** @}
+ */
Index: kernel/arch/sparc32/src/ddi/ddi.c
===================================================================
--- kernel/arch/sparc32/src/ddi/ddi.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/src/ddi/ddi.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2010 Martin Decky
+ * 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 sparc32ddi
+ * @{
+ */
+/** @file
+ *  @brief DDI.
+ */
+
+#include <ddi/ddi.h>
+#include <proc/task.h>
+#include <typedefs.h>
+
+/** Enable I/O space range for task.
+ *
+ */
+int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size)
+{
+	return 0;
+}
+
+/** @}
+ */
Index: kernel/arch/sparc32/src/debug/stacktrace.c
===================================================================
--- kernel/arch/sparc32/src/debug/stacktrace.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/src/debug/stacktrace.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2010 Jakub Jermar
+ * Copyright (c) 2013 Jakub Klama
+ * 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 sparc32
+ * @{
+ */
+/** @file
+ */
+
+#include <stacktrace.h>
+#include <syscall/copy.h>
+#include <typedefs.h>
+#include <arch.h>
+#include <arch/stack.h>
+
+#define FRAME_OFFSET_FP_PREV  14
+#define FRAME_OFFSET_RA       15
+
+static void alloc_window_and_flush(void)
+{
+	// FIXME TODO
+}
+
+bool kernel_stack_trace_context_validate(stack_trace_context_t *ctx)
+{
+	uintptr_t kstack;
+	uint32_t l1;
+	uint32_t l2;
+	
+	read_from_invalid(&kstack, &l1, &l2);
+	kstack -= 128;
+	
+	if ((THREAD) && (ctx->fp == kstack))
+		return false;
+	
+	return (ctx->fp != 0);
+}
+
+bool kernel_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev)
+{
+	uint32_t *stack = (void *) ctx->fp;
+	alloc_window_and_flush();
+	*prev = stack[FRAME_OFFSET_FP_PREV];
+	return true;
+}
+
+bool kernel_return_address_get(stack_trace_context_t *ctx, uintptr_t *ra)
+{
+	uint32_t *stack = (void *) ctx->fp;
+	alloc_window_and_flush();
+	*ra = stack[FRAME_OFFSET_RA];
+	return true;
+}
+
+bool uspace_stack_trace_context_validate(stack_trace_context_t *ctx)
+{
+	return false;
+}
+
+bool uspace_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev)
+{
+	return false;
+}
+
+bool uspace_return_address_get(stack_trace_context_t *ctx , uintptr_t *ra)
+{
+	return false;
+}
+
+uintptr_t frame_pointer_get(void)
+{
+	// FIXME TODO
+	return 0;
+}
+
+uintptr_t program_counter_get(void)
+{
+	// FIXME TODO
+	return 0;
+}
+
+/** @}
+ */
Index: kernel/arch/sparc32/src/exception.c
===================================================================
--- kernel/arch/sparc32/src/exception.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/src/exception.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2005 Jakub Jermar
+ * Copyright (c) 2013 Jakub Klama
+ * 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 sparc64interrupt
+ * @{
+ */
+/** @file
+ *
+ */
+
+#include <arch.h>
+#include <typedefs.h>
+#include <arch/istate.h>
+#include <arch/exception.h>
+#include <arch/regwin.h>
+#include <arch/machine_func.h>
+#include <syscall/syscall.h>
+#include <interrupt.h>
+#include <arch/asm.h>
+#include <mm/frame.h>
+#include <mm/page.h>
+#include <mm/as.h>
+#include <memstr.h>
+#include <debug.h>
+#include <print.h>
+#include <symtab.h>
+
+/** Handle instruction_access_exception. (0x1) */
+void instruction_access_exception(int n, istate_t *istate)
+{
+	page_fault(n, istate);
+}
+
+/** Handle instruction_access_error. (0x21) */
+void instruction_access_error(int n, istate_t *istate)
+{
+	fault_if_from_uspace(istate, "%s.", __func__);
+	panic_badtrap(istate, n, "%s.", __func__);
+}
+
+/** Handle illegal_instruction. (0x2) */
+void illegal_instruction(int n, istate_t *istate)
+{
+	fault_if_from_uspace(istate, "%s.", __func__);
+	panic_badtrap(istate, n, "%s.", __func__);
+}
+
+/** Handle privileged_instruction. (0x3) */
+void privileged_instruction(int n, istate_t *istate)
+{
+	fault_if_from_uspace(istate, "%s.", __func__);
+	panic_badtrap(istate, n, "%s.", __func__);
+}
+
+/** Handle fp_disabled. (0x3) */
+void fp_disabled(int n, istate_t *istate)
+{
+	fault_if_from_uspace(istate, "%s.", __func__);
+	panic_badtrap(istate, n, "%s.", __func__);
+}
+
+/** Handle fp_exception. (0x08) */
+void fp_exception(int n, istate_t *istate)
+{
+	fault_if_from_uspace(istate, "%s.", __func__);
+	panic_badtrap(istate, n, "%s.", __func__);
+}
+
+/** Handle tag_overflow. (0x0a) */
+void tag_overflow(int n, istate_t *istate)
+{
+	fault_if_from_uspace(istate, "%s.", __func__);
+	panic_badtrap(istate, n, "%s.", __func__);
+}
+
+/** Handle division_by_zero. (0x2a) */
+void division_by_zero(int n, istate_t *istate)
+{
+	fault_if_from_uspace(istate, "%s.", __func__);
+	panic_badtrap(istate, n, "%s.", __func__);
+}
+
+/** Handle data_access_exception. (0x9) */
+void data_access_exception(int n, istate_t *istate)
+{
+	page_fault(n, istate);
+}
+
+/** Handle data_access_error. (0x29) */
+void data_access_error(int n, istate_t *istate)
+{
+	page_fault(n, istate);
+}
+
+/** Handle data_store_error. (0x29) */
+void data_store_error(int n, istate_t *istate)
+{
+	page_fault(n, istate);
+}
+
+/** Handle data_access_error. (0x2c) */
+void data_access_mmu_miss(int n, istate_t *istate)
+{
+	fault_if_from_uspace(istate, "%s.", __func__);
+	panic_badtrap(istate, n, "%s.", __func__);
+}
+
+/** Handle mem_address_not_aligned. (0x7) */
+void mem_address_not_aligned(int n, istate_t *istate)
+{
+	fault_if_from_uspace(istate, "%s.", __func__);
+	panic_badtrap(istate, n, "%s.", __func__);
+}
+
+sysarg_t syscall(sysarg_t a1, sysarg_t a2, sysarg_t a3, sysarg_t a4,
+    sysarg_t a5, sysarg_t a6, sysarg_t id)
+{
+	return syscall_handler(a1, a2, a3, a4, a5, a6, id);
+}
+
+void irq_exception(unsigned int nr, istate_t *istate)
+{
+	machine_irq_exception(nr, istate);
+}
+
+void preemptible_save_uspace(uintptr_t sp, istate_t *istate)
+{
+	as_page_fault(sp, PF_ACCESS_WRITE, istate);
+}
+
+void preemptible_restore_uspace(uintptr_t sp, istate_t *istate)
+{
+	as_page_fault(sp, PF_ACCESS_WRITE, istate);
+}
+
+/** @}
+ */
Index: kernel/arch/sparc32/src/machine/leon3/leon3.c
===================================================================
--- kernel/arch/sparc32/src/machine/leon3/leon3.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/src/machine/leon3/leon3.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2013 Jakub Klama
+ * 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 sparc32
+ * @{
+ */
+/** @file
+ */
+
+#include <arch.h>
+#include <typedefs.h>
+#include <arch/interrupt.h>
+#include <arch/asm.h>
+#include <arch/machine_func.h>
+#include <arch/machine/leon3/leon3.h>
+#include <genarch/drivers/grlib/uart.h>
+#include <genarch/drivers/grlib/irqmp.h>
+#include <genarch/srln/srln.h>
+#include <func.h>
+#include <config.h>
+#include <errno.h>
+#include <context.h>
+#include <fpu_context.h>
+#include <interrupt.h>
+#include <syscall/copy.h>
+#include <ddi/irq.h>
+#include <proc/thread.h>
+#include <syscall/syscall.h>
+#include <console/console.h>
+#include <macros.h>
+#include <memstr.h>
+#include <str.h>
+
+static void leon3_init(bootinfo_t *);
+static void leon3_cpu_halt(void);
+static void leon3_get_memory_extents(uintptr_t *, size_t *);
+static void leon3_timer_start(void);
+static void leon3_irq_exception(unsigned int, istate_t *);
+static void leon3_output_init(void);
+static void leon3_input_init(void);
+static size_t leon3_get_irq_count(void);
+static const char *leon3_get_platform_name(void);
+
+struct leon3_machine_t {
+	bootinfo_t *bootinfo;
+	outdev_t *scons_dev;
+	grlib_irqmp_t irqmp;
+};
+
+struct sparc_machine_ops leon3_machine_ops = {
+	.machine_init = leon3_init,
+	.machine_cpu_halt = leon3_cpu_halt,
+	.machine_get_memory_extents = leon3_get_memory_extents,
+	.machine_timer_irq_start = leon3_timer_start,
+	.machine_irq_exception = leon3_irq_exception,
+	.machine_output_init = leon3_output_init,
+	.machine_input_init = leon3_input_init,
+	.machine_get_irq_count = leon3_get_irq_count,
+	.machine_get_platform_name = leon3_get_platform_name
+};
+
+static struct leon3_machine_t machine;
+
+static void leon3_init(bootinfo_t *bootinfo)
+{
+	machine.bootinfo = bootinfo;
+	grlib_irqmp_init(&machine.irqmp, bootinfo);
+}
+
+static void leon3_cpu_halt(void)
+{
+	// FIXME TODO
+	while (1);
+}
+
+static void leon3_get_memory_extents(uintptr_t *start, size_t *size)
+{
+	*start = LEON3_SDRAM_START;
+	*size = 64 * 1024 * 1024;
+	// FIXME: *size = machine.bootinfo->memsize;
+}
+
+static void leon3_timer_start(void)
+{
+	// FIXME:
+	// machine.timer =
+	//     grlib_timer_init(machine.bootinfo->timer_base,
+	//     machine.bootinfo->timer_irq);
+}
+
+static void leon3_irq_exception(unsigned int exc, istate_t *istate)
+{
+	int irqnum = grlib_irqmp_inum_get(&machine.irqmp);
+	
+	grlib_irqmp_clear(&machine.irqmp, irqnum);
+	
+	irq_t *irq = irq_dispatch_and_lock(exc);
+	if (irq) {
+		irq->handler(irq);
+		spinlock_unlock(&irq->lock);
+	} else
+		printf("cpu%d: spurious interrupt (irq=%d)\n", CPU->id, irqnum);
+}
+
+static void leon3_output_init(void)
+{
+	machine.scons_dev =
+	    grlib_uart_init(machine.bootinfo->uart_base,
+	    machine.bootinfo->uart_irq);
+	
+	if (machine.scons_dev)
+		stdout_wire(machine.scons_dev);
+}
+
+static void leon3_input_init(void)
+{
+	grlib_uart_t *scons_inst;
+	
+	if (machine.scons_dev) {
+		/* Create input device. */
+		scons_inst = (void *)machine.scons_dev->data;
+		
+		srln_instance_t *srln_instance = srln_init();
+		if (srln_instance) {
+			indev_t *sink = stdin_wire();
+			indev_t *srln = srln_wire(srln_instance, sink);
+			grlib_uart_input_wire(scons_inst, srln);
+			
+			/* Enable interrupts from UART */
+			grlib_irqmp_unmask(&machine.irqmp,
+			    machine.bootinfo->uart_irq);
+		}
+	}
+}
+
+static size_t leon3_get_irq_count(void)
+{
+	return LEON3_IRQ_COUNT;
+}
+
+static const char *leon3_get_platform_name(void)
+{
+	return "LEON3";
+}
Index: kernel/arch/sparc32/src/machine_func.c
===================================================================
--- kernel/arch/sparc32/src/machine_func.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/src/machine_func.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2009 Vineeth Pillai
+ * 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 sparc32
+ * @{
+ */
+/** @file
+ * @brief Definitions of machine specific functions.
+ *
+ * These functions enable to differentiate more kinds of SPARC emulators
+ * or CPUs. It's the same concept as "arch" functions on the architecture
+ * level.
+ */
+
+#include <arch/machine_func.h>
+#include <arch/machine/leon3/leon3.h>
+
+/** Pointer to machine_ops structure being used. */
+struct sparc_machine_ops *machine_ops;
+
+/** Initialize machine_ops pointer. */
+void machine_ops_init(void)
+{
+#if defined(MACHINE_leon3)
+	machine_ops = &leon3_machine_ops;
+#else
+#error Machine type not defined.
+#endif
+}
+
+/** Map HW devices to the kernel address space using #hw_map. */
+void machine_init(bootinfo_t *bootinfo)
+{
+	machine_ops->machine_init(bootinfo);
+}
+
+/** Start timer. */
+void machine_timer_irq_start(void)
+{
+	machine_ops->machine_timer_irq_start();
+}
+
+/** Halt CPU. */
+void machine_cpu_halt(void)
+{
+	machine_ops->machine_cpu_halt();
+}
+
+/** Get extents of available memory.
+ *
+ * @param start Place to store memory start address.
+ * @param size  Place to store memory size.
+ *
+ */
+void machine_get_memory_extents(uintptr_t *start, size_t *size)
+{
+	machine_ops->machine_get_memory_extents(start, size);
+}
+
+/** Interrupt exception handler.
+ *
+ * @param exc    Interrupt exception number.
+ * @param istate Saved processor state.
+ *
+ */
+void machine_irq_exception(unsigned int exc, istate_t *istate)
+{
+	machine_ops->machine_irq_exception(exc, istate);
+}
+
+/** Configure the output device. */
+void machine_output_init(void)
+{
+	machine_ops->machine_output_init();
+}
+
+/** Configure the input device. */
+void machine_input_init(void)
+{
+	machine_ops->machine_input_init();
+}
+
+/** Get IRQ number range used by machine. */
+size_t machine_get_irq_count(void)
+{
+	return machine_ops->machine_get_irq_count();
+}
+
+const char *machine_get_platform_name(void)
+{
+	if (machine_ops->machine_get_platform_name)
+		return machine_ops->machine_get_platform_name();
+	
+	return NULL;
+}
+
+/** @}
+ */
Index: kernel/arch/sparc32/src/mm/as.c
===================================================================
--- kernel/arch/sparc32/src/mm/as.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/src/mm/as.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2013 Jakub Klama
+ * 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 sparc32mm
+ * @{
+ */
+
+#include <mm/as.h>
+#include <arch/arch.h>
+#include <arch/asm.h>
+#include <arch/mm/as.h>
+#include <arch/mm/page.h>
+#include <genarch/mm/page_pt.h>
+
+uintptr_t as_context_table;
+
+static ptd_t context_table[ASID_MAX_ARCH] __attribute__((aligned(1024)));
+
+void as_arch_init(void)
+{
+	as_operations = &as_pt_operations;
+	as_context_table = (uintptr_t) &context_table;
+}
+
+void as_install_arch(as_t *as)
+{
+	context_table[as->asid].table_pointer =
+	    (uintptr_t) as->genarch.page_table >> 6;
+	context_table[as->asid].et = PTE_ET_DESCRIPTOR;
+	asi_u32_write(ASI_MMUREGS, 0x200, as->asid);
+	asi_u32_write(ASI_MMUCACHE, 0, 1);
+	asi_u32_write(ASI_MMUFLUSH, 0x400, 1);
+}
+
+/** @}
+ */
Index: kernel/arch/sparc32/src/mm/frame.c
===================================================================
--- kernel/arch/sparc32/src/mm/frame.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/src/mm/frame.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2007 Pavel Jancik, Michal Kebrt
+ * Copyright (c) 2013 Jakub Klama
+ * 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 sparc32mm
+ * @{
+ */
+/** @file
+ *  @brief Frame related functions.
+ */
+
+#include <mm/frame.h>
+#include <arch/machine_func.h>
+#include <arch/mm/frame.h>
+#include <config.h>
+#include <align.h>
+#include <macros.h>
+
+static void frame_common_arch_init(bool low)
+{
+	uintptr_t base;
+	size_t size;
+	machine_get_memory_extents(&base, &size);
+	
+	base = ALIGN_UP(base, FRAME_SIZE);
+	size = ALIGN_DOWN(size, FRAME_SIZE);
+	
+	if (!frame_adjust_zone_bounds(low, &base, &size))
+		return;
+	
+	if (low) {
+		zone_create(ADDR2PFN(base), SIZE2FRAMES(size),
+		    BOOT_PT_START_FRAME + BOOT_PT_SIZE_FRAMES,
+		    ZONE_AVAILABLE | ZONE_LOWMEM);
+	} else {
+		pfn_t conf = zone_external_conf_alloc(SIZE2FRAMES(size));
+		if (conf != 0)
+			zone_create(ADDR2PFN(base), SIZE2FRAMES(size), conf,
+			    ZONE_AVAILABLE | ZONE_HIGHMEM);
+	}
+}
+
+void physmem_print(void)
+{
+	// FIXME TODO
+}
+
+/** Create low memory zones. */
+void frame_low_arch_init(void)
+{
+	frame_common_arch_init(true);
+	
+	/* Blacklist boot page table */
+	frame_mark_unavailable(BOOT_PT_START_FRAME, BOOT_PT_SIZE_FRAMES);
+}
+
+/** Create high memory zones. */
+void frame_high_arch_init(void)
+{
+	frame_common_arch_init(false);
+}
+
+/** @}
+ */
Index: kernel/arch/sparc32/src/mm/km.c
===================================================================
--- kernel/arch/sparc32/src/mm/km.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/src/mm/km.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2011 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 sparc32mm
+ * @{
+ */
+
+#include <arch/mm/km.h>
+#include <mm/km.h>
+#include <typedefs.h>
+#include <macros.h>
+
+void km_identity_arch_init(void)
+{
+	config.identity_base = KM_SPARC32_IDENTITY_START;
+	config.identity_size = KM_SPARC32_IDENTITY_SIZE;
+}
+
+void km_non_identity_arch_init(void)
+{
+	km_non_identity_span_add(KM_SPARC32_NON_IDENTITY_START,
+	    KM_SPARC32_NON_IDENTITY_SIZE);
+}
+
+bool km_is_non_identity_arch(uintptr_t addr)
+{
+	return iswithin(KM_SPARC32_NON_IDENTITY_START,
+	    KM_SPARC32_NON_IDENTITY_SIZE, addr, 1);
+}
+
+/** @}
+ */
Index: kernel/arch/sparc32/src/mm/page.c
===================================================================
--- kernel/arch/sparc32/src/mm/page.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/src/mm/page.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2010 Martin Decky
+ * 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 sparc32mm
+ * @{
+ */
+/** @file
+ */
+
+#include <arch/mm/page.h>
+#include <arch/mm/page_fault.h>
+#include <arch/mm/tlb.h>
+#include <genarch/mm/page_pt.h>
+#include <arch/mm/frame.h>
+#include <mm/frame.h>
+#include <mm/page.h>
+#include <mm/as.h>
+#include <typedefs.h>
+#include <align.h>
+#include <config.h>
+#include <func.h>
+#include <arch/interrupt.h>
+#include <arch/asm.h>
+#include <debug.h>
+#include <memstr.h>
+#include <print.h>
+#include <interrupt.h>
+#include <macros.h>
+
+void page_arch_init(void)
+{
+	int flags = PAGE_CACHEABLE | PAGE_EXEC;
+	page_mapping_operations = &pt_mapping_operations;
+	
+	page_table_lock(AS_KERNEL, true);
+	
+	/* Kernel identity mapping */
+	// FIXME:
+	// We need to consider the possibility that
+	// identity_base > identity_size and physmem_end.
+	// This might lead to overflow if identity_size is too big.
+	for (uintptr_t cur = PHYSMEM_START_ADDR;
+	    cur < min(KA2PA(config.identity_base) +
+	    config.identity_size, config.physmem_end);
+	    cur += FRAME_SIZE)
+		page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags);
+	
+	page_table_unlock(AS_KERNEL, true);
+	as_switch(NULL, AS_KERNEL);
+	
+	/* Switch MMU to new context table */
+	asi_u32_write(ASI_MMUREGS, MMU_CONTEXT_TABLE, KA2PA(as_context_table) >> 4);
+}
+
+void page_fault(unsigned int n __attribute__((unused)), istate_t *istate)
+{
+	uint32_t fault_status = asi_u32_read(ASI_MMUREGS, MMU_FAULT_STATUS);
+	uintptr_t fault_address = asi_u32_read(ASI_MMUREGS, MMU_FAULT_ADDRESS);
+	mmu_fault_status_t *fault = (mmu_fault_status_t *) &fault_status;
+	mmu_fault_type_t type = (mmu_fault_type_t) fault->at;
+	
+	if ((type == FAULT_TYPE_LOAD_USER_DATA) ||
+	    (type == FAULT_TYPE_LOAD_SUPERVISOR_DATA))
+		as_page_fault(fault_address, PF_ACCESS_READ, istate);
+
+	if ((type == FAULT_TYPE_EXECUTE_USER) ||
+	    (type == FAULT_TYPE_EXECUTE_SUPERVISOR))
+		as_page_fault(fault_address, PF_ACCESS_EXEC, istate);
+
+	if ((type == FAULT_TYPE_STORE_USER_DATA) ||
+	    (type == FAULT_TYPE_STORE_USER_INSTRUCTION) ||
+	    (type == FAULT_TYPE_STORE_SUPERVISOR_INSTRUCTION) ||
+	    (type == FAULT_TYPE_STORE_SUPERVISOR_DATA))
+		as_page_fault(fault_address, PF_ACCESS_WRITE, istate);
+}
+
+/** @}
+ */
Index: kernel/arch/sparc32/src/mm/tlb.c
===================================================================
--- kernel/arch/sparc32/src/mm/tlb.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/src/mm/tlb.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2010 Martin Decky
+ * 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 sparc32mm
+ * @{
+ */
+
+#include <mm/tlb.h>
+#include <arch/arch.h>
+#include <arch/mm/asid.h>
+#include <arch/mm/as.h>
+#include <arch/mm/page.h>
+#include <arch/asm.h>
+#include <typedefs.h>
+
+void tlb_invalidate_all(void)
+{
+	asi_u32_write(ASI_MMUCACHE, 0, 1);
+	asi_u32_write(ASI_MMUFLUSH, 0x400, 1);
+}
+
+void tlb_invalidate_asid(asid_t asid __attribute__((unused)))
+{
+	tlb_invalidate_all();
+}
+
+void tlb_invalidate_pages(asid_t asid __attribute__((unused)), uintptr_t page,
+    size_t cnt)
+{
+	tlb_invalidate_all();
+}
+
+void tlb_arch_init(void)
+{
+}
+
+void tlb_print(void)
+{
+}
+
+/** @}
+ */
Index: kernel/arch/sparc32/src/proc/scheduler.c
===================================================================
--- kernel/arch/sparc32/src/proc/scheduler.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/src/proc/scheduler.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2013 Jakub Klama
+ * 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 sparc32proc
+ * @{
+ */
+/** @file
+ */
+
+#include <proc/scheduler.h>
+#include <proc/thread.h>
+#include <arch.h>
+#include <arch/arch.h>
+
+void before_task_runs_arch(void)
+{
+}
+
+void before_thread_runs_arch(void)
+{
+	if (THREAD->uspace) {
+		uint32_t kernel_sp = (uint32_t) THREAD->kstack + STACK_SIZE - 8;
+		uint32_t uspace_wbuf = (uint32_t) THREAD->arch.uspace_window_buffer;
+		write_to_invalid(kernel_sp, uspace_wbuf, 0);
+	}
+}
+
+void after_thread_ran_arch(void)
+{
+	if (THREAD->uspace) {
+		uint32_t kernel_sp;
+		uint32_t uspace_wbuf;
+		uint32_t l7;
+		read_from_invalid(&kernel_sp, &uspace_wbuf, &l7);
+		THREAD->arch.uspace_window_buffer = (uint8_t *) uspace_wbuf;
+	}
+}
+
+/** @}
+ */
Index: kernel/arch/sparc32/src/proc/task.c
===================================================================
--- kernel/arch/sparc32/src/proc/task.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/src/proc/task.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2010 Martin Decky
+ * 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 sparc32proc
+ * @{
+ */
+/** @file
+ */
+
+#include <proc/task.h>
+
+void task_create_arch(task_t *t)
+{
+}
+
+void task_destroy_arch(task_t *t)
+{
+}
+
+/** @}
+ */
Index: kernel/arch/sparc32/src/proc/thread.c
===================================================================
--- kernel/arch/sparc32/src/proc/thread.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/src/proc/thread.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2010 Martin Decky
+ * 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 sparc32proc
+ * @{
+ */
+/** @file
+ */
+
+#include <arch/regwin.h>
+#include <proc/thread.h>
+
+void thr_constructor_arch(thread_t *t)
+{
+	t->arch.uspace_window_buffer = NULL;
+}
+
+void thr_destructor_arch(thread_t *t)
+{
+	if (t->arch.uspace_window_buffer) {
+		uintptr_t uw_buf = (uintptr_t) t->arch.uspace_window_buffer;
+		/*
+		 * Mind the possible alignment of the userspace window buffer
+		 * belonging to a killed thread.
+		 */
+		free((uint8_t *) ALIGN_DOWN(uw_buf, UWB_ALIGNMENT));
+	}
+}
+
+void thread_create_arch(thread_t *t)
+{
+	if ((t->uspace) && (!t->arch.uspace_window_buffer))
+		{
+		/*
+		 * The thread needs userspace window buffer and the object
+		 * returned from the slab allocator doesn't have any.
+		 */
+		t->arch.uspace_window_buffer = malloc(UWB_ASIZE, 0);
+	} else {
+		uintptr_t uw_buf = (uintptr_t) t->arch.uspace_window_buffer;
+		
+		/*
+		 * Mind the possible alignment of the userspace window buffer
+		 * belonging to a killed thread.
+		 */
+		t->arch.uspace_window_buffer = (uint8_t *) ALIGN_DOWN(uw_buf,
+		    UWB_ASIZE);
+	}
+}
+
+/** @}
+ */
Index: kernel/arch/sparc32/src/smp/ipi.c
===================================================================
--- kernel/arch/sparc32/src/smp/ipi.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/src/smp/ipi.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2010 Martin Decky
+ * 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 sparc32
+ * @{
+ */
+/** @file
+ */
+
+#ifdef CONFIG_SMP
+
+#include <smp/ipi.h>
+
+void ipi_broadcast_arch(int ipi)
+{
+}
+
+#endif /* CONFIG_SMP */
+
+/** @}
+ */
Index: kernel/arch/sparc32/src/smp/smp.c
===================================================================
--- kernel/arch/sparc32/src/smp/smp.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/src/smp/smp.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2010 Martin Decky
+ * 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 sparc32
+ * @{
+ */
+/** @file
+ */
+
+#include <smp/smp.h>
+
+#if 0
+void smp_init(void)
+{
+}
+
+void kmp(void *arg)
+{
+}
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc32/src/sparc32.c
===================================================================
--- kernel/arch/sparc32/src/sparc32.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/src/sparc32.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2010 Martin Decky
+ * 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 sparc32
+ * @{
+ */
+/** @file
+ */
+
+#include <arch.h>
+#include <typedefs.h>
+#include <arch/interrupt.h>
+#include <arch/asm.h>
+#include <arch/machine_func.h>
+#include <func.h>
+#include <config.h>
+#include <errno.h>
+#include <context.h>
+#include <fpu_context.h>
+#include <interrupt.h>
+#include <syscall/copy.h>
+#include <ddi/irq.h>
+#include <proc/thread.h>
+#include <syscall/syscall.h>
+#include <console/console.h>
+#include <macros.h>
+#include <memstr.h>
+#include <str.h>
+
+char memcpy_from_uspace_failover_address;
+char memcpy_to_uspace_failover_address;
+
+static bootinfo_t machine_bootinfo;
+
+void arch_pre_main(void *unused, bootinfo_t *bootinfo)
+{
+	init.cnt = min3(bootinfo->cnt, TASKMAP_MAX_RECORDS, CONFIG_INIT_TASKS);
+	memcpy(&machine_bootinfo, bootinfo, sizeof(machine_bootinfo));
+	
+	for (size_t i = 0; i < init.cnt; i++) {
+		init.tasks[i].paddr = KA2PA(bootinfo->tasks[i].addr);
+		init.tasks[i].size = bootinfo->tasks[i].size;
+		str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN,
+		    bootinfo->tasks[i].name);
+	}
+	
+	machine_ops_init();
+}
+
+void arch_pre_mm_init(void)
+{
+}
+
+extern void func1(void);
+
+void arch_post_mm_init(void)
+{
+	machine_init(&machine_bootinfo);
+	
+	if (config.cpu_active == 1) {
+		/* Initialize IRQ routing */
+		irq_init(16, 16);
+		
+		/* Merge all memory zones to 1 big zone */
+		zone_merge_all();
+	}
+	
+	machine_output_init();
+}
+
+
+void arch_post_cpu_init()
+{
+}
+
+void arch_pre_smp_init(void)
+{
+}
+
+void arch_post_smp_init(void)
+{
+	machine_input_init();
+}
+
+void calibrate_delay_loop(void)
+{
+}
+
+sysarg_t sys_tls_set(uintptr_t addr)
+{
+	return EOK;
+}
+
+/** Construct function pointer
+ *
+ * @param fptr   function pointer structure
+ * @param addr   function address
+ * @param caller calling function address
+ *
+ * @return address of the function pointer
+ *
+ */
+void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller)
+{
+	return addr;
+}
+
+void arch_reboot(void)
+{
+}
+
+void irq_initialize_arch(irq_t *irq)
+{
+	(void) irq;
+}
+
+void istate_decode(istate_t *istate)
+{
+	(void) istate;
+}
+
+void fpu_init(void)
+{
+}
+
+void fpu_context_save(fpu_context_t *ctx)
+{
+}
+
+void fpu_context_restore(fpu_context_t *ctx)
+{
+}
+
+int memcpy_from_uspace(void *dst, const void *uspace_src, size_t size)
+{
+	memcpy(dst, uspace_src, size);
+	return 1;
+}
+
+int memcpy_to_uspace(void *uspace_dst, const void *src, size_t size)
+{
+	memcpy(uspace_dst, src, size);
+	return 1;
+}
+
+/** @}
+ */
Index: kernel/arch/sparc32/src/start.S
===================================================================
--- kernel/arch/sparc32/src/start.S	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/src/start.S	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,91 @@
+#
+# Copyright (c) 2013 Jakub Klama
+# 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.
+#
+
+.text
+
+.global kernel_image_start
+.global early_putchar
+.global kernel_sp
+.global uspace_wbuf
+
+kernel_image_start:
+	# Install trap handlers
+	set trap_table, %g1
+	mov %g1, %tbr
+	
+	mov %psr, %g1           ! Initialize WIM
+	add %g1, 1, %g2
+	and %g2, 0x7, %g2
+	set 1, %g3
+	sll %g3, %g2, %g3
+	mov %g3, %wim
+	
+	or %g1, 0x20, %g1
+	or %g1, 0xf00, %g1      ! PIL
+	wr %g1, %psr
+	
+	set boot_stack, %sp
+	mov %sp, %fp
+	sub %sp, 96, %sp
+	
+	mov %o1, %l1
+	set 0xdeadbeef, %o0
+	set 0xdeadbeef, %o1
+	set 0, %o2
+	call write_to_invalid
+	nop
+	
+	mov %l1, %o1
+	call arch_pre_main
+	nop
+	
+	call main_bsp
+	nop
+
+early_putchar:
+	set 0x80000100, %l0
+	cmp %o0, '\n'
+	bne skip
+	
+	set '\r', %l1
+	sta %l1, [%l0] 0x1c
+	
+	skip:
+		sta %o0, [%l0] 0x1c
+		retl
+		nop
+
+kernel_sp:
+.space 4
+
+uspace_wbuf:
+.space 4
+
+.align 16
+.space 4096
+boot_stack:
Index: kernel/arch/sparc32/src/trap_table.S
===================================================================
--- kernel/arch/sparc32/src/trap_table.S	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/src/trap_table.S	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,1260 @@
+#
+# Copyright (c) 2013 Jakub Klama
+# 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.
+#
+
+#include <arch/trap.h>
+#include <arch/regwin.h>
+
+.text
+
+.global trap_table
+.global reset_trap
+.global preemptible_trap
+.global interrupt_trap
+.global syscall_trap
+.global window_overflow_trap
+.global window_underflow_trap
+.global write_to_invalid
+.global read_from_invalid
+.global flush_windows
+
+.macro get_wim_number reg
+	clr \reg
+	mov %wim, %g5
+	
+	1:
+		andcc %g5, 1, %g0
+		bne 2f
+		nop
+		srl %g5, 1, %g5
+		inc \reg
+		b 1b
+	
+	2:
+		nop
+.endm
+
+.macro get_cwp reg
+	mov %psr, \reg
+	and \reg, 0x7, \reg
+.endm
+
+.macro switch_to_invalid saved_wim, saved_psr
+	get_wim_number %l3
+	mov %wim, \saved_wim    ! save WIM
+	mov %g0, %wim           ! clear WIM
+	mov %psr, \saved_psr    ! read PSR
+	and \saved_psr, 0xfffffff0, %l4
+	or %l4, %l3, %l3        ! set CWP
+	mov %l3, %psr           ! write PSR
+	nop
+	nop
+	nop
+	nop                     ! wait for PSR to be effective
+.endm
+
+.macro switch_back wim, psr
+	mov \wim, %wim          ! saved WIM
+	mov \psr, %psr          ! saved PSR
+	nop
+	nop
+	nop
+	nop
+.endm
+
+/* Save next window to kernel stack or UWB */
+.macro inline_save_kernel
+	mov %wim, %l3
+	sll %l3, 7, %l4
+	srl %l3, 1, %l3
+	or %l3, %l4, %l3
+	and %l3, 0xff, %l3
+	mov %g0, %wim
+	
+	mov %l5, %g5
+	mov %l6, %g6
+	mov %l7, %g7
+	
+	save
+	std %l0, [%sp + 0]
+	std %l2, [%sp + 8]
+	std %l4, [%sp + 16]
+	std %l6, [%sp + 24]
+	std %i0, [%sp + 32]
+	std %i2, [%sp + 40]
+	std %i4, [%sp + 48]
+	std %i6, [%sp + 56]
+	mov %g5, %l5
+	mov %g6, %l6
+	mov %g7, %l7
+	restore
+	mov %l3, %wim
+.endm
+
+.macro inline_save_uspace uwb
+	mov %wim, %l3
+	sll %l3, 7, %l4
+	srl %l3, 1, %l3
+	or %l3, %l4, %l3
+	and %l3, 0xff, %l3
+	mov %g0, %wim
+	mov \uwb, %g3
+	
+	mov %l5, %g5
+	mov %l6, %g6
+	mov %l7, %g7
+	
+	save
+	std %l0, [%g3 + 0]
+	std %l2, [%g3 + 8]
+	std %l4, [%g3 + 16]
+	std %l6, [%g3 + 24]
+	std %i0, [%g3 + 32]
+	std %i2, [%g3 + 40]
+	std %i4, [%g3 + 48]
+	std %i6, [%g3 + 56]
+	mov %g5, %l5
+	mov %g6, %l6
+	mov %g7, %l7
+	add \uwb, 64, \uwb
+	restore
+	mov %l3, %wim
+.endm
+
+/* Restore window from kernel stack or UWB */
+.macro inline_restore_kernel
+	mov %wim, %l3
+	srl %l3, 7, %l4
+	sll %l3, 1, %l3
+	or %l3, %l4, %l3
+	and %l3, 0xff, %l3
+	
+	mov %g0, %wim
+	restore
+	mov %l5, %g5
+	mov %l6, %g6
+	mov %l7, %g7
+	restore
+	mov %g5, %l5
+	mov %g6, %l6
+	mov %g7, %l7
+	save
+	
+	ldd [%sp + 0], %l0
+	ldd [%sp + 8], %l2
+	ldd [%sp + 16], %l4
+	ldd [%sp + 24], %l6
+	ldd [%sp + 32], %i0
+	ldd [%sp + 40], %i2
+	ldd [%sp + 48], %i4
+	ldd [%sp + 56], %i6
+	save
+	
+	mov %l3, %wim
+.endm
+
+.macro inline_restore_uspace uwb
+	mov %wim, %l3
+	srl %l3, 7, %l4
+	sll %l3, 1, %l3
+	or %l3, %l4, %l3
+	and %l3, 0xff, %l3
+	
+	mov %g0, %wim
+	restore
+	mov %l5, %g5
+	mov %l6, %g6
+	mov %l7, %g7
+	restore
+	mov %g5, %l5
+	mov %g6, %l6
+	mov %g7, %l7
+	save
+	
+	sub \uwb, 64, \uwb
+	ldd [\uwb + 0], %l0
+	ldd [\uwb + 8], %l2
+	ldd [\uwb + 16], %l4
+	ldd [\uwb + 24], %l6
+	ldd [\uwb + 32], %i0
+	ldd [\uwb + 40], %i2
+	ldd [\uwb + 48], %i4
+	ldd [\uwb + 56], %i6
+	save
+	
+	mov %l3, %wim
+.endm
+
+.macro if_from_kernel label
+	mov %psr, %l3
+	and %l3, (1 << 6), %l3
+	cmp %l3, 0
+	bne \label
+	nop
+.endm
+
+write_to_invalid:
+	! Write value 1
+	mov %o0, %g7
+	switch_to_invalid %g3, %g4
+	mov %g7, %l5
+	switch_back %g3, %g4
+	! Write value 2
+	mov %o1, %g7
+	switch_to_invalid %g3, %g4
+	mov %g7, %l6
+	switch_back %g3, %g4
+	! Write value 3
+	mov %o2, %g7
+	switch_to_invalid %g3, %g4
+	mov %g7, %l7
+	switch_back %g3, %g4
+	retl
+	nop
+
+read_from_invalid:
+	! Read value 1
+	mov %o0, %g7
+	switch_to_invalid %g3, %g4
+	st %l5, [%g7]
+	switch_back %g3, %g4
+	! Write value 2
+	mov %o1, %g7
+	switch_to_invalid %g3, %g4
+	st %l6, [%g7]
+	switch_back %g3, %g4
+	! Write value 3
+	mov %o2, %g7
+	switch_to_invalid %g3, %g4
+	st %l7, [%g7]
+	switch_back %g3, %g4
+	retl
+	nop
+
+reset_trap:
+	set 0x80000100, %l0
+	set 'r', %l1
+	sta %l1, [%l0] 0x1c
+	rett
+
+window_overflow_trap:
+	mov %g7, %l0
+	
+	/* Check whether previous mode was usermode */
+	mov %psr, %l4
+	and %l4, (1 << 6), %l4
+	cmp %l4, 0
+	bne 1f
+	nop
+	
+	/* User space: */
+	
+	/*
+	 * Time to check whether desired stack page is mapped
+	 * on the MMU. If so, process with saving window directly.
+	 * If not, go to preemptible trap handler.
+	 */
+	mov %wim, %g5
+	mov %g0, %wim
+	save
+	mov %sp, %g4
+	restore
+	mov %g5, %wim
+	
+	/* Check beginning of %sp */
+	and %g4, 0xfffff000, %l4
+	lda [%l4] 0x18, %l4
+	cmp %l4, 0
+	bne 1f
+	nop
+	
+	/* Prepare args for preemptible handler */
+	mov %g4, %o0
+	set preemptible_save_uspace, %o2
+	b preemptible_trap
+	nop
+	
+	/* Check end of %sp */
+	add %g4, 56, %g4
+	and %l4, 0xfffff000, %l4
+	lda [%l4] 0x18, %l4
+	cmp %l4, 0
+	bne 1f
+	nop
+	
+	/* Prepare args for preemptible handler */
+	mov %g4, %o0
+	set preemptible_save_uspace, %o2
+	b preemptible_trap
+	nop
+	
+	/* Kernel: */
+	
+	1:
+		/* Rotate WIM on bit right, we have 8 windows */
+		mov %wim, %l3
+		sll %l3, 7, %l4
+		srl %l3, 1, %l3
+		or %l3, %l4, %l3
+		and %l3, 0xff, %l3
+		
+		/* Disable WIM traps */
+		mov %g0,%wim
+		nop; nop; nop
+		
+		/* Save invalid window data */
+		mov %l5, %g5        ! kernel stack pointer
+		mov %l6, %g6        ! kernel wbuf
+		mov %l7, %g7
+		
+		/*
+		 * We should check whether window needs to be saved
+		 * to kernel stack or uwb.
+		 */
+		cmp %g7, 0
+		bne 2f
+		nop
+	
+	/* Dump registers to stack */
+	save
+	std %l0, [%sp + 0]
+	std %l2, [%sp + 8]
+	std %l4, [%sp + 16]
+	std %l6, [%sp + 24]
+	std %i0, [%sp + 32]
+	std %i2, [%sp + 40]
+	std %i4, [%sp + 48]
+	std %i6, [%sp + 56]
+	b 3f
+	nop
+	
+	/* Dump registers to uwb */
+	2:
+		save
+		std %l0, [%g6 + 0]
+		std %l2, [%g6 + 8]
+		std %l4, [%g6 + 16]
+		std %l6, [%g6 + 24]
+		std %i0, [%g6 + 32]
+		std %i2, [%g6 + 40]
+		std %i4, [%g6 + 48]
+		std %i6, [%g6 + 56]
+		add %g6, 64, %g6
+		
+		/* Check whether it's the last user window to be saved */
+		and %g7, 0x7, %l5
+		mov %psr, %l4
+		and %l4, 0x7, %l4
+		cmp %l5, %l4
+		bne 3f
+		nop
+	
+	/* Clear uspace window mark */
+	clr %g7
+	
+	3:
+		/* Back to where we should be */
+		mov %g5, %l5
+		mov %g6, %l6
+		mov %g7, %l7
+		restore
+		
+		/* Set new value of window */
+		mov %l3,%wim
+		nop; nop; nop
+		
+		/* Go home */
+		mov %l0, %g7
+		jmp %l1
+		rett %l2
+
+window_underflow_trap:
+	mov %g7, %l0
+	
+	/* Check whether previous mode was usermode */
+	mov %psr, %l4
+	and %l4, (1 << 6), %l4
+	cmp %l4, 0
+	bne 1f
+	nop
+	
+	/* User space: */
+	
+	/*
+	 * Time to check whether desired stack page is mapped
+	 * on the MMU. If so, process with saving window directly.
+	 * If not, go to preemptible trap handler.
+	 */
+	mov %wim, %g5
+	mov %g0, %wim
+	restore
+	restore
+	mov %sp, %g4
+	save
+	save
+	mov %g5, %wim
+	and %sp, 0xfffff000, %l4
+	lda [%l4] 0x18, %l4
+	cmp %l4, 0
+	bne 1f
+	nop
+	
+	/* Prepare args for preemptible handler */
+	mov %g4, %o0
+	set preemptible_restore_uspace, %o2
+	b preemptible_trap
+	nop
+	
+	1:
+		/* Rotate WIM on bit LEFT, we have 8 windows */
+		mov %wim, %l3
+		srl %l3, 7, %l4
+		sll %l3, 1, %l3
+		or %l3, %l4, %l3
+		and %l3, 0xff, %l3
+		
+		/* Disable WIM traps */
+		mov %g0, %wim
+		nop; nop; nop
+	
+	/* Kernel: */
+	restore
+	restore
+	mov %l5, %g5            ! kernel stack pointer
+	mov %l6, %g6            ! kernel wbuf
+	mov %l7, %g7
+	
+	ldd [%sp + 0], %l0
+	ldd [%sp + 8], %l2
+	ldd [%sp + 16], %l4
+	ldd [%sp + 24], %l6
+	ldd [%sp + 32], %i0
+	ldd [%sp + 40], %i2
+	ldd [%sp + 48], %i4
+	ldd [%sp + 56], %i6
+	b 2f
+	nop
+	
+	2:
+		/* Restore invalid window data */
+		restore
+		mov %g5, %l5
+		mov %g6, %l6
+		mov %g7, %l7
+		save
+		save
+		save
+		
+		/* Set new value of window */
+		mov %l3, %wim
+		nop; nop; nop
+		
+		/* Go home */
+		mov %l0, %g7
+		jmp %l1
+		rett %l2
+
+flush_windows:
+	mov 7, %g1
+	1:
+		subcc %g1, 1, %g1
+		bg 1b
+		save %sp, -64, %sp
+	
+	mov 7, %g1
+	1:
+		subcc %g1, 1, %g1
+		bg 1b
+		restore
+	
+	retl
+	nop
+
+preemptible_trap:
+	/* Save %g7 */
+	mov %g7, %l0
+	
+	/* Check whether we landed in invalid window */
+	get_wim_number %g6
+	get_cwp %g7
+	cmp %g6, %g7
+	bne 4f
+	nop
+	
+	/* We are in invalid window. Check whether previous mode was usermode. */
+	if_from_kernel 3f
+	
+	/* Trap originated from user space */
+	/* Kernel stack pointer is at %l5, uwb is at %l6 */
+	inline_save_uspace %l6
+	
+	/* Set uspace window mark */
+	mov %psr, %l7
+	inc %l7
+	and %l7, 0x7, %l7
+	or %l7, 0x10, %l7
+	b 4f
+	nop
+	
+	3:
+		/* Trap originated from kernel */
+		inline_save_kernel
+	
+	4:
+		/* Check whether previous mode was user mode */
+		if_from_kernel 5f
+	
+	/* Load kernel stack pointer from invalid window */
+	switch_to_invalid %g5, %g6
+	
+	/* set uspace window mark */
+	mov %g6, %l7
+	inc %l7
+	and %l7, 0x7, %l7
+	or %l7, 0x10, %l7
+	
+	/* Save stack pointer */
+	mov %l5, %g7
+	switch_back %g5, %g6
+	mov %g7, %sp
+	##	mov %sp, %fp
+	
+	5:
+		/* Set up stack frame */
+		sub %sp, 128, %sp
+		
+		/* Save trap data on stack */
+		mov %psr, %l5
+		st %l1, [%sp + 92]
+		st %l2, [%sp + 96]
+		st %l5, [%sp + 100]
+		st %g1, [%sp + 104]
+		st %g2, [%sp + 108]
+		st %g3, [%sp + 112]
+		st %g4, [%sp + 116]
+		st %l0, [%sp + 120]
+		
+		/* Enable traps */
+		mov %psr, %l0
+		or %l0, (1 << 5), %l0
+		or %l0, 0xf00, %l0
+		mov %l0, %psr
+		nop
+		nop
+		nop
+		nop
+		
+		/* Flush windows to stack */
+		call flush_windows
+		nop
+		
+		/* Jump to actual subroutine */
+		call %o2
+		add %sp, 128, %o1
+		
+		/* Return from handler (leave PIL disabled) */
+		ld [%sp + 92], %l1
+		ld [%sp + 96], %l2
+		ld [%sp + 100], %l0
+		or %l0, 0xf00, %l0
+		mov %l0, %psr
+		nop
+		nop
+		nop
+		nop
+		nop
+		
+		/*
+		 * If trap originated from user space, clear user space window mark
+		 * and save uwb address for future use.
+		 */
+		if_from_kernel 9f
+		switch_to_invalid %g5, %g6
+		clr %l7
+		mov %l5, %g2
+		mov %l6, %g7
+		switch_back %g5, %g6
+		mov %g7, %g1
+		
+		/* If trap originated from user space, restore all windows from UWB */
+		/* UWB pointer is at %g1 */
+	0:
+		mov %g0, %wim
+		clr %g5
+		andcc %g1, UWB_ALIGNMENT - 1, %g0
+		bz 0f
+		nop
+	
+	restore
+	sub %g1, 64, %g1
+	ldd [%g1 + 0], %l0
+	ldd [%g1 + 8], %l2
+	ldd [%g1 + 16], %l4
+	ldd [%g1 + 24], %l6
+	ldd [%g1 + 32], %i0
+	ldd [%g1 + 40], %i2
+	ldd [%g1 + 48], %i4
+	ldd [%g1 + 56], %i6
+	inc %g5
+	and %g5, 0x7, %g5
+	ba 0b
+	nop
+	
+	/*
+	 * We've restored all uspace windows. Now time to
+	 * fix CWP and WIM.
+	 */
+	0:
+		restore
+		get_cwp %g7
+		clr %g5
+		inc %g5
+		sll %g5, %g7, %g5
+		
+		/* Write values to invalid window and switch back */
+		mov %g2, %l5
+		mov %g1, %l6
+		clr %l7
+		switch_back %g5, %g6
+		
+		mov %sp, %l3
+		sub %g2, 128, %sp
+		ld [%sp + 104], %g1
+		ld [%sp + 108], %g2
+		ld [%sp + 112], %g3
+		ld [%sp + 116], %g4
+		ld [%sp + 120], %g7
+		
+		mov %l3, %sp
+		b 10f
+		nop
+	
+	9:
+		inline_restore_kernel
+		
+		ld [%sp + 104], %g1
+		ld [%sp + 108], %g2
+		ld [%sp + 112], %g3
+		ld [%sp + 116], %g4
+		ld [%sp + 120], %g7
+	
+		/* Restore old sp */
+		add %sp, 128, %sp
+	
+	10:
+		jmp %l1
+		rett %l2
+
+interrupt_trap:
+	/* Save %g7 */
+	mov %g7, %l0
+	
+	/* Check whether we landed in invalid window */
+	get_wim_number %g6
+	get_cwp %g7
+	cmp %g6, %g7
+	bne 4f
+	nop
+	
+	/* We are in invalid window. Check whether previous mode was user mode */
+	if_from_kernel 3f
+	
+	/* Trap originated from user space */
+	/* Kernel stack pointer is at %l5, uwb is at %l6 */
+	inline_save_uspace %l6
+	
+	/* Set uspace window mark */
+	mov %psr, %l7
+	inc %l7
+	and %l7, 0x7, %l7
+	or %l7, 0x10, %l7
+	b 4f
+	nop
+	
+	3:
+		/* Trap originated from kernel */
+		inline_save_kernel
+	
+	4:
+		/* Check whether previous mode was user mode */
+		if_from_kernel 5f
+		
+		/* Load kernel stack pointer from invalid window */
+		switch_to_invalid %g5, %g6
+		
+		/* Set user space window mark */
+		mov %g6, %l7
+		inc %l7
+		and %l7, 0x7, %l7
+		or %l7, 0x10, %l7
+		
+		/* Save stack pointer */
+		mov %l5, %g7
+		switch_back %g5, %g6
+		mov %g7, %sp
+	
+	5:
+		/* Set up stack frame */
+		sub %sp, 128, %sp
+		
+		/* Save trap data on stack */
+		mov %psr, %l5
+		st %l1, [%sp + 92]
+		st %l2, [%sp + 96]
+		st %l5, [%sp + 100]
+		st %g1, [%sp + 104]
+		st %g2, [%sp + 108]
+		st %g3, [%sp + 112]
+		st %g4, [%sp + 116]
+		st %l0, [%sp + 120]
+		
+		/* Enable traps (without PIL) */
+		mov %psr, %l0
+		or %l0, (1 << 5), %l0
+		or %l0, 0xf00, %l0
+		mov %l0, %psr
+		nop
+		nop
+		nop
+		nop
+		
+		/* Flush windows to stack */
+		call flush_windows
+		nop
+		
+		/* Jump to actual subroutine */
+		call irq_exception
+		add %sp, 128, %o1
+		
+		/* Return from handler (leave PIL disabled) */
+		ld [%sp + 92], %l1
+		ld [%sp + 96], %l2
+		ld [%sp + 100], %l0
+		or %l0, 0xf00, %l0
+		mov %l0, %psr
+		nop
+		nop
+		nop
+		nop
+		nop
+		
+		/*
+		 * If trap originated from user space, clear user space window mark
+		 * and save uwb address for future use.
+		 */
+		if_from_kernel 9f
+		switch_to_invalid %g5, %g6
+		clr %l7
+		mov %l5, %g2
+		mov %l6, %g7
+		switch_back %g5, %g6
+		mov %g7, %g1
+		
+		/* If trap originated from user space, restore all windows from UWB */
+		/* UWB pointer is at %g1 */
+	0:
+		mov %g0, %wim
+		clr %g5
+		andcc %g1, UWB_ALIGNMENT - 1, %g0
+		bz 0f
+		nop
+		
+		restore
+		sub %g1, 64, %g1
+		ldd [%g1 + 0], %l0
+		ldd [%g1 + 8], %l2
+		ldd [%g1 + 16], %l4
+		ldd [%g1 + 24], %l6
+		ldd [%g1 + 32], %i0
+		ldd [%g1 + 40], %i2
+		ldd [%g1 + 48], %i4
+		ldd [%g1 + 56], %i6
+		inc %g5
+		and %g5, 0x7, %g5
+		ba 0b
+		nop
+	
+	/*
+	 * We've restored all user space windows. Now time to
+	 * fix CWP and WIM.
+	 */
+	0:
+		restore
+		get_cwp %g7
+		clr %g5
+		inc %g5
+		sll %g5, %g7, %g5
+		
+		/* Write values to invalid window and switch back */
+		mov %g2, %l5
+		mov %g1, %l6
+		clr %l7
+		switch_back %g5, %g6
+		
+		mov %sp, %l3
+		sub %g2, 128, %sp
+		ld [%sp + 104], %g1
+		ld [%sp + 108], %g2
+		ld [%sp + 112], %g3
+		ld [%sp + 116], %g4
+		ld [%sp + 120], %g7
+		
+		mov %l3, %sp
+		b 10f
+		nop
+	
+	9:
+		inline_restore_kernel
+		
+		ld [%sp + 104], %g1
+		ld [%sp + 108], %g2
+		ld [%sp + 112], %g3
+		ld [%sp + 116], %g4
+		ld [%sp + 120], %g7
+		
+		/* Restore old sp */
+		add %sp, 128, %sp
+	
+	10:
+		jmp %l1
+		rett %l2
+
+syscall_trap:
+	/* Save %g7 */
+	mov %g7, %l0
+	
+	/* Check whether we landed in invalid window */
+	get_wim_number %g6
+	get_cwp %g7
+	cmp %g6, %g7
+	bne 4f
+	nop
+	
+	/* We are in invalid window. Check whether previous mode was user mode */
+	if_from_kernel 3f
+	
+	/* Trap originated from user space */
+	/* Kernel stack pointer is at %l5, uwb is at %l6 */
+	inline_save_uspace %l6
+	
+	/* Set user space window mark */
+	mov %psr, %l7
+	inc %l7
+	and %l7, 0x7, %l7
+	or %l7, 0x10, %l7
+	b 4f
+	nop
+	
+	3:
+		/* Trap originated from kernel */
+		inline_save_kernel
+	
+	4:
+		/* Check whether previous mode was user mode */
+		if_from_kernel 5f
+		
+		/* Load kernel stack pointer from invalid window */
+		switch_to_invalid %g5, %g6
+		
+		/* Set user space window mark */
+		mov %g6, %l7
+		inc %l7
+		and %l7, 0x7, %l7
+		or %l7, 0x10, %l7
+		
+		/* Save stack pointer */
+		mov %l5, %g7
+		switch_back %g5, %g6
+		mov %g7, %sp
+		## mov %sp, %fp
+		
+	5:
+		/* Set up stack frame */
+		sub %sp, 128, %sp
+		
+		/* Save trap data on stack */
+		mov %psr, %l5
+		st %l1, [%sp + 92]
+		st %l2, [%sp + 96]
+		st %l5, [%sp + 100]
+		st %g1, [%sp + 104]
+		st %g2, [%sp + 108]
+		st %g3, [%sp + 112]
+		st %g4, [%sp + 116]
+		st %l0, [%sp + 120]
+		
+		/* Enable traps (without PIL) */
+		mov %psr, %l0
+		or %l0, (1 << 5), %l0
+		or %l0, 0xf00, %l0
+		mov %l0, %psr
+		nop
+		nop
+		nop
+		nop
+		
+		/* Flush windows */
+		call flush_windows
+		nop
+		
+		/* Jump to actual subroutine */
+		sub %o0, 0x80, %o0
+		st %o0, [%sp + 92]
+		mov %i0, %o0
+		mov %i1, %o1
+		mov %i2, %o2
+		mov %i3, %o3
+		mov %i4, %o4
+		call syscall
+		mov %i5, %o5
+		
+		/* Return from handler (with PIL disabled) */
+		ld [%sp + 92], %l1
+		ld [%sp + 96], %l2
+		ld [%sp + 100], %l0
+		mov %o0, %i0
+		mov %psr, %l1
+		and %l1, 0xf, %l1
+		or %l1, 0x00000f00, %l1
+		and %l0, 0xfffffff0, %l0
+		or %l0, %l1, %l0
+		mov %l0, %psr
+		nop
+		nop
+		nop
+		nop
+		nop
+		
+		/*
+		 * If trap originated from user space, clear user space window mark
+		 * and save uwb address for future use.
+		 */
+		if_from_kernel 8f
+		switch_to_invalid %g5, %g6
+		mov %l5, %g2
+		mov %l6, %g1
+		mov %l7, %g7
+		switch_back %g5, %g6
+		
+		/* If trap originated from user space, restore all windows from UWB */
+		/* UWB pointer is at %g1 */
+	0:
+		mov %g0, %wim
+		clr %g5
+		andcc %g1, UWB_ALIGNMENT - 1, %g0
+		bz 0f
+		nop
+		
+		restore
+		sub %g1, 64, %g1
+		ldd [%g1 + 0], %l0
+		ldd [%g1 + 8], %l2
+		ldd [%g1 + 16], %l4
+		ldd [%g1 + 24], %l6
+		ldd [%g1 + 32], %i0
+		ldd [%g1 + 40], %i2
+		ldd [%g1 + 48], %i4
+		ldd [%g1 + 56], %i6
+		inc %g5
+		and %g5, 0x7, %g5
+		ba 0b
+		nop
+		
+		/*
+		 * We've restored all user space windows. Now time to
+		 * fix CWP and WIM.
+		 */
+	0:
+		restore
+		get_cwp %g7
+		clr %g5
+		inc %g5
+		sll %g5, %g7, %g5
+		
+		/* Write values to invalid window and switch back */
+		mov %g2, %l5
+		mov %g1, %l6
+		clr %l7
+		switch_back %g5, %g6
+	
+	8:
+		mov %sp, %l1
+		sub %g2, 128, %sp
+		ld [%sp + 104], %g1
+		ld [%sp + 108], %g2
+		ld [%sp + 112], %g3
+		ld [%sp + 116], %g4
+		ld [%sp + 120], %g7
+		
+		mov %l1, %sp
+		nop
+		nop
+		nop
+		
+		jmp %l2
+		rett %l2 + 4
+
+#define STRAP(_vector, _handler) \
+	.org trap_table + _vector * TRAP_ENTRY_SIZE; \
+	mov %psr, %l0 ; \
+	sethi %hi(_handler), %l4 ; \
+	jmp %lo(_handler) + %l4 ; \
+	nop
+
+#define TRAP(_vector, _handler) \
+	.org trap_table + _vector * TRAP_ENTRY_SIZE; \
+	set _vector, %o0 ; \
+	sethi %hi(_handler), %o2 ; \
+	b preemptible_trap ; \
+	or %o2, %lo(_handler), %o2 ;
+
+#define SYSCALL(_vector) \
+	.org trap_table + _vector * TRAP_ENTRY_SIZE; \
+	set _vector, %o0 ; \
+	b syscall_trap ; \
+	nop ;
+
+#define INTERRUPT(_vector, _priority) \
+	.org trap_table + _vector * TRAP_ENTRY_SIZE; \
+	mov _priority, %o0 ; \
+	b interrupt_trap ; \
+	nop ;
+	nop ;
+
+#define BADTRAP(_vector) \
+	.org trap_table + _vector * TRAP_ENTRY_SIZE ; \
+	ta 0 ;
+
+.align TRAP_TABLE_SIZE
+trap_table:
+	STRAP(0x0, reset_trap)
+	TRAP(0x1, instruction_access_exception)
+	TRAP(0x2, illegal_instruction)
+	TRAP(0x3, privileged_instruction)
+	TRAP(0x4, fp_disabled)
+	STRAP(0x5, window_overflow_trap)
+	STRAP(0x6, window_underflow_trap)
+	TRAP(0x7, mem_address_not_aligned)
+	TRAP(0x8, fp_exception)
+	TRAP(0x9, data_access_exception)
+	TRAP(0xa, tag_overflow)
+	BADTRAP(0xb)
+	BADTRAP(0xc)
+	BADTRAP(0xd)
+	BADTRAP(0xe)
+	BADTRAP(0xf)
+	BADTRAP(0x10)
+	INTERRUPT(0x11, 1)
+	INTERRUPT(0x12, 2)
+	INTERRUPT(0x13, 3)
+	INTERRUPT(0x14, 4)
+	INTERRUPT(0x15, 5)
+	INTERRUPT(0x16, 6)
+	INTERRUPT(0x17, 7)
+	INTERRUPT(0x18, 8)
+	INTERRUPT(0x19, 9)
+	INTERRUPT(0x1a, 10)
+	INTERRUPT(0x1b, 11)
+	INTERRUPT(0x1c, 12)
+	INTERRUPT(0x1d, 13)
+	INTERRUPT(0x1e, 14)
+	INTERRUPT(0x1f, 15)
+	TRAP(0x21, instruction_access_error)
+	BADTRAP(0x22)
+	BADTRAP(0x23)
+	BADTRAP(0x24)
+	BADTRAP(0x25)
+	BADTRAP(0x26)
+	BADTRAP(0x27)
+	BADTRAP(0x28)
+	TRAP(0x29, data_access_error)
+	TRAP(0x2a, division_by_zero)
+	TRAP(0x2b, data_store_error)
+	TRAP(0x2c, data_access_mmu_miss)
+	BADTRAP(0x2d)
+	BADTRAP(0x2e)
+	BADTRAP(0x2f)
+	BADTRAP(0x30)
+	BADTRAP(0x31)
+	BADTRAP(0x32)
+	BADTRAP(0x33)
+	BADTRAP(0x34)
+	BADTRAP(0x35)
+	BADTRAP(0x36)
+	BADTRAP(0x37)
+	BADTRAP(0x38)
+	BADTRAP(0x39)
+	BADTRAP(0x3a)
+	BADTRAP(0x3b)
+	BADTRAP(0x3c)
+	BADTRAP(0x3d)
+	BADTRAP(0x3e)
+	BADTRAP(0x3f)
+	BADTRAP(0x40)
+	BADTRAP(0x41)
+	BADTRAP(0x42)
+	BADTRAP(0x43)
+	BADTRAP(0x44)
+	BADTRAP(0x45)
+	BADTRAP(0x46)
+	BADTRAP(0x47)
+	BADTRAP(0x48)
+	BADTRAP(0x49)
+	BADTRAP(0x4a)
+	BADTRAP(0x4b)
+	BADTRAP(0x4c)
+	BADTRAP(0x4d)
+	BADTRAP(0x4e)
+	BADTRAP(0x4f)
+	BADTRAP(0x50)
+	BADTRAP(0x51)
+	BADTRAP(0x52)
+	BADTRAP(0x53)
+	BADTRAP(0x54)
+	BADTRAP(0x55)
+	BADTRAP(0x56)
+	BADTRAP(0x57)
+	BADTRAP(0x58)
+	BADTRAP(0x59)
+	BADTRAP(0x5a)
+	BADTRAP(0x5b)
+	BADTRAP(0x5c)
+	BADTRAP(0x5d)
+	BADTRAP(0x5e)
+	BADTRAP(0x5f)
+	BADTRAP(0x60)
+	BADTRAP(0x61)
+	BADTRAP(0x62)
+	BADTRAP(0x63)
+	BADTRAP(0x64)
+	BADTRAP(0x65)
+	BADTRAP(0x66)
+	BADTRAP(0x67)
+	BADTRAP(0x68)
+	BADTRAP(0x69)
+	BADTRAP(0x6a)
+	BADTRAP(0x6b)
+	BADTRAP(0x6c)
+	BADTRAP(0x6d)
+	BADTRAP(0x6e)
+	BADTRAP(0x6f)
+	BADTRAP(0x70)
+	BADTRAP(0x71)
+	BADTRAP(0x72)
+	BADTRAP(0x73)
+	BADTRAP(0x74)
+	BADTRAP(0x75)
+	BADTRAP(0x76)
+	BADTRAP(0x77)
+	BADTRAP(0x78)
+	BADTRAP(0x79)
+	BADTRAP(0x7a)
+	BADTRAP(0x7b)
+	BADTRAP(0x7c)
+	BADTRAP(0x7d)
+	BADTRAP(0x7e)
+	BADTRAP(0x7f)
+	SYSCALL(0x80)
+	SYSCALL(0x81)
+	SYSCALL(0x82)
+	SYSCALL(0x83)
+	SYSCALL(0x84)
+	SYSCALL(0x85)
+	SYSCALL(0x86)
+	SYSCALL(0x87)
+	SYSCALL(0x88)
+	SYSCALL(0x89)
+	SYSCALL(0x8a)
+	SYSCALL(0x8b)
+	SYSCALL(0x8c)
+	SYSCALL(0x8d)
+	SYSCALL(0x8e)
+	SYSCALL(0x8f)
+	SYSCALL(0x90)
+	SYSCALL(0x91)
+	SYSCALL(0x92)
+	SYSCALL(0x93)
+	SYSCALL(0x94)
+	SYSCALL(0x95)
+	SYSCALL(0x96)
+	SYSCALL(0x97)
+	SYSCALL(0x98)
+	SYSCALL(0x99)
+	SYSCALL(0x9a)
+	SYSCALL(0x9b)
+	SYSCALL(0x9c)
+	SYSCALL(0x9d)
+	SYSCALL(0x9e)
+	SYSCALL(0x9f)
+	SYSCALL(0xa0)
+	SYSCALL(0xa1)
+	SYSCALL(0xa2)
+	SYSCALL(0xa3)
+	SYSCALL(0xa4)
+	SYSCALL(0xa5)
+	SYSCALL(0xa6)
+	SYSCALL(0xa7)
+	SYSCALL(0xa8)
+	SYSCALL(0xa9)
+	SYSCALL(0xaa)
+	SYSCALL(0xab)
+	SYSCALL(0xac)
+	SYSCALL(0xad)
+	SYSCALL(0xae)
+	SYSCALL(0xaf)
+	SYSCALL(0xb0)
+	SYSCALL(0xb1)
+	SYSCALL(0xb2)
+	SYSCALL(0xb3)
+	SYSCALL(0xb4)
+	SYSCALL(0xb5)
+	SYSCALL(0xb6)
+	SYSCALL(0xb7)
+	SYSCALL(0xb8)
+	SYSCALL(0xb9)
+	SYSCALL(0xba)
+	SYSCALL(0xbb)
+	SYSCALL(0xbc)
+	SYSCALL(0xbd)
+	SYSCALL(0xbe)
+	SYSCALL(0xbf)
+	SYSCALL(0xc0)
+	SYSCALL(0xc1)
+	SYSCALL(0xc2)
+	SYSCALL(0xc3)
+	SYSCALL(0xc4)
+	SYSCALL(0xc5)
+	SYSCALL(0xc6)
+	SYSCALL(0xc7)
+	SYSCALL(0xc8)
+	SYSCALL(0xc9)
+	SYSCALL(0xca)
+	SYSCALL(0xcb)
+	SYSCALL(0xcc)
+	SYSCALL(0xcd)
+	SYSCALL(0xce)
+	SYSCALL(0xcf)
Index: kernel/arch/sparc32/src/userspace.c
===================================================================
--- kernel/arch/sparc32/src/userspace.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/arch/sparc32/src/userspace.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2010 Martin Decky
+ * 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 sparc32
+ * @{
+ */
+/** @file
+ */
+
+#include <userspace.h>
+#include <typedefs.h>
+#include <arch.h>
+#include <arch/asm.h>
+#include <abi/proc/uarg.h>
+#include <mm/as.h>
+
+void userspace(uspace_arg_t *kernel_uarg)
+{
+	uint32_t psr = psr_read();
+	psr &= ~(1 << 7);
+	psr &= ~(1 << 6);
+	
+	/* Read invalid window variables */
+	uint32_t l0;
+	uint32_t l1;
+	uint32_t l2;
+	read_from_invalid(&l0, &l1, &l2);
+	
+	/* Make current window invalid */
+	uint8_t wim = (psr & 0x7) + 1;
+	wim = (1 << wim) | (1 >> (8 - wim));
+	
+	asm volatile (
+		"flush\n"
+		"mov %[stack], %%sp\n"
+		"mov %[wim], %%wim\n"
+		"ld %[v0], %%o0\n"
+		"ld %[v1], %%o1\n"
+		"ld %[v2], %%o2\n"
+		"call write_to_invalid\n"
+		"nop\n"
+		"ld %[arg], %%o1\n"
+		"jmp %[entry]\n"
+		"mov %[psr], %%psr\n"
+		:: [entry] "r" (kernel_uarg->uspace_entry),
+		   [arg] "m" (kernel_uarg->uspace_uarg),
+		   [psr] "r" (psr),
+		   [wim] "r" ((uint32_t)wim),
+		   [v0] "m" (l0),
+		   [v1] "m" (l1),
+		   [v2] "m" (l2),
+		   [stack] "r" (kernel_uarg->uspace_stack +
+		   kernel_uarg->uspace_stack_size - 64)
+		: "%g3", "%g4"
+	);
+	
+	while (1);
+}
+
+/** @}
+ */
Index: kernel/arch/sparc64/src/drivers/kbd.c
===================================================================
--- kernel/arch/sparc64/src/drivers/kbd.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/arch/sparc64/src/drivers/kbd.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -44,5 +44,5 @@
 #include <align.h>
 #include <str.h>
-#include <print.h>
+#include <log.h>
 #include <sysinfo/sysinfo.h>
 
@@ -71,5 +71,6 @@
 	ofw_tree_property_t *prop = ofw_tree_getprop(node, "interrupts");
 	if ((!prop) || (!prop->value)) {
-		printf("ns16550: Unable to find interrupts property\n");
+		log(LF_ARCH, LVL_ERROR,
+		    "ns16550: Unable to find interrupts property");
 		return false;
 	}
@@ -82,5 +83,6 @@
 	prop = ofw_tree_getprop(node, "reg");
 	if ((!prop) || (!prop->value)) {
-		printf("ns16550: Unable to find reg property\n");
+		log(LF_ARCH, LVL_ERROR,
+		    "ns16550: Unable to find reg property");
 		return false;
 	}
@@ -91,5 +93,6 @@
 	if (!ofw_ebus_apply_ranges(node->parent,
 	    ((ofw_ebus_reg_t *) prop->value), &pa)) {
-		printf("ns16550: Failed to determine address\n");
+		log(LF_ARCH, LVL_ERROR,
+		    "ns16550: Failed to determine address");
 		return false;
 	}
@@ -101,5 +104,6 @@
 	    ((ofw_ebus_reg_t *) prop->value), interrupts, &inr, &cir,
 	    &cir_arg)) {
-		printf("ns16550: Failed to determine interrupt\n");
+		log(LF_ARCH, LVL_ERROR,
+		    "ns16550: Failed to determine interrupt");
 		return false;
 	}
@@ -117,5 +121,6 @@
 	    PAGE_WRITE | PAGE_NOT_CACHEABLE) + offset);
 	
-	ns16550_instance_t *ns16550_instance = ns16550_init(ns16550, inr, cir, cir_arg);
+	ns16550_instance_t *ns16550_instance = ns16550_init(ns16550, inr, cir,
+	    cir_arg);
 	if (ns16550_instance) {
 		kbrd_instance_t *kbrd_instance = kbrd_init();
Index: kernel/arch/sparc64/src/drivers/pci.c
===================================================================
--- kernel/arch/sparc64/src/drivers/pci.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/arch/sparc64/src/drivers/pci.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -43,5 +43,5 @@
 #include <typedefs.h>
 #include <debug.h>
-#include <print.h>
+#include <log.h>
 #include <str.h>
 #include <arch/asm.h>
@@ -213,5 +213,5 @@
 		 * Unsupported model.
 		 */
-		printf("Unsupported PCI controller model (%s).\n",
+		log(LF_ARCH, LVL_WARN, "Unsupported PCI controller model (%s).",
 		    (char *) prop->value);
 	}
Index: kernel/arch/sparc64/src/drivers/scr.c
===================================================================
--- kernel/arch/sparc64/src/drivers/scr.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/arch/sparc64/src/drivers/scr.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -81,5 +81,5 @@
 	
 	if (scr_type == SCR_UNKNOWN) {
-		printf("Unknown screen device.\n");
+		log(LF_ARCH, LVL_ERROR, "Unknown screen device.");
 		return;
 	}
@@ -117,5 +117,5 @@
 	case SCR_ATYFB:
 		if (prop->size / sizeof(ofw_pci_reg_t) < 2) {
-			printf("Too few screen registers.\n");
+			log(LF_ARCH, LVL_ERROR, "Too few screen registers.");
 			return;
 		}
@@ -124,5 +124,6 @@
 		
 		if (!ofw_pci_reg_absolutize(node, pci_reg, &pci_abs_reg)) {
-			printf("Failed to absolutize fb register.\n");
+			log(LF_ARCH, LVL_ERROR,
+			    "Failed to absolutize fb register.");
 			return;
 		}
@@ -130,5 +131,6 @@
 		if (!ofw_pci_apply_ranges(node->parent, &pci_abs_reg,
 		    &fb_addr)) {
-			printf("Failed to determine screen address.\n");
+			log(LF_ARCH, LVL_ERROR,
+			    "Failed to determine screen address.");
 			return;
 		}
@@ -152,5 +154,6 @@
 			break;
 		default:
-			printf("Unsupported bits per pixel.\n");
+			log(LF_ARCH, LVL_ERROR,
+			    "Unsupported bits per pixel.");
 			return;
 		}
@@ -159,5 +162,6 @@
 	case SCR_XVR:
 		if (prop->size / sizeof(ofw_pci_reg_t) < 2) {
-			printf("Too few screen registers.\n");
+			log(LF_ARCH, LVL_ERROR,
+			    "Too few screen registers.");
 			return;
 		}
@@ -166,5 +170,6 @@
 		
 		if (!ofw_pci_reg_absolutize(node, pci_reg, &pci_abs_reg)) {
-			printf("Failed to absolutize fb register.\n");
+			log(LF_ARCH, LVL_ERROR,
+			    "Failed to absolutize fb register.");
 			return;
 		}
@@ -172,5 +177,6 @@
 		if (!ofw_pci_apply_ranges(node->parent, &pci_abs_reg,
 		    &fb_addr)) {
-			printf("Failed to determine screen address.\n");
+			log(LF_ARCH, LVL_ERROR,
+			    "Failed to determine screen address.");
 			return;
 		}
@@ -196,5 +202,6 @@
 			break;
 		default:
-			printf("Unsupported bits per pixel.\n");
+			log(LF_ARCH, LVL_ERROR,
+			    "Unsupported bits per pixel.");
 			return;
 		}
@@ -207,5 +214,6 @@
 		upa_reg = &((ofw_upa_reg_t *) prop->value)[FFB_REG_24BPP];
 		if (!ofw_upa_apply_ranges(node->parent, upa_reg, &fb_addr)) {
-			printf("Failed to determine screen address.\n");
+			log(LF_ARCH, LVL_ERROR,
+			    "Failed to determine screen address.");
 			return;
 		}
@@ -219,5 +227,5 @@
 			break;
 		default:
-			printf("Not implemented.\n");
+			log(LF_ARCH, LVL_WARN, "Not implemented.");
 			return;
 		}
@@ -225,5 +233,6 @@
 		sbus_reg = &((ofw_sbus_reg_t *) prop->value)[0];
 		if (!ofw_sbus_apply_ranges(node->parent, sbus_reg, &fb_addr)) {
-			printf("Failed to determine screen address.\n");
+			log(LF_ARCH, LVL_ERROR,
+			    "Failed to determine screen address.");
 			return;
 		}
@@ -233,5 +242,5 @@
 	case SCR_QEMU_VGA:
 		if (prop->size / sizeof(ofw_pci_reg_t) < 2) {
-			printf("Too few screen registers.\n");
+			log(LF_ARCH, LVL_ERROR, "Too few screen registers.");
 			return;
 		}
@@ -240,5 +249,6 @@
 
 		if (!ofw_pci_reg_absolutize(node, pci_reg, &pci_abs_reg)) {
-			printf("Failed to absolutize fb register.\n");
+			log(LF_ARCH, LVL_ERROR,
+			    "Failed to absolutize fb register.");
 			return;
 		}
@@ -246,5 +256,6 @@
 		if (!ofw_pci_apply_ranges(node->parent, &pci_abs_reg,
 		    &fb_addr)) {
-			printf("Failed to determine screen address.\n");
+			log(LF_ARCH, LVL_ERROR,
+			    "Failed to determine screen address.");
 			return;
 		}
@@ -268,5 +279,5 @@
 			break;
 		default:
-			printf("Unsupported bits per pixel.\n");
+			log(LF_ARCH, LVL_ERROR, "Unsupported bits per pixel.");
 			return;
 		}
Index: kernel/arch/sparc64/src/mm/sun4v/tlb.c
===================================================================
--- kernel/arch/sparc64/src/mm/sun4v/tlb.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/arch/sparc64/src/mm/sun4v/tlb.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -46,4 +46,5 @@
 #include <arch.h>
 #include <print.h>
+#include <log.h>
 #include <typedefs.h>
 #include <config.h>
@@ -335,5 +336,5 @@
 void tlb_print(void)
 {
-	printf("Operation not possible on Niagara.\n");
+	log(LF_ARCH, LVL_WARN, "Operation not possible on Niagara.");
 }
 
Index: kernel/arch/sparc64/src/smp/sun4u/smp.c
===================================================================
--- kernel/arch/sparc64/src/smp/sun4u/smp.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/arch/sparc64/src/smp/sun4u/smp.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -43,5 +43,5 @@
 #include <typedefs.h>
 #include <synch/waitq.h>
-#include <print.h>
+#include <log.h>
 #include <arch/cpu_node.h>
 
@@ -108,6 +108,6 @@
 	if (waitq_sleep_timeout(&ap_completion_wq, 1000000, SYNCH_FLAGS_NONE) ==
 	    ESYNCH_TIMEOUT)
-		printf("%s: waiting for processor (mid = %" PRIu32
-		    ") timed out\n", __func__, mid);
+		log(LF_ARCH, LVL_NOTE, "%s: waiting for processor (mid = %" PRIu32
+		    ") timed out", __func__, mid);
 }
 
Index: kernel/arch/sparc64/src/sun4v/md.c
===================================================================
--- kernel/arch/sparc64/src/sun4v/md.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/arch/sparc64/src/sun4v/md.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -36,5 +36,5 @@
 #include <panic.h>
 #include <func.h>
-#include <print.h>
+#include <log.h>
 #include <str.h>
 #include <arch/sun4v/md.h>
@@ -310,6 +310,6 @@
 	retval = retval;
 	if (retval != HV_EOK) {
-		printf("Could not retrieve machine description, "
-		    "error=%" PRIu64 ".\n", retval);
+		log(LF_ARCH, LVL_ERROR, "Could not retrieve machine "
+		    "description, error=%" PRIu64 ".", retval);
 	}
 }
Index: kernel/arch/sparc64/src/trap/sun4u/interrupt.c
===================================================================
--- kernel/arch/sparc64/src/trap/sun4u/interrupt.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/arch/sparc64/src/trap/sun4u/interrupt.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -42,5 +42,5 @@
 #include <arch/asm.h>
 #include <arch/barrier.h>
-#include <print.h>
+#include <log.h>
 #include <arch.h>
 #include <mm/tlb.h>
@@ -96,6 +96,7 @@
 		 */
 #ifdef CONFIG_DEBUG
-		printf("cpu%u: spurious interrupt (intrcv=%#" PRIx64
-		    ", data0=%#" PRIx64 ")\n", CPU->id, intrcv, data0);
+		log(LF_ARCH, LVL_DEBUG,
+		    "cpu%u: spurious interrupt (intrcv=%#" PRIx64 ", data0=%#"
+		    PRIx64 ")", CPU->id, intrcv, data0);
 #else
 		(void) intrcv;
Index: kernel/arch/sparc64/src/trap/sun4v/interrupt.c
===================================================================
--- kernel/arch/sparc64/src/trap/sun4v/interrupt.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/arch/sparc64/src/trap/sun4v/interrupt.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -42,5 +42,5 @@
 #include <arch/asm.h>
 #include <arch/barrier.h>
-#include <print.h>
+#include <log.h>
 #include <arch.h>
 #include <mm/tlb.h>
@@ -111,6 +111,6 @@
 			((void (*)(void)) data1)();
 		} else {
-			printf("Spurious interrupt on %" PRIu64 ", data = %" PRIx64 ".\n",
-			    CPU->arch.id, data1);
+			log(LF_ARCH, LVL_DEBUG, "Spurious interrupt on %" PRIu64
+			    ", data = %" PRIx64 ".", CPU->arch.id, data1);
 		}
 	}
Index: kernel/doc/doxygroups.h
===================================================================
--- kernel/doc/doxygroups.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/doc/doxygroups.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -167,6 +167,6 @@
  */
  
-/** @defgroup genericklog KLog
- * @brief Kernel logging facility
+/** @defgroup generickio KIO
+ * @brief Kernel character input/output facility
  * @ingroup genericconsole
  */
Index: kernel/genarch/Makefile.inc
===================================================================
--- kernel/genarch/Makefile.inc	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/genarch/Makefile.inc	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -90,17 +90,17 @@
 endif
 
-ifeq ($(CONFIG_ARM926_UART),y)
+ifeq ($(CONFIG_PL011_UART),y)
 	GENARCH_SOURCES += \
-		genarch/src/drivers/arm926_uart/arm926_uart.c
+		genarch/src/drivers/pl011/pl011.c
 endif
 
 ifeq ($(CONFIG_S3C24XX_IRQC),y)
 	GENARCH_SOURCES += \
-		genarch/src/drivers/s3c24xx_irqc/s3c24xx_irqc.c
+		genarch/src/drivers/s3c24xx/irqc.c
 endif
 
 ifeq ($(CONFIG_S3C24XX_UART),y)
 	GENARCH_SOURCES += \
-		genarch/src/drivers/s3c24xx_uart/s3c24xx_uart.c
+		genarch/src/drivers/s3c24xx/uart.c
 endif
 
@@ -110,7 +110,22 @@
 endif
 
+ifeq ($(CONFIG_GRLIB_UART),y)
+	GENARCH_SOURCES += \
+		genarch/src/drivers/grlib/uart.c
+endif
+
+ifeq ($(CONFIG_GRLIB_IRQMP),y)
+	GENARCH_SOURCES += \
+		genarch/src/drivers/grlib/irqmp.c
+endif
+
 ifeq ($(CONFIG_AM335X_TIMERS),y)
 	GENARCH_SOURCES += \
 		genarch/src/drivers/am335x/timer.c
+endif
+
+ifeq ($(CONFIG_BCM2835_MAILBOX),y)
+	GENARCH_SOURCES += \
+		genarch/src/drivers/bcm2835/mbox.c
 endif
 
Index: rnel/genarch/include/genarch/drivers/arm926_uart/arm926_uart.h
===================================================================
--- kernel/genarch/include/genarch/drivers/arm926_uart/arm926_uart.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,169 +1,0 @@
-/*
- * Copyright (c) 2012 Jan Vesely
- * 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 genarch
- * @{
- */
-/**
- * @file
- * @brief ARM926 on-chip UART (PrimeCell UART, PL011) driver.
- */
-
-#ifndef KERN_ARM926_UART_H_
-#define KERN_ARM926_UART_H_
-
-#include <ddi/irq.h>
-#include <console/chardev.h>
-#include <typedefs.h>
-
-
-/** ARM926 User Guide ch. 4.8.5 (p. 106 in the pdf) */
-#define ARM926_UART0_BASE_ADDRESS   0x16000000
-#define ARM926_UART1_BASE_ADDRESS   0x16000000
-
-/** ARM926 User Guide ch. A.1 (p. 124 in the pdf) */
-#define ARM926_UART0_IRQ   1
-#define ARM926_UART1_IRQ   2
-
-/** PrimeCell UART TRM ch. 3.3 (p. 49 in the pdf) */
-typedef struct {
-	/** UART data register */
-	ioport32_t data;
-#define ARM926_UART_DATA_DATA_MASK   0xff
-#define ARM926_UART_DATA_FE_FLAG   (1 <<  7)
-#define ARM926_UART_DATA_PE_FLAG   (1 <<  9)
-#define ARM926_UART_DATA_BE_FLAG   (1 << 10)
-#define ARM926_UART_DATA_OE_FLAG   (1 << 11)
-
-	union {
-		/* Same values that are in upper bits of data register*/
-		const ioport32_t status;
-#define ARM926_UART_STATUS_FE_FLAG   (1 << 0)
-#define ARM926_UART_STATUS_PE_FLAG   (1 << 1)
-#define ARM926_UART_STATUS_BE_FLAG   (1 << 2)
-#define ARM926_UART_STATUS_OE_FLAG   (1 << 3)
-		/* Writing anything clears all errors */
-		ioport32_t error_clear;
-	};
-	uint32_t padd0_[4];
-
-	const ioport32_t flag;
-#define ARM926_UART_FLAG_CTS_FLAG    (1 << 0)
-#define ARM926_UART_FLAG_DSR_FLAG    (1 << 1)
-#define ARM926_UART_FLAG_DCD_FLAG    (1 << 2)
-#define ARM926_UART_FLAG_BUSY_FLAG   (1 << 3)
-#define ARM926_UART_FLAG_RXFE_FLAG   (1 << 4)
-#define ARM926_UART_FLAG_TXFF_FLAG   (1 << 5)
-#define ARM926_UART_FLAG_RXFF_FLAG   (1 << 6)
-#define ARM926_UART_FLAG_TXFE_FLAG   (1 << 7)
-#define ARM926_UART_FLAG_RI_FLAG     (1 << 8)
-	uint32_t padd1_;
-
-	ioport32_t irda_low_power;
-#define ARM926_UART_IRDA_LOW_POWER_MASK   0xff
-
-	ioport32_t int_baud_divisor;
-#define ARM926_UART_INT_BAUD_DIVISOR_MASK   0xffff
-
-	ioport32_t fract_baud_divisor;
-#define ARM926_UART_FRACT_BAUD_DIVISOR_MASK   0x1f
-
-	ioport32_t line_control_high;
-#define ARM926_UART_CONTROLHI_BRK_FLAG    (1 << 0)
-#define ARM926_UART_CONTROLHI_PEN_FLAG    (1 << 1)
-#define ARM926_UART_CONTROLHI_EPS_FLAG    (1 << 2)
-#define ARM926_UART_CONTROLHI_STP2_FLAG   (1 << 3)
-#define ARM926_UART_CONTROLHI_FEN_FLAG    (1 << 4)
-#define ARM926_UART_CONTROLHI_WLEN_MASK   0x3
-#define ARM926_UART_CONTROLHI_WLEN_SHIFT    5
-#define ARM926_UART_CONTROLHI_SPS_FLAG    (1 << 5)
-
-	ioport32_t control;
-#define ARM926_UART_CONTROL_UARTEN_FLAG   (1 << 0)
-#define ARM926_UART_CONTROL_SIREN_FLAG    (1 << 1)
-#define ARM926_UART_CONTROL_SIRLP_FLAG    (1 << 2)
-#define ARM926_UART_CONTROL_LBE_FLAG      (1 << 7)
-#define ARM926_UART_CONTROL_TXE_FLAG      (1 << 8)
-#define ARM926_UART_CONTROL_RXE_FLAG      (1 << 9)
-#define ARM926_UART_CONTROL_DTR_FLAG     (1 << 10)
-#define ARM926_UART_CONTROL_RTS_FLAG     (1 << 11)
-#define ARM926_UART_CONTROL_OUT1_FLAG    (1 << 12)
-#define ARM926_UART_CONTROL_OUT2_FLAG    (1 << 13)
-#define ARM926_UART_CONTROL_RTSE_FLAG    (1 << 14)
-#define ARM926_UART_CONTROL_CTSE_FLAG    (1 << 15)
-
-	ioport32_t interrupt_fifo;
-#define ARM926_UART_INTERRUPTFIFO_TX_MASK   0x7
-#define ARM926_UART_INTERRUPTFIFO_TX_SHIFT    0
-#define ARM926_UART_INTERRUPTFIFO_RX_MASK   0x7
-#define ARM926_UART_INTERRUPTFIFO_RX_SHIFT    3
-
-	/** Interrupt mask register */
-	ioport32_t interrupt_mask;
-	/** Pending interrupts before applying the mask */
-	const ioport32_t raw_interrupt_status;
-	/** Pending interrupts after applying the mask */
-	const ioport32_t masked_interrupt_status;
-	/** Write 1s to clear pending interrupts */
-	ioport32_t interrupt_clear;
-#define ARM926_UART_INTERRUPT_RIM_FLAG    (1 << 0)
-#define ARM926_UART_INTERRUPT_CTSM_FLAG   (1 << 1)
-#define ARM926_UART_INTERRUPT_DCDM_FLAG   (1 << 2)
-#define ARM926_UART_INTERRUPT_DSRM_FLAG   (1 << 3)
-#define ARM926_UART_INTERRUPT_RX_FLAG     (1 << 4)
-#define ARM926_UART_INTERRUPT_TX_FLAG     (1 << 5)
-#define ARM926_UART_INTERRUPT_RT_FLAG     (1 << 6)
-#define ARM926_UART_INTERRUPT_FE_FLAG     (1 << 7)
-#define ARM926_UART_INTERRUPT_PE_FLAG     (1 << 8)
-#define ARM926_UART_INTERRUPT_BE_FLAG     (1 << 9)
-#define ARM926_UART_INTERRUPT_OE_FLAG    (1 << 10)
-#define ARM926_UART_INTERRUPT_ALL           0x3ff
-
-	ioport32_t dma_control;
-#define ARM926_UART_DMACONTROL_RXDMAEN_FLAG    (1 << 0)
-#define ARM926_UART_DMACONTROL_TXDMAEN_FLAG    (1 << 1)
-#define ARM926_UART_DMACONTROL_DMAONERR_FLAG   (1 << 2)
-
-	// TODO There is some reserved space here followed by
-	// peripheral identification registers.
-} arm926_uart_regs_t;
-
-typedef struct {
-	arm926_uart_regs_t *regs;
-	indev_t *indev;
-	outdev_t outdev;
-	irq_t irq;
-} arm926_uart_t;
-
-bool arm926_uart_init(arm926_uart_t *, inr_t, uintptr_t, size_t);
-void arm926_uart_input_wire(arm926_uart_t *, indev_t *);
-
-#endif
-/**
- * @}
- */
Index: kernel/genarch/include/genarch/drivers/bcm2835/irc.h
===================================================================
--- kernel/genarch/include/genarch/drivers/bcm2835/irc.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/genarch/include/genarch/drivers/bcm2835/irc.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2012 Jan Vesely
+ * Copyright (c) 2013 Beniamino Galvani
+ * 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 genarch
+ * @{
+ */
+/**
+ * @file
+ * @brief Broadcom BCM2835 on-chip interrupt controller driver.
+ */
+
+#ifndef KERN_BCM2835_IRQC_H_
+#define KERN_BCM2835_IRQC_H_
+
+#include <typedefs.h>
+
+#define BANK_GPU0	0
+#define BANK_GPU1	1
+#define BANK_ARM	2
+
+#define IRQ_TO_BANK(x)	((x) >> 5)
+#define IRQ_TO_NUM(x)	((x) & 0x1f)
+
+#define MAKE_IRQ(b,n)	(((b) << 5) | ((n) & 0x1f))
+
+#define BCM2835_UART_IRQ	MAKE_IRQ(BANK_GPU1, 25)
+#define BCM2835_TIMER1_IRQ	MAKE_IRQ(BANK_GPU0,  1)
+
+#define IRQ_PEND_ARM_M		0xFF
+#define IRQ_PEND_GPU0_M		(1 << 8)
+#define IRQ_PEND_GPU1_M		(1 << 9)
+#define IRQ_PEND_SHORT_M	0x1FFC00
+#define IRQ_PEND_SHORT_S	10
+
+unsigned shortcut_inums[] = {7, 9, 10, 18, 19, 53, 54, 55, 56, 57, 62};
+
+typedef struct {
+	ioport32_t	irq_basic_pending;
+	ioport32_t	irq_pending1;
+	ioport32_t	irq_pending2;
+
+	ioport32_t	fiq_control;
+
+	ioport32_t	irq_enable[3];
+	ioport32_t	irq_disable[3];
+} bcm2835_irc_t;
+
+#define BCM2835_IRC_ADDR 0x2000b200
+#define BCM2835_IRQ_COUNT 96
+
+static inline void bcm2835_irc_dump(bcm2835_irc_t *regs)
+{
+#define DUMP_REG(name) \
+	printf("%s : %08x\n", #name, regs->name);
+
+	DUMP_REG(irq_basic_pending);
+	DUMP_REG(irq_pending1);
+	DUMP_REG(irq_pending2);
+	DUMP_REG(fiq_control);
+
+	for (int i = 0; i < 3; ++i) {
+		DUMP_REG(irq_enable[i]);
+		DUMP_REG(irq_disable[i]);
+	}
+#undef DUMP_REG
+}
+
+static inline void bcm2835_irc_init(bcm2835_irc_t *regs)
+{
+	/* Disable all interrupts */
+	regs->irq_disable[BANK_GPU0] = 0xffffffff;
+	regs->irq_disable[BANK_GPU1] = 0xffffffff;
+	regs->irq_disable[BANK_ARM]  = 0xffffffff;
+
+	/* Disable FIQ generation */
+	regs->fiq_control = 0;
+}
+
+static inline int ffs(unsigned int x)
+{
+	int ret;
+
+	asm volatile (
+		"clz r0, %[x]\n"
+		"rsb %[ret], r0, #32\n"
+		: [ret] "=r" (ret)
+		: [x] "r" (x)
+		: "r0" );
+
+	return ret;
+}
+
+static inline unsigned bcm2835_irc_inum_get(bcm2835_irc_t *regs)
+{
+	uint32_t pending;
+	int inum = -1;
+
+	pending = regs->irq_basic_pending;
+
+	/*
+	 * The basic pending register shows interrupts pending from ARM
+	 * peripherals and it also contains, in order to speed up processing,
+	 * additional information about pending GPU interrupts:
+	 *
+	 *  - bits 0-7 are associated to ARM peripherals
+	 *  - bit 8 is 1 when at least one bit is set in pending register 1
+	 *  - bit 9 is 1 when at least one bit is set in pending register 2
+	 *  - bits 10-20 indicate pending status of selected GPU peripherals
+	 *
+	 *  Reference: BCM2835 ARM Peripherals, p.113
+	 */
+
+	if (pending & IRQ_PEND_ARM_M) {
+		inum = MAKE_IRQ(BANK_ARM, ffs(pending & IRQ_PEND_ARM_M) - 1);
+	} else if (pending & IRQ_PEND_SHORT_M) {
+		int pos = (pending & IRQ_PEND_SHORT_M) >> IRQ_PEND_SHORT_S;
+		inum = shortcut_inums[ffs(pos) - 1];
+	} else if (pending & IRQ_PEND_GPU0_M) {
+		inum = MAKE_IRQ(BANK_GPU0, ffs(regs->irq_pending1) - 1);
+	} else if (pending & IRQ_PEND_GPU1_M) {
+		inum = MAKE_IRQ(BANK_GPU1, ffs(regs->irq_pending2) - 1);
+	}
+
+	if (inum < 0) {
+		printf("Spurious interrupt!\n");
+		bcm2835_irc_dump(regs);
+		inum = 0;
+	}
+
+	return inum;
+}
+
+static inline void bcm2835_irc_enable(bcm2835_irc_t *regs, unsigned inum)
+{
+	ASSERT(inum < BCM2835_IRQ_COUNT);
+	regs->irq_enable[IRQ_TO_BANK(inum)] |= (1 << IRQ_TO_NUM(inum));
+}
+
+static inline void bcm2835_irc_disable(bcm2835_irc_t *regs, unsigned inum)
+{
+	ASSERT(inum < BCM2835_IRQ_COUNT);
+	regs->irq_disable[IRQ_TO_BANK(inum)] |= (1 << IRQ_TO_NUM(inum));
+}
+
+#endif /* KERN_BCM2835_IRQC_H_ */
+
+/**
+ * @}
+ */
Index: kernel/genarch/include/genarch/drivers/bcm2835/mbox.h
===================================================================
--- kernel/genarch/include/genarch/drivers/bcm2835/mbox.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/genarch/include/genarch/drivers/bcm2835/mbox.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2013 Beniamino Galvani
+ * 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 genarch
+ * @{
+ */
+/**
+ * @file
+ * @brief BCM2835 mailbox communication routines
+ */
+
+#ifndef _BCM2835_MBOX_H_
+#define _BCM2835_MBOX_H_
+
+#include <genarch/fb/fb.h>
+#include <arch/mm/page.h>
+#include <align.h>
+
+#define BCM2835_MBOX0_ADDR	0x2000B880
+
+enum {
+	MBOX_CHAN_PM		= 0,
+	MBOX_CHAN_FB		= 1,
+	MBOX_CHAN_UART		= 2,
+	MBOX_CHAN_VCHIQ		= 3,
+	MBOX_CHAN_LED		= 4,
+	MBOX_CHAN_BTN		= 5,
+	MBOX_CHAN_TS		= 6,
+	MBOX_CHAN_PROP_A2V	= 8,
+	MBOX_CHAN_PROP_V2A	= 9
+};
+
+enum {
+	TAG_GET_FW_REV		= 0x00000001,
+	TAG_GET_BOARD_MODEL	= 0x00010001,
+	TAG_GET_BOARD_REV	= 0x00010002,
+	TAG_GET_BOARD_MAC	= 0x00010003,
+	TAG_GET_BOARD_SERIAL	= 0x00010004,
+	TAG_GET_ARM_MEMORY	= 0x00010005,
+	TAG_GET_VC_MEMORY	= 0x00010006,
+	TAG_GET_CLOCKS		= 0x00010007,
+	TAG_GET_CMD_LINE	= 0x00050001,
+};
+
+enum {
+	MBOX_PROP_CODE_REQ	= 0x00000000,
+	MBOX_PROP_CODE_RESP_OK	= 0x80000000,
+	MBOX_PROP_CODE_RESP_ERR	= 0x80000001
+};
+
+#define MBOX_STATUS_FULL	(1 << 31)
+#define MBOX_STATUS_EMPTY	(1 << 30)
+
+#define MBOX_COMPOSE(chan, value) (((chan) & 0xf) | ((value) & ~0xf))
+#define MBOX_MSG_CHAN(msg)	((msg) & 0xf)
+#define MBOX_MSG_VALUE(msg)	((msg) & ~0xf)
+
+#define KA2VCA(addr)		(KA2PA(addr) + 0x40000000)
+
+#define MBOX_ADDR_ALIGN		16
+
+#define MBOX_BUFF_ALLOC(name, type)					\
+	char tmp_ ## name[sizeof(type) + MBOX_ADDR_ALIGN] = { 0 };      \
+	type *name = (type *)ALIGN_UP((uintptr_t)tmp_ ## name, MBOX_ADDR_ALIGN);
+
+typedef struct {
+	ioport32_t read;
+	ioport32_t unused[3];
+	ioport32_t peek;
+	ioport32_t sender;
+	ioport32_t status;
+	ioport32_t config;
+	ioport32_t write;
+} bcm2835_mbox_t;
+
+typedef struct {
+	ioport32_t size;
+	ioport32_t code;
+} mbox_prop_buf_hdr_t;
+
+typedef struct {
+	ioport32_t tag_id;
+	ioport32_t buf_size;
+	ioport32_t val_len;
+} mbox_tag_hdr_t;
+
+typedef struct {
+	ioport32_t base;
+	ioport32_t size;
+} mbox_tag_getmem_resp_t;
+
+typedef struct {
+	mbox_prop_buf_hdr_t	buf_hdr;
+	mbox_tag_hdr_t		tag_hdr;
+	mbox_tag_getmem_resp_t	data;
+	uint32_t		zero;
+} mbox_getmem_buf_t;
+
+typedef struct {
+	ioport32_t width;
+	ioport32_t height;
+	ioport32_t virt_width;
+	ioport32_t virt_height;
+	ioport32_t pitch;
+	ioport32_t bpp;
+	ioport32_t x_offset;
+	ioport32_t y_offset;
+	ioport32_t addr;
+	ioport32_t size;
+} bcm2835_fb_desc_t;
+
+bool bcm2835_prop_get_memory(uint32_t *base, uint32_t *size);
+bool bcm2835_fb_init(fb_properties_t *prop);
+
+#endif
+/**
+ * @}
+ */
Index: kernel/genarch/include/genarch/drivers/bcm2835/timer.h
===================================================================
--- kernel/genarch/include/genarch/drivers/bcm2835/timer.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/genarch/include/genarch/drivers/bcm2835/timer.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2013 Beniamino Galvani
+ * 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 genarch
+ * @{
+ */
+/**
+ * @file
+ * @brief Broadcom BCM2835 system timer driver.
+ */
+
+#ifndef KERN_BCM2835_TIMER_H_
+
+#include <typedefs.h>
+#include <mm/km.h>
+
+#define BCM2835_TIMER_ADDR 0x20003000
+#define BCM2835_CLOCK_FREQ 1000000
+
+typedef struct {
+	/** System Timer Control/Status */
+	ioport32_t cs;
+#define BCM2835_TIMER_CS_M0 (1 << 0)
+#define BCM2835_TIMER_CS_M1 (1 << 1)
+#define BCM2835_TIMER_CS_M2 (1 << 2)
+#define BCM2835_TIMER_CS_M3 (1 << 3)
+	/** System Timer Counter Lower 32 bits */
+	ioport32_t clo;
+	/** System Timer Counter Higher 32 bits */
+	ioport32_t chi;
+	/** System Timer Compare 0 */
+	ioport32_t c0;
+	/** System Timer Compare 1 */
+	ioport32_t c1;
+	/** System Timer Compare 2 */
+	ioport32_t c2;
+	/** System Timer Compare 3 */
+	ioport32_t c3;
+} bcm2835_timer_t;
+
+
+static inline void bcm2835_timer_start(bcm2835_timer_t* timer)
+{
+	ASSERT(timer);
+	/* Clear pending interrupt on channel 1 */
+	timer->cs |= BCM2835_TIMER_CS_M1;
+	/* Initialize compare value for match channel 1 */
+	timer->c1 = timer->clo + (BCM2835_CLOCK_FREQ / HZ);
+}
+
+static inline void bcm2835_timer_irq_ack(bcm2835_timer_t* timer)
+{
+	ASSERT(timer);
+	/* Clear pending interrupt on channel 1 */
+	timer->cs |= BCM2835_TIMER_CS_M1;
+	/* Reprogram compare value for match channel 1 */
+	timer->c1 = timer->clo + (BCM2835_CLOCK_FREQ / HZ);
+}
+
+#endif /* KERN_BCM2835_TIMER_H_ */
Index: kernel/genarch/include/genarch/drivers/grlib/irqmp.h
===================================================================
--- kernel/genarch/include/genarch/drivers/grlib/irqmp.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/genarch/include/genarch/drivers/grlib/irqmp.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2013 Jakub Klama
+ * 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 genarch
+ * @{
+ */
+/**
+ * @file
+ * @brief Gaisler GRLIB interrupt controller driver.
+ */
+
+#ifndef KERN_GRLIB_IRQMP_H_
+#define KERN_GRLIB_IRQMP_H_
+
+#include <typedefs.h>
+#include <arch.h>
+
+#define GRLIB_IRQMP_MASK_OFFSET   0x40
+#define GRLIB_IRQMP_FORCE_OFFSET  0x80
+
+/** IRQMP registers */
+typedef struct {
+	uint32_t level;
+	uint32_t pending;
+	uint32_t force;
+	uint32_t clear;
+	uint32_t mp_status;
+	uint32_t broadcast;
+} grlib_irqmp_regs_t;
+
+/** LEON3 interrupt assignments */
+enum grlib_irq_source {
+	GRLIB_INT_AHBERROR = 1,
+	GRLIB_INT_UART1    = 2,
+	GRLIB_INT_PCIDMA   = 4,
+	GRLIB_INT_CAN      = 5,
+	GRLIB_INT_TIMER0   = 6,
+	GRLIB_INT_TIMER1   = 7,
+	GRLIB_INT_TIMER2   = 8,
+	GRLIB_INT_TIMER3   = 9,
+	GRLIB_INT_ETHERNET = 14
+};
+
+typedef struct {
+	grlib_irqmp_regs_t *regs;
+} grlib_irqmp_t;
+
+extern void grlib_irqmp_init(grlib_irqmp_t *, bootinfo_t *);
+extern int grlib_irqmp_inum_get(grlib_irqmp_t *);
+extern void grlib_irqmp_clear(grlib_irqmp_t *, unsigned int);
+extern void grlib_irqmp_mask(grlib_irqmp_t *, unsigned int);
+extern void grlib_irqmp_unmask(grlib_irqmp_t *, unsigned int);
+
+#endif
+
+/** @}
+ */
Index: kernel/genarch/include/genarch/drivers/grlib/timer.h
===================================================================
--- kernel/genarch/include/genarch/drivers/grlib/timer.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/genarch/include/genarch/drivers/grlib/timer.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,81 @@
+/*
+ * Copyrihgt (c) 2013 Jakub Klama
+ * 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 genarch
+ * @{
+ */
+/**
+ * @file
+ * @brief Gaisler GRLIB gptimer driver.
+ */
+
+#ifndef KERN_GRLIB_TIMER_H_
+#define KERN_GRLIB_TIMER_H_
+
+#include <typedefs.h>
+
+/** GRLIB gptimer registers */
+typedef struct {
+	uint32_t scaler;
+	uint32_t scaler_reload;
+	uint32_t config;
+	uint32_t latch_config;
+	struct {
+		uint32_t counter;
+		uint32_t reload;
+		uint32_t control;
+		uint32_t latch;
+	} timers[7];
+} grlib_timer_t;
+
+struct grlib_timer_config_t {
+	unsigned int : 20;
+	unsigned int es : 1;
+	unsigned int el : 1;
+	unsigned int ee : 1;
+	unsigned int df : 1;
+	unsigned int si : 1;
+	unsigned int irq : 5;
+	unsigned int timers : 2;
+};
+
+struct grlib_timer_control_t {
+	unsigned int : 25;
+	unsigned int dh : 1;
+	unsigned int ch : 1;
+	unsigned int ip : 1;
+	unsigned int ie : 1;
+	unsigned int ld : 1;
+	unsigned int rs : 1;
+	unsigned int en : 1;
+};
+
+#endif
+
+/** @}
+ */
Index: kernel/genarch/include/genarch/drivers/grlib/uart.h
===================================================================
--- kernel/genarch/include/genarch/drivers/grlib/uart.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/genarch/include/genarch/drivers/grlib/uart.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2010 Jiri Svoboda
+ * Copyright (c) 2013 Jakub Klama
+ * 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 genarch
+ * @{
+ */
+/**
+ * @file
+ * @brief Gaisler GRLIB UART IP-Core driver.
+ */
+
+#ifndef KERN_GRLIB_UART_H_
+#define KERN_GRLIB_UART_H_
+
+#include <ddi/ddi.h>
+#include <ddi/irq.h>
+#include <console/chardev.h>
+#include <typedefs.h>
+
+typedef struct {
+	unsigned int rcnt: 6;
+	unsigned int tcnt: 6;
+	unsigned int : 9;
+	unsigned int rf: 1;
+	unsigned int tf: 1;
+	unsigned int rh: 1;
+	unsigned int th: 1;
+	unsigned int fe: 1;
+	unsigned int pe: 1;
+	unsigned int ov: 1;
+	unsigned int br: 1;
+	unsigned int te: 1;
+	unsigned int ts: 1;
+	unsigned int dr: 1;
+} grlib_uart_status_t;
+
+typedef struct {
+	unsigned int fa: 1;
+	unsigned int : 16;
+	unsigned int si: 1;
+	unsigned int di: 1;
+	unsigned int bi: 1;
+	unsigned int db: 1;
+	unsigned int rf: 1;
+	unsigned int tf: 1;
+	unsigned int ec: 1;
+	unsigned int lb: 1;
+	unsigned int fl: 1;
+	unsigned int pe: 1;
+	unsigned int ps: 1;
+	unsigned int ti: 1;
+	unsigned int ri: 1;
+	unsigned int te: 1;
+	unsigned int re: 1;
+} grlib_uart_control_t;
+
+/** GRLIB UART registers */
+typedef struct {
+	uint32_t data;
+	uint32_t status;
+	uint32_t control;
+	uint32_t scaler;
+	uint32_t debug;
+} grlib_uart_io_t;
+
+typedef struct {
+	grlib_uart_io_t *io;
+	indev_t *indev;
+	irq_t irq;
+	parea_t parea;
+} grlib_uart_t;
+
+extern outdev_t *grlib_uart_init(uintptr_t, inr_t);
+extern void grlib_uart_input_wire(grlib_uart_t *,
+    indev_t *);
+
+#endif
+
+/** @}
+ */
Index: kernel/genarch/include/genarch/drivers/pl011/pl011.h
===================================================================
--- kernel/genarch/include/genarch/drivers/pl011/pl011.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/genarch/include/genarch/drivers/pl011/pl011.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2012 Jan Vesely
+ * 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 genarch
+ * @{
+ */
+/**
+ * @file
+ * @brief ARM PrimeCell PL011 UART driver.
+ */
+
+#ifndef KERN_PL011_H_
+#define KERN_PL011_H_
+
+#include <ddi/irq.h>
+#include <console/chardev.h>
+#include <typedefs.h>
+
+/** PrimeCell UART TRM ch. 3.3 (p. 49 in the pdf) */
+typedef struct {
+	/** UART data register */
+	ioport32_t data;
+#define PL011_UART_DATA_DATA_MASK   0xff
+#define PL011_UART_DATA_FE_FLAG   (1 <<  7)
+#define PL011_UART_DATA_PE_FLAG   (1 <<  9)
+#define PL011_UART_DATA_BE_FLAG   (1 << 10)
+#define PL011_UART_DATA_OE_FLAG   (1 << 11)
+
+	union {
+		/* Same values that are in upper bits of data register*/
+		const ioport32_t status;
+#define PL011_UART_STATUS_FE_FLAG   (1 << 0)
+#define PL011_UART_STATUS_PE_FLAG   (1 << 1)
+#define PL011_UART_STATUS_BE_FLAG   (1 << 2)
+#define PL011_UART_STATUS_OE_FLAG   (1 << 3)
+		/* Writing anything clears all errors */
+		ioport32_t error_clear;
+	};
+	uint32_t padd0_[4];
+
+	const ioport32_t flag;
+#define PL011_UART_FLAG_CTS_FLAG    (1 << 0)
+#define PL011_UART_FLAG_DSR_FLAG    (1 << 1)
+#define PL011_UART_FLAG_DCD_FLAG    (1 << 2)
+#define PL011_UART_FLAG_BUSY_FLAG   (1 << 3)
+#define PL011_UART_FLAG_RXFE_FLAG   (1 << 4)
+#define PL011_UART_FLAG_TXFF_FLAG   (1 << 5)
+#define PL011_UART_FLAG_RXFF_FLAG   (1 << 6)
+#define PL011_UART_FLAG_TXFE_FLAG   (1 << 7)
+#define PL011_UART_FLAG_RI_FLAG     (1 << 8)
+	uint32_t padd1_;
+
+	ioport32_t irda_low_power;
+#define PL011_UART_IRDA_LOW_POWER_MASK   0xff
+
+	ioport32_t int_baud_divisor;
+#define PL011_UART_INT_BAUD_DIVISOR_MASK   0xffff
+
+	ioport32_t fract_baud_divisor;
+#define PL011_UART_FRACT_BAUD_DIVISOR_MASK   0x1f
+
+	ioport32_t line_control_high;
+#define PL011_UART_CONTROLHI_BRK_FLAG    (1 << 0)
+#define PL011_UART_CONTROLHI_PEN_FLAG    (1 << 1)
+#define PL011_UART_CONTROLHI_EPS_FLAG    (1 << 2)
+#define PL011_UART_CONTROLHI_STP2_FLAG   (1 << 3)
+#define PL011_UART_CONTROLHI_FEN_FLAG    (1 << 4)
+#define PL011_UART_CONTROLHI_WLEN_MASK   0x3
+#define PL011_UART_CONTROLHI_WLEN_SHIFT    5
+#define PL011_UART_CONTROLHI_SPS_FLAG    (1 << 5)
+
+	ioport32_t control;
+#define PL011_UART_CONTROL_UARTEN_FLAG   (1 << 0)
+#define PL011_UART_CONTROL_SIREN_FLAG    (1 << 1)
+#define PL011_UART_CONTROL_SIRLP_FLAG    (1 << 2)
+#define PL011_UART_CONTROL_LBE_FLAG      (1 << 7)
+#define PL011_UART_CONTROL_TXE_FLAG      (1 << 8)
+#define PL011_UART_CONTROL_RXE_FLAG      (1 << 9)
+#define PL011_UART_CONTROL_DTR_FLAG     (1 << 10)
+#define PL011_UART_CONTROL_RTS_FLAG     (1 << 11)
+#define PL011_UART_CONTROL_OUT1_FLAG    (1 << 12)
+#define PL011_UART_CONTROL_OUT2_FLAG    (1 << 13)
+#define PL011_UART_CONTROL_RTSE_FLAG    (1 << 14)
+#define PL011_UART_CONTROL_CTSE_FLAG    (1 << 15)
+
+	ioport32_t interrupt_fifo;
+#define PL011_UART_INTERRUPTFIFO_TX_MASK   0x7
+#define PL011_UART_INTERRUPTFIFO_TX_SHIFT    0
+#define PL011_UART_INTERRUPTFIFO_RX_MASK   0x7
+#define PL011_UART_INTERRUPTFIFO_RX_SHIFT    3
+
+	/** Interrupt mask register */
+	ioport32_t interrupt_mask;
+	/** Pending interrupts before applying the mask */
+	const ioport32_t raw_interrupt_status;
+	/** Pending interrupts after applying the mask */
+	const ioport32_t masked_interrupt_status;
+	/** Write 1s to clear pending interrupts */
+	ioport32_t interrupt_clear;
+#define PL011_UART_INTERRUPT_RIM_FLAG    (1 << 0)
+#define PL011_UART_INTERRUPT_CTSM_FLAG   (1 << 1)
+#define PL011_UART_INTERRUPT_DCDM_FLAG   (1 << 2)
+#define PL011_UART_INTERRUPT_DSRM_FLAG   (1 << 3)
+#define PL011_UART_INTERRUPT_RX_FLAG     (1 << 4)
+#define PL011_UART_INTERRUPT_TX_FLAG     (1 << 5)
+#define PL011_UART_INTERRUPT_RT_FLAG     (1 << 6)
+#define PL011_UART_INTERRUPT_FE_FLAG     (1 << 7)
+#define PL011_UART_INTERRUPT_PE_FLAG     (1 << 8)
+#define PL011_UART_INTERRUPT_BE_FLAG     (1 << 9)
+#define PL011_UART_INTERRUPT_OE_FLAG    (1 << 10)
+#define PL011_UART_INTERRUPT_ALL           0x3ff
+
+	ioport32_t dma_control;
+#define PL011_UART_DMACONTROL_RXDMAEN_FLAG    (1 << 0)
+#define PL011_UART_DMACONTROL_TXDMAEN_FLAG    (1 << 1)
+#define PL011_UART_DMACONTROL_DMAONERR_FLAG   (1 << 2)
+
+	// TODO There is some reserved space here followed by
+	// peripheral identification registers.
+} pl011_uart_regs_t;
+
+typedef struct {
+	pl011_uart_regs_t *regs;
+	indev_t *indev;
+	outdev_t outdev;
+	irq_t irq;
+} pl011_uart_t;
+
+bool pl011_uart_init(pl011_uart_t *, inr_t, uintptr_t);
+void pl011_uart_input_wire(pl011_uart_t *, indev_t *);
+
+#endif
+/**
+ * @}
+ */
Index: kernel/genarch/include/genarch/drivers/s3c24xx/irqc.h
===================================================================
--- kernel/genarch/include/genarch/drivers/s3c24xx/irqc.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/genarch/include/genarch/drivers/s3c24xx/irqc.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2010 Jiri Svoboda
+ * 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 genarch
+ * @{
+ */
+/**
+ * @file
+ * @brief Samsung S3C24xx on-chip interrupt controller driver.
+ */
+
+#ifndef KERN_S3C24XX_IRQC_H_
+#define KERN_S3C24XX_IRQC_H_
+
+#include <typedefs.h>
+
+/** Physical address where S3C24XX Interrupt controller is mapped */
+#define S3C24XX_IRQC_ADDRESS	0x4a000000
+
+/** S3C24xx on-chip interrupt controller registers */
+typedef struct {
+	ioport32_t srcpnd;	/**< Source pending */
+	ioport32_t intmod;	/**< Interrupt mode */
+	ioport32_t intmsk;	/**< Interrupt mask */
+	ioport32_t priority;	/**< Priority */
+	ioport32_t intpnd;	/**< Interrupt pending */
+	ioport32_t intoffset;	/**< Interrupt offset */
+	ioport32_t subsrcpnd;	/**< Sub source pending */
+	ioport32_t intsubmsk;	/** Interrupt sub mask */
+} s3c24xx_irqc_regs_t;
+
+/** S3C24xx Interrupt source numbers.
+ *
+ * These correspond to bit numbers in srcpnd, intmod, intmsk and intpnd
+ * registers as well as to the values read from the intoffset register.
+ */
+enum s3c24xx_int_source {
+	S3C24XX_INT_ADC		= 31,
+	S3C24XX_INT_RTC		= 30,
+	S3C24XX_INT_SPI1	= 29,
+	S3C24XX_INT_UART0	= 28,
+	S3C24XX_INT_IIC		= 27,
+	S3C24XX_INT_USBH	= 26,
+	S3C24XX_INT_USBD	= 25,
+	S3C24XX_INT_NFCON	= 24,
+	S3C24XX_INT_UART1	= 23,
+	S3C24XX_INT_SPI0	= 22,
+	S3C24XX_INT_SDI		= 21,
+	S3C24XX_INT_DMA3	= 20,
+	S3C24XX_INT_DMA2	= 19,
+	S3C24XX_INT_DMA1	= 18,
+	S3C24XX_INT_DMA0	= 17,
+	S3C24XX_INT_LCD		= 16,
+	S3C24XX_INT_UART2	= 15,
+	S3C24XX_INT_TIMER4	= 14,
+	S3C24XX_INT_TIMER3	= 13,
+	S3C24XX_INT_TIMER2	= 12,
+	S3C24XX_INT_TIMER1	= 11,
+	S3C24XX_INT_TIMER0	= 10,
+	S3C24XX_INT_WDT_AC97	= 9,
+	S3C24XX_INT_TICK	= 8,
+	S3C24XX_nBATT_FLT	= 7,
+	S3C24XX_INT_CAM		= 6,
+	S3C24XX_EINT8_23	= 5,
+	S3C24XX_EINT4_7		= 4,
+	S3C24XX_EINT3		= 3,
+	S3C24XX_EINT2		= 2,
+	S3C24XX_EINT1		= 1,
+	S3C24XX_EINT0		= 0
+};
+
+/** S3C24xx Interrupt sub-source numbers.
+ *
+ * These correspond to bit numbers in the intsubmsk register.
+ */
+enum s3c24xx_int_subsource {
+	S3C24XX_SUBINT_AC97	= 14,
+	S3C24XX_SUBINT_WDT	= 13,
+	S3C24XX_SUBINT_CAM_P	= 12,
+	S3C24XX_SUBINT_CAM_C	= 11,
+	S3C24XX_SUBINT_ADC_S	= 10,
+	S3C24XX_SUBINT_TC	= 9,
+	S3C24XX_SUBINT_ERR2	= 8,
+	S3C24XX_SUBINT_TXD2	= 7,
+	S3C24XX_SUBINT_RXD2	= 6,
+	S3C24XX_SUBINT_ERR1	= 5,
+	S3C24XX_SUBINT_TXD1	= 4,
+	S3C24XX_SUBINT_RXD1	= 3,
+	S3C24XX_SUBINT_ERR0	= 2,
+	S3C24XX_SUBINT_TXD0	= 1,
+	S3C24XX_SUBINT_RXD0	= 0
+};
+
+#define S3C24XX_INT_BIT(source) (1 << (source))
+#define S3C24XX_SUBINT_BIT(subsource) (1 << (subsource))
+
+typedef struct {
+	s3c24xx_irqc_regs_t *regs;
+} s3c24xx_irqc_t;
+
+extern void s3c24xx_irqc_init(s3c24xx_irqc_t *, s3c24xx_irqc_regs_t *);
+extern unsigned s3c24xx_irqc_inum_get(s3c24xx_irqc_t *);
+extern void s3c24xx_irqc_clear(s3c24xx_irqc_t *, unsigned);
+extern void s3c24xx_irqc_src_enable(s3c24xx_irqc_t *, unsigned);
+extern void s3c24xx_irqc_src_disable(s3c24xx_irqc_t *, unsigned);
+extern void s3c24xx_irqc_subsrc_enable(s3c24xx_irqc_t *, unsigned);
+extern void s3c24xx_irqc_subsrc_disable(s3c24xx_irqc_t *, unsigned);
+
+#endif
+
+/** @}
+ */
Index: kernel/genarch/include/genarch/drivers/s3c24xx/timer.h
===================================================================
--- kernel/genarch/include/genarch/drivers/s3c24xx/timer.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/genarch/include/genarch/drivers/s3c24xx/timer.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2010 Jiri Svoboda
+ * 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 genarch
+ * @{
+ */
+/**
+ * @file
+ * @brief Samsung S3C24xx on-chip PWM timer driver.
+ */
+
+#ifndef KERN_S3C24XX_TIMER_H_
+#define KERN_S3C24XX_TIMER_H_
+
+#include <typedefs.h>
+
+/** Physical address where S3C24XX on-chip PWM timer is mapped */
+#define S3C24XX_TIMER_ADDRESS	0x51000000
+
+/** S3C24xx on-chip PWM timer registers */
+typedef struct {
+	ioport32_t tcfg0;	/**< Timer configuration register 0 */
+	ioport32_t tcfg1;	/**< Timer configuration register 1 */
+	ioport32_t tcon;	/**< Timer control register */
+
+	struct {
+		ioport32_t cntb;	/**< Count buffer register */
+		ioport32_t cmpb;	/**< Compare buffer register */
+		ioport32_t cnto;	/**< Count observation register */
+	} timer[5];
+} s3c24xx_timer_t;
+
+/** Bits in the S3C24xx PWM timer TCON register. */
+enum s3c24xx_tcon_bits {
+	TCON_T0_START		= (1 << 0),	/**< Timer 0 start */
+	TCON_T0_MUPDATE		= (1 << 1),	/**< Timer 0 manual update */
+	TCON_T0_INVERT		= (1 << 2),	/**< Timer 0 inverter on */
+	TCON_T0_AUTO_RLD	= (1 << 3),	/**< Timer 0 auto reload */
+
+	TCON_DEAD_ZONE		= (1 << 4),	/**< Dead zone enable */
+
+	TCON_T1_START		= (1 << 8),	/**< Timer 1 start */
+	TCON_T1_MUPDATE		= (1 << 9),	/**< Timer 1 manual update */
+	TCON_T1_INVERT		= (1 << 10),	/**< Timer 1 inverter on */
+	TCON_T1_AUTO_RLD	= (1 << 11),	/**< Timer 1 auto reload */
+
+	TCON_T2_START		= (1 << 12),	/**< Timer 2 start */
+	TCON_T2_MUPDATE		= (1 << 13),	/**< Timer 2 manual update */
+	TCON_T2_INVERT		= (1 << 14),	/**< Timer 2 inverter on */
+	TCON_T2_AUTO_RLD	= (1 << 15),	/**< Timer 2 auto reload */
+
+	TCON_T3_START		= (1 << 16),	/**< Timer 3 start */
+	TCON_T3_MUPDATE		= (1 << 17),	/**< Timer 3 manual update */
+	TCON_T3_INVERT		= (1 << 18),	/**< Timer 3 inverter on */
+	TCON_T3_AUTO_RLD	= (1 << 19),	/**< Timer 3 auto reload */
+
+	TCON_T4_START		= (1 << 20),	/**< Timer 4 start */
+	TCON_T4_MUPDATE		= (1 << 21),	/**< Timer 4 manual update */
+	TCON_T4_AUTO_RLD	= (1 << 22)	/**< Timer 4 auto reload */
+};
+
+#endif
+
+/** @}
+ */
Index: kernel/genarch/include/genarch/drivers/s3c24xx/uart.h
===================================================================
--- kernel/genarch/include/genarch/drivers/s3c24xx/uart.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/genarch/include/genarch/drivers/s3c24xx/uart.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2010 Jiri Svoboda
+ * 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 genarch
+ * @{
+ */
+/**
+ * @file
+ * @brief Samsung S3C24xx on-chip UART driver.
+ */
+
+#ifndef KERN_S3C24XX_UART_H_
+#define KERN_S3C24XX_UART_H_
+
+#include <ddi/ddi.h>
+#include <ddi/irq.h>
+#include <console/chardev.h>
+#include <typedefs.h>
+
+/** S3C24xx UART I/O */
+typedef struct {
+	uint32_t ulcon;
+	uint32_t ucon;
+	uint32_t ufcon;
+	uint32_t umcon;
+
+	uint32_t utrstat;
+	uint32_t uerstat;
+	uint32_t ufstat;
+	uint32_t umstat;
+
+	uint32_t utxh;
+	uint32_t urxh;
+
+	uint32_t ubrdiv;
+} s3c24xx_uart_io_t;
+
+/* Bits in UTRSTAT register */
+#define S3C24XX_UTRSTAT_TX_EMPTY	0x4
+#define S3C24XX_UTRSTAT_RDATA		0x1
+
+/* Bits in UFSTAT register */
+#define S3C24XX_UFSTAT_TX_FULL		0x4000
+#define S3C24XX_UFSTAT_RX_FULL		0x0040
+#define S3C24XX_UFSTAT_RX_COUNT		0x002f
+
+/* Bits in UCON register */
+#define UCON_RX_INT_LEVEL		0x100
+
+/* Bits in UFCON register */
+#define UFCON_TX_FIFO_TLEVEL_EMPTY	0x00
+#define UFCON_RX_FIFO_TLEVEL_1B		0x00
+#define UFCON_FIFO_ENABLE		0x01
+
+
+/** S3C24xx UART instance */
+typedef struct {
+	s3c24xx_uart_io_t *io;
+	indev_t *indev;
+	irq_t irq;
+	parea_t parea;
+} s3c24xx_uart_t;
+
+extern outdev_t *s3c24xx_uart_init(uintptr_t, inr_t inr);
+extern void s3c24xx_uart_input_wire(s3c24xx_uart_t *,
+    indev_t *);
+
+#endif
+
+/** @}
+ */
Index: rnel/genarch/include/genarch/drivers/s3c24xx_irqc/s3c24xx_irqc.h
===================================================================
--- kernel/genarch/include/genarch/drivers/s3c24xx_irqc/s3c24xx_irqc.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,137 +1,0 @@
-/*
- * Copyright (c) 2010 Jiri Svoboda
- * 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 genarch
- * @{
- */
-/**
- * @file
- * @brief Samsung S3C24xx on-chip interrupt controller driver.
- */
-
-#ifndef KERN_S3C24XX_IRQC_H_
-#define KERN_S3C24XX_IRQC_H_
-
-#include <typedefs.h>
-
-/** Physical address where S3C24XX Interrupt controller is mapped */
-#define S3C24XX_IRQC_ADDRESS	0x4a000000
-
-/** S3C24xx on-chip interrupt controller registers */
-typedef struct {
-	ioport32_t srcpnd;	/**< Source pending */
-	ioport32_t intmod;	/**< Interrupt mode */
-	ioport32_t intmsk;	/**< Interrupt mask */
-	ioport32_t priority;	/**< Priority */
-	ioport32_t intpnd;	/**< Interrupt pending */
-	ioport32_t intoffset;	/**< Interrupt offset */
-	ioport32_t subsrcpnd;	/**< Sub source pending */
-	ioport32_t intsubmsk;	/** Interrupt sub mask */
-} s3c24xx_irqc_regs_t;
-
-/** S3C24xx Interrupt source numbers.
- *
- * These correspond to bit numbers in srcpnd, intmod, intmsk and intpnd
- * registers as well as to the values read from the intoffset register.
- */
-enum s3c24xx_int_source {
-	S3C24XX_INT_ADC		= 31,
-	S3C24XX_INT_RTC		= 30,
-	S3C24XX_INT_SPI1	= 29,
-	S3C24XX_INT_UART0	= 28,
-	S3C24XX_INT_IIC		= 27,
-	S3C24XX_INT_USBH	= 26,
-	S3C24XX_INT_USBD	= 25,
-	S3C24XX_INT_NFCON	= 24,
-	S3C24XX_INT_UART1	= 23,
-	S3C24XX_INT_SPI0	= 22,
-	S3C24XX_INT_SDI		= 21,
-	S3C24XX_INT_DMA3	= 20,
-	S3C24XX_INT_DMA2	= 19,
-	S3C24XX_INT_DMA1	= 18,
-	S3C24XX_INT_DMA0	= 17,
-	S3C24XX_INT_LCD		= 16,
-	S3C24XX_INT_UART2	= 15,
-	S3C24XX_INT_TIMER4	= 14,
-	S3C24XX_INT_TIMER3	= 13,
-	S3C24XX_INT_TIMER2	= 12,
-	S3C24XX_INT_TIMER1	= 11,
-	S3C24XX_INT_TIMER0	= 10,
-	S3C24XX_INT_WDT_AC97	= 9,
-	S3C24XX_INT_TICK	= 8,
-	S3C24XX_nBATT_FLT	= 7,
-	S3C24XX_INT_CAM		= 6,
-	S3C24XX_EINT8_23	= 5,
-	S3C24XX_EINT4_7		= 4,
-	S3C24XX_EINT3		= 3,
-	S3C24XX_EINT2		= 2,
-	S3C24XX_EINT1		= 1,
-	S3C24XX_EINT0		= 0
-};
-
-/** S3C24xx Interrupt sub-source numbers.
- *
- * These correspond to bit numbers in the intsubmsk register.
- */
-enum s3c24xx_int_subsource {
-	S3C24XX_SUBINT_AC97	= 14,
-	S3C24XX_SUBINT_WDT	= 13,
-	S3C24XX_SUBINT_CAM_P	= 12,
-	S3C24XX_SUBINT_CAM_C	= 11,
-	S3C24XX_SUBINT_ADC_S	= 10,
-	S3C24XX_SUBINT_TC	= 9,
-	S3C24XX_SUBINT_ERR2	= 8,
-	S3C24XX_SUBINT_TXD2	= 7,
-	S3C24XX_SUBINT_RXD2	= 6,
-	S3C24XX_SUBINT_ERR1	= 5,
-	S3C24XX_SUBINT_TXD1	= 4,
-	S3C24XX_SUBINT_RXD1	= 3,
-	S3C24XX_SUBINT_ERR0	= 2,
-	S3C24XX_SUBINT_TXD0	= 1,
-	S3C24XX_SUBINT_RXD0	= 0
-};
-
-#define S3C24XX_INT_BIT(source) (1 << (source))
-#define S3C24XX_SUBINT_BIT(subsource) (1 << (subsource))
-
-typedef struct {
-	s3c24xx_irqc_regs_t *regs;
-} s3c24xx_irqc_t;
-
-extern void s3c24xx_irqc_init(s3c24xx_irqc_t *, s3c24xx_irqc_regs_t *);
-extern unsigned s3c24xx_irqc_inum_get(s3c24xx_irqc_t *);
-extern void s3c24xx_irqc_clear(s3c24xx_irqc_t *, unsigned);
-extern void s3c24xx_irqc_src_enable(s3c24xx_irqc_t *, unsigned);
-extern void s3c24xx_irqc_src_disable(s3c24xx_irqc_t *, unsigned);
-extern void s3c24xx_irqc_subsrc_enable(s3c24xx_irqc_t *, unsigned);
-extern void s3c24xx_irqc_subsrc_disable(s3c24xx_irqc_t *, unsigned);
-
-#endif
-
-/** @}
- */
Index: rnel/genarch/include/genarch/drivers/s3c24xx_timer/s3c24xx_timer.h
===================================================================
--- kernel/genarch/include/genarch/drivers/s3c24xx_timer/s3c24xx_timer.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,90 +1,0 @@
-/*
- * Copyright (c) 2010 Jiri Svoboda
- * 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 genarch
- * @{
- */
-/**
- * @file
- * @brief Samsung S3C24xx on-chip PWM timer driver.
- */
-
-#ifndef KERN_S3C24XX_TIMER_H_
-#define KERN_S3C24XX_TIMER_H_
-
-#include <typedefs.h>
-
-/** Physical address where S3C24XX on-chip PWM timer is mapped */
-#define S3C24XX_TIMER_ADDRESS	0x51000000
-
-/** S3C24xx on-chip PWM timer registers */
-typedef struct {
-	ioport32_t tcfg0;	/**< Timer configuration register 0 */
-	ioport32_t tcfg1;	/**< Timer configuration register 1 */
-	ioport32_t tcon;	/**< Timer control register */
-
-	struct {
-		ioport32_t cntb;	/**< Count buffer register */
-		ioport32_t cmpb;	/**< Compare buffer register */
-		ioport32_t cnto;	/**< Count observation register */
-	} timer[5];
-} s3c24xx_timer_t;
-
-/** Bits in the S3C24xx PWM timer TCON register. */
-enum s3c24xx_tcon_bits {
-	TCON_T0_START		= (1 << 0),	/**< Timer 0 start */
-	TCON_T0_MUPDATE		= (1 << 1),	/**< Timer 0 manual update */
-	TCON_T0_INVERT		= (1 << 2),	/**< Timer 0 inverter on */
-	TCON_T0_AUTO_RLD	= (1 << 3),	/**< Timer 0 auto reload */
-
-	TCON_DEAD_ZONE		= (1 << 4),	/**< Dead zone enable */
-
-	TCON_T1_START		= (1 << 8),	/**< Timer 1 start */
-	TCON_T1_MUPDATE		= (1 << 9),	/**< Timer 1 manual update */
-	TCON_T1_INVERT		= (1 << 10),	/**< Timer 1 inverter on */
-	TCON_T1_AUTO_RLD	= (1 << 11),	/**< Timer 1 auto reload */
-
-	TCON_T2_START		= (1 << 12),	/**< Timer 2 start */
-	TCON_T2_MUPDATE		= (1 << 13),	/**< Timer 2 manual update */
-	TCON_T2_INVERT		= (1 << 14),	/**< Timer 2 inverter on */
-	TCON_T2_AUTO_RLD	= (1 << 15),	/**< Timer 2 auto reload */
-
-	TCON_T3_START		= (1 << 16),	/**< Timer 3 start */
-	TCON_T3_MUPDATE		= (1 << 17),	/**< Timer 3 manual update */
-	TCON_T3_INVERT		= (1 << 18),	/**< Timer 3 inverter on */
-	TCON_T3_AUTO_RLD	= (1 << 19),	/**< Timer 3 auto reload */
-
-	TCON_T4_START		= (1 << 20),	/**< Timer 4 start */
-	TCON_T4_MUPDATE		= (1 << 21),	/**< Timer 4 manual update */
-	TCON_T4_AUTO_RLD	= (1 << 22)	/**< Timer 4 auto reload */
-};
-
-#endif
-
-/** @}
- */
Index: rnel/genarch/include/genarch/drivers/s3c24xx_uart/s3c24xx_uart.h
===================================================================
--- kernel/genarch/include/genarch/drivers/s3c24xx_uart/s3c24xx_uart.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,96 +1,0 @@
-/*
- * Copyright (c) 2010 Jiri Svoboda
- * 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 genarch
- * @{
- */
-/**
- * @file
- * @brief Samsung S3C24xx on-chip UART driver.
- */
-
-#ifndef KERN_S3C24XX_UART_H_
-#define KERN_S3C24XX_UART_H_
-
-#include <ddi/ddi.h>
-#include <ddi/irq.h>
-#include <console/chardev.h>
-#include <typedefs.h>
-
-/** S3C24xx UART I/O */
-typedef struct {
-	uint32_t ulcon;
-	uint32_t ucon;
-	uint32_t ufcon;
-	uint32_t umcon;
-
-	uint32_t utrstat;
-	uint32_t uerstat;
-	uint32_t ufstat;
-	uint32_t umstat;
-
-	uint32_t utxh;
-	uint32_t urxh;
-
-	uint32_t ubrdiv;
-} s3c24xx_uart_io_t;
-
-/* Bits in UTRSTAT register */
-#define S3C24XX_UTRSTAT_TX_EMPTY	0x4
-#define S3C24XX_UTRSTAT_RDATA		0x1
-
-/* Bits in UFSTAT register */
-#define S3C24XX_UFSTAT_TX_FULL		0x4000
-#define S3C24XX_UFSTAT_RX_FULL		0x0040
-#define S3C24XX_UFSTAT_RX_COUNT		0x002f
-
-/* Bits in UCON register */
-#define UCON_RX_INT_LEVEL		0x100
-
-/* Bits in UFCON register */
-#define UFCON_TX_FIFO_TLEVEL_EMPTY	0x00
-#define UFCON_RX_FIFO_TLEVEL_1B		0x00
-#define UFCON_FIFO_ENABLE		0x01
-
-
-/** S3C24xx UART instance */
-typedef struct {
-	s3c24xx_uart_io_t *io;
-	indev_t *indev;
-	irq_t irq;
-	parea_t parea;
-} s3c24xx_uart_t;
-
-extern outdev_t *s3c24xx_uart_init(uintptr_t, inr_t inr);
-extern void s3c24xx_uart_input_wire(s3c24xx_uart_t *,
-    indev_t *);
-
-#endif
-
-/** @}
- */
Index: kernel/genarch/src/acpi/acpi.c
===================================================================
--- kernel/genarch/src/acpi/acpi.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/genarch/src/acpi/acpi.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -41,5 +41,5 @@
 #include <mm/page.h>
 #include <mm/km.h>
-#include <print.h>
+#include <log.h>
 
 #define RSDP_SIGNATURE      "RSD PTR "
@@ -211,10 +211,10 @@
 	
 	if ((acpi_rsdt) && (!acpi_sdt_check((uint8_t *) acpi_rsdt))) {
-		printf("RSDT: bad checksum\n");
+		log(LF_ARCH, LVL_ERROR, "RSDT: bad checksum");
 		return;
 	}
 	
 	if ((acpi_xsdt) && (!acpi_sdt_check((uint8_t *) acpi_xsdt))) {
-		printf("XSDT: bad checksum\n");
+		log(LF_ARCH, LVL_ERROR, "XSDT: bad checksum");
 		return;
 	}
Index: kernel/genarch/src/acpi/madt.c
===================================================================
--- kernel/genarch/src/acpi/madt.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/genarch/src/acpi/madt.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -43,5 +43,5 @@
 #include <debug.h>
 #include <config.h>
-#include <print.h>
+#include <log.h>
 #include <mm/slab.h>
 #include <memstr.h>
@@ -236,5 +236,6 @@
 		case MADT_L_SAPIC:
 		case MADT_PLATFORM_INTR_SRC:
-			printf("MADT: Skipping %s entry (type=%" PRIu8 ")\n",
+			log(LF_ARCH, LVL_WARN,
+			    "MADT: Skipping %s entry (type=%" PRIu8 ")",
 			    entry[hdr->type], hdr->type);
 			break;
@@ -242,9 +243,11 @@
 			if ((hdr->type >= MADT_RESERVED_SKIP_BEGIN)
 			    && (hdr->type <= MADT_RESERVED_SKIP_END))
-				printf("MADT: Skipping reserved entry (type=%" PRIu8 ")\n",
+				log(LF_ARCH, LVL_NOTE,
+				    "MADT: Skipping reserved entry (type=%" PRIu8 ")",
 				    hdr->type);
 				
 			if (hdr->type >= MADT_RESERVED_OEM_BEGIN)
-				printf("MADT: Skipping OEM entry (type=%" PRIu8 ")\n",
+				log(LF_ARCH, LVL_NOTE,
+				    "MADT: Skipping OEM entry (type=%" PRIu8 ")",
 				    hdr->type);
 			
Index: rnel/genarch/src/drivers/arm926_uart/arm926_uart.c
===================================================================
--- kernel/genarch/src/drivers/arm926_uart/arm926_uart.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,140 +1,0 @@
-/*
- * Copyright (c) 2012 Jan Vesely
- * 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 genarch
- * @{
- */
-/**
- * @file
- * @brief ARM926 on-chip UART (PrimeCell UART, PL011) driver.
- */
-
-#include <genarch/drivers/arm926_uart/arm926_uart.h>
-#include <console/chardev.h>
-#include <console/console.h>
-#include <ddi/device.h>
-#include <arch/asm.h>
-#include <mm/slab.h>
-#include <mm/page.h>
-#include <mm/km.h>
-#include <sysinfo/sysinfo.h>
-#include <str.h>
-
-static void arm926_uart_sendb(arm926_uart_t *uart, uint8_t byte)
-{
-	/* Wait for space becoming available in Tx FIFO. */
-	// TODO make pio_read accept consts pointers and remove the cast
-	while ((pio_read_32((ioport32_t*)&uart->regs->flag) & ARM926_UART_FLAG_TXFF_FLAG) != 0)
-		;
-
-	pio_write_32(&uart->regs->data, byte);
-}
-
-static void arm926_uart_putchar(outdev_t *dev, wchar_t ch)
-{
-	arm926_uart_t *uart = dev->data;
-
-	if (!ascii_check(ch)) {
-		arm926_uart_sendb(uart, U_SPECIAL);
-	} else {
-		if (ch == '\n')
-			arm926_uart_sendb(uart, (uint8_t) '\r');
-		arm926_uart_sendb(uart, (uint8_t) ch);
-	}
-}
-
-static outdev_operations_t arm926_uart_ops = {
-	.write = arm926_uart_putchar,
-	.redraw = NULL,
-};
-
-static irq_ownership_t arm926_uart_claim(irq_t *irq)
-{
-	return IRQ_ACCEPT;
-}
-
-static void arm926_uart_irq_handler(irq_t *irq)
-{
-	arm926_uart_t *uart = irq->instance;
-
-	// TODO make pio_read accept const pointers and remove the cast
-	while ((pio_read_32((ioport32_t*)&uart->regs->flag) & ARM926_UART_FLAG_RXFE_FLAG) == 0) {
-		/* We ignore all error flags here */
-		const uint8_t data = pio_read_32(&uart->regs->data);
-		if (uart->indev)
-			indev_push_character(uart->indev, data);
-	}
-	/* Ack interrupts */
-	pio_write_32(&uart->regs->interrupt_clear, ARM926_UART_INTERRUPT_ALL);
-}
-
-bool arm926_uart_init(
-    arm926_uart_t *uart, inr_t interrupt, uintptr_t addr, size_t size)
-{
-	ASSERT(uart);
-	uart->regs = (void*)km_map(addr, size, PAGE_NOT_CACHEABLE);
-
-	ASSERT(uart->regs);
-
-	/* Enable hw flow control */
-	uart->regs->control = 0 |
-	    ARM926_UART_CONTROL_UARTEN_FLAG |
-	    ARM926_UART_CONTROL_RTSE_FLAG |
-	    ARM926_UART_CONTROL_CTSE_FLAG;
-
-	/* Mask all interrupts */
-	uart->regs->interrupt_mask = 0;
-
-	outdev_initialize("arm926_uart_dev", &uart->outdev, &arm926_uart_ops);
-	uart->outdev.data = uart;
-
-	/* Initialize IRQ */
-	irq_initialize(&uart->irq);
-        uart->irq.devno = device_assign_devno();
-        uart->irq.inr = interrupt;
-        uart->irq.claim = arm926_uart_claim;
-        uart->irq.handler = arm926_uart_irq_handler;
-        uart->irq.instance = uart;
-
-	return true;
-}
-
-void arm926_uart_input_wire(arm926_uart_t *uart, indev_t *indev)
-{
-	ASSERT(uart);
-	ASSERT(indev);
-
-	uart->indev = indev;
-	irq_register(&uart->irq);
-	/* Enable receive interrupt */
-	uart->regs->interrupt_mask |= ARM926_UART_INTERRUPT_RX_FLAG;
-}
-
-/** @}
- */
-
Index: kernel/genarch/src/drivers/bcm2835/mbox.c
===================================================================
--- kernel/genarch/src/drivers/bcm2835/mbox.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/genarch/src/drivers/bcm2835/mbox.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2013 Beniamino Galvani
+ * 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 genarch
+ * @{
+ */
+/**
+ * @file
+ * @brief BCM2835 mailbox communication routines
+ */
+
+#include <mm/km.h>
+#include <typedefs.h>
+#include <genarch/drivers/bcm2835/mbox.h>
+
+static void mbox_write(bcm2835_mbox_t *mbox, uint8_t chan, uint32_t value)
+{
+	while (mbox->status & MBOX_STATUS_FULL) ;
+	mbox->write = MBOX_COMPOSE(chan, value);
+}
+
+static uint32_t mbox_read(bcm2835_mbox_t *mbox, uint8_t chan)
+{
+	uint32_t msg;
+
+	do {
+		while (mbox->status & MBOX_STATUS_EMPTY) ;
+		msg = mbox->read;
+	} while (MBOX_MSG_CHAN(msg) != chan);
+
+	return MBOX_MSG_VALUE(msg);
+}
+
+bool bcm2835_prop_get_memory(uint32_t *base, uint32_t *size)
+{
+	bool ret;
+	MBOX_BUFF_ALLOC(req, mbox_getmem_buf_t);
+
+	req->buf_hdr.size = sizeof(mbox_getmem_buf_t);
+	req->buf_hdr.code = MBOX_PROP_CODE_REQ;
+	req->tag_hdr.tag_id = TAG_GET_ARM_MEMORY;
+	req->tag_hdr.buf_size = sizeof(mbox_tag_getmem_resp_t);
+	req->tag_hdr.val_len = 0;
+	req->zero = 0;
+
+	mbox_write((bcm2835_mbox_t *)BCM2835_MBOX0_ADDR,
+		   MBOX_CHAN_PROP_A2V, KA2VCA((uint32_t)req));
+	mbox_read((bcm2835_mbox_t *)BCM2835_MBOX0_ADDR,
+		  MBOX_CHAN_PROP_A2V);
+
+	if (req->buf_hdr.code == MBOX_PROP_CODE_RESP_OK) {
+		*base = req->data.base;
+		*size = req->data.size;
+		ret = true;
+	} else {
+		ret = false;
+	}
+
+	return ret;
+}
+
+bool bcm2835_fb_init(fb_properties_t *prop)
+{
+	bcm2835_mbox_t *fb_mbox;
+	bool ret = false;
+        MBOX_BUFF_ALLOC(fb_desc, bcm2835_fb_desc_t);
+
+	fb_mbox = (void *) km_map(BCM2835_MBOX0_ADDR, sizeof(bcm2835_mbox_t),
+				  PAGE_NOT_CACHEABLE);
+
+	fb_desc->width = 640;
+	fb_desc->height = 480;
+	fb_desc->virt_width = fb_desc->width;
+	fb_desc->virt_height = fb_desc->height;
+	fb_desc->pitch = 0;			/* Set by VC */
+	fb_desc->bpp = 16;
+	fb_desc->x_offset = 0;
+	fb_desc->y_offset = 0;
+	fb_desc->addr = 0;			/* Set by VC */
+	fb_desc->size = 0;			/* Set by VC */
+
+	mbox_write(fb_mbox, MBOX_CHAN_FB, KA2VCA(fb_desc));
+
+	if (mbox_read(fb_mbox, MBOX_CHAN_FB)) {
+		printf("BCM2835 framebuffer initialization failed\n");
+		goto out;
+	}
+
+	prop->addr = fb_desc->addr;
+	prop->offset = 0;
+	prop->x = fb_desc->width;
+	prop->y = fb_desc->height;
+	prop->scan = fb_desc->pitch;
+	prop->visual = VISUAL_RGB_5_6_5_LE;
+
+	printf("BCM2835 framebuffer at 0x%08x (%dx%d)\n", prop->addr,
+	       prop->x, prop->y);
+	ret = true;
+out:
+	km_unmap((uintptr_t)fb_mbox, sizeof(bcm2835_mbox_t));
+	return ret;
+}
+
+/**
+ * @}
+ */
Index: kernel/genarch/src/drivers/grlib/irqmp.c
===================================================================
--- kernel/genarch/src/drivers/grlib/irqmp.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/genarch/src/drivers/grlib/irqmp.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2013 Jakub Klama
+ * 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 genarch
+ * @{
+ */
+/**
+ * @file
+ * @brief Gaisler GRLIB interrupt controller.
+ */
+
+#include <genarch/drivers/grlib/irqmp.h>
+#include <arch/asm.h>
+#include <mm/km.h>
+
+void grlib_irqmp_init(grlib_irqmp_t *irqc, bootinfo_t *bootinfo)
+{
+	irqc->regs = (void *) km_map(bootinfo->intc_base, PAGE_SIZE,
+	    PAGE_NOT_CACHEABLE);
+	
+	/* Clear all pending interrupts */
+	pio_write_32(&irqc->regs->clear, 0xffffffff);
+	
+	/* Mask all interrupts */
+	pio_write_32((void *) irqc->regs + GRLIB_IRQMP_MASK_OFFSET, 0);
+}
+
+int grlib_irqmp_inum_get(grlib_irqmp_t *irqc)
+{
+	uint32_t pending = pio_read_32(&irqc->regs->pending);
+	
+	for (unsigned int i = 1; i < 16; i++) {
+		if (pending & (1 << i))
+			return i;
+	}
+	
+	return -1;
+}
+
+void grlib_irqmp_clear(grlib_irqmp_t *irqc, unsigned int inum)
+{
+	pio_write_32(&irqc->regs->clear, (1 << inum));
+}
+
+void grlib_irqmp_mask(grlib_irqmp_t *irqc, unsigned int src)
+{
+	uint32_t mask = pio_read_32((void *) irqc->regs +
+	    GRLIB_IRQMP_MASK_OFFSET);
+	
+	mask &= ~(1 << src);
+	pio_write_32((void *) irqc->regs + GRLIB_IRQMP_MASK_OFFSET, mask);
+}
+
+void grlib_irqmp_unmask(grlib_irqmp_t *irqc, unsigned int src)
+{
+	uint32_t mask = pio_read_32((void *) irqc->regs +
+	    GRLIB_IRQMP_MASK_OFFSET);
+	
+	mask |= (1 << src);
+	pio_write_32((void *) irqc->regs + GRLIB_IRQMP_MASK_OFFSET, mask);
+}
+
+/** @}
+ */
Index: kernel/genarch/src/drivers/grlib/uart.c
===================================================================
--- kernel/genarch/src/drivers/grlib/uart.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/genarch/src/drivers/grlib/uart.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2009 Martin Decky
+ * Copyright (c) 2010 Jiri Svoboda
+ * Copyright (c) 2013 Jakub Klama
+ * 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 genarch
+ * @{
+ */
+/**
+ * @file
+ * @brief Gaisler GRLIB UART IP-Core driver.
+ */
+
+#include <genarch/drivers/grlib/uart.h>
+#include <console/chardev.h>
+#include <console/console.h>
+#include <ddi/device.h>
+#include <arch/asm.h>
+#include <mm/slab.h>
+#include <mm/page.h>
+#include <mm/km.h>
+#include <sysinfo/sysinfo.h>
+#include <str.h>
+
+static void grlib_uart_sendb(outdev_t *dev, uint8_t byte)
+{
+	grlib_uart_status_t *status;
+	grlib_uart_t *uart = (grlib_uart_t *) dev->data;
+	
+	/* Wait for space becoming available in Tx FIFO. */
+	do {
+		uint32_t reg = pio_read_32(&uart->io->status);
+		status = (grlib_uart_status_t *) &reg;
+	} while (status->tf != 0);
+	
+	pio_write_32(&uart->io->data, byte);
+}
+
+static void grlib_uart_putchar(outdev_t *dev, wchar_t ch)
+{
+	grlib_uart_t *uart = (grlib_uart_t *) dev->data;
+	
+	if ((!uart->parea.mapped) || (console_override)) {
+		if (!ascii_check(ch)) {
+			grlib_uart_sendb(dev, U_SPECIAL);
+		} else {
+			if (ch == '\n')
+				grlib_uart_sendb(dev, (uint8_t) '\r');
+			
+			grlib_uart_sendb(dev, (uint8_t) ch);
+		}
+	}
+}
+
+static irq_ownership_t grlib_uart_claim(irq_t *irq)
+{
+	return IRQ_ACCEPT;
+}
+
+static void grlib_uart_irq_handler(irq_t *irq)
+{
+	grlib_uart_t *uart = irq->instance;
+	
+	uint32_t reg = pio_read_32(&uart->io->status);
+	grlib_uart_status_t *status = (grlib_uart_status_t *) &reg;
+	
+	while (status->dr != 0) {
+		uint32_t data = pio_read_32(&uart->io->data);
+		reg = pio_read_32(&uart->io->status);
+		status = (grlib_uart_status_t *) &reg;
+		indev_push_character(uart->indev, data & 0xff);
+	}
+}
+
+static outdev_operations_t grlib_uart_ops = {
+	.write = grlib_uart_putchar,
+	.redraw = NULL
+};
+
+outdev_t *grlib_uart_init(uintptr_t paddr, inr_t inr)
+{
+	outdev_t *uart_dev = malloc(sizeof(outdev_t), FRAME_ATOMIC);
+	if (!uart_dev)
+		return NULL;
+	
+	grlib_uart_t *uart = malloc(sizeof(grlib_uart_t), FRAME_ATOMIC);
+	if (!uart) {
+		free(uart_dev);
+		return NULL;
+	}
+	
+	outdev_initialize("grlib_uart_dev", uart_dev, &grlib_uart_ops);
+	uart_dev->data = uart;
+	
+	uart->io = (grlib_uart_io_t *) km_map(paddr, PAGE_SIZE,
+	    PAGE_WRITE | PAGE_NOT_CACHEABLE);
+	uart->indev = NULL;
+	
+	/* Initialize IRQ structure. */
+	irq_initialize(&uart->irq);
+	uart->irq.devno = device_assign_devno();
+	uart->irq.inr = inr;
+	uart->irq.claim = grlib_uart_claim;
+	uart->irq.handler = grlib_uart_irq_handler;
+	uart->irq.instance = uart;
+	
+	/* Enable FIFO, Tx trigger level: empty, Rx trigger level: 1 byte. */
+	grlib_uart_control_t control = {
+		.fa = 1,
+		.rf = 1,
+		.tf = 1,
+		.ri = 1,
+		.te = 1,
+		.re = 1
+	};
+	
+	uint32_t *reg = (uint32_t *) &control;
+	pio_write_32(&uart->io->control, *reg);
+	
+	link_initialize(&uart->parea.link);
+	uart->parea.pbase = paddr;
+	uart->parea.frames = 1;
+	uart->parea.unpriv = false;
+	uart->parea.mapped = false;
+	ddi_parea_register(&uart->parea);
+	
+	return uart_dev;
+}
+
+void grlib_uart_input_wire(grlib_uart_t *uart, indev_t *indev)
+{
+	ASSERT(uart);
+	ASSERT(indev);
+	
+	uart->indev = indev;
+	irq_register(&uart->irq);
+}
+
+/** @}
+ */
Index: kernel/genarch/src/drivers/pl011/pl011.c
===================================================================
--- kernel/genarch/src/drivers/pl011/pl011.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/genarch/src/drivers/pl011/pl011.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2012 Jan Vesely
+ * 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 genarch
+ * @{
+ */
+/**
+ * @file
+ * @brief ARM PrimeCell PL011 UART driver.
+ */
+
+#include <genarch/drivers/pl011/pl011.h>
+#include <console/chardev.h>
+#include <console/console.h>
+#include <ddi/device.h>
+#include <arch/asm.h>
+#include <mm/slab.h>
+#include <mm/page.h>
+#include <mm/km.h>
+#include <sysinfo/sysinfo.h>
+#include <str.h>
+
+static void pl011_uart_sendb(pl011_uart_t *uart, uint8_t byte)
+{
+	/* Wait for space becoming available in Tx FIFO. */
+	// TODO make pio_read accept consts pointers and remove the cast
+	while ((pio_read_32((ioport32_t*)&uart->regs->flag) & PL011_UART_FLAG_TXFF_FLAG) != 0)
+		;
+
+	pio_write_32(&uart->regs->data, byte);
+}
+
+static void pl011_uart_putchar(outdev_t *dev, wchar_t ch)
+{
+	pl011_uart_t *uart = dev->data;
+
+	if (!ascii_check(ch)) {
+		pl011_uart_sendb(uart, U_SPECIAL);
+	} else {
+		if (ch == '\n')
+			pl011_uart_sendb(uart, (uint8_t) '\r');
+		pl011_uart_sendb(uart, (uint8_t) ch);
+	}
+}
+
+static outdev_operations_t pl011_uart_ops = {
+	.write = pl011_uart_putchar,
+	.redraw = NULL,
+};
+
+static irq_ownership_t pl011_uart_claim(irq_t *irq)
+{
+	return IRQ_ACCEPT;
+}
+
+static void pl011_uart_irq_handler(irq_t *irq)
+{
+	pl011_uart_t *uart = irq->instance;
+
+	// TODO make pio_read accept const pointers and remove the cast
+	while ((pio_read_32((ioport32_t*)&uart->regs->flag) & PL011_UART_FLAG_RXFE_FLAG) == 0) {
+		/* We ignore all error flags here */
+		const uint8_t data = pio_read_32(&uart->regs->data);
+		if (uart->indev)
+			indev_push_character(uart->indev, data);
+	}
+	/* Ack interrupts */
+	pio_write_32(&uart->regs->interrupt_clear, PL011_UART_INTERRUPT_ALL);
+}
+
+bool pl011_uart_init(pl011_uart_t *uart, inr_t interrupt, uintptr_t addr)
+{
+	ASSERT(uart);
+	uart->regs = (void*)km_map(addr, sizeof(pl011_uart_regs_t),
+				   PAGE_NOT_CACHEABLE);
+	ASSERT(uart->regs);
+
+	/* Disable UART */
+	uart->regs->control &= ~ PL011_UART_CONTROL_UARTEN_FLAG;
+
+	/* Enable hw flow control */
+	uart->regs->control |=
+		PL011_UART_CONTROL_RTSE_FLAG |
+		PL011_UART_CONTROL_CTSE_FLAG;
+
+	/* Mask all interrupts */
+	uart->regs->interrupt_mask = 0;
+	/* Clear interrupts */
+	uart->regs->interrupt_clear = PL011_UART_INTERRUPT_ALL;
+	/* Enable UART, TX and RX */
+	uart->regs->control |=
+		PL011_UART_CONTROL_UARTEN_FLAG |
+		PL011_UART_CONTROL_TXE_FLAG |
+		PL011_UART_CONTROL_RXE_FLAG;
+
+	outdev_initialize("pl011_uart_dev", &uart->outdev, &pl011_uart_ops);
+	uart->outdev.data = uart;
+
+	/* Initialize IRQ */
+	irq_initialize(&uart->irq);
+	uart->irq.devno = device_assign_devno();
+	uart->irq.inr = interrupt;
+	uart->irq.claim = pl011_uart_claim;
+	uart->irq.handler = pl011_uart_irq_handler;
+	uart->irq.instance = uart;
+
+	return true;
+}
+
+void pl011_uart_input_wire(pl011_uart_t *uart, indev_t *indev)
+{
+	ASSERT(uart);
+	ASSERT(indev);
+
+	uart->indev = indev;
+	irq_register(&uart->irq);
+	/* Enable receive interrupts */
+	uart->regs->interrupt_mask |=
+		PL011_UART_INTERRUPT_RX_FLAG |
+		PL011_UART_INTERRUPT_RT_FLAG;
+}
+
+/** @}
+ */
+
Index: kernel/genarch/src/drivers/s3c24xx/irqc.c
===================================================================
--- kernel/genarch/src/drivers/s3c24xx/irqc.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/genarch/src/drivers/s3c24xx/irqc.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2010 Jiri Svoboda
+ * 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 genarch
+ * @{
+ */
+/**
+ * @file
+ * @brief Samsung S3C24xx on-chip interrupt controller.
+ *
+ * This IRQC is present on the Samsung S3C24xx CPU (on the gta02 platform).
+ */
+
+#include <genarch/drivers/s3c24xx/irqc.h>
+#include <arch/asm.h>
+
+/** Correspondence between interrupt sources and sub-sources. */
+static unsigned s3c24xx_subsrc_src[][2] = {
+	{ S3C24XX_SUBINT_CAM_P, S3C24XX_INT_CAM },
+	{ S3C24XX_SUBINT_CAM_C, S3C24XX_INT_CAM },
+	{ S3C24XX_SUBINT_ADC_S, S3C24XX_INT_ADC },
+	{ S3C24XX_SUBINT_TC, S3C24XX_INT_ADC },
+	{ S3C24XX_SUBINT_ERR2, S3C24XX_INT_UART2 },
+	{ S3C24XX_SUBINT_TXD2, S3C24XX_INT_UART2 },
+	{ S3C24XX_SUBINT_RXD2, S3C24XX_INT_UART2 },
+	{ S3C24XX_SUBINT_ERR1, S3C24XX_INT_UART1 },
+	{ S3C24XX_SUBINT_TXD1, S3C24XX_INT_UART1 },
+	{ S3C24XX_SUBINT_RXD1, S3C24XX_INT_UART1 },
+	{ S3C24XX_SUBINT_ERR0, S3C24XX_INT_UART0 },
+	{ S3C24XX_SUBINT_TXD0, S3C24XX_INT_UART0 },
+	{ S3C24XX_SUBINT_RXD0, S3C24XX_INT_UART0 }
+};
+
+/** Initialize S3C24xx interrupt controller.
+ *
+ * @param irqc	Instance structure
+ * @param regs	Register I/O structure
+ */
+void s3c24xx_irqc_init(s3c24xx_irqc_t *irqc, s3c24xx_irqc_regs_t *regs)
+{
+	irqc->regs = regs;
+
+	/* Make all interrupt sources use IRQ mode (not FIQ). */
+	pio_write_32(&regs->intmod, 0x00000000);
+
+	/* Disable all interrupt sources. */
+	pio_write_32(&regs->intmsk, 0xffffffff);
+
+	/* Disable interrupts from all sub-sources. */
+	pio_write_32(&regs->intsubmsk, 0xffffffff);
+}
+
+/** Obtain number of pending interrupt. */
+unsigned s3c24xx_irqc_inum_get(s3c24xx_irqc_t *irqc)
+{
+	return pio_read_32(&irqc->regs->intoffset);
+}
+
+/** Clear pending interrupt condition including sub-sources.
+ *
+ * Clear source and interrupt pending condition and also automatically clear
+ * any sub-source pending condition pertaining to the source.
+ */
+void s3c24xx_irqc_clear(s3c24xx_irqc_t *irqc, unsigned inum)
+{
+	unsigned src, subsrc;
+	unsigned entries, i;
+
+	entries = sizeof(s3c24xx_subsrc_src) / sizeof(s3c24xx_subsrc_src[0]);
+
+	for (i = 0; i < entries; i++) {
+		subsrc = s3c24xx_subsrc_src[i][0];
+		src = s3c24xx_subsrc_src[i][1];
+
+		if (src == inum) {
+			pio_write_32(&irqc->regs->subsrcpnd,
+			    S3C24XX_SUBINT_BIT(subsrc));
+		}
+	}
+
+	pio_write_32(&irqc->regs->srcpnd, S3C24XX_INT_BIT(inum));
+	pio_write_32(&irqc->regs->intpnd, S3C24XX_INT_BIT(inum));
+}
+
+/** Enable interrupts from the specified source. */
+void s3c24xx_irqc_src_enable(s3c24xx_irqc_t *irqc, unsigned src)
+{
+	pio_write_32(&irqc->regs->intmsk, pio_read_32(&irqc->regs->intmsk) &
+	    ~S3C24XX_INT_BIT(src));
+}
+
+/** Disable interrupts from the specified source. */
+void s3c24xx_irqc_src_disable(s3c24xx_irqc_t *irqc, unsigned src)
+{
+	pio_write_32(&irqc->regs->intmsk, pio_read_32(&irqc->regs->intmsk) |
+	    S3C24XX_INT_BIT(src));
+}
+
+/** Enable interrupts from the specified sub-source. */
+void s3c24xx_irqc_subsrc_enable(s3c24xx_irqc_t *irqc, unsigned subsrc)
+{
+	pio_write_32(&irqc->regs->intsubmsk,
+	    pio_read_32(&irqc->regs->intsubmsk) &
+	    ~S3C24XX_SUBINT_BIT(subsrc));
+}
+
+/** Disable interrupts from the specified sub-source. */
+void s3c24xx_irqc_subsrc_disable(s3c24xx_irqc_t *irqc, unsigned subsrc)
+{
+	pio_write_32(&irqc->regs->intsubmsk,
+	    pio_read_32(&irqc->regs->intsubmsk) |
+	    S3C24XX_SUBINT_BIT(subsrc));
+}
+
+/** @}
+ */
Index: kernel/genarch/src/drivers/s3c24xx/uart.c
===================================================================
--- kernel/genarch/src/drivers/s3c24xx/uart.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/genarch/src/drivers/s3c24xx/uart.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2009 Martin Decky
+ * Copyright (c) 2010 Jiri Svoboda
+ * 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 genarch
+ * @{
+ */
+/**
+ * @file
+ * @brief Samsung S3C24xx on-chip UART driver.
+ *
+ * This UART is present on the Samsung S3C24xx CPU (on the gta02 platform).
+ */
+
+#include <genarch/drivers/s3c24xx/uart.h>
+#include <console/chardev.h>
+#include <console/console.h>
+#include <ddi/device.h>
+#include <arch/asm.h>
+#include <mm/slab.h>
+#include <mm/page.h>
+#include <mm/km.h>
+#include <sysinfo/sysinfo.h>
+#include <str.h>
+
+static void s3c24xx_uart_sendb(outdev_t *dev, uint8_t byte)
+{
+	s3c24xx_uart_t *uart =
+	    (s3c24xx_uart_t *) dev->data;
+
+	/* Wait for space becoming available in Tx FIFO. */
+	while ((pio_read_32(&uart->io->ufstat) & S3C24XX_UFSTAT_TX_FULL) != 0)
+		;
+
+	pio_write_32(&uart->io->utxh, byte);
+}
+
+static void s3c24xx_uart_putchar(outdev_t *dev, wchar_t ch)
+{
+	s3c24xx_uart_t *uart =
+	    (s3c24xx_uart_t *) dev->data;
+	
+	if ((!uart->parea.mapped) || (console_override)) {
+		if (!ascii_check(ch)) {
+			s3c24xx_uart_sendb(dev, U_SPECIAL);
+		} else {
+			if (ch == '\n')
+				s3c24xx_uart_sendb(dev, (uint8_t) '\r');
+			s3c24xx_uart_sendb(dev, (uint8_t) ch);
+		}
+	}
+}
+
+static irq_ownership_t s3c24xx_uart_claim(irq_t *irq)
+{
+	return IRQ_ACCEPT;
+}
+
+static void s3c24xx_uart_irq_handler(irq_t *irq)
+{
+	s3c24xx_uart_t *uart = irq->instance;
+
+	while ((pio_read_32(&uart->io->ufstat) & S3C24XX_UFSTAT_RX_COUNT) != 0) {
+		uint32_t data = pio_read_32(&uart->io->urxh);
+		pio_read_32(&uart->io->uerstat);
+		indev_push_character(uart->indev, data & 0xff);
+	}
+}
+
+static outdev_operations_t s3c24xx_uart_ops = {
+	.write = s3c24xx_uart_putchar,
+	.redraw = NULL
+};
+
+outdev_t *s3c24xx_uart_init(uintptr_t paddr, inr_t inr)
+{
+	outdev_t *uart_dev = malloc(sizeof(outdev_t), FRAME_ATOMIC);
+	if (!uart_dev)
+		return NULL;
+
+	s3c24xx_uart_t *uart =
+	    malloc(sizeof(s3c24xx_uart_t), FRAME_ATOMIC);
+	if (!uart) {
+		free(uart_dev);
+		return NULL;
+	}
+
+	outdev_initialize("s3c24xx_uart_dev", uart_dev, &s3c24xx_uart_ops);
+	uart_dev->data = uart;
+
+	uart->io = (s3c24xx_uart_io_t *) km_map(paddr, PAGE_SIZE,
+	    PAGE_WRITE | PAGE_NOT_CACHEABLE);
+	uart->indev = NULL;
+
+	/* Initialize IRQ structure. */
+	irq_initialize(&uart->irq);
+	uart->irq.devno = device_assign_devno();
+	uart->irq.inr = inr;
+	uart->irq.claim = s3c24xx_uart_claim;
+	uart->irq.handler = s3c24xx_uart_irq_handler;
+	uart->irq.instance = uart;
+
+	/* Enable FIFO, Tx trigger level: empty, Rx trigger level: 1 byte. */
+	pio_write_32(&uart->io->ufcon, UFCON_FIFO_ENABLE |
+	    UFCON_TX_FIFO_TLEVEL_EMPTY | UFCON_RX_FIFO_TLEVEL_1B);
+
+	/* Set RX interrupt to pulse mode */
+	pio_write_32(&uart->io->ucon,
+	    pio_read_32(&uart->io->ucon) & ~UCON_RX_INT_LEVEL);
+	
+	link_initialize(&uart->parea.link);
+	uart->parea.pbase = paddr;
+	uart->parea.frames = 1;
+	uart->parea.unpriv = false;
+	uart->parea.mapped = false;
+	ddi_parea_register(&uart->parea);
+	
+	if (!fb_exported) {
+		/*
+		 * This is the necessary evil until
+		 * the userspace driver is entirely
+		 * self-sufficient.
+		 */
+		sysinfo_set_item_val("fb", NULL, true);
+		sysinfo_set_item_val("fb.kind", NULL, 3);
+		sysinfo_set_item_val("fb.address.physical", NULL, paddr);
+
+		fb_exported = true;
+	}
+
+	return uart_dev;
+}
+
+void s3c24xx_uart_input_wire(s3c24xx_uart_t *uart, indev_t *indev)
+{
+	ASSERT(uart);
+	ASSERT(indev);
+
+	uart->indev = indev;
+	irq_register(&uart->irq);
+}
+
+/** @}
+ */
Index: rnel/genarch/src/drivers/s3c24xx_irqc/s3c24xx_irqc.c
===================================================================
--- kernel/genarch/src/drivers/s3c24xx_irqc/s3c24xx_irqc.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,141 +1,0 @@
-/*
- * Copyright (c) 2010 Jiri Svoboda
- * 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 genarch
- * @{
- */
-/**
- * @file
- * @brief Samsung S3C24xx on-chip interrupt controller.
- *
- * This IRQC is present on the Samsung S3C24xx CPU (on the gta02 platform).
- */
-
-#include <genarch/drivers/s3c24xx_irqc/s3c24xx_irqc.h>
-#include <arch/asm.h>
-
-/** Correspondence between interrupt sources and sub-sources. */
-static unsigned s3c24xx_subsrc_src[][2] = {
-	{ S3C24XX_SUBINT_CAM_P, S3C24XX_INT_CAM },
-	{ S3C24XX_SUBINT_CAM_C, S3C24XX_INT_CAM },
-	{ S3C24XX_SUBINT_ADC_S, S3C24XX_INT_ADC },
-	{ S3C24XX_SUBINT_TC, S3C24XX_INT_ADC },
-	{ S3C24XX_SUBINT_ERR2, S3C24XX_INT_UART2 },
-	{ S3C24XX_SUBINT_TXD2, S3C24XX_INT_UART2 },
-	{ S3C24XX_SUBINT_RXD2, S3C24XX_INT_UART2 },
-	{ S3C24XX_SUBINT_ERR1, S3C24XX_INT_UART1 },
-	{ S3C24XX_SUBINT_TXD1, S3C24XX_INT_UART1 },
-	{ S3C24XX_SUBINT_RXD1, S3C24XX_INT_UART1 },
-	{ S3C24XX_SUBINT_ERR0, S3C24XX_INT_UART0 },
-	{ S3C24XX_SUBINT_TXD0, S3C24XX_INT_UART0 },
-	{ S3C24XX_SUBINT_RXD0, S3C24XX_INT_UART0 }
-};
-
-/** Initialize S3C24xx interrupt controller.
- *
- * @param irqc	Instance structure
- * @param regs	Register I/O structure
- */
-void s3c24xx_irqc_init(s3c24xx_irqc_t *irqc, s3c24xx_irqc_regs_t *regs)
-{
-	irqc->regs = regs;
-
-	/* Make all interrupt sources use IRQ mode (not FIQ). */
-	pio_write_32(&regs->intmod, 0x00000000);
-
-	/* Disable all interrupt sources. */
-	pio_write_32(&regs->intmsk, 0xffffffff);
-
-	/* Disable interrupts from all sub-sources. */
-	pio_write_32(&regs->intsubmsk, 0xffffffff);
-}
-
-/** Obtain number of pending interrupt. */
-unsigned s3c24xx_irqc_inum_get(s3c24xx_irqc_t *irqc)
-{
-	return pio_read_32(&irqc->regs->intoffset);
-}
-
-/** Clear pending interrupt condition including sub-sources.
- *
- * Clear source and interrupt pending condition and also automatically clear
- * any sub-source pending condition pertaining to the source.
- */
-void s3c24xx_irqc_clear(s3c24xx_irqc_t *irqc, unsigned inum)
-{
-	unsigned src, subsrc;
-	unsigned entries, i;
-
-	entries = sizeof(s3c24xx_subsrc_src) / sizeof(s3c24xx_subsrc_src[0]);
-
-	for (i = 0; i < entries; i++) {
-		subsrc = s3c24xx_subsrc_src[i][0];
-		src = s3c24xx_subsrc_src[i][1];
-
-		if (src == inum) {
-			pio_write_32(&irqc->regs->subsrcpnd,
-			    S3C24XX_SUBINT_BIT(subsrc));
-		}
-	}
-
-	pio_write_32(&irqc->regs->srcpnd, S3C24XX_INT_BIT(inum));
-	pio_write_32(&irqc->regs->intpnd, S3C24XX_INT_BIT(inum));
-}
-
-/** Enable interrupts from the specified source. */
-void s3c24xx_irqc_src_enable(s3c24xx_irqc_t *irqc, unsigned src)
-{
-	pio_write_32(&irqc->regs->intmsk, pio_read_32(&irqc->regs->intmsk) &
-	    ~S3C24XX_INT_BIT(src));
-}
-
-/** Disable interrupts from the specified source. */
-void s3c24xx_irqc_src_disable(s3c24xx_irqc_t *irqc, unsigned src)
-{
-	pio_write_32(&irqc->regs->intmsk, pio_read_32(&irqc->regs->intmsk) |
-	    S3C24XX_INT_BIT(src));
-}
-
-/** Enable interrupts from the specified sub-source. */
-void s3c24xx_irqc_subsrc_enable(s3c24xx_irqc_t *irqc, unsigned subsrc)
-{
-	pio_write_32(&irqc->regs->intsubmsk,
-	    pio_read_32(&irqc->regs->intsubmsk) &
-	    ~S3C24XX_SUBINT_BIT(subsrc));
-}
-
-/** Disable interrupts from the specified sub-source. */
-void s3c24xx_irqc_subsrc_disable(s3c24xx_irqc_t *irqc, unsigned subsrc)
-{
-	pio_write_32(&irqc->regs->intsubmsk,
-	    pio_read_32(&irqc->regs->intsubmsk) |
-	    S3C24XX_SUBINT_BIT(subsrc));
-}
-
-/** @}
- */
Index: rnel/genarch/src/drivers/s3c24xx_uart/s3c24xx_uart.c
===================================================================
--- kernel/genarch/src/drivers/s3c24xx_uart/s3c24xx_uart.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,169 +1,0 @@
-/*
- * Copyright (c) 2009 Martin Decky
- * Copyright (c) 2010 Jiri Svoboda
- * 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 genarch
- * @{
- */
-/**
- * @file
- * @brief Samsung S3C24xx on-chip UART driver.
- *
- * This UART is present on the Samsung S3C24xx CPU (on the gta02 platform).
- */
-
-#include <genarch/drivers/s3c24xx_uart/s3c24xx_uart.h>
-#include <console/chardev.h>
-#include <console/console.h>
-#include <ddi/device.h>
-#include <arch/asm.h>
-#include <mm/slab.h>
-#include <mm/page.h>
-#include <mm/km.h>
-#include <sysinfo/sysinfo.h>
-#include <str.h>
-
-static void s3c24xx_uart_sendb(outdev_t *dev, uint8_t byte)
-{
-	s3c24xx_uart_t *uart =
-	    (s3c24xx_uart_t *) dev->data;
-
-	/* Wait for space becoming available in Tx FIFO. */
-	while ((pio_read_32(&uart->io->ufstat) & S3C24XX_UFSTAT_TX_FULL) != 0)
-		;
-
-	pio_write_32(&uart->io->utxh, byte);
-}
-
-static void s3c24xx_uart_putchar(outdev_t *dev, wchar_t ch)
-{
-	s3c24xx_uart_t *uart =
-	    (s3c24xx_uart_t *) dev->data;
-	
-	if ((!uart->parea.mapped) || (console_override)) {
-		if (!ascii_check(ch)) {
-			s3c24xx_uart_sendb(dev, U_SPECIAL);
-		} else {
-			if (ch == '\n')
-				s3c24xx_uart_sendb(dev, (uint8_t) '\r');
-			s3c24xx_uart_sendb(dev, (uint8_t) ch);
-		}
-	}
-}
-
-static irq_ownership_t s3c24xx_uart_claim(irq_t *irq)
-{
-	return IRQ_ACCEPT;
-}
-
-static void s3c24xx_uart_irq_handler(irq_t *irq)
-{
-	s3c24xx_uart_t *uart = irq->instance;
-
-	while ((pio_read_32(&uart->io->ufstat) & S3C24XX_UFSTAT_RX_COUNT) != 0) {
-		uint32_t data = pio_read_32(&uart->io->urxh);
-		pio_read_32(&uart->io->uerstat);
-		indev_push_character(uart->indev, data & 0xff);
-	}
-}
-
-static outdev_operations_t s3c24xx_uart_ops = {
-	.write = s3c24xx_uart_putchar,
-	.redraw = NULL
-};
-
-outdev_t *s3c24xx_uart_init(uintptr_t paddr, inr_t inr)
-{
-	outdev_t *uart_dev = malloc(sizeof(outdev_t), FRAME_ATOMIC);
-	if (!uart_dev)
-		return NULL;
-
-	s3c24xx_uart_t *uart =
-	    malloc(sizeof(s3c24xx_uart_t), FRAME_ATOMIC);
-	if (!uart) {
-		free(uart_dev);
-		return NULL;
-	}
-
-	outdev_initialize("s3c24xx_uart_dev", uart_dev, &s3c24xx_uart_ops);
-	uart_dev->data = uart;
-
-	uart->io = (s3c24xx_uart_io_t *) km_map(paddr, PAGE_SIZE,
-	    PAGE_WRITE | PAGE_NOT_CACHEABLE);
-	uart->indev = NULL;
-
-	/* Initialize IRQ structure. */
-	irq_initialize(&uart->irq);
-	uart->irq.devno = device_assign_devno();
-	uart->irq.inr = inr;
-	uart->irq.claim = s3c24xx_uart_claim;
-	uart->irq.handler = s3c24xx_uart_irq_handler;
-	uart->irq.instance = uart;
-
-	/* Enable FIFO, Tx trigger level: empty, Rx trigger level: 1 byte. */
-	pio_write_32(&uart->io->ufcon, UFCON_FIFO_ENABLE |
-	    UFCON_TX_FIFO_TLEVEL_EMPTY | UFCON_RX_FIFO_TLEVEL_1B);
-
-	/* Set RX interrupt to pulse mode */
-	pio_write_32(&uart->io->ucon,
-	    pio_read_32(&uart->io->ucon) & ~UCON_RX_INT_LEVEL);
-	
-	link_initialize(&uart->parea.link);
-	uart->parea.pbase = paddr;
-	uart->parea.frames = 1;
-	uart->parea.unpriv = false;
-	uart->parea.mapped = false;
-	ddi_parea_register(&uart->parea);
-	
-	if (!fb_exported) {
-		/*
-		 * This is the necessary evil until
-		 * the userspace driver is entirely
-		 * self-sufficient.
-		 */
-		sysinfo_set_item_val("fb", NULL, true);
-		sysinfo_set_item_val("fb.kind", NULL, 3);
-		sysinfo_set_item_val("fb.address.physical", NULL, paddr);
-
-		fb_exported = true;
-	}
-
-	return uart_dev;
-}
-
-void s3c24xx_uart_input_wire(s3c24xx_uart_t *uart, indev_t *indev)
-{
-	ASSERT(uart);
-	ASSERT(indev);
-
-	uart->indev = indev;
-	irq_register(&uart->irq);
-}
-
-/** @}
- */
Index: kernel/genarch/src/drivers/via-cuda/cuda.c
===================================================================
--- kernel/genarch/src/drivers/via-cuda/cuda.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/genarch/src/drivers/via-cuda/cuda.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -118,5 +118,5 @@
 }
 
-#include <print.h>
+#include <log.h>
 void cuda_wire(cuda_instance_t *instance, indev_t *kbrdin)
 {
@@ -197,5 +197,5 @@
 
 	if ((b & TREQ) != 0) {
-		printf("cuda_irq_listen: no TREQ?!\n");
+		log(LF_OTHER, LVL_ERROR, "cuda_irq_listen: no TREQ?!");
 		return;
 	}
Index: kernel/generic/include/console/console.h
===================================================================
--- kernel/generic/include/console/console.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/generic/include/console/console.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -39,4 +39,5 @@
 #include <print.h>
 #include <console/chardev.h>
+#include <synch/spinlock.h>
 
 #define PAGING(counter, increment, before, after) \
@@ -62,10 +63,13 @@
 extern void console_init(void);
 
-extern void klog_init(void);
-extern void klog_update(void *);
+extern void kio_init(void);
+extern void kio_update(void *);
+extern void kio_flush(void);
+extern void kio_push_char(const wchar_t);
+SPINLOCK_EXTERN(kio_lock);
 
 extern wchar_t getc(indev_t *indev);
 extern size_t gets(indev_t *indev, char *buf, size_t buflen);
-extern sysarg_t sys_klog(int cmd, const void *buf, size_t size);
+extern sysarg_t sys_kio(int cmd, const void *buf, size_t size);
 
 extern void grab_console(void);
Index: kernel/generic/include/debug.h
===================================================================
--- kernel/generic/include/debug.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/generic/include/debug.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -107,5 +107,6 @@
 #define LOG(format, ...) \
 	do { \
-		printf("%s() from %s at %s:%u: " format "\n", __func__, \
+		log(LF_OTHER, LVL_DEBUG, \
+		    "%s() from %s at %s:%u: " format,__func__, \
 		    symtab_fmt_name_lookup(CALLER), __FILE__, __LINE__, \
 		    ##__VA_ARGS__); \
Index: kernel/generic/include/log.h
===================================================================
--- kernel/generic/include/log.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/generic/include/log.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2013 Martin Sucha
+ * 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 genericlog
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_LOG_H_
+#define KERN_LOG_H_
+
+#include <typedefs.h>
+#include <stdarg.h>
+#include <printf/verify.h>
+#include <abi/log.h>
+#include <abi/klog.h>
+
+extern void log_init(void);
+extern void log_begin(log_facility_t, log_level_t);
+extern void log_end(void);
+extern int log_vprintf(const char *, va_list);
+extern int log_printf(const char *, ...)
+    PRINTF_ATTRIBUTE(1, 2);
+extern int log(log_facility_t, log_level_t, const char *, ...)
+    PRINTF_ATTRIBUTE(3, 4);
+
+extern sysarg_t sys_klog(sysarg_t, void *buf, size_t size,
+    sysarg_t level);
+
+#endif /* KERN_LOG_H_ */
+
+/** @}
+ */
Index: kernel/generic/include/synch/spinlock.h
===================================================================
--- kernel/generic/include/synch/spinlock.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/generic/include/synch/spinlock.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -137,5 +137,5 @@
 #ifdef CONFIG_DEBUG_SPINLOCK
 
-#include <print.h>
+#include <log.h>
 
 #define DEADLOCK_THRESHOLD  100000000
@@ -146,5 +146,6 @@
 	if ((pname)++ > (value)) { \
 		(pname) = 0; \
-		printf("Deadlock probe %s: exceeded threshold %u\n" \
+		log(LF_OTHER, LVL_WARN, \
+		    "Deadlock probe %s: exceeded threshold %u\n" \
 		    "cpu%u: function=%s, line=%u\n", \
 		    #pname, (value), CPU->id, __func__, __LINE__); \
Index: kernel/generic/src/console/cmd.c
===================================================================
--- kernel/generic/src/console/cmd.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/generic/src/console/cmd.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -45,4 +45,5 @@
 #include <console/kconsole.h>
 #include <print.h>
+#include <log.h>
 #include <panic.h>
 #include <typedefs.h>
@@ -639,5 +640,6 @@
 	for (i = 0; basic_commands[i]; i++) {
 		if (!cmd_register(basic_commands[i])) {
-			printf("Cannot register command %s\n",
+			log(LF_OTHER, LVL_ERROR,
+			    "Cannot register command %s",
 			    basic_commands[i]->name);
 		}
@@ -665,5 +667,5 @@
 	unsigned int _len = (unsigned int) len;
 	if ((_len != len) || (((int) _len) < 0)) {
-		printf("Command length overflow\n");
+		log(LF_OTHER, LVL_ERROR, "Command length overflow");
 		return 1;
 	}
Index: kernel/generic/src/console/console.c
===================================================================
--- kernel/generic/src/console/console.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/generic/src/console/console.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -52,32 +52,32 @@
 #include <errno.h>
 #include <str.h>
-#include <abi/klog.h>
-
-#define KLOG_PAGES    8
-#define KLOG_LENGTH   (KLOG_PAGES * PAGE_SIZE / sizeof(wchar_t))
+#include <abi/kio.h>
+
+#define KIO_PAGES    8
+#define KIO_LENGTH   (KIO_PAGES * PAGE_SIZE / sizeof(wchar_t))
 
 /** Kernel log cyclic buffer */
-wchar_t klog[KLOG_LENGTH] __attribute__((aligned(PAGE_SIZE)));
+wchar_t kio[KIO_LENGTH] __attribute__((aligned(PAGE_SIZE)));
 
 /** Kernel log initialized */
-static atomic_t klog_inited = {false};
+static atomic_t kio_inited = {false};
 
 /** First kernel log characters */
-static size_t klog_start = 0;
+static size_t kio_start = 0;
 
 /** Number of valid kernel log characters */
-static size_t klog_len = 0;
+static size_t kio_len = 0;
 
 /** Number of stored (not printed) kernel log characters */
-static size_t klog_stored = 0;
+static size_t kio_stored = 0;
 
 /** Number of stored kernel log characters for uspace */
-static size_t klog_uspace = 0;
+static size_t kio_uspace = 0;
 
 /** Kernel log spinlock */
-SPINLOCK_STATIC_INITIALIZE_NAME(klog_lock, "klog_lock");
-
-/** Physical memory area used for klog buffer */
-static parea_t klog_parea;
+SPINLOCK_INITIALIZE_NAME(kio_lock, "kio_lock");
+
+/** Physical memory area used for kio buffer */
+static parea_t kio_parea;
 
 static indev_t stdin_sink;
@@ -146,21 +146,21 @@
  *
  */
-void klog_init(void)
-{
-	void *faddr = (void *) KA2PA(klog);
+void kio_init(void)
+{
+	void *faddr = (void *) KA2PA(kio);
 	
 	ASSERT((uintptr_t) faddr % FRAME_SIZE == 0);
 	
-	klog_parea.pbase = (uintptr_t) faddr;
-	klog_parea.frames = SIZE2FRAMES(sizeof(klog));
-	klog_parea.unpriv = false;
-	klog_parea.mapped = false;
-	ddi_parea_register(&klog_parea);
-	
-	sysinfo_set_item_val("klog.faddr", NULL, (sysarg_t) faddr);
-	sysinfo_set_item_val("klog.pages", NULL, KLOG_PAGES);
-	
-	event_set_unmask_callback(EVENT_KLOG, klog_update);
-	atomic_set(&klog_inited, true);
+	kio_parea.pbase = (uintptr_t) faddr;
+	kio_parea.frames = SIZE2FRAMES(sizeof(kio));
+	kio_parea.unpriv = false;
+	kio_parea.mapped = false;
+	ddi_parea_register(&kio_parea);
+	
+	sysinfo_set_item_val("kio.faddr", NULL, (sysarg_t) faddr);
+	sysinfo_set_item_val("kio.pages", NULL, KIO_PAGES);
+	
+	event_set_unmask_callback(EVENT_KIO, kio_update);
+	atomic_set(&kio_inited, true);
 }
 
@@ -247,18 +247,68 @@
 }
 
-void klog_update(void *event)
-{
-	if (!atomic_get(&klog_inited))
+void kio_update(void *event)
+{
+	if (!atomic_get(&kio_inited))
 		return;
 	
-	spinlock_lock(&klog_lock);
-	
-	if (klog_uspace > 0) {
-		if (event_notify_3(EVENT_KLOG, true, klog_start, klog_len,
-		    klog_uspace) == EOK)
-			klog_uspace = 0;
-	}
-	
-	spinlock_unlock(&klog_lock);
+	spinlock_lock(&kio_lock);
+	
+	if (kio_uspace > 0) {
+		if (event_notify_3(EVENT_KIO, true, kio_start, kio_len,
+		    kio_uspace) == EOK)
+			kio_uspace = 0;
+	}
+	
+	spinlock_unlock(&kio_lock);
+}
+
+/** Flush characters that are stored in the output buffer
+ * 
+ */
+void kio_flush(void)
+{
+	bool ordy = ((stdout) && (stdout->op->write));
+	
+	if (!ordy)
+		return;
+
+	spinlock_lock(&kio_lock);
+
+	/* Print characters that weren't printed earlier */
+	while (kio_stored > 0) {
+		wchar_t tmp = kio[(kio_start + kio_len - kio_stored) % KIO_LENGTH];
+		kio_stored--;
+
+		/*
+		 * We need to give up the spinlock for
+		 * the physical operation of writing out
+		 * the character.
+		 */
+		spinlock_unlock(&kio_lock);
+		stdout->op->write(stdout, tmp);
+		spinlock_lock(&kio_lock);
+	}
+
+	spinlock_unlock(&kio_lock);
+}
+
+/** Put a character into the output buffer.
+ * 
+ * The caller is required to hold kio_lock
+ */
+void kio_push_char(const wchar_t ch)
+{
+	kio[(kio_start + kio_len) % KIO_LENGTH] = ch;
+	if (kio_len < KIO_LENGTH)
+		kio_len++;
+	else
+		kio_start = (kio_start + 1) % KIO_LENGTH;
+	
+	if (kio_stored < kio_len)
+		kio_stored++;
+	
+	/* The character is stored for uspace */
+	if (kio_uspace < kio_len)
+		kio_uspace++;
 }
 
@@ -267,48 +317,12 @@
 	bool ordy = ((stdout) && (stdout->op->write));
 	
-	spinlock_lock(&klog_lock);
-	
-	/* Print charaters stored in kernel log */
-	if (ordy) {
-		while (klog_stored > 0) {
-			wchar_t tmp = klog[(klog_start + klog_len - klog_stored) % KLOG_LENGTH];
-			klog_stored--;
-			
-			/*
-			 * We need to give up the spinlock for
-			 * the physical operation of writting out
-			 * the character.
-			 */
-			spinlock_unlock(&klog_lock);
-			stdout->op->write(stdout, tmp);
-			spinlock_lock(&klog_lock);
-		}
-	}
-	
-	/* Store character in the cyclic kernel log */
-	klog[(klog_start + klog_len) % KLOG_LENGTH] = ch;
-	if (klog_len < KLOG_LENGTH)
-		klog_len++;
-	else
-		klog_start = (klog_start + 1) % KLOG_LENGTH;
+	spinlock_lock(&kio_lock);
+	kio_push_char(ch);
+	spinlock_unlock(&kio_lock);
+	
+	/* Output stored characters */
+	kio_flush();
 	
 	if (!ordy) {
-		if (klog_stored < klog_len)
-			klog_stored++;
-	}
-	
-	/* The character is stored for uspace */
-	if (klog_uspace < klog_len)
-		klog_uspace++;
-	
-	spinlock_unlock(&klog_lock);
-	
-	if (ordy) {
-		/*
-		 * Output the character. In this case
-		 * it should be no longer buffered.
-		 */
-		stdout->op->write(stdout, ch);
-	} else {
 		/*
 		 * No standard output routine defined yet.
@@ -326,5 +340,5 @@
 	/* Force notification on newline */
 	if (ch == '\n')
-		klog_update(NULL);
+		kio_update(NULL);
 }
 
@@ -334,5 +348,5 @@
  *
  */
-sysarg_t sys_klog(int cmd, const void *buf, size_t size)
+sysarg_t sys_kio(int cmd, const void *buf, size_t size)
 {
 	char *data;
@@ -340,9 +354,9 @@
 
 	switch (cmd) {
-	case KLOG_UPDATE:
-		klog_update(NULL);
+	case KIO_UPDATE:
+		kio_update(NULL);
 		return EOK;
-	case KLOG_WRITE:
-	case KLOG_COMMAND:
+	case KIO_WRITE:
+	case KIO_COMMAND:
 		break;
 	default:
@@ -366,8 +380,8 @@
 		
 		switch (cmd) {
-		case KLOG_WRITE:
+		case KIO_WRITE:
 			printf("%s", data);
 			break;
-		case KLOG_COMMAND:
+		case KIO_COMMAND:
 			if (!stdin)
 				break;
Index: kernel/generic/src/lib/func.c
===================================================================
--- kernel/generic/src/lib/func.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/generic/src/lib/func.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -37,5 +37,5 @@
 
 #include <func.h>
-#include <print.h>
+#include <log.h>
 #include <cpu.h>
 #include <arch/asm.h>
@@ -72,7 +72,7 @@
 	
 	if (CPU)
-		printf("cpu%u: halted\n", CPU->id);
+		log(LF_OTHER, LVL_NOTE, "cpu%u: halted", CPU->id);
 	else
-		printf("cpu: halted\n");
+		log(LF_OTHER, LVL_NOTE, "cpu: halted");
 	
 	cpu_halt();
Index: kernel/generic/src/lib/memfnc.c
===================================================================
--- kernel/generic/src/lib/memfnc.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/generic/src/lib/memfnc.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -1,3 +1,3 @@
-	/*
+/*
  * Copyright (c) 2011 Martin Decky
  * All rights reserved.
Index: kernel/generic/src/lib/rd.c
===================================================================
--- kernel/generic/src/lib/rd.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/generic/src/lib/rd.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -38,5 +38,5 @@
  */
 
-#include <print.h>
+#include <log.h>
 #include <lib/rd.h>
 #include <mm/frame.h>
@@ -68,5 +68,6 @@
 	sysinfo_set_item_val("rd.address.physical", NULL, (sysarg_t) base);
 	
-	printf("RAM disk at %p (size %zu bytes)\n", (void *) base, size);
+	log(LF_OTHER, LVL_NOTE, "RAM disk at %p (size %zu bytes)", (void *) base,
+	    size);
 }
 
Index: kernel/generic/src/log/log.c
===================================================================
--- kernel/generic/src/log/log.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ kernel/generic/src/log/log.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,385 @@
+/*
+ * Copyright (c) 2013 Martin Sucha
+ * 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 genericlog
+ * @{
+ */
+/** @file
+ */
+
+#include <sysinfo/sysinfo.h>
+#include <synch/spinlock.h>
+#include <typedefs.h>
+#include <ddi/irq.h>
+#include <ddi/ddi.h>
+#include <ipc/event.h>
+#include <ipc/irq.h>
+#include <arch.h>
+#include <panic.h>
+#include <putchar.h>
+#include <atomic.h>
+#include <syscall/copy.h>
+#include <errno.h>
+#include <str.h>
+#include <print.h>
+#include <printf/printf_core.h>
+#include <stdarg.h>
+#include <log.h>
+#include <console/console.h>
+#include <abi/log.h>
+
+#define LOG_PAGES    8
+#define LOG_LENGTH   (LOG_PAGES * PAGE_SIZE)
+#define LOG_ENTRY_HEADER_LENGTH (sizeof(size_t) + sizeof(uint32_t))
+
+/** Cyclic buffer holding the data for kernel log */
+uint8_t log_buffer[LOG_LENGTH] __attribute__((aligned(PAGE_SIZE)));
+
+/** Kernel log initialized */
+static atomic_t log_inited = {false};
+
+/** Position in the cyclic buffer where the first log entry starts */
+size_t log_start = 0;
+
+/** Sum of length of all log entries currently stored in the cyclic buffer */
+size_t log_used = 0;
+
+/** Log spinlock */
+SPINLOCK_STATIC_INITIALIZE_NAME(log_lock, "log_lock");
+
+/** Overall count of logged messages, which may overflow as needed */
+static uint32_t log_counter = 0;
+
+/** Starting position of the entry currently being written to the log */
+static size_t log_current_start = 0;
+
+/** Length (including header) of the entry currently being written to the log */
+static size_t log_current_len = 0;
+
+/** Start of the next entry to be handed to uspace starting from log_start */
+static size_t next_for_uspace = 0;
+
+static void log_update(void *);
+
+/** Initialize kernel logging facility
+ *
+ */
+void log_init(void)
+{	
+	event_set_unmask_callback(EVENT_KLOG, log_update);
+	atomic_set(&log_inited, true);
+}
+
+static size_t log_copy_from(uint8_t *data, size_t pos, size_t len) {
+	for (size_t i = 0; i < len; i++, pos = (pos + 1) % LOG_LENGTH) {
+		data[i] = log_buffer[pos];
+	}
+	return pos;
+}
+
+static size_t log_copy_to(const uint8_t *data, size_t pos, size_t len) {
+	for (size_t i = 0; i < len; i++, pos = (pos + 1) % LOG_LENGTH) {
+		log_buffer[pos] = data[i];
+	}
+	return pos;
+}
+
+/** Append data to the currently open log entry.
+ * 
+ * This function requires that the log_lock is acquired by the caller.
+ */
+static void log_append(const uint8_t *data, size_t len)
+{
+	/* Cap the length so that the entry entirely fits into the buffer */
+	if (len > LOG_LENGTH - log_current_len) {
+		len = LOG_LENGTH - log_current_len;
+	}
+	
+	if (len == 0)
+		return;
+	
+	size_t log_free = LOG_LENGTH - log_used - log_current_len;
+	
+	/* Discard older entries to make space, if necessary */
+	while (len > log_free) {
+		size_t entry_len;
+		log_copy_from((uint8_t *) &entry_len, log_start, sizeof(size_t));
+		log_start = (log_start + entry_len) % LOG_LENGTH;
+		log_used -= entry_len;
+		log_free += entry_len;
+		next_for_uspace -= entry_len;
+	}
+	
+	size_t pos = (log_current_start + log_current_len) % LOG_LENGTH;
+	log_copy_to(data, pos, len);
+	log_current_len += len;
+}
+
+/** Begin writing an entry to the log.
+ * 
+ * This acquires the log and output buffer locks, so only calls to log_* functions should
+ * be used until calling log_end.
+ */
+void log_begin(log_facility_t fac, log_level_t level)
+{
+	spinlock_lock(&log_lock);
+	spinlock_lock(&kio_lock);
+	
+	log_current_start = (log_start + log_used) % LOG_LENGTH;
+	log_current_len = 0;
+	
+	/* Write header of the log entry, the length will be written in log_end() */
+	log_append((uint8_t *) &log_current_len, sizeof(size_t));
+	log_append((uint8_t *) &log_counter, sizeof(uint32_t));
+	uint32_t fac32 = fac;
+	uint32_t lvl32 = level;
+	log_append((uint8_t *) &fac32, sizeof(uint32_t));
+	log_append((uint8_t *) &lvl32, sizeof(uint32_t));
+	
+	log_counter++;
+}
+
+/** Finish writing an entry to the log.
+ * 
+ * This releases the log and output buffer locks.
+ */
+void log_end(void) {
+	/* Set the length in the header to correct value */
+	log_copy_to((uint8_t *) &log_current_len, log_current_start, sizeof(size_t));
+	log_used += log_current_len;
+	
+	kio_push_char('\n');
+	spinlock_unlock(&kio_lock);
+	spinlock_unlock(&log_lock);
+	
+	/* This has to be called after we released the locks above */
+	kio_flush();
+	kio_update(NULL);
+	log_update(NULL);
+}
+
+static void log_update(void *event)
+{
+	if (!atomic_get(&log_inited))
+		return;
+	
+	spinlock_lock(&log_lock);
+	if (next_for_uspace < log_used)
+		event_notify_0(EVENT_KLOG, true);
+	spinlock_unlock(&log_lock);
+}
+
+static int log_printf_str_write(const char *str, size_t size, void *data)
+{
+	size_t offset = 0;
+	size_t chars = 0;
+	
+	while (offset < size) {
+		kio_push_char(str_decode(str, &offset, size));
+		chars++;
+	}
+	
+	log_append((const uint8_t *)str, size);
+	
+	return chars;
+}
+
+static int log_printf_wstr_write(const wchar_t *wstr, size_t size, void *data)
+{
+	char buffer[16];
+	size_t offset = 0;
+	size_t chars = 0;
+	
+	for (offset = 0; offset < size; offset += sizeof(wchar_t), chars++) {
+		kio_push_char(wstr[chars]);
+		
+		size_t buffer_offset = 0;
+		int rc = chr_encode(wstr[chars], buffer, &buffer_offset, 16);
+		if (rc != EOK) {
+			return rc;
+		}
+		
+		log_append((const uint8_t *)buffer, buffer_offset);
+	}
+	
+	return chars;
+}
+
+/** Append a message to the currently being written entry.
+ * 
+ * Requires that an entry has been started using log_begin()
+ */
+int log_vprintf(const char *fmt, va_list args)
+{
+	int ret;
+	
+	printf_spec_t ps = {
+		log_printf_str_write,
+		log_printf_wstr_write,
+		NULL
+	};
+	
+	
+	ret = printf_core(fmt, &ps, args);
+	
+	return ret;
+}
+
+/** Append a message to the currently being written entry.
+ * 
+ * Requires that an entry has been started using log_begin()
+ */
+int log_printf(const char *fmt, ...)
+{
+	int ret;
+	va_list args;
+	
+	va_start(args, fmt);
+	ret = log_vprintf(fmt, args);
+	va_end(args);
+	
+	return ret;
+}
+
+/** Log a message to the kernel log.
+ * 
+ * This atomically appends a log entry.
+ * The resulting message should not contain a trailing newline, as the log
+ * entries are explicitly delimited when stored in the log.
+ */
+int log(log_facility_t fac, log_level_t level, const char *fmt, ...)
+{
+	int ret;
+	va_list args;
+	
+	log_begin(fac, level);
+	
+	va_start(args, fmt);
+	ret = log_vprintf(fmt, args);
+	va_end(args);
+	
+	log_end();
+	
+	return ret;
+}
+
+/** Control of the log from uspace
+ *
+ */
+sysarg_t sys_klog(sysarg_t operation, void *buf, size_t size,
+    sysarg_t level)
+{
+	char *data;
+	int rc;
+	
+	if (size > PAGE_SIZE)
+		return (sysarg_t) ELIMIT;
+	
+	switch (operation) {
+		case KLOG_WRITE:
+			data = (char *) malloc(size + 1, 0);
+			if (!data)
+				return (sysarg_t) ENOMEM;
+			
+			rc = copy_from_uspace(data, buf, size);
+			if (rc) {
+				free(data);
+				return (sysarg_t) rc;
+			}
+			data[size] = 0;
+			
+			if (level >= LVL_LIMIT)
+				level = LVL_NOTE;
+			
+			log(LF_USPACE, level, "%s", data);
+			
+			free(data);
+			return EOK;
+		case KLOG_READ:
+			data = (char *) malloc(size, 0);
+			if (!data)
+				return (sysarg_t) ENOMEM;
+			
+			size_t entry_len = 0;
+			size_t copied = 0;
+			
+			rc = EOK;
+	
+			spinlock_lock(&log_lock);
+			
+			while (next_for_uspace < log_used) {
+				size_t pos = (log_start + next_for_uspace) % LOG_LENGTH;
+				log_copy_from((uint8_t *) &entry_len, pos, sizeof(size_t));
+				
+				if (entry_len > PAGE_SIZE) {
+					/* 
+					 * Since we limit data transfer
+					 * to uspace to a maximum of PAGE_SIZE
+					 * bytes, skip any entries larger
+					 * than this limit to prevent
+					 * userspace being stuck trying to
+					 * read them.
+					 */
+					next_for_uspace += entry_len;
+					continue;
+				}
+				
+				if (size < copied + entry_len) {
+					if (copied == 0)
+						rc = EOVERFLOW;
+					break;
+				}
+				
+				log_copy_from((uint8_t *) (data + copied), pos, entry_len);
+				copied += entry_len;
+				next_for_uspace += entry_len;
+			}
+			
+			spinlock_unlock(&log_lock);
+			
+			if (rc != EOK) {
+				free(data);
+				return (sysarg_t) rc;
+			}
+			
+			rc = copy_to_uspace(buf, data, size);
+			
+			free(data);
+			
+			if (rc != EOK)
+				return (sysarg_t) rc;
+			
+			return copied;
+		default:
+			return (sysarg_t) ENOTSUP;
+	}
+}
+
+
+/** @}
+ */
Index: kernel/generic/src/main/kinit.c
===================================================================
--- kernel/generic/src/main/kinit.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/generic/src/main/kinit.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -59,4 +59,5 @@
 #include <mm/km.h>
 #include <print.h>
+#include <log.h>
 #include <memstr.h>
 #include <console/console.h>
@@ -140,5 +141,6 @@
 				thread_ready(thread);
 			} else
-				printf("Unable to create kcpulb thread for cpu%u\n", i);
+				log(LF_OTHER, LVL_ERROR,
+				    "Unable to create kcpulb thread for cpu%u", i);
 		}
 	}
@@ -156,5 +158,5 @@
 		thread_ready(thread);
 	else
-		printf("Unable to create kload thread\n");
+		log(LF_OTHER, LVL_ERROR, "Unable to create kload thread");
 	
 #ifdef CONFIG_KCONSOLE
@@ -168,5 +170,6 @@
 			thread_ready(thread);
 		else
-			printf("Unable to create kconsole thread\n");
+			log(LF_OTHER, LVL_ERROR,
+			    "Unable to create kconsole thread");
 	}
 #endif /* CONFIG_KCONSOLE */
@@ -210,5 +213,6 @@
 	for (i = 0; i < init.cnt; i++) {
 		if (init.tasks[i].paddr % FRAME_SIZE) {
-			printf("init[%zu]: Address is not frame aligned\n", i);
+			log(LF_OTHER, LVL_ERROR,
+			    "init[%zu]: Address is not frame aligned", i);
 			programs[i].task = NULL;
 			continue;
@@ -273,6 +277,7 @@
 			init_rd((void *) init.tasks[i].paddr, init.tasks[i].size);
 		} else
-			printf("init[%zu]: Init binary load failed "
-			    "(error %d, loader status %u)\n", i, rc,
+			log(LF_OTHER, LVL_ERROR,
+			    "init[%zu]: Init binary load failed "
+			    "(error %d, loader status %u)", i, rc,
 			    programs[i].loader_status);
 	}
Index: kernel/generic/src/main/main.c
===================================================================
--- kernel/generic/src/main/main.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/generic/src/main/main.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -62,4 +62,5 @@
 #include <console/kconsole.h>
 #include <console/console.h>
+#include <log.h>
 #include <cpu.h>
 #include <align.h>
@@ -281,5 +282,6 @@
 	ipc_init();
 	event_init();
-	klog_init();
+	kio_init();
+	log_init();
 	stats_init();
 	
Index: kernel/generic/src/main/shutdown.c
===================================================================
--- kernel/generic/src/main/shutdown.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/generic/src/main/shutdown.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -39,4 +39,5 @@
 #include <func.h>
 #include <print.h>
+#include <log.h>
 
 void reboot(void)
@@ -45,5 +46,5 @@
 	
 #ifdef CONFIG_DEBUG
-	printf("Rebooting the system\n");
+	log(LF_OTHER, LVL_DEBUG, "Rebooting the system");
 #endif
 	
Index: kernel/generic/src/mm/frame.c
===================================================================
--- kernel/generic/src/mm/frame.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/generic/src/mm/frame.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -54,4 +54,5 @@
 #include <arch.h>
 #include <print.h>
+#include <log.h>
 #include <align.h>
 #include <mm/slab.h>
@@ -121,5 +122,6 @@
 {
 	if (zones.count + 1 == ZONES_MAX) {
-		printf("Maximum zone count %u exceeded!\n", ZONES_MAX);
+		log(LF_OTHER, LVL_ERROR, "Maximum zone count %u exceeded!",
+		    ZONES_MAX);
 		return (size_t) -1;
 	}
@@ -141,6 +143,7 @@
 			    (!iswithin(zones.info[i].base, zones.info[i].count,
 			    base, count))) {
-				printf("Zone (%p, %p) overlaps "
-				    "with previous zone (%p %p)!\n",
+				log(LF_OTHER, LVL_WARN,
+				    "Zone (%p, %p) overlaps "
+				    "with previous zone (%p %p)!",
 				    (void *) PFN2ADDR(base), (void *) PFN2ADDR(count),
 				    (void *) PFN2ADDR(zones.info[i].base),
@@ -913,6 +916,7 @@
 		
 #ifdef CONFIG_DEBUG
-		printf("Thread %" PRIu64 " waiting for %zu frames "
-		    "(%zu available).\n", THREAD->tid, count, avail);
+		log(LF_OTHER, LVL_DEBUG,
+		    "Thread %" PRIu64 " waiting for %zu frames "
+		    "%zu available.", THREAD->tid, count, avail);
 #endif
 		
@@ -938,5 +942,6 @@
 		
 #ifdef CONFIG_DEBUG
-		printf("Thread %" PRIu64 " woken up.\n", THREAD->tid);
+		log(LF_OTHER, LVL_DEBUG, "Thread %" PRIu64 " woken up.",
+		    THREAD->tid);
 #endif
 		
Index: kernel/generic/src/proc/program.c
===================================================================
--- kernel/generic/src/proc/program.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/generic/src/proc/program.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -49,5 +49,5 @@
 #include <lib/elf_load.h>
 #include <errno.h>
-#include <print.h>
+#include <log.h>
 #include <syscall/copy.h>
 #include <proc/program.h>
@@ -155,5 +155,5 @@
 		
 		program_loader = image_addr;
-		printf("Program loader at %p\n", (void *) image_addr);
+		log(LF_OTHER, LVL_NOTE, "Program loader at %p", (void *) image_addr);
 		
 		return EOK;
@@ -181,5 +181,6 @@
 	if (!loader) {
 		as_destroy(as);
-		printf("Cannot spawn loader as none was registered\n");
+		log(LF_OTHER, LVL_ERROR,
+		    "Cannot spawn loader as none was registered");
 		return ENOENT;
 	}
@@ -189,5 +190,5 @@
 	if (prg->loader_status != EE_OK) {
 		as_destroy(as);
-		printf("Cannot spawn loader (%s)\n",
+		log(LF_OTHER, LVL_ERROR, "Cannot spawn loader (%s)",
 		    elf_error(prg->loader_status));
 		return ENOENT;
Index: kernel/generic/src/proc/scheduler.c
===================================================================
--- kernel/generic/src/proc/scheduler.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/generic/src/proc/scheduler.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -61,4 +61,5 @@
 #include <cpu.h>
 #include <print.h>
+#include <log.h>
 #include <debug.h>
 #include <stacktrace.h>
@@ -517,6 +518,7 @@
 	
 #ifdef SCHEDULER_VERBOSE
-	printf("cpu%u: tid %" PRIu64 " (priority=%d, ticks=%" PRIu64 
-	    ", nrdy=%ld)\n", CPU->id, THREAD->tid, THREAD->priority,
+	log(LF_OTHER, LVL_DEBUG,
+	    "cpu%u: tid %" PRIu64 " (priority=%d, ticks=%" PRIu64
+	    ", nrdy=%" PRIua ")", CPU->id, THREAD->tid, THREAD->priority,
 	    THREAD->ticks, atomic_get(&CPU->nrdy));
 #endif
@@ -663,6 +665,7 @@
 				
 #ifdef KCPULB_VERBOSE
-				printf("kcpulb%u: TID %" PRIu64 " -> cpu%u, "
-				    "nrdy=%ld, avg=%ld\n", CPU->id, t->tid,
+				log(LF_OTHER, LVL_DEBUG,
+				    "kcpulb%u: TID %" PRIu64 " -> cpu%u, "
+				    "nrdy=%ld, avg=%ld", CPU->id, t->tid,
 				    CPU->id, atomic_get(&CPU->nrdy),
 				    atomic_get(&nrdy) / config.cpu_active);
Index: kernel/generic/src/syscall/syscall.c
===================================================================
--- kernel/generic/src/syscall/syscall.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ kernel/generic/src/syscall/syscall.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -56,4 +56,5 @@
 #include <console/console.h>
 #include <udebug/udebug.h>
+#include <log.h>
 
 /** Dispatch system call */
@@ -86,5 +87,6 @@
 		rc = syscall_table[id](a1, a2, a3, a4, a5, a6);
 	} else {
-		printf("Task %" PRIu64": Unknown syscall %#" PRIxn, TASK->taskid, id);
+		log(LF_OTHER, LVL_ERROR,
+		    "Task %" PRIu64": Unknown syscall %#" PRIxn, TASK->taskid, id);
 		task_kill_self(true);
 	}
@@ -120,5 +122,5 @@
 syshandler_t syscall_table[SYSCALL_END] = {
 	/* System management syscalls. */
-	(syshandler_t) sys_klog,
+	(syshandler_t) sys_kio,
 	(syshandler_t) sys_tls_set,
 	
@@ -190,5 +192,7 @@
 	
 	/* Kernel console syscalls. */
-	(syshandler_t) sys_debug_activate_console
+	(syshandler_t) sys_debug_activate_console,
+	
+	(syshandler_t) sys_klog,
 };
 
Index: tools/autotool.py
===================================================================
--- tools/autotool.py	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ tools/autotool.py	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -263,4 +263,9 @@
 		clang_target = "powerpc-unknown-linux"
 		helenos_target = "ppc-helenos"
+	
+	if (config['PLATFORM'] == "sparc32"):
+		target = config['PLATFORM'];
+		gnu_target = "sparc-leon3-linux-gnu"
+		helenos_target = "sparc-leon3-helenos"
 	
 	if (config['PLATFORM'] == "sparc64"):
Index: tools/ew.py
===================================================================
--- tools/ew.py	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ tools/ew.py	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -34,12 +34,27 @@
 
 import os 
+import sys
 import subprocess 
 import autotool
 import platform
 
+overrides = {}
+
+def is_override(str):
+	if str in overrides.keys():
+		return overrides[str]
+	return False
+
+def cfg_get(platform, machine):
+	if machine == "":
+		return emulators[platform]
+	else:
+		return emulators[platform][machine]
+
 def run_in_console(cmd, title):
 	cmdline = 'xterm -T ' + '"' + title + '"' + ' -e ' + cmd
 	print(cmdline)
-	subprocess.call(cmdline, shell = True);
+	if not is_override('dryrun'):
+		subprocess.call(cmdline, shell = True);
 
 def get_host_native_width():
@@ -52,5 +67,5 @@
 	# on 32 bits host
 	host_width = get_host_native_width()
-	if guest_width <= host_width:
+	if guest_width <= host_width and not is_override('nokvm'):
 		opts = opts + ' -enable-kvm'
 	
@@ -79,6 +94,10 @@
 
 def qemu_bd_options():
+	if is_override('nohdd'):
+		return ''
+
 	if not os.path.exists('hdisk.img'):
 		subprocess.call('tools/mkfat.py 1048576 uspace/dist/data hdisk.img', shell = True)
+
 	return ' -hda hdisk.img'
 
@@ -93,11 +112,33 @@
 
 def qemu_net_options():
-	nic_options = qemu_nic_e1k_options()
+	if is_override('nonet'):
+		return ''
+
+	nic_options = ''
+	if 'net' in overrides.keys():
+		if 'e1k' in overrides['net'].keys():
+			nic_options += qemu_nic_e1k_options()
+		if 'rtl8139' in overrides['net'].keys():
+			nic_options += qemu_nic_rtl8139_options()
+		if 'ne2k' in overrides['net'].keys():
+			nic_options += qemu_nic_ne2k_options()
+	else:
+		# Use the default NIC
+		nic_options += qemu_nic_e1k_options()
+
 	return nic_options + ' -net user -redir udp:8080::8080 -redir udp:8081::8081 -redir tcp:8080::8080 -redir tcp:8081::8081 -redir tcp:2223::2223'
 
 def qemu_usb_options():
-	return ''
-
-def qemu_run(platform, machine, console, image, networking, storage, usb):
+	if is_override('nousb'):
+		return ''
+	return ' -usb'
+
+def qemu_audio_options():
+	if is_override('nosnd'):
+		return ''
+	return ' -soundhw sb16' 
+
+def qemu_run(platform, machine):
+	cfg = cfg_get(platform, machine)
 	suffix, options = platform_to_qemu_options(platform, machine)
 	cmd = 'qemu-' + suffix
@@ -107,17 +148,19 @@
 		cmdline += ' ' + options
 
-	if storage:
-		cmdline += qemu_bd_options()
-	if networking:
+	cmdline += qemu_bd_options()
+
+	if (not 'net' in cfg.keys()) or cfg['net']:
 		cmdline += qemu_net_options()
-	if usb:
+	if (not 'usb' in cfg.keys()) or cfg['usb']:
 		cmdline += qemu_usb_options()
+	if (not 'audio' in cfg.keys()) or cfg['audio']:
+		cmdline += qemu_audio_options()
 	
-	if image == 'image.iso':
+	if cfg['image'] == 'image.iso':
 		cmdline += ' -boot d -cdrom image.iso'
-	elif image == 'image.boot':
+	elif cfg['image'] == 'image.boot':
 		cmdline += ' -kernel image.boot'
 
-	if not console:
+	if ('console' in cfg.keys()) and not cfg['console']:
 		cmdline += ' -nographic'
 
@@ -128,52 +171,137 @@
 	else:
 		print(cmdline)
-		subprocess.call(cmdline, shell = True)
+		if not is_override('dryrun'):
+			subprocess.call(cmdline, shell = True)
 		
-def ski_run(platform, machine, console, image, networking, storage, usb):
+def ski_run(platform, machine):
 	run_in_console('ski -i contrib/conf/ski.conf', 'HelenOS/ia64 on ski')
 
-def msim_run(platform, machine, console, image, networking, storage, usb):
+def msim_run(platform, machine):
 	run_in_console('msim -c contrib/conf/msim.conf', 'HelenOS/mips32 on msim')
 
-emulators = {}
-emulators['amd64'] = {}
-emulators['arm32'] = {}
-emulators['ia32'] = {}
-emulators['ia64'] = {}
-emulators['mips32'] = {}
-emulators['ppc32'] = {}
-emulators['sparc64'] = {}
-
-emulators['amd64'][''] = qemu_run, True, 'image.iso', True, True, True
-emulators['arm32']['integratorcp'] = qemu_run, True, 'image.boot', False, False, False
-emulators['ia32'][''] = qemu_run, True, 'image.iso', True, True, True
-emulators['ia64']['ski'] = ski_run, False, 'image.boot', False, False, False
-emulators['mips32']['msim'] = msim_run, False, 'image.boot', False, False, False
-emulators['mips32']['lmalta'] = qemu_run, False, 'image.boot', False, False, False
-emulators['mips32']['bmalta'] = qemu_run, False, 'image.boot', False, False, False
-emulators['ppc32'][''] = qemu_run, True, 'image.iso', True, True, True
-emulators['sparc64']['generic'] = qemu_run, True, 'image.iso', True, True, True
+
+emulators = {
+	'amd64' : {
+		'run' : qemu_run,
+		'image' : 'image.iso'
+	},
+	'arm32' : {
+		'integratorcp' : {
+			'run' : qemu_run,
+			'image' : 'image.boot',
+			'net' : False,
+			'audio' : False
+		}
+	},
+	'ia32' : {
+		'run' : qemu_run,
+		'image' : 'image.iso'
+	},
+	'ia64' : {
+		'ski' : {
+			'run' : ski_run
+		}
+	},
+	'mips32' : {
+		'msim' : {
+			'run' : msim_run
+		},
+		'lmalta' : {
+			'run' : qemu_run,
+			'image' : 'image.boot',
+			'console' : False
+		},
+		'bmalta' : {
+			'run' : qemu_run,
+			'image' : 'image.boot',
+			'console' : False
+		},
+	},
+	'ppc32' : {
+		'run' : qemu_run,
+		'image' : 'image.iso',
+		'audio' : False
+	},
+	'sparc64' : {
+		'generic' : {
+			'run' : qemu_run,
+			'image' : 'image.iso',
+			'audio' : False
+		}
+	},
+}
+
+def usage():
+	print("%s - emulator wrapper for running HelenOS\n" % os.path.basename(sys.argv[0]))
+	print("%s [-d] [-h] [-net e1k|rtl8139|ne2k] [-nohdd] [-nokvm] [-nonet] [-nosnd] [-nousb]\n" %
+	    os.path.basename(sys.argv[0]))
+	print("-d\tDry run: do not run the emulation, just print the command line.")
+	print("-h\tPrint the usage information and exit.")
+	print("-nohdd\tDisable hard disk, if applicable.")
+	print("-nokvm\tDisable KVM, if applicable.")
+	print("-nonet\tDisable networking support, if applicable.")
+	print("-nosnd\tDisable sound, if applicable.")
+	print("-nousb\tDisable USB support, if applicable.")
 
 def run():
+	expect_nic = False
+
+	for i in range(1, len(sys.argv)):
+
+		if expect_nic:
+			expect_nic = False
+			if not 'net' in overrides.keys():
+				overrides['net'] = {}
+			if sys.argv[i] == 'e1k':
+				overrides['net']['e1k'] = True
+			elif sys.argv[i] == 'rtl8139':
+				overrides['net']['rtl8139'] = True
+			elif sys.argv[i] == 'ne2k':
+				overrides['net']['ne2k'] = True
+			else:
+				usage()
+				exit()
+
+		elif sys.argv[i] == '-h':
+			usage()
+			exit()
+		elif sys.argv[i] == '-d':
+			overrides['dryrun'] = True
+		elif sys.argv[i] == '-net' and i < len(sys.argv) - 1:
+			expect_nic = True
+		elif sys.argv[i] == '-nohdd':
+			overrides['nohdd'] = True
+		elif sys.argv[i] == '-nokvm':
+			overrides['nokvm'] = True
+		elif sys.argv[i] == '-nonet':
+			overrides['nonet'] = True
+		elif sys.argv[i] == '-nosnd':
+			overrides['nosnd'] = True
+		elif sys.argv[i] == '-nousb':
+			overrides['nousb'] = True
+		else:
+			usage()
+			exit()
+
 	config = {}
 	autotool.read_config(autotool.CONFIG, config)
 
+	if 'PLATFORM' in config.keys():
+		platform = config['PLATFORM']
+	else:
+		platform = ''
+
+	if 'MACHINE' in config.keys():
+		mach = config['MACHINE']
+	else:
+		mach = ''
+
 	try:
-		platform = config['PLATFORM']
+		emu_run = cfg_get(platform, mach)['run']
 	except:
-		platform = ''
-
-	try:
-		mach = config['MACHINE']
-	except:
-		mach = ''
-
-	try:
-		emu_run, console, image, networking, storage, usb = emulators[platform][mach]
-	except:
-		print("Cannot start emulation for the chosen configuration.")
+		print("Cannot start emulation for the chosen configuration. (%s/%s)" % (platform, mach))
 		return
 
-	emu_run(platform, mach, console, image, networking, storage, usb)
+	emu_run(platform, mach)
 
 run()
Index: tools/toolchain.sh
===================================================================
--- tools/toolchain.sh	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ tools/toolchain.sh	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -62,4 +62,5 @@
 
 BASEDIR="`pwd`"
+SRCDIR="$(readlink -f $(dirname "$0"))"
 BINUTILS="binutils-${BINUTILS_VERSION}${BINUTILS_RELEASE}.tar.bz2"
 GCC="gcc-${GCC_VERSION}.tar.bz2"
@@ -154,4 +155,5 @@
 	echo " ppc32      32-bit PowerPC"
 	echo " ppc64      64-bit PowerPC"
+	echo " sparc32    SPARC V8"
 	echo " sparc64    SPARC V9"
 	echo " all        build all targets"
@@ -377,4 +379,8 @@
 			HELENOS_TARGET="ppc64-helenos"
 			;;
+		"sparc32")
+			LINUX_TARGET="sparc-leon3-linux-gnu"
+			HELENOS_TARGET="sparc-leon3-helenos"
+			;;
 		"sparc64")
 			LINUX_TARGET="sparc64-linux-gnu"
@@ -440,11 +446,11 @@
 	echo ">>> Applying patches"
 	for p in $BINUTILS_PATCHES; do
-		patch_sources "${BASEDIR}/${p}" 0 "binutils"
+		patch_sources "${SRCDIR}/${p}" 0 "binutils"
 	done
 	for p in $GCC_PATCHES; do
-		patch_sources "${BASEDIR}/${p}" 0 "GCC"
+		patch_sources "${SRCDIR}/${p}" 0 "GCC"
 	done
 	for p in $GDB_PATCHES; do
-		patch_sources "${BASEDIR}/${p}" 0 "GDB"
+		patch_sources "${SRCDIR}/${p}" 0 "GDB"
 	done
 	
@@ -554,5 +560,5 @@
 
 case "$1" in
-	amd64|arm32|ia32|ia64|mips32|mips32eb|mips64|ppc32|ppc64|sparc64)
+	amd64|arm32|ia32|ia64|mips32|mips32eb|mips64|ppc32|ppc64|sparc32|sparc64)
 		prepare
 		build_target "$1"
@@ -569,4 +575,5 @@
 		build_target "ppc32"
 		build_target "ppc64"
+		build_target "sparc32"
 		build_target "sparc64"
 		;;
@@ -582,4 +589,5 @@
 		build_target "ppc32" &
 		build_target "ppc64" &
+		build_target "sparc32" &
 		build_target "sparc64" &
 		wait
@@ -604,4 +612,7 @@
 		
 		build_target "ppc64" &
+		build_target "sparc32" &
+		wait
+		
 		build_target "sparc64" &
 		wait
Index: uspace/Makefile
===================================================================
--- uspace/Makefile	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/Makefile	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -45,9 +45,10 @@
 	app/edit \
 	app/getterm \
+	app/hdisk \
 	app/init \
 	app/inet \
 	app/kill \
 	app/killall \
-	app/klog \
+	app/kio \
 	app/loc \
 	app/logset \
@@ -68,4 +69,5 @@
 	app/trace \
 	app/top \
+	app/untar \
 	app/usbinfo \
 	app/vuhid \
@@ -90,4 +92,5 @@
 	srv/locsrv \
 	srv/logger \
+	srv/klog \
 	srv/devman \
 	srv/loader \
@@ -239,4 +242,5 @@
 	lib/softrend \
 	lib/draw \
+	lib/math \
 	lib/net \
 	lib/nic \
@@ -250,5 +254,7 @@
 	lib/pcm \
 	lib/bithenge \
-	lib/posix
+	lib/posix \
+	lib/mbr \
+	lib/gpt
 
 LIBC_BUILD = $(addsuffix .build,$(LIBC))
Index: uspace/Makefile.common
===================================================================
--- uspace/Makefile.common	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/Makefile.common	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -45,4 +45,5 @@
 #
 #   POSIX_COMPAT       set to 'y' to use POSIX compatibility layer
+#   NEEDS_MATH         set to 'y' to add implementation of mathematical functions
 #
 # Optionally, for a binary:
@@ -109,4 +110,5 @@
 LIBSOFTFLOAT_PREFIX = $(LIB_PREFIX)/softfloat
 LIBSOFTINT_PREFIX = $(LIB_PREFIX)/softint
+LIBMATH_PREFIX = $(LIB_PREFIX)/math
 
 LIBPOSIX_PREFIX = $(LIB_PREFIX)/posix
@@ -143,4 +145,7 @@
 LIBHTTP_PREFIX = $(LIB_PREFIX)/http
 LIBURI_PREFIX = $(LIB_PREFIX)/uri
+
+LIBMBR_PREFIX = $(LIB_PREFIX)/mbr
+LIBGPT_PREFIX = $(LIB_PREFIX)/gpt
 
 ifeq ($(STATIC_NEEDED),y)
@@ -233,4 +238,9 @@
 endif
 
+# Do we need math?
+ifeq ($(NEEDS_MATH),y)
+	BASE_LIBS += $(LIBMATH_PREFIX)/libmath.a
+endif
+
 ## Setup platform configuration
 #
Index: uspace/app/hdisk/Makefile
===================================================================
--- uspace/app/hdisk/Makefile	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/app/hdisk/Makefile	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,44 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+USPACE_PREFIX = ../..
+LIBS = $(LIBMBR_PREFIX)/libmbr.a $(LIBGPT_PREFIX)/libgpt.a \
+	$(LIBBLOCK_PREFIX)/libblock.a $(LIBCLUI_PREFIX)/libclui.a \
+	$(LIBC_PREFIX)/libc.a
+EXTRA_CFLAGS = -I$(LIBMBR_PREFIX) -I$(LIBGPT_PREFIX) -I$(LIBBLOCK_PREFIX) -I$(LIBCLUI_PREFIX)
+BINARY = hdisk
+
+SOURCES = \
+	hdisk.c \
+	input.c \
+	func_none.c \
+	func_mbr.c \
+	func_gpt.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/hdisk/common.h
===================================================================
--- uspace/app/hdisk/common.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/app/hdisk/common.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2012-2013 Dominik Taborsky
+ * 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 hdisk
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __COMMON_H__
+#define __COMMON_H__
+
+#include <libmbr.h>
+#include <libgpt.h>
+
+typedef enum {
+	LYT_NONE,
+	LYT_MBR,
+	LYT_GPT,
+} layouts_t;
+
+typedef union {
+	mbr_label_t *mbr;
+	gpt_label_t *gpt;
+} label_data_t;
+
+typedef struct label {
+	layouts_t layout;
+	aoff64_t blocks;
+	service_id_t device;
+	label_data_t data;
+	unsigned int alignment;
+	int (* destroy_label)(struct label *);
+	int (* add_part)(struct label *, tinput_t *);
+	int (* delete_part)(struct label *, tinput_t *);
+	int (* new_label)(struct label *);
+	int (* print_parts)(struct label *);
+	int (* read_parts)(struct label *);
+	int (* write_parts)(struct label *);
+	int (* extra_funcs)(struct label *, tinput_t *);
+} label_t;
+
+#endif
Index: uspace/app/hdisk/func_gpt.c
===================================================================
--- uspace/app/hdisk/func_gpt.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/app/hdisk/func_gpt.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2012-2013 Dominik Taborsky
+ * 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 hdisk
+ * @{
+ */
+/** @file
+ */
+
+#include <stdio.h>
+#include <str.h>
+#include <errno.h>
+#include <str_error.h>
+#include <sys/types.h>
+#include <sys/typefmt.h>
+#include "func_gpt.h"
+#include "input.h"
+
+static void print_part_types(void);
+static int set_gpt_partition(tinput_t *, gpt_part_t *, label_t *);
+
+int construct_gpt_label(label_t *this)
+{
+	this->layout = LYT_GPT;
+	this->alignment = 1;
+	
+	this->add_part = add_gpt_part;
+	this->delete_part = delete_gpt_part;
+	this->destroy_label = destroy_gpt_label;
+	this->new_label = new_gpt_label;
+	this->print_parts = print_gpt_parts;
+	this->read_parts = read_gpt_parts;
+	this->write_parts = write_gpt_parts;
+	this->extra_funcs = extra_gpt_funcs;
+	
+	return this->new_label(this);
+}
+
+int add_gpt_part(label_t *this, tinput_t *in)
+{
+	gpt_part_t *partition = gpt_get_partition(this->data.gpt);
+	if (partition == NULL)
+		return ENOMEM;
+	
+	return set_gpt_partition(in, partition, this);
+}
+
+int delete_gpt_part(label_t *this, tinput_t *in)
+{
+	printf("Index of the partition to delete (counted from 0): ");
+	size_t idx = get_input_size_t(in);
+	
+	int rc = gpt_remove_partition(this->data.gpt, idx);
+	if (rc == ENOMEM) {
+		printf("Warning: Running out on memory, not resizing.\n");
+		return rc;
+	} else if (rc == EINVAL) {
+		printf("Invalid index.\n");
+		return rc;
+	}
+	
+	return EOK;
+}
+
+int destroy_gpt_label(label_t *this)
+{
+	gpt_free_label(this->data.gpt);
+	return EOK;
+}
+
+int new_gpt_label(label_t *this)
+{
+	this->data.gpt = gpt_alloc_label();
+	return EOK;
+}
+
+int print_gpt_parts(label_t *this)
+{
+	printf("Current partition scheme: GPT\n");
+	printf("Number of blocks: %" PRIu64 "\n", this->blocks);
+	
+	size_t i = 0;
+	gpt_part_foreach (this->data.gpt, iter) {
+		if (gpt_get_part_type(iter) == GPT_PTE_UNUSED)
+			continue;
+		
+		if (i % 20 == 0)
+			printf("%15s %10s %10s Type: Name:\n",
+			    "Start:", "End:", "Length:");
+		
+		printf("%3zu  %10" PRIu64 " %10" PRIu64 " %10" PRIu64 "    %3zu %s\n",
+		   i, gpt_get_start_lba(iter), gpt_get_end_lba(iter),
+		   gpt_get_end_lba(iter) - gpt_get_start_lba(iter), 
+		   gpt_get_part_type(iter), gpt_get_part_name(iter));
+		
+		i++;
+	}
+	
+	return EOK;
+}
+
+int read_gpt_parts(label_t *this)
+{
+	int rc = gpt_read_header(this->data.gpt, this->device);
+	if (rc != EOK) {
+		printf("Error: Reading header failed: %d (%s)\n", rc,
+		    str_error(rc));
+		return rc;
+	}
+	
+	rc = gpt_read_partitions(this->data.gpt);
+	if (rc != EOK) {
+		printf("Error: Reading partitions failed: %d (%s)\n", rc,
+		    str_error(rc));
+		return rc;
+	}
+	
+	return EOK;
+}
+
+int write_gpt_parts(label_t *this)
+{
+	int rc = gpt_write_partitions(this->data.gpt, this->device);
+	if (rc != EOK) {
+		printf("Error: Writing partitions failed: %d (%s)\n", rc,
+		    str_error(rc));
+		return rc;
+	}
+	
+	return EOK;
+}
+
+int extra_gpt_funcs(label_t *this, tinput_t *in)
+{
+	printf("Not implemented.\n");
+	return EOK;
+}
+
+static int set_gpt_partition(tinput_t *in, gpt_part_t *partition, label_t *this)
+{
+	printf("Set starting address: ");
+	uint64_t sa = get_input_uint64(in);
+	if ((this->alignment != 0) && (this->alignment != 1) &&
+	    (sa % this->alignment != 0))
+		sa = gpt_get_next_aligned(sa, this->alignment);
+	
+	printf("Set end address (max: %" PRIu64 "): ", this->blocks);
+	uint64_t ea = get_input_uint64(in);
+	
+	if (ea <= sa) {
+		printf("Invalid value.\n");
+		return EINVAL;
+	}
+	
+	gpt_set_start_lba(partition, sa);
+	gpt_set_end_lba(partition, ea);
+	
+	printf("Choose type: ");
+	print_part_types();
+	printf("Set type (1 for HelenOS System): ");
+	size_t idx = get_input_size_t(in);
+	gpt_set_part_type(partition, idx);
+	
+	gpt_set_random_uuid(partition->part_id);
+	
+	printf("Name the partition: ");
+	char *name;
+	int rc = get_input_line(in, &name);
+	if (rc != EOK) {
+		printf("Error reading name: %d (%s)\n", rc, str_error(rc));
+		return rc;
+	}
+	
+	gpt_set_part_name(partition, name, str_size(name));
+	
+	return EOK;
+}
+
+static void print_part_types(void)
+{
+	unsigned int count = 0;
+	const partition_type_t *ptype = gpt_ptypes;
+	
+	do {
+		printf("%u: %s\n", count, ptype->desc);
+		count++;
+		ptype++;
+		
+		if (count % 10 == 0) {
+			printf("Print (more) partition types? (y/n)\n");
+			int c = getchar();
+			if (c == 'n')
+				return;
+		}
+	} while (ptype->guid != NULL);
+}
Index: uspace/app/hdisk/func_gpt.h
===================================================================
--- uspace/app/hdisk/func_gpt.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/app/hdisk/func_gpt.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2012-2013 Dominik Taborsky
+ * 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 hdisk
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __FUNC_GPT_H__
+#define __FUNC_GPT_H__
+
+#include <loc.h>
+#include <tinput.h>
+#include <libgpt.h>
+#include "common.h"
+
+extern int construct_gpt_label(label_t *);
+extern int add_gpt_part(label_t *, tinput_t *);
+extern int delete_gpt_part(label_t *, tinput_t *);
+extern int destroy_gpt_label(label_t *);
+extern int new_gpt_label(label_t *);
+extern int print_gpt_parts(label_t *);
+extern int read_gpt_parts(label_t *);
+extern int write_gpt_parts(label_t *);
+extern int extra_gpt_funcs(label_t *, tinput_t *);
+
+#endif
Index: uspace/app/hdisk/func_mbr.c
===================================================================
--- uspace/app/hdisk/func_mbr.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/app/hdisk/func_mbr.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 2012-2013 Dominik Taborsky
+ * 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 hdisk
+ * @{
+ */
+/** @file
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <str_error.h>
+#include <sys/types.h>
+#include "func_mbr.h"
+#include "input.h"
+
+static int set_mbr_partition(tinput_t *, mbr_part_t *, label_t *);
+
+int construct_mbr_label(label_t *this)
+{
+	this->layout = LYT_MBR;
+	this->alignment = 1;
+	
+	this->add_part      = add_mbr_part;
+	this->delete_part   = delete_mbr_part;
+	this->destroy_label = destroy_mbr_label;
+	this->new_label     = new_mbr_label;
+	this->print_parts   = print_mbr_parts;
+	this->read_parts    = read_mbr_parts;
+	this->write_parts   = write_mbr_parts;
+	this->extra_funcs   = extra_mbr_funcs;
+	
+	return this->new_label(this);
+}
+
+int add_mbr_part(label_t *this, tinput_t *in)
+{
+	mbr_part_t *partition = mbr_alloc_partition();
+	if (partition == NULL)
+		return ENOMEM;
+	
+	int rc = set_mbr_partition(in, partition, this);
+	if (rc != EOK)
+		return rc;
+	
+	rc = mbr_add_partition(this->data.mbr, partition);
+	if (rc != ERR_OK)
+		printf("Error adding partition: %d\n", rc);
+	
+	return EOK;
+}
+
+int delete_mbr_part(label_t *this, tinput_t *in)
+{
+	printf("Index of the partition to delete (counted from 0): ");
+	size_t idx = get_input_size_t(in);
+	
+	if ((idx == 0) && (errno != EOK))
+		return errno;
+	
+	int rc = mbr_remove_partition(this->data.mbr, idx);
+	if (rc != EOK)
+		printf("Error: partition does not exist?\n");
+	
+	return EOK;
+}
+
+int destroy_mbr_label(label_t *this)
+{
+	mbr_free_label(this->data.mbr);
+	return EOK;
+}
+
+int new_mbr_label(label_t *this)
+{
+	this->data.mbr = mbr_alloc_label();
+	if (this->data.mbr == NULL)
+		return ENOMEM;
+	
+	mbr_set_device(this->data.mbr, this->device);
+	return EOK;
+}
+
+int print_mbr_parts(label_t *this)
+{
+	printf("Current partition scheme: MBR\n");
+	printf("Number of blocks: %" PRIu64 "\n", this->blocks);
+	printf("\t\t%10s  %10s %10s %10s %7s\n",
+	    "Bootable:", "Start:", "End:", "Length:", "Type:");
+	
+	unsigned int num = 0;
+	mbr_part_t *it;
+	for (it = mbr_get_first_partition(this->data.mbr); it != NULL;
+	     it = mbr_get_next_partition(this->data.mbr, it)) {
+		if (it->type == PT_UNUSED)
+			continue;
+		
+		printf("\tP%u:\t", num);
+		if (mbr_get_flag(it, ST_BOOT))
+			printf("*");
+		else
+			printf(" ");
+		
+		printf("\t%10u %10u %10u %7u\n", it->start_addr,
+		    it->start_addr + it->length, it->length, it->type);
+		
+		num++;
+	}
+	
+	printf("%u partitions found.\n", num);
+	
+	return EOK;
+}
+
+int read_mbr_parts(label_t *this)
+{
+	int rc = mbr_read_mbr(this->data.mbr, this->device);
+	if (rc != EOK)
+		return rc;
+	
+	if (!mbr_is_mbr(this->data.mbr))
+		return EINVAL;
+	
+	rc = mbr_read_partitions(this->data.mbr);
+	if (rc != EOK)
+		return rc;
+	
+	return EOK;
+}
+
+int write_mbr_parts(label_t *this)
+{
+	int rc = mbr_write_partitions(this->data.mbr, this->device);
+	if (rc != EOK)
+		printf("Error occured during writing: ERR: %d: %s\n", rc,
+		    str_error(rc));
+	
+	return rc;
+}
+
+int extra_mbr_funcs(label_t *this, tinput_t *in)
+{
+	printf("Not implemented.\n");
+	return EOK;
+}
+
+static int set_mbr_partition(tinput_t *in, mbr_part_t *partition, label_t *this)
+{
+	printf("Primary (p) or logical (l): ");
+	int c = getchar();
+	printf("%c\n", c);
+
+	switch (c) {
+	case 'p':
+		mbr_set_flag(partition, ST_LOGIC, false);
+		break;
+	case 'l':
+		mbr_set_flag(partition, ST_LOGIC, true);
+		break;
+	default:
+		printf("Invalid type. Cancelled.\n");
+		return EINVAL;
+	}
+	
+	printf("Set type (0 - 255): ");
+	uint8_t type = get_input_uint8(in);
+	if ((type == 0) && (errno != EOK))
+		return errno;
+	
+	// FIXME: Make sure there is at most one bootable partition
+	printf("Bootable? (y/n): ");
+	c = getchar();
+	if ((c != 'y') && (c != 'Y') && (c != 'n') && (c != 'N')) {
+		printf("Invalid value. Cancelled.");
+		return EINVAL;
+	}
+	
+	printf("%c\n", c);
+	mbr_set_flag(partition, ST_BOOT, (c == 'y' || c == 'Y') ? true : false);
+	
+	printf("Set starting address: ");
+	uint32_t sa = get_input_uint32(in);
+	if ((sa == 0) && (errno != EOK))
+		return errno;
+	
+	if ((this->alignment != 0) && (this->alignment != 1) &&
+	    (sa % this->alignment != 0)) {
+		sa = mbr_get_next_aligned(sa, this->alignment);
+		printf("Starting address was aligned to %" PRIu32 ".\n", sa);
+	}
+	
+	printf("Set end addres (max: %" PRIu64 "): ", this->blocks);
+	uint32_t ea = get_input_uint32(in);
+	if ((ea == 0) && (errno != EOK))
+		return errno;
+	
+	if (ea < sa) {
+		printf("Invalid value. Canceled.\n");
+		return EINVAL;
+	}
+	
+	partition->type = type;
+	partition->start_addr = sa;
+	partition->length = ea - sa;
+	
+	return EOK;
+}
Index: uspace/app/hdisk/func_mbr.h
===================================================================
--- uspace/app/hdisk/func_mbr.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/app/hdisk/func_mbr.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2012-2013 Dominik Taborsky
+ * 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 hdisk
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __FUNC_MBR_H__
+#define __FUNC_MBR_H__
+
+#include <loc.h>
+#include <tinput.h>
+#include <libmbr.h>
+#include "common.h"
+
+extern int construct_mbr_label(label_t *);
+extern int add_mbr_part(label_t *, tinput_t *);
+extern int delete_mbr_part(label_t *, tinput_t *);
+extern int destroy_mbr_label(label_t *);
+extern int new_mbr_label(label_t *);
+extern int print_mbr_parts(label_t *);
+extern int read_mbr_parts(label_t *);
+extern int write_mbr_parts(label_t *);
+extern int extra_mbr_funcs(label_t *, tinput_t *);
+
+#endif
Index: uspace/app/hdisk/func_none.c
===================================================================
--- uspace/app/hdisk/func_none.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/app/hdisk/func_none.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2012-2013 Dominik Taborsky
+ * 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 hdisk
+ * @{
+ */
+/** @file
+ */
+
+#include <errno.h>
+#include "func_none.h"
+
+static void not_implemented(void);
+
+int construct_none_label(label_t *this)
+{
+	this->layout = LYT_NONE;
+	
+	this->add_part = add_none_part;
+	this->delete_part = delete_none_part;
+	this->destroy_label = destroy_none_label;
+	this->new_label = new_none_label;
+	this->print_parts = print_none_parts;
+	this->read_parts = read_none_parts;
+	this->write_parts = write_none_parts;
+	this->extra_funcs = extra_none_funcs;
+	
+	return EOK;
+}
+
+int add_none_part(label_t *this, tinput_t *in)
+{
+	not_implemented();
+	return EOK;
+}
+
+int delete_none_part(label_t *this, tinput_t *in)
+{
+	not_implemented();
+	return EOK;
+}
+
+int destroy_none_label(label_t *this)
+{
+	return EOK;
+}
+
+int new_none_label(label_t *this)
+{
+	not_implemented();
+	return EOK;
+}
+
+int print_none_parts(label_t *this)
+{
+	not_implemented();
+	return EOK;
+}
+
+int read_none_parts(label_t *this)
+{
+	not_implemented();
+	return EOK;
+}
+
+int write_none_parts(label_t *this)
+{
+	not_implemented();
+	return EOK;
+}
+
+int extra_none_funcs(label_t *this, tinput_t * in)
+{
+	not_implemented();
+	return EOK;
+}
+
+static void not_implemented(void)
+{
+	printf("No format selected.\n");
+}
Index: uspace/app/hdisk/func_none.h
===================================================================
--- uspace/app/hdisk/func_none.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/app/hdisk/func_none.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2012-2013 Dominik Taborsky
+ * 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 hdisk
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __FUNC_NONE_H__
+#define __FUNC_NONE_H__
+
+#include <loc.h>
+#include <tinput.h>
+#include "common.h"
+
+extern int construct_none_label(label_t *);
+extern int add_none_part(label_t *, tinput_t *);
+extern int delete_none_part(label_t *, tinput_t *);
+extern int destroy_none_label(label_t *);
+extern int new_none_label(label_t *);
+extern int print_none_parts(label_t *);
+extern int read_none_parts(label_t *);
+extern int write_none_parts(label_t *);
+extern int extra_none_funcs(label_t *, tinput_t *);
+
+#endif
Index: uspace/app/hdisk/hdisk.c
===================================================================
--- uspace/app/hdisk/hdisk.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/app/hdisk/hdisk.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 2012-2013 Dominik Taborsky
+ * 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 hdisk
+ * @{
+ */
+/** @file
+ */
+
+#include <ipc/bd.h>
+#include <loc.h>
+#include <async.h>
+#include <stdio.h>
+#include <ipc/services.h>
+#include <block.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <str.h>
+#include <libmbr.h>
+#include <libgpt.h>
+#include <tinput.h>
+#include <str_error.h>
+#include "hdisk.h"
+#include "input.h"
+#include "func_gpt.h"
+#include "func_mbr.h"
+#include "func_none.h"
+
+static int interact(void);
+static void print_help(void);
+static void select_label_format(tinput_t *);
+static void construct_label(layouts_t);
+static void free_label(void);
+static int try_read(void);
+static int try_read_mbr(void);
+static int try_read_gpt(void);
+static void set_alignment(tinput_t *);
+
+static label_t label;
+
+int main(int argc, char *argv[])
+{
+	if (argc == 1) {
+		printf("Missing argument. Please specify a device to operate on.\n");
+		return 1;
+	}
+	
+	service_id_t dev_handle;
+	int rc = loc_service_get_id(argv[1], &dev_handle, IPC_FLAG_BLOCKING);
+	if (rc != EOK) {
+		printf("Unknown device. Exiting.\n");
+		return 2;
+	}
+	
+	init_label();
+	label.device = dev_handle;
+	
+	rc = block_init(EXCHANGE_ATOMIC, dev_handle, 512);
+	if (rc != EOK) {
+		printf("Error during libblock init: %d - %s.\n", rc, str_error(rc));
+		return 3;
+	}
+	
+	aoff64_t blocks;
+	rc = block_get_nblocks(dev_handle, &blocks);
+	block_fini(dev_handle);
+	if (rc != EOK) {
+		printf("Error while getting number of blocks: %d - %s.\n",
+		    rc, str_error(rc));
+		return 4;
+	}
+	
+	label.blocks = blocks;
+	
+	rc = try_read_mbr();
+	if (rc == EOK)
+		goto interact;
+	
+	free_label();
+	
+	rc = try_read_gpt();
+	if (rc == EOK)
+		goto interact;
+	
+	printf("No label recognized. Create a new one.\n");
+	construct_label(LYT_NONE);
+	
+interact:
+	return interact();
+}
+
+/** Interact with user */
+int interact(void)
+{
+	tinput_t *in = tinput_new();
+	if (in == NULL) {
+		printf("Failed initing input. Free some memory.\n");
+		return ENOMEM;
+	}
+	tinput_set_prompt(in, "");
+	
+	printf("Welcome to hdisk.\nType 'h' for help.\n");
+	
+	while (true) {
+		printf("# ");
+		int input = getchar();
+		printf("%c\n", input);
+		
+		switch (input) {
+		case 'a':
+			label.add_part(&label, in);
+			break;
+		case 'd':
+			label.delete_part(&label, in);
+			break;
+		case 'e':
+			label.extra_funcs(&label, in);
+			break;
+		case 'f':
+			free_label();
+			select_label_format(in);
+			break;
+		case 'h':
+			print_help();
+			break;
+		case 'l':
+			set_alignment(in);
+			break;
+		case 'n':
+			printf("Discarding label...\n");
+			free_label();
+			label.new_label(&label);
+			break;
+		case 'p':
+			label.print_parts(&label);
+			break;
+		case 'q':
+			putchar('\n');
+			free_label();
+			goto end;
+		case 'r':
+			label.read_parts(&label);
+		case 'w':
+			label.write_parts(&label);
+			break;
+		default:
+			printf("Unknown command. Try 'h' for help.\n");
+			break;
+		}
+	}
+	
+end:
+	tinput_destroy(in);
+	return EOK;
+}
+
+void print_help(void)
+{
+	printf(
+	    "\t 'a' \t\t Add partition.\n"
+	    "\t 'd' \t\t Delete partition.\n"
+	    "\t 'e' \t\t Extra functions (per label format).\n"
+	    "\t 'f' \t\t Switch the format of the partition label.\n"
+	    "\t 'h' \t\t Prints help. See help for more.\n"
+	    "\t 'l' \t\t Set alignment.\n"
+	    "\t 'n' \t\t Create new label (discarding the old one).\n"
+	    "\t 'p' \t\t Prints label contents.\n"
+	    "\t 'q' \t\t Quit.\n"
+	    "\t 'r' \t\t Read label from disk.\n"
+	    "\t 'w' \t\t Write label to disk.\n");
+}
+
+void select_label_format(tinput_t *in)
+{
+	printf("Available formats are: \n"
+	    "1) MBR\n"
+	    "2) GPT\n");
+	
+	uint8_t val = get_input_uint8(in);
+	switch (val) {
+	case 1:
+		construct_label(LYT_MBR);
+		break;
+	case 2:
+		construct_label(LYT_GPT);
+		break;
+	default:
+		construct_label(LYT_NONE);
+		break;
+	}
+}
+
+void construct_label(layouts_t layout)
+{
+	switch (layout) {
+	case LYT_MBR:
+		label.layout = LYT_MBR;
+		construct_mbr_label(&label);
+		break;
+	case LYT_GPT:
+		label.layout = LYT_GPT;
+		construct_gpt_label(&label);
+		break;
+	default:
+		label.layout = LYT_NONE;
+		construct_none_label(&label);
+		break;
+	}
+}
+
+void free_label(void)
+{
+	label.destroy_label(&label);
+}
+
+int try_read(void)
+{
+	return label.read_parts(&label);
+}
+
+int try_read_mbr(void)
+{
+	construct_label(LYT_MBR);
+	return try_read();
+}
+
+int try_read_gpt(void)
+{
+	construct_label(LYT_GPT);
+	return try_read();
+}
+
+void set_alignment(tinput_t *in)
+{
+	printf("Set alignment to sectors: ");
+	label.alignment = get_input_uint32(in);
+	printf("Alignment set to %u sectors.\n", label.alignment);
+}
Index: uspace/app/hdisk/hdisk.h
===================================================================
--- uspace/app/hdisk/hdisk.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/app/hdisk/hdisk.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2012-2013 Dominik Taborsky
+ * 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 hdisk
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __HDISK_H__
+#define __HDISK_H__
+
+#include "common.h"
+
+#define init_label() \
+	label.layout = LYT_NONE
+
+#endif
Index: uspace/app/hdisk/input.c
===================================================================
--- uspace/app/hdisk/input.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/app/hdisk/input.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2012-2013 Dominik Taborsky
+ * 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 hdisk
+ * @{
+ */
+/** @file
+ */
+
+#include <str.h>
+#include <errno.h>
+#include <stdlib.h>
+#include "input.h"
+
+typedef int (*conv_f)(const char *, char **, unsigned int, bool, void *);
+
+static int convert(tinput_t *, conv_f, void *);
+
+int get_input_line(tinput_t *in, char **str)
+{
+	int rc = tinput_read(in, str);
+	if (rc == ENOENT)
+		return EINTR;
+	
+	if (rc != EOK)
+		return rc;
+	
+	/* Check for empty input. */
+	if (str_cmp(*str, "") == 0) {
+		free(*str);
+		*str = NULL;
+		return EINVAL;
+	}
+	
+	return EOK;
+}
+
+uint8_t get_input_uint8(tinput_t *in)
+{
+	uint32_t val;
+	int rc = convert(in, (conv_f) str_uint8_t, &val);
+	if (rc != EOK) {
+		errno = rc;
+		return 0;
+	}
+	
+	errno = EOK;
+	return val;
+}
+
+uint32_t get_input_uint32(tinput_t *in)
+{
+	uint32_t val;
+	int rc = convert(in, (conv_f) str_uint32_t, &val);
+	if (rc != EOK) {
+		errno = rc;
+		return 0;
+	}
+	
+	errno = EOK;
+	return val;
+}
+
+uint64_t get_input_uint64(tinput_t *in)
+{
+	uint64_t val;
+	int rc = convert(in, (conv_f) str_uint64_t, &val);
+	if (rc != EOK) {
+		errno = rc;
+		return 0;
+	}
+	
+	errno = EOK;
+	return val;
+}
+
+size_t get_input_size_t(tinput_t *in)
+{
+	size_t val;
+	int rc = convert(in, (conv_f) str_size_t, &val);
+	if (rc != EOK) {
+		errno = rc;
+		return 0;
+	}
+	
+	errno = EOK;
+	return val;
+}
+
+static int convert(tinput_t *in, conv_f str_f, void *val)
+{
+	char *str;
+	int rc = get_input_line(in, &str);
+	if (rc != EOK) {
+		printf("Error reading input.\n");
+		return rc;
+	}
+	
+	rc = str_f(str, NULL, 10, true, val);
+	if (rc != EOK)
+		printf("Invalid value.\n");
+	
+	free(str);
+	return rc;
+}
Index: uspace/app/hdisk/input.h
===================================================================
--- uspace/app/hdisk/input.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/app/hdisk/input.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2012-2013 Dominik Taborsky
+ * 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 hdisk
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __INPUT_H__
+#define __INPUT_H__
+
+#include <tinput.h>
+
+extern int get_input_line(tinput_t *, char **);
+extern uint8_t get_input_uint8(tinput_t *);
+extern uint32_t get_input_uint32(tinput_t *);
+extern uint64_t get_input_uint64(tinput_t *);
+extern size_t get_input_size_t(tinput_t *);
+
+#endif
Index: uspace/app/init/init.c
===================================================================
--- uspace/app/init/init.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/app/init/init.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -336,4 +336,5 @@
 		srv_start("/srv/tmpfs");
 	
+	srv_start("/srv/klog");
 	srv_start("/srv/locfs");
 	srv_start("/srv/taskmon");
Index: uspace/app/kio/Makefile
===================================================================
--- uspace/app/kio/Makefile	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/app/kio/Makefile	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+USPACE_PREFIX = ../..
+LIBS = $(LIBCLUI_PREFIX)/libclui.a
+EXTRA_CFLAGS = -I$(LIBCLUI_PREFIX)
+BINARY = kio
+
+SOURCES = \
+	kio.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/kio/kio.c
===================================================================
--- uspace/app/kio/kio.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/app/kio/kio.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,261 @@
+/*
+ * Copyright (c) 2006 Ondrej Palkovsky
+ * 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 kio KIO
+ * @brief HelenOS KIO
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <stdio.h>
+#include <async.h>
+#include <as.h>
+#include <ddi.h>
+#include <event.h>
+#include <errno.h>
+#include <str_error.h>
+#include <io/kio.h>
+#include <sysinfo.h>
+#include <malloc.h>
+#include <fibril_synch.h>
+#include <adt/list.h>
+#include <adt/prodcons.h>
+#include <tinput.h>
+
+#define NAME       "kio"
+#define LOG_FNAME  "/log/kio"
+
+/* Producer/consumer buffers */
+typedef struct {
+	link_t link;
+	size_t length;
+	wchar_t *data;
+} item_t;
+
+static prodcons_t pc;
+
+/* Pointer to kio area */
+static wchar_t *kio;
+static size_t kio_length;
+
+/* Notification mutex */
+static FIBRIL_MUTEX_INITIALIZE(mtx);
+
+/** Klog producer
+ *
+ * Copies the contents of a character buffer to local
+ * producer/consumer queue.
+ *
+ * @param length Number of characters to copy.
+ * @param data   Pointer to the kernel kio buffer.
+ *
+ */
+static void producer(size_t length, wchar_t *data)
+{
+	item_t *item = (item_t *) malloc(sizeof(item_t));
+	if (item == NULL)
+		return;
+	
+	size_t sz = sizeof(wchar_t) * length;
+	wchar_t *buf = (wchar_t *) malloc(sz);
+	if (data == NULL) {
+		free(item);
+		return;
+	}
+	
+	memcpy(buf, data, sz);
+	
+	link_initialize(&item->link);
+	item->length = length;
+	item->data = buf;
+	prodcons_produce(&pc, &item->link);
+}
+
+/** Klog consumer
+ *
+ * Waits in an infinite loop for the character data created by
+ * the producer and outputs them to stdout and optionally into
+ * a file.
+ *
+ * @param data Unused.
+ *
+ * @return Always EOK (unreachable).
+ *
+ */
+static int consumer(void *data)
+{
+	FILE *log = fopen(LOG_FNAME, "a");
+	if (log == NULL)
+		printf("%s: Unable to create log file %s (%s)\n", NAME, LOG_FNAME,
+		    str_error(errno));
+	
+	while (true) {
+		link_t *link = prodcons_consume(&pc);
+		item_t *item = list_get_instance(link, item_t, link);
+		
+		for (size_t i = 0; i < item->length; i++)
+			putchar(item->data[i]);
+		
+		if (log != NULL) {
+			for (size_t i = 0; i < item->length; i++)
+				fputc(item->data[i], log);
+			
+			fflush(log);
+			fsync(fileno(log));
+		}
+		
+		free(item->data);
+		free(item);
+	}
+	
+	fclose(log);
+	return EOK;
+}
+
+/** Kernel notification handler
+ *
+ * Receives kernel kio notifications.
+ *
+ * @param callid IPC call ID
+ * @param call   IPC call structure
+ * @param arg    Local argument
+ *
+ */
+static void notification_received(ipc_callid_t callid, ipc_call_t *call)
+{
+	/*
+	 * Make sure we process only a single notification
+	 * at any time to limit the chance of the consumer
+	 * starving.
+	 *
+	 * Note: Usually the automatic masking of the kio
+	 * notifications on the kernel side does the trick
+	 * of limiting the chance of accidentally copying
+	 * the same data multiple times. However, due to
+	 * the non-blocking architecture of kio notifications,
+	 * this possibility cannot be generally avoided.
+	 */
+	
+	fibril_mutex_lock(&mtx);
+	
+	size_t kio_start = (size_t) IPC_GET_ARG1(*call);
+	size_t kio_len = (size_t) IPC_GET_ARG2(*call);
+	size_t kio_stored = (size_t) IPC_GET_ARG3(*call);
+	
+	size_t offset = (kio_start + kio_len - kio_stored) % kio_length;
+	
+	/* Copy data from the ring buffer */
+	if (offset + kio_stored >= kio_length) {
+		size_t split = kio_length - offset;
+		
+		producer(split, kio + offset);
+		producer(kio_stored - split, kio);
+	} else
+		producer(kio_stored, kio + offset);
+	
+	event_unmask(EVENT_KIO);
+	fibril_mutex_unlock(&mtx);
+}
+
+int main(int argc, char *argv[])
+{
+	size_t pages;
+	int rc = sysinfo_get_value("kio.pages", &pages);
+	if (rc != EOK) {
+		fprintf(stderr, "%s: Unable to get number of kio pages\n",
+		    NAME);
+		return rc;
+	}
+	
+	uintptr_t faddr;
+	rc = sysinfo_get_value("kio.faddr", &faddr);
+	if (rc != EOK) {
+		fprintf(stderr, "%s: Unable to get kio physical address\n",
+		    NAME);
+		return rc;
+	}
+	
+	size_t size = pages * PAGE_SIZE;
+	kio_length = size / sizeof(wchar_t);
+	
+	rc = physmem_map(faddr, pages, AS_AREA_READ | AS_AREA_CACHEABLE,
+	    (void *) &kio);
+	if (rc != EOK) {
+		fprintf(stderr, "%s: Unable to map kio\n", NAME);
+		return rc;
+	}
+	
+	prodcons_initialize(&pc);
+	async_set_interrupt_received(notification_received);
+	rc = event_subscribe(EVENT_KIO, 0);
+	if (rc != EOK) {
+		fprintf(stderr, "%s: Unable to register kio notifications\n",
+		    NAME);
+		return rc;
+	}
+	
+	fid_t fid = fibril_create(consumer, NULL);
+	if (!fid) {
+		fprintf(stderr, "%s: Unable to create consumer fibril\n",
+		    NAME);
+		return ENOMEM;
+	}
+	
+	tinput_t *input = tinput_new();
+	if (!input) {
+		fprintf(stderr, "%s: Could not create input\n", NAME);
+		return ENOMEM;
+	}	
+
+	fibril_add_ready(fid);
+	event_unmask(EVENT_KIO);
+	kio_update();
+	
+	tinput_set_prompt(input, "kio> ");
+
+	char *str;
+	while ((rc = tinput_read(input, &str)) == EOK) {
+		if (str_cmp(str, "") == 0) {
+			free(str);
+			continue;
+		}
+
+		kio_command(str, str_size(str));
+		free(str);
+	}
+ 
+	if (rc == ENOENT)
+		rc = EOK;	
+
+	return EOK;
+}
+
+/** @}
+ */
Index: pace/app/klog/Makefile
===================================================================
--- uspace/app/klog/Makefile	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,38 +1,0 @@
-#
-# Copyright (c) 2005 Martin Decky
-# Copyright (c) 2007 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.
-#
-
-USPACE_PREFIX = ../..
-LIBS = $(LIBCLUI_PREFIX)/libclui.a
-EXTRA_CFLAGS = -I$(LIBCLUI_PREFIX)
-BINARY = klog
-
-SOURCES = \
-	klog.c
-
-include $(USPACE_PREFIX)/Makefile.common
Index: pace/app/klog/klog.c
===================================================================
--- uspace/app/klog/klog.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,261 +1,0 @@
-/*
- * Copyright (c) 2006 Ondrej Palkovsky
- * 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 klog KLog
- * @brief HelenOS KLog
- * @{
- */
-/**
- * @file
- */
-
-#include <stdio.h>
-#include <async.h>
-#include <as.h>
-#include <ddi.h>
-#include <event.h>
-#include <errno.h>
-#include <str_error.h>
-#include <io/klog.h>
-#include <sysinfo.h>
-#include <malloc.h>
-#include <fibril_synch.h>
-#include <adt/list.h>
-#include <adt/prodcons.h>
-#include <tinput.h>
-
-#define NAME       "klog"
-#define LOG_FNAME  "/log/klog"
-
-/* Producer/consumer buffers */
-typedef struct {
-	link_t link;
-	size_t length;
-	wchar_t *data;
-} item_t;
-
-static prodcons_t pc;
-
-/* Pointer to klog area */
-static wchar_t *klog;
-static size_t klog_length;
-
-/* Notification mutex */
-static FIBRIL_MUTEX_INITIALIZE(mtx);
-
-/** Klog producer
- *
- * Copies the contents of a character buffer to local
- * producer/consumer queue.
- *
- * @param length Number of characters to copy.
- * @param data   Pointer to the kernel klog buffer.
- *
- */
-static void producer(size_t length, wchar_t *data)
-{
-	item_t *item = (item_t *) malloc(sizeof(item_t));
-	if (item == NULL)
-		return;
-	
-	size_t sz = sizeof(wchar_t) * length;
-	wchar_t *buf = (wchar_t *) malloc(sz);
-	if (data == NULL) {
-		free(item);
-		return;
-	}
-	
-	memcpy(buf, data, sz);
-	
-	link_initialize(&item->link);
-	item->length = length;
-	item->data = buf;
-	prodcons_produce(&pc, &item->link);
-}
-
-/** Klog consumer
- *
- * Waits in an infinite loop for the character data created by
- * the producer and outputs them to stdout and optionally into
- * a file.
- *
- * @param data Unused.
- *
- * @return Always EOK (unreachable).
- *
- */
-static int consumer(void *data)
-{
-	FILE *log = fopen(LOG_FNAME, "a");
-	if (log == NULL)
-		printf("%s: Unable to create log file %s (%s)\n", NAME, LOG_FNAME,
-		    str_error(errno));
-	
-	while (true) {
-		link_t *link = prodcons_consume(&pc);
-		item_t *item = list_get_instance(link, item_t, link);
-		
-		for (size_t i = 0; i < item->length; i++)
-			putchar(item->data[i]);
-		
-		if (log != NULL) {
-			for (size_t i = 0; i < item->length; i++)
-				fputc(item->data[i], log);
-			
-			fflush(log);
-			fsync(fileno(log));
-		}
-		
-		free(item->data);
-		free(item);
-	}
-	
-	fclose(log);
-	return EOK;
-}
-
-/** Kernel notification handler
- *
- * Receives kernel klog notifications.
- *
- * @param callid IPC call ID
- * @param call   IPC call structure
- * @param arg    Local argument
- *
- */
-static void notification_received(ipc_callid_t callid, ipc_call_t *call)
-{
-	/*
-	 * Make sure we process only a single notification
-	 * at any time to limit the chance of the consumer
-	 * starving.
-	 *
-	 * Note: Usually the automatic masking of the klog
-	 * notifications on the kernel side does the trick
-	 * of limiting the chance of accidentally copying
-	 * the same data multiple times. However, due to
-	 * the non-blocking architecture of klog notifications,
-	 * this possibility cannot be generally avoided.
-	 */
-	
-	fibril_mutex_lock(&mtx);
-	
-	size_t klog_start = (size_t) IPC_GET_ARG1(*call);
-	size_t klog_len = (size_t) IPC_GET_ARG2(*call);
-	size_t klog_stored = (size_t) IPC_GET_ARG3(*call);
-	
-	size_t offset = (klog_start + klog_len - klog_stored) % klog_length;
-	
-	/* Copy data from the ring buffer */
-	if (offset + klog_stored >= klog_length) {
-		size_t split = klog_length - offset;
-		
-		producer(split, klog + offset);
-		producer(klog_stored - split, klog);
-	} else
-		producer(klog_stored, klog + offset);
-	
-	event_unmask(EVENT_KLOG);
-	fibril_mutex_unlock(&mtx);
-}
-
-int main(int argc, char *argv[])
-{
-	size_t pages;
-	int rc = sysinfo_get_value("klog.pages", &pages);
-	if (rc != EOK) {
-		fprintf(stderr, "%s: Unable to get number of klog pages\n",
-		    NAME);
-		return rc;
-	}
-	
-	uintptr_t faddr;
-	rc = sysinfo_get_value("klog.faddr", &faddr);
-	if (rc != EOK) {
-		fprintf(stderr, "%s: Unable to get klog physical address\n",
-		    NAME);
-		return rc;
-	}
-	
-	size_t size = pages * PAGE_SIZE;
-	klog_length = size / sizeof(wchar_t);
-	
-	rc = physmem_map(faddr, pages, AS_AREA_READ | AS_AREA_CACHEABLE,
-	    (void *) &klog);
-	if (rc != EOK) {
-		fprintf(stderr, "%s: Unable to map klog\n", NAME);
-		return rc;
-	}
-	
-	prodcons_initialize(&pc);
-	async_set_interrupt_received(notification_received);
-	rc = event_subscribe(EVENT_KLOG, 0);
-	if (rc != EOK) {
-		fprintf(stderr, "%s: Unable to register klog notifications\n",
-		    NAME);
-		return rc;
-	}
-	
-	fid_t fid = fibril_create(consumer, NULL);
-	if (!fid) {
-		fprintf(stderr, "%s: Unable to create consumer fibril\n",
-		    NAME);
-		return ENOMEM;
-	}
-	
-	tinput_t *input = tinput_new();
-	if (!input) {
-		fprintf(stderr, "%s: Could not create input\n", NAME);
-		return ENOMEM;
-	}	
-
-	fibril_add_ready(fid);
-	event_unmask(EVENT_KLOG);
-	klog_update();
-	
-	tinput_set_prompt(input, "klog> ");
-
-	char *str;
-	while ((rc = tinput_read(input, &str)) == EOK) {
-		if (str_cmp(str, "") == 0) {
-			free(str);
-			continue;
-		}
-
-		klog_command(str, str_size(str));
-		free(str);
-	}
- 
-	if (rc == ENOENT)
-		rc = EOK;	
-
-	return EOK;
-}
-
-/** @}
- */
Index: uspace/app/mkbd/Makefile
===================================================================
--- uspace/app/mkbd/Makefile	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/app/mkbd/Makefile	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -34,5 +34,6 @@
 	$(LIBUSBDEV_PREFIX)/libusbdev.a \
 	$(LIBUSB_PREFIX)/libusb.a \
-	$(LIBDRV_PREFIX)/libdrv.a 
+	$(LIBDRV_PREFIX)/libdrv.a
+
 EXTRA_CFLAGS = \
 	-I$(LIBUSB_PREFIX)/include \
Index: uspace/app/mkbd/main.c
===================================================================
--- uspace/app/mkbd/main.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/app/mkbd/main.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -45,5 +45,5 @@
 #include <loc.h>
 #include <usb/dev/hub.h>
-#include <usb/hid/iface.h>
+#include <usbhid_iface.h>
 #include <usb/dev/pipes.h>
 #include <async.h>
Index: uspace/app/sportdmp/Makefile
===================================================================
--- uspace/app/sportdmp/Makefile	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/app/sportdmp/Makefile	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -28,6 +28,6 @@
 
 USPACE_PREFIX = ../..
-#LIBS = 
-#EXTRA_CFLAGS = 
+LIBS = $(LIBDRV_PREFIX)/libdrv.a
+EXTRA_CFLAGS = -I$(LIBDRV_PREFIX)/include
 BINARY = sportdmp
 
Index: uspace/app/sportdmp/sportdmp.c
===================================================================
--- uspace/app/sportdmp/sportdmp.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/app/sportdmp/sportdmp.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -27,5 +27,5 @@
  */
 
-#include <device/char_dev.h>
+#include <char_dev_iface.h>
 #include <errno.h>
 #include <ipc/serial_ctl.h>
Index: uspace/app/tester/Makefile
===================================================================
--- uspace/app/tester/Makefile	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/app/tester/Makefile	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -29,6 +29,14 @@
 
 USPACE_PREFIX = ../..
-LIBS = $(LIBBLOCK_PREFIX)/libblock.a $(LIBSOFTFLOAT_PREFIX)/libsoftfloat.a
-EXTRA_CFLAGS = -I$(LIBBLOCK_PREFIX) -I$(LIBSOFTFLOAT_PREFIX)
+LIBS = \
+	$(LIBBLOCK_PREFIX)/libblock.a \
+	$(LIBSOFTFLOAT_PREFIX)/libsoftfloat.a \
+	$(LIBDRV_PREFIX)/libdrv.a
+
+EXTRA_CFLAGS = \
+	-I$(LIBBLOCK_PREFIX) \
+	-I$(LIBSOFTFLOAT_PREFIX) \
+	-I$(LIBDRV_PREFIX)/include
+
 BINARY = tester
 
@@ -37,4 +45,5 @@
 	util.c \
 	thread/thread1.c \
+	thread/setjmp1.c \
 	print/print1.c \
 	print/print2.c \
Index: uspace/app/tester/hw/misc/virtchar1.c
===================================================================
--- uspace/app/tester/hw/misc/virtchar1.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/app/tester/hw/misc/virtchar1.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -40,5 +40,5 @@
 #include <sys/types.h>
 #include <async.h>
-#include <device/char_dev.h>
+#include <char_dev_iface.h>
 #include <str.h>
 #include <vfs/vfs.h>
Index: uspace/app/tester/hw/serial/serial1.c
===================================================================
--- uspace/app/tester/hw/serial/serial1.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/app/tester/hw/serial/serial1.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -43,5 +43,5 @@
 #include <ipc/services.h>
 #include <loc.h>
-#include <device/char_dev.h>
+#include <char_dev_iface.h>
 #include <str.h>
 #include <ipc/serial_ctl.h>
Index: uspace/app/tester/tester.c
===================================================================
--- uspace/app/tester/tester.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/app/tester/tester.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -48,4 +48,5 @@
 test_t tests[] = {
 #include "thread/thread1.def"
+#include "thread/setjmp1.def"
 #include "print/print1.def"
 #include "print/print2.def"
Index: uspace/app/tester/tester.h
===================================================================
--- uspace/app/tester/tester.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/app/tester/tester.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -39,4 +39,5 @@
 #include <stdbool.h>
 #include <stacktrace.h>
+#include <stdio.h>
 
 #define IPC_TEST_SERVICE  10240
@@ -80,4 +81,5 @@
 
 extern const char *test_thread1(void);
+extern const char *test_setjmp1(void);
 extern const char *test_print1(void);
 extern const char *test_print2(void);
Index: uspace/app/tester/thread/setjmp1.c
===================================================================
--- uspace/app/tester/thread/setjmp1.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/app/tester/thread/setjmp1.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2013 Vojtech Horky
+ * 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.
+ */
+
+#include <setjmp.h>
+#include <stdlib.h>
+#include "../tester.h"
+
+static jmp_buf jmp_env;
+static int counter;
+
+static void do_the_long_jump(void) {
+	TPRINTF("Will do a long jump back to test_it().\n");
+	longjmp(jmp_env, 1);
+}
+
+static const char *test_it(void) {
+	int second_round = setjmp(jmp_env);
+	counter++;
+	TPRINTF("Just after setjmp(), counter is %d.\n", counter);
+	if (second_round) {
+		if (counter != 2) {
+			return "setjmp() have not returned twice";
+		} else {
+			return NULL;
+		}
+	}
+
+	if (counter != 1) {
+		return "Shall not reach here more than once";
+	}
+
+	do_the_long_jump();
+
+	return "Survived a long jump";
+}
+
+const char *test_setjmp1(void)
+{
+	counter = 0;
+	
+	const char *err_msg = test_it();
+	
+	return err_msg;
+}
Index: uspace/app/tester/thread/setjmp1.def
===================================================================
--- uspace/app/tester/thread/setjmp1.def	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/app/tester/thread/setjmp1.def	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,6 @@
+{
+	"setjmp1",
+	"Long jump test",
+	&test_setjmp1,
+	true
+},
Index: uspace/app/trace/syscalls.c
===================================================================
--- uspace/app/trace/syscalls.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/app/trace/syscalls.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -38,5 +38,5 @@
 
 const sc_desc_t syscall_desc[] = {
-    [SYS_KLOG] ={ "klog",				3,	V_INT_ERRNO },
+    [SYS_KIO] ={ "kio",					3,	V_INT_ERRNO },
     [SYS_TLS_SET] = { "tls_set",			1,	V_ERRNO },
 
Index: uspace/app/untar/Makefile
===================================================================
--- uspace/app/untar/Makefile	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/app/untar/Makefile	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2013 Vojtech Horky
+# 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.
+#
+
+USPACE_PREFIX = ../..
+BINARY = untar
+
+SOURCES = \
+	main.c \
+	tar.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/untar/main.c
===================================================================
--- uspace/app/untar/main.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/app/untar/main.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2013 Vojtech Horky
+ * 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 untar
+ * @{
+ */
+/** @file
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <str_error.h>
+#include "tar.h"
+
+static size_t get_block_count(size_t bytes) {
+	return (bytes + TAR_BLOCK_SIZE - 1) / TAR_BLOCK_SIZE;
+}
+
+static int skip_blocks(FILE *tarfile, size_t valid_data_size)
+{
+	size_t blocks_to_read = get_block_count(valid_data_size);
+	while (blocks_to_read > 0) {
+		uint8_t block[TAR_BLOCK_SIZE];
+		size_t actually_read = fread(block, TAR_BLOCK_SIZE, 1, tarfile);
+		if (actually_read != 1) {
+			return errno;
+		}
+		blocks_to_read--;
+	}
+	return EOK;
+}
+
+static int handle_normal_file(const tar_header_t *header, FILE *tarfile)
+{
+	// FIXME: create the directory first
+
+	FILE *file = fopen(header->filename, "wb");
+	if (file == NULL) {
+		fprintf(stderr, "Failed to create %s: %s.\n", header->filename,
+		    str_error(errno));
+		return errno;
+	}
+
+	int rc = EOK;
+	size_t bytes_remaining = header->size;
+	size_t blocks = get_block_count(bytes_remaining);
+	while (blocks > 0) {
+		uint8_t block[TAR_BLOCK_SIZE];
+		size_t actually_read = fread(block, 1, TAR_BLOCK_SIZE, tarfile);
+		if (actually_read != TAR_BLOCK_SIZE) {
+			rc = errno;
+			fprintf(stderr, "Failed to read block for %s: %s.\n",
+			    header->filename, str_error(rc));
+			break;
+		}
+		size_t to_write = TAR_BLOCK_SIZE;
+		if (bytes_remaining < TAR_BLOCK_SIZE) {
+			to_write = bytes_remaining;
+		}
+		size_t actually_written = fwrite(block, 1, to_write, file);
+		if (actually_written != to_write) {
+			rc = errno;
+			fprintf(stderr, "Failed to write to %s: %s.\n",
+			    header->filename, str_error(rc));
+			break;
+		}
+		blocks--;
+		bytes_remaining -= TAR_BLOCK_SIZE;
+	}
+
+	fclose(file);
+
+	return rc;
+}
+
+static int handle_directory(const tar_header_t *header, FILE *tarfile)
+{
+	int rc = mkdir(header->filename, 0755);
+	if ((rc == EEXIST) || (rc == EEXISTS)) {
+		// printf("Note: directory %s already exists.\n", header->filename);
+		rc = EOK;
+	}
+	if (rc != EOK) {
+		fprintf(stderr, "Failed to create directory %s: %s.\n",
+		    header->filename, str_error(rc));
+		return rc;
+	}
+
+	return skip_blocks(tarfile, header->size);
+}
+
+int main(int argc, char *argv[])
+{
+	if (argc != 2) {
+		fprintf(stderr, "Usage: %s tar-file\n", argv[0]);
+		return 1;
+	}
+
+	const char *filename = argv[1];
+
+	FILE *tarfile = fopen(filename, "rb");
+	if (tarfile == NULL) {
+		fprintf(stderr, "Failed to open `%s': %s.\n", filename, str_error(errno));
+		return 2;
+	}
+
+	while (true) {
+		size_t header_ok;
+		tar_header_raw_t header_raw;
+		tar_header_t header;
+		header_ok = fread(&header_raw, sizeof(header_raw), 1, tarfile);
+		if (header_ok != 1) {
+			break;
+		}
+		int rc = tar_header_parse(&header, &header_raw);
+		if (rc == EEMPTY) {
+			continue;
+		}
+		if (rc != EOK) {
+			fprintf(stderr, "Failed parsing TAR header: %s.\n", str_error(rc));
+			break;
+		}
+
+		//printf(" ==> %s (%zuB, type %s)\n", header.filename,
+		//    header.size, tar_type_str(header.type));
+
+		switch (header.type) {
+		case TAR_TYPE_DIRECTORY:
+			rc = handle_directory(&header, tarfile);
+			break;
+		case TAR_TYPE_NORMAL:
+			rc = handle_normal_file(&header, tarfile);
+			break;
+		default:
+			rc = skip_blocks(tarfile, header.size);
+			break;
+		}
+		if (rc != EOK) {
+			break;
+		}
+
+	}
+
+	fclose(tarfile);
+
+	return 0;
+}
+
+/** @}
+ */
Index: uspace/app/untar/tar.c
===================================================================
--- uspace/app/untar/tar.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/app/untar/tar.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2013 Vojtech Horky
+ * 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 untar
+ * @{
+ */
+/** @file
+ */
+
+#include <str.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <assert.h>
+
+#include "tar.h"
+
+tar_type_t tar_type_parse(const char type) {
+	switch (type) {
+	case '0':
+	case 0:
+		return TAR_TYPE_NORMAL;
+	case '5':
+		return TAR_TYPE_DIRECTORY;
+	default:
+		return TAR_TYPE_UNKNOWN;
+	}
+}
+
+const char *tar_type_str(tar_type_t type) {
+	switch (type) {
+	case TAR_TYPE_UNKNOWN:
+		return "unknown";
+	case TAR_TYPE_NORMAL:
+		return "normal";
+	case TAR_TYPE_DIRECTORY:
+		return "directory";
+	default:
+		assert(false && "unexpected tar_type_t enum value");
+		return "?";
+	}
+}
+
+int tar_header_parse(tar_header_t *parsed, const tar_header_raw_t *raw)
+{
+	int rc;
+
+	if (str_length(raw->filename) == 0) {
+		return EEMPTY;
+	}
+
+	size_t size;
+	rc = str_size_t(raw->size, NULL, 8, true, &size);
+	if (rc != EOK) {
+		return rc;
+	}
+	parsed->size = size;
+
+	str_cpy(parsed->filename, 100, raw->filename);
+
+	parsed->type = tar_type_parse(raw->type);
+
+	return EOK;
+}
+
+/** @}
+ */
Index: uspace/app/untar/tar.h
===================================================================
--- uspace/app/untar/tar.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/app/untar/tar.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2013 Vojtech Horky
+ * 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 untar
+ * @{
+ */
+/** @file
+ */
+#ifndef TAR_H_GUARD
+#define TAR_H_GUARD
+
+#define TAR_BLOCK_SIZE 512
+
+typedef struct tar_header_raw {
+	char filename[100];
+	char permissions[8];
+	char owner[8];
+	char group[8];
+	char size[12];
+	char modification_time[12];
+	char checksum[8];
+	char type;
+	char name[100];
+	char ustar_magic[6];
+	char ustar_version[2];
+	char ustar_owner_name[32];
+	char ustar_group_name[32];
+	char ustar_device_major[8];
+	char ustar_device_minor[8];
+	char ustar_prefix[155];
+	char ignored[12];
+} tar_header_raw_t;
+
+typedef enum tar_type {
+	TAR_TYPE_UNKNOWN,
+	TAR_TYPE_NORMAL,
+	TAR_TYPE_DIRECTORY
+} tar_type_t;
+
+typedef struct tar_header {
+	char filename[100];
+	size_t size;
+	tar_type_t type;
+} tar_header_t;
+
+
+extern int tar_header_parse(tar_header_t *, const tar_header_raw_t *);
+extern tar_type_t tar_type_parse(const char);
+extern const char *tar_type_str(tar_type_t);
+
+#endif
+
+/** @}
+ */
Index: uspace/app/vdemo/vdemo.c
===================================================================
--- uspace/app/vdemo/vdemo.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/app/vdemo/vdemo.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -110,5 +110,5 @@
 {
 	if (argc >= 2) {
-		window_t *main_window = window_open(argv[1], true, true, "vdemo", 0, 0);
+		window_t *main_window = window_open(argv[1], true, true, "vdemo");
 		if (!main_window) {
 			printf("Cannot open main window.\n");
@@ -117,12 +117,18 @@
 
 		pixel_t grd_bg = PIXEL(255, 240, 240, 240);
-		pixel_t btn_bg = PIXEL(255, 0, 0, 0);
-		pixel_t btn_fg = PIXEL(255, 240, 240, 240);
+		
+		pixel_t btn_bg = PIXEL(255, 240, 240, 240);
+		pixel_t btn_fg = PIXEL(255, 186, 186, 186);
+		pixel_t btn_text = PIXEL(255, 0, 0, 0);
+		
 		pixel_t lbl_bg = PIXEL(255, 240, 240, 240);
-		pixel_t lbl_fg = PIXEL(255, 0, 0, 0);
+		pixel_t lbl_text = PIXEL(255, 0, 0, 0);
 
-		my_label_t *lbl_action = create_my_label(NULL, "Hello there!", 16, lbl_bg, lbl_fg);
-		button_t *btn_confirm = create_button(NULL, "Confirm", 16, btn_bg, btn_fg);
-		button_t *btn_cancel = create_button(NULL, "Cancel", 16, btn_bg, btn_fg);
+		my_label_t *lbl_action = create_my_label(NULL, "Hello there!", 16,
+		    lbl_bg, lbl_text);
+		button_t *btn_confirm = create_button(NULL, "Confirm", 16, btn_bg,
+		    btn_fg, btn_text);
+		button_t *btn_cancel = create_button(NULL, "Cancel", 16, btn_bg,
+		    btn_fg, btn_text);
 		grid_t *grid = create_grid(window_root(main_window), 2, 2, grd_bg);
 		if (!lbl_action || !btn_confirm || !btn_cancel || !grid) {
@@ -144,5 +150,6 @@
 		grid->add(grid, &btn_confirm->widget, 0, 1, 1, 1);
 		grid->add(grid, &btn_cancel->widget, 1, 1, 1, 1);
-		window_resize(main_window, 200, 76);
+		window_resize(main_window, 0, 0, 200, 76,
+		    WINDOW_PLACEMENT_CENTER);
 
 		window_exec(main_window);
Index: uspace/app/viewer/viewer.c
===================================================================
--- uspace/app/viewer/viewer.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/app/viewer/viewer.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -166,5 +166,5 @@
 	}
 	
-	main_window = window_open(argv[1], true, false, "viewer", 0, 0);
+	main_window = window_open(argv[1], true, false, "viewer");
 	if (!main_window) {
 		printf("Cannot open main window.\n");
@@ -192,5 +192,6 @@
 	}
 	
-	window_resize(main_window, WINDOW_WIDTH, WINDOW_HEIGHT);
+	window_resize(main_window, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT,
+	    WINDOW_PLACEMENT_ABSOLUTE);
 	window_exec(main_window);
 	
Index: uspace/app/vlaunch/vlaunch.c
===================================================================
--- uspace/app/vlaunch/vlaunch.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/app/vlaunch/vlaunch.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -115,5 +115,5 @@
 	
 	winreg = argv[1];
-	window_t *main_window = window_open(argv[1], true, true, "vlaunch", 0, 0);
+	window_t *main_window = window_open(argv[1], true, true, "vlaunch");
 	if (!main_window) {
 		printf("Cannot open main window.\n");
@@ -122,19 +122,22 @@
 	
 	pixel_t grd_bg = PIXEL(255, 255, 255, 255);
-	pixel_t btn_bg = PIXEL(255, 0, 0, 0);
-	pixel_t btn_fg = PIXEL(255, 240, 240, 240);
+	
+	pixel_t btn_bg = PIXEL(255, 255, 255, 255);
+	pixel_t btn_fg = PIXEL(255, 186, 186, 186);
+	pixel_t btn_text = PIXEL(255, 0, 0, 0);
+	
 	pixel_t lbl_bg = PIXEL(255, 255, 255, 255);
-	pixel_t lbl_fg = PIXEL(255, 0, 0, 0);
+	pixel_t lbl_text = PIXEL(255, 0, 0, 0);
 	
 	canvas_t *logo_canvas = create_canvas(NULL, LOGO_WIDTH, LOGO_HEIGHT,
 	    logo);
 	label_t *lbl_caption = create_label(NULL, "Launch application:", 16,
-	    lbl_bg, lbl_fg);
+	    lbl_bg, lbl_text);
 	button_t *btn_vterm = create_button(NULL, "vterm", 16, btn_bg,
-	    btn_fg);
+	    btn_fg, btn_text);
 	button_t *btn_vdemo = create_button(NULL, "vdemo", 16, btn_bg,
-	    btn_fg);
+	    btn_fg, btn_text);
 	button_t *btn_vlaunch = create_button(NULL, "vlaunch", 16, btn_bg,
-	    btn_fg);
+	    btn_fg, btn_text);
 	grid_t *grid = create_grid(window_root(main_window), 1, 5, grd_bg);
 	
@@ -156,5 +159,6 @@
 	grid->add(grid, &btn_vlaunch->widget, 0, 4, 1, 1);
 	
-	window_resize(main_window, 210, 130 + LOGO_HEIGHT);
+	window_resize(main_window, 0, 0, 210, 130 + LOGO_HEIGHT,
+	    WINDOW_PLACEMENT_RIGHT | WINDOW_PLACEMENT_TOP);
 	window_exec(main_window);
 	
Index: uspace/app/vterm/vterm.c
===================================================================
--- uspace/app/vterm/vterm.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/app/vterm/vterm.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -49,5 +49,5 @@
 	}
 	
-	window_t *main_window = window_open(argv[1], true, true, "vterm", 0, 0);
+	window_t *main_window = window_open(argv[1], true, true, "vterm");
 	if (!main_window) {
 		printf("%s: Cannot open main window.\n", NAME);
@@ -55,5 +55,5 @@
 	}
 	
-	window_resize(main_window, 650, 510);
+	window_resize(main_window, 0, 0, 648, 508, WINDOW_PLACEMENT_ANY);
 	terminal_t *terminal_widget =
 	    create_terminal(window_root(main_window), 640, 480);
Index: uspace/dist/src/c/demos/hello/build.gcc
===================================================================
--- uspace/dist/src/c/demos/hello/build.gcc	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/dist/src/c/demos/hello/build.gcc	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,2 @@
+gcc -nostdlib -nostdinc -I/inc/c -Wl,-T/inc/_link.ld -L/lib -lc -lsoftint -o hello hello.c
+
Index: uspace/dist/src/c/demos/tetris/build.gcc
===================================================================
--- uspace/dist/src/c/demos/tetris/build.gcc	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/dist/src/c/demos/tetris/build.gcc	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,6 @@
+gcc -nostdinc -I/inc/c -c -Drestrict= scores.c
+gcc -nostdinc -I/inc/c -c -Drestrict= screen.c
+gcc -nostdinc -I/inc/c -c -Drestrict= shapes.c
+gcc -nostdinc -I/inc/c -c -Drestrict= tetris.c
+gcc -nostdlib -Wl,-T/inc/_link.ld -L/lib -o tetris_ scores.o screen.o shapes.o tetris.o -lc -lsoftint
+
Index: uspace/dist/src/c/demos/tetris/screen.c
===================================================================
--- uspace/dist/src/c/demos/tetris/screen.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/dist/src/c/demos/tetris/screen.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -344,7 +344,7 @@
 	
 	while (timeout > 0) {
-		kbd_event_t event;
-		
-		if (!console_get_kbd_event_timeout(console, &event, &timeout))
+		cons_event_t event;
+		
+		if (!console_get_event_timeout(console, &event, &timeout))
 			break;
 	}
@@ -376,13 +376,13 @@
 	
 	while (c == 0) {
-		kbd_event_t event;
-		
-		if (!console_get_kbd_event_timeout(console, &event, &timeleft)) {
+		cons_event_t event;
+		
+		if (!console_get_event_timeout(console, &event, &timeleft)) {
 			timeleft = 0;
 			return -1;
 		}
 		
-		if (event.type == KEY_PRESS)
-			c = event.c;
+		if (event.type == CEV_KEY && event.ev.key.type == KEY_PRESS)
+			c = event.ev.key.c;
 	}
 	
@@ -398,11 +398,11 @@
 	
 	while (c == 0) {
-		kbd_event_t event;
-		
-		if (!console_get_kbd_event(console, &event))
+		cons_event_t event;
+		
+		if (!console_get_event(console, &event))
 			return -1;
 		
-		if (event.type == KEY_PRESS)
-			c = event.c;
+		if (event.type == CEV_KEY && event.ev.key.type == KEY_PRESS)
+			c = event.ev.key.c;
 	}
 	
Index: uspace/dist/src/python/demo/hello.py
===================================================================
--- uspace/dist/src/python/demo/hello.py	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/dist/src/python/demo/hello.py	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,4 @@
+#!/usr/bin/python
+
+print("Hello, World!")
+
Index: uspace/dist/src/python/demo/sintab.py
===================================================================
--- uspace/dist/src/python/demo/sintab.py	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/dist/src/python/demo/sintab.py	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,23 @@
+#!/usr/bin/python
+
+# Probably not very Pythonic, but it runs well with both Python2 and Python3
+
+import math
+import sys
+
+sys.stdout.write("    ")
+for frac_part in range(0,10):
+	sys.stdout.write(" %5d" % frac_part)
+print("")
+
+for angle_deg in range(0,90):
+	sys.stdout.write("%3d " % angle_deg)
+	for angle_deg_frac in range(0,10):
+		angle = math.radians(angle_deg + angle_deg_frac/10.)
+		value = math.sin(angle) * 10000 + 0.5
+		if value > 10000:
+			sys.stdout.write(" %05d" % (value))
+		else:
+			sys.stdout.write("  %04d" % (value))
+	print("")
+
Index: uspace/dist/src/python/modules.py
===================================================================
--- uspace/dist/src/python/modules.py	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/dist/src/python/modules.py	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,15 @@
+#!/usr/bin/python
+
+import sys
+
+for m in sys.builtin_module_names:
+	print("Built-in module '%s'." % m)
+
+try:
+	import pkgutil
+	for (loader, name, ispkg) in pkgutil.iter_modules():
+		print("Loadable module '%s'." % name)
+except ImportError:
+	print("Cannot determine list of loadable modules (pkgutil not found)!")
+
+
Index: uspace/drv/block/ahci/ahci.c
===================================================================
--- uspace/drv/block/ahci/ahci.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/drv/block/ahci/ahci.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -37,5 +37,5 @@
 #include <ddf/log.h>
 #include <device/hw_res_parsed.h>
-#include <device/pci.h>
+#include <pci_dev_iface.h>
 #include <sysinfo.h>
 #include <ipc/irc.h>
@@ -111,9 +111,9 @@
 	}
 
-static int ahci_get_sata_device_name(ddf_fun_t *, size_t, char *);
-static int ahci_get_num_blocks(ddf_fun_t *, uint64_t *);
-static int ahci_get_block_size(ddf_fun_t *, size_t *);
-static int ahci_read_blocks(ddf_fun_t *, uint64_t, size_t, void *);
-static int ahci_write_blocks(ddf_fun_t *, uint64_t, size_t, void *);
+static int get_sata_device_name(ddf_fun_t *, size_t, char *);
+static int get_num_blocks(ddf_fun_t *, uint64_t *);
+static int get_block_size(ddf_fun_t *, size_t *);
+static int read_blocks(ddf_fun_t *, uint64_t, size_t, void *);
+static int write_blocks(ddf_fun_t *, uint64_t, size_t, void *);
 
 static int ahci_identify_device(sata_dev_t *);
@@ -139,9 +139,9 @@
 
 static ahci_iface_t ahci_interface = {
-	.get_sata_device_name = &ahci_get_sata_device_name,
-	.get_num_blocks = &ahci_get_num_blocks,
-	.get_block_size = &ahci_get_block_size,
-	.read_blocks = &ahci_read_blocks,
-	.write_blocks = &ahci_write_blocks
+	.get_sata_device_name = &get_sata_device_name,
+	.get_num_blocks = &get_num_blocks,
+	.get_block_size = &get_block_size,
+	.read_blocks = &read_blocks,
+	.write_blocks = &write_blocks
 };
 
@@ -180,5 +180,5 @@
  *
  */
-static int ahci_get_sata_device_name(ddf_fun_t *fun,
+static int get_sata_device_name(ddf_fun_t *fun,
     size_t sata_dev_name_length, char *sata_dev_name)
 {
@@ -196,5 +196,5 @@
  *
  */
-static int ahci_get_num_blocks(ddf_fun_t *fun, uint64_t *num_blocks)
+static int get_num_blocks(ddf_fun_t *fun, uint64_t *num_blocks)
 {
 	sata_dev_t *sata = fun_sata_dev(fun);
@@ -211,5 +211,5 @@
  *
  */
-static int ahci_get_block_size(ddf_fun_t *fun, size_t *block_size)
+static int get_block_size(ddf_fun_t *fun, size_t *block_size)
 {
 	sata_dev_t *sata = fun_sata_dev(fun);
@@ -228,5 +228,5 @@
  *
  */
-static int ahci_read_blocks(ddf_fun_t *fun, uint64_t blocknum,
+static int read_blocks(ddf_fun_t *fun, uint64_t blocknum,
     size_t count, void *buf)
 {
@@ -271,5 +271,5 @@
  *
  */
-static int ahci_write_blocks(ddf_fun_t *fun, uint64_t blocknum,
+static int write_blocks(ddf_fun_t *fun, uint64_t blocknum,
     size_t count, void *buf)
 {
Index: uspace/drv/bus/amba/Makefile
===================================================================
--- uspace/drv/bus/amba/Makefile	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/drv/bus/amba/Makefile	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2010 Lenka Trochtova
+# 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.
+#
+
+USPACE_PREFIX = ../../..
+LIBS = $(LIBDRV_PREFIX)/libdrv.a
+EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include
+BINARY = amba
+
+SOURCES = \
+	amba.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/drv/bus/amba/amba.c
===================================================================
--- uspace/drv/bus/amba/amba.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/drv/bus/amba/amba.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,397 @@
+/*
+ * Copyright (c) 2013 Jakub Klama
+ * 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.
+ */
+
+/**
+ * @defgroup amba AMBA bus driver.
+ * @brief HelenOS AMBA bus driver.
+ * @{
+ */
+/** @file
+ */
+
+#include <assert.h>
+#include <byteorder.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <fibril_synch.h>
+#include <str.h>
+#include <ctype.h>
+#include <macros.h>
+#include <str_error.h>
+#include <ddf/driver.h>
+#include <ddf/log.h>
+#include <ipc/dev_iface.h>
+#include <ipc/irc.h>
+#include <ns.h>
+#include <ipc/services.h>
+#include <sysinfo.h>
+#include <ops/hw_res.h>
+#include <device/hw_res.h>
+#include <ddi.h>
+#include "ambapp.h"
+
+#define NAME  "amba"
+#define ID_MAX_STR_LEN  32
+
+#define LVL_DEBUG  LVL_ERROR
+
+typedef struct leon_amba_bus {
+	/** DDF device node */
+	ddf_dev_t *dnode;
+	uintptr_t master_area_addr;
+	uintptr_t slave_area_addr;
+	size_t master_area_size;
+	size_t slave_area_size;
+	void *master_area;
+	void *slave_area;
+	fibril_mutex_t area_mutex;
+} amba_bus_t;
+
+typedef struct amba_fun_data {
+	amba_bus_t *busptr;
+	ddf_fun_t *fnode;
+	int bus;
+	int index;
+	uint8_t vendor_id;
+	uint32_t device_id;
+	int version;
+	hw_resource_list_t hw_resources;
+	hw_resource_t resources[AMBA_MAX_HW_RES];
+} amba_fun_t;
+
+static amba_fun_t *amba_fun_new(amba_bus_t *);
+static void amba_fun_set_name(amba_fun_t *);
+static void amba_fun_create_match_ids(amba_fun_t *);
+static int amba_fun_online(ddf_fun_t *);
+static int amba_fun_offline(ddf_fun_t *);
+static hw_resource_list_t *amba_get_resources(ddf_fun_t *);
+static bool amba_enable_interrupt(ddf_fun_t *);
+static void amba_add_bar(amba_fun_t *, uintptr_t, size_t);
+static void amba_add_interrupt(amba_fun_t *, int);
+static int amba_bus_scan(amba_bus_t *, void *, unsigned int);
+static void amba_fake_scan(amba_bus_t *);
+static int amba_dev_add(ddf_dev_t *);
+
+static hw_res_ops_t amba_fun_hw_res_ops = {
+	.get_resource_list = &amba_get_resources,
+	.enable_interrupt = &amba_enable_interrupt
+};
+
+static ddf_dev_ops_t amba_fun_ops = {
+	.interfaces[HW_RES_DEV_IFACE] = &amba_fun_hw_res_ops
+};
+
+static driver_ops_t amba_ops = {
+	.dev_add = &amba_dev_add,
+	.fun_online = &amba_fun_online,
+	.fun_offline = &amba_fun_offline
+};
+
+static driver_t amba_driver = {
+	.name = NAME,
+	.driver_ops = &amba_ops
+};
+
+static amba_fun_t *amba_fun_new(amba_bus_t *bus)
+{
+	ddf_msg(LVL_DEBUG, "amba_fun_new(): bus=%p, bus->dnode=%p", bus,
+	    bus->dnode);
+	
+	ddf_fun_t *fnode = ddf_fun_create(bus->dnode, fun_inner, NULL);
+	if (fnode == NULL)
+		return NULL;
+	
+	ddf_msg(LVL_DEBUG, "amba_fun_new(): created");
+	
+	amba_fun_t *fun = ddf_fun_data_alloc(fnode, sizeof(amba_fun_t));
+	if (fun == NULL)
+		return NULL;
+	
+	ddf_msg(LVL_DEBUG, "amba_fun_new(): allocated data");
+	
+	fun->busptr = bus;
+	fun->fnode = fnode;
+	return fun;
+}
+
+static void amba_fun_set_name(amba_fun_t *fun)
+{
+	char *name = NULL;
+	
+	asprintf(&name, "%02x:%02x", fun->bus, fun->index);
+	ddf_fun_set_name(fun->fnode, name);
+}
+
+static void amba_fun_create_match_ids(amba_fun_t *fun)
+{
+	/* Vendor ID & Device ID */
+	char match_id_str[ID_MAX_STR_LEN];
+	int rc = snprintf(match_id_str, ID_MAX_STR_LEN, "amba/ven=%02x&dev=%08x",
+	    fun->vendor_id, fun->device_id);
+	if (rc < 0) {
+		ddf_msg(LVL_ERROR, "Failed creating match ID str: %s",
+		    str_error(rc));
+	}
+	
+	rc = ddf_fun_add_match_id(fun->fnode, match_id_str, 90);
+}
+
+static int amba_fun_online(ddf_fun_t *fun)
+{
+	ddf_msg(LVL_DEBUG, "amba_fun_online()");
+	return ddf_fun_online(fun);
+
+}
+
+static int amba_fun_offline(ddf_fun_t *fun)
+{
+	ddf_msg(LVL_DEBUG, "amba_fun_offline()");
+	return ddf_fun_offline(fun);
+}
+
+static hw_resource_list_t *amba_get_resources(ddf_fun_t *fnode)
+{
+	amba_fun_t *fun = ddf_fun_data_get(fnode);
+	
+	if (fun == NULL)
+		return NULL;
+	
+	return &fun->hw_resources;
+}
+
+static bool amba_enable_interrupt(ddf_fun_t *fnode)
+{
+	return true;
+}
+
+static void amba_alloc_resource_list(amba_fun_t *fun)
+{
+	fun->hw_resources.resources = fun->resources;
+}
+
+static void amba_add_bar(amba_fun_t *fun, uintptr_t addr, size_t size)
+{
+	hw_resource_list_t *hw_res_list = &fun->hw_resources;
+	hw_resource_t *hw_resources =  hw_res_list->resources;
+	size_t count = hw_res_list->count;
+	
+	assert(hw_resources != NULL);
+	assert(count < AMBA_MAX_HW_RES);
+	
+	hw_resources[count].type = MEM_RANGE;
+	hw_resources[count].res.mem_range.address = addr;
+	hw_resources[count].res.mem_range.size = size;
+	hw_resources[count].res.mem_range.endianness = BIG_ENDIAN;
+	
+	hw_res_list->count++;
+}
+
+static void amba_add_interrupt(amba_fun_t *fun, int irq)
+{
+	hw_resource_list_t *hw_res_list = &fun->hw_resources;
+	hw_resource_t *hw_resources = hw_res_list->resources;
+	size_t count = hw_res_list->count;
+	
+	assert(NULL != hw_resources);
+	assert(count < AMBA_MAX_HW_RES);
+	
+	hw_resources[count].type = INTERRUPT;
+	hw_resources[count].res.interrupt.irq = irq;
+	
+	hw_res_list->count++;
+	
+	ddf_msg(LVL_NOTE, "Function %s uses irq %x.", ddf_fun_get_name(fun->fnode), irq);
+}
+
+static int amba_bus_scan(amba_bus_t *bus, void *area, unsigned int max_entries)
+{
+	ddf_msg(LVL_DEBUG, "amba_bus_scan(): area=%p, max_entries=%u", area, max_entries);
+	
+	ambapp_entry_t *devices = (ambapp_entry_t *) area;
+	int found = 0;
+	
+	for (unsigned int i = 0; i < max_entries; i++) {
+		ambapp_entry_t *entry = &devices[i];
+		if (entry->vendor_id == 0xff)
+			continue;
+		
+		amba_fun_t *fun = amba_fun_new(bus);
+		fun->bus = 0;
+		fun->index = i;
+		fun->vendor_id = entry->vendor_id;
+		fun->device_id = entry->device_id;
+		fun->version = entry->version;
+		
+		for (unsigned int bnum = 0; bnum < 4; bnum++) {
+			ambapp_bar_t *bar = &entry->bar[bnum];
+			amba_add_bar(fun, bar->addr << 20, bar->mask);
+		}
+		
+		if (entry->irq != -1)
+			amba_add_interrupt(fun, entry->irq);
+		
+		ddf_fun_set_ops(fun->fnode, &amba_fun_ops);
+		ddf_fun_bind(fun->fnode);
+	}
+	
+	return found;
+}
+
+static void amba_fake_scan(amba_bus_t *bus)
+{
+	ddf_msg(LVL_DEBUG, "amba_fake_scan()");
+	
+	/* UART */
+	amba_fun_t *fun = amba_fun_new(bus);
+	fun->bus = 0;
+	fun->index = 0;
+	fun->vendor_id = GAISLER;
+	fun->device_id = GAISLER_APBUART;
+	fun->version = 1;
+	amba_alloc_resource_list(fun);
+	amba_add_bar(fun, 0x80000100, 0x100);
+	amba_add_interrupt(fun, 3);
+	amba_fun_set_name(fun);
+	amba_fun_create_match_ids(fun);
+	ddf_fun_set_ops(fun->fnode, &amba_fun_ops);
+	ddf_fun_bind(fun->fnode);
+	
+	ddf_msg(LVL_DEBUG, "added uart");
+	
+	/* IRQMP */
+	fun = amba_fun_new(bus);
+	fun->bus = 0;
+	fun->index = 1;
+	fun->vendor_id = GAISLER;
+	fun->device_id = GAISLER_IRQMP;
+	fun->version = 1;
+	amba_alloc_resource_list(fun);
+	amba_add_bar(fun, 0x80000200, 0x100);
+	amba_fun_set_name(fun);
+	amba_fun_create_match_ids(fun);
+	ddf_fun_set_ops(fun->fnode, &amba_fun_ops);
+	ddf_fun_bind(fun->fnode);
+	
+	ddf_msg(LVL_DEBUG, "added irqmp");
+	
+	/* GPTIMER */
+	fun = amba_fun_new(bus);
+	fun->bus = 0;
+	fun->index = 2;
+	fun->vendor_id = GAISLER;
+	fun->device_id = GAISLER_GPTIMER;
+	fun->version = 1;
+	amba_alloc_resource_list(fun);
+	amba_add_bar(fun, 0x80000300, 0x100);
+	amba_add_interrupt(fun, 8);
+	amba_fun_set_name(fun);
+	amba_fun_create_match_ids(fun);
+	ddf_fun_set_ops(fun->fnode, &amba_fun_ops);
+	ddf_fun_bind(fun->fnode);
+	
+	ddf_msg(LVL_DEBUG, "added timer");
+}
+
+static int amba_dev_add(ddf_dev_t *dnode)
+{
+	int rc = 0;
+	int found = 0;
+	bool got_res = false;
+	
+	amba_bus_t *bus = ddf_dev_data_alloc(dnode, sizeof(amba_bus_t));
+	if (bus == NULL) {
+		ddf_msg(LVL_ERROR, "amba_dev_add: allocation failed.");
+		rc = ENOMEM;
+		goto fail;
+	}
+	
+	bus->dnode = dnode;
+	async_sess_t *sess = ddf_dev_parent_sess_create(dnode, EXCHANGE_SERIALIZE);
+	if (sess == NULL) {
+		ddf_msg(LVL_ERROR, "amba_dev_add failed to connect to the "
+		    "parent driver.");
+		rc = ENOENT;
+		goto fail;
+	}
+	
+	hw_resource_list_t hw_resources;
+	rc = hw_res_get_resource_list(sess, &hw_resources);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "amba_dev_add failed to get hw resources "
+		    "for the device.");
+		goto fail;
+	}
+	
+	got_res = true;
+	assert(hw_resources.count > 1);
+	
+	bus->master_area_addr = hw_resources.resources[0].res.mem_range.address;
+	bus->master_area_size = hw_resources.resources[0].res.mem_range.size;
+	bus->slave_area_addr = hw_resources.resources[1].res.mem_range.address;
+	bus->slave_area_size = hw_resources.resources[1].res.mem_range.size;
+	
+	ddf_msg(LVL_DEBUG, "AMBA master area: 0x%08x", bus->master_area_addr);
+	ddf_msg(LVL_DEBUG, "AMBA slave area: 0x%08x", bus->slave_area_addr);
+	
+	if (pio_enable((void *)bus->master_area_addr, bus->master_area_size, &bus->master_area)) {
+		ddf_msg(LVL_ERROR, "Failed to enable master area.");
+		rc = EADDRNOTAVAIL;
+		goto fail;
+	}
+	
+	if (pio_enable((void *)bus->slave_area_addr, bus->slave_area_size, &bus->slave_area)) {
+		ddf_msg(LVL_ERROR, "Failed to enable slave area.");
+		rc = EADDRNOTAVAIL;
+		goto fail;
+	}
+	
+	/*
+	 * If nothing is found, we are probably running inside QEMU
+	 * and need to fake AMBA P&P entries.
+	 */
+	if (found == 0)
+		amba_fake_scan(bus);
+	
+	ddf_msg(LVL_DEBUG, "done");
+	
+	return EOK;
+	
+fail:
+	if (got_res)
+		hw_res_clean_resource_list(&hw_resources);
+	
+	return rc;
+}
+
+int main(int argc, char *argv[])
+{
+	printf("%s: HelenOS LEON3 AMBA bus driver\n", NAME);
+	ddf_log_init(NAME);
+	return ddf_driver_main(&amba_driver);
+}
Index: uspace/drv/bus/amba/amba.ma
===================================================================
--- uspace/drv/bus/amba/amba.ma	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/drv/bus/amba/amba.ma	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,1 @@
+10 amba
Index: uspace/drv/bus/amba/ambapp.h
===================================================================
--- uspace/drv/bus/amba/ambapp.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/drv/bus/amba/ambapp.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2010 Lenka Trochtova
+ * Copyright (c) 2011 Jiri Svoboda
+ * Copyright (c) 2013 Jakub Klama
+ * 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 amba
+ * @{
+ */
+/** @file
+ */
+
+#ifndef AMBAPP_H_
+#define AMBAPP_H_
+
+#include <ddf/driver.h>
+
+#define AMBAPP_MAX_DEVICES     64
+#define AMBAPP_AHBMASTER_AREA  0xfffff000
+#define AMBAPP_AHBSLAVE_AREA   0xfffff800
+#define AMBAPP_CONF_AREA       0xff000
+
+#define AMBA_MAX_HW_RES  (4 + 1)
+
+typedef enum {
+	GAISLER = 1,
+	ESA = 4
+} amba_vendor_id_t;
+
+typedef enum {
+	GAISLER_LEON3    = 0x003,
+	GAISLER_LEON3DSU = 0x004,
+	GAISLER_ETHAHB   = 0x005,
+	GAISLER_APBMST   = 0x006,
+	GAISLER_AHBUART  = 0x007,
+	GAISLER_SRCTRL   = 0x008,
+	GAISLER_SDCTRL   = 0x009,
+	GAISLER_APBUART  = 0x00c,
+	GAISLER_IRQMP    = 0x00d,
+	GAISLER_AHBRAM   = 0x00e,
+	GAISLER_GPTIMER  = 0x011,
+	GAISLER_PCITRG   = 0x012,
+	GAISLER_PCISBRG  = 0x013,
+	GAISLER_PCIFBRG  = 0x014,
+	GAISLER_PCITRACE = 0x015,
+	GAISLER_PCIDMA   = 0x016,
+	GAISLER_AHBTRACE = 0x017,
+	GAISLER_ETHDSU   = 0x018,
+	GAISLER_PIOPORT  = 0x01a,
+	GAISLER_AHBJTAG  = 0x01c,
+	GAISLER_SPW      = 0x01f,
+	GAISLER_ATACTRL  = 0x024,
+	GAISLER_VGA      = 0x061,
+	GAISLER_KBD      = 0x060,
+	GAISLER_ETHMAC   = 0x01d,
+	GAISLER_DDRSPA   = 0x025,
+	GAISLER_EHCI     = 0x026,
+	GAISLER_UHCI     = 0x027,
+	GAISLER_SPW2     = 0x029,
+	GAISLER_DDR2SPA  = 0x02e,
+	GAISLER_AHBSTAT  = 0x052,
+	GAISLER_FTMCTRL  = 0x054,
+	ESA_MCTRL        = 0x00f
+} amba_device_id_t;
+
+typedef struct {
+	unsigned int addr : 12;
+	unsigned int reserved : 2;
+	unsigned int prefetchable : 1;
+	unsigned int cacheable : 1;
+	unsigned int mask : 12;
+	unsigned int type : 4;
+} __attribute__((packed)) ambapp_bar_t;
+
+typedef struct {
+	unsigned int vendor_id : 8;
+	unsigned int device_id : 24;
+	unsigned int reserved : 2;
+	unsigned int version : 5;
+	unsigned int irq : 5;
+	uint32_t user_defined[3];
+	ambapp_bar_t bar[4];
+} __attribute__((packed)) ambapp_entry_t;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/drv/bus/pci/pciintel/pci.c
===================================================================
--- uspace/drv/bus/pci/pciintel/pci.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/drv/bus/pci/pciintel/pci.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -153,5 +153,5 @@
 
 
-static int pci_config_space_write_32(ddf_fun_t *fun, uint32_t address,
+static int config_space_write_32(ddf_fun_t *fun, uint32_t address,
     uint32_t data)
 {
@@ -162,5 +162,5 @@
 }
 
-static int pci_config_space_write_16(
+static int config_space_write_16(
     ddf_fun_t *fun, uint32_t address, uint16_t data)
 {
@@ -171,5 +171,5 @@
 }
 
-static int pci_config_space_write_8(
+static int config_space_write_8(
     ddf_fun_t *fun, uint32_t address, uint8_t data)
 {
@@ -180,5 +180,5 @@
 }
 
-static int pci_config_space_read_32(
+static int config_space_read_32(
     ddf_fun_t *fun, uint32_t address, uint32_t *data)
 {
@@ -189,5 +189,5 @@
 }
 
-static int pci_config_space_read_16(
+static int config_space_read_16(
     ddf_fun_t *fun, uint32_t address, uint16_t *data)
 {
@@ -198,5 +198,5 @@
 }
 
-static int pci_config_space_read_8(
+static int config_space_read_8(
     ddf_fun_t *fun, uint32_t address, uint8_t *data)
 {
@@ -217,10 +217,10 @@
 
 static pci_dev_iface_t pci_dev_ops = {
-	.config_space_read_8 = &pci_config_space_read_8,
-	.config_space_read_16 = &pci_config_space_read_16,
-	.config_space_read_32 = &pci_config_space_read_32,
-	.config_space_write_8 = &pci_config_space_write_8,
-	.config_space_write_16 = &pci_config_space_write_16,
-	.config_space_write_32 = &pci_config_space_write_32
+	.config_space_read_8 = &config_space_read_8,
+	.config_space_read_16 = &config_space_read_16,
+	.config_space_read_32 = &config_space_read_32,
+	.config_space_write_8 = &config_space_write_8,
+	.config_space_write_16 = &config_space_write_16,
+	.config_space_write_32 = &config_space_write_32
 };
 
Index: uspace/drv/bus/usb/ehci/res.c
===================================================================
--- uspace/drv/bus/usb/ehci/res.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/drv/bus/usb/ehci/res.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -43,5 +43,5 @@
 #include <usb/debug.h>
 #include <device/hw_res_parsed.h>
-#include <device/pci.h>
+#include <pci_dev_iface.h>
 
 #include "res.h"
Index: uspace/drv/bus/usb/uhci/res.c
===================================================================
--- uspace/drv/bus/usb/uhci/res.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/drv/bus/usb/uhci/res.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -39,5 +39,5 @@
 #include <devman.h>
 #include <device/hw_res_parsed.h>
-#include <device/pci.h>
+#include <pci_dev_iface.h>
 
 #include "res.h"
@@ -62,5 +62,5 @@
 	hw_res_list_parsed_t hw_res;
 	hw_res_list_parsed_init(&hw_res);
-	const int ret =  hw_res_get_list_parsed(parent_sess, &hw_res, 0);
+	const int ret = hw_res_get_list_parsed(parent_sess, &hw_res, 0);
 	async_hangup(parent_sess);
 	if (ret != EOK) {
Index: uspace/drv/bus/usb/uhci/root_hub.c
===================================================================
--- uspace/drv/bus/usb/uhci/root_hub.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/drv/bus/usb/uhci/root_hub.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -36,4 +36,5 @@
 #include <str_error.h>
 #include <stdio.h>
+#include <device/hw_res_parsed.h>
 
 #include <usb/debug.h>
@@ -48,8 +49,16 @@
  * @return Error code.
  */
-int rh_init(rh_t *instance, ddf_fun_t *fun, uintptr_t reg_addr, size_t reg_size)
+int
+rh_init(rh_t *instance, ddf_fun_t *fun, addr_range_t *regs, uintptr_t reg_addr,
+    size_t reg_size)
 {
 	assert(instance);
 	assert(fun);
+
+	/* Crop the PIO window to the absolute address range of UHCI I/O. */
+	instance->pio_window.mem.base = 0;
+	instance->pio_window.mem.size = 0;
+	instance->pio_window.io.base = RNGABS(*regs);
+	instance->pio_window.io.size = RNGSZ(*regs);
 
 	/* Initialize resource structure */
@@ -60,4 +69,5 @@
 	instance->io_regs.res.io_range.address = reg_addr;
 	instance->io_regs.res.io_range.size = reg_size;
+	instance->io_regs.res.io_range.relative = true;
 	instance->io_regs.res.io_range.endianness = LITTLE_ENDIAN;
 
Index: uspace/drv/bus/usb/uhci/root_hub.h
===================================================================
--- uspace/drv/bus/usb/uhci/root_hub.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/drv/bus/usb/uhci/root_hub.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -38,4 +38,5 @@
 #include <ddf/driver.h>
 #include <ops/hw_res.h>
+#include <ops/pio_window.h>
 
 /** DDF support structure for uhci_rhd driver, provides I/O resources */
@@ -45,8 +46,9 @@
 	/** The only resource in the RH resource list */
 	hw_resource_t io_regs;
+	/** PIO window in which the RH will operate. */
+	pio_window_t pio_window;	
 } rh_t;
 
-int rh_init(
-    rh_t *instance, ddf_fun_t *fun, uintptr_t reg_addr, size_t reg_size);
+extern int rh_init(rh_t *, ddf_fun_t *, addr_range_t *, uintptr_t, size_t);
 
 #endif
Index: uspace/drv/bus/usb/uhci/uhci.c
===================================================================
--- uspace/drv/bus/usb/uhci/uhci.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/drv/bus/usb/uhci/uhci.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -132,8 +132,22 @@
 };
 
+static pio_window_t *get_pio_window(ddf_fun_t *fun)
+{
+	rh_t *rh = ddf_fun_data_get(fun);
+	
+	if (rh == NULL)
+		return NULL;
+	return &rh->pio_window;
+}
+
+static pio_window_ops_t pio_window_iface = {
+	.get_pio_window = get_pio_window
+};
+
 /** RH function support for uhci_rhd */
 static ddf_dev_ops_t rh_ops = {
 	.interfaces[USB_DEV_IFACE] = &usb_iface,
-	.interfaces[HW_RES_DEV_IFACE] = &hw_res_iface
+	.interfaces[HW_RES_DEV_IFACE] = &hw_res_iface,
+	.interfaces[PIO_WINDOW_DEV_IFACE] = &pio_window_iface
 };
 
@@ -246,6 +260,5 @@
 	}
 
-	rc = rh_init(&instance->rh, instance->rh_fun,
-	    (uintptr_t)instance->hc.registers + 0x10, 4);
+	rc = rh_init(&instance->rh, instance->rh_fun, &regs, 0x10, 4);
 	if (rc != EOK) {
 		usb_log_error("Failed to setup UHCI root hub: %s.\n",
Index: uspace/drv/bus/usb/uhcirh/main.c
===================================================================
--- uspace/drv/bus/usb/uhcirh/main.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/drv/bus/usb/uhcirh/main.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -138,5 +138,5 @@
 	hw_res_list_parsed_t hw_res;
 	hw_res_list_parsed_init(&hw_res);
-	const int ret =  hw_res_get_list_parsed(parent_sess, &hw_res, 0);
+	const int ret = hw_res_get_list_parsed(parent_sess, &hw_res, 0);
 	async_hangup(parent_sess);
 	if (ret != EOK) {
Index: uspace/drv/char/grlib_uart/Makefile
===================================================================
--- uspace/drv/char/grlib_uart/Makefile	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/drv/char/grlib_uart/Makefile	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2013 Jakub Klama
+# 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.
+#
+
+USPACE_PREFIX = ../../..
+LIBS = $(LIBDRV_PREFIX)/libdrv.a
+EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include
+BINARY = grlib_uart
+
+SOURCES = \
+	grlib_uart.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/drv/char/grlib_uart/cyclic_buffer.h
===================================================================
--- uspace/drv/char/grlib_uart/cyclic_buffer.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/drv/char/grlib_uart/cyclic_buffer.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2010 Lenka Trochtova
+ * 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 ns8250
+ * @{
+ */
+/** @file
+ */
+
+#ifndef CYCLIC_BUFFER_H_
+#define CYCLIC_BUFFER_H_
+
+#define BUF_LEN 4096
+
+typedef struct cyclic_buffer {
+	uint8_t buf[BUF_LEN];
+	int start;
+	int cnt;
+}  cyclic_buffer_t;
+
+/*
+ * @return		False if the buffer is full.
+ */
+static inline bool buf_push_back(cyclic_buffer_t *buf, uint8_t item)
+{
+	if (buf->cnt >= BUF_LEN)
+		return false;
+	
+	int pos = (buf->start + buf->cnt) % BUF_LEN;
+	buf->buf[pos] = item;
+	buf->cnt++;
+	return true;
+}
+
+static inline bool buf_is_empty(cyclic_buffer_t *buf)
+{
+	return buf->cnt == 0;
+}
+
+static inline uint8_t buf_pop_front(cyclic_buffer_t *buf)
+{
+	assert(!buf_is_empty(buf));
+	
+	uint8_t res = buf->buf[buf->start];
+	buf->start = (buf->start + 1) % BUF_LEN;
+	buf->cnt--;
+	return res;
+}
+
+static inline void buf_clear(cyclic_buffer_t *buf)
+{
+	buf->cnt = 0;
+}
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/drv/char/grlib_uart/grlib_uart.c
===================================================================
--- uspace/drv/char/grlib_uart/grlib_uart.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/drv/char/grlib_uart/grlib_uart.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,872 @@
+/*
+ * Copyright (c) 2010 Lenka Trochtova
+ * Copyright (c) 2011 Jiri Svoboda
+ * Copyright (c) 2013 Jakub Klama
+ * 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.
+ */
+
+/**
+ * @defgroup grlib_uart Serial port driver.
+ * @brief HelenOS serial port driver.
+ * @{
+ */
+
+/** @file
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <fibril_synch.h>
+#include <stdlib.h>
+#include <str.h>
+#include <ctype.h>
+#include <macros.h>
+#include <malloc.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <ddi.h>
+
+#include <ddf/driver.h>
+#include <ddf/interrupt.h>
+#include <ddf/log.h>
+#include <ops/char_dev.h>
+
+#include <ns.h>
+#include <ipc/services.h>
+#include <ipc/irc.h>
+#include <device/hw_res.h>
+#include <ipc/serial_ctl.h>
+
+#include "cyclic_buffer.h"
+
+#define NAME "grlib_uart"
+
+#define REG_COUNT 5
+#define MAX_BAUD_RATE 115200
+
+#define LVL_DEBUG LVL_ERROR
+
+#define GRLIB_UART_STATUS_DR  (1 << 0)
+#define GRLIB_UART_STATUS_TS  (1 << 1)
+#define GRLIB_UART_STATUS_TE  (1 << 2)
+#define GRLIB_UART_STATUS_BR  (1 << 3)
+#define GRLIB_UART_STATUS_OV  (1 << 4)
+#define GRLIB_UART_STATUS_PE  (1 << 5)
+#define GRLIB_UART_STATUS_FE  (1 << 6)
+#define GRLIB_UART_STATUS_TH  (1 << 7)
+#define GRLIB_UART_STATUS_RH  (1 << 8)
+#define GRLIB_UART_STATUS_TF  (1 << 9)
+#define GRLIB_UART_STATUS_RF  (1 << 10)
+
+#define GRLIB_UART_CONTROL_RE  (1 << 0)
+#define GRLIB_UART_CONTROL_TE  (1 << 1)
+#define GRLIB_UART_CONTROL_RI  (1 << 2)
+#define GRLIB_UART_CONTROL_TI  (1 << 3)
+#define GRLIB_UART_CONTROL_PS  (1 << 4)
+#define GRLIB_UART_CONTROL_PE  (1 << 5)
+#define GRLIB_UART_CONTROL_FL  (1 << 6)
+#define GRLIB_UART_CONTROL_LB  (1 << 7)
+#define GRLIB_UART_CONTROL_EC  (1 << 8)
+#define GRLIB_UART_CONTROL_TF  (1 << 9)
+#define GRLIB_UART_CONTROL_RF  (1 << 10)
+#define GRLIB_UART_CONTROL_DB  (1 << 11)
+#define GRLIB_UART_CONTROL_BI  (1 << 12)
+#define GRLIB_UART_CONTROL_DI  (1 << 13)
+#define GRLIB_UART_CONTROL_SI  (1 << 14)
+#define GRLIB_UART_CONTROL_FA  (1 << 31)
+
+typedef struct {
+	unsigned int fa : 1;
+	unsigned int : 16;
+	unsigned int si : 1;
+	unsigned int di : 1;
+	unsigned int bi : 1;
+	unsigned int db : 1;
+	unsigned int rf : 1;
+	unsigned int tf : 1;
+	unsigned int ec : 1;
+	unsigned int lb : 1;
+	unsigned int fl : 1;
+	unsigned int pe : 1;
+	unsigned int ps : 1;
+	unsigned int ti : 1;
+	unsigned int ri : 1;
+	unsigned int te : 1;
+	unsigned int re : 1;
+} grlib_uart_control_t;
+
+/** GRLIB UART registers */
+typedef struct {
+	ioport32_t data;
+	ioport32_t status;
+	ioport32_t control;
+	ioport32_t scaler;
+	ioport32_t debug;
+} grlib_uart_regs_t;
+
+/** The number of bits of one data unit send by the serial port. */
+typedef enum {
+	WORD_LENGTH_5,
+	WORD_LENGTH_6,
+	WORD_LENGTH_7,
+	WORD_LENGTH_8
+} word_length_t;
+
+/** The number of stop bits used by the serial port. */
+typedef enum {
+	/** Use one stop bit. */
+	ONE_STOP_BIT,
+	/** 1.5 stop bits for word length 5, 2 stop bits otherwise. */
+	TWO_STOP_BITS
+} stop_bit_t;
+
+/** The driver data for the serial port devices. */
+typedef struct grlib_uart {
+	/** DDF device node */
+	ddf_dev_t *dev;
+	/** DDF function node */
+	ddf_fun_t *fun;
+	/** I/O registers **/
+	grlib_uart_regs_t *regs;
+	/** Are there any clients connected to the device? */
+	unsigned client_connections;
+	/** The irq assigned to this device. */
+	int irq;
+	/** The base i/o address of the devices registers. */
+	uintptr_t regs_addr;
+	/** The buffer for incoming data. */
+	cyclic_buffer_t input_buffer;
+	/** The fibril mutex for synchronizing the access to the device. */
+	fibril_mutex_t mutex;
+	/** Indicates that some data has become available */
+	fibril_condvar_t input_buffer_available;
+	/** True if device is removed. */
+	bool removed;
+} grlib_uart_t;
+
+/** Obtain soft-state structure from device node */
+static grlib_uart_t *dev_grlib_uart(ddf_dev_t *dev)
+{
+	return ddf_dev_data_get(dev);
+}
+
+/** Obtain soft-state structure from function node */
+static grlib_uart_t *fun_grlib_uart(ddf_fun_t *fun)
+{
+	return dev_grlib_uart(ddf_fun_get_dev(fun));
+}
+
+/** Find out if there is some incoming data available on the serial port.
+ *
+ * @param port The base address of the serial port device's ports.
+ *
+ * @return True if there are data waiting to be read.
+ * @return False otherwise.
+ *
+ */
+static bool grlib_uart_received(grlib_uart_regs_t *regs)
+{
+	return ((pio_read_32(&regs->status) & GRLIB_UART_STATUS_DR) != 0);
+}
+
+/** Read one byte from the serial port.
+ *
+ * @param port The base address of the serial port device's ports.
+ *
+ * @return The data read.
+ *
+ */
+static uint8_t grlib_uart_read_8(grlib_uart_regs_t *regs)
+{
+	return (uint8_t) pio_read_32(&regs->data);
+}
+
+/** Find out wheter it is possible to send data.
+ *
+ * @param port The base address of the serial port device's ports.
+ *
+ */
+static bool is_transmit_empty(grlib_uart_regs_t *regs)
+{
+	return ((pio_read_32(&regs->status) & GRLIB_UART_STATUS_TS) != 0);
+}
+
+/** Write one character on the serial port.
+ *
+ * @param port The base address of the serial port device's ports.
+ * @param c    The character to be written to the serial port device.
+ *
+ */
+static void grlib_uart_write_8(grlib_uart_regs_t *regs, uint8_t c)
+{
+	while (!is_transmit_empty(regs));
+	
+	pio_write_32(&regs->data, (uint32_t) c);
+}
+
+/** Read data from the serial port device.
+ *
+ * @param fun   The serial port function
+ * @param buf   The output buffer for read data.
+ * @param count The number of bytes to be read.
+ *
+ * @return The number of bytes actually read on success,
+ * @return Negative error number otherwise.
+ *
+ */
+static int grlib_uart_read(ddf_fun_t *fun, char *buf, size_t count)
+{
+	if (count == 0)
+		return 0;
+	
+	grlib_uart_t *ns = fun_grlib_uart(fun);
+	
+	fibril_mutex_lock(&ns->mutex);
+	
+	while (buf_is_empty(&ns->input_buffer))
+		fibril_condvar_wait(&ns->input_buffer_available, &ns->mutex);
+	
+	int ret = 0;
+	while ((!buf_is_empty(&ns->input_buffer)) && ((size_t) ret < count)) {
+		buf[ret] = (char) buf_pop_front(&ns->input_buffer);
+		ret++;
+	}
+	
+	fibril_mutex_unlock(&ns->mutex);
+	
+	return ret;
+}
+
+/** Write a character to the serial port.
+ *
+ * @param ns Serial port device
+ * @param c  The character to be written
+ *
+ */
+static inline void grlib_uart_putchar(grlib_uart_t *ns, uint8_t c)
+{
+	fibril_mutex_lock(&ns->mutex);
+	grlib_uart_write_8(ns->regs, c);
+	fibril_mutex_unlock(&ns->mutex);
+}
+
+/** Write data to the serial port.
+ *
+ * @param fun   The serial port function
+ * @param buf   The data to be written
+ * @param count The number of bytes to be written
+ *
+ * @return Zero on success
+ *
+ */
+static int grlib_uart_write(ddf_fun_t *fun, char *buf, size_t count)
+{
+	grlib_uart_t *ns = fun_grlib_uart(fun);
+	
+	for (size_t idx = 0; idx < count; idx++)
+		grlib_uart_putchar(ns, (uint8_t) buf[idx]);
+	
+	return count;
+}
+
+static ddf_dev_ops_t grlib_uart_dev_ops;
+
+/** The character interface's callbacks. */
+static char_dev_ops_t grlib_uart_char_dev_ops = {
+	.read = &grlib_uart_read,
+	.write = &grlib_uart_write
+};
+
+static int grlib_uart_dev_add(ddf_dev_t *);
+static int grlib_uart_dev_remove(ddf_dev_t *);
+
+/** The serial port device driver's standard operations. */
+static driver_ops_t grlib_uart_ops = {
+	.dev_add = &grlib_uart_dev_add,
+	.dev_remove = &grlib_uart_dev_remove
+};
+
+/** The serial port device driver structure. */
+static driver_t grlib_uart_driver = {
+	.name = NAME,
+	.driver_ops = &grlib_uart_ops
+};
+
+/** Clean up the serial port soft-state
+ *
+ * @param ns Serial port device
+ *
+ */
+static void grlib_uart_dev_cleanup(grlib_uart_t *ns)
+{
+}
+
+/** Enable the i/o ports of the device.
+ *
+ * @param ns Serial port device
+ *
+ * @return True on success, false otherwise
+ *
+ */
+static bool grlib_uart_pio_enable(grlib_uart_t *ns)
+{
+	ddf_msg(LVL_DEBUG, "grlib_uart_pio_enable %s", ddf_dev_get_name(ns->dev));
+	
+	/* Gain control over port's registers. */
+	if (pio_enable((void *) ns->regs_addr, REG_COUNT,
+	    (void **) &ns->regs)) {
+		ddf_msg(LVL_ERROR, "Cannot map the port %#" PRIx32
+		    " for device %s.", ns->regs_addr, ddf_dev_get_name(ns->dev));
+		return false;
+	}
+	
+	return true;
+}
+
+/** Probe the serial port device for its presence.
+ *
+ * @param ns Serial port device
+ *
+ * @return True if the device is present, false otherwise
+ *
+ */
+static bool grlib_uart_dev_probe(grlib_uart_t *ns)
+{
+	ddf_msg(LVL_DEBUG, "grlib_uart_dev_probe %s", ddf_dev_get_name(ns->dev));
+	
+	return true;
+}
+
+/** Initialize serial port device.
+ *
+ * @param ns Serial port device
+ *
+ * @return Zero on success, negative error number otherwise
+ *
+ */
+static int grlib_uart_dev_initialize(grlib_uart_t *ns)
+{
+	ddf_msg(LVL_DEBUG, "grlib_uart_dev_initialize %s", ddf_dev_get_name(ns->dev));
+	
+	hw_resource_list_t hw_resources;
+	memset(&hw_resources, 0, sizeof(hw_resource_list_t));
+	
+	int ret = EOK;
+	
+	/* Connect to the parent's driver. */
+	async_sess_t *parent_sess = ddf_dev_parent_sess_create(ns->dev,
+	    EXCHANGE_SERIALIZE);
+	if (parent_sess == NULL) {
+		ddf_msg(LVL_ERROR, "Failed to connect to parent driver of "
+		    "device %s.", ddf_dev_get_name(ns->dev));
+		ret = ENOENT;
+		goto failed;
+	}
+	
+	/* Get hw resources. */
+	ret = hw_res_get_resource_list(parent_sess, &hw_resources);
+	if (ret != EOK) {
+		ddf_msg(LVL_ERROR, "Failed to get HW resources for device "
+		    "%s.", ddf_dev_get_name(ns->dev));
+		goto failed;
+	}
+	
+	bool irq = false;
+	bool ioport = false;
+	
+	for (size_t i = 0; i < hw_resources.count; i++) {
+		hw_resource_t *res = &hw_resources.resources[i];
+		switch (res->type) {
+		case INTERRUPT:
+			ns->irq = res->res.interrupt.irq;
+			irq = true;
+			ddf_msg(LVL_NOTE, "Device %s was assigned irq = 0x%x.",
+			    ddf_dev_get_name(ns->dev), ns->irq);
+			break;
+			
+		case MEM_RANGE:
+			ns->regs_addr = res->res.mem_range.address;
+			if (res->res.mem_range.size < REG_COUNT) {
+				ddf_msg(LVL_ERROR, "I/O range assigned to "
+				    "device %s is too small.", ddf_dev_get_name(ns->dev));
+				ret = ELIMIT;
+				goto failed;
+			}
+			ioport = true;
+			ddf_msg(LVL_NOTE, "Device %s was assigned I/O address = "
+			    "0x%x.", ddf_dev_get_name(ns->dev), ns->regs_addr);
+    			break;
+			
+		default:
+			break;
+		}
+	}
+	
+	if ((!irq) || (!ioport)) {
+		ddf_msg(LVL_ERROR, "Missing HW resource(s) for device %s.",
+		    ddf_dev_get_name(ns->dev));
+		ret = ENOENT;
+		goto failed;
+	}
+	
+	hw_res_clean_resource_list(&hw_resources);
+	return ret;
+	
+failed:
+	grlib_uart_dev_cleanup(ns);
+	hw_res_clean_resource_list(&hw_resources);
+	return ret;
+}
+
+/** Enable interrupts on the serial port device.
+ *
+ * Interrupt when data is received
+ *
+ * @param port The base address of the serial port device's ports.
+ *
+ */
+static inline void grlib_uart_port_interrupts_enable(grlib_uart_regs_t *regs)
+{
+	/* Interrupt when data received. */
+	uint32_t control = pio_read_32(&regs->control);
+	pio_write_32(&regs->control, control | GRLIB_UART_CONTROL_RE);
+}
+
+/** Disable interrupts on the serial port device.
+ *
+ * @param port The base address of the serial port device's ports.
+ *
+ */
+static inline void grlib_uart_port_interrupts_disable(grlib_uart_regs_t *regs)
+{
+	uint32_t control = pio_read_32(&regs->control);
+	pio_write_32(&regs->control, control & (~GRLIB_UART_CONTROL_RE));
+}
+
+/** Enable interrupts for the serial port device.
+ *
+ * @param ns Serial port device
+ *
+ * @return Zero on success, negative error number otherwise
+ *
+ */
+static int grlib_uart_interrupt_enable(grlib_uart_t *ns)
+{
+	/* Enable interrupt on the serial port. */
+	grlib_uart_port_interrupts_enable(ns->regs);
+	
+	return EOK;
+}
+
+static int grlib_uart_port_set_baud_rate(grlib_uart_regs_t *regs,
+    unsigned int baud_rate)
+{
+	if ((baud_rate < 50) || (MAX_BAUD_RATE % baud_rate != 0)) {
+		ddf_msg(LVL_ERROR, "Invalid baud rate %d requested.",
+		    baud_rate);
+		return EINVAL;
+	}
+	
+	/* XXX: Set baud rate */
+	
+	return EOK;
+}
+
+/** Set the parameters of the serial communication on the serial port device.
+ *
+ * @param parity      The parity to be used.
+ * @param word_length The length of one data unit in bits.
+ * @param stop_bits   The number of stop bits used (one or two).
+ *
+ * @return Zero on success.
+ * @return EINVAL if some of the specified values is invalid.
+ *
+ */
+static int grlib_uart_port_set_com_props(grlib_uart_regs_t *regs,
+    unsigned int parity, unsigned int word_length, unsigned int stop_bits)
+{
+	uint32_t val = pio_read_32(&regs->control);
+	
+	switch (parity) {
+	case SERIAL_NO_PARITY:
+	case SERIAL_ODD_PARITY:
+	case SERIAL_EVEN_PARITY:
+	case SERIAL_MARK_PARITY:
+	case SERIAL_SPACE_PARITY:
+		val |= GRLIB_UART_CONTROL_PE;
+		break;
+	default:
+		return EINVAL;
+	}
+	
+	pio_write_32(&regs->control, val);
+	
+	return EOK;
+}
+
+/** Initialize the serial port device.
+ *
+ * Set the default parameters of the serial communication.
+ *
+ * @param ns Serial port device
+ *
+ */
+static void grlib_uart_initialize_port(grlib_uart_t *ns)
+{
+	/* Disable interrupts. */
+	grlib_uart_port_interrupts_disable(ns->regs);
+	
+	/* Set baud rate. */
+	grlib_uart_port_set_baud_rate(ns->regs, 38400);
+	
+	/* 8 bits, no parity, two stop bits. */
+	grlib_uart_port_set_com_props(ns->regs, SERIAL_NO_PARITY, 8, 2);
+	
+	/*
+	 * Enable FIFO, clear them, with 4-byte threshold for greater
+	 * reliability.
+	 */
+	pio_write_32(&ns->regs->control, GRLIB_UART_CONTROL_RE |
+	    GRLIB_UART_CONTROL_TE | GRLIB_UART_CONTROL_RF |
+	    GRLIB_UART_CONTROL_TF | GRLIB_UART_CONTROL_RI |
+	    GRLIB_UART_CONTROL_FA);
+}
+
+/** Deinitialize the serial port device.
+ *
+ * @param ns Serial port device
+ *
+ */
+static void grlib_uart_port_cleanup(grlib_uart_t *ns)
+{
+	grlib_uart_port_interrupts_disable(ns->regs);
+}
+
+/** Read the data from the serial port device and store them to the input
+ * buffer.
+ *
+ * @param ns Serial port device
+ *
+ */
+static void grlib_uart_read_from_device(grlib_uart_t *ns)
+{
+	grlib_uart_regs_t *regs = ns->regs;
+	bool cont = true;
+	
+	fibril_mutex_lock(&ns->mutex);
+	
+	while (cont) {
+		cont = grlib_uart_received(regs);
+		if (cont) {
+			uint8_t val = grlib_uart_read_8(regs);
+			
+			if (ns->client_connections > 0) {
+				bool buf_was_empty = buf_is_empty(&ns->input_buffer);
+				if (!buf_push_back(&ns->input_buffer, val)) {
+					ddf_msg(LVL_WARN, "Buffer overflow on "
+					    "%s.", ddf_dev_get_name(ns->dev));
+					break;
+				} else {
+					ddf_msg(LVL_DEBUG2, "Character %c saved "
+					    "to the buffer of %s.",
+					    val, ddf_dev_get_name(ns->dev));
+					if (buf_was_empty)
+						fibril_condvar_broadcast(&ns->input_buffer_available);
+				}
+			}
+		}
+	}
+	
+	fibril_mutex_unlock(&ns->mutex);
+	fibril_yield();
+}
+
+/** The interrupt handler.
+ *
+ * The serial port is initialized to interrupt when some data come or line
+ * status register changes, so the interrupt is handled by reading the incoming
+ * data and reading the line status register.
+ *
+ * @param dev The serial port device.
+ *
+ */
+static inline void grlib_uart_interrupt_handler(ddf_dev_t *dev,
+    ipc_callid_t iid, ipc_call_t *icall)
+{
+	grlib_uart_t *ns = dev_grlib_uart(dev);
+	
+	uint32_t status = pio_read_32(&ns->regs->status);
+	
+	if (status & GRLIB_UART_STATUS_RF) {
+		if (status & GRLIB_UART_STATUS_OV)
+			ddf_msg(LVL_WARN, "Overrun error on %s", ddf_dev_get_name(ns->dev));
+	}
+	
+	grlib_uart_read_from_device(ns);
+}
+
+/** Register the interrupt handler for the device.
+ *
+ * @param ns Serial port device
+ *
+ */
+static inline int grlib_uart_register_interrupt_handler(grlib_uart_t *ns)
+{
+	return register_interrupt_handler(ns->dev, ns->irq,
+	    grlib_uart_interrupt_handler, NULL);
+}
+
+/** Unregister the interrupt handler for the device.
+ *
+ * @param ns Serial port device
+ *
+ */
+static inline int grlib_uart_unregister_interrupt_handler(grlib_uart_t *ns)
+{
+	return unregister_interrupt_handler(ns->dev, ns->irq);
+}
+
+/** The dev_add callback method of the serial port driver.
+ *
+ * Probe and initialize the newly added device.
+ *
+ * @param dev The serial port device.
+ *
+ */
+static int grlib_uart_dev_add(ddf_dev_t *dev)
+{
+	grlib_uart_t *ns = NULL;
+	ddf_fun_t *fun = NULL;
+	bool need_cleanup = false;
+	bool need_unreg_intr_handler = false;
+	int rc;
+	
+	ddf_msg(LVL_DEBUG, "grlib_uart_dev_add %s (handle = %d)",
+	    ddf_dev_get_name(dev), (int) ddf_dev_get_handle(dev));
+	
+	/* Allocate soft-state for the device */
+	ns = ddf_dev_data_alloc(dev, sizeof(grlib_uart_t));
+	if (ns == NULL) {
+		rc = ENOMEM;
+		goto fail;
+	}
+	
+	fibril_mutex_initialize(&ns->mutex);
+	fibril_condvar_initialize(&ns->input_buffer_available);
+	ns->dev = dev;
+	
+	rc = grlib_uart_dev_initialize(ns);
+	if (rc != EOK)
+		goto fail;
+	
+	need_cleanup = true;
+	
+	if (!grlib_uart_pio_enable(ns)) {
+		rc = EADDRNOTAVAIL;
+		goto fail;
+	}
+	
+	/* Find out whether the device is present. */
+	if (!grlib_uart_dev_probe(ns)) {
+		rc = ENOENT;
+		goto fail;
+	}
+	
+	/* Serial port initialization (baud rate etc.). */
+	grlib_uart_initialize_port(ns);
+	
+	/* Register interrupt handler. */
+	if (grlib_uart_register_interrupt_handler(ns) != EOK) {
+		ddf_msg(LVL_ERROR, "Failed to register interrupt handler.");
+		rc = EADDRNOTAVAIL;
+		goto fail;
+	}
+	need_unreg_intr_handler = true;
+	
+	/* Enable interrupt. */
+	rc = grlib_uart_interrupt_enable(ns);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed to enable the interrupt. Error code = "
+		    "%d.", rc);
+		goto fail;
+	}
+	
+	fun = ddf_fun_create(dev, fun_exposed, "a");
+	if (fun == NULL) {
+		ddf_msg(LVL_ERROR, "Failed creating function.");
+		goto fail;
+	}
+	
+	/* Set device operations. */
+	ddf_fun_set_ops(fun, &grlib_uart_dev_ops);
+	rc = ddf_fun_bind(fun);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed binding function.");
+		goto fail;
+	}
+	
+	ns->fun = fun;
+	
+	ddf_fun_add_to_category(fun, "serial");
+	
+	ddf_msg(LVL_NOTE, "Device %s successfully initialized.",
+	    ddf_dev_get_name(dev));
+	
+	return EOK;
+	
+fail:
+	if (fun != NULL)
+		ddf_fun_destroy(fun);
+	
+	if (need_unreg_intr_handler)
+		grlib_uart_unregister_interrupt_handler(ns);
+	
+	if (need_cleanup)
+		grlib_uart_dev_cleanup(ns);
+	
+	return rc;
+}
+
+static int grlib_uart_dev_remove(ddf_dev_t *dev)
+{
+	grlib_uart_t *ns = dev_grlib_uart(dev);
+	
+	fibril_mutex_lock(&ns->mutex);
+	if (ns->client_connections > 0) {
+		fibril_mutex_unlock(&ns->mutex);
+		return EBUSY;
+	}
+	ns->removed = true;
+	fibril_mutex_unlock(&ns->mutex);
+	
+	int rc = ddf_fun_unbind(ns->fun);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed to unbind function.");
+		return rc;
+	}
+	
+	ddf_fun_destroy(ns->fun);
+	
+	grlib_uart_port_cleanup(ns);
+	grlib_uart_unregister_interrupt_handler(ns);
+	grlib_uart_dev_cleanup(ns);
+	return EOK;
+}
+
+/** Open the device.
+ *
+ * This is a callback function called when a client tries to connect to the
+ * device.
+ *
+ * @param dev The device.
+ *
+ */
+static int grlib_uart_open(ddf_fun_t *fun)
+{
+	grlib_uart_t *ns = fun_grlib_uart(fun);
+	int res;
+	
+	fibril_mutex_lock(&ns->mutex);
+	if (ns->removed) {
+		res = ENXIO;
+	} else {
+		res = EOK;
+		ns->client_connections++;
+	}
+	fibril_mutex_unlock(&ns->mutex);
+	
+	return res;
+}
+
+/** Close the device.
+ *
+ * This is a callback function called when a client tries to disconnect from
+ * the device.
+ *
+ * @param dev The device.
+ *
+ */
+static void grlib_uart_close(ddf_fun_t *fun)
+{
+	grlib_uart_t *data = fun_grlib_uart(fun);
+	
+	fibril_mutex_lock(&data->mutex);
+	
+	assert(data->client_connections > 0);
+	
+	if (!(--data->client_connections))
+		buf_clear(&data->input_buffer);
+	
+	fibril_mutex_unlock(&data->mutex);
+}
+
+/** Default handler for client requests which are not handled by the standard
+ * interfaces.
+ *
+ * Configure the parameters of the serial communication.
+ *
+ */
+static void grlib_uart_default_handler(ddf_fun_t *fun, ipc_callid_t callid,
+    ipc_call_t *call)
+{
+	sysarg_t method = IPC_GET_IMETHOD(*call);
+	
+	switch (method) {
+	default:
+		async_answer_0(callid, ENOTSUP);
+	}
+}
+
+/** Initialize the serial port driver.
+ *
+ * Initialize device operations structures with callback methods for handling
+ * client requests to the serial port devices.
+ *
+ */
+static void grlib_uart_init(void)
+{
+	ddf_log_init(NAME);
+	
+	grlib_uart_dev_ops.open = &grlib_uart_open;
+	grlib_uart_dev_ops.close = &grlib_uart_close;
+	
+	grlib_uart_dev_ops.interfaces[CHAR_DEV_IFACE] = &grlib_uart_char_dev_ops;
+	grlib_uart_dev_ops.default_handler = &grlib_uart_default_handler;
+}
+
+int main(int argc, char *argv[])
+{
+	printf("%s: HelenOS serial port driver\n", NAME);
+	grlib_uart_init();
+	return ddf_driver_main(&grlib_uart_driver);
+}
+
+/**
+ * @}
+ */
Index: uspace/drv/char/grlib_uart/grlib_uart.ma
===================================================================
--- uspace/drv/char/grlib_uart/grlib_uart.ma	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/drv/char/grlib_uart/grlib_uart.ma	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,1 @@
+10 amba/ven=01&dev=0000000c
Index: uspace/drv/infrastructure/rootleon3/Makefile
===================================================================
--- uspace/drv/infrastructure/rootleon3/Makefile	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/drv/infrastructure/rootleon3/Makefile	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2012 Jan Vesely
+# 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.
+#
+
+USPACE_PREFIX = ../../..
+LIBS = $(LIBDRV_PREFIX)/libdrv.a
+EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include
+BINARY = rootleon3
+
+SOURCES = \
+	rootleon3.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/drv/infrastructure/rootleon3/rootleon3.c
===================================================================
--- uspace/drv/infrastructure/rootleon3/rootleon3.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/drv/infrastructure/rootleon3/rootleon3.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2012 Jan Vesely
+ * Copyright (c) 2013 Jakub Klama
+ * 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.
+ */
+
+/**
+ * @defgroup root_leon3 SPARC LEON3 platform driver.
+ * @brief HelenOS SPARC LEON3 platform driver.
+ * @{
+ */
+/** @file
+ */
+
+#include <ddf/log.h>
+#include <errno.h>
+#include <ops/hw_res.h>
+#include <stdio.h>
+#include "rootleon3.h"
+
+#define NAME  "rootleon3"
+
+typedef struct {
+	const char *name;
+	match_id_t match_id;
+	hw_resource_list_t hw_resources;
+} rootleon3_fun_t;
+
+static hw_resource_t amba_res[] = {
+	{
+		.type = MEM_RANGE,
+		.res.mem_range = {
+			.address = AMBAPP_MASTER_AREA,
+			.size = AMBAPP_MASTER_SIZE,
+			.endianness = BIG_ENDIAN
+		}
+	},
+	{
+		.type = MEM_RANGE,
+		.res.mem_range = {
+			.address = AMBAPP_SLAVE_AREA,
+			.size = AMBAPP_SLAVE_SIZE,
+			.endianness = BIG_ENDIAN,
+		}
+	}
+};
+
+static const rootleon3_fun_t leon3_func = {
+	.name = "leon_amba",
+	.match_id = {
+		.id =  "leon_amba",
+		.score = 90 
+	},
+	.hw_resources = {
+		.count = 2,
+		.resources = amba_res
+	}
+};
+
+static hw_resource_list_t *rootleon3_get_resources(ddf_fun_t *);
+static bool rootleon3_enable_interrupt(ddf_fun_t *);
+
+static hw_res_ops_t fun_hw_res_ops = {
+	.get_resource_list = &rootleon3_get_resources,
+	.enable_interrupt = &rootleon3_enable_interrupt
+};
+
+static ddf_dev_ops_t rootleon3_fun_ops = {
+	.interfaces[HW_RES_DEV_IFACE] = &fun_hw_res_ops
+};
+
+static int rootleon3_add_fun(ddf_dev_t *dev, const rootleon3_fun_t *fun)
+{
+	assert(dev);
+	assert(fun);
+	
+	ddf_msg(LVL_DEBUG, "Adding new function '%s'.", fun->name);
+	
+	/* Create new device function. */
+	ddf_fun_t *fnode = ddf_fun_create(dev, fun_inner, fun->name);
+	if (fnode == NULL)
+		return ENOMEM;
+	
+	/* Add match id */
+	int ret = ddf_fun_add_match_id(fnode, fun->match_id.id,
+	    fun->match_id.score);
+	if (ret != EOK) {
+		ddf_fun_destroy(fnode);
+		return ret;
+	}
+	
+	/* Allocate needed data */
+	rootleon3_fun_t *rf =
+	    ddf_fun_data_alloc(fnode, sizeof(rootleon3_fun_t));
+	if (!rf) {
+		ddf_fun_destroy(fnode);
+		return ENOMEM;
+	}
+	*rf = *fun;
+	
+	/* Set provided operations to the device. */
+	ddf_fun_set_ops(fnode, &rootleon3_fun_ops);
+	
+	/* Register function. */
+	ret = ddf_fun_bind(fnode);
+	if (ret != EOK) {
+		ddf_msg(LVL_ERROR, "Failed binding function %s.", fun->name);
+		ddf_fun_destroy(fnode);
+		return ret;
+	}
+	
+	return EOK;
+}
+
+/** Add the root device.
+ *
+ * @param dev Device which is root of the whole device tree
+ *            (both of HW and pseudo devices).
+ *
+ * @return Zero on success, negative error number otherwise.
+ *
+ */
+static int rootleon3_dev_add(ddf_dev_t *dev)
+{
+	assert(dev);
+	
+	/* Register functions */
+	if (rootleon3_add_fun(dev, &leon3_func) != EOK) {
+		ddf_msg(LVL_ERROR, "Failed to add %s function for "
+		    "LEON3 platform.", leon3_func.name);
+	}
+	
+	return EOK;
+}
+
+/** The root device driver's standard operations. */
+static driver_ops_t rootleon3_ops = {
+	.dev_add = &rootleon3_dev_add
+};
+
+/** The root device driver structure. */
+static driver_t rootleon3_driver = {
+	.name = NAME,
+	.driver_ops = &rootleon3_ops
+};
+
+static hw_resource_list_t *rootleon3_get_resources(ddf_fun_t *fnode)
+{
+	rootleon3_fun_t *fun = ddf_fun_data_get(fnode);
+	assert(fun != NULL);
+	
+	printf("rootleon3_get_resources() called\n");
+	
+	return &fun->hw_resources;
+}
+
+static bool rootleon3_enable_interrupt(ddf_fun_t *fun)
+{
+	// FIXME TODO
+	return false;
+}
+
+int main(int argc, char *argv[])
+{
+	printf("%s: HelenOS SPARC LEON3 platform driver\n", NAME);
+	ddf_log_init(NAME);
+	return ddf_driver_main(&rootleon3_driver);
+}
+
+/**
+ * @}
+ */
Index: uspace/drv/infrastructure/rootleon3/rootleon3.h
===================================================================
--- uspace/drv/infrastructure/rootleon3/rootleon3.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/drv/infrastructure/rootleon3/rootleon3.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013 Jakub Klama
+ * 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 leon3drv
+ * @{
+ */
+/** @file
+ * @brief LEON3 root device.
+ */
+
+#ifndef ROOTLEON3_H
+#define ROOTLEON3_H
+
+#define AMBAPP_MASTER_AREA  0xfffff000
+#define AMBAPP_SLAVE_AREA   0xfffff800
+#define AMBAPP_MASTER_SIZE  0x800
+#define AMBAPP_SLAVE_SIZE   0x800
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/drv/infrastructure/rootleon3/rootleon3.ma
===================================================================
--- uspace/drv/infrastructure/rootleon3/rootleon3.ma	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/drv/infrastructure/rootleon3/rootleon3.ma	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,1 @@
+100 platform/leon3
Index: uspace/drv/infrastructure/rootmalta/rootmalta.c
===================================================================
--- uspace/drv/infrastructure/rootmalta/rootmalta.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/drv/infrastructure/rootmalta/rootmalta.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -52,7 +52,5 @@
 #include <ipc/dev_iface.h>
 #include <ops/hw_res.h>
-#include <device/hw_res.h>
 #include <ops/pio_window.h>
-#include <device/pio_window.h>
 #include <byteorder.h>
 
Index: uspace/drv/infrastructure/rootpc/rootpc.c
===================================================================
--- uspace/drv/infrastructure/rootpc/rootpc.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/drv/infrastructure/rootpc/rootpc.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -50,7 +50,5 @@
 #include <ipc/dev_iface.h>
 #include <ops/hw_res.h>
-#include <device/hw_res.h>
 #include <ops/pio_window.h>
-#include <device/pio_window.h>
 
 #define NAME "rootpc"
Index: uspace/drv/nic/e1k/e1k.c
===================================================================
--- uspace/drv/nic/e1k/e1k.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/drv/nic/e1k/e1k.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -50,5 +50,5 @@
 #include <ddf/interrupt.h>
 #include <device/hw_res_parsed.h>
-#include <device/pci.h>
+#include <pci_dev_iface.h>
 #include <nic.h>
 #include <ops/nic.h>
Index: uspace/drv/nic/rtl8139/driver.c
===================================================================
--- uspace/drv/nic/rtl8139/driver.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/drv/nic/rtl8139/driver.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -41,5 +41,5 @@
 #include <io/log.h>
 #include <nic.h>
-#include <device/pci.h>
+#include <pci_dev_iface.h>
 
 #include <ipc/irc.h>
@@ -190,6 +190,4 @@
 	return;
 }
-
-#include <device/pci.h>
 
 /** Set PmEn (Power management enable) bit value
Index: uspace/lib/c/Makefile
===================================================================
--- uspace/lib/c/Makefile	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/c/Makefile	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -61,5 +61,4 @@
 	generic/bd.c \
 	generic/bd_srv.c \
-	generic/bitops.c \
 	generic/cap.c \
 	generic/cfg.c \
@@ -70,11 +69,5 @@
 	generic/device/hw_res_parsed.c \
 	generic/device/pio_window.c \
-	generic/device/char_dev.c \
 	generic/device/clock_dev.c \
-	generic/device/battery_dev.c \
-	generic/device/graph_dev.c \
-	generic/device/nic.c \
-	generic/device/pci.c \
-	generic/device/ahci.c \
 	generic/dhcp.c \
 	generic/dnsr.c \
@@ -108,4 +101,5 @@
 	generic/io/log.c \
 	generic/io/logctl.c \
+	generic/io/kio.c \
 	generic/io/klog.c \
 	generic/io/snprintf.c \
@@ -129,4 +123,5 @@
 	generic/loader.c \
 	generic/getopt.c \
+	generic/adt/checksum.c \
 	generic/adt/list.c \
 	generic/adt/hash_table.c \
@@ -143,4 +138,5 @@
 	generic/net/socket_client.c \
 	generic/net/socket_parse.c \
+	generic/setjmp.c \
 	generic/stack.c \
 	generic/stacktrace.c \
Index: uspace/lib/c/arch/abs32le/include/libarch/atomic.h
===================================================================
--- uspace/lib/c/arch/abs32le/include/libarch/atomic.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/c/arch/abs32le/include/libarch/atomic.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -53,5 +53,6 @@
 }
 
-static inline void atomic_inc(atomic_t *val) {
+static inline void atomic_inc(atomic_t *val)
+{
 	/* On real hardware the increment has to be done
 	   as an atomic action. */
@@ -60,5 +61,6 @@
 }
 
-static inline void atomic_dec(atomic_t *val) {
+static inline void atomic_dec(atomic_t *val)
+{
 	/* On real hardware the decrement has to be done
 	   as an atomic action. */
Index: uspace/lib/c/arch/amd64/_link.ld.in
===================================================================
--- uspace/lib/c/arch/amd64/_link.ld.in	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/c/arch/amd64/_link.ld.in	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -39,4 +39,5 @@
 	.data : {
 		*(.data);
+		*(.data.rel*);
 	} :data
 	
Index: uspace/lib/c/arch/ia32/Makefile.inc
===================================================================
--- uspace/lib/c/arch/ia32/Makefile.inc	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/c/arch/ia32/Makefile.inc	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -34,5 +34,4 @@
 	arch/$(UARCH)/src/fibril.S \
 	arch/$(UARCH)/src/tls.c \
-	arch/$(UARCH)/src/setjmp.S \
 	arch/$(UARCH)/src/stacktrace.c \
 	arch/$(UARCH)/src/stacktrace_asm.S \
Index: pace/lib/c/arch/ia32/src/setjmp.S
===================================================================
--- uspace/lib/c/arch/ia32/src/setjmp.S	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,55 +1,0 @@
-#
-# Copyright (c) 2008 Josef Cejka
-# 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.
-#
-
-#include <libarch/context_offset.h>
-
-.text
-.global setjmp
-.global longjmp
-
-.type setjmp,@function
-setjmp:
-	movl 0(%esp), %eax  # save pc value into eax
-	movl 4(%esp), %edx  # address of the jmp_buf structure to save context to
-	
-	# save registers to the jmp_buf structure
-	CONTEXT_SAVE_ARCH_CORE %edx %eax
-	
-	xorl %eax, %eax     # set_jmp returns 0
-	ret
-
-.type longjmp,@function
-longjmp:
-	movl 4(%esp), %ecx  # put address of jmp_buf into ecx
-	movl 8(%esp), %eax  # put return value into eax
-	
-	# restore registers from the jmp_buf structure
-	CONTEXT_RESTORE_ARCH_CORE %ecx %edx
-	
-	movl %edx, 0(%esp)  # put saved pc on stack
-	ret
Index: uspace/lib/c/arch/sparc32/Makefile.common
===================================================================
--- uspace/lib/c/arch/sparc32/Makefile.common	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/c/arch/sparc32/Makefile.common	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,34 @@
+#
+# Copyright (c) 2006 Martin Decky
+# 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.
+#
+
+LFLAGS = -no-check-sections
+
+ENDIANESS = BE
+
+BFD_NAME = elf32-sparc
+BFD_ARCH = sparc
Index: uspace/lib/c/arch/sparc32/Makefile.inc
===================================================================
--- uspace/lib/c/arch/sparc32/Makefile.inc	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/c/arch/sparc32/Makefile.inc	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2006 Martin Decky
+# 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.
+#
+
+ARCH_SOURCES = \
+	arch/$(UARCH)/src/entry.s \
+	arch/$(UARCH)/src/entryjmp.s \
+	arch/$(UARCH)/src/thread_entry.s \
+	arch/$(UARCH)/src/fibril.S \
+	arch/$(UARCH)/src/tls.c \
+	arch/$(UARCH)/src/stacktrace.c \
+	arch/$(UARCH)/src/stacktrace_asm.S
+
+.PRECIOUS: arch/$(UARCH)/src/entry.o
Index: uspace/lib/c/arch/sparc32/_link.ld.in
===================================================================
--- uspace/lib/c/arch/sparc32/_link.ld.in	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/c/arch/sparc32/_link.ld.in	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,68 @@
+STARTUP(LIBC_PATH/arch/UARCH/src/entry.o)
+ENTRY(__entry)
+
+PHDRS {
+#ifdef LOADER
+	interp PT_INTERP;
+	text PT_LOAD FILEHDR PHDRS FLAGS(5);
+#else
+	text PT_LOAD FLAGS(5);
+#endif
+	data PT_LOAD FLAGS(6);
+}
+
+SECTIONS {
+#ifdef LOADER
+	. = 0x70004000 + SIZEOF_HEADERS;
+#else
+	. = 0x4000 + SIZEOF_HEADERS;
+#endif
+	
+	.init : {
+		*(.init);
+	} :text
+	
+	.text : {
+		*(.text .text.*);
+		*(.rodata .rodata.*);
+	} :text
+	
+#ifdef LOADER
+	.interp : {
+		*(.interp);
+	} :interp :text
+#endif
+	
+	. = . + 0x4000;
+	
+	.got : {
+		 _gp = .;
+		 *(.got*);
+	} :data
+	
+	.data : {
+		*(.data);
+		*(.sdata);
+	} :data
+	
+	.tdata : {
+		_tdata_start = .;
+		*(.tdata);
+		_tdata_end = .;
+		_tbss_start = .;
+		*(.tbss);
+		_tbss_end = .;
+	} :data
+	
+	_tls_alignment = ALIGNOF(.tdata);
+	
+	.bss : {
+		*(.sbss);
+		*(COMMON);
+		*(.bss);
+	} :data
+	
+	/DISCARD/ : {
+		*(*);
+	}
+}
Index: uspace/lib/c/arch/sparc32/include/libarch/atomic.h
===================================================================
--- uspace/lib/c/arch/sparc32/include/libarch/atomic.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/c/arch/sparc32/include/libarch/atomic.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2005 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 libcsparc32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_sparc32_ATOMIC_H_
+#define LIBC_sparc32_ATOMIC_H_
+
+#define LIBC_ARCH_ATOMIC_H_
+
+#define CAS
+
+#include <atomicdflt.h>
+#include <sys/types.h>
+
+static inline bool cas(atomic_t *val, atomic_count_t ov, atomic_count_t nv)
+{
+	if (val->count == ov) {
+		val->count = nv;
+		return true;
+	}
+	
+	return false;
+}
+
+static inline void atomic_inc(atomic_t *val)
+{
+	// FIXME TODO
+	val->count++;
+}
+
+static inline void atomic_dec(atomic_t *val)
+{
+	// FIXME TODO
+	val->count++;
+}
+
+static inline atomic_count_t atomic_postinc(atomic_t *val)
+{
+	// FIXME TODO
+	
+	atomic_count_t prev = val->count;
+	
+	val->count++;
+	return prev;
+}
+
+static inline atomic_count_t atomic_postdec(atomic_t *val)
+{
+	// FIXME TODO
+	
+	atomic_count_t prev = val->count;
+	
+	val->count--;
+	return prev;
+}
+
+#define atomic_preinc(val) (atomic_postinc(val) + 1)
+#define atomic_predec(val) (atomic_postdec(val) - 1)
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/sparc32/include/libarch/barrier.h
===================================================================
--- uspace/lib/c/arch/sparc32/include/libarch/barrier.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/c/arch/sparc32/include/libarch/barrier.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,1 @@
+../../../../../../../kernel/arch/sparc32/include/arch/barrier.h
Index: uspace/lib/c/arch/sparc32/include/libarch/config.h
===================================================================
--- uspace/lib/c/arch/sparc32/include/libarch/config.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/c/arch/sparc32/include/libarch/config.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,44 @@
+/*
+ * 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 libcsparc32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_sparc32_CONFIG_H_
+#define LIBC_sparc32_CONFIG_H_
+
+#define PAGE_WIDTH  12
+#define PAGE_SIZE   (1 << PAGE_WIDTH)
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/sparc32/include/libarch/context_offset.h
===================================================================
--- uspace/lib/c/arch/sparc32/include/libarch/context_offset.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/c/arch/sparc32/include/libarch/context_offset.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,1 @@
+../../../../../../../kernel/arch/sparc32/include/arch/context_offset.h
Index: uspace/lib/c/arch/sparc32/include/libarch/ddi.h
===================================================================
--- uspace/lib/c/arch/sparc32/include/libarch/ddi.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/c/arch/sparc32/include/libarch/ddi.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2009 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.
+ */
+
+/** @file
+ * @ingroup libsparc32
+ */
+
+#ifndef LIBC_sparc32_DDI_H_
+#define LIBC_sparc32_DDI_H_
+
+#include <sys/types.h>
+#include <libarch/types.h>
+
+static inline void memory_barrier(void)
+{
+	asm volatile (
+		"stbar\n"
+		::: "memory"
+	);
+}
+
+static inline void arch_pio_write_8(ioport8_t *port, uint8_t v)
+{
+	*port = v;
+	memory_barrier();
+}
+
+static inline void arch_pio_write_16(ioport16_t *port, uint16_t v)
+{
+	*port = v;
+	memory_barrier();
+}
+
+static inline void arch_pio_write_32(ioport32_t *port, uint32_t v)
+{
+	*port = v;
+	memory_barrier();
+}
+
+static inline uint8_t arch_pio_read_8(const ioport8_t *port)
+{
+	uint8_t rv = *port;
+	memory_barrier();
+	
+	return rv;
+}
+
+static inline uint16_t arch_pio_read_16(const ioport16_t *port)
+{
+	uint16_t rv = *port;
+	memory_barrier();
+	
+	return rv;
+}
+
+static inline uint32_t arch_pio_read_32(const ioport32_t *port)
+{
+	uint32_t rv = *port;
+	memory_barrier();
+	
+	return rv;
+}
+
+#endif
Index: uspace/lib/c/arch/sparc32/include/libarch/elf.h
===================================================================
--- uspace/lib/c/arch/sparc32/include/libarch/elf.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/c/arch/sparc32/include/libarch/elf.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,1 @@
+../../../../../../../kernel/arch/sparc32/include/arch/elf.h
Index: uspace/lib/c/arch/sparc32/include/libarch/elf_linux.h
===================================================================
--- uspace/lib/c/arch/sparc32/include/libarch/elf_linux.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/c/arch/sparc32/include/libarch/elf_linux.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2011 Jiri Svoboda
+ * 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 libcsparc32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_sparc32_ELF_LINUX_H_
+#define LBIC_sparc32_ELF_LINUX_H_
+
+#include <libarch/istate.h>
+#include <sys/types.h>
+
+typedef struct {
+	/* TODO */
+	uint64_t pad[16];
+} elf_regs_t;
+
+static inline void istate_to_elf_regs(istate_t *istate, elf_regs_t *elf_regs)
+{
+	/* TODO */
+	(void) istate;
+	(void) elf_regs;
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/sparc32/include/libarch/faddr.h
===================================================================
--- uspace/lib/c/arch/sparc32/include/libarch/faddr.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/c/arch/sparc32/include/libarch/faddr.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2005 Ondrej Palkovsky
+ * 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 libcsparc32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_sparc32_FADDR_H_
+#define LIBC_sparc32_FADDR_H_
+
+#include <libarch/types.h>
+
+#define FADDR(fptr)  ((uintptr_t) (fptr))
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/sparc32/include/libarch/fibril.h
===================================================================
--- uspace/lib/c/arch/sparc32/include/libarch/fibril.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/c/arch/sparc32/include/libarch/fibril.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2005 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 libcsparc32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_sparc32_FIBRIL_H_
+#define LIBC_sparc32_FIBRIL_H_
+
+#include <libarch/stack.h>
+#include <sys/types.h>
+#include <align.h>
+
+#define SP_DELTA  (STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE)
+
+#define context_set(c, _pc, stack, size, ptls) \
+	do { \
+		(c)->pc = ((uintptr_t) _pc) - 8; \
+		(c)->sp = ((uintptr_t) stack) + ALIGN_UP((size), \
+		    STACK_ALIGNMENT) - (SP_DELTA); \
+		(c)->fp = 0; \
+		(c)->tp = (uint32_t) ptls; \
+	} while (0)
+
+/*
+ * Save only registers that must be preserved across
+ * function calls.
+ */
+typedef struct {
+	uintptr_t sp;  /* %o6 */
+	uintptr_t pc;  /* %o7 */
+	uint32_t i0;
+	uint32_t i1;
+	uint32_t i2;
+	uint32_t i3;
+	uint32_t i4;
+	uint32_t i5;
+	uintptr_t fp;  /* %i6 */
+	uintptr_t i7;
+	uint32_t l0;
+	uint32_t l1;
+	uint32_t l2;
+	uint32_t l3;
+	uint32_t l4;
+	uint32_t l5;
+	uint32_t l6;
+	uint32_t l7;
+	uint32_t tp;  /* %g7 */
+} context_t;
+
+static inline uintptr_t context_get_fp(context_t *ctx)
+{
+	return ctx->sp;
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/sparc32/include/libarch/inttypes.h
===================================================================
--- uspace/lib/c/arch/sparc32/include/libarch/inttypes.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/c/arch/sparc32/include/libarch/inttypes.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2010 Jiri Svoboda
+ * 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 libcsparc32
+ * @{
+ */
+
+#ifndef LIBC_sparc32_INTTYPES_H_
+#define LIBC_sparc32_INTTYPES_H_
+
+#define PRIdn  PRId32  /**< Format for native_t. */
+#define PRIun  PRIu32  /**< Format for sysarg_t. */
+#define PRIxn  PRIx32  /**< Format for hexadecimal sysarg_t. */
+#define PRIua  PRIu32  /**< Format for atomic_count_t. */
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/sparc32/include/libarch/istate.h
===================================================================
--- uspace/lib/c/arch/sparc32/include/libarch/istate.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/c/arch/sparc32/include/libarch/istate.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,1 @@
+../../../../../../../kernel/arch/sparc32/include/arch/istate.h
Index: uspace/lib/c/arch/sparc32/include/libarch/stack.h
===================================================================
--- uspace/lib/c/arch/sparc32/include/libarch/stack.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/c/arch/sparc32/include/libarch/stack.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2005 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 libcsparc32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_sparc32_STACK_H_
+#define LIBC_sparc32_STACK_H_
+
+#define STACK_ITEM_SIZE  4
+
+#define STACK_ALIGNMENT  8
+
+/** 16-extended-word save area for %i[0-7] and %l[0-7] registers. */
+#define STACK_WINDOW_SAVE_AREA_SIZE  (16 * STACK_ITEM_SIZE)
+
+/* Six extended words for first six arguments. */
+#define STACK_ARG_SAVE_AREA_SIZE  (6 * STACK_ITEM_SIZE)
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/sparc32/include/libarch/stackarg.h
===================================================================
--- uspace/lib/c/arch/sparc32/include/libarch/stackarg.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/c/arch/sparc32/include/libarch/stackarg.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2006 Josef Cejka
+ * 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 libcsparc32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_sparc32_STACKARG_H_
+#define LIBC_sparc32_STACKARG_H_
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/sparc32/include/libarch/syscall.h
===================================================================
--- uspace/lib/c/arch/sparc32/include/libarch/syscall.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/c/arch/sparc32/include/libarch/syscall.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2005 Martin Decky
+ * 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 libcsparc32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_sparc32_SYSCALL_H_
+#define LIBC_sparc32_SYSCALL_H_
+
+#include <sys/types.h>
+#include <abi/syscall.h>
+
+#define __syscall0  __syscall
+#define __syscall1  __syscall
+#define __syscall2  __syscall
+#define __syscall3  __syscall
+#define __syscall4  __syscall
+#define __syscall5  __syscall
+#define __syscall6  __syscall
+
+static inline sysarg_t __syscall(const sysarg_t p1, const sysarg_t p2,
+    const sysarg_t p3, const sysarg_t p4, const sysarg_t p5, const sysarg_t p6,
+    const syscall_t id)
+{
+	register uint32_t a1 asm("o0") = p1;
+	register uint32_t a2 asm("o1") = p2;
+	register uint32_t a3 asm("o2") = p3;
+	register uint32_t a4 asm("o3") = p4;
+	register uint32_t a5 asm("o4") = p5;
+	register uint32_t a6 asm("o5") = p6;
+	
+	asm volatile (
+		"ta %7\n"
+		: "=r" (a1)
+		: "r" (a1),
+		  "r" (a2),
+		  "r" (a3),
+		  "r" (a4),
+		  "r" (a5),
+		  "r" (a6),
+		  "i" (id)
+		: "memory"
+	);
+	
+	return a1;
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/sparc32/include/libarch/thread.h
===================================================================
--- uspace/lib/c/arch/sparc32/include/libarch/thread.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/c/arch/sparc32/include/libarch/thread.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2006 Ondrej Palkovsky
+ * 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 libcsparc32
+ * @{
+ */
+
+#ifndef LIBC_sparc32_THREAD_H_
+#define LIBC_sparc32_THREAD_H_
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/sparc32/include/libarch/tls.h
===================================================================
--- uspace/lib/c/arch/sparc32/include/libarch/tls.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/c/arch/sparc32/include/libarch/tls.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2006 Ondrej Palkovsky
+ * 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 libcsparc32
+ * @{
+ */
+/** @file
+ * @brief sparc32 TLS functions.
+ */
+
+#ifndef LIBC_sparc32_TLS_H_
+#define LIBC_sparc32_TLS_H_
+
+#define CONFIG_TLS_VARIANT_2
+
+typedef struct {
+	void *self;
+	void *fibril_data;
+} tcb_t;
+
+static inline void __tcb_set(tcb_t *tcb)
+{
+	asm volatile (
+		"mov %0, %%g7\n"
+		:: "r" (tcb)
+		: "g7"
+	);
+}
+
+static inline tcb_t *__tcb_get(void)
+{
+	void *retval;
+	
+	asm volatile (
+		"mov %%g7, %0\n"
+		: "=r" (retval)
+	);
+	
+	return retval;
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/sparc32/include/libarch/types.h
===================================================================
--- uspace/lib/c/arch/sparc32/include/libarch/types.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/c/arch/sparc32/include/libarch/types.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2005 Martin Decky
+ * 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 libcsparc32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_sparc32_TYPES_H_
+#define LIBC_sparc32_TYPES_H_
+
+#define __32_BITS__
+
+#include <libarch/common.h>
+
+#define SIZE_MIN  UINT32_MIN
+#define SIZE_MAX  UINT32_MAX
+
+#define SSIZE_MIN  INT32_MIN
+#define SSIZE_MAX  INT32_MAX
+
+typedef uint32_t sysarg_t;
+typedef int32_t native_t;
+
+typedef int32_t ssize_t;
+typedef uint32_t size_t;
+
+typedef uint32_t uintptr_t;
+typedef int32_t intptr_t;
+typedef uint32_t atomic_count_t;
+typedef int32_t atomic_signed_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/sparc32/src/entry.s
===================================================================
--- uspace/lib/c/arch/sparc32/src/entry.s	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/c/arch/sparc32/src/entry.s	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,67 @@
+#
+# Copyright (c) 2006 Martin Decky
+# 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.
+#
+
+.section .init, "ax"
+
+.org 0
+
+.globl __entry
+
+## User-space task entry point
+#
+# %o0 contains uarg
+# %o1 contains pcb_ptr
+#
+__entry:
+	#
+	# Create the first stack frame.
+	#
+	
+	save %sp, -176, %sp
+	## XXX	flushw
+	mov 7, %g1
+	1:
+		subcc %g1, 1, %g1
+		bg 1b
+		save %sp, -64, %sp
+	
+	mov 7, %g1
+	1:
+		subcc %g1, 1, %g1
+		bg 1b
+		restore
+	
+	## XXX end flush
+	## add %g0, -0x7ff, %fp
+	set 0x80000000, %fp
+	
+	# Pass pcb_ptr as the first argument to __main()
+	mov %i1, %o0
+	sethi %hi(_gp), %l7
+	call __main
+	or %l7, %lo(_gp), %l7
Index: uspace/lib/c/arch/sparc32/src/entryjmp.s
===================================================================
--- uspace/lib/c/arch/sparc32/src/entryjmp.s	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/c/arch/sparc32/src/entryjmp.s	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,42 @@
+#
+# Copyright (c) 2008 Jiri Svoboda
+# 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.
+#
+
+.globl entry_point_jmp
+
+## void entry_point_jmp(void *entry_point, void *pcb);
+#
+# %o0	contains entry_point
+# %o1	contains pcb
+#
+# Jump to program entry point
+entry_point_jmp:
+	# Pass pcb pointer to entry point in %o1. As it is already
+	# there, no action is needed.
+	call %o0
+	nop
+	# FIXME: use branch instead of call
Index: uspace/lib/c/arch/sparc32/src/fibril.S
===================================================================
--- uspace/lib/c/arch/sparc32/src/fibril.S	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/c/arch/sparc32/src/fibril.S	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,85 @@
+#
+# Copyright (c) 2005 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.
+#
+
+#include <libarch/context_offset.h>
+
+.text
+
+.global flush_windows
+.global context_save
+.global context_restore
+
+context_save:
+	#
+	# We rely on the kernel to flush our active register windows to memory
+	# should a thread switch occur.
+	#
+	
+	mov 7, %g1
+	1:
+		subcc %g1, 1, %g1
+		bg 1b
+		save %sp, -64, %sp
+	
+	mov 7, %g1
+	1:
+		subcc %g1, 1, %g1
+		bg 1b
+		restore
+	
+	CONTEXT_SAVE_ARCH_CORE %o0
+	retl
+	mov 1, %o0              ! context_save_arch returns 1
+
+context_restore:
+	#
+	# Flush all active windows.
+	# This is essential, because CONTEXT_RESTORE_ARCH_CORE overwrites %sp of
+	# CWP - 1 with the value written to %fp of CWP.  Flushing all active
+	# windows mitigates this problem as CWP - 1 becomes the overlap window.
+	#
+	
+	## XXX
+	## flushw
+	## ta 0x4f
+	## nop
+	mov 7, %g1
+	1:
+		subcc %g1, 1, %g1
+		bg 1b
+		save %sp, -64, %sp
+	
+	mov 7, %g1
+	1:
+		subcc %g1, 1, %g1
+		bg 1b
+		restore
+	
+	CONTEXT_RESTORE_ARCH_CORE %o0
+	retl
+	xor %o0, %o0, %o0       ! context_restore_arch returns 0
Index: uspace/lib/c/arch/sparc32/src/stacktrace.c
===================================================================
--- uspace/lib/c/arch/sparc32/src/stacktrace.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/c/arch/sparc32/src/stacktrace.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2010 Jakub Jermar
+ * Copyright (c) 2010 Jiri Svoboda
+ * Copyright (c) 2013 Jakub Klama
+ * 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 sparc32
+ * @{
+ */
+/** @file
+ */
+
+#include <sys/types.h>
+#include <stdbool.h>
+#include <libarch/stack.h>
+#include <errno.h>
+#include <stacktrace.h>
+
+#define FRAME_OFFSET_FP_PREV  (14 * 4)
+#define FRAME_OFFSET_RA       (15 * 4)
+
+bool stacktrace_fp_valid(stacktrace_t *st, uintptr_t fp)
+{
+	(void) st;
+	return fp != 0;
+}
+
+int stacktrace_fp_prev(stacktrace_t *st, uintptr_t fp, uintptr_t *prev)
+{
+	uintptr_t bprev;
+	int rc = (*st->read_uintptr)(st->op_arg, fp + FRAME_OFFSET_FP_PREV,
+	    &bprev);
+	if (rc == EOK)
+		*prev = bprev;
+	
+	return rc;
+}
+
+int stacktrace_ra_get(stacktrace_t *st, uintptr_t fp, uintptr_t *ra)
+{
+	return (*st->read_uintptr)(st->op_arg, fp + FRAME_OFFSET_RA, ra);
+}
+
+/** @}
+ */
Index: uspace/lib/c/arch/sparc32/src/stacktrace_asm.S
===================================================================
--- uspace/lib/c/arch/sparc32/src/stacktrace_asm.S	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/c/arch/sparc32/src/stacktrace_asm.S	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,63 @@
+#
+# Copyright (c) 2009 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.
+#
+
+#include <libarch/stack.h>
+
+.text
+
+.global stacktrace_prepare
+.global stacktrace_fp_get
+.global stacktrace_pc_get
+
+stacktrace_prepare:
+	save %sp, -(STACK_WINDOW_SAVE_AREA_SIZE+STACK_ARG_SAVE_AREA_SIZE), %sp
+	
+	# Flush all other windows to memory so that we can read their contents.
+	
+	mov 7, %g1
+	1:
+		subcc %g1, 1, %g1
+		bg 1b
+		save %sp, -64, %sp
+	
+	mov 7, %g1
+	1:
+		subcc %g1, 1, %g1
+		bg 1b
+	
+	ret
+	restore
+
+stacktrace_fp_get:
+	# Add the stack bias to %sp to get the actual address.
+	retl
+	mov %sp,  %o0
+
+stacktrace_pc_get:
+	retl
+	mov %o7, %o0
Index: uspace/lib/c/arch/sparc32/src/thread_entry.s
===================================================================
--- uspace/lib/c/arch/sparc32/src/thread_entry.s	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/c/arch/sparc32/src/thread_entry.s	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,69 @@
+#
+# 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.
+#
+
+.text
+
+.globl __thread_entry
+
+## User-space thread entry point for all but the first threads.
+#
+#
+__thread_entry:
+	#
+	# Create the first stack frame.
+	#
+	
+	save %sp, -176, %sp
+	## XXX flushw
+	mov 7, %g1
+	1:
+		subcc %g1, 1, %g1
+		bg 1b
+		save %sp, -64, %sp
+	
+	mov 7, %g1
+	1:
+		subcc %g1, 1, %g1
+		bg 1b
+	
+	## XXX end flushw
+	set 0x80000000, %fp
+	
+	#
+	# Propagate the input arguments to the new window.
+	#
+	
+	mov %i0, %o0
+	
+	sethi %hi(_gp), %l7
+	call __thread_main      ! %o0 contains address of uarg
+	or %l7, %lo(_gp), %l7
+	
+	! not reached
+	
+.end __thread_entry
Index: uspace/lib/c/arch/sparc32/src/tls.c
===================================================================
--- uspace/lib/c/arch/sparc32/src/tls.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/c/arch/sparc32/src/tls.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2006 Ondrej Palkovsky
+ * 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 libcsparc32 sparc32
+ * @ingroup lc
+ * @{
+ */
+/** @file
+ *
+ */
+
+#include <tls.h>
+#include <sys/types.h>
+
+tcb_t *tls_alloc_arch(void **data, size_t size)
+{
+	return tls_alloc_variant_2(data, size);
+}
+
+void tls_free_arch(tcb_t *tcb, size_t size)
+{
+	tls_free_variant_2(tcb, size);
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/adt/checksum.c
===================================================================
--- uspace/lib/c/generic/adt/checksum.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/c/generic/adt/checksum.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2012 Dominik Taborsky
+ * 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.
+ */
+
+#include <adt/checksum.h>
+
+/**
+ * 256-value table of precomputed polynomials for CRC32. Note
+ * the values depend on the selected divisor polynomial (currently
+ * 0xedb88320) and whether the CRC computation is reflected or not.
+ * See http://www.repairfaq.org/filipg/LINK/F_crc_v3.html for a perfect
+ * source of info about this.
+ */
+uint32_t poly_table[256] = {
+	0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
+	0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
+	0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+	0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
+	0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+	0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+	0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
+	0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
+	0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+	0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+	0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
+	0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+	0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
+	0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
+	0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+	0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
+	0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
+	0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+	0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
+	0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+	0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+	0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
+	0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
+	0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+	0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+	0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
+	0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+	0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
+	0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
+	0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+	0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
+	0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
+	0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+	0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
+	0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+	0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+	0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
+	0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
+	0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+	0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+	0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
+	0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+	0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
+	0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
+	0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+	0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
+	0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
+	0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+	0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
+	0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+	0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+	0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
+	0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
+	0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+	0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+	0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
+	0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+	0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
+	0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
+	0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+	0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
+	0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
+	0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+	0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+};
+
+/** Compute CRC32 value.
+ *
+ * See wiki.osdev.org/CRC32 for reference.
+ *
+ * @param[in] data   Data to process.
+ * @param[in] length Length of the data in bytes.
+ *
+ * @return Computed CRC32 of the data.
+ *
+ */
+uint32_t compute_crc32(uint8_t *data, size_t length)
+{
+	return compute_crc32_seed(data, length, 0);
+}
+
+/** Compute CRC32 value with initial seed.
+ *
+ * Use this when checksumming non-continous data (linked lists, trees,
+ * etc.). On the first data block call compute_crc32() and use the result
+ * as the seed for the following call of compute_crc32_seed() on the next
+ * block. Then use the result of that call as the seed of the following
+ * call, etc.
+ *
+ * @param[in] data   Fata to process.
+ * @param[in] length Length of the data in bytes.
+ * @param[in] seed   The starting value of the CRC.
+ *
+ * @return Computed CRC32 of the data of all the previous blocks.
+ *
+ */
+uint32_t compute_crc32_seed(uint8_t *data, size_t length, uint32_t seed)
+{
+	uint32_t crc;
+	
+	for (crc = ~seed; length > 0; length--)
+		crc = poly_table[((uint8_t) crc ^ *(data++))] ^ (crc >> 8);
+	
+	return (~crc);
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/assert.c
===================================================================
--- uspace/lib/c/generic/assert.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/c/generic/assert.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -33,5 +33,5 @@
 #include <assert.h>
 #include <stdio.h>
-#include <io/klog.h>
+#include <io/kio.h>
 #include <stdlib.h>
 #include <atomic.h>
@@ -44,7 +44,7 @@
 {
 	/*
-	 * Send the message safely to klog. Nested asserts should not occur.
+	 * Send the message safely to kio. Nested asserts should not occur.
 	 */
-	klog_printf("Assertion failed (%s) in file \"%s\", line %u.\n",
+	kio_printf("Assertion failed (%s) in file \"%s\", line %u.\n",
 	    cond, file, line);
 	
Index: pace/lib/c/generic/bitops.c
===================================================================
--- uspace/lib/c/generic/bitops.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,48 +1,0 @@
-/*
- * Copyright (c) 2013 Vojtech Horky
- * 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 libc
- * @{
- */
-
-#include <bitops.h>
-
-int __popcountsi2(int a)
-{
-	int bits = 0;
-	for (unsigned int i = 0; i < sizeof(a) * 8; i++)	 {
-		if (((a >> i) & 1) != 0) {
-			bits++;
-		}
-	}
-	return bits;									
-}
-
-
-/** @}
- */
Index: uspace/lib/c/generic/ddi.c
===================================================================
--- uspace/lib/c/generic/ddi.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/c/generic/ddi.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -280,5 +280,5 @@
  *
  */
-int irq_register(int inr, int devno, int method, irq_code_t *ucode)
+int irq_register(int inr, int devno, int method, const irq_code_t *ucode)
 {
 	return __SYSCALL4(SYS_IRQ_REGISTER, inr, devno, method,
Index: pace/lib/c/generic/device/ahci.c
===================================================================
--- uspace/lib/c/generic/device/ahci.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,185 +1,0 @@
-/*
- * Copyright (c) 2012 Petr Jerman
- * 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 libc
- * @{
- */
-/** @file
- */
-
-#include <ipc/dev_iface.h>
-#include <assert.h>
-#include <device/ahci.h>
-#include <errno.h>
-#include <async.h>
-#include <ipc/services.h>
-#include <stdio.h>
-#include <as.h>
-
-typedef enum {
-	IPC_M_AHCI_GET_SATA_DEVICE_NAME,
-	IPC_M_AHCI_GET_NUM_BLOCKS,
-	IPC_M_AHCI_GET_BLOCK_SIZE,
-	IPC_M_AHCI_READ_BLOCKS,
-	IPC_M_AHCI_WRITE_BLOCKS,
-} ahci_iface_funcs_t;
-
-#define MAX_NAME_LENGTH  1024
-
-#define LO(ptr) \
-	((uint32_t) (((uint64_t) ((uintptr_t) (ptr))) & 0xffffffff))
-
-#define HI(ptr) \
-	((uint32_t) (((uint64_t) ((uintptr_t) (ptr))) >> 32))
-
-async_sess_t* ahci_get_sess(devman_handle_t funh, char **name)
-{
-	// FIXME: Use a better way than substring match
-	
-	*name = NULL;
-	
-	char devn[MAX_NAME_LENGTH];
-	int rc = devman_fun_get_name(funh, devn, MAX_NAME_LENGTH);
-	if (rc != EOK)
-		return NULL;
-	
-	size_t devn_size = str_size(devn);
-	
-	if ((devn_size > 5) && (str_lcmp(devn, "ahci_", 5) == 0)) {
-		async_sess_t *sess = devman_device_connect(EXCHANGE_PARALLEL,
-		    funh, IPC_FLAG_BLOCKING);
-		
-		if (sess) {
-			*name = str_dup(devn);
-			return sess;
-		}
-	}
-	
-	return NULL;
-}
-
-int ahci_get_sata_device_name(async_sess_t *sess, size_t sata_dev_name_length,
-    char *sata_dev_name)
-{
-	async_exch_t *exch = async_exchange_begin(sess);
-	if (!exch)
-		return EINVAL;
-	
-	aid_t req = async_send_2(exch, DEV_IFACE_ID(AHCI_DEV_IFACE),
-	    IPC_M_AHCI_GET_SATA_DEVICE_NAME, sata_dev_name_length, NULL);
-	
-	async_data_read_start(exch, sata_dev_name, sata_dev_name_length);
-	
-	sysarg_t rc;
-	async_wait_for(req, &rc);
-	
-	return rc;
-}
-
-int ahci_get_num_blocks(async_sess_t *sess, uint64_t *blocks)
-{
-	async_exch_t *exch = async_exchange_begin(sess);
-	if (!exch)
-		return EINVAL;
-	
-	sysarg_t blocks_hi;
-	sysarg_t blocks_lo;
-	int rc = async_req_1_2(exch, DEV_IFACE_ID(AHCI_DEV_IFACE),
-	    IPC_M_AHCI_GET_NUM_BLOCKS, &blocks_hi, &blocks_lo);
-	
-	async_exchange_end(exch);
-	
-	if (rc == EOK) {
-		*blocks = (((uint64_t) blocks_hi) << 32)
-		    | (((uint64_t) blocks_lo) & 0xffffffff);
-	}
-	
-	return rc;
-}
-
-int ahci_get_block_size(async_sess_t *sess, size_t *blocks_size)
-{
-	async_exch_t *exch = async_exchange_begin(sess);
-	if (!exch)
-		return EINVAL;
-	
-	sysarg_t bs;
-	int rc = async_req_1_1(exch, DEV_IFACE_ID(AHCI_DEV_IFACE),
-	    IPC_M_AHCI_GET_BLOCK_SIZE, &bs);
-	
-	async_exchange_end(exch);
-	
-	if (rc == EOK)
-		*blocks_size = (size_t) bs;
-	
-	return rc;
-}
-
-int ahci_read_blocks(async_sess_t *sess, uint64_t blocknum, size_t count,
-    void *buf)
-{
-	async_exch_t *exch = async_exchange_begin(sess);
-	if (!exch)
-		return EINVAL;
-	
-	aid_t req;
-	req = async_send_4(exch, DEV_IFACE_ID(AHCI_DEV_IFACE),
-	    IPC_M_AHCI_READ_BLOCKS, HI(blocknum),  LO(blocknum), count, NULL);
-	
-	async_share_out_start(exch, buf, AS_AREA_READ | AS_AREA_WRITE);
-	
-	async_exchange_end(exch);
-	
-	sysarg_t rc;
-	async_wait_for(req, &rc);
-	
-	return rc;
-}
-
-int ahci_write_blocks(async_sess_t *sess, uint64_t blocknum, size_t count,
-    void* buf)
-{
-	async_exch_t *exch = async_exchange_begin(sess);
-	if (!exch)
-		return EINVAL;
-	
-	aid_t req = async_send_4(exch, DEV_IFACE_ID(AHCI_DEV_IFACE),
-	    IPC_M_AHCI_WRITE_BLOCKS, HI(blocknum),  LO(blocknum), count, NULL);
-	
-	async_share_out_start(exch, buf, AS_AREA_READ | AS_AREA_WRITE);
-	
-	async_exchange_end(exch);
-	
-	sysarg_t rc;
-	async_wait_for(req, &rc);
-	
-	return rc;
-}
-
-/** @}
- */
Index: pace/lib/c/generic/device/battery_dev.c
===================================================================
--- uspace/lib/c/generic/device/battery_dev.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,93 +1,0 @@
-/*
- * Copyright (c) 2012 Maurizio Lombardi
- * 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 libc
- * @{
- */
-/** @file
- */
-
-#include <ipc/dev_iface.h>
-#include <device/battery_dev.h>
-#include <errno.h>
-#include <async.h>
-#include <time.h>
-
-/** Read the current battery status from the device
- *
- * @param sess     Session of the device
- * @param status   Current status of the battery
- *
- * @return         EOK on success or a negative error code
- */
-int
-battery_status_get(async_sess_t *sess, battery_status_t *batt_status)
-{
-	sysarg_t status;
-
-	async_exch_t *exch = async_exchange_begin(sess);
-
-	int const rc = async_req_1_1(exch, DEV_IFACE_ID(BATTERY_DEV_IFACE),
-	    BATTERY_STATUS_GET, &status);
-
-	async_exchange_end(exch);
-
-	if (rc == EOK)
-		*batt_status = (battery_status_t) status;
-
-	return rc;
-}
-
-/** Read the current battery charge level from the device
- *
- * @param sess     Session of the device
- * @param level    Battery charge level (0 - 100)
- *
- * @return         EOK on success or a negative error code
- */
-int
-battery_charge_level_get(async_sess_t *sess, int *level)
-{
-	sysarg_t charge_level;
-
-	async_exch_t *exch = async_exchange_begin(sess);
-
-	int const rc = async_req_1_1(exch, DEV_IFACE_ID(BATTERY_DEV_IFACE),
-	    BATTERY_CHARGE_LEVEL_GET, &charge_level);
-
-	async_exchange_end(exch);
-
-	if (rc == EOK)
-		*level = (int) charge_level;
-
-	return rc;
-}
-
-/** @}
- */
-
Index: pace/lib/c/generic/device/char_dev.c
===================================================================
--- uspace/lib/c/generic/device/char_dev.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,127 +1,0 @@
-/*
- * Copyright (c) 2010 Lenka Trochtova
- * 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 libc
- * @{
- */
-/** @file
- */
-
-#include <ipc/dev_iface.h>
-#include <device/char_dev.h>
-#include <errno.h>
-#include <async.h>
-#include <malloc.h>
-#include <stdio.h>
-
-/** Read to or write from device.
- *
- * Helper function to read to or write from a device
- * using its character interface.
- *
- * @param sess Session to the device.
- * @param buf  Buffer for the data read from or written to the device.
- * @param size Maximum size of data (in bytes) to be read or written.
- * @param read Read from the device if true, write to it otherwise.
- *
- * @return Non-negative number of bytes actually read from or
- *         written to the device on success, negative error number
- *         otherwise.
- *
- */
-static ssize_t char_dev_rw(async_sess_t *sess, void *buf, size_t size, bool read)
-{
-	ipc_call_t answer;
-	aid_t req;
-	int ret;
-	
-	async_exch_t *exch = async_exchange_begin(sess);
-	
-	if (read) {
-		req = async_send_1(exch, DEV_IFACE_ID(CHAR_DEV_IFACE),
-		    CHAR_DEV_READ, &answer);
-		ret = async_data_read_start(exch, buf, size);
-	} else {
-		req = async_send_1(exch, DEV_IFACE_ID(CHAR_DEV_IFACE),
-		    CHAR_DEV_WRITE, &answer);
-		ret = async_data_write_start(exch, buf, size);
-	}
-	
-	async_exchange_end(exch);
-	
-	sysarg_t rc;
-	if (ret != EOK) {
-		async_wait_for(req, &rc);
-		if (rc == EOK)
-			return (ssize_t) ret;
-		
-		return (ssize_t) rc;
-	}
-	
-	async_wait_for(req, &rc);
-	
-	ret = (int) rc;
-	if (ret != EOK)
-		return (ssize_t) ret;
-	
-	return (ssize_t) IPC_GET_ARG1(answer);
-}
-
-/** Read from character device.
- *
- * @param sess Session to the device.
- * @param buf  Output buffer for the data read from the device.
- * @param size Maximum size (in bytes) of the data to be read.
- *
- * @return Non-negative number of bytes actually read from the
- *         device on success, negative error number otherwise.
- *
- */
-ssize_t char_dev_read(async_sess_t *sess, void *buf, size_t size)
-{
-	return char_dev_rw(sess, buf, size, true);
-}
-
-/** Write to character device.
- *
- * @param sess Session to the device.
- * @param buf  Input buffer containg the data to be written to the
- *             device.
- * @param size Maximum size (in bytes) of the data to be written.
- *
- * @return Non-negative number of bytes actually written to the
- *         device on success, negative error number otherwise.
- *
- */
-ssize_t char_dev_write(async_sess_t *sess, void *buf, size_t size)
-{
-	return char_dev_rw(sess, buf, size, false);
-}
-
-/** @}
- */
Index: pace/lib/c/generic/device/graph_dev.c
===================================================================
--- uspace/lib/c/generic/device/graph_dev.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,49 +1,0 @@
-/*
- * Copyright (c) 2011 Petr Koupy
- * 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 libc
- * @{
- */
-/** @file
- */
-
-#include <errno.h>
-#include <ipc/dev_iface.h>
-#include <device/graph_dev.h>
-
-int graph_dev_connect(async_sess_t *sess)
-{
-	async_exch_t *exch = async_exchange_begin(sess);
-	int ret = async_req_1_0(exch, DEV_IFACE_ID(GRAPH_DEV_IFACE), GRAPH_DEV_CONNECT);
-	async_exchange_end(exch);
-
-	return ret;
-}
-
-/** @}
- */
Index: pace/lib/c/generic/device/nic.c
===================================================================
--- uspace/lib/c/generic/device/nic.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,1292 +1,0 @@
-/*
- * Copyright (c) 2011 Radim Vansa
- * 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 libc
- * @{
- */
-/**
- * @file
- * @brief Client-side RPC stubs for DDF NIC
- */
-
-#include <ipc/dev_iface.h>
-#include <assert.h>
-#include <device/nic.h>
-#include <errno.h>
-#include <async.h>
-#include <malloc.h>
-#include <stdio.h>
-#include <ipc/services.h>
-
-/** Send frame from NIC
- *
- * @param[in] dev_sess
- * @param[in] data     Frame data
- * @param[in] size     Frame size in bytes
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_send_frame(async_sess_t *dev_sess, void *data, size_t size)
-{
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	ipc_call_t answer;
-	aid_t req = async_send_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_SEND_MESSAGE, &answer);
-	sysarg_t retval = async_data_write_start(exch, data, size);
-	
-	async_exchange_end(exch);
-	
-	if (retval != EOK) {
-		async_forget(req);
-		return retval;
-	}
-
-	async_wait_for(req, &retval);
-	return retval;
-}
-
-/** Create callback connection from NIC service
- *
- * @param[in] dev_sess
- * @param[in] device_id
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_callback_create(async_sess_t *dev_sess, async_client_conn_t cfun,
-    void *carg)
-{
-	ipc_call_t answer;
-	int rc;
-	sysarg_t retval;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	aid_t req = async_send_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_CALLBACK_CREATE, &answer);
-	
-	rc = async_connect_to_me(exch, 0, 0, 0, cfun, carg);
-	if (rc != EOK) {
-		async_forget(req);
-		return rc;
-	}
-	async_exchange_end(exch);
-	
-	async_wait_for(req, &retval);
-	return (int) retval;
-}
-
-/** Get the current state of the device
- *
- * @param[in]  dev_sess
- * @param[out] state    Current state
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_get_state(async_sess_t *dev_sess, nic_device_state_t *state)
-{
-	assert(state);
-	
-	sysarg_t _state;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_1_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_GET_STATE, &_state);
-	async_exchange_end(exch);
-	
-	*state = (nic_device_state_t) _state;
-	
-	return rc;
-}
-
-/** Request the device to change its state
- *
- * @param[in] dev_sess
- * @param[in] state    New state
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_set_state(async_sess_t *dev_sess, nic_device_state_t state)
-{
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_2_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_SET_STATE, state);
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
-/** Request the MAC address of the device
- *
- * @param[in]  dev_sess
- * @param[out] address  Structure with buffer for the address
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_get_address(async_sess_t *dev_sess, nic_address_t *address)
-{
-	assert(address);
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	aid_t aid = async_send_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_GET_ADDRESS, NULL);
-	int rc = async_data_read_start(exch, address, sizeof(nic_address_t));
-	async_exchange_end(exch);
-	
-	sysarg_t res;
-	async_wait_for(aid, &res);
-	
-	if (rc != EOK)
-		return rc;
-	
-	return (int) res;
-}
-
-/** Set the address of the device (e.g. MAC on Ethernet)
- *
- * @param[in] dev_sess
- * @param[in] address  Pointer to the address
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_set_address(async_sess_t *dev_sess, const nic_address_t *address)
-{
-	assert(address);
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	aid_t aid = async_send_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_SET_ADDRESS, NULL);
-	int rc = async_data_write_start(exch, address, sizeof(nic_address_t));
-	async_exchange_end(exch);
-	
-	sysarg_t res;
-	async_wait_for(aid, &res);
-	
-	if (rc != EOK)
-		return rc;
-	
-	return (int) res;
-}
-
-/** Request statistic data about NIC operation.
- *
- * @param[in]  dev_sess
- * @param[out] stats    Structure with the statistics
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_get_stats(async_sess_t *dev_sess, nic_device_stats_t *stats)
-{
-	assert(stats);
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	int rc = async_req_1_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_GET_STATS);
-	if (rc != EOK) {
-		async_exchange_end(exch);
-		return rc;
-	}
-	
-	rc = async_data_read_start(exch, stats, sizeof(nic_device_stats_t));
-	
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
-/** Request information about the device.
- *
- * @see nic_device_info_t
- *
- * @param[in]  dev_sess
- * @param[out] device_info Information about the device
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_get_device_info(async_sess_t *dev_sess, nic_device_info_t *device_info)
-{
-	assert(device_info);
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	int rc = async_req_1_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_GET_DEVICE_INFO);
-	if (rc != EOK) {
-		async_exchange_end(exch);
-		return rc;
-	}
-	
-	rc = async_data_read_start(exch, device_info, sizeof(nic_device_info_t));
-	
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
-/** Request status of the cable (plugged/unplugged)
- *
- * @param[in]  dev_sess
- * @param[out] cable_state Current cable state
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_get_cable_state(async_sess_t *dev_sess, nic_cable_state_t *cable_state)
-{
-	assert(cable_state);
-	
-	sysarg_t _cable_state;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_1_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_GET_CABLE_STATE, &_cable_state);
-	async_exchange_end(exch);
-	
-	*cable_state = (nic_cable_state_t) _cable_state;
-	
-	return rc;
-}
-
-/** Request current operation mode.
- *
- * @param[in]  dev_sess
- * @param[out] speed    Current operation speed in Mbps. Can be NULL.
- * @param[out] duplex   Full duplex/half duplex. Can be NULL.
- * @param[out] role     Master/slave/auto. Can be NULL.
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_get_operation_mode(async_sess_t *dev_sess, int *speed,
-   nic_channel_mode_t *duplex, nic_role_t *role)
-{
-	sysarg_t _speed;
-	sysarg_t _duplex;
-	sysarg_t _role;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_1_3(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_GET_OPERATION_MODE, &_speed, &_duplex, &_role);
-	async_exchange_end(exch);
-	
-	if (speed)
-		*speed = (int) _speed;
-	
-	if (duplex)
-		*duplex = (nic_channel_mode_t) _duplex;
-	
-	if (role)
-		*role = (nic_role_t) _role;
-	
-	return rc;
-}
-
-/** Set current operation mode.
- *
- * If the NIC has auto-negotiation enabled, this command
- * disables auto-negotiation and sets the operation mode.
- *
- * @param[in] dev_sess
- * @param[in] speed    Operation speed in Mbps
- * @param[in] duplex   Full duplex/half duplex
- * @param[in] role     Master/slave/auto (e.g. in Gbit Ethernet]
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_set_operation_mode(async_sess_t *dev_sess, int speed,
-    nic_channel_mode_t duplex, nic_role_t role)
-{
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_4_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_SET_OPERATION_MODE, (sysarg_t) speed, (sysarg_t) duplex,
-	    (sysarg_t) role);
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
-/** Enable auto-negotiation.
- *
- * The advertisement argument can only limit some modes,
- * it can never force the NIC to advertise unsupported modes.
- *
- * The allowed modes are defined in "nic/eth_phys.h" in the C library.
- *
- * @param[in] dev_sess
- * @param[in] advertisement Allowed advertised modes. Use 0 for all modes.
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_autoneg_enable(async_sess_t *dev_sess, uint32_t advertisement)
-{
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_2_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_AUTONEG_ENABLE, (sysarg_t) advertisement);
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
-/** Disable auto-negotiation.
- *
- * @param[in] dev_sess
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_autoneg_disable(async_sess_t *dev_sess)
-{
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_1_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_AUTONEG_DISABLE);
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
-/** Probe current state of auto-negotiation.
- *
- * Modes are defined in the "nic/eth_phys.h" in the C library.
- *
- * @param[in]  dev_sess
- * @param[out] our_advertisement   Modes advertised by this NIC.
- *                                 Can be NULL.
- * @param[out] their_advertisement Modes advertised by the other side.
- *                                 Can be NULL.
- * @param[out] result              General state of auto-negotiation.
- *                                 Can be NULL.
- * @param[out]  their_result       State of other side auto-negotiation.
- *                                 Can be NULL.
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_autoneg_probe(async_sess_t *dev_sess, uint32_t *our_advertisement,
-    uint32_t *their_advertisement, nic_result_t *result,
-    nic_result_t *their_result)
-{
-	sysarg_t _our_advertisement;
-	sysarg_t _their_advertisement;
-	sysarg_t _result;
-	sysarg_t _their_result;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_1_4(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_AUTONEG_PROBE, &_our_advertisement, &_their_advertisement,
-	    &_result, &_their_result);
-	async_exchange_end(exch);
-	
-	if (our_advertisement)
-		*our_advertisement = (uint32_t) _our_advertisement;
-	
-	if (*their_advertisement)
-		*their_advertisement = (uint32_t) _their_advertisement;
-	
-	if (result)
-		*result = (nic_result_t) _result;
-	
-	if (their_result)
-		*their_result = (nic_result_t) _their_result;
-	
-	return rc;
-}
-
-/** Restart the auto-negotiation process.
- *
- * @param[in] dev_sess
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_autoneg_restart(async_sess_t *dev_sess)
-{
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_1_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_AUTONEG_RESTART);
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
-/** Query party's sending and reception of the PAUSE frame.
- *
- * @param[in]  dev_sess
- * @param[out] we_send    This NIC sends the PAUSE frame (true/false)
- * @param[out] we_receive This NIC receives the PAUSE frame (true/false)
- * @param[out] pause      The time set to transmitted PAUSE frames.
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_get_pause(async_sess_t *dev_sess, nic_result_t *we_send,
-    nic_result_t *we_receive, uint16_t *pause)
-{
-	sysarg_t _we_send;
-	sysarg_t _we_receive;
-	sysarg_t _pause;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_1_3(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_GET_PAUSE, &_we_send, &_we_receive, &_pause);
-	async_exchange_end(exch);
-	
-	if (we_send)
-		*we_send = _we_send;
-	
-	if (we_receive)
-		*we_receive = _we_receive;
-	
-	if (pause)
-		*pause = _pause;
-	
-	return rc;
-}
-
-/** Control sending and reception of the PAUSE frame.
- *
- * @param[in] dev_sess
- * @param[in] allow_send    Allow sending the PAUSE frame (true/false)
- * @param[in] allow_receive Allow reception of the PAUSE frame (true/false)
- * @param[in] pause         Pause length in 512 bit units written
- *                          to transmitted frames. The value 0 means
- *                          auto value (the best). If the requested
- *                          time cannot be set the driver is allowed
- *                          to set the nearest supported value.
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_set_pause(async_sess_t *dev_sess, int allow_send, int allow_receive,
-    uint16_t pause)
-{
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_4_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_SET_PAUSE, allow_send, allow_receive, pause);
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
-/** Retrieve current settings of unicast frames reception.
- *
- * Note: In case of mode != NIC_UNICAST_LIST the contents of
- * address_list and address_count are undefined.
- *
- * @param[in]   dev_sess
- * @param[out]  mode          Current operation mode
- * @param[in]   max_count     Maximal number of addresses that could
- *                            be written into the list buffer.
- * @param[out]  address_list  Buffer for the list (array). Can be NULL.
- * @param[out]  address_count Number of addresses in the list before
- *                            possible truncation due to the max_count.
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_unicast_get_mode(async_sess_t *dev_sess, nic_unicast_mode_t *mode,
-    size_t max_count, nic_address_t *address_list, size_t *address_count)
-{
-	assert(mode);
-	
-	sysarg_t _mode;
-	sysarg_t _address_count;
-	
-	if (!address_list)
-		max_count = 0;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	int rc = async_req_2_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_UNICAST_GET_MODE, max_count, &_mode, &_address_count);
-	if (rc != EOK) {
-		async_exchange_end(exch);
-		return rc;
-	}
-	
-	*mode = (nic_unicast_mode_t) _mode;
-	if (address_count)
-		*address_count = (size_t) _address_count;
-	
-	if ((max_count) && (_address_count))
-		rc = async_data_read_start(exch, address_list,
-		    max_count * sizeof(nic_address_t));
-	
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
-/** Set which unicast frames are received.
- *
- * @param[in] dev_sess
- * @param[in] mode          Current operation mode
- * @param[in] address_list  The list of addresses. Can be NULL.
- * @param[in] address_count Number of addresses in the list.
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_unicast_set_mode(async_sess_t *dev_sess, nic_unicast_mode_t mode,
-    const nic_address_t *address_list, size_t address_count)
-{
-	if (address_list == NULL)
-		address_count = 0;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	aid_t message_id = async_send_3(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_UNICAST_SET_MODE, (sysarg_t) mode, address_count, NULL);
-	
-	int rc;
-	if (address_count)
-		rc = async_data_write_start(exch, address_list,
-		    address_count * sizeof(nic_address_t));
-	else
-		rc = EOK;
-	
-	async_exchange_end(exch);
-	
-	sysarg_t res;
-	async_wait_for(message_id, &res);
-	
-	if (rc != EOK)
-		return rc;
-	
-	return (int) res;
-}
-
-/** Retrieve current settings of multicast frames reception.
- *
- * Note: In case of mode != NIC_MULTICAST_LIST the contents of
- * address_list and address_count are undefined.
- *
- * @param[in]  dev_sess
- * @param[out] mode          Current operation mode
- * @param[in]  max_count     Maximal number of addresses that could
- *                           be written into the list buffer.
- * @param[out] address_list  Buffer for the list (array). Can be NULL.
- * @param[out] address_count Number of addresses in the list before
- *                           possible truncation due to the max_count.
- *                           Can be NULL.
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_multicast_get_mode(async_sess_t *dev_sess, nic_multicast_mode_t *mode,
-    size_t max_count, nic_address_t *address_list, size_t *address_count)
-{
-	assert(mode);
-	
-	sysarg_t _mode;
-	
-	if (!address_list)
-		max_count = 0;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	sysarg_t ac;
-	int rc = async_req_2_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_MULTICAST_GET_MODE, max_count, &_mode, &ac);
-	if (rc != EOK) {
-		async_exchange_end(exch);
-		return rc;
-	}
-	
-	*mode = (nic_multicast_mode_t) _mode;
-	if (address_count)
-		*address_count = (size_t) ac;
-	
-	if ((max_count) && (ac))
-		rc = async_data_read_start(exch, address_list,
-		    max_count * sizeof(nic_address_t));
-	
-	async_exchange_end(exch);
-	return rc;
-}
-
-/** Set which multicast frames are received.
- *
- * @param[in] dev_sess
- * @param[in] mode          Current operation mode
- * @param[in] address_list  The list of addresses. Can be NULL.
- * @param[in] address_count Number of addresses in the list.
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_multicast_set_mode(async_sess_t *dev_sess, nic_multicast_mode_t mode,
-    const nic_address_t *address_list, size_t address_count)
-{
-	if (address_list == NULL)
-		address_count = 0;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	aid_t message_id = async_send_3(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_MULTICAST_SET_MODE, (sysarg_t) mode, address_count, NULL);
-	
-	int rc;
-	if (address_count)
-		rc = async_data_write_start(exch, address_list,
-		    address_count * sizeof(nic_address_t));
-	else
-		rc = EOK;
-	
-	async_exchange_end(exch);
-	
-	sysarg_t res;
-	async_wait_for(message_id, &res);
-	
-	if (rc != EOK)
-		return rc;
-	
-	return (int) res;
-}
-
-/** Determine if broadcast packets are received.
- *
- * @param[in]  dev_sess
- * @param[out] mode     Current operation mode
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_broadcast_get_mode(async_sess_t *dev_sess, nic_broadcast_mode_t *mode)
-{
-	assert(mode);
-	
-	sysarg_t _mode;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_1_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_BROADCAST_GET_MODE, &_mode);
-	async_exchange_end(exch);
-	
-	*mode = (nic_broadcast_mode_t) _mode;
-	
-	return rc;
-}
-
-/** Set whether broadcast packets are received.
- *
- * @param[in] dev_sess
- * @param[in] mode     Current operation mode
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_broadcast_set_mode(async_sess_t *dev_sess, nic_broadcast_mode_t mode)
-{
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_2_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_BROADCAST_SET_MODE, mode);
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
-/** Determine if defective (erroneous) packets are received.
- *
- * @param[in]  dev_sess
- * @param[out] mode     Bitmask specifying allowed errors
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_defective_get_mode(async_sess_t *dev_sess, uint32_t *mode)
-{
-	assert(mode);
-	
-	sysarg_t _mode;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_1_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_DEFECTIVE_GET_MODE, &_mode);
-	async_exchange_end(exch);
-	
-	*mode = (uint32_t) _mode;
-	
-	return rc;
-}
-
-/** Set whether defective (erroneous) packets are received.
- *
- * @param[in]  dev_sess
- * @param[out] mode     Bitmask specifying allowed errors
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_defective_set_mode(async_sess_t *dev_sess, uint32_t mode)
-{
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_2_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_DEFECTIVE_SET_MODE, mode);
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
-/** Retrieve the currently blocked source MAC addresses.
- *
- * @param[in]  dev_sess
- * @param[in]  max_count     Maximal number of addresses that could
- *                           be written into the list buffer.
- * @param[out] address_list  Buffer for the list (array). Can be NULL.
- * @param[out] address_count Number of addresses in the list before
- *                           possible truncation due to the max_count.
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_blocked_sources_get(async_sess_t *dev_sess, size_t max_count,
-    nic_address_t *address_list, size_t *address_count)
-{
-	if (!address_list)
-		max_count = 0;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	sysarg_t ac;
-	int rc = async_req_2_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_BLOCKED_SOURCES_GET, max_count, &ac);
-	if (rc != EOK) {
-		async_exchange_end(exch);
-		return rc;
-	}
-	
-	if (address_count)
-		*address_count = (size_t) ac;
-	
-	if ((max_count) && (ac))
-		rc = async_data_read_start(exch, address_list,
-		    max_count * sizeof(nic_address_t));
-	
-	async_exchange_end(exch);
-	return rc;
-}
-
-/** Set which source MACs are blocked
- *
- * @param[in] dev_sess
- * @param[in] address_list  The list of addresses. Can be NULL.
- * @param[in] address_count Number of addresses in the list.
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_blocked_sources_set(async_sess_t *dev_sess,
-    const nic_address_t *address_list, size_t address_count)
-{
-	if (address_list == NULL)
-		address_count = 0;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	aid_t message_id = async_send_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_BLOCKED_SOURCES_SET, address_count, NULL);
-	
-	int rc;
-	if (address_count)
-		rc = async_data_write_start(exch, address_list,
-			address_count * sizeof(nic_address_t));
-	else
-		rc = EOK;
-	
-	async_exchange_end(exch);
-	
-	sysarg_t res;
-	async_wait_for(message_id, &res);
-	
-	if (rc != EOK)
-		return rc;
-	
-	return (int) res;
-}
-
-/** Request current VLAN filtering mask.
- *
- * @param[in]  dev_sess
- * @param[out] stats    Structure with the statistics
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_vlan_get_mask(async_sess_t *dev_sess, nic_vlan_mask_t *mask)
-{
-	assert(mask);
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_1_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_VLAN_GET_MASK);
-	if (rc != EOK) {
-		async_exchange_end(exch);
-		return rc;
-	}
-	
-	rc = async_data_read_start(exch, mask, sizeof(nic_vlan_mask_t));
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
-/** Set the mask used for VLAN filtering.
- *
- * If NULL, VLAN filtering is disabled.
- *
- * @param[in] dev_sess
- * @param[in] mask     Pointer to mask structure or NULL to disable.
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_vlan_set_mask(async_sess_t *dev_sess, const nic_vlan_mask_t *mask)
-{
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	aid_t message_id = async_send_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_VLAN_SET_MASK, mask != NULL, NULL);
-	
-	int rc;
-	if (mask != NULL)
-		rc = async_data_write_start(exch, mask, sizeof(nic_vlan_mask_t));
-	else
-		rc = EOK;
-	
-	async_exchange_end(exch);
-	
-	sysarg_t res;
-	async_wait_for(message_id, &res);
-	
-	if (rc != EOK)
-		return rc;
-	
-	return (int) res;
-}
-
-/** Set VLAN (802.1q) tag.
- *
- * Set whether the tag is to be signaled in offload info and
- * if the tag should be stripped from received frames and added
- * to sent frames automatically. Not every combination of add
- * and strip must be supported.
- *
- * @param[in] dev_sess
- * @param[in] tag      VLAN priority (top 3 bits) and
- *                     the VLAN tag (bottom 12 bits)
- * @param[in] add      Add the VLAN tag automatically (boolean)
- * @param[in] strip    Strip the VLAN tag automatically (boolean)
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_vlan_set_tag(async_sess_t *dev_sess, uint16_t tag, bool add, bool strip)
-{
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_4_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_VLAN_SET_TAG, (sysarg_t) tag, (sysarg_t) add, (sysarg_t) strip);
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
-/** Add new Wake-On-LAN virtue.
- *
- * @param[in]  dev_sess
- * @param[in]  type     Type of the virtue
- * @param[in]  data     Data required for this virtue
- *                      (depends on type)
- * @param[in]  length   Length of the data
- * @param[out] id       Identifier of the new virtue
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_wol_virtue_add(async_sess_t *dev_sess, nic_wv_type_t type,
-    const void *data, size_t length, nic_wv_id_t *id)
-{
-	assert(id);
-	
-	bool send_data = ((data != NULL) && (length != 0));
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	ipc_call_t result;
-	aid_t message_id = async_send_3(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_WOL_VIRTUE_ADD, (sysarg_t) type, send_data, &result);
-	
-	sysarg_t res;
-	if (send_data) {
-		int rc = async_data_write_start(exch, data, length);
-		if (rc != EOK) {
-			async_exchange_end(exch);
-			async_wait_for(message_id, &res);
-			return rc;
-		}
-	}
-	
-	async_exchange_end(exch);
-	async_wait_for(message_id, &res);
-	
-	*id = IPC_GET_ARG1(result);
-	return (int) res;
-}
-
-/** Remove Wake-On-LAN virtue.
- *
- * @param[in] dev_sess
- * @param[in] id       Virtue identifier
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_wol_virtue_remove(async_sess_t *dev_sess, nic_wv_id_t id)
-{
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_2_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_WOL_VIRTUE_REMOVE, (sysarg_t) id);
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
-/** Get information about virtue.
- *
- * @param[in]  dev_sess
- * @param[in]  id         Virtue identifier
- * @param[out] type       Type of the filter. Can be NULL.
- * @param[out] max_length Size of the data buffer.
- * @param[out] data       Buffer for data used when the
- *                        virtue was created. Can be NULL.
- * @param[out] length     Length of the data. Can be NULL.
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_wol_virtue_probe(async_sess_t *dev_sess, nic_wv_id_t id,
-    nic_wv_type_t *type, size_t max_length, void *data, size_t *length)
-{
-	sysarg_t _type;
-	sysarg_t _length;
-	
-	if (data == NULL)
-		max_length = 0;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	int rc = async_req_3_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_WOL_VIRTUE_PROBE, (sysarg_t) id, max_length,
-	    &_type, &_length);
-	if (rc != EOK) {
-		async_exchange_end(exch);
-		return rc;
-	}
-	
-	if (type)
-		*type = _type;
-	
-	if (length)
-		*length = _length;
-	
-	if ((max_length) && (_length != 0))
-		rc = async_data_read_start(exch, data, max_length);
-	
-	async_exchange_end(exch);
-	return rc;
-}
-
-/** Get a list of all virtues of the specified type.
- *
- * When NIC_WV_NONE is specified as the virtue type the function
- * lists virtues of all types.
- *
- * @param[in]  dev_sess
- * @param[in]  type      Type of the virtues
- * @param[in]  max_count Maximum number of ids that can be
- *                       written into the list buffer.
- * @param[out] id_list   Buffer for to the list of virtue ids.
- *                       Can be NULL.
- * @param[out] id_count  Number of virtue identifiers in the list
- *                       before possible truncation due to the
- *                       max_count. Can be NULL.
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_wol_virtue_list(async_sess_t *dev_sess, nic_wv_type_t type,
-    size_t max_count, nic_wv_id_t *id_list, size_t *id_count)
-{
-	if (id_list == NULL)
-		max_count = 0;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	sysarg_t count;
-	int rc = async_req_3_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_WOL_VIRTUE_LIST, (sysarg_t) type, max_count, &count);
-	
-	if (id_count)
-		*id_count = (size_t) count;
-	
-	if ((rc != EOK) || (!max_count)) {
-		async_exchange_end(exch);
-		return rc;
-	}
-	
-	rc = async_data_read_start(exch, id_list,
-	    max_count * sizeof(nic_wv_id_t));
-	
-	async_exchange_end(exch);
-	return rc;
-}
-
-/** Get number of virtues that can be enabled yet.
- *
- * Count: < 0 => Virtue of this type can be never used
- *        = 0 => No more virtues can be enabled
- *        > 0 => #count virtues can be enabled yet
- *
- * @param[in]  dev_sess
- * @param[in]  type     Virtue type
- * @param[out] count    Number of virtues
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_wol_virtue_get_caps(async_sess_t *dev_sess, nic_wv_type_t type,
-    int *count)
-{
-	assert(count);
-	
-	sysarg_t _count;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_2_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_WOL_VIRTUE_GET_CAPS, (sysarg_t) type, &_count);
-	async_exchange_end(exch);
-	
-	*count = (int) _count;
-	return rc;
-}
-
-/** Load the frame that issued the wakeup.
- *
- * The NIC can support only matched_type,  only part of the frame
- * can be available or not at all. Sometimes even the type can be
- * uncertain -- in this case the matched_type contains NIC_WV_NONE.
- *
- * Frame_length can be greater than max_length, but at most max_length
- * bytes will be copied into the frame buffer.
- *
- * Note: Only the type of the filter can be detected, not the concrete
- * filter, because the driver is probably not running when the wakeup
- * is issued.
- *
- * @param[in]  dev_sess
- * @param[out] matched_type Type of the filter that issued wakeup.
- * @param[in]  max_length   Size of the buffer
- * @param[out] frame        Buffer for the frame. Can be NULL.
- * @param[out] frame_length Length of the stored frame. Can be NULL.
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_wol_load_info(async_sess_t *dev_sess, nic_wv_type_t *matched_type,
-    size_t max_length, uint8_t *frame, size_t *frame_length)
-{
-	assert(matched_type);
-	
-	sysarg_t _matched_type;
-	sysarg_t _frame_length;
-	
-	if (frame == NULL)
-		max_length = 0;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	int rc = async_req_2_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_WOL_LOAD_INFO, max_length, &_matched_type, &_frame_length);
-	if (rc != EOK) {
-		async_exchange_end(exch);
-		return rc;
-	}
-	
-	*matched_type = (nic_wv_type_t) _matched_type;
-	if (frame_length)
-		*frame_length = (size_t) _frame_length;
-	
-	if ((max_length != 0) && (_frame_length != 0))
-		rc = async_data_read_start(exch, frame, max_length);
-	
-	async_exchange_end(exch);
-	return rc;
-}
-
-/** Probe supported options and current setting of offload computations
- *
- * @param[in]  dev_sess
- * @param[out] supported Supported offload options
- * @param[out] active    Currently active offload options
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_offload_probe(async_sess_t *dev_sess, uint32_t *supported,
-    uint32_t *active)
-{
-	assert(supported);
-	assert(active);
-	
-	sysarg_t _supported;
-	sysarg_t _active;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_1_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_OFFLOAD_PROBE, &_supported, &_active);
-	async_exchange_end(exch);
-	
-	*supported = (uint32_t) _supported;
-	*active = (uint32_t) _active;
-	return rc;
-}
-
-/** Set which offload computations can be performed on the NIC.
- *
- * @param[in] dev_sess
- * @param[in] mask     Mask for the options (only those set here will be set)
- * @param[in] active   Which options should be enabled and which disabled
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_offload_set(async_sess_t *dev_sess, uint32_t mask, uint32_t active)
-{
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_3_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_AUTONEG_RESTART, (sysarg_t) mask, (sysarg_t) active);
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
-/** Query the current interrupt/poll mode of the NIC
- *
- * @param[in]  dev_sess
- * @param[out] mode     Current poll mode
- * @param[out] period   Period used in periodic polling.
- *                      Can be NULL.
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_poll_get_mode(async_sess_t *dev_sess, nic_poll_mode_t *mode,
-    struct timeval *period)
-{
-	assert(mode);
-	
-	sysarg_t _mode;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	int rc = async_req_2_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_POLL_GET_MODE, period != NULL, &_mode);
-	if (rc != EOK) {
-		async_exchange_end(exch);
-		return rc;
-	}
-	
-	*mode = (nic_poll_mode_t) _mode;
-	
-	if (period != NULL)
-		rc = async_data_read_start(exch, period, sizeof(struct timeval));
-	
-	async_exchange_end(exch);
-	return rc;
-}
-
-/** Set the interrupt/poll mode of the NIC.
- *
- * @param[in] dev_sess
- * @param[in] mode     New poll mode
- * @param[in] period   Period used in periodic polling. Can be NULL.
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_poll_set_mode(async_sess_t *dev_sess, nic_poll_mode_t mode,
-    const struct timeval *period)
-{
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	aid_t message_id = async_send_3(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
-	    NIC_POLL_SET_MODE, (sysarg_t) mode, period != NULL, NULL);
-	
-	int rc;
-	if (period)
-		rc = async_data_write_start(exch, period, sizeof(struct timeval));
-	else
-		rc = EOK;
-	
-	async_exchange_end(exch);
-	
-	sysarg_t res;
-	async_wait_for(message_id, &res);
-	
-	if (rc != EOK)
-		return rc;
-	
-	return (int) res;
-}
-
-/** Request the driver to poll the NIC.
- *
- * @param[in] dev_sess
- *
- * @return EOK If the operation was successfully completed
- *
- */
-int nic_poll_now(async_sess_t *dev_sess)
-{
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	int rc = async_req_1_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE), NIC_POLL_NOW);
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
-/** @}
- */
Index: pace/lib/c/generic/device/pci.c
===================================================================
--- uspace/lib/c/generic/device/pci.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,116 +1,0 @@
-/*
- * Copyright (c) 2011 Jiri Michalec
- * 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 libc
- * @{
- */
-/** @file
- */
-
-#include <ipc/dev_iface.h>
-#include <assert.h>
-#include <device/pci.h>
-#include <errno.h>
-#include <async.h>
-#include <ipc/services.h>
-
-int pci_config_space_read_8(async_sess_t *sess, uint32_t address, uint8_t *val)
-{
-	sysarg_t res = 0;
-	
-	async_exch_t *exch = async_exchange_begin(sess);
-	int rc = async_req_2_1(exch, DEV_IFACE_ID(PCI_DEV_IFACE),
-	    IPC_M_CONFIG_SPACE_READ_8, address, &res);
-	async_exchange_end(exch);
-	
-	*val = (uint8_t) res;
-	return rc;
-}
-
-int pci_config_space_read_16(async_sess_t *sess, uint32_t address,
-    uint16_t *val)
-{
-	sysarg_t res = 0;
-	
-	async_exch_t *exch = async_exchange_begin(sess);
-	int rc = async_req_2_1(exch, DEV_IFACE_ID(PCI_DEV_IFACE),
-	    IPC_M_CONFIG_SPACE_READ_16, address, &res);
-	async_exchange_end(exch);
-	
-	*val = (uint16_t) res;
-	return rc;
-}
-
-int pci_config_space_read_32(async_sess_t *sess, uint32_t address,
-    uint32_t *val)
-{
-	sysarg_t res = 0;
-	
-	async_exch_t *exch = async_exchange_begin(sess);
-	int rc = async_req_2_1(exch, DEV_IFACE_ID(PCI_DEV_IFACE),
-	    IPC_M_CONFIG_SPACE_READ_32, address, &res);
-	async_exchange_end(exch);
-	
-	*val = (uint32_t) res;
-	return rc;
-}
-
-int pci_config_space_write_8(async_sess_t *sess, uint32_t address, uint8_t val)
-{
-	async_exch_t *exch = async_exchange_begin(sess);
-	int rc = async_req_3_0(exch, DEV_IFACE_ID(PCI_DEV_IFACE),
-	    IPC_M_CONFIG_SPACE_WRITE_8, address, val);
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
-int pci_config_space_write_16(async_sess_t *sess, uint32_t address,
-    uint16_t val)
-{
-	async_exch_t *exch = async_exchange_begin(sess);
-	int rc = async_req_3_0(exch, DEV_IFACE_ID(PCI_DEV_IFACE),
-	    IPC_M_CONFIG_SPACE_WRITE_16, address, val);
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
-int pci_config_space_write_32(async_sess_t *sess, uint32_t address,
-    uint32_t val)
-{
-	async_exch_t *exch = async_exchange_begin(sess);
-	int rc = async_req_3_0(exch, DEV_IFACE_ID(PCI_DEV_IFACE),
-	    IPC_M_CONFIG_SPACE_WRITE_32, address, val);
-	async_exchange_end(exch);
-	
-	return rc;
-}
-
-/** @}
- */
Index: uspace/lib/c/generic/io/io.c
===================================================================
--- uspace/lib/c/generic/io/io.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/c/generic/io/io.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -42,5 +42,5 @@
 #include <malloc.h>
 #include <async.h>
-#include <io/klog.h>
+#include <io/kio.h>
 #include <vfs/vfs.h>
 #include <vfs/vfs_sess.h>
@@ -57,5 +57,5 @@
 	.error = true,
 	.eof = true,
-	.klog = false,
+	.kio = false,
 	.sess = NULL,
 	.btype = _IONBF,
@@ -67,9 +67,9 @@
 };
 
-static FILE stdout_klog = {
+static FILE stdout_kio = {
 	.fd = -1,
 	.error = false,
 	.eof = false,
-	.klog = true,
+	.kio = true,
 	.sess = NULL,
 	.btype = _IOLBF,
@@ -81,9 +81,9 @@
 };
 
-static FILE stderr_klog = {
+static FILE stderr_kio = {
 	.fd = -1,
 	.error = false,
 	.eof = false,
-	.klog = true,
+	.kio = true,
 	.sess = NULL,
 	.btype = _IONBF,
@@ -113,5 +113,5 @@
 		stdout = fdopen(1, "w");
 	} else {
-		stdout = &stdout_klog;
+		stdout = &stdout_kio;
 		list_append(&stdout->link, &files);
 	}
@@ -120,5 +120,5 @@
 		stderr = fdopen(2, "w");
 	} else {
-		stderr = &stderr_klog;
+		stderr = &stderr_kio;
 		list_append(&stderr->link, &files);
 	}
@@ -267,5 +267,5 @@
 	stream->error = false;
 	stream->eof = false;
-	stream->klog = false;
+	stream->kio = false;
 	stream->sess = NULL;
 	stream->need_sync = false;
@@ -289,5 +289,5 @@
 	stream->error = false;
 	stream->eof = false;
-	stream->klog = false;
+	stream->kio = false;
 	stream->sess = NULL;
 	stream->need_sync = false;
@@ -314,6 +314,6 @@
 	
 	if ((stream != &stdin_null)
-	    && (stream != &stdout_klog)
-	    && (stream != &stderr_klog))
+	    && (stream != &stdout_kio)
+	    && (stream != &stderr_kio))
 		free(stream);
 	
@@ -382,6 +382,6 @@
 		ssize_t wr;
 		
-		if (stream->klog)
-			wr = klog_write(buf + done, left);
+		if (stream->kio)
+			wr = kio_write(buf + done, left);
 		else
 			wr = write(stream->fd, buf + done, left);
@@ -705,6 +705,6 @@
 	_fflushbuf(stream);
 	
-	if (stream->klog) {
-		klog_update();
+	if (stream->kio) {
+		kio_update();
 		return EOK;
 	}
@@ -740,5 +740,5 @@
 int fileno(FILE *stream)
 {
-	if (stream->klog) {
+	if (stream->kio) {
 		errno = EBADF;
 		return -1;
Index: uspace/lib/c/generic/io/kio.c
===================================================================
--- uspace/lib/c/generic/io/kio.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/c/generic/io/kio.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2006 Josef Cejka
+ * Copyright (c) 2006 Jakub Vana
+ * 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 libc
+ * @{
+ */
+/** @file
+ */
+
+#include <libc.h>
+#include <str.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+#include <abi/kio.h>
+#include <io/kio.h>
+#include <io/printf_core.h>
+
+size_t kio_write(const void *buf, size_t size)
+{
+	ssize_t ret = (ssize_t) __SYSCALL3(SYS_KIO, KIO_WRITE, (sysarg_t) buf, size);
+	
+	if (ret >= 0)
+		return (size_t) ret;
+	
+	return 0;
+}
+
+void kio_update(void)
+{
+	(void) __SYSCALL3(SYS_KIO, KIO_UPDATE, (uintptr_t) NULL, 0);
+}
+
+void kio_command(const void *buf, size_t size)
+{
+	(void) __SYSCALL3(SYS_KIO, KIO_COMMAND, (sysarg_t) buf, (sysarg_t) size);
+}
+
+/** Print formatted text to kio.
+ *
+ * @param fmt Format string
+ *
+ * \see For more details about format string see printf_core.
+ *
+ */
+int kio_printf(const char *fmt, ...)
+{
+	va_list args;
+	va_start(args, fmt);
+	
+	int ret = kio_vprintf(fmt, args);
+	
+	va_end(args);
+	
+	return ret;
+}
+
+static int kio_vprintf_str_write(const char *str, size_t size, void *data)
+{
+	size_t wr = kio_write(str, size);
+	return str_nlength(str, wr);
+}
+
+static int kio_vprintf_wstr_write(const wchar_t *str, size_t size, void *data)
+{
+	size_t offset = 0;
+	size_t chars = 0;
+	
+	while (offset < size) {
+		char buf[STR_BOUNDS(1)];
+		size_t sz = 0;
+		
+		if (chr_encode(str[chars], buf, &sz, STR_BOUNDS(1)) == EOK)
+			kio_write(buf, sz);
+		
+		chars++;
+		offset += sizeof(wchar_t);
+	}
+	
+	return chars;
+}
+
+/** Print formatted text to kio.
+ *
+ * @param fmt Format string
+ * @param ap  Format parameters
+ *
+ * \see For more details about format string see printf_core.
+ *
+ */
+int kio_vprintf(const char *fmt, va_list ap)
+{
+	printf_spec_t ps = {
+		kio_vprintf_str_write,
+		kio_vprintf_wstr_write,
+		NULL
+	};
+	
+	return printf_core(fmt, &ps, ap);
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/io/klog.c
===================================================================
--- uspace/lib/c/generic/io/klog.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/c/generic/io/klog.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -1,5 +1,4 @@
 /*
- * Copyright (c) 2006 Josef Cejka
- * Copyright (c) 2006 Jakub Vana
+ * Copyright (c) 2013 Martin Sucha
  * All rights reserved.
  *
@@ -41,9 +40,10 @@
 #include <abi/klog.h>
 #include <io/klog.h>
-#include <io/printf_core.h>
+#include <abi/log.h>
 
-size_t klog_write(const void *buf, size_t size)
+size_t klog_write(log_level_t lvl, const void *buf, size_t size)
 {
-	ssize_t ret = (ssize_t) __SYSCALL3(SYS_KLOG, KLOG_WRITE, (sysarg_t) buf, size);
+	ssize_t ret = (ssize_t) __SYSCALL4(SYS_KLOG, KLOG_WRITE, (sysarg_t) buf,
+	    size, lvl);
 	
 	if (ret >= 0)
@@ -53,75 +53,7 @@
 }
 
-void klog_update(void)
+int klog_read(void *data, size_t size)
 {
-	(void) __SYSCALL3(SYS_KLOG, KLOG_UPDATE, (uintptr_t) NULL, 0);
-}
-
-void klog_command(const void *buf, size_t size)
-{
-	(void) __SYSCALL3(SYS_KLOG, KLOG_COMMAND, (sysarg_t) buf, (sysarg_t) size);
-}
-
-/** Print formatted text to klog.
- *
- * @param fmt Format string
- *
- * \see For more details about format string see printf_core.
- *
- */
-int klog_printf(const char *fmt, ...)
-{
-	va_list args;
-	va_start(args, fmt);
-	
-	int ret = klog_vprintf(fmt, args);
-	
-	va_end(args);
-	
-	return ret;
-}
-
-static int klog_vprintf_str_write(const char *str, size_t size, void *data)
-{
-	size_t wr = klog_write(str, size);
-	return str_nlength(str, wr);
-}
-
-static int klog_vprintf_wstr_write(const wchar_t *str, size_t size, void *data)
-{
-	size_t offset = 0;
-	size_t chars = 0;
-	
-	while (offset < size) {
-		char buf[STR_BOUNDS(1)];
-		size_t sz = 0;
-		
-		if (chr_encode(str[chars], buf, &sz, STR_BOUNDS(1)) == EOK)
-			klog_write(buf, sz);
-		
-		chars++;
-		offset += sizeof(wchar_t);
-	}
-	
-	return chars;
-}
-
-/** Print formatted text to klog.
- *
- * @param fmt Format string
- * @param ap  Format parameters
- *
- * \see For more details about format string see printf_core.
- *
- */
-int klog_vprintf(const char *fmt, va_list ap)
-{
-	printf_spec_t ps = {
-		klog_vprintf_str_write,
-		klog_vprintf_wstr_write,
-		NULL
-	};
-	
-	return printf_core(fmt, &ps, ap);
+	return (int) __SYSCALL4(SYS_KLOG, KLOG_READ, (uintptr_t) data, size, 0);
 }
 
Index: uspace/lib/c/generic/io/window.c
===================================================================
--- uspace/lib/c/generic/io/window.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/c/generic/io/window.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -40,11 +40,10 @@
 #include <stdio.h>
 
-int win_register(async_sess_t *sess, service_id_t *in, service_id_t *out, 
-    sysarg_t x_offset, sysarg_t y_offset)
+int win_register(async_sess_t *sess, service_id_t *in, service_id_t *out)
 {
 	async_exch_t *exch = async_exchange_begin(sess);
-	int ret = async_req_2_2(exch, WINDOW_REGISTER, x_offset, y_offset, in, out);
+	int ret = async_req_0_2(exch, WINDOW_REGISTER, in, out);
 	async_exchange_end(exch);
-
+	
 	return ret;
 }
@@ -92,25 +91,26 @@
 }
 
-int win_resize(async_sess_t *sess, sysarg_t width, sysarg_t height, void *cells)
+int win_resize(async_sess_t *sess, sysarg_t x, sysarg_t y, sysarg_t width,
+    sysarg_t height, window_placement_flags_t placement_flags, void *cells)
 {
 	async_exch_t *exch = async_exchange_begin(sess);
-
+	
 	ipc_call_t answer;
-	aid_t req = async_send_2(exch, WINDOW_RESIZE, width, height, &answer);
-
+	aid_t req = async_send_5(exch, WINDOW_RESIZE, x, y, width, height,
+	    (sysarg_t) placement_flags, &answer);
+	
 	int rc = async_share_out_start(exch, cells, AS_AREA_READ | AS_AREA_CACHEABLE);
-
+	
 	async_exchange_end(exch);
-
+	
 	sysarg_t ret;
 	async_wait_for(req, &ret);
-
-	if (rc != EOK) {
+	
+	if (rc != EOK)
 		return rc;
-	} else if (ret != EOK) {
+	else if (ret != EOK)
 		return ret;
-	} else {
-		return EOK;
-	}
+	
+	return EOK;
 }
 
Index: uspace/lib/c/generic/private/stdio.h
===================================================================
--- uspace/lib/c/generic/private/stdio.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/c/generic/private/stdio.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -53,6 +53,6 @@
 	int eof;
 	
-	/** Klog indicator */
-	int klog;
+	/** KIO indicator */
+	int kio;
 	
 	/** Session to the file provider */
Index: uspace/lib/c/generic/setjmp.c
===================================================================
--- uspace/lib/c/generic/setjmp.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/c/generic/setjmp.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2013 Vojtech Horky
+ * 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 libc
+ * @{
+ */
+/** @file Long jump implementation.
+ *
+ * Implementation inspired by Jiri Zarevucky's code from
+ * http://bazaar.launchpad.net/~zarevucky-jiri/helenos/stdc/revision/1544/uspace/lib/posix/setjmp.h
+ */
+
+#include <setjmp.h>
+#include <libarch/fibril.h>
+#include <fibril.h>
+
+/**
+ * Restore environment previously stored by setjmp.
+ *
+ * This function never returns.
+ *
+ * @param env Variable with the environment previously stored by call
+ * to setjmp.
+ * @param val Value to fake when returning from setjmp (0 is transformed to 1).
+ */
+void longjmp(jmp_buf env, int val) {
+	env[0].return_value = (val == 0) ? 1 : val;
+	context_restore(&env[0].context);
+	__builtin_unreachable();
+}
+
+/** @}
+ */
Index: uspace/lib/c/include/adt/checksum.h
===================================================================
--- uspace/lib/c/include/adt/checksum.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/c/include/adt/checksum.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2012 Dominik Taborsky
+ * 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 libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_CHECKSUM_H_
+#define LIBC_CHECKSUM_H_
+
+#include <sys/types.h>
+
+extern uint32_t compute_crc32(uint8_t *, size_t);
+extern uint32_t compute_crc32_seed(uint8_t *, size_t, uint32_t);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/bitops.h
===================================================================
--- uspace/lib/c/include/bitops.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/c/include/bitops.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -107,6 +107,4 @@
 }
 
-extern int __popcountsi2(int);
-
 #endif
 
Index: uspace/lib/c/include/ddi.h
===================================================================
--- uspace/lib/c/include/ddi.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/c/include/ddi.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -130,5 +130,5 @@
 }
 
-extern int irq_register(int, int, int, irq_code_t *);
+extern int irq_register(int, int, int, const irq_code_t *);
 extern int irq_unregister(int, int);
 
Index: pace/lib/c/include/device/ahci.h
===================================================================
--- uspace/lib/c/include/device/ahci.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,53 +1,0 @@
-/*
- * Copyright (c) 2012 Petr Jerman
- * 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 libc
- * @{
- */
-/** @file
- * @brief AHCI interface definition.
- */
-
-#ifndef LIBC_DEVICE_AHCI_H_
-#define LIBC_DEVICE_AHCI_H_
-
-#include <async.h>
-#include <devman.h>
-
-extern async_sess_t* ahci_get_sess(devman_handle_t, char **);
-
-extern int ahci_get_sata_device_name(async_sess_t *, size_t, char *);
-extern int ahci_get_num_blocks(async_sess_t *, uint64_t *);
-extern int ahci_get_block_size(async_sess_t *, size_t *);
-extern int ahci_read_blocks(async_sess_t *, uint64_t, size_t, void *);
-extern int ahci_write_blocks(async_sess_t *, uint64_t, size_t, void *);
-
-#endif
-
-/** @}
- */
Index: pace/lib/c/include/device/battery_dev.h
===================================================================
--- uspace/lib/c/include/device/battery_dev.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,55 +1,0 @@
-/*
- * Copyright (c) 2012 Maurizio Lombardi
- * 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 libc
- * @{
- */
-/** @file
- */
-
-#ifndef LIBC_DEVICE_BATTERY_DEV_H_
-#define LIBC_DEVICE_BATTERY_DEV_H_
-
-#include <async.h>
-
-typedef enum {
-	BATTERY_OK,
-	BATTERY_LOW,
-	BATTERY_NOT_PRESENT,
-} battery_status_t;
-
-typedef enum {
-	BATTERY_STATUS_GET = 0,
-	BATTERY_CHARGE_LEVEL_GET,
-} battery_dev_method_t;
-
-extern int battery_status_get(async_sess_t *, battery_status_t *);
-extern int battery_charge_level_get(async_sess_t *, int *);
-
-#endif
-
Index: pace/lib/c/include/device/char_dev.h
===================================================================
--- uspace/lib/c/include/device/char_dev.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,51 +1,0 @@
-/*
- * Copyright (c) 2010 Lenka Trochtova
- * 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 libc
- * @{
- */
-/** @file
- */
-
-#ifndef LIBC_DEVICE_CHAR_DEV_H_
-#define LIBC_DEVICE_CHAR_DEV_H_
-
-#include <async.h>
-
-typedef enum {
-	CHAR_DEV_READ = 0,
-	CHAR_DEV_WRITE
-} char_dev_method_t;
-
-extern ssize_t char_dev_read(async_sess_t *, void *, size_t);
-extern ssize_t char_dev_write(async_sess_t *, void *, size_t);
-
-#endif
-
-/** @}
- */
Index: pace/lib/c/include/device/graph_dev.h
===================================================================
--- uspace/lib/c/include/device/graph_dev.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,49 +1,0 @@
-/*
- * Copyright (c) 2011 Petr Koupy
- * 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 libc
- * @{
- */
-/** @file
- */
-
-#ifndef LIBC_DEVICE_GRAPH_DEV_H_
-#define LIBC_DEVICE_GRAPH_DEV_H_
-
-#include <async.h>
-
-typedef enum {
-	GRAPH_DEV_CONNECT = 0
-} graph_dev_method_t;
-
-extern int graph_dev_connect(async_sess_t *);
-
-#endif
-
-/** @}
- */
Index: pace/lib/c/include/device/nic.h
===================================================================
--- uspace/lib/c/include/device/nic.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,159 +1,0 @@
-/*
- * Copyright (c) 2010 Radim Vansa
- * 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 libc
- * @{
- */
-/** @file
- */
-
-#ifndef LIBC_DEVICE_NIC_H_
-#define LIBC_DEVICE_NIC_H_
-
-#include <async.h>
-#include <nic/nic.h>
-#include <ipc/common.h>
-
-typedef enum {
-	NIC_SEND_MESSAGE = 0,
-	NIC_CALLBACK_CREATE,
-	NIC_GET_STATE,
-	NIC_SET_STATE,
-	NIC_GET_ADDRESS,
-	NIC_SET_ADDRESS,
-	NIC_GET_STATS,
-	NIC_GET_DEVICE_INFO,
-	NIC_GET_CABLE_STATE,
-	NIC_GET_OPERATION_MODE,
-	NIC_SET_OPERATION_MODE,
-	NIC_AUTONEG_ENABLE,
-	NIC_AUTONEG_DISABLE,
-	NIC_AUTONEG_PROBE,
-	NIC_AUTONEG_RESTART,
-	NIC_GET_PAUSE,
-	NIC_SET_PAUSE,
-	NIC_UNICAST_GET_MODE,
-	NIC_UNICAST_SET_MODE,
-	NIC_MULTICAST_GET_MODE,
-	NIC_MULTICAST_SET_MODE,
-	NIC_BROADCAST_GET_MODE,
-	NIC_BROADCAST_SET_MODE,
-	NIC_DEFECTIVE_GET_MODE,
-	NIC_DEFECTIVE_SET_MODE,
-	NIC_BLOCKED_SOURCES_GET,
-	NIC_BLOCKED_SOURCES_SET,
-	NIC_VLAN_GET_MASK,
-	NIC_VLAN_SET_MASK,
-	NIC_VLAN_SET_TAG,
-	NIC_WOL_VIRTUE_ADD,
-	NIC_WOL_VIRTUE_REMOVE,
-	NIC_WOL_VIRTUE_PROBE,
-	NIC_WOL_VIRTUE_LIST,
-	NIC_WOL_VIRTUE_GET_CAPS,
-	NIC_WOL_LOAD_INFO,
-	NIC_OFFLOAD_PROBE,
-	NIC_OFFLOAD_SET,
-	NIC_POLL_GET_MODE,
-	NIC_POLL_SET_MODE,
-	NIC_POLL_NOW
-} nic_funcs_t;
-
-typedef enum {
-	NIC_EV_ADDR_CHANGED = IPC_FIRST_USER_METHOD,
-	NIC_EV_RECEIVED,
-	NIC_EV_DEVICE_STATE
-} nic_event_t;
-
-extern int nic_send_frame(async_sess_t *, void *, size_t);
-extern int nic_callback_create(async_sess_t *, async_client_conn_t, void *);
-extern int nic_get_state(async_sess_t *, nic_device_state_t *);
-extern int nic_set_state(async_sess_t *, nic_device_state_t);
-extern int nic_get_address(async_sess_t *, nic_address_t *);
-extern int nic_set_address(async_sess_t *, const nic_address_t *);
-extern int nic_get_stats(async_sess_t *, nic_device_stats_t *);
-extern int nic_get_device_info(async_sess_t *, nic_device_info_t *);
-extern int nic_get_cable_state(async_sess_t *, nic_cable_state_t *);
-
-extern int nic_get_operation_mode(async_sess_t *, int *, nic_channel_mode_t *,
-    nic_role_t *);
-extern int nic_set_operation_mode(async_sess_t *, int, nic_channel_mode_t,
-    nic_role_t);
-extern int nic_autoneg_enable(async_sess_t *, uint32_t);
-extern int nic_autoneg_disable(async_sess_t *);
-extern int nic_autoneg_probe(async_sess_t *, uint32_t *, uint32_t *,
-    nic_result_t *, nic_result_t *);
-extern int nic_autoneg_restart(async_sess_t *);
-extern int nic_get_pause(async_sess_t *, nic_result_t *, nic_result_t *,
-    uint16_t *);
-extern int nic_set_pause(async_sess_t *, int, int, uint16_t);
-
-extern int nic_unicast_get_mode(async_sess_t *, nic_unicast_mode_t *, size_t,
-    nic_address_t *, size_t *);
-extern int nic_unicast_set_mode(async_sess_t *, nic_unicast_mode_t,
-    const nic_address_t *, size_t);
-extern int nic_multicast_get_mode(async_sess_t *, nic_multicast_mode_t *,
-    size_t, nic_address_t *, size_t *);
-extern int nic_multicast_set_mode(async_sess_t *, nic_multicast_mode_t,
-    const nic_address_t *, size_t);
-extern int nic_broadcast_get_mode(async_sess_t *, nic_broadcast_mode_t *);
-extern int nic_broadcast_set_mode(async_sess_t *, nic_broadcast_mode_t);
-extern int nic_defective_get_mode(async_sess_t *, uint32_t *);
-extern int nic_defective_set_mode(async_sess_t *, uint32_t);
-extern int nic_blocked_sources_get(async_sess_t *, size_t, nic_address_t *,
-    size_t *);
-extern int nic_blocked_sources_set(async_sess_t *, const nic_address_t *,
-    size_t);
-
-extern int nic_vlan_get_mask(async_sess_t *, nic_vlan_mask_t *);
-extern int nic_vlan_set_mask(async_sess_t *, const nic_vlan_mask_t *);
-extern int nic_vlan_set_tag(async_sess_t *, uint16_t, bool, bool);
-
-extern int nic_wol_virtue_add(async_sess_t *, nic_wv_type_t, const void *,
-    size_t, nic_wv_id_t *);
-extern int nic_wol_virtue_remove(async_sess_t *, nic_wv_id_t);
-extern int nic_wol_virtue_probe(async_sess_t *, nic_wv_id_t, nic_wv_type_t *,
-    size_t, void *, size_t *);
-extern int nic_wol_virtue_list(async_sess_t *, nic_wv_type_t, size_t,
-    nic_wv_id_t *, size_t *);
-extern int nic_wol_virtue_get_caps(async_sess_t *, nic_wv_type_t, int *);
-extern int nic_wol_load_info(async_sess_t *, nic_wv_type_t *, size_t, uint8_t *,
-    size_t *);
-
-extern int nic_offload_probe(async_sess_t *, uint32_t *, uint32_t *);
-extern int nic_offload_set(async_sess_t *, uint32_t, uint32_t);
-
-extern int nic_poll_get_mode(async_sess_t *, nic_poll_mode_t *,
-    struct timeval *);
-extern int nic_poll_set_mode(async_sess_t *, nic_poll_mode_t,
-    const struct timeval *);
-extern int nic_poll_now(async_sess_t *);
-
-#endif
-
-/** @}
- */
Index: pace/lib/c/include/device/pci.h
===================================================================
--- uspace/lib/c/include/device/pci.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,63 +1,0 @@
-/*
- * Copyright (c) 2011 Jiri Michalec
- * 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 libc
- * @{
- */
-/** @file
- */
-
-#ifndef LIBC_DEVICE_PCI_H_
-#define LIBC_DEVICE_PCI_H_
-
-#include <async.h>
-
-#define PCI_DEVICE_ID  0x02
-
-typedef enum {
-	IPC_M_CONFIG_SPACE_READ_8,
-	IPC_M_CONFIG_SPACE_READ_16,
-	IPC_M_CONFIG_SPACE_READ_32,
-	
-	IPC_M_CONFIG_SPACE_WRITE_8,
-	IPC_M_CONFIG_SPACE_WRITE_16,
-	IPC_M_CONFIG_SPACE_WRITE_32
-} pci_dev_iface_funcs_t;
-
-extern int pci_config_space_read_8(async_sess_t *, uint32_t, uint8_t *);
-extern int pci_config_space_read_16(async_sess_t *, uint32_t, uint16_t *);
-extern int pci_config_space_read_32(async_sess_t *, uint32_t, uint32_t *);
-
-extern int pci_config_space_write_8(async_sess_t *, uint32_t, uint8_t);
-extern int pci_config_space_write_16(async_sess_t *, uint32_t, uint16_t);
-extern int pci_config_space_write_32(async_sess_t *, uint32_t, uint32_t);
-
-#endif
-
-/** @}
- */
Index: uspace/lib/c/include/io/kio.h
===================================================================
--- uspace/lib/c/include/io/kio.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/c/include/io/kio.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2006 Jakub Vana
+ * 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 libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_IO_KIO_H_
+#define LIBC_IO_KIO_H_
+
+#include <sys/types.h>
+#include <stdarg.h>
+#include <io/verify.h>
+
+extern size_t kio_write(const void *, size_t);
+extern void kio_update(void);
+extern void kio_command(const void *, size_t);
+extern int kio_printf(const char *, ...)
+    PRINTF_ATTRIBUTE(1, 2);
+extern int kio_vprintf(const char *, va_list);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/io/klog.h
===================================================================
--- uspace/lib/c/include/io/klog.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/c/include/io/klog.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2006 Jakub Vana
+ * Copyright (c) 2013 Martin Sucha
  * All rights reserved.
  *
@@ -39,11 +39,26 @@
 #include <stdarg.h>
 #include <io/verify.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <str.h>
+#include <abi/log.h>
 
-extern size_t klog_write(const void *, size_t);
-extern void klog_update(void);
-extern void klog_command(const void *, size_t);
-extern int klog_printf(const char *, ...)
-    PRINTF_ATTRIBUTE(1, 2);
-extern int klog_vprintf(const char *, va_list);
+extern size_t klog_write(log_level_t, const void *, size_t);
+extern int klog_read(void *, size_t);
+
+#define KLOG_PRINTF(lvl, fmt, ...) ({ \
+	char *_fmt = str_dup(fmt); \
+	size_t _fmtsize = str_size(_fmt); \
+	if (_fmtsize > 0 && _fmt[_fmtsize - 1] == '\n') \
+		_fmt[_fmtsize - 1] = 0; \
+	char *_s; \
+	int _c = asprintf(&_s, _fmt, ##__VA_ARGS__); \
+	free(_fmt); \
+	if (_c >= 0) { \
+		_c = klog_write((lvl), _s, str_size(_s)); \
+		free(_s); \
+	}; \
+	(_c >= 0); \
+})
 
 #endif
Index: uspace/lib/c/include/io/log.h
===================================================================
--- uspace/lib/c/include/io/log.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/c/include/io/log.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -39,22 +39,5 @@
 #include <io/verify.h>
 
-/** Log message level. */
-typedef enum {
-	/** Fatal error, program is not able to recover at all. */
-	LVL_FATAL,
-	/** Serious error but the program can recover from it. */
-	LVL_ERROR,
-	/** Easily recoverable problem. */
-	LVL_WARN,
-	/** Information message that ought to be printed by default. */
-	LVL_NOTE,
-	/** Debugging purpose message. */
-	LVL_DEBUG,
-	/** More detailed debugging message. */
-	LVL_DEBUG2,
-	
-	/** For checking range of values */
-	LVL_LIMIT
-} log_level_t;
+#include <abi/log.h>
 
 /** Log itself (logging target). */
Index: uspace/lib/c/include/io/window.h
===================================================================
--- uspace/lib/c/include/io/window.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/c/include/io/window.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -43,14 +43,43 @@
 #include <io/pos_event.h>
 
+typedef enum {
+	GF_EMPTY = 0,
+	GF_MOVE_X = 1,
+	GF_MOVE_Y = 2,
+	GF_RESIZE_X = 4,
+	GF_RESIZE_Y = 8,
+	GF_SCALE_X = 16,
+	GF_SCALE_Y = 32
+} window_grab_flags_t;
+
+typedef enum {
+	WINDOW_PLACEMENT_ANY = 0,
+	WINDOW_PLACEMENT_CENTER_X = 1,
+	WINDOW_PLACEMENT_CENTER_Y = 2,
+	WINDOW_PLACEMENT_CENTER =
+	    WINDOW_PLACEMENT_CENTER_X | WINDOW_PLACEMENT_CENTER_Y,
+	WINDOW_PLACEMENT_LEFT = 4,
+	WINDOW_PLACEMENT_RIGHT = 8,
+	WINDOW_PLACEMENT_TOP = 16,
+	WINDOW_PLACEMENT_BOTTOM = 32,
+	WINDOW_PLACEMENT_ABSOLUTE_X = 64,
+	WINDOW_PLACEMENT_ABSOLUTE_Y = 128,
+	WINDOW_PLACEMENT_ABSOLUTE =
+	    WINDOW_PLACEMENT_ABSOLUTE_X | WINDOW_PLACEMENT_ABSOLUTE_Y
+} window_placement_flags_t;
+
 typedef struct {
 	sysarg_t object;
 	sysarg_t slot;
 	sysarg_t argument;
-} sig_event_t;
+} signal_event_t;
 
 typedef struct {
+	sysarg_t offset_x;
+	sysarg_t offset_y;
 	sysarg_t width;
 	sysarg_t height;
-} rsz_event_t;
+	window_placement_flags_t placement_flags;
+} resize_event_t;
 
 typedef enum {
@@ -69,6 +98,6 @@
 	kbd_event_t kbd;
 	pos_event_t pos;
-	sig_event_t sig;
-	rsz_event_t rsz;
+	signal_event_t signal;
+	resize_event_t resize;
 } window_event_data_t;
 
@@ -79,15 +108,5 @@
 } window_event_t;
 
-typedef enum {
-	GF_EMPTY = 0,
-	GF_MOVE_X = 1,
-	GF_MOVE_Y = 2,
-	GF_RESIZE_X = 4,
-	GF_RESIZE_Y = 8,
-	GF_SCALE_X = 16,
-	GF_SCALE_Y = 32
-} window_grab_flags_t;
-
-extern int win_register(async_sess_t *, service_id_t *, service_id_t *, sysarg_t, sysarg_t);
+extern int win_register(async_sess_t *, service_id_t *, service_id_t *);
 
 extern int win_get_event(async_sess_t *, window_event_t *);
@@ -95,5 +114,6 @@
 extern int win_damage(async_sess_t *, sysarg_t, sysarg_t, sysarg_t, sysarg_t);
 extern int win_grab(async_sess_t *, sysarg_t, sysarg_t);
-extern int win_resize(async_sess_t *, sysarg_t, sysarg_t, void *);
+extern int win_resize(async_sess_t *, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
+    window_placement_flags_t, void *);
 extern int win_close(async_sess_t *);
 extern int win_close_request(async_sess_t *);
Index: uspace/lib/c/include/math.h
===================================================================
--- uspace/lib/c/include/math.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/c/include/math.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2011 Petr Koupy
+ * 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 libposix
+ * @{
+ */
+/** @file Mathematical operations.
+ *
+ * The implementation is provided by a separate library to allow
+ * switching of the implementations.
+ */
+
+#ifndef LIBC_MATH_H_
+#define LIBC_MATH_H_
+
+#ifdef __GNUC__
+	#define HUGE_VAL (__builtin_huge_val())
+#endif
+
+extern double ldexp(double, int);
+extern double frexp(double, int *);
+
+extern double fabs(double);
+extern double floor(double);
+extern double ceil(double);
+extern double modf(double, double *);
+extern double fmod(double, double);
+extern double pow(double, double);
+extern double exp(double);
+extern double expm1(double);
+extern double sqrt(double);
+extern double log(double);
+extern double log10(double);
+extern double sin(double);
+extern double sinh(double);
+extern double asin(double);
+extern double asinh(double);
+extern double cos(double);
+extern double cosh(double);
+extern double acos(double);
+extern double acosh(double);
+extern double tan(double);
+extern double tanh(double);
+extern double atan(double);
+extern double atanh(double);
+extern double atan2(double, double);
+
+double copysign(double, double);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/setjmp.h
===================================================================
--- uspace/lib/c/include/setjmp.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/c/include/setjmp.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -1,4 +1,5 @@
 /*
  * Copyright (c) 2008 Josef Cejka
+ * Copyright (c) 2013 Vojtech Horky
  * All rights reserved.
  *
@@ -30,5 +31,8 @@
  * @{
  */
-/** @file
+/** @file Long jump implementation.
+ *
+ * Implementation inspired by Jiri Zarevucky's code from
+ * http://bazaar.launchpad.net/~zarevucky-jiri/helenos/stdc/revision/1544/uspace/lib/posix/setjmp.h
  */
 
@@ -38,7 +42,31 @@
 #include <libarch/fibril.h>
 
-typedef context_t jmp_buf[1];
+struct jmp_buf_interal {
+	context_t context;
+	int return_value;
+};
+typedef struct jmp_buf_interal jmp_buf[1];
 
-extern int setjmp(jmp_buf env);
+/*
+ * Specified as extern to minimize number of included headers
+ * because this file is used as is in libposix too.
+ */
+extern int context_save(context_t *ctx) __attribute__((returns_twice));
+
+/**
+ * Save current environment (registers).
+ *
+ * This function may return twice.
+ *
+ * @param env Variable where to save the environment (of type jmp_buf).
+ * @return Whether the call returned after longjmp.
+ * @retval 0 Environment was saved, normal execution.
+ * @retval other longjmp was executed and returned here.
+ */
+#define setjmp(env) \
+	((env)[0].return_value = 0, \
+	context_save(&(env)[0].context), \
+	(env)[0].return_value)
+
 extern void longjmp(jmp_buf env, int val) __attribute__((noreturn));
 
Index: uspace/lib/c/include/stdio.h
===================================================================
--- uspace/lib/c/include/stdio.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/c/include/stdio.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -40,5 +40,5 @@
 #include <str.h>
 #include <io/verify.h>
-#include <abi/klog.h>
+#include <abi/kio.h>
 
 #define EOF  (-1)
@@ -52,5 +52,5 @@
 		int _n = snprintf(_buf, sizeof(_buf), fmt, ##__VA_ARGS__); \
 		if (_n > 0) \
-			(void) __SYSCALL3(SYS_KLOG, KLOG_WRITE, (sysarg_t) _buf, str_size(_buf)); \
+			(void) __SYSCALL3(SYS_KIO, KIO_WRITE, (sysarg_t) _buf, str_size(_buf)); \
 	}
 
Index: uspace/lib/draw/cursor/embedded.c
===================================================================
--- uspace/lib/draw/cursor/embedded.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/draw/cursor/embedded.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -46,5 +46,5 @@
 	assert(state_count);
 	assert(data);
-
+	
 	(*state_count) = 1;
 	(*data) = NULL;
@@ -53,13 +53,10 @@
 static surface_t *cde_render(uint8_t state)
 {
-	if (state != 0) {
+	if (state != 0)
 		return NULL;
-	}
-
+	
 	surface_t *surface = surface_create(CURSOR_WIDTH, CURSOR_HEIGHT, NULL, 0);
-
-	if (!surface) {
+	if (!surface)
 		return NULL;
-	}
 	
 	for (unsigned int y = 0; y < CURSOR_HEIGHT; ++y) {
@@ -69,8 +66,10 @@
 			pixel_t pixel = (cursor_texture[offset] & (1 << (x % 8))) ?
 			    PIXEL(255, 0, 0, 0) : PIXEL(255, 255, 255, 255);
-			surface_put_pixel(surface, x, y, visible ? pixel : PIXEL(0, 0, 0, 0));
+			
+			if (visible)
+				surface_put_pixel(surface, x, y, pixel);
 		}
 	}
-
+	
 	return surface;
 }
Index: uspace/lib/drv/Makefile
===================================================================
--- uspace/lib/drv/Makefile	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/Makefile	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -29,5 +29,9 @@
 
 USPACE_PREFIX = ../..
-EXTRA_CFLAGS = -Iinclude -I$(LIBUSB_PREFIX)/include -I$(LIBPCM_PREFIX)/include
+EXTRA_CFLAGS = \
+	-Iinclude \
+	-Igeneric/private \
+	-I$(LIBUSB_PREFIX)/include \
+	-I$(LIBPCM_PREFIX)/include
 LIBRARY = libdrv
 
Index: uspace/lib/drv/generic/dev_iface.c
===================================================================
--- uspace/lib/drv/generic/dev_iface.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/generic/dev_iface.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -69,9 +69,9 @@
 		[CLOCK_DEV_IFACE] = &remote_clock_dev_iface,
 		[BATTERY_DEV_IFACE] = &remote_battery_dev_iface,
-		[AHCI_DEV_IFACE] = &remote_ahci_iface
+		[AHCI_DEV_IFACE] = &remote_ahci_iface,
 	}
 };
 
-remote_iface_t *get_remote_iface(int idx)
+const remote_iface_t *get_remote_iface(int idx)
 {
 	assert(is_valid_iface_idx(idx));
@@ -80,5 +80,5 @@
 
 remote_iface_func_ptr_t
-get_remote_method(remote_iface_t *rem_iface, sysarg_t iface_method_idx)
+get_remote_method(const remote_iface_t *rem_iface, sysarg_t iface_method_idx)
 {
 	if (iface_method_idx >= rem_iface->method_count)
Index: uspace/lib/drv/generic/driver.c
===================================================================
--- uspace/lib/drv/generic/driver.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/generic/driver.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -63,5 +63,5 @@
 
 /** Driver structure */
-static driver_t *driver;
+static const driver_t *driver;
 
 /** Devices */
@@ -413,5 +413,5 @@
 		 * handling ("remote interface").
 		 */
-		remote_iface_t *rem_iface = get_remote_iface(iface_idx);
+		const remote_iface_t *rem_iface = get_remote_iface(iface_idx);
 		assert(rem_iface != NULL);
 		
@@ -956,5 +956,5 @@
 }
 
-int ddf_driver_main(driver_t *drv)
+int ddf_driver_main(const driver_t *drv)
 {
 	/*
Index: uspace/lib/drv/generic/interrupt.c
===================================================================
--- uspace/lib/drv/generic/interrupt.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/generic/interrupt.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -39,4 +39,5 @@
 #include <errno.h>
 #include <sys/types.h>
+#include <macros.h>
 
 #include "ddf/interrupt.h"
@@ -55,7 +56,4 @@
 static interrupt_context_t *find_interrupt_context(
     interrupt_context_list_t *list, ddf_dev_t *dev, int irq);
-int register_interrupt_handler(ddf_dev_t *dev, int irq,
-    interrupt_handler_t *handler, irq_code_t *pseudocode);
-int unregister_interrupt_handler(ddf_dev_t *dev, int irq);
 
 /** Interrupts */
@@ -68,8 +66,8 @@
 };
 
-static irq_code_t default_pseudocode = {
+static const irq_code_t default_pseudocode = {
 	0,
 	NULL,
-	sizeof(default_cmds) / sizeof(irq_cmd_t),
+	ARRAY_SIZE(default_cmds),
 	default_cmds
 };
@@ -169,5 +167,5 @@
 
 int register_interrupt_handler(ddf_dev_t *dev, int irq,
-    interrupt_handler_t *handler, irq_code_t *pseudocode)
+    interrupt_handler_t *handler, const irq_code_t *pseudocode)
 {
 	interrupt_context_t *ctx = create_interrupt_context();
Index: uspace/lib/drv/generic/private/remote_ahci.h
===================================================================
--- uspace/lib/drv/generic/private/remote_ahci.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/drv/generic/private/remote_ahci.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2012 Petr Jerman
+ * 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_REMOTE_AHCI_H_
+#define LIBDRV_REMOTE_AHCI_H_
+
+extern remote_iface_t remote_ahci_iface;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/drv/generic/private/remote_audio_mixer.h
===================================================================
--- uspace/lib/drv/generic/private/remote_audio_mixer.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/drv/generic/private/remote_audio_mixer.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2011 Jan Vesely
+ * 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_REMOTE_AUDIO_MIXER_H_
+#define LIBDRV_REMOTE_AUDIO_MIXER_H_
+
+extern remote_iface_t remote_audio_mixer_iface;
+
+#endif
+
+/**
+ * @}
+ */
+
Index: uspace/lib/drv/generic/private/remote_audio_pcm.h
===================================================================
--- uspace/lib/drv/generic/private/remote_audio_pcm.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/drv/generic/private/remote_audio_pcm.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2011 Jan Vesely
+ * 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_REMOTE_AUDIO_PCM_H_
+#define LIBDRV_REMOTE_AUDIO_PCM_H_
+
+extern remote_iface_t remote_audio_pcm_iface;
+
+#endif
+
+/**
+ * @}
+ */
+
Index: uspace/lib/drv/generic/private/remote_battery_dev.h
===================================================================
--- uspace/lib/drv/generic/private/remote_battery_dev.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/drv/generic/private/remote_battery_dev.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2012 Maurizio Lombardi
+ * 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_REMOTE_BATTERY_DEV_H_
+#define LIBDRV_REMOTE_BATTERY_DEV_H_
+
+extern remote_iface_t remote_battery_dev_iface;
+
+#endif
+
+/**
+ * @}
+ */
+
Index: uspace/lib/drv/generic/private/remote_char_dev.h
===================================================================
--- uspace/lib/drv/generic/private/remote_char_dev.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/drv/generic/private/remote_char_dev.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2010 Lenka Trochtova
+ * 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_REMOTE_CHAR_DEV_H_
+#define LIBDRV_REMOTE_CHAR_DEV_H_
+
+extern remote_iface_t remote_char_dev_iface;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/drv/generic/private/remote_clock_dev.h
===================================================================
--- uspace/lib/drv/generic/private/remote_clock_dev.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/drv/generic/private/remote_clock_dev.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2012 Maurizio Lombardi
+ * 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_REMOTE_CLOCK_DEV_H_
+#define LIBDRV_REMOTE_CLOCK_DEV_H_
+
+extern remote_iface_t remote_clock_dev_iface;
+
+#endif
+
+/**
+ * @}
+ */
+
Index: uspace/lib/drv/generic/private/remote_graph_dev.h
===================================================================
--- uspace/lib/drv/generic/private/remote_graph_dev.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/drv/generic/private/remote_graph_dev.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2011 Petr Koupy
+ * 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_REMOTE_GRAPH_DEV_H_
+#define LIBDRV_REMOTE_GRAPH_DEV_H_
+
+extern remote_iface_t remote_graph_dev_iface;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/drv/generic/private/remote_hw_res.h
===================================================================
--- uspace/lib/drv/generic/private/remote_hw_res.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/drv/generic/private/remote_hw_res.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2010 Lenka Trochtova
+ * 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_REMOTE_HW_RES_H_
+#define LIBDRV_REMOTE_HW_RES_H_
+
+extern remote_iface_t remote_hw_res_iface;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/drv/generic/private/remote_nic.h
===================================================================
--- uspace/lib/drv/generic/private/remote_nic.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/drv/generic/private/remote_nic.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2011 Radim Vansa
+ * 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_REMOTE_NIC_H_
+#define LIBDRV_REMOTE_NIC_H_
+
+extern remote_iface_t remote_nic_iface;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/drv/generic/private/remote_pci.h
===================================================================
--- uspace/lib/drv/generic/private/remote_pci.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/drv/generic/private/remote_pci.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2011 Jan Vesely
+ * 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_REMOTE_PCI_H_
+#define LIBDRV_REMOTE_PCI_H_
+
+extern remote_iface_t remote_pci_iface;
+
+#endif
+
+/**
+ * @}
+ */
+
Index: uspace/lib/drv/generic/private/remote_pio_window.h
===================================================================
--- uspace/lib/drv/generic/private/remote_pio_window.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/drv/generic/private/remote_pio_window.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2013 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_REMOTE_PIO_WINDOW_H_
+#define LIBDRV_REMOTE_PIO_WINDOW_H_
+
+extern remote_iface_t remote_pio_window_iface;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/drv/generic/private/remote_usb.h
===================================================================
--- uspace/lib/drv/generic/private/remote_usb.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/drv/generic/private/remote_usb.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2010 Vojtech Horky
+ * 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_REMOTE_USB_H_
+#define LIBDRV_REMOTE_USB_H_
+
+extern remote_iface_t remote_usb_iface;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/drv/generic/private/remote_usbhc.h
===================================================================
--- uspace/lib/drv/generic/private/remote_usbhc.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/drv/generic/private/remote_usbhc.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2010 Vojtech Horky
+ * 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_REMOTE_USBHC_H_
+#define LIBDRV_REMOTE_USBHC_H_
+
+extern remote_iface_t remote_usbhc_iface;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/drv/generic/private/remote_usbhid.h
===================================================================
--- uspace/lib/drv/generic/private/remote_usbhid.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/drv/generic/private/remote_usbhid.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2011 Vojtech Horky
+ * 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_REMOTE_USBHID_H_
+#define LIBDRV_REMOTE_USBHID_H_
+
+extern remote_iface_t remote_usbhid_iface;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/drv/generic/remote_ahci.c
===================================================================
--- uspace/lib/drv/generic/remote_ahci.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/generic/remote_ahci.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -33,7 +33,10 @@
  */
 
+#include <as.h>
 #include <async.h>
+#include <devman.h>
 #include <errno.h>
 #include <stdio.h>
+#include <macros.h>
 #include "ahci_iface.h"
 #include "ddf/driver.h"
@@ -47,4 +50,6 @@
 } ahci_iface_funcs_t;
 
+#define MAX_NAME_LENGTH  1024
+
 #define LO(ptr) \
 	((uint32_t) (((uint64_t) ((uintptr_t) (ptr))) & 0xffffffff))
@@ -53,4 +58,128 @@
 	((uint32_t) (((uint64_t) ((uintptr_t) (ptr))) >> 32))
 
+async_sess_t* ahci_get_sess(devman_handle_t funh, char **name)
+{
+	// FIXME: Use a better way than substring match
+	
+	*name = NULL;
+	
+	char devn[MAX_NAME_LENGTH];
+	int rc = devman_fun_get_name(funh, devn, MAX_NAME_LENGTH);
+	if (rc != EOK)
+		return NULL;
+	
+	size_t devn_size = str_size(devn);
+	
+	if ((devn_size > 5) && (str_lcmp(devn, "ahci_", 5) == 0)) {
+		async_sess_t *sess = devman_device_connect(EXCHANGE_PARALLEL,
+		    funh, IPC_FLAG_BLOCKING);
+		
+		if (sess) {
+			*name = str_dup(devn);
+			return sess;
+		}
+	}
+	
+	return NULL;
+}
+
+int ahci_get_sata_device_name(async_sess_t *sess, size_t sata_dev_name_length,
+    char *sata_dev_name)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	if (!exch)
+		return EINVAL;
+	
+	aid_t req = async_send_2(exch, DEV_IFACE_ID(AHCI_DEV_IFACE),
+	    IPC_M_AHCI_GET_SATA_DEVICE_NAME, sata_dev_name_length, NULL);
+	
+	async_data_read_start(exch, sata_dev_name, sata_dev_name_length);
+	
+	sysarg_t rc;
+	async_wait_for(req, &rc);
+	
+	return rc;
+}
+
+int ahci_get_num_blocks(async_sess_t *sess, uint64_t *blocks)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	if (!exch)
+		return EINVAL;
+	
+	sysarg_t blocks_hi;
+	sysarg_t blocks_lo;
+	int rc = async_req_1_2(exch, DEV_IFACE_ID(AHCI_DEV_IFACE),
+	    IPC_M_AHCI_GET_NUM_BLOCKS, &blocks_hi, &blocks_lo);
+	
+	async_exchange_end(exch);
+	
+	if (rc == EOK) {
+		*blocks = (((uint64_t) blocks_hi) << 32)
+		    | (((uint64_t) blocks_lo) & 0xffffffff);
+	}
+	
+	return rc;
+}
+
+int ahci_get_block_size(async_sess_t *sess, size_t *blocks_size)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	if (!exch)
+		return EINVAL;
+	
+	sysarg_t bs;
+	int rc = async_req_1_1(exch, DEV_IFACE_ID(AHCI_DEV_IFACE),
+	    IPC_M_AHCI_GET_BLOCK_SIZE, &bs);
+	
+	async_exchange_end(exch);
+	
+	if (rc == EOK)
+		*blocks_size = (size_t) bs;
+	
+	return rc;
+}
+
+int ahci_read_blocks(async_sess_t *sess, uint64_t blocknum, size_t count,
+    void *buf)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	if (!exch)
+		return EINVAL;
+	
+	aid_t req;
+	req = async_send_4(exch, DEV_IFACE_ID(AHCI_DEV_IFACE),
+	    IPC_M_AHCI_READ_BLOCKS, HI(blocknum),  LO(blocknum), count, NULL);
+	
+	async_share_out_start(exch, buf, AS_AREA_READ | AS_AREA_WRITE);
+	
+	async_exchange_end(exch);
+	
+	sysarg_t rc;
+	async_wait_for(req, &rc);
+	
+	return rc;
+}
+
+int ahci_write_blocks(async_sess_t *sess, uint64_t blocknum, size_t count,
+    void* buf)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	if (!exch)
+		return EINVAL;
+	
+	aid_t req = async_send_4(exch, DEV_IFACE_ID(AHCI_DEV_IFACE),
+	    IPC_M_AHCI_WRITE_BLOCKS, HI(blocknum),  LO(blocknum), count, NULL);
+	
+	async_share_out_start(exch, buf, AS_AREA_READ | AS_AREA_WRITE);
+	
+	async_exchange_end(exch);
+	
+	sysarg_t rc;
+	async_wait_for(req, &rc);
+	
+	return rc;
+}
+
 static void remote_ahci_get_sata_device_name(ddf_fun_t *, void *, ipc_callid_t,
     ipc_call_t *);
@@ -65,5 +194,5 @@
 
 /** Remote AHCI interface operations. */
-static remote_iface_func_ptr_t remote_ahci_iface_ops [] = {
+static const remote_iface_func_ptr_t remote_ahci_iface_ops [] = {
 	[IPC_M_AHCI_GET_SATA_DEVICE_NAME] = remote_ahci_get_sata_device_name,
 	[IPC_M_AHCI_GET_NUM_BLOCKS] = remote_ahci_get_num_blocks,
@@ -75,7 +204,6 @@
 /** Remote AHCI interface structure.
  */
-remote_iface_t remote_ahci_iface = {
-	.method_count = sizeof(remote_ahci_iface_ops) /
-	    sizeof(remote_ahci_iface_ops[0]),
+const remote_iface_t remote_ahci_iface = {
+	.method_count = ARRAY_SIZE(remote_ahci_iface_ops),
 	.methods = remote_ahci_iface_ops
 };
Index: uspace/lib/drv/generic/remote_audio_mixer.c
===================================================================
--- uspace/lib/drv/generic/remote_audio_mixer.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/generic/remote_audio_mixer.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -37,4 +37,5 @@
 #include <assert.h>
 #include <str.h>
+#include <macros.h>
 
 #include "audio_mixer_iface.h"
@@ -204,5 +205,5 @@
 
 /** Remote audio mixer interface operations. */
-static remote_iface_func_ptr_t remote_audio_mixer_iface_ops[] = {
+static const remote_iface_func_ptr_t remote_audio_mixer_iface_ops[] = {
 	[IPC_M_AUDIO_MIXER_GET_INFO] = remote_audio_mixer_get_info,
 	[IPC_M_AUDIO_MIXER_GET_ITEM_INFO] = remote_audio_mixer_get_item_info,
@@ -212,7 +213,6 @@
 
 /** Remote audio mixer interface structure. */
-remote_iface_t remote_audio_mixer_iface = {
-	.method_count = sizeof(remote_audio_mixer_iface_ops) /
-	    sizeof(remote_audio_mixer_iface_ops[0]),
+const remote_iface_t remote_audio_mixer_iface = {
+	.method_count = ARRAY_SIZE(remote_audio_mixer_iface_ops),
 	.methods = remote_audio_mixer_iface_ops
 };
Index: uspace/lib/drv/generic/remote_audio_pcm.c
===================================================================
--- uspace/lib/drv/generic/remote_audio_pcm.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/generic/remote_audio_pcm.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -38,5 +38,4 @@
 #include <macros.h>
 #include <str.h>
-#include <as.h>
 #include <sys/mman.h>
 
@@ -611,5 +610,5 @@
 
 /** Remote audio pcm buffer interface operations. */
-static remote_iface_func_ptr_t remote_audio_pcm_iface_ops[] = {
+static const remote_iface_func_ptr_t remote_audio_pcm_iface_ops[] = {
 	[IPC_M_AUDIO_PCM_GET_INFO_STR] = remote_audio_pcm_get_info_str,
 	[IPC_M_AUDIO_PCM_QUERY_CAPS] = remote_audio_pcm_query_caps,
@@ -627,7 +626,6 @@
 
 /** Remote audio mixer interface structure. */
-remote_iface_t remote_audio_pcm_iface = {
-	.method_count = sizeof(remote_audio_pcm_iface_ops) /
-	    sizeof(remote_audio_pcm_iface_ops[0]),
+const remote_iface_t remote_audio_pcm_iface = {
+	.method_count = ARRAY_SIZE(remote_audio_pcm_iface_ops),
 	.methods = remote_audio_pcm_iface_ops
 };
Index: uspace/lib/drv/generic/remote_battery_dev.c
===================================================================
--- uspace/lib/drv/generic/remote_battery_dev.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/generic/remote_battery_dev.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -36,6 +36,57 @@
 #include <errno.h>
 #include <ops/battery_dev.h>
-#include <device/battery_dev.h>
+#include <battery_iface.h>
 #include <ddf/driver.h>
+#include <macros.h>
+
+/** Read the current battery status from the device
+ *
+ * @param sess     Session of the device
+ * @param status   Current status of the battery
+ *
+ * @return         EOK on success or a negative error code
+ */
+int
+battery_status_get(async_sess_t *sess, battery_status_t *batt_status)
+{
+	sysarg_t status;
+
+	async_exch_t *exch = async_exchange_begin(sess);
+
+	int const rc = async_req_1_1(exch, DEV_IFACE_ID(BATTERY_DEV_IFACE),
+	    BATTERY_STATUS_GET, &status);
+
+	async_exchange_end(exch);
+
+	if (rc == EOK)
+		*batt_status = (battery_status_t) status;
+
+	return rc;
+}
+
+/** Read the current battery charge level from the device
+ *
+ * @param sess     Session of the device
+ * @param level    Battery charge level (0 - 100)
+ *
+ * @return         EOK on success or a negative error code
+ */
+int
+battery_charge_level_get(async_sess_t *sess, int *level)
+{
+	sysarg_t charge_level;
+
+	async_exch_t *exch = async_exchange_begin(sess);
+
+	int const rc = async_req_1_1(exch, DEV_IFACE_ID(BATTERY_DEV_IFACE),
+	    BATTERY_CHARGE_LEVEL_GET, &charge_level);
+
+	async_exchange_end(exch);
+
+	if (rc == EOK)
+		*level = (int) charge_level;
+
+	return rc;
+}
 
 static void remote_battery_status_get(ddf_fun_t *, void *, ipc_callid_t,
@@ -45,7 +96,7 @@
 
 /** Remote battery interface operations */
-static remote_iface_func_ptr_t remote_battery_dev_iface_ops[] = {
-	&remote_battery_status_get,
-	&remote_battery_charge_level_get,
+static const remote_iface_func_ptr_t remote_battery_dev_iface_ops[] = {
+	[BATTERY_STATUS_GET] = remote_battery_status_get,
+	[BATTERY_CHARGE_LEVEL_GET] = remote_battery_charge_level_get,
 };
 
@@ -56,7 +107,6 @@
  *
  */
-remote_iface_t remote_battery_dev_iface = {
-	.method_count = sizeof(remote_battery_dev_iface_ops) /
-	    sizeof(remote_iface_func_ptr_t),
+const remote_iface_t remote_battery_dev_iface = {
+	.method_count = ARRAY_SIZE(remote_battery_dev_iface_ops),
 	.methods = remote_battery_dev_iface_ops,
 };
Index: uspace/lib/drv/generic/remote_char_dev.c
===================================================================
--- uspace/lib/drv/generic/remote_char_dev.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/generic/remote_char_dev.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -35,9 +35,95 @@
 #include <async.h>
 #include <errno.h>
+#include <macros.h>
 
 #include "ops/char_dev.h"
+#include "char_dev_iface.h"
 #include "ddf/driver.h"
 
 #define MAX_CHAR_RW_COUNT 256
+
+/** Read to or write from device.
+ *
+ * Helper function to read to or write from a device
+ * using its character interface.
+ *
+ * @param sess Session to the device.
+ * @param buf  Buffer for the data read from or written to the device.
+ * @param size Maximum size of data (in bytes) to be read or written.
+ * @param read Read from the device if true, write to it otherwise.
+ *
+ * @return Non-negative number of bytes actually read from or
+ *         written to the device on success, negative error number
+ *         otherwise.
+ *
+ */
+static ssize_t char_dev_rw(async_sess_t *sess, void *buf, size_t size, bool read)
+{
+	ipc_call_t answer;
+	aid_t req;
+	int ret;
+	
+	async_exch_t *exch = async_exchange_begin(sess);
+	
+	if (read) {
+		req = async_send_1(exch, DEV_IFACE_ID(CHAR_DEV_IFACE),
+		    CHAR_DEV_READ, &answer);
+		ret = async_data_read_start(exch, buf, size);
+	} else {
+		req = async_send_1(exch, DEV_IFACE_ID(CHAR_DEV_IFACE),
+		    CHAR_DEV_WRITE, &answer);
+		ret = async_data_write_start(exch, buf, size);
+	}
+	
+	async_exchange_end(exch);
+	
+	sysarg_t rc;
+	if (ret != EOK) {
+		async_wait_for(req, &rc);
+		if (rc == EOK)
+			return (ssize_t) ret;
+		
+		return (ssize_t) rc;
+	}
+	
+	async_wait_for(req, &rc);
+	
+	ret = (int) rc;
+	if (ret != EOK)
+		return (ssize_t) ret;
+	
+	return (ssize_t) IPC_GET_ARG1(answer);
+}
+
+/** Read from character device.
+ *
+ * @param sess Session to the device.
+ * @param buf  Output buffer for the data read from the device.
+ * @param size Maximum size (in bytes) of the data to be read.
+ *
+ * @return Non-negative number of bytes actually read from the
+ *         device on success, negative error number otherwise.
+ *
+ */
+ssize_t char_dev_read(async_sess_t *sess, void *buf, size_t size)
+{
+	return char_dev_rw(sess, buf, size, true);
+}
+
+/** Write to character device.
+ *
+ * @param sess Session to the device.
+ * @param buf  Input buffer containg the data to be written to the
+ *             device.
+ * @param size Maximum size (in bytes) of the data to be written.
+ *
+ * @return Non-negative number of bytes actually written to the
+ *         device on success, negative error number otherwise.
+ *
+ */
+ssize_t char_dev_write(async_sess_t *sess, void *buf, size_t size)
+{
+	return char_dev_rw(sess, buf, size, false);
+}
 
 static void remote_char_read(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
@@ -45,7 +131,7 @@
 
 /** Remote character interface operations. */
-static remote_iface_func_ptr_t remote_char_dev_iface_ops[] = {
-	&remote_char_read,
-	&remote_char_write
+static const remote_iface_func_ptr_t remote_char_dev_iface_ops[] = {
+	[CHAR_DEV_READ] = remote_char_read,
+	[CHAR_DEV_WRITE] = remote_char_write
 };
 
@@ -55,7 +141,6 @@
  * character interface.
  */
-remote_iface_t remote_char_dev_iface = {
-	.method_count = sizeof(remote_char_dev_iface_ops) /
-	    sizeof(remote_iface_func_ptr_t),
+const remote_iface_t remote_char_dev_iface = {
+	.method_count = ARRAY_SIZE(remote_char_dev_iface_ops),
 	.methods = remote_char_dev_iface_ops
 };
Index: uspace/lib/drv/generic/remote_clock_dev.c
===================================================================
--- uspace/lib/drv/generic/remote_clock_dev.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/generic/remote_clock_dev.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -36,4 +36,6 @@
 #include <errno.h>
 #include <time.h>
+#include <macros.h>
+#include <device/clock_dev.h>
 
 #include <ops/clock_dev.h>
@@ -46,7 +48,7 @@
 
 /** Remote clock interface operations */
-static remote_iface_func_ptr_t remote_clock_dev_iface_ops[] = {
-	&remote_clock_time_get,
-	&remote_clock_time_set,
+static const remote_iface_func_ptr_t remote_clock_dev_iface_ops[] = {
+	[CLOCK_DEV_TIME_GET] = remote_clock_time_get,
+	[CLOCK_DEV_TIME_SET] = remote_clock_time_set,
 };
 
@@ -56,7 +58,6 @@
  * addressed by the clock interface.
  */
-remote_iface_t remote_clock_dev_iface = {
-	.method_count = sizeof(remote_clock_dev_iface_ops) /
-	    sizeof(remote_iface_func_ptr_t),
+const remote_iface_t remote_clock_dev_iface = {
+	.method_count = ARRAY_SIZE(remote_clock_dev_iface_ops),
 	.methods = remote_clock_dev_iface_ops,
 };
Index: uspace/lib/drv/generic/remote_graph_dev.c
===================================================================
--- uspace/lib/drv/generic/remote_graph_dev.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/generic/remote_graph_dev.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -35,17 +35,31 @@
 #include <errno.h>
 #include <async.h>
+#include <macros.h>
 
 #include "ops/graph_dev.h"
+#include "graph_iface.h"
 #include "ddf/driver.h"
+
+typedef enum {
+	GRAPH_DEV_CONNECT = 0
+} graph_dev_method_t;
+
+int graph_dev_connect(async_sess_t *sess)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	int ret = async_req_1_0(exch, DEV_IFACE_ID(GRAPH_DEV_IFACE), GRAPH_DEV_CONNECT);
+	async_exchange_end(exch);
+
+	return ret;
+}
 
 static void remote_graph_connect(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
 
-static remote_iface_func_ptr_t remote_graph_dev_iface_ops[] = {
-	&remote_graph_connect
+static const remote_iface_func_ptr_t remote_graph_dev_iface_ops[] = {
+	[GRAPH_DEV_CONNECT] = remote_graph_connect
 };
 
-remote_iface_t remote_graph_dev_iface = {
-	.method_count = sizeof(remote_graph_dev_iface_ops) /
-	    sizeof(remote_iface_func_ptr_t),
+const remote_iface_t remote_graph_dev_iface = {
+	.method_count = ARRAY_SIZE(remote_graph_dev_iface_ops),
 	.methods = remote_graph_dev_iface_ops
 };
Index: uspace/lib/drv/generic/remote_hw_res.c
===================================================================
--- uspace/lib/drv/generic/remote_hw_res.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/generic/remote_hw_res.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -36,4 +36,5 @@
 #include <async.h>
 #include <errno.h>
+#include <macros.h>
 
 #include "ops/hw_res.h"
@@ -49,5 +50,5 @@
     ipc_call_t *);
 
-static remote_iface_func_ptr_t remote_hw_res_iface_ops [] = {
+static const remote_iface_func_ptr_t remote_hw_res_iface_ops [] = {
 	[HW_RES_GET_RESOURCE_LIST] = &remote_hw_res_get_resource_list,
 	[HW_RES_ENABLE_INTERRUPT] = &remote_hw_res_enable_interrupt,
@@ -56,7 +57,6 @@
 };
 
-remote_iface_t remote_hw_res_iface = {
-	.method_count = sizeof(remote_hw_res_iface_ops) /
-	    sizeof(remote_iface_func_ptr_t),
+const remote_iface_t remote_hw_res_iface = {
+	.method_count = ARRAY_SIZE(remote_hw_res_iface_ops),
 	.methods = remote_hw_res_iface_ops
 };
Index: uspace/lib/drv/generic/remote_nic.c
===================================================================
--- uspace/lib/drv/generic/remote_nic.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/generic/remote_nic.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -40,5 +40,1297 @@
 #include <ipc/services.h>
 #include <sys/time.h>
+#include <macros.h>
+
 #include "ops/nic.h"
+#include "nic_iface.h"
+
+typedef enum {
+	NIC_SEND_MESSAGE = 0,
+	NIC_CALLBACK_CREATE,
+	NIC_GET_STATE,
+	NIC_SET_STATE,
+	NIC_GET_ADDRESS,
+	NIC_SET_ADDRESS,
+	NIC_GET_STATS,
+	NIC_GET_DEVICE_INFO,
+	NIC_GET_CABLE_STATE,
+	NIC_GET_OPERATION_MODE,
+	NIC_SET_OPERATION_MODE,
+	NIC_AUTONEG_ENABLE,
+	NIC_AUTONEG_DISABLE,
+	NIC_AUTONEG_PROBE,
+	NIC_AUTONEG_RESTART,
+	NIC_GET_PAUSE,
+	NIC_SET_PAUSE,
+	NIC_UNICAST_GET_MODE,
+	NIC_UNICAST_SET_MODE,
+	NIC_MULTICAST_GET_MODE,
+	NIC_MULTICAST_SET_MODE,
+	NIC_BROADCAST_GET_MODE,
+	NIC_BROADCAST_SET_MODE,
+	NIC_DEFECTIVE_GET_MODE,
+	NIC_DEFECTIVE_SET_MODE,
+	NIC_BLOCKED_SOURCES_GET,
+	NIC_BLOCKED_SOURCES_SET,
+	NIC_VLAN_GET_MASK,
+	NIC_VLAN_SET_MASK,
+	NIC_VLAN_SET_TAG,
+	NIC_WOL_VIRTUE_ADD,
+	NIC_WOL_VIRTUE_REMOVE,
+	NIC_WOL_VIRTUE_PROBE,
+	NIC_WOL_VIRTUE_LIST,
+	NIC_WOL_VIRTUE_GET_CAPS,
+	NIC_WOL_LOAD_INFO,
+	NIC_OFFLOAD_PROBE,
+	NIC_OFFLOAD_SET,
+	NIC_POLL_GET_MODE,
+	NIC_POLL_SET_MODE,
+	NIC_POLL_NOW
+} nic_funcs_t;
+
+/** Send frame from NIC
+ *
+ * @param[in] dev_sess
+ * @param[in] data     Frame data
+ * @param[in] size     Frame size in bytes
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_send_frame(async_sess_t *dev_sess, void *data, size_t size)
+{
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	ipc_call_t answer;
+	aid_t req = async_send_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_SEND_MESSAGE, &answer);
+	sysarg_t retval = async_data_write_start(exch, data, size);
+	
+	async_exchange_end(exch);
+	
+	if (retval != EOK) {
+		async_forget(req);
+		return retval;
+	}
+
+	async_wait_for(req, &retval);
+	return retval;
+}
+
+/** Create callback connection from NIC service
+ *
+ * @param[in] dev_sess
+ * @param[in] device_id
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_callback_create(async_sess_t *dev_sess, async_client_conn_t cfun,
+    void *carg)
+{
+	ipc_call_t answer;
+	int rc;
+	sysarg_t retval;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	aid_t req = async_send_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_CALLBACK_CREATE, &answer);
+	
+	rc = async_connect_to_me(exch, 0, 0, 0, cfun, carg);
+	if (rc != EOK) {
+		async_forget(req);
+		return rc;
+	}
+	async_exchange_end(exch);
+	
+	async_wait_for(req, &retval);
+	return (int) retval;
+}
+
+/** Get the current state of the device
+ *
+ * @param[in]  dev_sess
+ * @param[out] state    Current state
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_get_state(async_sess_t *dev_sess, nic_device_state_t *state)
+{
+	assert(state);
+	
+	sysarg_t _state;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_1_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_GET_STATE, &_state);
+	async_exchange_end(exch);
+	
+	*state = (nic_device_state_t) _state;
+	
+	return rc;
+}
+
+/** Request the device to change its state
+ *
+ * @param[in] dev_sess
+ * @param[in] state    New state
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_set_state(async_sess_t *dev_sess, nic_device_state_t state)
+{
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_2_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_SET_STATE, state);
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+/** Request the MAC address of the device
+ *
+ * @param[in]  dev_sess
+ * @param[out] address  Structure with buffer for the address
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_get_address(async_sess_t *dev_sess, nic_address_t *address)
+{
+	assert(address);
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	aid_t aid = async_send_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_GET_ADDRESS, NULL);
+	int rc = async_data_read_start(exch, address, sizeof(nic_address_t));
+	async_exchange_end(exch);
+	
+	sysarg_t res;
+	async_wait_for(aid, &res);
+	
+	if (rc != EOK)
+		return rc;
+	
+	return (int) res;
+}
+
+/** Set the address of the device (e.g. MAC on Ethernet)
+ *
+ * @param[in] dev_sess
+ * @param[in] address  Pointer to the address
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_set_address(async_sess_t *dev_sess, const nic_address_t *address)
+{
+	assert(address);
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	aid_t aid = async_send_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_SET_ADDRESS, NULL);
+	int rc = async_data_write_start(exch, address, sizeof(nic_address_t));
+	async_exchange_end(exch);
+	
+	sysarg_t res;
+	async_wait_for(aid, &res);
+	
+	if (rc != EOK)
+		return rc;
+	
+	return (int) res;
+}
+
+/** Request statistic data about NIC operation.
+ *
+ * @param[in]  dev_sess
+ * @param[out] stats    Structure with the statistics
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_get_stats(async_sess_t *dev_sess, nic_device_stats_t *stats)
+{
+	assert(stats);
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	int rc = async_req_1_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_GET_STATS);
+	if (rc != EOK) {
+		async_exchange_end(exch);
+		return rc;
+	}
+	
+	rc = async_data_read_start(exch, stats, sizeof(nic_device_stats_t));
+	
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+/** Request information about the device.
+ *
+ * @see nic_device_info_t
+ *
+ * @param[in]  dev_sess
+ * @param[out] device_info Information about the device
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_get_device_info(async_sess_t *dev_sess, nic_device_info_t *device_info)
+{
+	assert(device_info);
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	int rc = async_req_1_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_GET_DEVICE_INFO);
+	if (rc != EOK) {
+		async_exchange_end(exch);
+		return rc;
+	}
+	
+	rc = async_data_read_start(exch, device_info, sizeof(nic_device_info_t));
+	
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+/** Request status of the cable (plugged/unplugged)
+ *
+ * @param[in]  dev_sess
+ * @param[out] cable_state Current cable state
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_get_cable_state(async_sess_t *dev_sess, nic_cable_state_t *cable_state)
+{
+	assert(cable_state);
+	
+	sysarg_t _cable_state;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_1_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_GET_CABLE_STATE, &_cable_state);
+	async_exchange_end(exch);
+	
+	*cable_state = (nic_cable_state_t) _cable_state;
+	
+	return rc;
+}
+
+/** Request current operation mode.
+ *
+ * @param[in]  dev_sess
+ * @param[out] speed    Current operation speed in Mbps. Can be NULL.
+ * @param[out] duplex   Full duplex/half duplex. Can be NULL.
+ * @param[out] role     Master/slave/auto. Can be NULL.
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_get_operation_mode(async_sess_t *dev_sess, int *speed,
+   nic_channel_mode_t *duplex, nic_role_t *role)
+{
+	sysarg_t _speed;
+	sysarg_t _duplex;
+	sysarg_t _role;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_1_3(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_GET_OPERATION_MODE, &_speed, &_duplex, &_role);
+	async_exchange_end(exch);
+	
+	if (speed)
+		*speed = (int) _speed;
+	
+	if (duplex)
+		*duplex = (nic_channel_mode_t) _duplex;
+	
+	if (role)
+		*role = (nic_role_t) _role;
+	
+	return rc;
+}
+
+/** Set current operation mode.
+ *
+ * If the NIC has auto-negotiation enabled, this command
+ * disables auto-negotiation and sets the operation mode.
+ *
+ * @param[in] dev_sess
+ * @param[in] speed    Operation speed in Mbps
+ * @param[in] duplex   Full duplex/half duplex
+ * @param[in] role     Master/slave/auto (e.g. in Gbit Ethernet]
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_set_operation_mode(async_sess_t *dev_sess, int speed,
+    nic_channel_mode_t duplex, nic_role_t role)
+{
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_4_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_SET_OPERATION_MODE, (sysarg_t) speed, (sysarg_t) duplex,
+	    (sysarg_t) role);
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+/** Enable auto-negotiation.
+ *
+ * The advertisement argument can only limit some modes,
+ * it can never force the NIC to advertise unsupported modes.
+ *
+ * The allowed modes are defined in "nic/eth_phys.h" in the C library.
+ *
+ * @param[in] dev_sess
+ * @param[in] advertisement Allowed advertised modes. Use 0 for all modes.
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_autoneg_enable(async_sess_t *dev_sess, uint32_t advertisement)
+{
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_2_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_AUTONEG_ENABLE, (sysarg_t) advertisement);
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+/** Disable auto-negotiation.
+ *
+ * @param[in] dev_sess
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_autoneg_disable(async_sess_t *dev_sess)
+{
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_1_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_AUTONEG_DISABLE);
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+/** Probe current state of auto-negotiation.
+ *
+ * Modes are defined in the "nic/eth_phys.h" in the C library.
+ *
+ * @param[in]  dev_sess
+ * @param[out] our_advertisement   Modes advertised by this NIC.
+ *                                 Can be NULL.
+ * @param[out] their_advertisement Modes advertised by the other side.
+ *                                 Can be NULL.
+ * @param[out] result              General state of auto-negotiation.
+ *                                 Can be NULL.
+ * @param[out]  their_result       State of other side auto-negotiation.
+ *                                 Can be NULL.
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_autoneg_probe(async_sess_t *dev_sess, uint32_t *our_advertisement,
+    uint32_t *their_advertisement, nic_result_t *result,
+    nic_result_t *their_result)
+{
+	sysarg_t _our_advertisement;
+	sysarg_t _their_advertisement;
+	sysarg_t _result;
+	sysarg_t _their_result;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_1_4(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_AUTONEG_PROBE, &_our_advertisement, &_their_advertisement,
+	    &_result, &_their_result);
+	async_exchange_end(exch);
+	
+	if (our_advertisement)
+		*our_advertisement = (uint32_t) _our_advertisement;
+	
+	if (*their_advertisement)
+		*their_advertisement = (uint32_t) _their_advertisement;
+	
+	if (result)
+		*result = (nic_result_t) _result;
+	
+	if (their_result)
+		*their_result = (nic_result_t) _their_result;
+	
+	return rc;
+}
+
+/** Restart the auto-negotiation process.
+ *
+ * @param[in] dev_sess
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_autoneg_restart(async_sess_t *dev_sess)
+{
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_1_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_AUTONEG_RESTART);
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+/** Query party's sending and reception of the PAUSE frame.
+ *
+ * @param[in]  dev_sess
+ * @param[out] we_send    This NIC sends the PAUSE frame (true/false)
+ * @param[out] we_receive This NIC receives the PAUSE frame (true/false)
+ * @param[out] pause      The time set to transmitted PAUSE frames.
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_get_pause(async_sess_t *dev_sess, nic_result_t *we_send,
+    nic_result_t *we_receive, uint16_t *pause)
+{
+	sysarg_t _we_send;
+	sysarg_t _we_receive;
+	sysarg_t _pause;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_1_3(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_GET_PAUSE, &_we_send, &_we_receive, &_pause);
+	async_exchange_end(exch);
+	
+	if (we_send)
+		*we_send = _we_send;
+	
+	if (we_receive)
+		*we_receive = _we_receive;
+	
+	if (pause)
+		*pause = _pause;
+	
+	return rc;
+}
+
+/** Control sending and reception of the PAUSE frame.
+ *
+ * @param[in] dev_sess
+ * @param[in] allow_send    Allow sending the PAUSE frame (true/false)
+ * @param[in] allow_receive Allow reception of the PAUSE frame (true/false)
+ * @param[in] pause         Pause length in 512 bit units written
+ *                          to transmitted frames. The value 0 means
+ *                          auto value (the best). If the requested
+ *                          time cannot be set the driver is allowed
+ *                          to set the nearest supported value.
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_set_pause(async_sess_t *dev_sess, int allow_send, int allow_receive,
+    uint16_t pause)
+{
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_4_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_SET_PAUSE, allow_send, allow_receive, pause);
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+/** Retrieve current settings of unicast frames reception.
+ *
+ * Note: In case of mode != NIC_UNICAST_LIST the contents of
+ * address_list and address_count are undefined.
+ *
+ * @param[in]   dev_sess
+ * @param[out]  mode          Current operation mode
+ * @param[in]   max_count     Maximal number of addresses that could
+ *                            be written into the list buffer.
+ * @param[out]  address_list  Buffer for the list (array). Can be NULL.
+ * @param[out]  address_count Number of addresses in the list before
+ *                            possible truncation due to the max_count.
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_unicast_get_mode(async_sess_t *dev_sess, nic_unicast_mode_t *mode,
+    size_t max_count, nic_address_t *address_list, size_t *address_count)
+{
+	assert(mode);
+	
+	sysarg_t _mode;
+	sysarg_t _address_count;
+	
+	if (!address_list)
+		max_count = 0;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	int rc = async_req_2_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_UNICAST_GET_MODE, max_count, &_mode, &_address_count);
+	if (rc != EOK) {
+		async_exchange_end(exch);
+		return rc;
+	}
+	
+	*mode = (nic_unicast_mode_t) _mode;
+	if (address_count)
+		*address_count = (size_t) _address_count;
+	
+	if ((max_count) && (_address_count))
+		rc = async_data_read_start(exch, address_list,
+		    max_count * sizeof(nic_address_t));
+	
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+/** Set which unicast frames are received.
+ *
+ * @param[in] dev_sess
+ * @param[in] mode          Current operation mode
+ * @param[in] address_list  The list of addresses. Can be NULL.
+ * @param[in] address_count Number of addresses in the list.
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_unicast_set_mode(async_sess_t *dev_sess, nic_unicast_mode_t mode,
+    const nic_address_t *address_list, size_t address_count)
+{
+	if (address_list == NULL)
+		address_count = 0;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	aid_t message_id = async_send_3(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_UNICAST_SET_MODE, (sysarg_t) mode, address_count, NULL);
+	
+	int rc;
+	if (address_count)
+		rc = async_data_write_start(exch, address_list,
+		    address_count * sizeof(nic_address_t));
+	else
+		rc = EOK;
+	
+	async_exchange_end(exch);
+	
+	sysarg_t res;
+	async_wait_for(message_id, &res);
+	
+	if (rc != EOK)
+		return rc;
+	
+	return (int) res;
+}
+
+/** Retrieve current settings of multicast frames reception.
+ *
+ * Note: In case of mode != NIC_MULTICAST_LIST the contents of
+ * address_list and address_count are undefined.
+ *
+ * @param[in]  dev_sess
+ * @param[out] mode          Current operation mode
+ * @param[in]  max_count     Maximal number of addresses that could
+ *                           be written into the list buffer.
+ * @param[out] address_list  Buffer for the list (array). Can be NULL.
+ * @param[out] address_count Number of addresses in the list before
+ *                           possible truncation due to the max_count.
+ *                           Can be NULL.
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_multicast_get_mode(async_sess_t *dev_sess, nic_multicast_mode_t *mode,
+    size_t max_count, nic_address_t *address_list, size_t *address_count)
+{
+	assert(mode);
+	
+	sysarg_t _mode;
+	
+	if (!address_list)
+		max_count = 0;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	sysarg_t ac;
+	int rc = async_req_2_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_MULTICAST_GET_MODE, max_count, &_mode, &ac);
+	if (rc != EOK) {
+		async_exchange_end(exch);
+		return rc;
+	}
+	
+	*mode = (nic_multicast_mode_t) _mode;
+	if (address_count)
+		*address_count = (size_t) ac;
+	
+	if ((max_count) && (ac))
+		rc = async_data_read_start(exch, address_list,
+		    max_count * sizeof(nic_address_t));
+	
+	async_exchange_end(exch);
+	return rc;
+}
+
+/** Set which multicast frames are received.
+ *
+ * @param[in] dev_sess
+ * @param[in] mode          Current operation mode
+ * @param[in] address_list  The list of addresses. Can be NULL.
+ * @param[in] address_count Number of addresses in the list.
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_multicast_set_mode(async_sess_t *dev_sess, nic_multicast_mode_t mode,
+    const nic_address_t *address_list, size_t address_count)
+{
+	if (address_list == NULL)
+		address_count = 0;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	aid_t message_id = async_send_3(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_MULTICAST_SET_MODE, (sysarg_t) mode, address_count, NULL);
+	
+	int rc;
+	if (address_count)
+		rc = async_data_write_start(exch, address_list,
+		    address_count * sizeof(nic_address_t));
+	else
+		rc = EOK;
+	
+	async_exchange_end(exch);
+	
+	sysarg_t res;
+	async_wait_for(message_id, &res);
+	
+	if (rc != EOK)
+		return rc;
+	
+	return (int) res;
+}
+
+/** Determine if broadcast packets are received.
+ *
+ * @param[in]  dev_sess
+ * @param[out] mode     Current operation mode
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_broadcast_get_mode(async_sess_t *dev_sess, nic_broadcast_mode_t *mode)
+{
+	assert(mode);
+	
+	sysarg_t _mode;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_1_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_BROADCAST_GET_MODE, &_mode);
+	async_exchange_end(exch);
+	
+	*mode = (nic_broadcast_mode_t) _mode;
+	
+	return rc;
+}
+
+/** Set whether broadcast packets are received.
+ *
+ * @param[in] dev_sess
+ * @param[in] mode     Current operation mode
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_broadcast_set_mode(async_sess_t *dev_sess, nic_broadcast_mode_t mode)
+{
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_2_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_BROADCAST_SET_MODE, mode);
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+/** Determine if defective (erroneous) packets are received.
+ *
+ * @param[in]  dev_sess
+ * @param[out] mode     Bitmask specifying allowed errors
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_defective_get_mode(async_sess_t *dev_sess, uint32_t *mode)
+{
+	assert(mode);
+	
+	sysarg_t _mode;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_1_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_DEFECTIVE_GET_MODE, &_mode);
+	async_exchange_end(exch);
+	
+	*mode = (uint32_t) _mode;
+	
+	return rc;
+}
+
+/** Set whether defective (erroneous) packets are received.
+ *
+ * @param[in]  dev_sess
+ * @param[out] mode     Bitmask specifying allowed errors
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_defective_set_mode(async_sess_t *dev_sess, uint32_t mode)
+{
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_2_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_DEFECTIVE_SET_MODE, mode);
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+/** Retrieve the currently blocked source MAC addresses.
+ *
+ * @param[in]  dev_sess
+ * @param[in]  max_count     Maximal number of addresses that could
+ *                           be written into the list buffer.
+ * @param[out] address_list  Buffer for the list (array). Can be NULL.
+ * @param[out] address_count Number of addresses in the list before
+ *                           possible truncation due to the max_count.
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_blocked_sources_get(async_sess_t *dev_sess, size_t max_count,
+    nic_address_t *address_list, size_t *address_count)
+{
+	if (!address_list)
+		max_count = 0;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	sysarg_t ac;
+	int rc = async_req_2_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_BLOCKED_SOURCES_GET, max_count, &ac);
+	if (rc != EOK) {
+		async_exchange_end(exch);
+		return rc;
+	}
+	
+	if (address_count)
+		*address_count = (size_t) ac;
+	
+	if ((max_count) && (ac))
+		rc = async_data_read_start(exch, address_list,
+		    max_count * sizeof(nic_address_t));
+	
+	async_exchange_end(exch);
+	return rc;
+}
+
+/** Set which source MACs are blocked
+ *
+ * @param[in] dev_sess
+ * @param[in] address_list  The list of addresses. Can be NULL.
+ * @param[in] address_count Number of addresses in the list.
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_blocked_sources_set(async_sess_t *dev_sess,
+    const nic_address_t *address_list, size_t address_count)
+{
+	if (address_list == NULL)
+		address_count = 0;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	aid_t message_id = async_send_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_BLOCKED_SOURCES_SET, address_count, NULL);
+	
+	int rc;
+	if (address_count)
+		rc = async_data_write_start(exch, address_list,
+			address_count * sizeof(nic_address_t));
+	else
+		rc = EOK;
+	
+	async_exchange_end(exch);
+	
+	sysarg_t res;
+	async_wait_for(message_id, &res);
+	
+	if (rc != EOK)
+		return rc;
+	
+	return (int) res;
+}
+
+/** Request current VLAN filtering mask.
+ *
+ * @param[in]  dev_sess
+ * @param[out] stats    Structure with the statistics
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_vlan_get_mask(async_sess_t *dev_sess, nic_vlan_mask_t *mask)
+{
+	assert(mask);
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_1_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_VLAN_GET_MASK);
+	if (rc != EOK) {
+		async_exchange_end(exch);
+		return rc;
+	}
+	
+	rc = async_data_read_start(exch, mask, sizeof(nic_vlan_mask_t));
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+/** Set the mask used for VLAN filtering.
+ *
+ * If NULL, VLAN filtering is disabled.
+ *
+ * @param[in] dev_sess
+ * @param[in] mask     Pointer to mask structure or NULL to disable.
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_vlan_set_mask(async_sess_t *dev_sess, const nic_vlan_mask_t *mask)
+{
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	aid_t message_id = async_send_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_VLAN_SET_MASK, mask != NULL, NULL);
+	
+	int rc;
+	if (mask != NULL)
+		rc = async_data_write_start(exch, mask, sizeof(nic_vlan_mask_t));
+	else
+		rc = EOK;
+	
+	async_exchange_end(exch);
+	
+	sysarg_t res;
+	async_wait_for(message_id, &res);
+	
+	if (rc != EOK)
+		return rc;
+	
+	return (int) res;
+}
+
+/** Set VLAN (802.1q) tag.
+ *
+ * Set whether the tag is to be signaled in offload info and
+ * if the tag should be stripped from received frames and added
+ * to sent frames automatically. Not every combination of add
+ * and strip must be supported.
+ *
+ * @param[in] dev_sess
+ * @param[in] tag      VLAN priority (top 3 bits) and
+ *                     the VLAN tag (bottom 12 bits)
+ * @param[in] add      Add the VLAN tag automatically (boolean)
+ * @param[in] strip    Strip the VLAN tag automatically (boolean)
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_vlan_set_tag(async_sess_t *dev_sess, uint16_t tag, bool add, bool strip)
+{
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_4_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_VLAN_SET_TAG, (sysarg_t) tag, (sysarg_t) add, (sysarg_t) strip);
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+/** Add new Wake-On-LAN virtue.
+ *
+ * @param[in]  dev_sess
+ * @param[in]  type     Type of the virtue
+ * @param[in]  data     Data required for this virtue
+ *                      (depends on type)
+ * @param[in]  length   Length of the data
+ * @param[out] id       Identifier of the new virtue
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_wol_virtue_add(async_sess_t *dev_sess, nic_wv_type_t type,
+    const void *data, size_t length, nic_wv_id_t *id)
+{
+	assert(id);
+	
+	bool send_data = ((data != NULL) && (length != 0));
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	ipc_call_t result;
+	aid_t message_id = async_send_3(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_WOL_VIRTUE_ADD, (sysarg_t) type, send_data, &result);
+	
+	sysarg_t res;
+	if (send_data) {
+		int rc = async_data_write_start(exch, data, length);
+		if (rc != EOK) {
+			async_exchange_end(exch);
+			async_wait_for(message_id, &res);
+			return rc;
+		}
+	}
+	
+	async_exchange_end(exch);
+	async_wait_for(message_id, &res);
+	
+	*id = IPC_GET_ARG1(result);
+	return (int) res;
+}
+
+/** Remove Wake-On-LAN virtue.
+ *
+ * @param[in] dev_sess
+ * @param[in] id       Virtue identifier
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_wol_virtue_remove(async_sess_t *dev_sess, nic_wv_id_t id)
+{
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_2_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_WOL_VIRTUE_REMOVE, (sysarg_t) id);
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+/** Get information about virtue.
+ *
+ * @param[in]  dev_sess
+ * @param[in]  id         Virtue identifier
+ * @param[out] type       Type of the filter. Can be NULL.
+ * @param[out] max_length Size of the data buffer.
+ * @param[out] data       Buffer for data used when the
+ *                        virtue was created. Can be NULL.
+ * @param[out] length     Length of the data. Can be NULL.
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_wol_virtue_probe(async_sess_t *dev_sess, nic_wv_id_t id,
+    nic_wv_type_t *type, size_t max_length, void *data, size_t *length)
+{
+	sysarg_t _type;
+	sysarg_t _length;
+	
+	if (data == NULL)
+		max_length = 0;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	int rc = async_req_3_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_WOL_VIRTUE_PROBE, (sysarg_t) id, max_length,
+	    &_type, &_length);
+	if (rc != EOK) {
+		async_exchange_end(exch);
+		return rc;
+	}
+	
+	if (type)
+		*type = _type;
+	
+	if (length)
+		*length = _length;
+	
+	if ((max_length) && (_length != 0))
+		rc = async_data_read_start(exch, data, max_length);
+	
+	async_exchange_end(exch);
+	return rc;
+}
+
+/** Get a list of all virtues of the specified type.
+ *
+ * When NIC_WV_NONE is specified as the virtue type the function
+ * lists virtues of all types.
+ *
+ * @param[in]  dev_sess
+ * @param[in]  type      Type of the virtues
+ * @param[in]  max_count Maximum number of ids that can be
+ *                       written into the list buffer.
+ * @param[out] id_list   Buffer for to the list of virtue ids.
+ *                       Can be NULL.
+ * @param[out] id_count  Number of virtue identifiers in the list
+ *                       before possible truncation due to the
+ *                       max_count. Can be NULL.
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_wol_virtue_list(async_sess_t *dev_sess, nic_wv_type_t type,
+    size_t max_count, nic_wv_id_t *id_list, size_t *id_count)
+{
+	if (id_list == NULL)
+		max_count = 0;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	sysarg_t count;
+	int rc = async_req_3_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_WOL_VIRTUE_LIST, (sysarg_t) type, max_count, &count);
+	
+	if (id_count)
+		*id_count = (size_t) count;
+	
+	if ((rc != EOK) || (!max_count)) {
+		async_exchange_end(exch);
+		return rc;
+	}
+	
+	rc = async_data_read_start(exch, id_list,
+	    max_count * sizeof(nic_wv_id_t));
+	
+	async_exchange_end(exch);
+	return rc;
+}
+
+/** Get number of virtues that can be enabled yet.
+ *
+ * Count: < 0 => Virtue of this type can be never used
+ *        = 0 => No more virtues can be enabled
+ *        > 0 => #count virtues can be enabled yet
+ *
+ * @param[in]  dev_sess
+ * @param[in]  type     Virtue type
+ * @param[out] count    Number of virtues
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_wol_virtue_get_caps(async_sess_t *dev_sess, nic_wv_type_t type,
+    int *count)
+{
+	assert(count);
+	
+	sysarg_t _count;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_2_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_WOL_VIRTUE_GET_CAPS, (sysarg_t) type, &_count);
+	async_exchange_end(exch);
+	
+	*count = (int) _count;
+	return rc;
+}
+
+/** Load the frame that issued the wakeup.
+ *
+ * The NIC can support only matched_type,  only part of the frame
+ * can be available or not at all. Sometimes even the type can be
+ * uncertain -- in this case the matched_type contains NIC_WV_NONE.
+ *
+ * Frame_length can be greater than max_length, but at most max_length
+ * bytes will be copied into the frame buffer.
+ *
+ * Note: Only the type of the filter can be detected, not the concrete
+ * filter, because the driver is probably not running when the wakeup
+ * is issued.
+ *
+ * @param[in]  dev_sess
+ * @param[out] matched_type Type of the filter that issued wakeup.
+ * @param[in]  max_length   Size of the buffer
+ * @param[out] frame        Buffer for the frame. Can be NULL.
+ * @param[out] frame_length Length of the stored frame. Can be NULL.
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_wol_load_info(async_sess_t *dev_sess, nic_wv_type_t *matched_type,
+    size_t max_length, uint8_t *frame, size_t *frame_length)
+{
+	assert(matched_type);
+	
+	sysarg_t _matched_type;
+	sysarg_t _frame_length;
+	
+	if (frame == NULL)
+		max_length = 0;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	int rc = async_req_2_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_WOL_LOAD_INFO, max_length, &_matched_type, &_frame_length);
+	if (rc != EOK) {
+		async_exchange_end(exch);
+		return rc;
+	}
+	
+	*matched_type = (nic_wv_type_t) _matched_type;
+	if (frame_length)
+		*frame_length = (size_t) _frame_length;
+	
+	if ((max_length != 0) && (_frame_length != 0))
+		rc = async_data_read_start(exch, frame, max_length);
+	
+	async_exchange_end(exch);
+	return rc;
+}
+
+/** Probe supported options and current setting of offload computations
+ *
+ * @param[in]  dev_sess
+ * @param[out] supported Supported offload options
+ * @param[out] active    Currently active offload options
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_offload_probe(async_sess_t *dev_sess, uint32_t *supported,
+    uint32_t *active)
+{
+	assert(supported);
+	assert(active);
+	
+	sysarg_t _supported;
+	sysarg_t _active;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_1_2(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_OFFLOAD_PROBE, &_supported, &_active);
+	async_exchange_end(exch);
+	
+	*supported = (uint32_t) _supported;
+	*active = (uint32_t) _active;
+	return rc;
+}
+
+/** Set which offload computations can be performed on the NIC.
+ *
+ * @param[in] dev_sess
+ * @param[in] mask     Mask for the options (only those set here will be set)
+ * @param[in] active   Which options should be enabled and which disabled
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_offload_set(async_sess_t *dev_sess, uint32_t mask, uint32_t active)
+{
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_3_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_AUTONEG_RESTART, (sysarg_t) mask, (sysarg_t) active);
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+/** Query the current interrupt/poll mode of the NIC
+ *
+ * @param[in]  dev_sess
+ * @param[out] mode     Current poll mode
+ * @param[out] period   Period used in periodic polling.
+ *                      Can be NULL.
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_poll_get_mode(async_sess_t *dev_sess, nic_poll_mode_t *mode,
+    struct timeval *period)
+{
+	assert(mode);
+	
+	sysarg_t _mode;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	int rc = async_req_2_1(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_POLL_GET_MODE, period != NULL, &_mode);
+	if (rc != EOK) {
+		async_exchange_end(exch);
+		return rc;
+	}
+	
+	*mode = (nic_poll_mode_t) _mode;
+	
+	if (period != NULL)
+		rc = async_data_read_start(exch, period, sizeof(struct timeval));
+	
+	async_exchange_end(exch);
+	return rc;
+}
+
+/** Set the interrupt/poll mode of the NIC.
+ *
+ * @param[in] dev_sess
+ * @param[in] mode     New poll mode
+ * @param[in] period   Period used in periodic polling. Can be NULL.
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_poll_set_mode(async_sess_t *dev_sess, nic_poll_mode_t mode,
+    const struct timeval *period)
+{
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	aid_t message_id = async_send_3(exch, DEV_IFACE_ID(NIC_DEV_IFACE),
+	    NIC_POLL_SET_MODE, (sysarg_t) mode, period != NULL, NULL);
+	
+	int rc;
+	if (period)
+		rc = async_data_write_start(exch, period, sizeof(struct timeval));
+	else
+		rc = EOK;
+	
+	async_exchange_end(exch);
+	
+	sysarg_t res;
+	async_wait_for(message_id, &res);
+	
+	if (rc != EOK)
+		return rc;
+	
+	return (int) res;
+}
+
+/** Request the driver to poll the NIC.
+ *
+ * @param[in] dev_sess
+ *
+ * @return EOK If the operation was successfully completed
+ *
+ */
+int nic_poll_now(async_sess_t *dev_sess)
+{
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	int rc = async_req_1_0(exch, DEV_IFACE_ID(NIC_DEV_IFACE), NIC_POLL_NOW);
+	async_exchange_end(exch);
+	
+	return rc;
+}
 
 static void remote_nic_send_frame(ddf_fun_t *dev, void *iface,
@@ -1198,46 +2490,46 @@
  *
  */
-static remote_iface_func_ptr_t remote_nic_iface_ops[] = {
-	&remote_nic_send_frame,
-	&remote_nic_callback_create,
-	&remote_nic_get_state,
-	&remote_nic_set_state,
-	&remote_nic_get_address,
-	&remote_nic_set_address,
-	&remote_nic_get_stats,
-	&remote_nic_get_device_info,
-	&remote_nic_get_cable_state,
-	&remote_nic_get_operation_mode,
-	&remote_nic_set_operation_mode,
-	&remote_nic_autoneg_enable,
-	&remote_nic_autoneg_disable,
-	&remote_nic_autoneg_probe,
-	&remote_nic_autoneg_restart,
-	&remote_nic_get_pause,
-	&remote_nic_set_pause,
-	&remote_nic_unicast_get_mode,
-	&remote_nic_unicast_set_mode,
-	&remote_nic_multicast_get_mode,
-	&remote_nic_multicast_set_mode,
-	&remote_nic_broadcast_get_mode,
-	&remote_nic_broadcast_set_mode,
-	&remote_nic_defective_get_mode,
-	&remote_nic_defective_set_mode,
-	&remote_nic_blocked_sources_get,
-	&remote_nic_blocked_sources_set,
-	&remote_nic_vlan_get_mask,
-	&remote_nic_vlan_set_mask,
-	&remote_nic_vlan_set_tag,
-	&remote_nic_wol_virtue_add,
-	&remote_nic_wol_virtue_remove,
-	&remote_nic_wol_virtue_probe,
-	&remote_nic_wol_virtue_list,
-	&remote_nic_wol_virtue_get_caps,
-	&remote_nic_wol_load_info,
-	&remote_nic_offload_probe,
-	&remote_nic_offload_set,
-	&remote_nic_poll_get_mode,
-	&remote_nic_poll_set_mode,
-	&remote_nic_poll_now
+static const remote_iface_func_ptr_t remote_nic_iface_ops[] = {
+	[NIC_SEND_MESSAGE] = remote_nic_send_frame,
+	[NIC_CALLBACK_CREATE] = remote_nic_callback_create,
+	[NIC_GET_STATE] = remote_nic_get_state,
+	[NIC_SET_STATE] = remote_nic_set_state,
+	[NIC_GET_ADDRESS] = remote_nic_get_address,
+	[NIC_SET_ADDRESS] = remote_nic_set_address,
+	[NIC_GET_STATS] = remote_nic_get_stats,
+	[NIC_GET_DEVICE_INFO] = remote_nic_get_device_info,
+	[NIC_GET_CABLE_STATE] = remote_nic_get_cable_state,
+	[NIC_GET_OPERATION_MODE] = remote_nic_get_operation_mode,
+	[NIC_SET_OPERATION_MODE] = remote_nic_set_operation_mode,
+	[NIC_AUTONEG_ENABLE] = remote_nic_autoneg_enable,
+	[NIC_AUTONEG_DISABLE] = remote_nic_autoneg_disable,
+	[NIC_AUTONEG_PROBE] = remote_nic_autoneg_probe,
+	[NIC_AUTONEG_RESTART] = remote_nic_autoneg_restart,
+	[NIC_GET_PAUSE] = remote_nic_get_pause,
+	[NIC_SET_PAUSE] = remote_nic_set_pause,
+	[NIC_UNICAST_GET_MODE] = remote_nic_unicast_get_mode,
+	[NIC_UNICAST_SET_MODE] = remote_nic_unicast_set_mode,
+	[NIC_MULTICAST_GET_MODE] = remote_nic_multicast_get_mode,
+	[NIC_MULTICAST_SET_MODE] = remote_nic_multicast_set_mode,
+	[NIC_BROADCAST_GET_MODE] = remote_nic_broadcast_get_mode,
+	[NIC_BROADCAST_SET_MODE] = remote_nic_broadcast_set_mode,
+	[NIC_DEFECTIVE_GET_MODE] = remote_nic_defective_get_mode,
+	[NIC_DEFECTIVE_SET_MODE] = remote_nic_defective_set_mode,
+	[NIC_BLOCKED_SOURCES_GET] = remote_nic_blocked_sources_get,
+	[NIC_BLOCKED_SOURCES_SET] = remote_nic_blocked_sources_set,
+	[NIC_VLAN_GET_MASK] = remote_nic_vlan_get_mask,
+	[NIC_VLAN_SET_MASK] = remote_nic_vlan_set_mask,
+	[NIC_VLAN_SET_TAG] = remote_nic_vlan_set_tag,
+	[NIC_WOL_VIRTUE_ADD] = remote_nic_wol_virtue_add,
+	[NIC_WOL_VIRTUE_REMOVE] = remote_nic_wol_virtue_remove,
+	[NIC_WOL_VIRTUE_PROBE] = remote_nic_wol_virtue_probe,
+	[NIC_WOL_VIRTUE_LIST] = remote_nic_wol_virtue_list,
+	[NIC_WOL_VIRTUE_GET_CAPS] = remote_nic_wol_virtue_get_caps,
+	[NIC_WOL_LOAD_INFO] = remote_nic_wol_load_info,
+	[NIC_OFFLOAD_PROBE] = remote_nic_offload_probe,
+	[NIC_OFFLOAD_SET] = remote_nic_offload_set,
+	[NIC_POLL_GET_MODE] = remote_nic_poll_get_mode,
+	[NIC_POLL_SET_MODE] = remote_nic_poll_set_mode,
+	[NIC_POLL_NOW] = remote_nic_poll_now
 };
 
@@ -1248,7 +2540,6 @@
  *
  */
-remote_iface_t remote_nic_iface = {
-	.method_count = sizeof(remote_nic_iface_ops) /
-	    sizeof(remote_iface_func_ptr_t),
+const remote_iface_t remote_nic_iface = {
+	.method_count = ARRAY_SIZE(remote_nic_iface_ops),
 	.methods = remote_nic_iface_ops
 };
Index: uspace/lib/drv/generic/remote_pci.c
===================================================================
--- uspace/lib/drv/generic/remote_pci.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/generic/remote_pci.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -36,7 +36,91 @@
 #include <async.h>
 #include <errno.h>
+#include <macros.h>
 
 #include "pci_dev_iface.h"
 #include "ddf/driver.h"
+
+typedef enum {
+	IPC_M_CONFIG_SPACE_READ_8,
+	IPC_M_CONFIG_SPACE_READ_16,
+	IPC_M_CONFIG_SPACE_READ_32,
+
+	IPC_M_CONFIG_SPACE_WRITE_8,
+	IPC_M_CONFIG_SPACE_WRITE_16,
+	IPC_M_CONFIG_SPACE_WRITE_32
+} pci_dev_iface_funcs_t;
+
+int pci_config_space_read_8(async_sess_t *sess, uint32_t address, uint8_t *val)
+{
+	sysarg_t res = 0;
+	
+	async_exch_t *exch = async_exchange_begin(sess);
+	int rc = async_req_2_1(exch, DEV_IFACE_ID(PCI_DEV_IFACE),
+	    IPC_M_CONFIG_SPACE_READ_8, address, &res);
+	async_exchange_end(exch);
+	
+	*val = (uint8_t) res;
+	return rc;
+}
+
+int pci_config_space_read_16(async_sess_t *sess, uint32_t address,
+    uint16_t *val)
+{
+	sysarg_t res = 0;
+	
+	async_exch_t *exch = async_exchange_begin(sess);
+	int rc = async_req_2_1(exch, DEV_IFACE_ID(PCI_DEV_IFACE),
+	    IPC_M_CONFIG_SPACE_READ_16, address, &res);
+	async_exchange_end(exch);
+	
+	*val = (uint16_t) res;
+	return rc;
+}
+
+int pci_config_space_read_32(async_sess_t *sess, uint32_t address,
+    uint32_t *val)
+{
+	sysarg_t res = 0;
+	
+	async_exch_t *exch = async_exchange_begin(sess);
+	int rc = async_req_2_1(exch, DEV_IFACE_ID(PCI_DEV_IFACE),
+	    IPC_M_CONFIG_SPACE_READ_32, address, &res);
+	async_exchange_end(exch);
+	
+	*val = (uint32_t) res;
+	return rc;
+}
+
+int pci_config_space_write_8(async_sess_t *sess, uint32_t address, uint8_t val)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	int rc = async_req_3_0(exch, DEV_IFACE_ID(PCI_DEV_IFACE),
+	    IPC_M_CONFIG_SPACE_WRITE_8, address, val);
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+int pci_config_space_write_16(async_sess_t *sess, uint32_t address,
+    uint16_t val)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	int rc = async_req_3_0(exch, DEV_IFACE_ID(PCI_DEV_IFACE),
+	    IPC_M_CONFIG_SPACE_WRITE_16, address, val);
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+int pci_config_space_write_32(async_sess_t *sess, uint32_t address,
+    uint32_t val)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	int rc = async_req_3_0(exch, DEV_IFACE_ID(PCI_DEV_IFACE),
+	    IPC_M_CONFIG_SPACE_WRITE_32, address, val);
+	async_exchange_end(exch);
+	
+	return rc;
+}
 
 static void remote_config_space_read_8(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
@@ -49,19 +133,18 @@
 
 /** Remote USB interface operations. */
-static remote_iface_func_ptr_t remote_pci_iface_ops [] = {
-	remote_config_space_read_8,
-	remote_config_space_read_16,
-	remote_config_space_read_32,
-
-	remote_config_space_write_8,
-	remote_config_space_write_16,
-	remote_config_space_write_32
+static const remote_iface_func_ptr_t remote_pci_iface_ops [] = {
+	[IPC_M_CONFIG_SPACE_READ_8] = remote_config_space_read_8,
+	[IPC_M_CONFIG_SPACE_READ_16] = remote_config_space_read_16,
+	[IPC_M_CONFIG_SPACE_READ_32] = remote_config_space_read_32,
+
+	[IPC_M_CONFIG_SPACE_WRITE_8] = remote_config_space_write_8,
+	[IPC_M_CONFIG_SPACE_WRITE_16] = remote_config_space_write_16,
+	[IPC_M_CONFIG_SPACE_WRITE_32] = remote_config_space_write_32
 };
 
 /** Remote USB interface structure.
  */
-remote_iface_t remote_pci_iface = {
-	.method_count = sizeof(remote_pci_iface_ops) /
-	    sizeof(remote_pci_iface_ops[0]),
+const remote_iface_t remote_pci_iface = {
+	.method_count = ARRAY_SIZE(remote_pci_iface_ops),
 	.methods = remote_pci_iface_ops
 };
Index: uspace/lib/drv/generic/remote_pio_window.c
===================================================================
--- uspace/lib/drv/generic/remote_pio_window.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/generic/remote_pio_window.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -35,4 +35,5 @@
 #include <async.h>
 #include <errno.h>
+#include <macros.h>
 
 #include "ops/pio_window.h"
@@ -42,11 +43,10 @@
     ipc_call_t *);
 
-static remote_iface_func_ptr_t remote_pio_window_iface_ops [] = {
+static const remote_iface_func_ptr_t remote_pio_window_iface_ops [] = {
 	[PIO_WINDOW_GET] = &remote_pio_window_get
 };
 
-remote_iface_t remote_pio_window_iface = {
-	.method_count = sizeof(remote_pio_window_iface_ops) /
-	    sizeof(remote_iface_func_ptr_t),
+const remote_iface_t remote_pio_window_iface = {
+	.method_count = ARRAY_SIZE(remote_pio_window_iface_ops),
 	.methods = remote_pio_window_iface_ops
 };
Index: uspace/lib/drv/generic/remote_usb.c
===================================================================
--- uspace/lib/drv/generic/remote_usb.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/generic/remote_usb.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -36,4 +36,5 @@
 #include <async.h>
 #include <errno.h>
+#include <macros.h>
 
 #include "usb_iface.h"
@@ -107,5 +108,5 @@
 
 /** Remote USB interface operations. */
-static remote_iface_func_ptr_t remote_usb_iface_ops [] = {
+static const remote_iface_func_ptr_t remote_usb_iface_ops [] = {
 	[IPC_M_USB_GET_MY_ADDRESS] = remote_usb_get_my_address,
 	[IPC_M_USB_GET_MY_INTERFACE] = remote_usb_get_my_interface,
@@ -115,7 +116,6 @@
 /** Remote USB interface structure.
  */
-remote_iface_t remote_usb_iface = {
-	.method_count = sizeof(remote_usb_iface_ops) /
-	    sizeof(remote_usb_iface_ops[0]),
+const remote_iface_t remote_usb_iface = {
+	.method_count = ARRAY_SIZE(remote_usb_iface_ops),
 	.methods = remote_usb_iface_ops
 };
Index: uspace/lib/drv/generic/remote_usbhc.c
===================================================================
--- uspace/lib/drv/generic/remote_usbhc.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/generic/remote_usbhc.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -37,4 +37,5 @@
 #include <errno.h>
 #include <assert.h>
+#include <macros.h>
 
 #include "usbhc_iface.h"
@@ -334,5 +335,5 @@
 
 /** Remote USB host controller interface operations. */
-static remote_iface_func_ptr_t remote_usbhc_iface_ops[] = {
+static const remote_iface_func_ptr_t remote_usbhc_iface_ops[] = {
 	[IPC_M_USBHC_REQUEST_ADDRESS] = remote_usbhc_request_address,
 	[IPC_M_USBHC_RELEASE_ADDRESS] = remote_usbhc_release_address,
@@ -349,7 +350,6 @@
 /** Remote USB host controller interface structure.
  */
-remote_iface_t remote_usbhc_iface = {
-	.method_count = sizeof(remote_usbhc_iface_ops) /
-	    sizeof(remote_usbhc_iface_ops[0]),
+const remote_iface_t remote_usbhc_iface = {
+	.method_count = ARRAY_SIZE(remote_usbhc_iface_ops),
 	.methods = remote_usbhc_iface_ops
 };
Index: uspace/lib/drv/generic/remote_usbhid.c
===================================================================
--- uspace/lib/drv/generic/remote_usbhid.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/generic/remote_usbhid.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -37,7 +37,249 @@
 #include <assert.h>
 #include <stdio.h>
+#include <macros.h>
 
 #include "usbhid_iface.h"
 #include "ddf/driver.h"
+
+/** IPC methods for USB HID device interface. */
+typedef enum {
+	/** Get number of events reported in single burst.
+	 * Parameters: none
+	 * Answer:
+	 * - Size of one report in bytes.
+	 */
+	IPC_M_USBHID_GET_EVENT_LENGTH,
+	/** Get single event from the HID device.
+	 * The word single refers to set of individual events that were
+	 * available at particular point in time.
+	 * Parameters:
+	 * - flags
+	 * The call is followed by data read expecting two concatenated
+	 * arrays.
+	 * Answer:
+	 * - EOK - events returned
+	 * - EAGAIN - no event ready (only in non-blocking mode)
+	 *
+	 * It is okay if the client requests less data. Extra data must
+	 * be truncated by the driver.
+	 *
+	 * @todo Change this comment.
+	 */
+	IPC_M_USBHID_GET_EVENT,
+	
+	/** Get the size of the report descriptor from the HID device.
+	 *
+	 * Parameters:
+	 * - none
+	 * Answer:
+	 * - EOK - method is implemented (expected always)
+	 * Parameters of the answer:
+	 * - Size of the report in bytes.
+	 */
+	IPC_M_USBHID_GET_REPORT_DESCRIPTOR_LENGTH,
+	
+	/** Get the report descriptor from the HID device.
+	 *
+	 * Parameters:
+	 * - none
+	 * The call is followed by data read expecting the descriptor itself.
+	 * Answer:
+	 * - EOK - report descriptor returned.
+	 */
+	IPC_M_USBHID_GET_REPORT_DESCRIPTOR
+} usbhid_iface_funcs_t;
+
+/** Ask for event array length.
+ *
+ * @param dev_sess Session to DDF device providing USB HID interface.
+ *
+ * @return Number of usages returned or negative error code.
+ *
+ */
+int usbhid_dev_get_event_length(async_sess_t *dev_sess, size_t *size)
+{
+	if (!dev_sess)
+		return EINVAL;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	sysarg_t len;
+	int rc = async_req_1_1(exch, DEV_IFACE_ID(USBHID_DEV_IFACE),
+	    IPC_M_USBHID_GET_EVENT_LENGTH, &len);
+	
+	async_exchange_end(exch);
+	
+	if (rc == EOK) {
+		if (size != NULL)
+			*size = (size_t) len;
+	}
+	
+	return rc;
+}
+
+/** Request for next event from HID device.
+ *
+ * @param[in]  dev_sess    Session to DDF device providing USB HID interface.
+ * @param[out] usage_pages Where to store usage pages.
+ * @param[out] usages      Where to store usages (actual data).
+ * @param[in]  usage_count Length of @p usage_pages and @p usages buffer
+ *                         (in items, not bytes).
+ * @param[out] actual_usage_count Number of usages actually returned by the
+ *                                device driver.
+ * @param[in] flags        Flags (see USBHID_IFACE_FLAG_*).
+ *
+ * @return Error code.
+ *
+ */
+int usbhid_dev_get_event(async_sess_t *dev_sess, uint8_t *buf,
+    size_t size, size_t *actual_size, int *event_nr, unsigned int flags)
+{
+	if (!dev_sess)
+		return EINVAL;
+	
+	if (buf == NULL)
+		return ENOMEM;
+	
+	if (size == 0)
+		return EINVAL;
+	
+	size_t buffer_size =  size;
+	uint8_t *buffer = malloc(buffer_size);
+	if (buffer == NULL)
+		return ENOMEM;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	ipc_call_t opening_request_call;
+	aid_t opening_request = async_send_2(exch,
+	    DEV_IFACE_ID(USBHID_DEV_IFACE), IPC_M_USBHID_GET_EVENT,
+	    flags, &opening_request_call);
+	
+	if (opening_request == 0) {
+		async_exchange_end(exch);
+		free(buffer);
+		return ENOMEM;
+	}
+	
+	ipc_call_t data_request_call;
+	aid_t data_request = async_data_read(exch, buffer, buffer_size,
+	    &data_request_call);
+	
+	async_exchange_end(exch);
+	
+	if (data_request == 0) {
+		async_forget(opening_request);
+		free(buffer);
+		return ENOMEM;
+	}
+	
+	sysarg_t data_request_rc;
+	sysarg_t opening_request_rc;
+	async_wait_for(data_request, &data_request_rc);
+	async_wait_for(opening_request, &opening_request_rc);
+	
+	if (data_request_rc != EOK) {
+		/* Prefer return code of the opening request. */
+		if (opening_request_rc != EOK)
+			return (int) opening_request_rc;
+		else
+			return (int) data_request_rc;
+	}
+	
+	if (opening_request_rc != EOK)
+		return (int) opening_request_rc;
+	
+	size_t act_size = IPC_GET_ARG2(data_request_call);
+	
+	/* Copy the individual items. */
+	memcpy(buf, buffer, act_size);
+	
+	if (actual_size != NULL)
+		*actual_size = act_size;
+	
+	if (event_nr != NULL)
+		*event_nr = IPC_GET_ARG1(opening_request_call);
+	
+	return EOK;
+}
+
+int usbhid_dev_get_report_descriptor_length(async_sess_t *dev_sess,
+    size_t *size)
+{
+	if (!dev_sess)
+		return EINVAL;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	sysarg_t arg_size;
+	int rc = async_req_1_1(exch, DEV_IFACE_ID(USBHID_DEV_IFACE),
+	    IPC_M_USBHID_GET_REPORT_DESCRIPTOR_LENGTH, &arg_size);
+	
+	async_exchange_end(exch);
+	
+	if (rc == EOK) {
+		if (size != NULL)
+			*size = (size_t) arg_size;
+	}
+	
+	return rc;
+}
+
+int usbhid_dev_get_report_descriptor(async_sess_t *dev_sess, uint8_t *buf,
+    size_t size, size_t *actual_size)
+{
+	if (!dev_sess)
+		return EINVAL;
+	
+	if (buf == NULL)
+		return ENOMEM;
+	
+	if (size == 0)
+		return EINVAL;
+	
+	async_exch_t *exch = async_exchange_begin(dev_sess);
+	
+	aid_t opening_request = async_send_1(exch,
+	    DEV_IFACE_ID(USBHID_DEV_IFACE), IPC_M_USBHID_GET_REPORT_DESCRIPTOR,
+	    NULL);
+	if (opening_request == 0) {
+		async_exchange_end(exch);
+		return ENOMEM;
+	}
+	
+	ipc_call_t data_request_call;
+	aid_t data_request = async_data_read(exch, buf, size,
+	    &data_request_call);
+	
+	async_exchange_end(exch);
+	
+	if (data_request == 0) {
+		async_forget(opening_request);
+		return ENOMEM;
+	}
+	
+	sysarg_t data_request_rc;
+	sysarg_t opening_request_rc;
+	async_wait_for(data_request, &data_request_rc);
+	async_wait_for(opening_request, &opening_request_rc);
+	
+	if (data_request_rc != EOK) {
+		/* Prefer return code of the opening request. */
+		if (opening_request_rc != EOK)
+			return (int) opening_request_rc;
+		else
+			return (int) data_request_rc;
+	}
+	
+	if (opening_request_rc != EOK)
+		return (int) opening_request_rc;
+	
+	size_t act_size = IPC_GET_ARG2(data_request_call);
+	
+	if (actual_size != NULL)
+		*actual_size = act_size;
+	
+	return EOK;
+}
 
 static void remote_usbhid_get_event_length(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
@@ -48,16 +290,16 @@
 
 /** Remote USB HID interface operations. */
-static remote_iface_func_ptr_t remote_usbhid_iface_ops [] = {
-	remote_usbhid_get_event_length,
-	remote_usbhid_get_event,
-	remote_usbhid_get_report_descriptor_length,
-	remote_usbhid_get_report_descriptor
+static const remote_iface_func_ptr_t remote_usbhid_iface_ops [] = {
+	[IPC_M_USBHID_GET_EVENT_LENGTH] = remote_usbhid_get_event_length,
+	[IPC_M_USBHID_GET_EVENT] = remote_usbhid_get_event,
+	[IPC_M_USBHID_GET_REPORT_DESCRIPTOR_LENGTH] =
+	    remote_usbhid_get_report_descriptor_length,
+	[IPC_M_USBHID_GET_REPORT_DESCRIPTOR] = remote_usbhid_get_report_descriptor
 };
 
 /** Remote USB HID interface structure.
  */
-remote_iface_t remote_usbhid_iface = {
-	.method_count = sizeof(remote_usbhid_iface_ops) /
-	    sizeof(remote_usbhid_iface_ops[0]),
+const remote_iface_t remote_usbhid_iface = {
+	.method_count = ARRAY_SIZE(remote_usbhid_iface_ops),
 	.methods = remote_usbhid_iface_ops
 };
Index: uspace/lib/drv/include/ahci_iface.h
===================================================================
--- uspace/lib/drv/include/ahci_iface.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/include/ahci_iface.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -41,4 +41,12 @@
 #include <async.h>
 
+extern async_sess_t* ahci_get_sess(devman_handle_t, char **);
+
+extern int ahci_get_sata_device_name(async_sess_t *, size_t, char *);
+extern int ahci_get_num_blocks(async_sess_t *, uint64_t *);
+extern int ahci_get_block_size(async_sess_t *, size_t *);
+extern int ahci_read_blocks(async_sess_t *, uint64_t, size_t, void *);
+extern int ahci_write_blocks(async_sess_t *, uint64_t, size_t, void *);
+
 /** AHCI device communication interface. */
 typedef struct {
Index: uspace/lib/drv/include/battery_iface.h
===================================================================
--- uspace/lib/drv/include/battery_iface.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/drv/include/battery_iface.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2012 Maurizio Lombardi
+ * 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 libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_BATTERY_IFACE_H_
+#define LIBDRV_BATTERY_IFACE_H_
+
+#include <async.h>
+
+typedef enum {
+	BATTERY_OK,
+	BATTERY_LOW,
+	BATTERY_NOT_PRESENT,
+} battery_status_t;
+
+typedef enum {
+	BATTERY_STATUS_GET = 0,
+	BATTERY_CHARGE_LEVEL_GET,
+} battery_dev_method_t;
+
+extern int battery_status_get(async_sess_t *, battery_status_t *);
+extern int battery_charge_level_get(async_sess_t *, int *);
+
+#endif
+
Index: uspace/lib/drv/include/char_dev_iface.h
===================================================================
--- uspace/lib/drv/include/char_dev_iface.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/drv/include/char_dev_iface.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2010 Lenka Trochtova
+ * 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 libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_CHAR_DEV_IFACE_H_
+#define LIBDRV_CHAR_DEV_IFACE_H_
+
+#include <async.h>
+
+typedef enum {
+	CHAR_DEV_READ = 0,
+	CHAR_DEV_WRITE
+} char_dev_method_t;
+
+extern ssize_t char_dev_read(async_sess_t *, void *, size_t);
+extern ssize_t char_dev_write(async_sess_t *, void *, size_t);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/drv/include/ddf/driver.h
===================================================================
--- uspace/lib/drv/include/ddf/driver.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/include/ddf/driver.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -108,5 +108,5 @@
 	const char *name;
 	/** Generic device driver operations */
-	driver_ops_t *driver_ops;
+	const driver_ops_t *driver_ops;
 } driver_t;
 
@@ -116,5 +116,5 @@
 #endif
 
-extern int ddf_driver_main(driver_t *);
+extern int ddf_driver_main(const driver_t *);
 
 extern void *ddf_dev_data_alloc(ddf_dev_t *, size_t);
Index: uspace/lib/drv/include/ddf/interrupt.h
===================================================================
--- uspace/lib/drv/include/ddf/interrupt.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/include/ddf/interrupt.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -67,5 +67,5 @@
 extern void interrupt_init(void);
 extern int register_interrupt_handler(ddf_dev_t *, int, interrupt_handler_t *,
-    irq_code_t *);
+    const irq_code_t *);
 extern int unregister_interrupt_handler(ddf_dev_t *, int);
 
Index: uspace/lib/drv/include/dev_iface.h
===================================================================
--- uspace/lib/drv/include/dev_iface.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/include/dev_iface.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -55,14 +55,14 @@
 
 typedef struct {
-	size_t method_count;
-	remote_iface_func_ptr_t *methods;
+	const size_t method_count;
+	const remote_iface_func_ptr_t *methods;
 } remote_iface_t;
 
 typedef struct {
-	remote_iface_t *ifaces[DEV_IFACE_COUNT];
+	const remote_iface_t *ifaces[DEV_IFACE_COUNT];
 } iface_dipatch_table_t;
 
-extern remote_iface_t *get_remote_iface(int);
-extern remote_iface_func_ptr_t get_remote_method(remote_iface_t *, sysarg_t);
+extern const remote_iface_t *get_remote_iface(int);
+extern remote_iface_func_ptr_t get_remote_method(const remote_iface_t *, sysarg_t);
 
 
Index: uspace/lib/drv/include/graph_iface.h
===================================================================
--- uspace/lib/drv/include/graph_iface.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/drv/include/graph_iface.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2011 Petr Koupy
+ * 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 libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_DEVICE_GRAPH_DEV_H_
+#define LIBC_DEVICE_GRAPH_DEV_H_
+
+#include <async.h>
+
+extern int graph_dev_connect(async_sess_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/drv/include/nic_iface.h
===================================================================
--- uspace/lib/drv/include/nic_iface.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/drv/include/nic_iface.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2010 Radim Vansa
+ * 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 libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_NIC_IFACE_H_
+#define LIBDRV_NIC_IFACE_H_
+
+#include <async.h>
+#include <nic/nic.h>
+#include <ipc/common.h>
+
+
+typedef enum {
+	NIC_EV_ADDR_CHANGED = IPC_FIRST_USER_METHOD,
+	NIC_EV_RECEIVED,
+	NIC_EV_DEVICE_STATE
+} nic_event_t;
+
+extern int nic_send_frame(async_sess_t *, void *, size_t);
+extern int nic_callback_create(async_sess_t *, async_client_conn_t, void *);
+extern int nic_get_state(async_sess_t *, nic_device_state_t *);
+extern int nic_set_state(async_sess_t *, nic_device_state_t);
+extern int nic_get_address(async_sess_t *, nic_address_t *);
+extern int nic_set_address(async_sess_t *, const nic_address_t *);
+extern int nic_get_stats(async_sess_t *, nic_device_stats_t *);
+extern int nic_get_device_info(async_sess_t *, nic_device_info_t *);
+extern int nic_get_cable_state(async_sess_t *, nic_cable_state_t *);
+
+extern int nic_get_operation_mode(async_sess_t *, int *, nic_channel_mode_t *,
+    nic_role_t *);
+extern int nic_set_operation_mode(async_sess_t *, int, nic_channel_mode_t,
+    nic_role_t);
+extern int nic_autoneg_enable(async_sess_t *, uint32_t);
+extern int nic_autoneg_disable(async_sess_t *);
+extern int nic_autoneg_probe(async_sess_t *, uint32_t *, uint32_t *,
+    nic_result_t *, nic_result_t *);
+extern int nic_autoneg_restart(async_sess_t *);
+extern int nic_get_pause(async_sess_t *, nic_result_t *, nic_result_t *,
+    uint16_t *);
+extern int nic_set_pause(async_sess_t *, int, int, uint16_t);
+
+extern int nic_unicast_get_mode(async_sess_t *, nic_unicast_mode_t *, size_t,
+    nic_address_t *, size_t *);
+extern int nic_unicast_set_mode(async_sess_t *, nic_unicast_mode_t,
+    const nic_address_t *, size_t);
+extern int nic_multicast_get_mode(async_sess_t *, nic_multicast_mode_t *,
+    size_t, nic_address_t *, size_t *);
+extern int nic_multicast_set_mode(async_sess_t *, nic_multicast_mode_t,
+    const nic_address_t *, size_t);
+extern int nic_broadcast_get_mode(async_sess_t *, nic_broadcast_mode_t *);
+extern int nic_broadcast_set_mode(async_sess_t *, nic_broadcast_mode_t);
+extern int nic_defective_get_mode(async_sess_t *, uint32_t *);
+extern int nic_defective_set_mode(async_sess_t *, uint32_t);
+extern int nic_blocked_sources_get(async_sess_t *, size_t, nic_address_t *,
+    size_t *);
+extern int nic_blocked_sources_set(async_sess_t *, const nic_address_t *,
+    size_t);
+
+extern int nic_vlan_get_mask(async_sess_t *, nic_vlan_mask_t *);
+extern int nic_vlan_set_mask(async_sess_t *, const nic_vlan_mask_t *);
+extern int nic_vlan_set_tag(async_sess_t *, uint16_t, bool, bool);
+
+extern int nic_wol_virtue_add(async_sess_t *, nic_wv_type_t, const void *,
+    size_t, nic_wv_id_t *);
+extern int nic_wol_virtue_remove(async_sess_t *, nic_wv_id_t);
+extern int nic_wol_virtue_probe(async_sess_t *, nic_wv_id_t, nic_wv_type_t *,
+    size_t, void *, size_t *);
+extern int nic_wol_virtue_list(async_sess_t *, nic_wv_type_t, size_t,
+    nic_wv_id_t *, size_t *);
+extern int nic_wol_virtue_get_caps(async_sess_t *, nic_wv_type_t, int *);
+extern int nic_wol_load_info(async_sess_t *, nic_wv_type_t *, size_t, uint8_t *,
+    size_t *);
+
+extern int nic_offload_probe(async_sess_t *, uint32_t *, uint32_t *);
+extern int nic_offload_set(async_sess_t *, uint32_t, uint32_t);
+
+extern int nic_poll_get_mode(async_sess_t *, nic_poll_mode_t *,
+    struct timeval *);
+extern int nic_poll_set_mode(async_sess_t *, nic_poll_mode_t,
+    const struct timeval *);
+extern int nic_poll_now(async_sess_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/drv/include/ops/battery_dev.h
===================================================================
--- uspace/lib/drv/include/ops/battery_dev.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/include/ops/battery_dev.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -37,5 +37,5 @@
 
 #include "../ddf/driver.h"
-#include "device/battery_dev.h"
+#include "battery_iface.h"
 
 typedef struct {
Index: uspace/lib/drv/include/pci_dev_iface.h
===================================================================
--- uspace/lib/drv/include/pci_dev_iface.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/include/pci_dev_iface.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -40,13 +40,13 @@
 #include "ddf/driver.h"
 
-typedef enum {
-	IPC_M_CONFIG_SPACE_READ_8,
-	IPC_M_CONFIG_SPACE_READ_16,
-	IPC_M_CONFIG_SPACE_READ_32,
+#define PCI_DEVICE_ID  0x02
 
-	IPC_M_CONFIG_SPACE_WRITE_8,
-	IPC_M_CONFIG_SPACE_WRITE_16,
-	IPC_M_CONFIG_SPACE_WRITE_32
-} pci_dev_iface_funcs_t;
+extern int pci_config_space_read_8(async_sess_t *, uint32_t, uint8_t *);
+extern int pci_config_space_read_16(async_sess_t *, uint32_t, uint16_t *);
+extern int pci_config_space_read_32(async_sess_t *, uint32_t, uint32_t *);
+
+extern int pci_config_space_write_8(async_sess_t *, uint32_t, uint8_t);
+extern int pci_config_space_write_16(async_sess_t *, uint32_t, uint16_t);
+extern int pci_config_space_write_32(async_sess_t *, uint32_t, uint32_t);
 
 /** PCI device communication interface. */
Index: pace/lib/drv/include/remote_ahci.h
===================================================================
--- uspace/lib/drv/include/remote_ahci.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,44 +1,0 @@
-/*
- * Copyright (c) 2012 Petr Jerman
- * 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 libdrv
- * @{
- */
-/** @file
- */
-
-#ifndef LIBDRV_REMOTE_AHCI_H_
-#define LIBDRV_REMOTE_AHCI_H_
-
-extern remote_iface_t remote_ahci_iface;
-
-#endif
-
-/**
- * @}
- */
Index: pace/lib/drv/include/remote_audio_mixer.h
===================================================================
--- uspace/lib/drv/include/remote_audio_mixer.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,45 +1,0 @@
-/*
- * Copyright (c) 2011 Jan Vesely
- * 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 libdrv
- * @{
- */
-/** @file
- */
-
-#ifndef LIBDRV_REMOTE_AUDIO_MIXER_H_
-#define LIBDRV_REMOTE_AUDIO_MIXER_H_
-
-extern remote_iface_t remote_audio_mixer_iface;
-
-#endif
-
-/**
- * @}
- */
-
Index: pace/lib/drv/include/remote_audio_pcm.h
===================================================================
--- uspace/lib/drv/include/remote_audio_pcm.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,44 +1,0 @@
-/*
- * Copyright (c) 2011 Jan Vesely
- * 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 libdrv
- * @{
- */
-/** @file
- */
-
-#ifndef LIBDRV_REMOTE_AUDIO_PCM_H_
-#define LIBDRV_REMOTE_AUDIO_PCM_H_
-
-extern remote_iface_t remote_audio_pcm_iface;
-
-#endif
-
-/**
- * @}
- */
-
Index: pace/lib/drv/include/remote_battery_dev.h
===================================================================
--- uspace/lib/drv/include/remote_battery_dev.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,45 +1,0 @@
-/*
- * Copyright (c) 2012 Maurizio Lombardi
- * 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 libdrv
- * @{
- */
-/** @file
- */
-
-#ifndef LIBDRV_REMOTE_BATTERY_DEV_H_
-#define LIBDRV_REMOTE_BATTERY_DEV_H_
-
-extern remote_iface_t remote_battery_dev_iface;
-
-#endif
-
-/**
- * @}
- */
-
Index: pace/lib/drv/include/remote_char_dev.h
===================================================================
--- uspace/lib/drv/include/remote_char_dev.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,44 +1,0 @@
-/*
- * Copyright (c) 2010 Lenka Trochtova
- * 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 libdrv
- * @{
- */
-/** @file
- */
-
-#ifndef LIBDRV_REMOTE_CHAR_DEV_H_
-#define LIBDRV_REMOTE_CHAR_DEV_H_
-
-extern remote_iface_t remote_char_dev_iface;
-
-#endif
-
-/**
- * @}
- */
Index: pace/lib/drv/include/remote_clock_dev.h
===================================================================
--- uspace/lib/drv/include/remote_clock_dev.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,45 +1,0 @@
-/*
- * Copyright (c) 2012 Maurizio Lombardi
- * 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 libdrv
- * @{
- */
-/** @file
- */
-
-#ifndef LIBDRV_REMOTE_CLOCK_DEV_H_
-#define LIBDRV_REMOTE_CLOCK_DEV_H_
-
-extern remote_iface_t remote_clock_dev_iface;
-
-#endif
-
-/**
- * @}
- */
-
Index: pace/lib/drv/include/remote_graph_dev.h
===================================================================
--- uspace/lib/drv/include/remote_graph_dev.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,44 +1,0 @@
-/*
- * Copyright (c) 2011 Petr Koupy
- * 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 libdrv
- * @{
- */
-/** @file
- */
-
-#ifndef LIBDRV_REMOTE_GRAPH_DEV_H_
-#define LIBDRV_REMOTE_GRAPH_DEV_H_
-
-extern remote_iface_t remote_graph_dev_iface;
-
-#endif
-
-/**
- * @}
- */
Index: pace/lib/drv/include/remote_hw_res.h
===================================================================
--- uspace/lib/drv/include/remote_hw_res.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,44 +1,0 @@
-/*
- * Copyright (c) 2010 Lenka Trochtova
- * 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 libdrv
- * @{
- */
-/** @file
- */
-
-#ifndef LIBDRV_REMOTE_HW_RES_H_
-#define LIBDRV_REMOTE_HW_RES_H_
-
-extern remote_iface_t remote_hw_res_iface;
-
-#endif
-
-/**
- * @}
- */
Index: pace/lib/drv/include/remote_nic.h
===================================================================
--- uspace/lib/drv/include/remote_nic.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,44 +1,0 @@
-/*
- * Copyright (c) 2011 Radim Vansa
- * 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 libdrv
- * @{
- */
-/** @file
- */
-
-#ifndef LIBDRV_REMOTE_NIC_H_
-#define LIBDRV_REMOTE_NIC_H_
-
-extern remote_iface_t remote_nic_iface;
-
-#endif
-
-/**
- * @}
- */
Index: pace/lib/drv/include/remote_pci.h
===================================================================
--- uspace/lib/drv/include/remote_pci.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,45 +1,0 @@
-/*
- * Copyright (c) 2011 Jan Vesely
- * 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 libdrv
- * @{
- */
-/** @file
- */
-
-#ifndef LIBDRV_REMOTE_PCI_H_
-#define LIBDRV_REMOTE_PCI_H_
-
-extern remote_iface_t remote_pci_iface;
-
-#endif
-
-/**
- * @}
- */
-
Index: pace/lib/drv/include/remote_pio_window.h
===================================================================
--- uspace/lib/drv/include/remote_pio_window.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,44 +1,0 @@
-/*
- * Copyright (c) 2013 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 libdrv
- * @{
- */
-/** @file
- */
-
-#ifndef LIBDRV_REMOTE_PIO_WINDOW_H_
-#define LIBDRV_REMOTE_PIO_WINDOW_H_
-
-extern remote_iface_t remote_pio_window_iface;
-
-#endif
-
-/**
- * @}
- */
Index: pace/lib/drv/include/remote_usb.h
===================================================================
--- uspace/lib/drv/include/remote_usb.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,44 +1,0 @@
-/*
- * Copyright (c) 2010 Vojtech Horky
- * 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 libdrv
- * @{
- */
-/** @file
- */
-
-#ifndef LIBDRV_REMOTE_USB_H_
-#define LIBDRV_REMOTE_USB_H_
-
-extern remote_iface_t remote_usb_iface;
-
-#endif
-
-/**
- * @}
- */
Index: pace/lib/drv/include/remote_usbhc.h
===================================================================
--- uspace/lib/drv/include/remote_usbhc.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,44 +1,0 @@
-/*
- * Copyright (c) 2010 Vojtech Horky
- * 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 libdrv
- * @{
- */
-/** @file
- */
-
-#ifndef LIBDRV_REMOTE_USBHC_H_
-#define LIBDRV_REMOTE_USBHC_H_
-
-extern remote_iface_t remote_usbhc_iface;
-
-#endif
-
-/**
- * @}
- */
Index: pace/lib/drv/include/remote_usbhid.h
===================================================================
--- uspace/lib/drv/include/remote_usbhid.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,44 +1,0 @@
-/*
- * Copyright (c) 2011 Vojtech Horky
- * 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 libdrv
- * @{
- */
-/** @file
- */
-
-#ifndef LIBDRV_REMOTE_USBHID_H_
-#define LIBDRV_REMOTE_USBHID_H_
-
-extern remote_iface_t remote_usbhid_iface;
-
-#endif
-
-/**
- * @}
- */
Index: uspace/lib/drv/include/usbhid_iface.h
===================================================================
--- uspace/lib/drv/include/usbhid_iface.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/drv/include/usbhid_iface.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -40,54 +40,10 @@
 #include <usb/usb.h>
 
-/** IPC methods for USB HID device interface. */
-typedef enum {
-	/** Get number of events reported in single burst.
-	 * Parameters: none
-	 * Answer:
-	 * - Size of one report in bytes.
-	 */
-	IPC_M_USBHID_GET_EVENT_LENGTH,
-	/** Get single event from the HID device.
-	 * The word single refers to set of individual events that were
-	 * available at particular point in time.
-	 * Parameters:
-	 * - flags
-	 * The call is followed by data read expecting two concatenated
-	 * arrays.
-	 * Answer:
-	 * - EOK - events returned
-	 * - EAGAIN - no event ready (only in non-blocking mode)
-	 *
-	 * It is okay if the client requests less data. Extra data must
-	 * be truncated by the driver.
-	 *
-	 * @todo Change this comment.
-	 */
-	IPC_M_USBHID_GET_EVENT,
-	
-	/** Get the size of the report descriptor from the HID device.
-	 *
-	 * Parameters:
-	 * - none
-	 * Answer:
-	 * - EOK - method is implemented (expected always)
-	 * Parameters of the answer:
-	 * - Size of the report in bytes.
-	 */
-	IPC_M_USBHID_GET_REPORT_DESCRIPTOR_LENGTH,
-	
-	/** Get the report descriptor from the HID device.
-	 *
-	 * Parameters:
-	 * - none
-	 * The call is followed by data read expecting the descriptor itself.
-	 * Answer:
-	 * - EOK - report descriptor returned.
-	 */
-	IPC_M_USBHID_GET_REPORT_DESCRIPTOR
-} usbhid_iface_funcs_t;
-
-/** USB HID interface flag - return immediately if no data are available. */
-#define USBHID_IFACE_FLAG_NON_BLOCKING (1 << 0)
+extern int usbhid_dev_get_event_length(async_sess_t *, size_t *);
+extern int usbhid_dev_get_event(async_sess_t *, uint8_t *, size_t, size_t *,
+    int *, unsigned int);
+extern int usbhid_dev_get_report_descriptor_length(async_sess_t *, size_t *);
+extern int usbhid_dev_get_report_descriptor(async_sess_t *, uint8_t *, size_t,
+    size_t *);
 
 /** USB HID device communication interface. */
Index: uspace/lib/gpt/Makefile
===================================================================
--- uspace/lib/gpt/Makefile	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/gpt/Makefile	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2011 Dominik Taborsky
+# 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.
+#
+
+USPACE_PREFIX = ../..
+EXTRA_CFLAGS = -I$(LIBBLOCK_PREFIX) -I$(LIBMBR_PREFIX)
+LIBRARY = libgpt
+
+SOURCES = \
+	libgpt.c \
+	global.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/lib/gpt/global.c
===================================================================
--- uspace/lib/gpt/global.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/gpt/global.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2011-2013 Dominik Taborsky
+ * 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 libgpt
+ * @{
+ */
+/** @file
+ */
+
+#include "libgpt.h"
+
+/** GPT header signature ("EFI PART" in ASCII) */
+const uint8_t efi_signature[8] = {
+	0x45, 0x46, 0x49, 0x20, 0x50, 0x41, 0x52, 0x54
+};
+
+const uint8_t revision[4] = {
+	00, 00, 01, 00
+};
+
+const partition_type_t gpt_ptypes[] = {
+	{ "unused entry",                 "00000000" "0000" "0000" "0000000000000000" }, /* 0 */
+	{ "HelenOS System",               "3dc61fa0" "cf7a" "3ad8" "ac57615029d81a6b" }, /* "HelenOS System" encoded as RFC 4122 UUID, version 3 (MD5 name-based) */
+	{ "MBR partition scheme",         "024dee41" "33e7" "11d3" "9d690008c781f39f" },
+	{ "EFI System",                   "c12a7328" "f81f" "11d2" "ba4b00a0c93ec93b" },
+	{ "BIOS Boot",                    "21686148" "6449" "6e6f" "744e656564454649" },
+	{ "Windows Reserved",             "e3c9e316" "0b5c" "4db8" "817df92df00215ae" },
+	{ "Windows Basic data",           "ebd0a0a2" "b9e5" "4433" "87c068b6b72699c7" },
+	{ "Windows LDM metadata",         "5808c8aa" "7e8f" "42e0" "85d2e1e90434cfb3" },
+	{ "Windows LDM data",             "af9b60a0" "1431" "4f62" "bc683311714a69ad" },
+	{ "Windows Recovery Environment", "de94bba4" "06d1" "4d40" "a16abfd50179d6ac" },
+	{ "Windows IBM GPFS",             "37affc90" "ef7d" "4e96" "91c32d7ae055b174" }, /* 10 */
+	{ "Windows Cluster metadata",     "db97dba9" "0840" "4bae" "97f0ffb9a327c7e1" },
+	{ "HP-UX Data",                   "75894c1e" "3aeb" "11d3" "b7c17b03a0000000" },
+	{ "HP-UX Service",                "e2a1e728" "32e3" "11d6" "a6827b03a0000000" },
+	{ "Linux filesystem data",        "0fc63daf" "8483" "4772" "8e793d69d8477de4" },
+	{ "Linux RAID",                   "a19d880f" "05fc" "4d3b" "a006743f0f84911e" },
+	{ "Linux Swap",                   "0657fd6d" "a4ab" "43c4" "84e50933c84b4f4f" },
+	{ "Linux LVM",                    "e6d6d379" "f507" "44c2" "a23c238f2a3df928" },
+	{ "Linux filesystem data",        "933ac7e1" "2eb4" "4f13" "b8440e14e2aef915" },
+	{ "Linux Reserved",               "8da63339" "0007" "60c0" "c436083ac8230908" },
+	{ "FreeBSD Boot",                 "83bd6b9d" "7f41" "11dc" "be0b001560b84f0f" }, /* 20 */
+	{ "FreeBSD Data",                 "516e7cb4" "6ecf" "11d6" "8ff800022d09712b" },
+	{ "FreeBSD Swap",                 "516e7cb5" "6ecf" "11d6" "8ff800022d09712b" },
+	{ "FreeBSD UFS",                  "516e7cb6" "6ecf" "11d6" "8ff800022d09712b" },
+	{ "FreeBSD Vinum VM",             "516e7cb8" "6ecf" "11d6" "8ff800022d09712b" },
+	{ "FreeBSD ZFS",                  "516e7cba" "6ecf" "11d6" "8ff800022d09712b" },
+	{ "Mac OS X HFS+",                "48465300" "0000" "11aa" "aa1100306543ecac" },
+	{ "Mac OS X UFS",                 "55465300" "0000" "11aa" "aa1100306543ecac" },
+	{ "Mac OS X ZFS",                 "6a898cc3" "1dd2" "11b2" "99a6080020736631" },
+	{ "Mac OS X RAID",                "52414944" "0000" "11aa" "aa1100306543ecac" },
+	{ "Mac OS X RAID, offline",       "52414944" "5f4f" "11aa" "aa1100306543ecac" }, /* 30 */
+	{ "Mac OS X Boot",                "426f6f74" "0000" "11aa" "aa1100306543ecac" },
+	{ "Mac OS X Label",               "4c616265" "6c00" "11aa" "aa1100306543ecac" },
+	{ "Mac OS X TV Recovery",         "5265636f" "7665" "11aa" "aa1100306543ecac" },
+	{ "Mac OS X Core Storage",        "53746f72" "6167" "11aa" "aa1100306543ecac" },
+	{ "Solaris Boot",                 "6a82cb45" "1dd2" "11b2" "99a6080020736631" },
+	{ "Solaris Root",                 "6a85cf4d" "1dd2" "11b2" "99a6080020736631" },
+	{ "Solaris Swap",                 "6a87c46f" "1dd2" "11b2" "99a6080020736631" },
+	{ "Solaris Backup",               "6a8b642b" "1dd2" "11b2" "99a6080020736631" },
+	{ "Solaris /usr",                 "6a898cc3" "1dd2" "11b2" "99a6080020736631" },
+	{ "Solaris /var",                 "6a8ef2e9" "1dd2" "11b2" "99a6080020736631" }, /* 40 */
+	{ "Solaris /home",                "6a90ba39" "1dd2" "11b2" "99a6080020736631" },
+	{ "Solaris Alternate sector",     "6a9283a5" "1dd2" "11b2" "99a6080020736631" },
+	{ "Solaris Reserved",             "6a945a3b" "1dd2" "11b2" "99a6080020736631" },
+	{ "Solaris Reserved",             "6a9630d1" "1dd2" "11b2" "99a6080020736631" },
+	{ "Solaris Reserved",             "6a980767" "1dd2" "11b2" "99a6080020736631" },
+	{ "Solaris Reserved",             "6a96237f" "1dd2" "11b2" "99a6080020736631" },
+	{ "Solaris Reserved",             "6a8d2ac7" "1dd2" "11b2" "99a6080020736631" },
+	{ "NetBSD Swap",                  "49f48d32" "b10e" "11dc" "b99b0019d1879648" },
+	{ "NetBSD FFS",                   "49f48d5a" "b10e" "11dc" "b99b0019d1879648" },
+	{ "NetBSD LFS",                   "49f48d82" "b10e" "11dc" "b99b0019d1879648" }, /* 50 */
+	{ "NetBSD RAID",                  "49f48daa" "b10e" "11dc" "b99b0019d1879648" },
+	{ "NetBSD Concatenated",          "2db519c4" "b10f" "11dc" "b99b0019d1879648" },
+	{ "NetBSD Encrypted",             "2db519ec" "b10f" "11dc" "b99b0019d1879648" },
+	{ "ChromeOS ChromeOS kernel",     "fe3a2a5d" "4f32" "41a7" "b725accc3285a309" },
+	{ "ChromeOS rootfs",              "3cb8e202" "3b7e" "47dd" "8a3c7ff2a13cfcec" },
+	{ "ChromeOS future use",          "2e0a753d" "9e48" "43b0" "8337b15192cb1b5e" },
+	{ "MidnightBSD Boot",             "85d5e45e" "237c" "11e1" "b4b3e89a8f7fc3a7" },
+	{ "MidnightBSD Data",             "85d5e45a" "237c" "11e1" "b4b3e89a8f7fc3a7" },
+	{ "MidnightBSD Swap",             "85d5e45b" "237c" "11e1" "b4b3e89a8f7fc3a7" },
+	{ "MidnightBSD UFS",              "0394ef8b" "237e" "11e1" "b4b3e89a8f7fc3a7" }, /* 60 */
+	{ "MidnightBSD Vinum VM",         "85d5e45c" "237c" "11e1" "b4b3e89a8f7fc3a7" },
+	{ "MidnightBSD ZFS",              "85d5e45d" "237c" "11e1" "b4b3e89a8f7fc3a7" },
+	{ "unknown entry",                NULL } /* Keep this as the last entry */
+};
Index: uspace/lib/gpt/gpt.h
===================================================================
--- uspace/lib/gpt/gpt.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/gpt/gpt.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2009 Jiri Svoboda
+ * Copyright (c) 2011-2013 Dominik Taborsky
+ * 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 libgpt
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBGPT_GPT_H_
+#define LIBGPT_GPT_H_
+
+typedef enum {
+	AT_REQ_PART = 0,
+	AT_NO_BLOCK_IO,
+	AT_LEGACY_BOOT,
+	AT_UNDEFINED,
+	AT_SPECIFIC = 48
+} gpt_attr_t;
+
+/** GPT header */
+typedef struct {
+	uint8_t efi_signature[8];
+	uint8_t revision[4];
+	uint32_t header_size;
+	uint32_t header_crc32;
+	uint32_t reserved;
+	uint64_t current_lba;
+	uint64_t alternate_lba;
+	uint64_t first_usable_lba;
+	uint64_t last_usable_lba;
+	uint8_t disk_guid[16];
+	uint64_t entry_lba;
+	uint32_t fillries;
+	uint32_t entry_size;
+	uint32_t pe_array_crc32;
+} __attribute__((packed)) gpt_header_t;
+
+/** GPT partition entry */
+typedef struct {
+	uint8_t part_type[16];
+	uint8_t part_id[16];
+	uint64_t start_lba;
+	uint64_t end_lba;
+	uint64_t attributes;
+	uint8_t part_name[72];
+} __attribute__((packed)) gpt_entry_t;
+
+#endif
Index: uspace/lib/gpt/libgpt.c
===================================================================
--- uspace/lib/gpt/libgpt.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/gpt/libgpt.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,853 @@
+/*
+ * Copyright (c) 2011-2013 Dominik Taborsky
+ * 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 libgpt
+ * @{
+ */
+/** @file
+ */
+
+/* TODO:
+ * The implementation currently supports fixed size partition entries only.
+ * The specification requires otherwise, though.
+ */
+
+#include <ipc/bd.h>
+#include <async.h>
+#include <stdio.h>
+#include <block.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <byteorder.h>
+#include <adt/checksum.h>
+#include <mem.h>
+#include <sys/typefmt.h>
+#include <mbr.h>
+#include <align.h>
+#include "libgpt.h"
+
+static int load_and_check_header(service_id_t, aoff64_t, size_t, gpt_header_t *);
+static gpt_partitions_t *alloc_part_array(uint32_t);
+static int extend_part_array(gpt_partitions_t *);
+static int reduce_part_array(gpt_partitions_t *);
+static uint8_t get_byte(const char *);
+static bool check_overlap(gpt_part_t *, gpt_part_t *);
+static bool check_encaps(gpt_part_t *, uint64_t, uint64_t);
+
+/** Allocate a GPT label */
+gpt_label_t *gpt_alloc_label(void)
+{
+	gpt_label_t *label = malloc(sizeof(gpt_label_t));
+	if (label == NULL)
+		return NULL;
+	
+	label->parts = gpt_alloc_partitions();
+	if (label->parts == NULL) {
+		free(label);
+		return NULL;
+	}
+	
+	label->gpt = NULL;
+	label->device = 0;
+	
+	return label;
+}
+
+/** Free a GPT label */
+void gpt_free_label(gpt_label_t *label)
+{
+	if (label->gpt != NULL)
+		gpt_free_gpt(label->gpt);
+	
+	if (label->parts != NULL)
+		gpt_free_partitions(label->parts);
+	
+	free(label);
+}
+
+/** Allocate a GPT header */
+gpt_t *gpt_alloc_header(size_t size)
+{
+	gpt_t *gpt = malloc(sizeof(gpt_t));
+	if (gpt == NULL)
+		return NULL;
+	
+	/*
+	 * We might need only sizeof(gpt_header_t), but we should follow
+	 * specs and have zeroes through all the rest of the block
+	 */
+	size_t final_size = max(size, sizeof(gpt_header_t));
+	gpt->header = malloc(final_size);
+	if (gpt->header == NULL) {
+		free(gpt);
+		return NULL;
+	}
+	
+	memset(gpt->header, 0, final_size);
+	memcpy(gpt->header->efi_signature, efi_signature, 8);
+	memcpy(gpt->header->revision, revision, 4);
+	gpt->header->header_size = host2uint32_t_le(final_size);
+	gpt->header->entry_lba = host2uint64_t_le((uint64_t) 2);
+	gpt->header->entry_size = host2uint32_t_le(sizeof(gpt_entry_t));
+	
+	return gpt;
+}
+
+/** Free a GPT header */
+void gpt_free_gpt(gpt_t *gpt)
+{
+	free(gpt->header);
+	free(gpt);
+}
+
+/** Read GPT from a device
+ *
+ * @param label      Label to read.
+ * @param dev_handle Device to read GPT from.
+ *
+ * @return EOK on success, error code on error.
+ *
+ */
+int gpt_read_header(gpt_label_t *label, service_id_t dev_handle)
+{
+	int rc = block_init(EXCHANGE_ATOMIC, dev_handle, 512);
+	if (rc != EOK)
+		return rc;
+	
+	size_t block_size;
+	rc = block_get_bsize(dev_handle, &block_size);
+	if (rc != EOK)
+		goto end;
+	
+	if (label->gpt == NULL) {
+		label->gpt = gpt_alloc_header(block_size);
+		if (label->gpt == NULL) {
+			rc = ENOMEM;
+			goto end;
+		}
+	}
+	
+	rc = load_and_check_header(dev_handle, GPT_HDR_BA, block_size,
+	    label->gpt->header);
+	if ((rc == EBADCHECKSUM) || (rc == EINVAL)) {
+		aoff64_t blocks;
+		rc = block_get_nblocks(dev_handle, &blocks);
+		if (rc != EOK) {
+			gpt_free_gpt(label->gpt);
+			goto end;
+		}
+		
+		rc = load_and_check_header(dev_handle, blocks - 1, block_size,
+		    label->gpt->header);
+		if ((rc == EBADCHECKSUM) || (rc == EINVAL)) {
+			gpt_free_gpt(label->gpt);
+			goto end;
+		}
+	}
+	
+	label->device = dev_handle;
+	rc = EOK;
+	
+end:
+	block_fini(dev_handle);
+	return rc;
+}
+
+/** Write GPT header to device
+ *
+ * @param label        Label to be written.
+ * @param dev_handle   Device to write the GPT to.
+ *
+ * @return EOK on success, libblock error code otherwise.
+ *
+ */
+int gpt_write_header(gpt_label_t *label, service_id_t dev_handle)
+{
+	/* The comm_size argument (the last one) is ignored */
+	int rc = block_init(EXCHANGE_ATOMIC, dev_handle, 4096);
+	if ((rc != EOK) && (rc != EEXIST))
+		return rc;
+	
+	size_t block_size;
+	rc = block_get_bsize(dev_handle, &block_size);
+	if (rc != EOK)
+		goto end;
+	
+	aoff64_t blocks;
+	rc = block_get_nblocks(dev_handle, &blocks);
+	if (rc != EOK)
+		goto end;
+	
+	gpt_set_random_uuid(label->gpt->header->disk_guid);
+	
+	/* Prepare the backup header */
+	label->gpt->header->alternate_lba = label->gpt->header->current_lba;
+	label->gpt->header->current_lba = host2uint64_t_le(blocks - 1);
+	
+	uint64_t lba = label->gpt->header->entry_lba;
+	label->gpt->header->entry_lba = host2uint64_t_le(blocks -
+	    (uint32_t_le2host(label->gpt->header->fillries) *
+	    sizeof(gpt_entry_t)) / block_size - 1);
+	
+	label->gpt->header->header_crc32 = 0;
+	label->gpt->header->header_crc32 =
+	    host2uint32_t_le(compute_crc32((uint8_t *) label->gpt->header,
+	    uint32_t_le2host(label->gpt->header->header_size)));
+	
+	/* Write to backup GPT header location */
+	rc = block_write_direct(dev_handle, blocks - 1, GPT_HDR_BS,
+	    label->gpt->header);
+	if (rc != EOK)
+		goto end;
+	
+	/* Prepare the main header */
+	label->gpt->header->entry_lba = lba;
+	
+	lba = label->gpt->header->alternate_lba;
+	label->gpt->header->alternate_lba = label->gpt->header->current_lba;
+	label->gpt->header->current_lba = lba;
+	
+	label->gpt->header->header_crc32 = 0;
+	label->gpt->header->header_crc32 =
+	    host2uint32_t_le(compute_crc32((uint8_t *) label->gpt->header,
+	    uint32_t_le2host(label->gpt->header->header_size)));
+	
+	/* Write to main GPT header location */
+	rc = block_write_direct(dev_handle, GPT_HDR_BA, GPT_HDR_BS,
+	    label->gpt->header);
+	if (rc != EOK)
+		goto end;
+	
+	/* Write Protective MBR */
+	br_block_t mbr;
+	memset(&mbr, 0, 512);
+	
+	memset(mbr.pte[0].first_chs, 1, 3);
+	mbr.pte[0].ptype = 0xEE;
+	memset(mbr.pte[0].last_chs, 0xff, 3);
+	mbr.pte[0].first_lba = host2uint32_t_le(1);
+	mbr.pte[0].length = 0xffffffff;
+	mbr.signature = host2uint16_t_le(BR_SIGNATURE);
+	
+	rc = block_write_direct(dev_handle, 0, 1, &mbr);
+	
+end:
+	block_fini(dev_handle);
+	return rc;
+}
+
+/** Alloc partition array */
+gpt_partitions_t *gpt_alloc_partitions(void)
+{
+	return alloc_part_array(GPT_MIN_PART_NUM);
+}
+
+/** Parse partitions from GPT
+ *
+ * @param label GPT label to be parsed.
+ *
+ * @return EOK on success, error code otherwise.
+ *
+ */
+int gpt_read_partitions(gpt_label_t *label)
+{
+	uint32_t fillries = uint32_t_le2host(label->gpt->header->fillries);
+	uint32_t ent_size = uint32_t_le2host(label->gpt->header->entry_size);
+	uint64_t ent_lba = uint64_t_le2host(label->gpt->header->entry_lba);
+	
+	if (label->parts == NULL) {
+		label->parts = alloc_part_array(fillries);
+		if (label->parts == NULL)
+			return ENOMEM;
+	}
+	
+	int rc = block_init(EXCHANGE_SERIALIZE, label->device,
+	    sizeof(gpt_entry_t));
+	if (rc != EOK) {
+		gpt_free_partitions(label->parts);
+		label->parts = NULL;
+		goto end;
+	}
+	
+	size_t block_size;
+	rc = block_get_bsize(label->device, &block_size);
+	if (rc != EOK) {
+		gpt_free_partitions(label->parts);
+		label->parts = NULL;
+		goto end;
+	}
+	
+	aoff64_t pos = ent_lba * block_size;
+	
+	for (uint32_t i = 0; i < fillries; i++) {
+		rc = block_read_bytes_direct(label->device, pos, sizeof(gpt_entry_t),
+		    label->parts->part_array + i);
+		pos += ent_size;
+		
+		if (rc != EOK) {
+			gpt_free_partitions(label->parts);
+			label->parts = NULL;
+			goto end;
+		}
+	}
+	
+	uint32_t crc = compute_crc32((uint8_t *) label->parts->part_array,
+	    fillries * ent_size);
+	
+	if (uint32_t_le2host(label->gpt->header->pe_array_crc32) != crc) {
+		rc = EBADCHECKSUM;
+		gpt_free_partitions(label->parts);
+		label->parts = NULL;
+		goto end;
+	}
+	
+	rc = EOK;
+	
+end:
+	block_fini(label->device);
+	return rc;
+}
+
+/** Write GPT and partitions to device
+ *
+ * Note: Also writes the header.
+ *
+ * @param label      Label to write.
+ * @param dev_handle Device to write the data to.
+ *
+ * @return EOK on succes, error code otherwise
+ *
+ */
+int gpt_write_partitions(gpt_label_t *label, service_id_t dev_handle)
+{
+	/* comm_size of 4096 is ignored */
+	int rc = block_init(EXCHANGE_ATOMIC, dev_handle, 4096);
+	if ((rc != EOK) && (rc != EEXIST))
+		return rc;
+	
+	size_t block_size;
+	rc = block_get_bsize(dev_handle, &block_size);
+	if (rc != EOK)
+		goto fail;
+	
+	aoff64_t blocks;
+	rc = block_get_nblocks(dev_handle, &blocks);
+	if (rc != EOK)
+		goto fail;
+	
+	if (label->gpt == NULL)
+		label->gpt = gpt_alloc_header(block_size);
+	
+	uint32_t entry_size =
+	    uint32_t_le2host(label->gpt->header->entry_size);
+	size_t fillries = (label->parts->fill > GPT_MIN_PART_NUM) ?
+	    label->parts->fill : GPT_MIN_PART_NUM;
+	
+	if (entry_size != sizeof(gpt_entry_t))
+		return ENOTSUP;
+	
+	label->gpt->header->fillries = host2uint32_t_le(fillries);
+	
+	uint64_t arr_blocks = (fillries * sizeof(gpt_entry_t)) / block_size;
+	
+	/* Include Protective MBR */
+	uint64_t gpt_space = arr_blocks + GPT_HDR_BS + 1;
+	
+	label->gpt->header->first_usable_lba = host2uint64_t_le(gpt_space);
+	label->gpt->header->last_usable_lba =
+	    host2uint64_t_le(blocks - gpt_space - 1);
+	
+	/* Perform checks */
+	gpt_part_foreach (label, p) {
+		if (gpt_get_part_type(p) == GPT_PTE_UNUSED)
+			continue;
+		
+		if (!check_encaps(p, blocks, gpt_space)) {
+			rc = ERANGE;
+			goto fail;
+		}
+		
+		gpt_part_foreach (label, q) {
+			if (p == q)
+				continue;
+			
+			if (gpt_get_part_type(p) != GPT_PTE_UNUSED) {
+				if (check_overlap(p, q)) {
+					rc = ERANGE;
+					goto fail;
+				}
+			}
+		}
+	}
+	
+	label->gpt->header->pe_array_crc32 =
+	    host2uint32_t_le(compute_crc32((uint8_t *) label->parts->part_array,
+	    fillries * entry_size));
+	
+	/* Write to backup GPT partition array location */
+	rc = block_write_direct(dev_handle, blocks - arr_blocks - 1,
+	    arr_blocks, label->parts->part_array);
+	if (rc != EOK)
+		goto fail;
+	
+	/* Write to main GPT partition array location */
+	rc = block_write_direct(dev_handle,
+	    uint64_t_le2host(label->gpt->header->entry_lba),
+	    arr_blocks, label->parts->part_array);
+	if (rc != EOK)
+		goto fail;
+	
+	return gpt_write_header(label, dev_handle);
+	
+fail:
+	block_fini(dev_handle);
+	return rc;
+}
+
+/** Allocate a new partition
+ *
+ * Note: Use either gpt_alloc_partition() or gpt_get_partition().
+ * This returns a memory block (zero-filled) and needs gpt_add_partition()
+ * to be called to insert it into a partition array.
+ * Requires you to call gpt_free_partition afterwards.
+ *
+ * @return Pointer to the new partition or NULL.
+ *
+ */
+gpt_part_t *gpt_alloc_partition(void)
+{
+	gpt_part_t *partition = malloc(sizeof(gpt_part_t));
+	if (partition == NULL)
+		return NULL;
+	
+	memset(partition, 0, sizeof(gpt_part_t));
+	
+	return partition;
+}
+
+/** Allocate a new partition already inside the label
+ *
+ * Note: Use either gpt_alloc_partition() or gpt_get_partition().
+ * This one returns a pointer to the first empty structure already
+ * inside the array, so don't call gpt_add_partition() afterwards.
+ * This is the one you will usually want.
+ *
+ * @param label Label to carry new partition.
+ *
+ * @return Pointer to the new partition or NULL.
+ *
+ */
+gpt_part_t *gpt_get_partition(gpt_label_t *label)
+{
+	gpt_part_t *partition;
+	
+	/* Find the first empty entry */
+	do {
+		if (label->parts->fill == label->parts->arr_size) {
+			if (extend_part_array(label->parts) == -1)
+				return NULL;
+		}
+		
+		partition = label->parts->part_array + label->parts->fill++;
+	} while (gpt_get_part_type(partition) != GPT_PTE_UNUSED);
+	
+	return partition;
+}
+
+/** Get partition already inside the label
+ *
+ * Note: For new partitions use either gpt_alloc_partition() or
+ * gpt_get_partition() unless you want a partition at a specific place.
+ * This returns a pointer to a structure already inside the array,
+ * so don't call gpt_add_partition() afterwards.
+ * This function is handy when you want to change already existing
+ * partition or to simply write somewhere in the middle. This works only
+ * for indexes smaller than either 128 or the actual number of filled
+ * entries.
+ *
+ * @param label Label to carrying the partition.
+ * @param idx   Index of the partition.
+ *
+ * @return Pointer to the partition or NULL when out of range.
+ *
+ */
+gpt_part_t *gpt_get_partition_at(gpt_label_t *label, size_t idx)
+{
+	if ((idx >= GPT_MIN_PART_NUM) && (idx >= label->parts->fill))
+		return NULL;
+	
+	return label->parts->part_array + idx;
+}
+
+/** Copy partition into partition array
+ *
+ * Note: For use with gpt_alloc_partition() only. You will get
+ * duplicates with gpt_get_partition().
+ * Note: Does not call gpt_free_partition()!
+ *
+ * @param parts     Target label
+ * @param partition Source partition to copy
+ *
+ * @return EOK on succes, error code otherwise
+ *
+ */
+int gpt_add_partition(gpt_label_t *label, gpt_part_t *partition)
+{
+	/* Find the first empty entry */
+	
+	gpt_part_t *part;
+	
+	do {
+		if (label->parts->fill == label->parts->arr_size) {
+			if (extend_part_array(label->parts) == -1)
+				return ENOMEM;
+		}
+		
+		part = label->parts->part_array + label->parts->fill++;
+	} while (gpt_get_part_type(part) != GPT_PTE_UNUSED);
+	
+	memcpy(part, partition, sizeof(gpt_entry_t));
+	return EOK;
+}
+
+/** Remove partition from array
+ *
+ * Note: Even if it fails, the partition still gets removed. Only
+ * reducing the array failed.
+ *
+ * @param label Label to remove from
+ * @param idx   Index of the partition to remove
+ *
+ * @return EOK on success, ENOMEM on array reduction failure
+ *
+ */
+int gpt_remove_partition(gpt_label_t *label, size_t idx)
+{
+	if (idx >= label->parts->arr_size)
+		return EINVAL;
+	
+	/*
+	 * FIXME:
+	 * If we allow blank spots, we break the array. If we have more than
+	 * 128 partitions in the array and then remove something from
+	 * the first 128 partitions, we would forget to write the last one.
+	 */
+	
+	memset(label->parts->part_array + idx, 0, sizeof(gpt_entry_t));
+	
+	if (label->parts->fill > idx)
+		label->parts->fill = idx;
+	
+	gpt_part_t *partition;
+	
+	if ((label->parts->fill > GPT_MIN_PART_NUM) &&
+	    (label->parts->fill < (label->parts->arr_size / 2) -
+	    GPT_IGNORE_FILL_NUM)) {
+		for (partition = gpt_get_partition_at(label, label->parts->arr_size / 2);
+		     partition < label->parts->part_array + label->parts->arr_size;
+		     partition++) {
+			if (gpt_get_part_type(partition) != GPT_PTE_UNUSED)
+				return EOK;
+		}
+		
+		if (reduce_part_array(label->parts) == ENOMEM)
+			return ENOMEM;
+	}
+	
+	return EOK;
+}
+
+/** Free partition list
+ *
+ * @param parts Partition list to be freed
+ *
+ */
+void gpt_free_partitions(gpt_partitions_t *parts)
+{
+	free(parts->part_array);
+	free(parts);
+}
+
+/** Get partition type */
+size_t gpt_get_part_type(gpt_part_t *partition)
+{
+	size_t i;
+	
+	for (i = 0; gpt_ptypes[i].guid != NULL; i++) {
+		if ((partition->part_type[3] == get_byte(gpt_ptypes[i].guid + 0)) &&
+		    (partition->part_type[2] == get_byte(gpt_ptypes[i].guid + 2)) &&
+		    (partition->part_type[1] == get_byte(gpt_ptypes[i].guid + 4)) &&
+		    (partition->part_type[0] == get_byte(gpt_ptypes[i].guid + 6)) &&
+		    (partition->part_type[5] == get_byte(gpt_ptypes[i].guid + 8)) &&
+		    (partition->part_type[4] == get_byte(gpt_ptypes[i].guid + 10)) &&
+		    (partition->part_type[7] == get_byte(gpt_ptypes[i].guid + 12)) &&
+		    (partition->part_type[6] == get_byte(gpt_ptypes[i].guid + 14)) &&
+		    (partition->part_type[8] == get_byte(gpt_ptypes[i].guid + 16)) &&
+		    (partition->part_type[9] == get_byte(gpt_ptypes[i].guid + 18)) &&
+		    (partition->part_type[10] == get_byte(gpt_ptypes[i].guid + 20)) &&
+		    (partition->part_type[11] == get_byte(gpt_ptypes[i].guid + 22)) &&
+		    (partition->part_type[12] == get_byte(gpt_ptypes[i].guid + 24)) &&
+		    (partition->part_type[13] == get_byte(gpt_ptypes[i].guid + 26)) &&
+		    (partition->part_type[14] == get_byte(gpt_ptypes[i].guid + 28)) &&
+		    (partition->part_type[15] == get_byte(gpt_ptypes[i].guid + 30)))
+			return i;
+	}
+	
+	return i;
+}
+
+/** Set partition type */
+void gpt_set_part_type(gpt_part_t *partition, size_t type)
+{
+	/* Beware: first 3 blocks are byteswapped! */
+	partition->part_type[3] = get_byte(gpt_ptypes[type].guid + 0);
+	partition->part_type[2] = get_byte(gpt_ptypes[type].guid + 2);
+	partition->part_type[1] = get_byte(gpt_ptypes[type].guid + 4);
+	partition->part_type[0] = get_byte(gpt_ptypes[type].guid + 6);
+	
+	partition->part_type[5] = get_byte(gpt_ptypes[type].guid + 8);
+	partition->part_type[4] = get_byte(gpt_ptypes[type].guid + 10);
+	
+	partition->part_type[7] = get_byte(gpt_ptypes[type].guid + 12);
+	partition->part_type[6] = get_byte(gpt_ptypes[type].guid + 14);
+	
+	partition->part_type[8] = get_byte(gpt_ptypes[type].guid + 16);
+	partition->part_type[9] = get_byte(gpt_ptypes[type].guid + 18);
+	partition->part_type[10] = get_byte(gpt_ptypes[type].guid + 20);
+	partition->part_type[11] = get_byte(gpt_ptypes[type].guid + 22);
+	partition->part_type[12] = get_byte(gpt_ptypes[type].guid + 24);
+	partition->part_type[13] = get_byte(gpt_ptypes[type].guid + 26);
+	partition->part_type[14] = get_byte(gpt_ptypes[type].guid + 28);
+	partition->part_type[15] = get_byte(gpt_ptypes[type].guid + 30);
+}
+
+/** Get partition starting LBA */
+uint64_t gpt_get_start_lba(gpt_part_t *partition)
+{
+	return uint64_t_le2host(partition->start_lba);
+}
+
+/** Set partition starting LBA */
+void gpt_set_start_lba(gpt_part_t *partition, uint64_t start)
+{
+	partition->start_lba = host2uint64_t_le(start);
+}
+
+/** Get partition ending LBA */
+uint64_t gpt_get_end_lba(gpt_part_t *partition)
+{
+	return uint64_t_le2host(partition->end_lba);
+}
+
+/** Set partition ending LBA */
+void gpt_set_end_lba(gpt_part_t *partition, uint64_t end)
+{
+	partition->end_lba = host2uint64_t_le(end);
+}
+
+/** Get partition name */
+unsigned char * gpt_get_part_name(gpt_part_t *partition)
+{
+	return partition->part_name;
+}
+
+/** Copy partition name */
+void gpt_set_part_name(gpt_part_t *partition, char *name, size_t length)
+{
+	if (length >= 72)
+		length = 71;
+	
+	memcpy(partition->part_name, name, length);
+	partition->part_name[length] = '\0';
+}
+
+/** Get partition attribute */
+bool gpt_get_flag(gpt_part_t *partition, gpt_attr_t flag)
+{
+	return (partition->attributes & (((uint64_t) 1) << flag)) ? 1 : 0;
+}
+
+/** Set partition attribute */
+void gpt_set_flag(gpt_part_t *partition, gpt_attr_t flag, bool value)
+{
+	uint64_t attr = partition->attributes;
+	
+	if (value)
+		attr = attr | (((uint64_t) 1) << flag);
+	else
+		attr = attr ^ (attr & (((uint64_t) 1) << flag));
+	
+	partition->attributes = attr;
+}
+
+/** Generate a new pseudo-random UUID
+ *
+ * FIXME: This UUID generator is not compliant with RFC 4122.
+ *
+ */
+void gpt_set_random_uuid(uint8_t *uuid)
+{
+	srandom((unsigned int) (size_t) uuid);
+	
+	for (size_t i = 0; i < 16; i++)
+		uuid[i] = random();
+}
+
+/** Get next aligned address */
+uint64_t gpt_get_next_aligned(uint64_t addr, unsigned int alignment)
+{
+	return ALIGN_UP(addr + 1, alignment);
+}
+
+static int load_and_check_header(service_id_t dev_handle, aoff64_t addr,
+    size_t block_size, gpt_header_t *header)
+{
+	int rc = block_read_direct(dev_handle, addr, GPT_HDR_BS, header);
+	if (rc != EOK)
+		return rc;
+	
+	/* Check the EFI signature */
+	for (unsigned int i = 0; i < 8; i++) {
+		if (header->efi_signature[i] != efi_signature[i])
+			return EINVAL;
+	}
+	
+	/* Check the CRC32 of the header */
+	uint32_t crc = header->header_crc32;
+	header->header_crc32 = 0;
+	
+	if (crc != compute_crc32((uint8_t *) header, header->header_size))
+		return EBADCHECKSUM;
+	else
+		header->header_crc32 = crc;
+	
+	/* Check for zeroes in the rest of the block */
+	for (size_t i = sizeof(gpt_header_t); i < block_size; i++) {
+		if (((uint8_t *) header)[i] != 0)
+			return EINVAL;
+	}
+	
+	return EOK;
+}
+
+static gpt_partitions_t *alloc_part_array(uint32_t num)
+{
+	gpt_partitions_t *res = malloc(sizeof(gpt_partitions_t));
+	if (res == NULL)
+		return NULL;
+	
+	uint32_t size = num > GPT_BASE_PART_NUM ? num : GPT_BASE_PART_NUM;
+	res->part_array = malloc(size * sizeof(gpt_entry_t));
+	if (res->part_array == NULL) {
+		free(res);
+		return NULL;
+	}
+	
+	memset(res->part_array, 0, size * sizeof(gpt_entry_t));
+	
+	res->fill = 0;
+	res->arr_size = num;
+	
+	return res;
+}
+
+static int extend_part_array(gpt_partitions_t *partition)
+{
+	size_t nsize = partition->arr_size * 2;
+	gpt_entry_t *entry = malloc(nsize * sizeof(gpt_entry_t));
+	if (entry == NULL)
+		return ENOMEM;
+	
+	memcpy(entry, partition->part_array, partition->fill *
+	    sizeof(gpt_entry_t));
+	free(partition->part_array);
+	
+	partition->part_array = entry;
+	partition->arr_size = nsize;
+	
+	return EOK;
+}
+
+static int reduce_part_array(gpt_partitions_t *partition)
+{
+	if (partition->arr_size > GPT_MIN_PART_NUM) {
+		unsigned int nsize = partition->arr_size / 2;
+		nsize = nsize > GPT_MIN_PART_NUM ? nsize : GPT_MIN_PART_NUM;
+		
+		gpt_entry_t *entry = malloc(nsize * sizeof(gpt_entry_t));
+		if (entry == NULL)
+			return ENOMEM;
+		
+		memcpy(entry, partition->part_array,
+		    partition->fill < nsize ? partition->fill : nsize);
+		free(partition->part_array);
+		
+		partition->part_array = entry;
+		partition->arr_size = nsize;
+	}
+	
+	return EOK;
+}
+
+/* Parse a byte from a string in hexadecimal */
+static uint8_t get_byte(const char *c)
+{
+	uint8_t val = 0;
+	char hex[3] = {*c, *(c + 1), 0};
+	
+	str_uint8_t(hex, NULL, 16, false, &val);
+	return val;
+}
+
+static bool check_overlap(gpt_part_t *part1, gpt_part_t *part2)
+{
+	if ((gpt_get_start_lba(part1) < gpt_get_start_lba(part2)) &&
+	    (gpt_get_end_lba(part1) < gpt_get_start_lba(part2)))
+		return false;
+	
+	if ((gpt_get_start_lba(part1) > gpt_get_start_lba(part2)) &&
+	    (gpt_get_end_lba(part2) < gpt_get_start_lba(part1)))
+		return false;
+	
+	return true;
+}
+
+static bool check_encaps(gpt_part_t *part, uint64_t blocks,
+    uint64_t first_lba)
+{
+	/*
+	 * We allow "<=" in the second expression because it lacks
+	 * MBR so it is smaller by 1 block.
+	 */
+	if ((gpt_get_start_lba(part) >= first_lba) &&
+	    (gpt_get_end_lba(part) <= blocks - first_lba))
+		return true;
+	
+	return false;
+}
Index: uspace/lib/gpt/libgpt.h
===================================================================
--- uspace/lib/gpt/libgpt.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/gpt/libgpt.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2009 Jiri Svoboda
+ * Copyright (c) 2011-2013 Dominik Taborsky
+ * 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 libgpt
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBGPT_LIBGPT_H_
+#define LIBGPT_LIBGPT_H_
+
+#include <loc.h>
+#include <sys/types.h>
+#include "gpt.h"
+
+/** Block address of GPT header. */
+#define GPT_HDR_BA  1
+
+/** Block size of GPT header. */
+#define GPT_HDR_BS  1
+
+/** Minimum number of GPT partition entries */
+#define GPT_MIN_PART_NUM  128
+
+/** Basic number of GPT partition entries */
+#define GPT_BASE_PART_NUM  (GPT_MIN_PART_NUM)
+
+/** How much fill we ignore before resizing partition array */
+#define GPT_IGNORE_FILL_NUM  10
+
+/** Unused partition entry */
+#define GPT_PTE_UNUSED  0
+
+/** Raw GPT header.
+ *
+ * Uses more bytes than sizeof(gpt_header_t).
+ */
+typedef struct {
+	gpt_header_t *header;
+} gpt_t;
+
+typedef gpt_entry_t gpt_part_t;
+
+typedef struct {
+	/** Number of entries */
+	size_t fill;
+	
+	/** Size of the array */
+	size_t arr_size;
+	
+	/** Resizable partition array */
+	gpt_part_t *part_array;
+} gpt_partitions_t;
+
+typedef struct {
+	gpt_t *gpt;
+	gpt_partitions_t *parts;
+	service_id_t device;
+} gpt_label_t;
+
+typedef struct {
+	const char *desc;
+	const char *guid;
+} partition_type_t;
+
+/** GPT header signature ("EFI PART" in ASCII) */
+extern const uint8_t efi_signature[8];
+extern const uint8_t revision[4];
+
+extern const partition_type_t gpt_ptypes[];
+
+extern gpt_label_t *gpt_alloc_label(void);
+extern void gpt_free_label(gpt_label_t *);
+
+extern gpt_t *gpt_alloc_header(size_t);
+extern int gpt_read_header(gpt_label_t *, service_id_t);
+extern int gpt_write_header(gpt_label_t *, service_id_t);
+
+extern gpt_partitions_t *gpt_alloc_partitions(void);
+extern int gpt_read_partitions(gpt_label_t *);
+extern int gpt_write_partitions(gpt_label_t *, service_id_t);
+extern gpt_part_t *gpt_alloc_partition(void);
+extern gpt_part_t *gpt_get_partition(gpt_label_t *);
+extern gpt_part_t *gpt_get_partition_at(gpt_label_t *, size_t);
+extern int gpt_add_partition(gpt_label_t *, gpt_part_t *);
+extern int gpt_remove_partition(gpt_label_t *, size_t);
+
+extern size_t gpt_get_part_type(gpt_part_t *);
+extern void gpt_set_part_type(gpt_part_t *, size_t);
+extern void gpt_set_start_lba(gpt_part_t *, uint64_t);
+extern uint64_t gpt_get_start_lba(gpt_part_t *);
+extern void gpt_set_end_lba(gpt_part_t *, uint64_t);
+extern uint64_t gpt_get_end_lba(gpt_part_t *);
+extern unsigned char *gpt_get_part_name(gpt_part_t *);
+extern void gpt_set_part_name(gpt_part_t *, char *, size_t);
+extern bool gpt_get_flag(gpt_part_t *, gpt_attr_t);
+extern void gpt_set_flag(gpt_part_t *, gpt_attr_t, bool);
+
+extern void gpt_set_random_uuid(uint8_t *);
+extern uint64_t gpt_get_next_aligned(uint64_t, unsigned int);
+
+
+#define gpt_part_foreach(label, iterator) \
+	for (gpt_part_t *iterator = (label)->parts->part_array; \
+	    iterator < (label)->parts->part_array + (label)->parts->arr_size; \
+	    iterator++)
+
+extern void gpt_free_gpt(gpt_t *);
+extern void gpt_free_partitions(gpt_partitions_t *);
+
+#endif
Index: uspace/lib/gui/Makefile
===================================================================
--- uspace/lib/gui/Makefile	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/gui/Makefile	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -34,4 +34,5 @@
 
 SOURCES = \
+	common.c \
 	button.c \
 	canvas.c \
Index: uspace/lib/gui/button.c
===================================================================
--- uspace/lib/gui/button.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/gui/button.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -36,45 +36,57 @@
 #include <str.h>
 #include <malloc.h>
-
 #include <drawctx.h>
 #include <surface.h>
-
+#include "common.h"
 #include "window.h"
 #include "button.h"
 
-static void paint_internal(widget_t *w)
-{
-	button_t *btn = (button_t *) w;
-
+static pixel_t color_highlight = PIXEL(255, 255, 255, 255);
+static pixel_t color_shadow = PIXEL(255, 85, 85, 85);
+
+static void paint_internal(widget_t *widget)
+{
+	button_t *btn = (button_t *) widget;
+	
 	surface_t *surface = window_claim(btn->widget.window);
-	if (!surface) {
+	if (!surface)
 		window_yield(btn->widget.window);
+	
+	source_t source;
+	source_init(&source);
+	
+	drawctx_t drawctx;
+	drawctx_init(&drawctx, surface);
+	
+	drawctx_set_source(&drawctx, &btn->background);
+	drawctx_transfer(&drawctx, widget->hpos, widget->vpos,
+	    widget->width, widget->height);
+	
+	if ((widget->width >= 8) && (widget->height >= 8)) {
+		drawctx_set_source(&drawctx, &source);
+		draw_bevel(&drawctx, &source, widget->hpos + 3, widget->vpos + 3,
+		    widget->width - 6, widget->height - 6, color_highlight,
+		    color_shadow);
+		
+		drawctx_set_source(&drawctx, &btn->foreground);
+		drawctx_transfer(&drawctx, widget->hpos + 4, widget->vpos + 4,
+		    widget->width - 8, widget->height - 8);
 	}
-
-	drawctx_t drawctx;
-
-	drawctx_init(&drawctx, surface);
-	drawctx_set_source(&drawctx, &btn->foreground);
-	drawctx_transfer(&drawctx, w->hpos, w->vpos, w->width, w->height);
-
-	if (w->width >= 6 && w->height >= 6) {
-		drawctx_set_source(&drawctx, &btn->background);
-		drawctx_transfer(&drawctx,
-		    w->hpos + 3, w->vpos + 3, w->width - 6, w->height - 6);
-	}
-
+	
 	sysarg_t cpt_width;
 	sysarg_t cpt_height;
 	font_get_box(&btn->font, btn->caption, &cpt_width, &cpt_height);
-	if (w->width >= cpt_width && w->height >= cpt_height) {
-		drawctx_set_source(&drawctx, &btn->foreground);
+	
+	if ((widget->width >= cpt_width) && (widget->height >= cpt_height)) {
+		sysarg_t x = ((widget->width - cpt_width) / 2) + widget->hpos;
+		sysarg_t y = ((widget->height - cpt_height) / 2) + widget->vpos;
+		
+		drawctx_set_source(&drawctx, &btn->text);
 		drawctx_set_font(&drawctx, &btn->font);
-		sysarg_t x = ((w->width - cpt_width) / 2) + w->hpos;
-		sysarg_t y = ((w->height - cpt_height) / 2) + w->vpos;
-		if (btn->caption) {
+		
+		if (btn->caption)
 			drawctx_print(&drawctx, btn->caption, x, y);
-		}
 	}
-
+	
 	window_yield(btn->widget.window);
 }
@@ -90,7 +102,6 @@
 {
 	button_t *btn = (button_t *) widget;
-
+	
 	deinit_button(btn);
-	
 	free(btn);
 }
@@ -117,7 +128,7 @@
 {
 	button_t *btn = (button_t *) widget;
-	if (event.key == KC_ENTER && event.type == KEY_PRESS) {
+	
+	if (event.key == KC_ENTER && event.type == KEY_PRESS)
 		sig_send(&btn->clicked, NULL);
-	}
 }
 
@@ -126,18 +137,17 @@
 	button_t *btn = (button_t *) widget;
 	widget->window->focus = widget;
-
+	
 	// TODO make the click logic more robust (mouse grabbing, mouse moves)
 	if (event.btn_num == 1) {
-		if (event.type == POS_RELEASE) {
+		if (event.type == POS_RELEASE)
 			sig_send(&btn->clicked, NULL);
-		}
 	}
 }
 
-bool init_button(button_t *btn, widget_t *parent,
-    const char *caption, uint16_t points, pixel_t background, pixel_t foreground)
+bool init_button(button_t *btn, widget_t *parent, const char *caption,
+    uint16_t points, pixel_t background, pixel_t foreground, pixel_t text)
 {
 	widget_init(&btn->widget, parent);
-
+	
 	btn->widget.destroy = button_destroy;
 	btn->widget.reconfigure = button_reconfigure;
@@ -146,42 +156,45 @@
 	btn->widget.handle_keyboard_event = button_handle_keyboard_event;
 	btn->widget.handle_position_event = button_handle_position_event;
-
+	
 	source_init(&btn->background);
 	source_set_color(&btn->background, background);
+	
 	source_init(&btn->foreground);
 	source_set_color(&btn->foreground, foreground);
-
-	if (caption == NULL) {
+	
+	source_init(&btn->text);
+	source_set_color(&btn->text, text);
+	
+	if (caption == NULL)
 		btn->caption = NULL;
-	} else {
+	else
 		btn->caption = str_dup(caption);
-	}
+	
 	font_init(&btn->font, FONT_DECODER_EMBEDDED, NULL, points);
-
+	
 	sysarg_t cpt_width;
 	sysarg_t cpt_height;
 	font_get_box(&btn->font, btn->caption, &cpt_width, &cpt_height);
-	btn->widget.width_min = cpt_width + 8;
-	btn->widget.height_min = cpt_height + 8;
-	btn->widget.width_ideal = cpt_width + 28;
-	btn->widget.height_ideal = cpt_height + 8;
-
+	btn->widget.width_min = cpt_width + 10;
+	btn->widget.height_min = cpt_height + 10;
+	btn->widget.width_ideal = cpt_width + 30;
+	btn->widget.height_ideal = cpt_height + 10;
+	
 	return true;
 }
 
-button_t *create_button(widget_t *parent,
-    const char *caption, uint16_t points, pixel_t background, pixel_t foreground)
+button_t *create_button(widget_t *parent, const char *caption, uint16_t points,
+    pixel_t background, pixel_t foreground, pixel_t text)
 {
 	button_t *btn = (button_t *) malloc(sizeof(button_t));
-	if (!btn) {
+	if (!btn)
 		return NULL;
-	}
-
-	if (init_button(btn, parent, caption, points, background, foreground)) {
+	
+	if (init_button(btn, parent, caption, points, background, foreground,
+	    text))
 		return btn;
-	} else {
-		free(btn);
-		return NULL;
-	}
+	
+	free(btn);
+	return NULL;
 }
 
Index: uspace/lib/gui/button.h
===================================================================
--- uspace/lib/gui/button.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/gui/button.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -50,4 +50,5 @@
 	source_t background;
 	source_t foreground;
+	source_t text;
 	char *caption;
 	font_t font;
@@ -55,6 +56,8 @@
 } button_t;
 
-extern bool init_button(button_t *, widget_t *, const char *, uint16_t, pixel_t, pixel_t);
-extern button_t *create_button(widget_t *, const char *, uint16_t, pixel_t, pixel_t);
+extern bool init_button(button_t *, widget_t *, const char *, uint16_t, pixel_t,
+    pixel_t, pixel_t);
+extern button_t *create_button(widget_t *, const char *, uint16_t, pixel_t,
+    pixel_t, pixel_t);
 extern void deinit_button(button_t *);
 
Index: uspace/lib/gui/canvas.c
===================================================================
--- uspace/lib/gui/canvas.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/gui/canvas.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -112,5 +112,12 @@
 static void canvas_handle_position_event(widget_t *widget, pos_event_t event)
 {
-	/* No-op */
+	canvas_t *canvas = (canvas_t *) widget;
+	pos_event_t tevent;
+	
+	tevent = event;
+	tevent.hpos -= widget->hpos;
+	tevent.vpos -= widget->vpos;
+	
+	sig_send(&canvas->position_event, &tevent);
 }
 
Index: uspace/lib/gui/canvas.h
===================================================================
--- uspace/lib/gui/canvas.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/gui/canvas.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -50,4 +50,5 @@
 	surface_t *surface;
 	signal_t keyboard_event;
+	signal_t position_event;
 } canvas_t;
 
Index: uspace/lib/gui/common.c
===================================================================
--- uspace/lib/gui/common.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/gui/common.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2014 Martin Decky
+ * 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 gui
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <sys/types.h>
+#include <drawctx.h>
+#include "common.h"
+
+#define CROSS_WIDTH   14
+#define CROSS_HEIGHT  14
+
+static uint8_t cross_texture[] = {
+	0x00, 0x00, 0x02, 0x08, 0x04, 0x04, 0x08, 0x02, 0x10, 0x01, 0xa0, 0x00,
+	0x40, 0x00, 0xa0, 0x00, 0x10, 0x01, 0x08, 0x02, 0x04, 0x04, 0x02, 0x08,
+	0x01, 0x10, 0x00, 0x00
+};
+
+static uint8_t cross_mask[] = {
+	0x00, 0x00, 0x02, 0x18, 0x06, 0x0c, 0x0c, 0x06, 0x18, 0x03, 0xb0, 0x01,
+	0xe0, 0x00, 0xe0, 0x00, 0xb0, 0x01, 0x18, 0x03, 0x0c, 0x06, 0x06, 0x0c,
+	0x03, 0x18, 0x00, 0x00
+};
+
+void draw_icon_cross(surface_t *surface, sysarg_t hpos, sysarg_t vpos,
+    pixel_t highlight, pixel_t shadow)
+{
+	for (unsigned int y = 0; y < CROSS_HEIGHT; y++) {
+		for (unsigned int x = 0; x < CROSS_WIDTH; x++) {
+			size_t offset = y * ((CROSS_WIDTH - 1) / 8 + 1) + x / 8;
+			bool visible = cross_mask[offset] & (1 << (x % 8));
+			pixel_t pixel = (cross_texture[offset] & (1 << (x % 8))) ?
+			    highlight : shadow;
+			
+			if (visible)
+				surface_put_pixel(surface, hpos + x, vpos + y, pixel);
+		}
+	}
+}
+
+void draw_bevel(drawctx_t *drawctx, source_t *source, sysarg_t hpos,
+    sysarg_t vpos, sysarg_t width, sysarg_t height, pixel_t highlight,
+    pixel_t shadow)
+{
+	source_set_color(source, highlight);
+	drawctx_transfer(drawctx, hpos, vpos, width - 1, 1);
+	drawctx_transfer(drawctx, hpos, vpos + 1, 1, height - 2);
+	
+	source_set_color(source, shadow);
+	drawctx_transfer(drawctx, hpos, vpos + height - 1, width, 1);
+	drawctx_transfer(drawctx, hpos + width - 1, vpos, 1, height);
+}
+
+/** @}
+ */
Index: uspace/lib/gui/common.h
===================================================================
--- uspace/lib/gui/common.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/gui/common.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2014 Martin Decky
+ * 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 gui
+ * @{
+ */
+/**
+ * @file
+ */
+
+#ifndef GUI_COMMON_H_
+#define GUI_COMMON_H_
+
+#include <sys/types.h>
+#include <drawctx.h>
+
+extern void draw_icon_cross(surface_t *, sysarg_t, sysarg_t, pixel_t, pixel_t);
+extern void draw_bevel(drawctx_t *, source_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, pixel_t, pixel_t);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/gui/connection.c
===================================================================
--- uspace/lib/gui/connection.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/gui/connection.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -210,7 +210,7 @@
 			link_initialize(&event->link);
 			event->type = ET_SIGNAL_EVENT;
-			event->data.sig.object = (sysarg_t) cur->widget;
-			event->data.sig.slot = (sysarg_t) cur->slot;
-			event->data.sig.argument = (sysarg_t) data_copy;
+			event->data.signal.object = (sysarg_t) cur->widget;
+			event->data.signal.slot = (sysarg_t) cur->slot;
+			event->data.signal.argument = (sysarg_t) data_copy;
 			prodcons_produce(&cur->widget->window->events, &event->link);
 		} else {
Index: uspace/lib/gui/label.c
===================================================================
--- uspace/lib/gui/label.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/gui/label.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -36,39 +36,39 @@
 #include <str.h>
 #include <malloc.h>
-
 #include <drawctx.h>
 #include <surface.h>
-
 #include "window.h"
 #include "label.h"
 
-static void paint_internal(widget_t *w)
+static void paint_internal(widget_t *widget)
 {
-	label_t *lbl = (label_t *) w;
+	label_t *lbl = (label_t *) widget;
 
 	surface_t *surface = window_claim(lbl->widget.window);
-	if (!surface) {
+	if (!surface)
 		window_yield(lbl->widget.window);
-	}
-
+	
 	drawctx_t drawctx;
-
 	drawctx_init(&drawctx, surface);
+	
 	drawctx_set_source(&drawctx, &lbl->background);
-	drawctx_transfer(&drawctx, w->hpos, w->vpos, w->width, w->height);
-
+	drawctx_transfer(&drawctx, widget->hpos, widget->vpos, widget->width,
+	    widget->height);
+	
 	sysarg_t cpt_width;
 	sysarg_t cpt_height;
 	font_get_box(&lbl->font, lbl->caption, &cpt_width, &cpt_height);
-	if (w->width >= cpt_width && w->height >= cpt_height) {
-		drawctx_set_source(&drawctx, &lbl->foreground);
+	
+	if ((widget->width >= cpt_width) && (widget->height >= cpt_height)) {
+		sysarg_t x = ((widget->width - cpt_width) / 2) + widget->hpos;
+		sysarg_t y = ((widget->height - cpt_height) / 2) + widget->vpos;
+		
+		drawctx_set_source(&drawctx, &lbl->text);
 		drawctx_set_font(&drawctx, &lbl->font);
-		sysarg_t x = ((w->width - cpt_width) / 2) + w->hpos;
-		sysarg_t y = ((w->height - cpt_height) / 2) + w->vpos;
-		if (lbl->caption) {
+		
+		if (lbl->caption)
 			drawctx_print(&drawctx, lbl->caption, x, y);
-		}
 	}
-
+	
 	window_yield(lbl->widget.window);
 }
@@ -78,15 +78,17 @@
 	if (data != NULL) {
 		label_t *lbl = (label_t *) widget;
+		
 		const char *new_caption = (const char *) data;
 		lbl->caption = str_dup(new_caption);
-
+		
 		sysarg_t cpt_width;
 		sysarg_t cpt_height;
 		font_get_box(&lbl->font, lbl->caption, &cpt_width, &cpt_height);
+		
 		lbl->widget.width_min = cpt_width + 4;
 		lbl->widget.height_min = cpt_height + 4;
 		lbl->widget.width_ideal = lbl->widget.width_min;
 		lbl->widget.height_ideal = lbl->widget.height_min;
-
+		
 		window_refresh(lbl->widget.window);
 	}
@@ -103,7 +105,6 @@
 {
 	label_t *lbl = (label_t *) widget;
-
+	
 	deinit_label(lbl);
-	
 	free(lbl);
 }
@@ -137,9 +138,9 @@
 }
 
-bool init_label(label_t *lbl, widget_t *parent,
-    const char *caption, uint16_t points, pixel_t background, pixel_t foreground)
+bool init_label(label_t *lbl, widget_t *parent, const char *caption,
+    uint16_t points, pixel_t background, pixel_t text)
 {
 	widget_init(&lbl->widget, parent);
-
+	
 	lbl->widget.destroy = label_destroy;
 	lbl->widget.reconfigure = label_reconfigure;
@@ -148,47 +149,46 @@
 	lbl->widget.handle_keyboard_event = label_handle_keyboard_event;
 	lbl->widget.handle_position_event = label_handle_position_event;
-
+	
 	source_init(&lbl->background);
 	source_set_color(&lbl->background, background);
-	source_init(&lbl->foreground);
-	source_set_color(&lbl->foreground, foreground);
-
-	if (caption == NULL) {
+	
+	source_init(&lbl->text);
+	source_set_color(&lbl->text, text);
+	
+	if (caption == NULL)
 		lbl->caption = NULL;
-	} else {
+	else
 		lbl->caption = str_dup(caption);
-	}
+	
 	font_init(&lbl->font, FONT_DECODER_EMBEDDED, NULL, points);
-
+	
 	sysarg_t cpt_width;
 	sysarg_t cpt_height;
 	font_get_box(&lbl->font, lbl->caption, &cpt_width, &cpt_height);
+	
 	lbl->widget.width_min = cpt_width + 4;
 	lbl->widget.height_min = cpt_height + 4;
 	lbl->widget.width_ideal = lbl->widget.width_min;
 	lbl->widget.height_ideal = lbl->widget.height_min;
-
+	
 	lbl->rewrite = on_rewrite;
-
+	
 	return true;
 }
 
-label_t *create_label(widget_t *parent,
-    const char *caption, uint16_t points, pixel_t background, pixel_t foreground)
+label_t *create_label(widget_t *parent, const char *caption, uint16_t points,
+    pixel_t background, pixel_t text)
 {
 	label_t *lbl = (label_t *) malloc(sizeof(label_t));
-	if (!lbl) {
+	if (!lbl)
 		return NULL;
-	}
-
-	if (init_label(lbl, parent, caption, points, background, foreground)) {
+	
+	if (init_label(lbl, parent, caption, points, background, text))
 		return lbl;
-	} else {
-		free(lbl);
-		return NULL;
-	}
+	
+	free(lbl);
+	return NULL;
 }
 
 /** @}
  */
-
Index: uspace/lib/gui/label.h
===================================================================
--- uspace/lib/gui/label.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/gui/label.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -49,5 +49,5 @@
 	widget_t widget;
 	source_t background;
-	source_t foreground;
+	source_t text;
 	char *caption;
 	font_t font;
@@ -55,6 +55,8 @@
 } label_t;
 
-extern bool init_label(label_t *, widget_t *, const char *, uint16_t, pixel_t, pixel_t);
-extern label_t *create_label(widget_t *, const char *, uint16_t, pixel_t, pixel_t);
+extern bool init_label(label_t *, widget_t *, const char *, uint16_t, pixel_t,
+    pixel_t);
+extern label_t *create_label(widget_t *, const char *, uint16_t, pixel_t,
+    pixel_t);
 extern void deinit_label(label_t *);
 
Index: uspace/lib/gui/window.c
===================================================================
--- uspace/lib/gui/window.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/gui/window.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -56,75 +56,133 @@
 #include <surface.h>
 
+#include "common.h"
 #include "connection.h"
 #include "widget.h"
 #include "window.h"
 
-static sysarg_t border_thickness = 5;
+static sysarg_t border_thickness = 4;
+static sysarg_t bevel_thickness = 1;
 static sysarg_t header_height = 20;
 static sysarg_t header_min_width = 40;
-static sysarg_t close_width = 20;
-
-static pixel_t border_color = PIXEL(255, 0, 0, 0);
-static pixel_t header_bg_focus_color = PIXEL(255, 88, 106, 196);
-static pixel_t header_fg_focus_color = PIXEL(255, 255, 255, 255);
-static pixel_t header_bg_unfocus_color = PIXEL(255, 12, 57, 92);
-static pixel_t header_fg_unfocus_color = PIXEL(255, 255, 255, 255);
-
-static void paint_internal(widget_t *w)
-{
-	surface_t *surface = window_claim(w->window);
-	if (!surface) {
-		window_yield(w->window);
-	}
-
+static sysarg_t close_thickness = 20;
+
+static pixel_t color_highlight = PIXEL(255, 255, 255, 255);
+static pixel_t color_shadow = PIXEL(255, 85, 85, 85);
+static pixel_t color_surface = PIXEL(255, 186, 186, 186);
+
+static pixel_t color_header_focus_highlight = PIXEL(255, 120, 145, 255);
+static pixel_t color_header_focus_shadow = PIXEL(255, 40, 48, 89);
+static pixel_t color_header_focus_surface = PIXEL(255, 88, 106, 196);
+
+static pixel_t color_header_unfocus_highlight = PIXEL(255, 16, 78, 126);
+static pixel_t color_header_unfocus_shadow = PIXEL(255, 5, 26, 42);
+static pixel_t color_header_unfocus_surface = PIXEL(255, 12, 57, 92);
+
+static pixel_t color_caption_focus = PIXEL(255, 255, 255, 255);
+static pixel_t color_caption_unfocus = PIXEL(255, 207, 207, 207);
+
+static void paint_internal(widget_t *widget)
+{
+	surface_t *surface = window_claim(widget->window);
+	if (!surface)
+		window_yield(widget->window);
+	
 	source_t source;
-	font_t font;
+	source_init(&source);
+	
 	drawctx_t drawctx;
-
-	source_init(&source);
-	font_init(&font, FONT_DECODER_EMBEDDED, NULL, 16);
 	drawctx_init(&drawctx, surface);
 	drawctx_set_source(&drawctx, &source);
+	
+	/* Window border outer bevel */
+	
+	draw_bevel(&drawctx, &source, widget->vpos, widget->hpos,
+	    widget->width, widget->height, color_highlight, color_shadow);
+	
+	/* Window border surface */
+	
+	source_set_color(&source, color_surface);
+	drawctx_transfer(&drawctx, widget->hpos + 1, widget->vpos + 1,
+	    widget->width - 2, 2);
+	drawctx_transfer(&drawctx, widget->hpos + 1, widget->vpos + 1,
+	    2, widget->height - 2);
+	drawctx_transfer(&drawctx, widget->hpos + 1,
+	    widget->vpos + widget->height - 3, widget->width - 2, 2);
+	drawctx_transfer(&drawctx, widget->hpos + widget->width - 3,
+	    widget->vpos + 1, 2, widget->height - 4);
+	
+	/* Window border inner bevel */
+	
+	draw_bevel(&drawctx, &source, widget->hpos + 3, widget->vpos + 3,
+	    widget->width - 6, widget->height - 6, color_shadow,
+	    color_highlight);
+	
+	/* Header bevel */
+	
+	sysarg_t header_hpos = widget->hpos + border_thickness;
+	sysarg_t header_vpos = widget->vpos + border_thickness;
+	sysarg_t header_width = widget->width - 2 * border_thickness -
+	    close_thickness;
+	
+	draw_bevel(&drawctx, &source, header_hpos, header_vpos,
+	    header_width, header_height, widget->window->is_focused ?
+	    color_header_focus_highlight : color_header_unfocus_highlight,
+	    widget->window->is_focused ?
+	    color_header_focus_shadow : color_header_unfocus_shadow);
+	
+	/* Header surface */
+	
+	source_set_color(&source, widget->window->is_focused ?
+	    color_header_focus_surface : color_header_unfocus_surface);
+	drawctx_transfer(&drawctx, header_hpos + 1, header_vpos + 1,
+	    header_width - 2, header_height - 2);
+	
+	/* Close button bevel */
+	
+	sysarg_t close_hpos = widget->hpos + widget->width -
+	    border_thickness - close_thickness;
+	sysarg_t close_vpos = widget->vpos + border_thickness;
+	
+	draw_bevel(&drawctx, &source, close_hpos, close_vpos,
+	    close_thickness, close_thickness, color_highlight, color_shadow);
+	
+	/* Close button surface */
+	
+	source_set_color(&source, color_surface);
+	drawctx_transfer(&drawctx, close_hpos + 1, close_vpos + 1,
+	    close_thickness - 2, close_thickness - 2);
+	
+	/* Close button icon */
+	
+	draw_icon_cross(surface, close_hpos + 3, close_vpos + 3,
+	    color_highlight, color_shadow);
+	
+	/* Window caption */
+	
+	font_t font;
+	font_init(&font, FONT_DECODER_EMBEDDED, NULL, 16);
+	
 	drawctx_set_font(&drawctx, &font);
-
-	source_set_color(&source, border_color);
-	drawctx_transfer(&drawctx, w->hpos, w->vpos, border_thickness, w->height);
-	drawctx_transfer(&drawctx, w->hpos + w->width - border_thickness,
-	    w->vpos, border_thickness, w->height);
-	drawctx_transfer(&drawctx, w->hpos, w->vpos, w->width, border_thickness);
-	drawctx_transfer(&drawctx, w->hpos,
-	    w->vpos + w->height - border_thickness, w->width, border_thickness);
-
-	source_set_color(&source, 
-	    w->window->is_focused ? header_bg_focus_color : header_bg_unfocus_color);
-	drawctx_transfer(&drawctx,
-	    w->hpos + border_thickness, w->vpos + border_thickness,
-		w->width - 2 * border_thickness, header_height);
-
+	source_set_color(&source, widget->window->is_focused ?
+	    color_caption_focus : color_caption_unfocus);
+	
 	sysarg_t cpt_width;
 	sysarg_t cpt_height;
-	font_get_box(&font, w->window->caption, &cpt_width, &cpt_height);
-	sysarg_t cls_width;
-	sysarg_t cls_height;
-	char cls_pict[] = "x";
-	font_get_box(&font, cls_pict, &cls_width, &cls_height);
-	source_set_color(&source, 
-	    w->window->is_focused ? header_fg_focus_color : header_fg_unfocus_color);
-	sysarg_t cls_x = ((close_width - cls_width) / 2) + w->hpos + w->width -
-	    border_thickness - close_width;
-	sysarg_t cls_y = ((header_height - cls_height) / 2) + w->vpos + border_thickness;
-	drawctx_print(&drawctx, cls_pict, cls_x, cls_y);
-
-	bool draw_title = (w->width >= 2 * border_thickness + close_width + cpt_width);
+	font_get_box(&font, widget->window->caption, &cpt_width, &cpt_height);
+	
+	bool draw_title =
+	    (widget->width >= 2 * border_thickness + 2 * bevel_thickness +
+	    close_thickness + cpt_width);
 	if (draw_title) {
-		sysarg_t cpt_x = ((w->width - cpt_width) / 2) + w->hpos;
-		sysarg_t cpt_y = ((header_height - cpt_height) / 2) + w->vpos + border_thickness;
-		if (w->window->caption) {
-			drawctx_print(&drawctx, w->window->caption, cpt_x, cpt_y);
-		}
-	}
-
+		sysarg_t cpt_x = ((widget->width - cpt_width) / 2) + widget->hpos;
+		sysarg_t cpt_y = ((header_height - cpt_height) / 2) +
+		    widget->vpos + border_thickness;
+		
+		if (widget->window->caption)
+			drawctx_print(&drawctx, widget->window->caption, cpt_x, cpt_y);
+	}
+	
 	font_release(&font);
-	window_yield(w->window);
+	window_yield(widget->window);
 }
 
@@ -138,5 +196,5 @@
 	if (widget->window->is_decorated) {
 		list_foreach(widget->children, link, widget_t, child) {
-			child->rearrange(child, 
+			child->rearrange(child,
 			    widget->hpos + border_thickness,
 			    widget->vpos + border_thickness + header_height,
@@ -211,5 +269,6 @@
 		    (event.vpos >= border_thickness) &&
 		    (event.vpos < border_thickness + header_height);
-		bool close = header && (event.hpos >= width - border_thickness - close_width);
+		bool close = (header) &&
+		    (event.hpos >= width - border_thickness - close_thickness);
 
 		if (top && left && allowed_button) {
@@ -292,5 +351,5 @@
 }
 
-static void handle_signal_event(window_t *win, sig_event_t event)
+static void handle_signal_event(window_t *win, signal_event_t event)
 {
 	widget_t *widget = (widget_t *) event.object;
@@ -303,58 +362,56 @@
 }
 
-static void handle_resize(window_t *win, sysarg_t width, sysarg_t height)
-{
-	int rc;
-	surface_t *old_surface;
-	surface_t *new_surface;
-
+static void handle_resize(window_t *win, sysarg_t offset_x, sysarg_t offset_y,
+    sysarg_t width, sysarg_t height, window_placement_flags_t placement_flags)
+{
 	if (width < 2 * border_thickness + header_min_width) {
 		win_damage(win->osess, 0, 0, 0, 0);
 		return;
 	}
-
+	
 	if (height < 2 * border_thickness + header_height) {
 		win_damage(win->osess, 0, 0, 0, 0);
 		return;
 	}
-
+	
 	/* Allocate resources for new surface. */
-	new_surface = surface_create(width, height, NULL, SURFACE_FLAG_SHARED);
-	if (!new_surface) {
+	surface_t *new_surface = surface_create(width, height, NULL,
+	    SURFACE_FLAG_SHARED);
+	if (!new_surface)
 		return;
-	}
-
+	
 	/* Switch new and old surface. */
 	fibril_mutex_lock(&win->guard);
-	old_surface = win->surface;
+	surface_t *old_surface = win->surface;
 	win->surface = new_surface;
 	fibril_mutex_unlock(&win->guard);
-
-	/* Let all widgets in the tree alter their position and size. Widgets might
-	 * also paint themselves onto the new surface. */
+	
+	/*
+	 * Let all widgets in the tree alter their position and size.
+	 * Widgets might also paint themselves onto the new surface.
+	 */
 	win->root.rearrange(&win->root, 0, 0, width, height);
-
+	
 	fibril_mutex_lock(&win->guard);
 	surface_reset_damaged_region(win->surface);
 	fibril_mutex_unlock(&win->guard);
-
+	
 	/* Inform compositor about new surface. */
-	rc = win_resize(win->osess,
-		width, height, surface_direct_access(new_surface));
-
+	int rc = win_resize(win->osess, offset_x, offset_y, width, height,
+	    placement_flags, surface_direct_access(new_surface));
+	
 	if (rc != EOK) {
 		/* Rollback to old surface. Reverse all changes. */
-
+		
 		sysarg_t old_width = 0;
 		sysarg_t old_height = 0;
-		if (old_surface) {
+		if (old_surface)
 			surface_get_resolution(old_surface, &old_width, &old_height);
-		}
-
+		
 		fibril_mutex_lock(&win->guard);
 		new_surface = win->surface;
 		win->surface = old_surface;
 		fibril_mutex_unlock(&win->guard);
-
+		
 		win->root.rearrange(&win->root, 0, 0, old_width, old_height);
 		
@@ -364,12 +421,10 @@
 			fibril_mutex_unlock(&win->guard);
 		}
-
+		
 		surface_destroy(new_surface);
-		return;
-	}
-
-	/* Finally deallocate old surface. */
-	if (old_surface) {
-		surface_destroy(old_surface);
+	} else {
+		/* Deallocate old surface. */
+		if (old_surface)
+			surface_destroy(old_surface);
 	}
 }
@@ -453,8 +508,10 @@
 			break;
 		case ET_SIGNAL_EVENT:
-			handle_signal_event(win, event->data.sig);
+			handle_signal_event(win, event->data.signal);
 			break;
 		case ET_WINDOW_RESIZE:
-			handle_resize(win, event->data.rsz.width, event->data.rsz.height);
+			handle_resize(win, event->data.resize.offset_x,
+			    event->data.resize.offset_y, event->data.resize.width,
+			    event->data.resize.height, event->data.resize.placement_flags);
 			break;
 		case ET_WINDOW_FOCUS:
@@ -530,13 +587,10 @@
 
 window_t *window_open(const char *winreg, bool is_main, bool is_decorated,
-    const char *caption, sysarg_t x_offset, sysarg_t y_offset)
-{
-	int rc;
-
+    const char *caption)
+{
 	window_t *win = (window_t *) malloc(sizeof(window_t));
-	if (!win) {
+	if (!win)
 		return NULL;
-	}
-
+	
 	win->is_main = is_main;
 	win->is_decorated = is_decorated;
@@ -544,4 +598,5 @@
 	prodcons_initialize(&win->events);
 	fibril_mutex_initialize(&win->guard);
+	
 	widget_init(&win->root, NULL);
 	win->root.window = win;
@@ -555,24 +610,22 @@
 	win->focus = NULL;
 	win->surface = NULL;
-
+	
 	service_id_t reg_dsid;
-	async_sess_t *reg_sess;
-
-	rc = loc_service_get_id(winreg, &reg_dsid, 0);
+	int rc = loc_service_get_id(winreg, &reg_dsid, 0);
 	if (rc != EOK) {
 		free(win);
 		return NULL;
 	}
-
-	reg_sess = loc_service_connect(EXCHANGE_SERIALIZE, reg_dsid, 0);
+	
+	async_sess_t *reg_sess = loc_service_connect(EXCHANGE_SERIALIZE,
+	    reg_dsid, 0);
 	if (reg_sess == NULL) {
 		free(win);
 		return NULL;
 	}
-
+	
 	service_id_t in_dsid;
 	service_id_t out_dsid;
-	
-	rc = win_register(reg_sess, &in_dsid, &out_dsid, x_offset, y_offset);
+	rc = win_register(reg_sess, &in_dsid, &out_dsid);
 	async_hangup(reg_sess);
 	if (rc != EOK) {
@@ -580,5 +633,5 @@
 		return NULL;
 	}
-
+	
 	win->osess = loc_service_connect(EXCHANGE_SERIALIZE, out_dsid, 0);
 	if (win->osess == NULL) {
@@ -586,5 +639,5 @@
 		return NULL;
 	}
-
+	
 	win->isess = loc_service_connect(EXCHANGE_SERIALIZE, in_dsid, 0);
 	if (win->isess == NULL) {
@@ -593,15 +646,15 @@
 		return NULL;
 	}
-
-	if (caption == NULL) {
+	
+	if (caption == NULL)
 		win->caption = NULL;
-	} else {
+	else
 		win->caption = str_dup(caption);
-	}
-
+	
 	return win;
 }
 
-void window_resize(window_t *win, sysarg_t width, sysarg_t height)
+void window_resize(window_t *win, sysarg_t offset_x, sysarg_t offset_y,
+    sysarg_t width, sysarg_t height, window_placement_flags_t placement_flags)
 {
 	window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
@@ -609,6 +662,9 @@
 		link_initialize(&event->link);
 		event->type = ET_WINDOW_RESIZE;
-		event->data.rsz.width = width;
-		event->data.rsz.height = height;
+		event->data.resize.offset_x = offset_x;
+		event->data.resize.offset_y = offset_y;
+		event->data.resize.width = width;
+		event->data.resize.height = height;
+		event->data.resize.placement_flags = placement_flags;
 		prodcons_produce(&win->events, &event->link);
 	}
Index: uspace/lib/gui/window.h
===================================================================
--- uspace/lib/gui/window.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/gui/window.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -66,6 +66,5 @@
  * If the window is declared as main, its closure causes termination of the
  * whole application. Note that opened window does not have any surface yet. */
-extern window_t *window_open(const char *, bool, bool, const char *, sysarg_t,
-    sysarg_t);
+extern window_t *window_open(const char *, bool, bool, const char *);
 
 /**
@@ -74,5 +73,6 @@
  * and to paint themselves on the new surface (top-bottom order). Should be
  * called also after opening new window to obtain surface. */
-extern void window_resize(window_t *, sysarg_t, sysarg_t);
+extern void window_resize(window_t *, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
+    window_placement_flags_t);
 
 /**
Index: uspace/lib/math/Makefile
===================================================================
--- uspace/lib/math/Makefile	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/math/Makefile	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,35 @@
+#
+# Copyright (c) 2013 Vojtech Horky
+# 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.
+#
+
+USPACE_PREFIX = ../..
+LIBRARY = libmath
+
+SOURCES = \
+	src/dummy.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/lib/math/src/dummy.c
===================================================================
--- uspace/lib/math/src/dummy.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/math/src/dummy.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2011 Petr Koupy
+ * Copyright (c) 2013 Vojtech Horky
+ * 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 libmath
+ * @{
+ */
+/** @file Mathematical operations (dummy implementation).
+ */
+#include <math.h>
+#include <stdio.h>
+
+#define WARN_NOT_IMPLEMENTED() \
+	do { \
+		static int __not_implemented_counter = 0; \
+		if (__not_implemented_counter == 0) { \
+			fprintf(stderr, "Warning: using dummy implementation of %s().\n", \
+				__func__); \
+		} \
+		__not_implemented_counter++; \
+	} while (0)
+
+double ldexp(double x, int exp)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double frexp(double num, int *exp)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double cos(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double cosh(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double acos(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double acosh(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double pow(double x, double y)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double floor(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double ceil(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double fabs(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double modf(double x, double *iptr)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double fmod(double x, double y)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double log(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double log10(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+
+double atan2(double y, double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double sin(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double sinh(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double asin(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double asinh(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double tan(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double tanh(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double atan(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double atanh(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+
+double exp(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double expm1(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double sqrt(double x)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+double copysign(double x, double y)
+{
+	WARN_NOT_IMPLEMENTED();
+	return 0.0;
+}
+
+
+/** @}
+ */
Index: uspace/lib/mbr/Makefile
===================================================================
--- uspace/lib/mbr/Makefile	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/mbr/Makefile	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2011 Dominik Taborsky
+# 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.
+#
+
+USPACE_PREFIX = ../..
+EXTRA_CFLAGS = -I$(LIBBLOCK_PREFIX)
+LIBRARY = libmbr
+
+SOURCES = \
+	libmbr.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/lib/mbr/libmbr.c
===================================================================
--- uspace/lib/mbr/libmbr.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/mbr/libmbr.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,852 @@
+/*
+ * Copyright (c) 2011-2013 Dominik Taborsky
+ * 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 LIBMBR_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 libmbr
+ * @{
+ */
+/** @file MBR extraxtion library
+ */
+
+#include <async.h>
+#include <assert.h>
+#include <block.h>
+#include <byteorder.h>
+#include <errno.h>
+#include <ipc/bd.h>
+#include <mem.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <str_error.h>
+#include <align.h>
+#include "libmbr.h"
+
+static br_block_t *alloc_br(void);
+static int decode_part(pt_entry_t *, mbr_part_t *, uint32_t);
+static int decode_logical(mbr_label_t *, mbr_part_t *);
+static void encode_part(mbr_part_t *, pt_entry_t *, uint32_t, bool);
+static bool check_overlap(mbr_part_t *, mbr_part_t *);
+static bool check_encaps(mbr_part_t *, mbr_part_t *);
+static bool check_preceeds(mbr_part_t *, mbr_part_t *);
+static mbr_err_val mbr_add_primary(mbr_label_t *, mbr_part_t *);
+static mbr_err_val mbr_add_logical(mbr_label_t *, mbr_part_t *);
+
+/** Allocate and initialize mbr_label_t structure */
+mbr_label_t *mbr_alloc_label(void)
+{
+	mbr_label_t *label = malloc(sizeof(mbr_label_t));
+	if (label == NULL)
+		return NULL;
+	
+	label->mbr = NULL;
+	label->parts = NULL;
+	label->device = 0;
+	
+	return label;
+}
+
+void mbr_set_device(mbr_label_t *label, service_id_t dev_handle)
+{
+	label->device = dev_handle;
+}
+
+/** Free mbr_label_t structure */
+void mbr_free_label(mbr_label_t *label)
+{
+	if (label->mbr != NULL)
+		mbr_free_mbr(label->mbr);
+	
+	if (label->parts != NULL)
+		mbr_free_partitions(label->parts);
+	
+	free(label);
+}
+
+/** Allocate memory for mbr_t */
+mbr_t *mbr_alloc_mbr(void)
+{
+	return malloc(sizeof(mbr_t));
+}
+
+/** Read MBR from specific device
+ *
+ * @param label      Label to be read.
+ * @param dev_handle Device to read MBR from.
+ *
+ * @return EOK on success, error code on error.
+ *
+ */
+int mbr_read_mbr(mbr_label_t *label, service_id_t dev_handle)
+{	
+	if (label->mbr == NULL) {
+		label->mbr = mbr_alloc_mbr();
+		if (label->mbr == NULL)
+			return ENOMEM;
+	}
+	
+	int rc = block_init(EXCHANGE_ATOMIC, dev_handle, 512);
+	if (rc != EOK)
+		return rc;
+	
+	rc = block_read_direct(dev_handle, 0, 1, &label->mbr->raw_data);
+	block_fini(dev_handle);
+	if (rc != EOK)
+		return rc;
+	
+	label->device = dev_handle;
+	
+	return EOK;
+}
+
+/** Write MBR to specific device
+ *
+ * @param label      Label to be written.
+ * @param dev_handle Device to write MBR to.
+ *
+ * @return EOK on success, error code on error.
+ *
+ */
+int mbr_write_mbr(mbr_label_t *label, service_id_t dev_handle)
+{
+	int rc = block_init(EXCHANGE_ATOMIC, dev_handle, 512);
+	if (rc != EOK)
+		return rc;
+	
+	rc = block_write_direct(dev_handle, 0, 1, &label->mbr->raw_data);
+	block_fini(dev_handle);
+	
+	return rc;
+}
+
+/** Decide whether this is an actual MBR or a Protective MBR for GPT
+ *
+ * @param label Label to decide upon.
+ *
+ * @return True if MBR.
+ * @return False if Protective MBR for GPT.
+ *
+ */
+int mbr_is_mbr(mbr_label_t *label)
+{
+	return (label->mbr->raw_data.pte[0].ptype != PT_GPT);
+}
+
+/** Parse partitions from MBR (freeing previous partitions if any)
+ *
+ * It is assumed that mbr_read_mbr() was called before.
+ *
+ * @param label Label to be parsed.
+ *
+ * @return EOK on success, error code on error.
+ *
+ */
+int mbr_read_partitions(mbr_label_t *label)
+{
+	if ((label == NULL) || (label->mbr == NULL))
+		return EINVAL;
+	
+	if (label->parts != NULL)
+		mbr_free_partitions(label->parts);
+	
+	label->parts = mbr_alloc_partitions();
+	if (label->parts == NULL)
+		return ENOMEM;
+	
+	mbr_part_t *extended = NULL;
+	
+	/* Generate the primary partitions */
+	for (unsigned int i = 0; i < N_PRIMARY; i++) {
+		if (label->mbr->raw_data.pte[i].ptype == PT_UNUSED)
+			continue;
+		
+		mbr_part_t *partition = mbr_alloc_partition();
+		if (partition == NULL) {
+			mbr_free_partitions(label->parts);
+			return ENOMEM;
+		}
+		
+		int is_extended =
+		    decode_part(&label->mbr->raw_data.pte[i], partition, 0);
+		
+		mbr_set_flag(partition, ST_LOGIC, false);
+		
+		int rc = mbr_add_partition(label, partition);
+		if (rc != ERR_OK) {
+			mbr_free_partitions(label->parts);
+			return EINVAL;
+		}
+		
+		if (is_extended) {
+			extended = partition;
+			label->parts->l_extended = &partition->link;
+		}
+	}
+	
+	/* Fill in the primary partitions and generate logical ones (if any) */
+	return decode_logical(label, extended);
+}
+
+/** Write MBR and partitions to device
+ *
+ * @param label      Label to write.
+ * @param dev_handle Device to write the data to.
+ *
+ * @return EOK on success, specific error code otherwise.
+ *
+ */
+int mbr_write_partitions(mbr_label_t *label, service_id_t dev_handle)
+{
+	if (label->parts == NULL)
+		return EOK;
+	
+	if (label->mbr == NULL)
+		label->mbr = mbr_alloc_mbr();
+	
+	int rc = block_init(EXCHANGE_ATOMIC, dev_handle, 512);
+	if (rc != EOK)
+		return rc;
+	
+	mbr_part_t *partition = NULL;
+	mbr_part_t *extended = NULL;
+	
+	if (label->parts->l_extended != NULL)
+		extended = list_get_instance(label->parts->l_extended,
+		    mbr_part_t, link);
+	
+	link_t *link = label->parts->list.head.next;
+	
+	/* Encode primary partitions */
+	for (unsigned int i = 0; i < N_PRIMARY; i++) {
+		partition = list_get_instance(link, mbr_part_t, link);
+		
+		encode_part(partition, &label->mbr->raw_data.pte[i], 0, false);
+		link = link->next;
+	}
+	
+	/* Write MBR */
+	rc = block_write_direct(dev_handle, 0, 1, &label->mbr->raw_data);
+	if ((rc != EOK) || (extended == NULL))
+		goto end;
+	
+	uint32_t base = extended->start_addr;
+	mbr_part_t *prev_partition;
+	
+	/* Encode and write first logical partition */
+	if (link != &label->parts->list.head) {
+		partition = list_get_instance(link, mbr_part_t, link);
+		
+		partition->ebr_addr = base;
+		encode_part(partition, &partition->ebr->pte[0], base, false);
+		link = link->next;
+	} else {
+		/*
+		 * If there was an extended partition but no logical partitions,
+		 * we should overwrite the space where the first logical
+		 * partitions's EBR would have been. There might be some
+		 * garbage from the past.
+		 */
+		
+		br_block_t *br = alloc_br();
+		rc = block_write_direct(dev_handle, base, 1, br);
+		if (rc != EOK)
+			goto end;
+		
+		free(br);
+		goto end;
+	}
+	
+	prev_partition = partition;
+	
+	/*
+	 * Check EBR addresses: The code saves previous EBR
+	 * placements from other software. But if our user
+	 * modifies the logical partition chain, we have to
+	 * fix those placements if needed.
+	 */
+	
+	link_t *link_ebr = link;
+	link_t *link_iter;
+	
+	mbr_part_t tmp_partition;
+	tmp_partition.length = 1;
+	
+	while (link_ebr != &label->parts->list.head) {
+		partition = list_get_instance(link_ebr, mbr_part_t, link);
+		
+		tmp_partition.start_addr = partition->ebr_addr;
+		
+		link_iter = link;
+		while (link_iter != &label->parts->list.head) {
+			/*
+			 * Check whether EBR address makes sense. If not, we take
+			 * a guess.  So far this is simple, we just take the first
+			 * preceeding sector. FDisk always reserves at least 2048
+			 * sectors (1 MiB), so it can have the EBR aligned as well
+			 * as the partition itself. Parted reserves minimum one
+			 * sector, like we do.
+			 *
+			 * Note that we know there is at least one sector free from
+			 * previous checks. Also note that the user can set ebr_addr
+			 * to their liking (if it is valid).
+			 */
+			
+			if ((partition->ebr_addr < base) ||
+			    (partition->ebr_addr >= base + extended->length) ||
+			    (check_overlap(&tmp_partition,
+			    list_get_instance(link_iter, mbr_part_t, link)))) {
+				partition->ebr_addr = partition->start_addr - 1;
+				break;
+			}
+			
+			link_iter = link_iter->next;
+		}
+		
+		link_ebr = link_ebr->next;
+	}
+	
+	/* Encode and write logical partitions */
+	while (link != &label->parts->list.head) {
+		partition = list_get_instance(link, mbr_part_t, link);
+		
+		encode_part(partition, &partition->ebr->pte[0],
+		    partition->ebr_addr, false);
+		encode_part(partition, &prev_partition->ebr->pte[1],
+		    base, true);
+		
+		rc = block_write_direct(dev_handle, prev_partition->ebr_addr, 1,
+		    prev_partition->ebr);
+		if (rc != EOK)
+			goto end;
+		
+		prev_partition = partition;
+		link = link->next;
+	}
+	
+	/* Write the last EBR */
+	encode_part(NULL, &prev_partition->ebr->pte[1], 0, false);
+	rc = block_write_direct(dev_handle, prev_partition->ebr_addr,
+	    1, prev_partition->ebr);
+	
+end:
+	block_fini(dev_handle);
+	return rc;
+}
+
+/** Partition constructor */
+mbr_part_t *mbr_alloc_partition(void)
+{
+	mbr_part_t *partition = malloc(sizeof(mbr_part_t));
+	if (partition == NULL)
+		return NULL;
+	
+	link_initialize(&partition->link);
+	partition->ebr = NULL;
+	partition->type = PT_UNUSED;
+	partition->status = 0;
+	partition->start_addr = 0;
+	partition->length = 0;
+	partition->ebr_addr = 0;
+	
+	return partition;
+}
+
+/** Partitions constructor */
+mbr_partitions_t *mbr_alloc_partitions(void)
+{
+	mbr_partitions_t *parts = malloc(sizeof(mbr_partitions_t));
+	if (parts == NULL)
+		return NULL;
+	
+	list_initialize(&parts->list);
+	parts->n_primary = 0;
+	parts->n_logical = 0;
+	parts->l_extended = NULL;
+	
+	/* Add blank primary partitions */
+	for (unsigned int i = 0; i < N_PRIMARY; ++i) {
+		mbr_part_t *part = mbr_alloc_partition();
+		if (part == NULL) {
+			mbr_free_partitions(parts);
+			return NULL;
+		}
+		
+		list_append(&part->link, &parts->list);
+	}
+	
+	return parts;
+}
+
+/** Add partition
+ *
+ * Perform checks, sort the list.
+ *
+ * @param label Label to add to.
+ * @param part  Partition to add.
+ *
+ * @return ERR_OK on success, other MBR_ERR_VAL otherwise
+ *
+ */
+mbr_err_val mbr_add_partition(mbr_label_t *label, mbr_part_t *part)
+{
+	int rc = block_init(EXCHANGE_ATOMIC, label->device, 512);
+	if ((rc != EOK) && (rc != EEXIST))
+		return ERR_LIBBLOCK;
+	
+	aoff64_t nblocks;
+	int ret = block_get_nblocks(label->device, &nblocks);
+	
+	if (rc != EEXIST)
+		block_fini(label->device);
+	
+	if (ret != EOK)
+		return ERR_LIBBLOCK;
+	
+	if ((aoff64_t) part->start_addr + part->length > nblocks)
+		return ERR_OUT_BOUNDS;
+	
+	if (label->parts == NULL) {
+		label->parts = mbr_alloc_partitions();
+		if (label->parts == NULL)
+			// FIXME! merge mbr_err_val into errno.h
+			return ENOMEM;
+	}
+	
+	if (mbr_get_flag(part, ST_LOGIC))
+		return mbr_add_logical(label, part);
+	else
+		return mbr_add_primary(label, part);
+}
+
+/** Remove partition
+ *
+ * Remove partition (indexed from zero). When removing the extended
+ * partition, all logical partitions get removed as well.
+ *
+ * @param label Label to remove from.
+ * @param idx   Index of the partition to remove.
+ *
+ * @return EOK on success.
+ * @return EINVAL if the index is invalid.
+ *
+ */
+int mbr_remove_partition(mbr_label_t *label, size_t idx)
+{
+	link_t *link = list_nth(&label->parts->list, idx);
+	if (link == NULL)
+		return EINVAL;
+	
+	/*
+	 * If removing the extended partition, remove all
+	 * logical partitions as well.
+	 */
+	if (link == label->parts->l_extended) {
+		label->parts->l_extended = NULL;
+		
+		link_t *iterator = link->next;
+		link_t *next;
+		
+		while (iterator != &label->parts->list.head) {
+			next = iterator->next;
+			mbr_part_t *partition =
+			    list_get_instance(iterator, mbr_part_t, link);
+			
+			if (mbr_get_flag(partition, ST_LOGIC)) {
+				list_remove(iterator);
+				label->parts->n_logical--;
+				mbr_free_partition(partition);
+			}
+			
+			iterator = next;
+		}
+	}
+	
+	/* Remove the partition itself */
+	mbr_part_t *partition =
+	    list_get_instance(link, mbr_part_t, link);
+	
+	if (mbr_get_flag(partition, ST_LOGIC)) {
+		label->parts->n_logical--;
+		list_remove(link);
+		mbr_free_partition(partition);
+	} else {
+		/*
+		 * Cannot remove a primary partition without
+		 * breaking the ordering. Just zero it.
+		 */
+		label->parts->n_primary--;
+		partition->type = 0;
+		partition->status = 0;
+		partition->start_addr = 0;
+		partition->length = 0;
+		partition->ebr_addr = 0;
+	}
+	
+	return EOK;
+}
+
+/** Partition destructor */
+void mbr_free_partition(mbr_part_t *partition)
+{
+	if (partition->ebr != NULL)
+		free(partition->ebr);
+	
+	free(partition);
+}
+
+/** Check for flag */
+int mbr_get_flag(mbr_part_t *partition, mbr_flags_t flag)
+{
+	return (partition->status & (1 << flag));
+}
+
+/** Set a specific status flag */
+void mbr_set_flag(mbr_part_t *partition, mbr_flags_t flag, bool set)
+{
+	if (set)
+		partition->status |= 1 << flag;
+	else
+		partition->status &= ~((uint16_t) (1 << flag));
+}
+
+/** Get next aligned address */
+uint32_t mbr_get_next_aligned(uint32_t addr, unsigned int alignment)
+{
+	return ALIGN_UP(addr + 1, alignment);
+}
+
+list_t *mbr_get_list(mbr_label_t *label)
+{
+	if (label->parts != NULL)
+		return &label->parts->list;
+	else
+		return NULL;
+}
+
+mbr_part_t *mbr_get_first_partition(mbr_label_t *label)
+{
+	list_t *list = mbr_get_list(label);
+	if ((list != NULL) && (!list_empty(list)))
+		return list_get_instance(list->head.next, mbr_part_t, link);
+	else
+		return NULL;
+}
+
+mbr_part_t *mbr_get_next_partition(mbr_label_t *label, mbr_part_t *partition)
+{
+	list_t *list = mbr_get_list(label);
+	if ((list != NULL) && (&partition->link != list_last(list)))
+		return list_get_instance(partition->link.next, mbr_part_t, link);
+	else
+		return NULL;
+}
+
+void mbr_free_mbr(mbr_t *mbr)
+{
+	free(mbr);
+}
+
+/** Free partition list
+ *
+ * @param parts Partition list to be freed
+ *
+ */
+void mbr_free_partitions(mbr_partitions_t *parts)
+{
+	list_foreach_safe(parts->list, cur_link, next) {
+		mbr_part_t *partition = list_get_instance(cur_link, mbr_part_t, link);
+		list_remove(cur_link);
+		mbr_free_partition(partition);
+	}
+	
+	free(parts);
+}
+
+static br_block_t *alloc_br(void)
+{
+	br_block_t *br = malloc(sizeof(br_block_t));
+	if (br == NULL)
+		return NULL;
+	
+	memset(br, 0, 512);
+	br->signature = host2uint16_t_le(BR_SIGNATURE);
+	
+	return br;
+}
+
+/** Decode partition entry */
+static int decode_part(pt_entry_t *src, mbr_part_t *partition, uint32_t base)
+{
+	partition->type = src->ptype;
+	partition->status = (partition->status & 0xff00) | (uint16_t) src->status;
+	partition->start_addr = uint32_t_le2host(src->first_lba) + base;
+	partition->length = uint32_t_le2host(src->length);
+	
+	return (src->ptype == PT_EXTENDED);
+}
+
+/** Parse logical partitions */
+static int decode_logical(mbr_label_t *label, mbr_part_t *extended)
+{
+	if (extended == NULL)
+		return EOK;
+	
+	br_block_t *ebr = alloc_br();
+	if (ebr == NULL)
+		return ENOMEM;
+	
+	uint32_t base = extended->start_addr;
+	uint32_t addr = base;
+	
+	int rc = block_init(EXCHANGE_ATOMIC, label->device, 512);
+	if (rc != EOK)
+		goto end;
+	
+	rc = block_read_direct(label->device, addr, 1, ebr);
+	if (rc != EOK)
+		goto end;
+	
+	if (uint16_t_le2host(ebr->signature) != BR_SIGNATURE) {
+		rc = EINVAL;
+		goto end;
+	}
+	
+	if (ebr->pte[0].ptype == PT_UNUSED) {
+		rc = EOK;
+		goto end;
+	}
+	
+	mbr_part_t *partition = mbr_alloc_partition();
+	if (partition == NULL) {
+		rc = ENOMEM;
+		goto end;
+	}
+	
+	decode_part(&ebr->pte[0], partition, base);
+	mbr_set_flag(partition, ST_LOGIC, true);
+	partition->ebr = ebr;
+	partition->ebr_addr = addr;
+	
+	rc = mbr_add_partition(label, partition);
+	if (rc != ERR_OK)
+		goto end;
+	
+	addr = uint32_t_le2host(ebr->pte[1].first_lba) + base;
+	
+	while (ebr->pte[1].ptype != PT_UNUSED) {
+		rc = block_read_direct(label->device, addr, 1, ebr);
+		if (rc != EOK)
+			goto end;
+		
+		if (uint16_t_le2host(ebr->signature) != BR_SIGNATURE) {
+			rc = EINVAL;
+			goto end;
+		}
+		
+		mbr_part_t *partition = mbr_alloc_partition();
+		if (partition == NULL) {
+			rc = ENOMEM;
+			goto end;
+		}
+		
+		decode_part(&ebr->pte[0], partition, addr);
+		mbr_set_flag(partition, ST_LOGIC, true);
+		partition->ebr = ebr;
+		partition->ebr_addr = addr;
+		
+		rc = mbr_add_partition(label, partition);
+		if (rc != ERR_OK)
+			goto end;
+		
+		addr = uint32_t_le2host(ebr->pte[1].first_lba) + base;
+	}
+	
+	rc = EOK;
+	
+end:
+	// FIXME possible memory leaks
+	block_fini(label->device);
+	
+	return rc;
+}
+
+/** Encode partition entry */
+static void encode_part(mbr_part_t *src, pt_entry_t *entry, uint32_t base,
+    bool ebr)
+{
+	if (src != NULL) {
+		entry->status = (uint8_t) src->status & 0xff;
+		
+		/* Ignore CHS */
+		entry->first_chs[0] = 0xfe;
+		entry->first_chs[1] = 0xff;
+		entry->first_chs[2] = 0xff;
+		entry->last_chs[0] = 0xfe;
+		entry->last_chs[1] = 0xff;
+		entry->last_chs[2] = 0xff;
+		
+		if (ebr) {
+			/* Encode reference to EBR */
+			entry->ptype = PT_EXTENDED_LBA;
+			entry->first_lba = host2uint32_t_le(src->ebr_addr - base);
+			entry->length = host2uint32_t_le(src->length + src->start_addr -
+			    src->ebr_addr);
+		} else {
+			/* Encode reference to partition */
+			entry->ptype = src->type;
+			entry->first_lba = host2uint32_t_le(src->start_addr - base);
+			entry->length = host2uint32_t_le(src->length);
+		}
+		
+		if (entry->ptype == PT_UNUSED)
+			memset(entry, 0, sizeof(pt_entry_t));
+	} else
+		memset(entry, 0, sizeof(pt_entry_t));
+}
+
+/** Check whether two partitions overlap */
+static bool check_overlap(mbr_part_t *part1, mbr_part_t *part2)
+{
+	if ((part1->start_addr < part2->start_addr) &&
+	    (part1->start_addr + part1->length <= part2->start_addr))
+		return false;
+	
+	if ((part1->start_addr > part2->start_addr) &&
+	    (part2->start_addr + part2->length <= part1->start_addr))
+		return false;
+	
+	return true;
+}
+
+/** Check whether one partition encapsulates the other */
+static bool check_encaps(mbr_part_t *inner, mbr_part_t *outer)
+{
+	if ((inner->start_addr <= outer->start_addr) ||
+	    (outer->start_addr + outer->length <= inner->start_addr))
+		return false;
+	
+	if (outer->start_addr + outer->length < inner->start_addr + inner->length)
+		return false;
+	
+	return true;
+}
+
+/** Check whether one partition preceeds the other */
+static bool check_preceeds(mbr_part_t *preceeder, mbr_part_t *precedee)
+{
+	return preceeder->start_addr < precedee->start_addr;
+}
+
+mbr_err_val mbr_add_primary(mbr_label_t *label, mbr_part_t *part)
+{
+	if (label->parts->n_primary == 4)
+		return ERR_PRIMARY_FULL;
+	
+	/* Check if partition makes space for MBR itself */
+	if (part->start_addr == 0)
+		return ERR_OUT_BOUNDS;
+	
+	/* If it is an extended partition, is there any other one? */
+	if (((part->type == PT_EXTENDED) || (part->type == PT_EXTENDED_LBA)) &&
+	    (label->parts->l_extended != NULL))
+		return ERR_EXTENDED_PRESENT;
+	
+	/* Find a place and add it */
+	mbr_part_t *iter;
+	mbr_part_t *empty = NULL;
+	mbr_part_foreach(label, iter) {
+		if (iter->type == PT_UNUSED) {
+			if (empty == NULL)
+				empty = iter;
+		} else if (check_overlap(part, iter))
+			return ERR_OVERLAP;
+	}
+	
+	list_insert_after(&part->link, &empty->link);
+	list_remove(&empty->link);
+	free(empty);
+	
+	label->parts->n_primary++;
+	
+	if ((part->type == PT_EXTENDED) || (part->type == PT_EXTENDED_LBA))
+		label->parts->l_extended = &part->link;
+	
+	return EOK;
+}
+
+mbr_err_val mbr_add_logical(mbr_label_t *label, mbr_part_t *part)
+{
+	/* Is there any extended partition? */
+	if (label->parts->l_extended == NULL)
+		return ERR_NO_EXTENDED;
+	
+	/* Is the logical partition inside the extended partition? */
+	mbr_part_t *extended = list_get_instance(label->parts->l_extended, mbr_part_t, link);
+	if (!check_encaps(part, extended))
+		return ERR_OUT_BOUNDS;
+	
+	/* Find a place for the new partition in a sorted linked list */
+	bool first_logical = true;
+	mbr_part_t *iter;
+	mbr_part_foreach (label, iter) {
+		if (mbr_get_flag(iter, ST_LOGIC)) {
+			if (check_overlap(part, iter))
+				return ERR_OVERLAP;
+			
+			if (check_preceeds(iter, part)) {
+				/* Check if there is at least one sector of space preceeding */
+				if ((iter->start_addr + iter->length) >= part->start_addr - 1)
+					return ERR_NO_EBR;
+			} else if (first_logical) {
+				/*
+				 * First logical partition's EBR is before every other
+				 * logical partition. Thus we do not check if this partition
+				 * leaves enough space for it.
+				 */
+				first_logical = false;
+			} else {
+				/*
+				 * Check if there is at least one sector of space following
+				 * (for following partitions's EBR).
+				 */
+				if ((part->start_addr + part->length) >= iter->start_addr - 1)
+					return ERR_NO_EBR;
+			}
+		}
+	}
+	
+	/* Allocate EBR if it is not already there */
+	if (part->ebr == NULL) {
+		part->ebr = alloc_br();
+		if (part->ebr == NULL)
+			return ERR_NOMEM;
+	}
+	
+	list_append(&part->link, &label->parts->list);
+	label->parts->n_logical++;
+	
+	return EOK;
+}
Index: uspace/lib/mbr/libmbr.h
===================================================================
--- uspace/lib/mbr/libmbr.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/mbr/libmbr.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2009 Jiri Svoboda
+ * Copyright (c) 2011-2013 Dominik Taborsky
+ * 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 libmbr
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBMBR_LIBMBR_H_
+#define LIBMBR_LIBMBR_H_
+
+#include <sys/types.h>
+#include "mbr.h"
+
+/*
+ * WARNING: When changing both header and partitions, write first header,
+ * then partitions. The MBR headers' raw_data is not updated to follow
+ * partition changes.
+ *
+ * NOTE: Writing partitions writes the complete header as well.
+ */
+
+typedef enum {
+	/** Other flags unknown - saving previous state */
+	/** Bootability */
+	ST_BOOT = 7,
+	/** Logical partition, 0 = primary, 1 = logical*/
+	ST_LOGIC = 8
+} mbr_flags_t;
+
+typedef enum {
+	/** No error */
+	ERR_OK = 0,
+	/** All primary partitions already present */
+	ERR_PRIMARY_FULL,
+	/** Extended partition already present */
+	ERR_EXTENDED_PRESENT,
+	/** No extended partition present */
+	ERR_NO_EXTENDED,
+	/** Partition overlapping */
+	ERR_OVERLAP,
+	/** Partition out of bounds */
+	ERR_OUT_BOUNDS,
+	/** No space left for EBR */
+	ERR_NO_EBR,
+	/** Out of memory */
+	ERR_NOMEM,
+	/** Libblock error */
+	ERR_LIBBLOCK,
+} mbr_err_val;
+
+/** MBR header */
+typedef struct {
+	/** Raw access to data */
+	br_block_t raw_data;
+} mbr_t;
+
+/** Partition */
+typedef struct mbr_part {
+	/** The link in the doubly-linked list */
+	link_t link;
+	/** Partition type */
+	uint8_t type;
+	/** Flags */
+	uint16_t status;
+	/** Address of first block */
+	uint32_t start_addr;
+	/** Number of blocks */
+	uint32_t length;
+	/** Points to Extended Boot Record of logical partition */
+	br_block_t *ebr;
+	/** EBR address */
+	uint32_t ebr_addr;
+} mbr_part_t;
+
+/** Partition list structure */
+typedef struct mbr_parts {
+	/** Number of primary partitions */
+	unsigned char n_primary;
+	/** Index to the extended partition in the array */
+	link_t *l_extended;
+	/** Number of logical partitions */
+	unsigned int n_logical;
+	/** Logical partition linked list */
+	list_t list;
+} mbr_partitions_t;
+
+/** Both header and partition list */
+typedef struct mbr_label {
+	/** MBR header */
+	mbr_t *mbr;
+	/** Partition list */
+	mbr_partitions_t * parts;
+	/** Device where the data are from (or for) */
+	service_id_t device;
+} mbr_label_t;
+
+#define mbr_part_foreach(label, iterator) \
+	for (iterator = list_get_instance((label)->parts->list.head.next, mbr_part_t, link); \
+	    iterator != list_get_instance(&((label)->parts->list.head), mbr_part_t, link); \
+	    iterator = list_get_instance(iterator->link.next, mbr_part_t, link))
+
+extern mbr_label_t *mbr_alloc_label(void);
+
+extern void mbr_set_device(mbr_label_t *, service_id_t);
+extern mbr_t *mbr_alloc_mbr(void);
+extern int mbr_read_mbr(mbr_label_t *, service_id_t);
+extern int mbr_write_mbr(mbr_label_t *, service_id_t);
+extern int mbr_is_mbr(mbr_label_t *);
+
+extern int mbr_read_partitions(mbr_label_t *);
+extern int mbr_write_partitions(mbr_label_t *, service_id_t);
+extern mbr_part_t *mbr_alloc_partition(void);
+extern mbr_partitions_t *mbr_alloc_partitions(void);
+extern mbr_err_val mbr_add_partition(mbr_label_t *, mbr_part_t *);
+extern int mbr_remove_partition(mbr_label_t *, size_t);
+extern int mbr_get_flag(mbr_part_t *, mbr_flags_t);
+extern void mbr_set_flag(mbr_part_t *, mbr_flags_t, bool);
+extern uint32_t mbr_get_next_aligned(uint32_t, unsigned int);
+extern list_t *mbr_get_list(mbr_label_t *);
+extern mbr_part_t *mbr_get_first_partition(mbr_label_t *);
+extern mbr_part_t *mbr_get_next_partition(mbr_label_t *, mbr_part_t *);
+
+extern void mbr_free_label(mbr_label_t *);
+extern void mbr_free_mbr(mbr_t *);
+extern void mbr_free_partition(mbr_part_t *);
+extern void mbr_free_partitions(mbr_partitions_t *);
+
+#endif
Index: uspace/lib/mbr/mbr.h
===================================================================
--- uspace/lib/mbr/mbr.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/mbr/mbr.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2009 Jiri Svoboda
+ * Copyright (c) 2011-2013 Dominik Taborsky
+ * 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 libmbr
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBMBR_MBR_H_
+#define LIBMBR_MBR_H_
+
+#include <sys/types.h>
+
+enum {
+	/** Number of primary partition records */
+	N_PRIMARY = 4,
+	
+	/** Boot record signature */
+	BR_SIGNATURE = 0xAA55
+};
+
+enum {
+	/** Non-bootable */
+	B_INACTIVE = 0x00,
+	/** Bootable */
+	B_ACTIVE = 0x80,
+	/** Anything else means invalid */
+};
+
+enum {
+	/** Unused partition entry */
+	PT_UNUSED = 0x00,
+	/** Extended partition */
+	PT_EXTENDED = 0x05,
+	/** Extended partition with LBA */
+	PT_EXTENDED_LBA = 0x0F,
+	/** GPT Protective partition */
+	PT_GPT = 0xEE,
+};
+
+/** Structure of a partition table entry */
+typedef struct {
+	uint8_t status;
+	/** CHS of fist block in partition */
+	uint8_t first_chs[3];
+	/** Partition type */
+	uint8_t ptype;
+	/** CHS of last block in partition */
+	uint8_t last_chs[3];
+	/** LBA of first block in partition */
+	uint32_t first_lba;
+	/** Number of blocks in partition */
+	uint32_t length;
+} __attribute__((packed)) pt_entry_t;
+
+/** Structure of a boot-record block */
+typedef struct {
+	/** Area for boot code */
+	uint8_t code_area[440];
+	/** Optional media ID */
+	uint32_t media_id;
+	/** Padding */
+	uint16_t pad0;
+	/** Partition table entries */
+	pt_entry_t pte[N_PRIMARY];
+	/** Boot record block signature (@c BR_SIGNATURE) */
+	uint16_t signature;
+} __attribute__((packed)) br_block_t;
+
+#endif
+
Index: uspace/lib/nic/Makefile
===================================================================
--- uspace/lib/nic/Makefile	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/nic/Makefile	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -30,4 +30,5 @@
 LIBRARY = libnic
 EXTRA_CFLAGS += -DLIBNIC_INTERNAL -Iinclude -I$(LIBDRV_PREFIX)/include
+LIBS = $(LIBDRV_PREFIX)/libdrv.a
 
 SOURCES = \
Index: uspace/lib/nic/src/nic_ev.c
===================================================================
--- uspace/lib/nic/src/nic_ev.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/nic/src/nic_ev.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -37,5 +37,5 @@
 
 #include <async.h>
-#include <device/nic.h>
+#include <nic_iface.h>
 #include <errno.h>
 #include "nic_ev.h"
Index: uspace/lib/posix/Makefile
===================================================================
--- uspace/lib/posix/Makefile	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/posix/Makefile	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -60,5 +60,4 @@
 	source/getopt.c \
 	source/locale.c \
-	source/math.c \
 	source/pthread/condvar.c \
 	source/pthread/keys.c \
Index: uspace/lib/posix/include/posix/float.h
===================================================================
--- uspace/lib/posix/include/posix/float.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/posix/include/posix/float.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -59,4 +59,6 @@
 	#undef DBL_EPSILON
 	#define DBL_EPSILON __DBL_EPSILON__
+	#undef LDBL_EPSILON
+	#define LDBL_EPSILON __LDBL_EPSILON__
 	#undef FLT_RADIX
 	#define FLT_RADIX __FLT_RADIX__
@@ -69,4 +71,8 @@
 	#undef FLT_MANT_DIG
 	#define FLT_MANT_DIG __FLT_MANT_DIG__
+	#undef LDBL_MIN
+	#define LDBL_MIN __LDBL_MIN__
+	#undef LDBL_MAX
+	#define LDBL_MAX __LDBL_MAX__
 	#undef LDBL_MANT_DIG 
 	#define LDBL_MANT_DIG __LDBL_MANT_DIG__
Index: uspace/lib/posix/include/posix/math.h
===================================================================
--- uspace/lib/posix/include/posix/math.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/posix/include/posix/math.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -36,27 +36,5 @@
 #define POSIX_MATH_H_
 
-#ifndef __POSIX_DEF__
-#define __POSIX_DEF__(x) x
-#endif
-
-#ifdef __GNUC__
-	#define HUGE_VAL (__builtin_huge_val())
-#endif
-
-/* Normalization Functions */
-extern double __POSIX_DEF__(ldexp)(double x, int exp);
-extern double __POSIX_DEF__(frexp)(double num, int *exp);
-
-double __POSIX_DEF__(fabs)(double x);
-double __POSIX_DEF__(floor)(double x);
-double __POSIX_DEF__(modf)(double x, double *iptr);
-double __POSIX_DEF__(fmod)(double x, double y);
-double __POSIX_DEF__(pow)(double x, double y);
-double __POSIX_DEF__(exp)(double x);
-double __POSIX_DEF__(sqrt)(double x);
-double __POSIX_DEF__(log)(double x);
-double __POSIX_DEF__(sin)(double x);
-double __POSIX_DEF__(cos)(double x);
-double __POSIX_DEF__(atan2)(double y, double x);
+#include "libc/math.h"
 
 #endif /* POSIX_MATH_H_ */
Index: uspace/lib/posix/include/posix/setjmp.h
===================================================================
--- uspace/lib/posix/include/posix/setjmp.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/posix/include/posix/setjmp.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2013 Vojtech Horky
+ * 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 libposix
+ * @{
+ */
+
+/*
+ * Just a pass-through to libc setjmp.
+ */
+#include "libc/setjmp.h"
+
+/** @}
+ */
Index: uspace/lib/posix/include/posix/stdlib.h
===================================================================
--- uspace/lib/posix/include/posix/stdlib.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/posix/include/posix/stdlib.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -56,5 +56,5 @@
 #define _Exit exit
 extern int __POSIX_DEF__(atexit)(void (*func)(void));
-extern void exit(int status);
+extern void exit(int status) __attribute__((noreturn));
 extern void abort(void) __attribute__((noreturn));
 
Index: pace/lib/posix/source/math.c
===================================================================
--- uspace/lib/posix/source/math.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,204 +1,0 @@
-/*
- * Copyright (c) 2011 Petr Koupy
- * 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 libposix
- * @{
- */
-/** @file Mathematical operations.
- */
-
-#define LIBPOSIX_INTERNAL
-#define __POSIX_DEF__(x) posix_##x
-
-#include "internal/common.h"
-#include "posix/math.h"
-
-/**
- * 
- * @param x
- * @param exp
- * @return
- */
-double posix_ldexp(double x, int exp)
-{
-	// TODO: low priority, just a compile-time dependency of binutils
-	not_implemented();
-	return 0.0;
-}
-
-/**
- * 
- * @param num
- * @param exp
- * @return
- */
-double posix_frexp(double num, int *exp)
-{
-	// TODO: low priority, just a compile-time dependency of binutils
-	not_implemented();
-	return 0.0;
-}
-
-/**
- * 
- * @param x
- * @return
- */
-double posix_cos(double x)
-{
-	// TODO: Python dependency
-	not_implemented();
-	return 0.0;
-}
-
-/**
- * 
- * @param x
- * @param y
- * @return
- */
-double posix_pow(double x, double y)
-{
-	// TODO: Python dependency
-	not_implemented();
-	return 0.0;
-}
-
-/**
- * 
- * @param x
- * @return
- */
-double posix_floor(double x)
-{
-	// TODO: Python dependency
-	not_implemented();
-	return 0.0;
-}
-
-/**
- * 
- * @param x
- * @return
- */
-double posix_fabs(double x)
-{
-	// TODO: Python dependency
-	not_implemented();
-	return 0.0;
-}
-
-/**
- * 
- * @param x
- * @param iptr
- * @return
- */
-double posix_modf(double x, double *iptr)
-{
-	// TODO: Python dependency
-	not_implemented();
-	return 0.0;
-}
-
-/**
- * 
- * @param x
- * @param y
- * @return
- */
-double posix_fmod(double x, double y)
-{
-	// TODO: Python dependency
-	not_implemented();
-	return 0.0;
-}
-
-/**
- * 
- * @param x
- * @return
- */
-double posix_log(double x)
-{
-	// TODO: Python dependency
-	not_implemented();
-	return 0.0;
-}
-
-/**
- * 
- * @param x
- * @param y
- * @return
- */
-double posix_atan2(double y, double x)
-{
-	// TODO: Python dependency
-	not_implemented();
-	return 0.0;
-}
-
-/**
- * 
- * @param x
- * @return
- */
-double posix_sin(double x)
-{
-	// TODO: Python dependency
-	not_implemented();
-	return 0.0;
-}
-
-/**
- * 
- * @param x
- * @return
- */
-double posix_exp(double x)
-{
-	// TODO: Python dependency
-	not_implemented();
-	return 0.0;
-}
-
-/**
- * 
- * @param x
- * @return
- */
-double posix_sqrt(double x)
-{
-	// TODO: Python dependency
-	not_implemented();
-	return 0.0;
-}
-
-/** @}
- */
Index: uspace/lib/softfloat/softfloat.c
===================================================================
--- uspace/lib/softfloat/softfloat.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/softfloat/softfloat.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -1265,4 +1265,15 @@
 }
 
+float __aeabi_d2f(double a)
+{
+	return __truncdfsf2(a);
+}
+
+double __aeabi_f2d(float a)
+{
+	return __extendsfdf2(a);
+}
+
+
 float __aeabi_i2f(int i)
 {
@@ -1285,4 +1296,19 @@
 }
 
+double __aeabi_l2d(long long i)
+{
+	return __floattidf(i);
+}
+
+float __aeabi_l2f(long long i)
+{
+	return __floattisf(i);
+}
+
+float __aeabi_ul2f(unsigned long long u)
+{
+	return __floatuntisf(u);
+}
+
 int __aeabi_f2iz(float a)
 {
@@ -1305,4 +1331,9 @@
 }
 
+long long __aeabi_d2lz(double a)
+{
+	return __fixdfti(a);
+}
+
 int __aeabi_fcmpge(float a, float b)
 {
@@ -1339,4 +1370,10 @@
 	return __ltdf2(a, b);
 }
+
+int __aeabi_dcmple(double a, double b)
+{
+	return __ledf2(a, b);
+}
+
 
 int __aeabi_dcmpeq(double a, double b)
Index: uspace/lib/softfloat/softfloat.h
===================================================================
--- uspace/lib/softfloat/softfloat.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/softfloat/softfloat.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -204,9 +204,15 @@
 
 /* ARM EABI */
+extern float __aeabi_d2f(double);
+extern double __aeabi_f2d(float);
 extern float __aeabi_i2f(int);
 extern float __aeabi_ui2f(int);
 extern double __aeabi_i2d(int);
 extern double __aeabi_ui2d(unsigned int);
+extern double __aeabi_l2d(long long);
+extern float __aeabi_l2f(long long);
+extern float __aeabi_ul2f(unsigned long long);
 extern unsigned int __aeabi_d2uiz(double);
+extern long long __aeabi_d2lz(double);
 
 extern int __aeabi_f2iz(float);
@@ -222,4 +228,5 @@
 extern int __aeabi_dcmpgt(double, double);
 extern int __aeabi_dcmplt(double, double);
+extern int __aeabi_dcmple(double, double);
 extern int __aeabi_dcmpeq(double, double);
 
Index: uspace/lib/softint/Makefile
===================================================================
--- uspace/lib/softint/Makefile	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/softint/Makefile	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -35,4 +35,5 @@
 
 SOURCES = \
+	generic/bits.c \
 	generic/comparison.c \
 	generic/division.c \
Index: uspace/lib/softint/generic/bits.c
===================================================================
--- uspace/lib/softint/generic/bits.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/softint/generic/bits.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2013 Vojtech Horky
+ * 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 softint
+ * @{
+ */
+
+#include <bits.h>
+
+/** Compute number of trailing 0-bits in a number. */
+int __ctzdi2(long a)
+{
+	unsigned int bits = 0;
+	while (((a >> bits) & 1) == 0) {
+		bits++;
+		if (bits >= sizeof(a) * 8) {
+			break;
+		}
+	}
+
+	return bits;
+}
+
+/** Compute number of trailing 0-bits in a number. */
+int __ctzsi2(int a)
+{
+	unsigned int bits = 0;
+	while (((a >> bits) & 1) == 0) {
+		bits++;
+		if (bits >= sizeof(a) * 8) {
+			break;
+		}
+	}
+
+	return bits;
+}
+
+/** Compute number of leading 0-bits in a number. */
+int __clzdi2(long a)
+{
+	int index = sizeof(a) * 8 - 1;
+	int bits = 0;
+	while (index >= 0) {
+		if (((a >> index) & 1) == 0) {
+			bits++;
+		} else {
+			break;
+		}
+		index--;
+	}
+
+	return bits;
+}
+
+/** Compute index of the first 1-bit in a number increased by one.
+ *
+ * If the number is zero, zero is returned.
+ */
+int __ffsdi2(long a) {
+	if (a == 0) {
+		return 0;
+	}
+
+	return 1 + __ctzdi2(a);
+}
+
+/** Compute number of set bits in a number. */
+int __popcountsi2(int a)
+{
+	int bits = 0;
+	for (unsigned int i = 0; i < sizeof(a) * 8; i++)	 {
+		if (((a >> i) & 1) != 0) {
+			bits++;
+		}
+	}
+	return bits;									
+}
+
+/** Compute number of set bits in a number. */
+int __popcountdi2(long a)
+{
+	int bits = 0;
+	for (unsigned int i = 0; i < sizeof(a) * 8; i++)	 {
+		if (((a >> i) & 1) != 0) {
+			bits++;
+		}
+	}
+	return bits;									
+}
+
+/** @}
+ */
Index: uspace/lib/softint/generic/shift.c
===================================================================
--- uspace/lib/softint/generic/shift.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/softint/generic/shift.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -123,4 +123,9 @@
 }
 
+long long __aeabi_llsl(long long val, int shift)
+{
+	return __ashldi3(val, shift);
+}
+
 /** @}
  */
Index: uspace/lib/softint/include/bits.h
===================================================================
--- uspace/lib/softint/include/bits.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/lib/softint/include/bits.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2013 Vojtech Horky
+ * 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 softint
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __SOFTINT_BITS_H_
+#define __SOFTINT_BITS_H_
+
+extern int __ctzdi2(long);
+extern int __ctzsi2(int);
+extern int __clzdi2(long);
+extern int __ffsdi2(long);
+extern int __popcountsi2(int);
+extern int __popcountdi2(long);
+
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/softint/include/shift.h
===================================================================
--- uspace/lib/softint/include/shift.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/softint/include/shift.h	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -46,4 +46,8 @@
 extern long long __lshrdi3(long long, int);
 
+
+/* ARM EABI */
+extern long long __aeabi_llsl(long long, int);
+
 #endif
 
Index: uspace/lib/usbhid/Makefile
===================================================================
--- uspace/lib/usbhid/Makefile	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/lib/usbhid/Makefile	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -37,5 +37,4 @@
 SOURCES = \
 	src/hiddescriptor.c \
-	src/hidiface.c \
 	src/hidparser.c \
 	src/hidpath.c \
Index: pace/lib/usbhid/include/usb/hid/iface.h
===================================================================
--- uspace/lib/usbhid/include/usb/hid/iface.h	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,51 +1,0 @@
-/*
- * Copyright (c) 2011 Vojtech Horky
- * 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 libusbhid
- * @{
- */
-/** @file
- * Client functions for accessing USB HID interface.
- */
-#ifndef LIBUSBHID_CLASSES_HID_IFACE_H_
-#define LIBUSBHID_CLASSES_HID_IFACE_H_
-
-#include <sys/types.h>
-#include <async.h>
-
-extern int usbhid_dev_get_event_length(async_sess_t *, size_t *);
-extern int usbhid_dev_get_event(async_sess_t *, uint8_t *, size_t, size_t *,
-    int *, unsigned int);
-extern int usbhid_dev_get_report_descriptor_length(async_sess_t *, size_t *);
-extern int usbhid_dev_get_report_descriptor(async_sess_t *, uint8_t *, size_t,
-    size_t *);
-
-#endif
-/**
- * @}
- */
Index: pace/lib/usbhid/src/hidiface.c
===================================================================
--- uspace/lib/usbhid/src/hidiface.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ 	(revision )
@@ -1,239 +1,0 @@
-/*
- * Copyright (c) 2011 Vojtech Horky
- * 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 libusbhid
- * @{
- */
-/** @file
- * Client functions for accessing USB HID interface (implementation).
- */
-
-#include <dev_iface.h>
-#include <usbhid_iface.h>
-#include <usb/hid/iface.h>
-#include <errno.h>
-#include <str_error.h>
-#include <async.h>
-#include <assert.h>
-
-/** Ask for event array length.
- *
- * @param dev_sess Session to DDF device providing USB HID interface.
- *
- * @return Number of usages returned or negative error code.
- *
- */
-int usbhid_dev_get_event_length(async_sess_t *dev_sess, size_t *size)
-{
-	if (!dev_sess)
-		return EINVAL;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	sysarg_t len;
-	int rc = async_req_1_1(exch, DEV_IFACE_ID(USBHID_DEV_IFACE),
-	    IPC_M_USBHID_GET_EVENT_LENGTH, &len);
-	
-	async_exchange_end(exch);
-	
-	if (rc == EOK) {
-		if (size != NULL)
-			*size = (size_t) len;
-	}
-	
-	return rc;
-}
-
-/** Request for next event from HID device.
- *
- * @param[in]  dev_sess    Session to DDF device providing USB HID interface.
- * @param[out] usage_pages Where to store usage pages.
- * @param[out] usages      Where to store usages (actual data).
- * @param[in]  usage_count Length of @p usage_pages and @p usages buffer
- *                         (in items, not bytes).
- * @param[out] actual_usage_count Number of usages actually returned by the
- *                                device driver.
- * @param[in] flags        Flags (see USBHID_IFACE_FLAG_*).
- *
- * @return Error code.
- *
- */
-int usbhid_dev_get_event(async_sess_t *dev_sess, uint8_t *buf,
-    size_t size, size_t *actual_size, int *event_nr, unsigned int flags)
-{
-	if (!dev_sess)
-		return EINVAL;
-	
-	if (buf == NULL)
-		return ENOMEM;
-	
-	if (size == 0)
-		return EINVAL;
-	
-	size_t buffer_size =  size;
-	uint8_t *buffer = malloc(buffer_size);
-	if (buffer == NULL)
-		return ENOMEM;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	ipc_call_t opening_request_call;
-	aid_t opening_request = async_send_2(exch,
-	    DEV_IFACE_ID(USBHID_DEV_IFACE), IPC_M_USBHID_GET_EVENT,
-	    flags, &opening_request_call);
-	
-	if (opening_request == 0) {
-		async_exchange_end(exch);
-		free(buffer);
-		return ENOMEM;
-	}
-	
-	ipc_call_t data_request_call;
-	aid_t data_request = async_data_read(exch, buffer, buffer_size,
-	    &data_request_call);
-	
-	async_exchange_end(exch);
-	
-	if (data_request == 0) {
-		async_forget(opening_request);
-		free(buffer);
-		return ENOMEM;
-	}
-	
-	sysarg_t data_request_rc;
-	sysarg_t opening_request_rc;
-	async_wait_for(data_request, &data_request_rc);
-	async_wait_for(opening_request, &opening_request_rc);
-	
-	if (data_request_rc != EOK) {
-		/* Prefer return code of the opening request. */
-		if (opening_request_rc != EOK)
-			return (int) opening_request_rc;
-		else
-			return (int) data_request_rc;
-	}
-	
-	if (opening_request_rc != EOK)
-		return (int) opening_request_rc;
-	
-	size_t act_size = IPC_GET_ARG2(data_request_call);
-	
-	/* Copy the individual items. */
-	memcpy(buf, buffer, act_size);
-	
-	if (actual_size != NULL)
-		*actual_size = act_size;
-	
-	if (event_nr != NULL)
-		*event_nr = IPC_GET_ARG1(opening_request_call);
-	
-	return EOK;
-}
-
-int usbhid_dev_get_report_descriptor_length(async_sess_t *dev_sess,
-    size_t *size)
-{
-	if (!dev_sess)
-		return EINVAL;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	sysarg_t arg_size;
-	int rc = async_req_1_1(exch, DEV_IFACE_ID(USBHID_DEV_IFACE),
-	    IPC_M_USBHID_GET_REPORT_DESCRIPTOR_LENGTH, &arg_size);
-	
-	async_exchange_end(exch);
-	
-	if (rc == EOK) {
-		if (size != NULL)
-			*size = (size_t) arg_size;
-	}
-	
-	return rc;
-}
-
-int usbhid_dev_get_report_descriptor(async_sess_t *dev_sess, uint8_t *buf,
-    size_t size, size_t *actual_size)
-{
-	if (!dev_sess)
-		return EINVAL;
-	
-	if (buf == NULL)
-		return ENOMEM;
-	
-	if (size == 0)
-		return EINVAL;
-	
-	async_exch_t *exch = async_exchange_begin(dev_sess);
-	
-	aid_t opening_request = async_send_1(exch,
-	    DEV_IFACE_ID(USBHID_DEV_IFACE), IPC_M_USBHID_GET_REPORT_DESCRIPTOR,
-	    NULL);
-	if (opening_request == 0) {
-		async_exchange_end(exch);
-		return ENOMEM;
-	}
-	
-	ipc_call_t data_request_call;
-	aid_t data_request = async_data_read(exch, buf, size,
-	    &data_request_call);
-	
-	async_exchange_end(exch);
-	
-	if (data_request == 0) {
-		async_forget(opening_request);
-		return ENOMEM;
-	}
-	
-	sysarg_t data_request_rc;
-	sysarg_t opening_request_rc;
-	async_wait_for(data_request, &data_request_rc);
-	async_wait_for(opening_request, &opening_request_rc);
-	
-	if (data_request_rc != EOK) {
-		/* Prefer return code of the opening request. */
-		if (opening_request_rc != EOK)
-			return (int) opening_request_rc;
-		else
-			return (int) data_request_rc;
-	}
-	
-	if (opening_request_rc != EOK)
-		return (int) opening_request_rc;
-	
-	size_t act_size = IPC_GET_ARG2(data_request_call);
-	
-	if (actual_size != NULL)
-		*actual_size = act_size;
-	
-	return EOK;
-}
-
-/**
- * @}
- */
Index: uspace/srv/bd/sata_bd/Makefile
===================================================================
--- uspace/srv/bd/sata_bd/Makefile	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/srv/bd/sata_bd/Makefile	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -29,4 +29,6 @@
 USPACE_PREFIX = ../../..
 BINARY = sata_bd
+EXTRA_CFLAGS = -I$(LIBDRV_PREFIX)/include
+LIBS = $(LIBDRV_PREFIX)/libdrv.a
 
 SOURCES = \
Index: uspace/srv/bd/sata_bd/sata_bd.c
===================================================================
--- uspace/srv/bd/sata_bd/sata_bd.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/srv/bd/sata_bd/sata_bd.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -39,4 +39,5 @@
 #include <sys/types.h>
 #include <bd_srv.h>
+#include <devman.h>
 #include <errno.h>
 #include <stdio.h>
@@ -45,5 +46,5 @@
 #include <macros.h>
 
-#include <device/ahci.h>
+#include <ahci_iface.h>
 #include "sata_bd.h"
 
Index: uspace/srv/hid/compositor/Makefile
===================================================================
--- uspace/srv/hid/compositor/Makefile	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/srv/hid/compositor/Makefile	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -28,21 +28,19 @@
 
 USPACE_PREFIX = ../../..
-LIBS = $(LIBDRAW_PREFIX)/libdraw.a $(LIBSOFTREND_PREFIX)/libsoftrend.a \
-	$(LIBSOFTFLOAT_PREFIX)/libsoftfloat.a
-EXTRA_CFLAGS += -I$(LIBDRAW_PREFIX) -I$(LIBSOFTREND_PREFIX)
+LIBS = \
+	$(LIBDRAW_PREFIX)/libdraw.a \
+	$(LIBSOFTREND_PREFIX)/libsoftrend.a \
+	$(LIBSOFTFLOAT_PREFIX)/libsoftfloat.a \
+	$(LIBDRV_PREFIX)/libdrv.a
+
+EXTRA_CFLAGS += \
+	-I$(LIBDRAW_PREFIX) \
+	-I$(LIBSOFTREND_PREFIX) \
+	-I$(LIBDRV_PREFIX)/include
+
 BINARY = compositor
 
 SOURCES = \
-	compositor.c \
-	images.c
-
-IMAGES = \
-	gfx/nameic.tga
-
-PRE_DEPEND = images.c images.h
-EXTRA_CLEAN = images.c images.h
+	compositor.c
 
 include $(USPACE_PREFIX)/Makefile.common
-
-images.c images.h: $(IMAGES)
-	$(ROOT_PATH)/tools/mkarray.py images COMPOSITOR_IMAGES $^
Index: uspace/srv/hid/compositor/compositor.c
===================================================================
--- uspace/srv/hid/compositor/compositor.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/srv/hid/compositor/compositor.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -58,5 +58,5 @@
 
 #include <event.h>
-#include <device/graph_dev.h>
+#include <graph_iface.h>
 #include <io/keycode.h>
 #include <io/mode.h>
@@ -72,5 +72,4 @@
 #include <codec/tga.h>
 
-#include "images.h"
 #include "compositor.h"
 
@@ -162,5 +161,4 @@
 static void input_disconnect(void);
 
-
 static pointer_t *input_pointer(input_t *input)
 {
@@ -168,11 +166,10 @@
 }
 
-static pointer_t *pointer_create()
+static pointer_t *pointer_create(void)
 {
 	pointer_t *p = (pointer_t *) malloc(sizeof(pointer_t));
-	if (!p) {
+	if (!p)
 		return NULL;
-	}
-
+	
 	link_initialize(&p->link);
 	p->pos.x = coord_origin;
@@ -186,5 +183,5 @@
 	p->state = 0;
 	cursor_init(&p->cursor, CURSOR_DECODER_EMBEDDED, NULL);
-
+	
 	/* Ghost window for transformation animation. */
 	transform_identity(&p->ghost.transform);
@@ -199,5 +196,5 @@
 	p->accum_ghost.x = 0;
 	p->accum_ghost.y = 0;
-
+	
 	return p;
 }
@@ -211,19 +208,17 @@
 }
 
-static window_t *window_create(sysarg_t x_offset, sysarg_t y_offset)
+static window_t *window_create(void)
 {
 	window_t *win = (window_t *) malloc(sizeof(window_t));
-	if (!win) {
+	if (!win)
 		return NULL;
-	}
-
+	
 	link_initialize(&win->link);
 	atomic_set(&win->ref_cnt, 0);
 	prodcons_initialize(&win->queue);
 	transform_identity(&win->transform);
-	transform_translate(&win->transform, 
-	    coord_origin + x_offset, coord_origin + y_offset);
-	win->dx = coord_origin + x_offset;
-	win->dy = coord_origin + y_offset;
+	transform_translate(&win->transform, coord_origin, coord_origin);
+	win->dx = coord_origin;
+	win->dy = coord_origin;
 	win->fx = 1;
 	win->fy = 1;
@@ -231,5 +226,5 @@
 	win->opacity = 255;
 	win->surface = NULL;
-
+	
 	return win;
 }
@@ -294,16 +289,19 @@
     sysarg_t *x_out, sysarg_t *y_out, sysarg_t *w_out, sysarg_t *h_out)
 {
-	if (w_in > 0 && h_in > 0) {
+	if ((w_in > 0) && (h_in > 0)) {
 		sysarg_t x[4];
 		sysarg_t y[4];
+		
 		comp_coord_from_client(x_in, y_in, win_trans, &x[0], &y[0]);
 		comp_coord_from_client(x_in + w_in - 1, y_in, win_trans, &x[1], &y[1]);
 		comp_coord_from_client(x_in + w_in - 1, y_in + h_in - 1, win_trans, &x[2], &y[2]);
 		comp_coord_from_client(x_in, y_in + h_in - 1, win_trans, &x[3], &y[3]);
+		
 		(*x_out) = x[0];
 		(*y_out) = y[0];
 		(*w_out) = x[0];
 		(*h_out) = y[0];
-		for (int i = 1; i < 4; ++i) {
+		
+		for (unsigned int i = 1; i < 4; ++i) {
 			(*x_out) = (x[i] < (*x_out)) ? x[i] : (*x_out);
 			(*y_out) = (y[i] < (*y_out)) ? y[i] : (*y_out);
@@ -311,4 +309,5 @@
 			(*h_out) = (y[i] > (*h_out)) ? y[i] : (*h_out);
 		}
+		
 		(*w_out) = (*w_out) - (*x_out) + 1;
 		(*h_out) = (*h_out) - (*y_out) + 1;
@@ -321,13 +320,13 @@
 }
 
-static void comp_restrict_pointers(void)
+static void comp_update_viewport_bound_rect(void)
 {
 	fibril_mutex_lock(&viewport_list_mtx);
-
+	
 	sysarg_t x_res = coord_origin;
 	sysarg_t y_res = coord_origin;
 	sysarg_t w_res = 0;
 	sysarg_t h_res = 0;
-
+	
 	if (!list_empty(&viewport_list)) {
 		viewport_t *vp = (viewport_t *) list_first(&viewport_list);
@@ -336,23 +335,27 @@
 		surface_get_resolution(vp->surface, &w_res, &h_res);
 	}
-
+	
 	list_foreach(viewport_list, link, viewport_t, vp) {
 		sysarg_t w_vp, h_vp;
 		surface_get_resolution(vp->surface, &w_vp, &h_vp);
-		rectangle_union(
-		    x_res, y_res, w_res, h_res,
+		rectangle_union(x_res, y_res, w_res, h_res,
 		    vp->pos.x, vp->pos.y, w_vp, h_vp,
 		    &x_res, &y_res, &w_res, &h_res);
 	}
-
+	
 	viewport_bound_rect.x = x_res;
 	viewport_bound_rect.y = y_res;
 	viewport_bound_rect.w = w_res;
 	viewport_bound_rect.h = h_res;
-
+	
 	fibril_mutex_unlock(&viewport_list_mtx);
-
+}
+
+static void comp_restrict_pointers(void)
+{
+	comp_update_viewport_bound_rect();
+	
 	fibril_mutex_lock(&pointer_list_mtx);
-
+	
 	list_foreach(pointer_list, link, pointer_t, ptr) {
 		ptr->pos.x = ptr->pos.x > viewport_bound_rect.x ? ptr->pos.x : viewport_bound_rect.x;
@@ -363,5 +366,5 @@
 		    ptr->pos.y : viewport_bound_rect.y + viewport_bound_rect.h;
 	}
-
+	
 	fibril_mutex_unlock(&pointer_list_mtx);
 }
@@ -642,12 +645,39 @@
 }
 
+static void comp_recalc_transform(window_t *win)
+{
+	transform_t translate;
+	transform_identity(&translate);
+	transform_translate(&translate, win->dx, win->dy);
+	
+	transform_t scale;
+	transform_identity(&scale);
+	if ((win->fx != 1) || (win->fy != 1))
+		transform_scale(&scale, win->fx, win->fy);
+	
+	transform_t rotate;
+	transform_identity(&rotate);
+	if (win->angle != 0)
+		transform_rotate(&rotate, win->angle);
+	
+	transform_t transform;
+	transform_t temp;
+	transform_identity(&transform);
+	temp = transform;
+	transform_multiply(&transform, &temp, &translate);
+	temp = transform;
+	transform_multiply(&transform, &temp, &rotate);
+	temp = transform;
+	transform_multiply(&transform, &temp, &scale);
+	
+	win->transform = transform;
+}
+
 static void comp_window_resize(window_t *win, ipc_callid_t iid, ipc_call_t *icall)
 {
-	int rc;
-
 	ipc_callid_t callid;
 	size_t size;
 	unsigned int flags;
-
+	
 	/* Start sharing resized window with client. */
 	if (!async_share_out_receive(&callid, &size, &flags)) {
@@ -655,15 +685,15 @@
 		return;
 	}
+	
 	void *new_cell_storage;
-	rc = async_share_out_finalize(callid, &new_cell_storage);
+	int rc = async_share_out_finalize(callid, &new_cell_storage);
 	if ((rc != EOK) || (new_cell_storage == AS_MAP_FAILED)) {
 		async_answer_0(iid, ENOMEM);
 		return;
 	}
-
+	
 	/* Create new surface for the resized window. */
-	surface_t *new_surface = surface_create(
-	    IPC_GET_ARG1(*icall), IPC_GET_ARG2(*icall),
-	    new_cell_storage, SURFACE_FLAG_SHARED);
+	surface_t *new_surface = surface_create(IPC_GET_ARG3(*icall),
+	    IPC_GET_ARG4(*icall), new_cell_storage, SURFACE_FLAG_SHARED);
 	if (!new_surface) {
 		as_area_destroy(new_cell_storage);
@@ -671,30 +701,88 @@
 		return;
 	}
-
+	
+	sysarg_t offset_x = IPC_GET_ARG1(*icall);
+	sysarg_t offset_y = IPC_GET_ARG2(*icall);
+	window_placement_flags_t placement_flags =
+	    (window_placement_flags_t) IPC_GET_ARG5(*icall);
+	
+	comp_update_viewport_bound_rect();
+	
 	/* Switch new surface with old surface and calculate damage. */
 	fibril_mutex_lock(&window_list_mtx);
-
+	
 	sysarg_t old_width = 0;
 	sysarg_t old_height = 0;
+	
 	if (win->surface) {
 		surface_get_resolution(win->surface, &old_width, &old_height);
 		surface_destroy(win->surface);
 	}
-
+	
 	win->surface = new_surface;
-
+	
 	sysarg_t new_width = 0;
 	sysarg_t new_height = 0;
 	surface_get_resolution(win->surface, &new_width, &new_height);
-
-	sysarg_t x, y;
-	sysarg_t width = old_width > new_width ? old_width : new_width;
-	sysarg_t height = old_height > new_height ? old_height : new_height;
-	comp_coord_bounding_rect(0, 0, width, height, win->transform, &x, &y, &width, &height);
-
+	
+	if (placement_flags & WINDOW_PLACEMENT_CENTER_X)
+		win->dx = viewport_bound_rect.x + viewport_bound_rect.w / 2 -
+		    new_width / 2;
+	
+	if (placement_flags & WINDOW_PLACEMENT_CENTER_Y)
+		win->dy = viewport_bound_rect.y + viewport_bound_rect.h / 2 -
+		    new_height / 2;
+	
+	if (placement_flags & WINDOW_PLACEMENT_LEFT)
+		win->dx = viewport_bound_rect.x;
+	
+	if (placement_flags & WINDOW_PLACEMENT_TOP)
+		win->dy = viewport_bound_rect.y;
+	
+	if (placement_flags & WINDOW_PLACEMENT_RIGHT)
+		win->dx = viewport_bound_rect.x + viewport_bound_rect.w -
+		    new_width;
+	
+	if (placement_flags & WINDOW_PLACEMENT_BOTTOM)
+		win->dy = viewport_bound_rect.y + viewport_bound_rect.h -
+		    new_height;
+	
+	if (placement_flags & WINDOW_PLACEMENT_ABSOLUTE_X)
+		win->dx = coord_origin + offset_x;
+	
+	if (placement_flags & WINDOW_PLACEMENT_ABSOLUTE_Y)
+		win->dy = coord_origin + offset_y;
+	
+	/* Transform the window and calculate damage. */
+	sysarg_t x1;
+	sysarg_t y1;
+	sysarg_t width1;
+	sysarg_t height1;
+	
+	comp_coord_bounding_rect(0, 0, old_width, old_height, win->transform,
+	    &x1, &y1, &width1, &height1);
+	
+	comp_recalc_transform(win);
+	
+	sysarg_t x2;
+	sysarg_t y2;
+	sysarg_t width2;
+	sysarg_t height2;
+	
+	comp_coord_bounding_rect(0, 0, new_width, new_height, win->transform,
+	    &x2, &y2, &width2, &height2);
+	
+	sysarg_t x;
+	sysarg_t y;
+	sysarg_t width;
+	sysarg_t height;
+	
+	rectangle_union(x1, y1, width1, height1, x2, y2, width2, height2,
+	    &x, &y, &width, &height);
+	
 	fibril_mutex_unlock(&window_list_mtx);
-
+	
 	comp_damage(x, y, width, height);
-
+	
 	async_answer_0(iid, EOK);
 }
@@ -703,5 +791,5 @@
 {
 	fibril_mutex_lock(&window_list_mtx);
-
+	
 	list_foreach(window_list, link, window_t, window) {
 		if (window == target) {
@@ -711,5 +799,5 @@
 		}
 	}
-
+	
 	fibril_mutex_unlock(&window_list_mtx);
 	free(event);
@@ -719,10 +807,11 @@
 {
 	fibril_mutex_lock(&window_list_mtx);
+	
 	window_t *win = (window_t *) list_first(&window_list);
-	if (win) {
+	if (win)
 		prodcons_produce(&win->queue, &event->link);
-	} else {
+	else
 		free(event);
-	}
+	
 	fibril_mutex_unlock(&window_list_mtx);
 }
@@ -801,5 +890,5 @@
 			fibril_mutex_lock(&window_list_mtx);
 
-			window_t *win = window_create(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
+			window_t *win = window_create();
 			if (!win) {
 				async_answer_2(callid, ENOMEM, 0, 0);
@@ -1173,36 +1262,4 @@
 }
 
-static void comp_recalc_transform(window_t *win)
-{
-	transform_t translate;
-	transform_identity(&translate);
-	transform_translate(&translate, win->dx, win->dy);
-
-	transform_t scale;
-	transform_identity(&scale);
-	if (win->fx != 1 || win->fy != 1) {
-		transform_scale(&scale, win->fx, win->fy);
-	}
-
-	transform_t rotate;
-	transform_identity(&rotate);
-	if (win->angle != 0) {
-		transform_rotate(&rotate, win->angle);
-	}
-
-	transform_t transform;
-	transform_t temp;
-	transform_identity(&transform);
-	temp = transform;
-	transform_multiply(&transform, &temp, &translate);
-	temp = transform;
-	transform_multiply(&transform, &temp, &rotate);
-	temp = transform;
-	transform_multiply(&transform, &temp, &scale);
-	
-
-	win->transform = transform;
-}
-
 static void comp_window_animate(pointer_t *pointer, window_t *win,
     sysarg_t *dmg_x, sysarg_t *dmg_y, sysarg_t *dmg_width, sysarg_t *dmg_height)
@@ -1226,26 +1283,27 @@
 		double cx = 0;
 		double cy = 0;
-		if (pointer->grab_flags & GF_MOVE_X) {
+		
+		if (pointer->grab_flags & GF_MOVE_X)
 			cx = 1;
-		}
-		if (pointer->grab_flags & GF_MOVE_Y) {
+		
+		if (pointer->grab_flags & GF_MOVE_Y)
 			cy = 1;
-		}
-
-		if ((scale || resize) && (win->angle != 0)) {
+		
+		if (((scale) || (resize)) && (win->angle != 0)) {
 			transform_t rotate;
 			transform_identity(&rotate);
+			
 			transform_rotate(&rotate, win->angle);
 			transform_apply_linear(&rotate, &cx, &cy);
 		}
 		
-		cx = (cx < 0) ? (-1 * cx) : cx; 
+		cx = (cx < 0) ? (-1 * cx) : cx;
 		cy = (cy < 0) ? (-1 * cy) : cy;
-
+		
 		win->dx += (cx * dx);
 		win->dy += (cy * dy);
 	}
 
-	if (scale || resize) {
+	if ((scale) || (resize)) {
 		double _dx = dx;
 		double _dy = dy;
@@ -1263,5 +1321,6 @@
 			if (fx > 0) {
 #if ANIMATE_WINDOW_TRANSFORMS == 0
-				if (scale) win->fx *= fx;
+				if (scale)
+					win->fx *= fx;
 #endif
 #if ANIMATE_WINDOW_TRANSFORMS == 1
@@ -1444,24 +1503,29 @@
 {
 	pointer_t *pointer = input_pointer(input);
-
+	
+	comp_update_viewport_bound_rect();
+	
 	/* Update pointer position. */
 	fibril_mutex_lock(&pointer_list_mtx);
+	
 	desktop_point_t old_pos = pointer->pos;
+	
 	sysarg_t cursor_width;
 	sysarg_t cursor_height;
-	surface_get_resolution(pointer->cursor.states[pointer->state], 
+	surface_get_resolution(pointer->cursor.states[pointer->state],
 	     &cursor_width, &cursor_height);
-	if (pointer->pos.x + dx < viewport_bound_rect.x) {
+	
+	if (pointer->pos.x + dx < viewport_bound_rect.x)
 		dx = -1 * (pointer->pos.x - viewport_bound_rect.x);
-	}
-	if (pointer->pos.y + dy < viewport_bound_rect.y) {
+	
+	if (pointer->pos.y + dy < viewport_bound_rect.y)
 		dy = -1 * (pointer->pos.y - viewport_bound_rect.y);
-	}
-	if (pointer->pos.x + dx > viewport_bound_rect.x + viewport_bound_rect.w) {
+	
+	if (pointer->pos.x + dx > viewport_bound_rect.x + viewport_bound_rect.w)
 		dx = (viewport_bound_rect.x + viewport_bound_rect.w - pointer->pos.x);
-	}
-	if (pointer->pos.y + dy > viewport_bound_rect.y + viewport_bound_rect.h) {
+	
+	if (pointer->pos.y + dy > viewport_bound_rect.y + viewport_bound_rect.h)
 		dy = (viewport_bound_rect.y + viewport_bound_rect.h - pointer->pos.y);
-	}
+	
 	pointer->pos.x += dx;
 	pointer->pos.y += dy;
@@ -1469,5 +1533,5 @@
 	comp_damage(old_pos.x, old_pos.y, cursor_width, cursor_height);
 	comp_damage(old_pos.x + dx, old_pos.y + dy, cursor_width, cursor_height);
-
+	
 	fibril_mutex_lock(&window_list_mtx);
 	fibril_mutex_lock(&pointer_list_mtx);
@@ -1630,5 +1694,5 @@
 
 #if ANIMATE_WINDOW_TRANSFORMS == 0
-		sysarg_t pre_x = 0; 
+		sysarg_t pre_x = 0;
 		sysarg_t pre_y = 0;
 		sysarg_t pre_width = 0;
@@ -1662,21 +1726,25 @@
 				link_initialize(&event_top->link);
 				event_top->type = ET_WINDOW_RESIZE;
-
+				
+				event_top->data.resize.offset_x = 0;
+				event_top->data.resize.offset_y = 0;
+				
 				int dx = (int) (((double) width) * (scale_back_x - 1.0));
 				int dy = (int) (((double) height) * (scale_back_y - 1.0));
-
-				if (pointer->grab_flags & GF_RESIZE_X) {
-					event_top->data.rsz.width =
-						((((int) width) + dx) >= 0) ? (width + dx) : 0;
-				} else {
-					event_top->data.rsz.width = width;
-				}
-
-				if (pointer->grab_flags & GF_RESIZE_Y) {
-					event_top->data.rsz.height =
-						((((int) height) + dy) >= 0) ? (height + dy) : 0;
-				} else {
-					event_top->data.rsz.height = height;
-				}
+				
+				if (pointer->grab_flags & GF_RESIZE_X)
+					event_top->data.resize.width =
+					    ((((int) width) + dx) >= 0) ? (width + dx) : 0;
+				else
+					event_top->data.resize.width = width;
+				
+				if (pointer->grab_flags & GF_RESIZE_Y)
+					event_top->data.resize.height =
+					    ((((int) height) + dy) >= 0) ? (height + dy) : 0;
+				else
+					event_top->data.resize.height = height;
+				
+				event_top->data.resize.placement_flags =
+				    WINDOW_PLACEMENT_ANY;
 			}
 
@@ -1746,9 +1814,8 @@
 	    key == KC_O || key == KC_P);
 	bool kconsole_switch = (mods & KM_ALT) && (key == KC_M);
-	bool compositor_test = (mods & KM_ALT) && (key == KC_H);
 
 	bool filter = (type == KEY_RELEASE) && (win_transform || win_resize ||
 	    win_opacity || win_close || win_switch || viewport_move ||
-	    viewport_change || kconsole_switch || compositor_test);
+	    viewport_change || kconsole_switch);
 
 	if (filter) {
@@ -1816,34 +1883,39 @@
 				return ENOMEM;
 			}
-
+			
 			sysarg_t width, height;
 			surface_get_resolution(win->surface, &width, &height);
-
+			
 			link_initialize(&event->link);
 			event->type = ET_WINDOW_RESIZE;
-
+			
+			event->data.resize.offset_x = 0;
+			event->data.resize.offset_y = 0;
+			
 			switch (key) {
 			case KC_T:
-				event->data.rsz.width = width;
-				event->data.rsz.height = (height >= 20) ? height - 20 : 0;
+				event->data.resize.width = width;
+				event->data.resize.height = (height >= 20) ? height - 20 : 0;
 				break;
 			case KC_G:
-				event->data.rsz.width = width;
-				event->data.rsz.height = height + 20;
+				event->data.resize.width = width;
+				event->data.resize.height = height + 20;
 				break;
 			case KC_B:
-				event->data.rsz.width = (width >= 20) ? width - 20 : 0;;
-				event->data.rsz.height = height;
+				event->data.resize.width = (width >= 20) ? width - 20 : 0;;
+				event->data.resize.height = height;
 				break;
 			case KC_N:
-				event->data.rsz.width = width + 20;
-				event->data.rsz.height = height;
+				event->data.resize.width = width + 20;
+				event->data.resize.height = height;
 				break;
 			default:
-				event->data.rsz.width = 0;
-				event->data.rsz.height = 0;
-				break;
-			}
-
+				event->data.resize.width = 0;
+				event->data.resize.height = 0;
+				break;
+			}
+			
+			event->data.resize.placement_flags = WINDOW_PLACEMENT_ANY;
+			
 			fibril_mutex_unlock(&window_list_mtx);
 			comp_post_event_top(event);
@@ -2014,33 +2086,4 @@
 	} else if (kconsole_switch) {
 		__SYSCALL0(SYS_DEBUG_ACTIVATE_CONSOLE);
-	} else if (compositor_test) {
-		fibril_mutex_lock(&window_list_mtx);
-
-		window_t *red_win = window_create(0, 0);
-		red_win->surface = surface_create(250, 150, NULL, 0);
-		pixel_t red_pix = PIXEL(255, 240, 0, 0);
-		for (sysarg_t y = 0; y <  150; ++y) {
-			for (sysarg_t x = 0; x < 250; ++x) {
-				surface_put_pixel(red_win->surface, x, y, red_pix);
-			}
-		}
-		list_prepend(&red_win->link, &window_list);
-
-		window_t *blue_win = window_create(0, 0);
-		blue_win->surface = surface_create(200, 100, NULL, 0);
-		pixel_t blue_pix = PIXEL(255, 0, 0, 240);
-		for (sysarg_t y = 0; y <  100; ++y) {
-			for (sysarg_t x = 0; x < 200; ++x) {
-				surface_put_pixel(blue_win->surface, x, y, blue_pix);
-			}
-		}
-		list_prepend(&blue_win->link, &window_list);
-		
-		window_t *nameic_win = window_create(0, 0);
-		nameic_win->surface = decode_tga((void *) nameic_tga, nameic_tga_size, 0);
-		list_prepend(&nameic_win->link, &window_list);
-
-		fibril_mutex_unlock(&window_list_mtx);
-		comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
 	} else {
 		window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
Index: uspace/srv/hid/isdv4_tablet/Makefile
===================================================================
--- uspace/srv/hid/isdv4_tablet/Makefile	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/srv/hid/isdv4_tablet/Makefile	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -28,6 +28,6 @@
 
 USPACE_PREFIX = ../../..
-#LIBS = 
-#EXTRA_CFLAGS = 
+LIBS = $(LIBDRV_PREFIX)/libdrv.a
+EXTRA_CFLAGS = -I$(LIBDRV_PREFIX)/include
 BINARY = isdv4_tablet
 
Index: uspace/srv/hid/isdv4_tablet/isdv4.c
===================================================================
--- uspace/srv/hid/isdv4_tablet/isdv4.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/srv/hid/isdv4_tablet/isdv4.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -27,5 +27,5 @@
  */
 
-#include <device/char_dev.h>
+#include <char_dev_iface.h>
 #include <errno.h>
 #include <stdlib.h>
Index: uspace/srv/hid/isdv4_tablet/main.c
===================================================================
--- uspace/srv/hid/isdv4_tablet/main.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/srv/hid/isdv4_tablet/main.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -27,5 +27,5 @@
  */
 
-#include <device/char_dev.h>
+#include <char_dev_iface.h>
 #include <errno.h>
 #include <ipc/serial_ctl.h>
Index: uspace/srv/klog/Makefile
===================================================================
--- uspace/srv/klog/Makefile	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/srv/klog/Makefile	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 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.
+#
+
+USPACE_PREFIX = ../..
+BINARY = klog
+
+SOURCES = \
+	klog.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/srv/klog/klog.c
===================================================================
--- uspace/srv/klog/klog.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
+++ uspace/srv/klog/klog.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 2006 Ondrej Palkovsky
+ * Copyright (c) 2013 Martin Sucha
+ * 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 klog KLog
+ * @brief HelenOS KLog
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <stdio.h>
+#include <async.h>
+#include <as.h>
+#include <ddi.h>
+#include <event.h>
+#include <errno.h>
+#include <str_error.h>
+#include <io/klog.h>
+#include <sysinfo.h>
+#include <malloc.h>
+#include <fibril_synch.h>
+#include <adt/list.h>
+#include <adt/prodcons.h>
+#include <io/log.h>
+#include <io/logctl.h>
+
+#define NAME       "klog"
+
+typedef struct {
+	size_t entry_len;
+	uint32_t serial;
+	uint32_t facility;
+	uint32_t level;
+	char message[0];
+	
+} __attribute__((__packed__)) log_entry_t;
+
+/* Producer/consumer buffers */
+typedef struct {
+	link_t link;
+	size_t size;
+	log_entry_t *data;
+} item_t;
+
+static prodcons_t pc;
+
+/* Pointer to buffer where kernel stores new entries */
+#define BUFFER_SIZE PAGE_SIZE
+static void *buffer;
+
+/* Notification mutex */
+static FIBRIL_MUTEX_INITIALIZE(mtx);
+
+static log_t kernel_ctx;
+static const char *facility_name[] = {
+	"other",
+	"uspace",
+	"arch"
+};
+
+#define facility_len (sizeof(facility_name) / sizeof(const char *))
+static log_t facility_ctx[facility_len];
+
+/** Klog producer
+ *
+ * Copies the log entries to a producer/consumer queue.
+ *
+ * @param length Number of characters to copy.
+ * @param data   Pointer to the kernel klog buffer.
+ *
+ */
+static void producer()
+{
+	int read = klog_read(buffer, BUFFER_SIZE);
+	
+	if (read < 0) {
+		log_msg(LOG_DEFAULT, LVL_ERROR, "klog_read failed, rc = %d",
+		    read);
+		return;
+	}
+	
+	size_t len = read;
+	size_t offset = 0;
+	while (offset < len) {
+		size_t entry_len = *((size_t *) (buffer + offset));
+		
+		if (offset + entry_len > len || entry_len < sizeof(log_entry_t))
+			break;
+		
+		log_entry_t *buf = malloc(entry_len + 1);
+		if (buf == NULL)
+			break;
+		
+		item_t *item = malloc(sizeof(item_t));
+		if (item == NULL) {
+			free(buf);
+			break;
+		}
+		
+		memcpy(buf, buffer + offset, entry_len);
+		*((uint8_t *) buf + entry_len) = 0;
+		link_initialize(&item->link);
+		item->size = entry_len;
+		item->data = buf;
+		prodcons_produce(&pc, &item->link);
+		
+		offset += entry_len;
+	}
+}
+
+/** Klog consumer
+ *
+ * Waits in an infinite loop for the log data created by
+ * the producer and logs them to the logger.
+ *
+ * @param data Unused.
+ *
+ * @return Always EOK (unreachable).
+ *
+ */
+static int consumer(void *data)
+{
+	
+	while (true) {
+		link_t *link = prodcons_consume(&pc);
+		item_t *item = list_get_instance(link, item_t, link);
+		
+		if (item->size < sizeof(log_entry_t)) {
+			free(item->data);
+			free(item);
+			continue;
+		}
+		
+		if (item->data->facility == LF_USPACE) {
+			/* Avoid reposting messages */
+			free(item->data);
+			free(item);
+			continue;
+		}
+		
+		log_t ctx = kernel_ctx;
+		if (item->data->facility < facility_len) {
+			ctx = facility_ctx[item->data->facility];
+		}
+		
+		log_level_t lvl = item->data->level;
+		if (lvl > LVL_LIMIT)
+			lvl = LVL_NOTE;
+		
+		log_msg(ctx, lvl, "%s", item->data->message);
+		
+		free(item->data);
+		free(item);
+	}
+	
+	return EOK;
+}
+
+/** Kernel notification handler
+ *
+ * Receives kernel klog notifications.
+ *
+ * @param callid IPC call ID
+ * @param call   IPC call structure
+ * @param arg    Local argument
+ *
+ */
+static void notification_received(ipc_callid_t callid, ipc_call_t *call)
+{
+	/*
+	 * Make sure we process only a single notification
+	 * at any time to limit the chance of the consumer
+	 * starving.
+	 */
+	
+	fibril_mutex_lock(&mtx);
+	
+	producer();
+	
+	event_unmask(EVENT_KLOG);
+	fibril_mutex_unlock(&mtx);
+}
+
+int main(int argc, char *argv[])
+{
+	int rc = log_init(NAME);
+	if (rc != EOK) {
+		fprintf(stderr, "%s: Unable to initialize log\n", NAME);
+		return rc;
+	}
+	
+	kernel_ctx = log_create("kernel", LOG_NO_PARENT);
+	for (unsigned int i = 0; i < facility_len; i++) {
+		facility_ctx[i] = log_create(facility_name[i], kernel_ctx);
+	}
+	
+	buffer = malloc(BUFFER_SIZE);
+	if (buffer == NULL) {
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Unable to allocate buffer");
+		return 1;
+	}
+	
+	prodcons_initialize(&pc);
+	async_set_interrupt_received(notification_received);
+	rc = event_subscribe(EVENT_KLOG, 0);
+	if (rc != EOK) {
+		log_msg(LOG_DEFAULT, LVL_ERROR,
+		    "Unable to register klog notifications");
+		return rc;
+	}
+	
+	fid_t fid = fibril_create(consumer, NULL);
+	if (!fid) {
+		log_msg(LOG_DEFAULT, LVL_ERROR,
+		    "Unable to create consumer fibril");
+		return ENOMEM;
+	}
+	
+	fibril_add_ready(fid);
+	event_unmask(EVENT_KLOG);
+	
+	fibril_mutex_lock(&mtx);
+	producer();
+	fibril_mutex_unlock(&mtx);
+	
+	task_retval(0);
+	async_manager();
+	
+	return 0;
+}
+
+/** @}
+ */
Index: uspace/srv/logger/writer.c
===================================================================
--- uspace/srv/logger/writer.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/srv/logger/writer.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -40,4 +40,5 @@
 #include <io/log.h>
 #include <io/logctl.h>
+#include <io/klog.h>
 #include <ns.h>
 #include <async.h>
@@ -79,5 +80,5 @@
 	}
 
-	printf("[%s] %s: %s\n",
+	KLOG_PRINTF(level, "[%s] %s: %s\n",
 	    log->full_name, log_level_str(level),
 	    (const char *) message);
Index: uspace/srv/net/ethip/Makefile
===================================================================
--- uspace/srv/net/ethip/Makefile	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/srv/net/ethip/Makefile	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -29,4 +29,6 @@
 USPACE_PREFIX = ../../..
 BINARY = ethip
+EXTRA_CFLAGS = -I$(LIBDRV_PREFIX)/include
+LIBS = $(LIBDRV_PREFIX)/libdrv.a
 
 SOURCES = \
Index: uspace/srv/net/ethip/ethip_nic.c
===================================================================
--- uspace/srv/net/ethip/ethip_nic.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/srv/net/ethip/ethip_nic.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -43,5 +43,5 @@
 #include <io/log.h>
 #include <loc.h>
-#include <device/nic.h>
+#include <nic_iface.h>
 #include <stdlib.h>
 #include <mem.h>
Index: uspace/srv/net/slip/Makefile
===================================================================
--- uspace/srv/net/slip/Makefile	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/srv/net/slip/Makefile	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -29,5 +29,6 @@
 USPACE_PREFIX = ../../..
 BINARY = slip
-
+LIBS = $(LIBDRV_PREFIX)/libdrv.a
+EXTRA_CFLAGS = -I$(LIBDRV_PREFIX)/include
 SOURCES = \
 	slip.c
Index: uspace/srv/net/slip/slip.c
===================================================================
--- uspace/srv/net/slip/slip.c	(revision 2f59112756a7b4e140a34a9de2e2150cdffe0fb1)
+++ uspace/srv/net/slip/slip.c	(revision 5828554423254c2cf4c4eb9a849b1d5d9ffd413d)
@@ -40,5 +40,5 @@
 #include <inet/addr.h>
 #include <inet/iplink_srv.h>
-#include <device/char_dev.h>
+#include <char_dev_iface.h>
 #include <io/log.h>
 #include <errno.h>
